PHP文件系统概述

PHP文件系统概述

>> 本文固定链接: http://php.ncong.com/php_course/file/wenjianxitong.html

>> 转载请注明:  2014年08月08日 于 恩聪PHP学习教程 发表

文件类型

  PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”、“dir”或者“unknown”三中文件类型。而在UNIX系统中,我们可以获得“block”、“char”、“dir”、“fifo”、“file”、“link”和“unknown”7种类型,各文件类型的详细说明如下表所示:UNIX系统中7种文件类型说明

  在PHP中可以使用filetype()函数获取文件的上述类型,该函数接受一个文件名作为参数,如果文件不存在将返回FALSE。下面的程序是判断文件类型的示例,代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
    //获取Linux系统下的文件类型    
    echo filetype('/etc/passwd');      //输出file,/etc/passwd为普通文件
    echo filetype('/etc/grub.conf');       //输出lilnk,/etc/grub.conf为连接文件-->/boot/grub/grub.conf
    echo filetype('/etc/');            //输出dir,/etc/为一个目录,即文件夹
    echo filetype('/dev/sda1');          //输出block,/dev/sda1为块设备,它是一个分区
    echo filetype('/dev/tty01');          //输出char,为字符设备,它是一个字符终端
    //获取windows系统下文件类型
    echo filetype("C:\\WINDOWS\\php.ini");    //输出file,C:\\WINDOWS\\php.ini为一个普通文件
    echo filetype("C:\\WINDOWS");              //输出dir,C:\\WINDOWS为一个文件夹(目录)
?>
  对于一个已知的文件,还可以使用is_file()函数判断给定的文件名是否为一个正常的文件。和它类似,使用is_dir()函数判断给定的文件名是否是同一个目录,使用is_link()函数判断给定的文件名是否为一个符号连接。
  文件的属性
  在进行编程时,需要使用到文件的一些常见属性,如文件的大小、文件的类型、文件的修改时间、文件的访问时间和文件的权限等。PHP中提供了非常全面的用来获取这些属性的内置函数,如下表所示:PHP的文件属性处理函数

  在表中的函数都需要提供同样的字符串参数,即一个指向文件或目录的字符串变量。PHP将缓存这些函数的返回信息以提供更快的性能。然而在某些情况下,你可能想清楚被缓存的信息。例如,如果在一个脚本中多次检查同一个文件,而该文件在此脚本执行期间有被删除或修改的危险时,你需要清楚文件状态缓存。在这种情况下,可以用clearstatcache()函数来清楚被PHP缓存的该文件信息。clearstatcache()函数缓存特定文件名的信息,因此只在对同一个文件名进行多次操作,并且需要该文件信息不被缓存时才需要调用它。下面的程序中通过调用这些函数获取文件大部分属性。代码如下所示:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?php
    //声明一个函数,通过传入一个文件名称获取文件大部分属性
    function getFilePro($fileName){
        //如果提供的文件或目录不存在,则直接退出函数
        if(!file_exists($fileName)){
            echo "目标不存在!!<br>";
            return;
        }
        //判断是否是一个普通文件,如果是则条件成立
        if(is_file($fileName))
            echo $fileName."是一个文件<br>";
        //判断是否是一个目录
        if(is_dir($fileName))
            echo $fileName."是一个目录<br>";
        //用定义的函数输出文件形态
        echo "文件形态:".getFileType($fileName)."<br>";
        //获取文件大小,并自定义转换单位
        echo "文件大小:".getFileSize(filesize($fileName))."<br>";
        if(is_readable($fileName))      //判断提供的文件是否可以读取内容
           echo "文件可读<br>";
        if(is_writable($fileName))      //判断提供的文件是否可以改写
           echo "文件可写<br>";
        if(is_executable($fileName))      //判断提供的文件是否有执行的权限
           echo "文件可执行<br>";
        echo "文件建立时间:".date("Y年m月j日",filectime($fileName))."<br>";
        echo "文件最后更新的时间:".date("Y年m月j日",filemtime($fileName))."<br>";
        echo "文件最后打开时间:".date("Y年m月j日",fileatime($fileName))."<br>";
    }
    //声明一个函数用来返回文件的类型
    function getFileType($fileName){
        //通过filetype()函数返回的文件类型作为选择条件
        switch(filetype($fileName)){
            case 'file': $type .= "普通文件";   break;
            case 'dir': $type .= "目录文件";   break;
            case 'block': $type .= "块设备文件";   break;
            case 'char': $type .= "字符设备文件";   break;
            case 'fifo': $type .= "命名管道文件";   break;
            case 'link': $type .= "符号连接";   break;
            case 'unknown': $type .= "未知类型";   break;
            default:     $type .="没有检测到类型";
        }
        return $type;       //返回转换后的类型
    }
    //自定义一个文件大小单位转换函数
    function getFileSize($bytes){
        if($bytes >= pow(2,40)){           //如果提供的字符数大于等于2的40次方
            $return = round($bytes/pow(1024,4),2);        //将字节大小转换为同等的T大小
            $suffix = "TB";               //单位为TB
        }elseif($bytes >= pow(2,30)){           //如果提供的字符数大于等于2的30次方
            $return = round($bytes/pow(1024,3),2);        //将字节大小转换为同等的G大小
            $suffix = "GB";               //单位为GB   
        }elseif($bytes >= pow(2,20)){           //如果提供的字符数大于等于2的20次方
            $return = round($bytes/pow(1024,2),2);        //将字节大小转换为同等的M大小
            $suffix = "MB";               //单位为MB   
        }elseif($bytes >= pow(2,10)){           //如果提供的字符数大于等于2的10次方
            $return = round($bytes/pow(1024,1),2);        //将字节大小转换为同等的K大小
            $suffix = "KB";               //单位为KB   
        }else{
            $return = $bytes;                             //字节大小单位不变
            $suffix = "Byte";
        }
        return $return." ".$suffix;         //返回合适的文件大小和单位
    }
    //调用自定义函数,将当前目录下的file.php文件传入,获取属性
    getFilePro("file.php");          
?>

除了可以使用这些独立的函数分别获取文件的属性外,还可以使用一个stat()函数获取文件的大部分属性值。该函数将返回一个数组,数组中的每个元素对应文件的一种属性值。该函数的使用如下代码所示:

1
2
3
4
5
6
<?php
    //返回关于文件的信息数组,是关联和索引混合的数组
    $filePro = stat("file.php");
    //只打印其中的关联数组,第13个元素之后为关联数组
    print_r(array_slice($filePro,13));
?>

除了使用stat()函数获取文件的大部分属性值之外,也可以使用对应的函数lstat和fstat()函数取得。和stat()函数略有不同,stat()函数作用于一个普通的文件,lstat()只能作用于一个符号连接,而fstat()函数需要一个资源句柄。

PHP的生成器、yield和协程

虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究。不过公司的框架是基于php的协程实现,觉得有必要深入的瞅瞅了。

由于之前对于生成器接触不多,后来也是在看了鸟哥的介绍在PHP中使用协程实现多任务调度才有所了解。下面也只是说说我的理解。

迭代和迭代器

在了解生成器之前我们先来看一下迭代器和迭代。迭代是指反复执行一个过程,每执行一次叫做迭代一次。比如普通的遍历便是迭代:

$arr = [1, 2, 3, 4, 5];

foreach($arr as $key => $value) {
    echo $key . ' => ' . $value . "\n";
}

我们可以看到通过foreach对数组遍历并迭代输出其内容。在foreach内部,每次迭代都会将当前的元素的值赋给$value并将数组的指针移动指向下一个元素为下一次迭代坐准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是迭代器接口,对应的那个被迭代的自己就是迭代器对象

PHP提供了统一的迭代器接口:

Iterator extends Traversable {

    // 返回当前的元素
    abstract public mixed current(void)
    // 返回当前元素的键
    abstract public scalar key(void)
    // 向下移动到下一个元素
    abstract public void next(void)
    // 返回到迭代器的第一个元素
    abstract public void rewind(void)
    // 检查当前位置是否有效
    abstract public boolean valid(void)
}

通过实现Iterator接口,我们可以自行的决定如何遍历对象。比如通过实现Iterator接口我们可以观察迭代器的调用顺序。


class MyIterator implements Iterator {
    private $position = 0;
    private $arr = [
        'first', 'second', 'third',
    ];
    
    public function __construct() {
        $this->position = 0;
    }
    
    public function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }
    
    public function current() {
        var_dump(__METHOD__);
        return $this->arr[$this->position];
    }
    
    public function key() {
        var_dump(__METHOD__);
        return $this->position;
    }
    
    public function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }
    
    public function valid() {
        var_dump(__METHOD__);
        return isset($this->arr[$this->position]);
    }
    
}

$it = new MyIterator();

foreach($it as $key => $value) {
    echo "\n";
    var_dump($key, $value);
}

通过这个例子能够清楚的看到了foreach循环中调用的顺序。从例子也能看出通过迭代器能够将一个普通的对象转化为一个可被遍历的对象。这在有些时候,能够将一个普通的UsersInfo对象转化为一个可以遍历的对象,那么就不需要通过UsersInfo::getAllUser()获取一个数组然后遍历数组,而且还可以在对象中对数据进行预处理。

yield和生成器

相比较迭代器,生成器提供了一种更容易的方法来实现简单的对象迭代,性能开销和复杂性都大大降低。

一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成可以yield生成许多它所需要的值,并且每一次的生成返回值只是暂停当前的执行状态,当下次调用生成器函数时,PHP会从上次暂停的状态继续执行下去。

我们在使用生成器的时候可以像关联数组那样指定一个键名对应生成的值。如下生成一个键值对与定义一个关联数组相似。


function xrange($start, $limit, $step = 1) {
    for ($i = $start, $j = 0; $i <= $limit; $i += $step, $j++) {
        // 给予键值
        yield $j => $i;
    }
}

$xrange = xrange(1, 10, 2);
foreach ($xrange as $key => $value) {
    echo $key . ' => ' . $value . "\n";
}

更多的生成器语法可以参见生成器语法

实际上生成器函数返回的是一个Generator对象,这个对象不能通过new实例化,并且实现了Iterator接口。


Generator implements Iterator {
    public mixed current(void)
    public mixed key(void)
    public void next(void)
    public void rewind(void)
    // 向生成器传入一个值
    public mixed send(mixed $value)
    public void throw(Exception $exception)
    public bool valid(void)
    // 序列化回调
    public void __wakeup(void)
}

可以看到出了实现Iterator的接口之外Generator还添加了send方法,用来向生成器传入一个值,并且当做yield表达式的结果,然后继续执行生成器,直到遇到下一个yield后会再次停住。

function printer() {
    while(true) {
        echo 'receive: ' . yield . "\n";
    }
}

$printer = printer();
$printer->send('Hello');
$printer->send('world');

以上的例子会输出:

receive: Hello
receive: world

在上面的例子中,经过第一个send()方法,yield表达式的值变为Hello,之后执行echo语句,输出第一条结果receive: Hello,输出完毕后继续执行到第二个yield处,只不过当前的语句没有执行到底,不会执行输出。如果将例子改改就能够看出来yield的继续执行到哪里。


function printer() {
    $i = 1;
    while(true) {
        echo 'this is the yield ' . $i . "\n";
        echo 'receive: ' . yield . "\n";
        $i++;
    }
}

$printer = printer();
$printer->send('Hello');
$printer->send('world');

这次的输出便会变为:

this is the yield 1
receive: hello
this is the yield 2
receive: world
this is the yield 3

这边可以清楚的看出send之后的继续执行到第二个yield处,之前的代码照常执行。

我们再对例子进行适当的修改:


function printer() {
    $i = 1;
    while(true) {
        echo 'this is the yield ' . (yield $i) . "\n";
        $i++;
    }
}

$printer = printer();
var_dump($printer->send('first'));
var_dump($printer->send('second'));

执行一下会发现结果为:

this is the yield first
int(2)
this is the yield second
int(3)

让我们来看一下,是不是发现了问题,跑出来的结果不是从1开始的而是从2开始,这是为啥嘞,我们来分析一下:

在此之前我们先来跑另外一段代码:


function printer() {
    $i = 1;
    while(true) {
        echo 'this is the yield ' . (yield $i) . "\n";
        $i++;
    }
}

$printer = printer();
var_dump($printer->current());
var_dump($printer->send('first'));
var_dump($printer->send('second'));

这个时候我们会发现执行的结果变成了:

int(1)
this is the yield first
int(2)
this is the yield second
int(3)

可以看到在第一次调用生成器函数的时候,生成器已经执行到了第一个yield表达式处,所以在$printer->send('first')之前,生成器便已经yield 1出来了,只是没有对这个生成的值进行接收处理,在send()了之后,echo语句便会紧接着完整的执行,执行完毕继续执行$i++,下次循环便是var_dump(2)

至此,我们看到了yield不仅能够返回数据而且还可以接收数据,而且两者可以同时进行,此时yield便成了数据双向传输的工具,这就为了实现协程提供了可能性。

至于接下来的协程的知识,水平有限不好介绍,还是看鸟哥的原文比较直接,里面例子很丰富,介绍的很详尽。

php 字符串替换函数

strtr

(PHP 4, PHP 5, PHP 7)

strtr — 转换指定字符

说明

string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )

该函数返回 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

参见

add a note add a note

User Contributed Notes 40 notes

24

evan dot king at NOSPAM dot example dot com ¶

2 years ago
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.

21

Hayley Watson ¶

4 years ago
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
?>

7

dcz at phpbb-seo dot com ¶

4 years ago
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.

5

doydoy44 ¶

4 years ago
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

11

dot dot dot dot dot alexander at gmail dot com ¶

9 years ago
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 */

3

ktogias at math dot upatras dot gr ¶

13 years ago
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."'";

4

Anonymous ¶

12 years ago
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);
?>

2

patrick at p-roocks dot de ¶

12 years ago
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

2

gabi at unica dot edu ¶

15 years ago
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.

5

Tedy ¶

4 years ago
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('Ă' => 'ă',
'Â' => 'â',
'Î' => 'î',
'Ș' => 'ș',
'Ş' => 'ş',
'Ț' => 'ț',
'Ţ' => 'ţ');

$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($stringarray_merge($utf_letters$letters)) : strtr($stringarray_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.

3

allixsenos at gmail dot com ¶

8 years ago
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''Þ'=>'B''ß'=>'Ss',
'à'=>'a''á'=>'a''â'=>'a''ã'=>'a''ä'=>'a''å'=>'a''æ'=>'a''ç'=>'c''è'=>'e''é'=>'e',
'ê'=>'e''ë'=>'e''ì'=>'i''í'=>'i''î'=>'i''ï'=>'i''ð'=>'o''ñ'=>'n''ò'=>'o''ó'=>'o',
'ô'=>'o''õ'=>'o''ö'=>'o''ø'=>'o''ù'=>'u''ú'=>'u''û'=>'u''ý'=>'y''ý'=>'y''þ'=>'b',
'ÿ'=>'y''Ŕ'=>'R''ŕ'=>'r',
);

return strtr($string$table);
}

?>

1

ru dot dy at gmx dot net ¶

12 years ago
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;
}
?>
2

qeremy [atta] gmail [dotta] com ¶

4 years ago
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
?>

2

elloromtz at gmail dot com ¶

7 years ago
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' , '_');

3

Sidney Ricardo ¶

9 years ago
This work fine to me:

<?php
function normaliza ($string){
$a 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ
ßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ'
;
$b 'aaaaaaaceeeeiiiidnoooooouuuuy
bsaaaaaaaceeeeiiiidnoooooouuuyybyRr'
;
$string utf8_decode($string);
$string strtr($stringutf8_decode($a), $b);
$string strtolower($string);
return 
utf8_encode($string);
}
?>

2

dot dot dot dot dot alexander at gmail dot com ¶

9 years ago
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(  $one0minstrlen($one), strlen($two) )  );
$two substr(  $two0minstrlen($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(  $product0$winner  ) . $positions[$key] . substr(  $product, ( $winner strlen($key) )  )   );
$pos1 = (  $winner strlen$positions[$key] )  );
}
return 
$product;
}
else{
return 
$string;
}
}
/* endfunction stritr */
}/* endfunction exists stritr */
?>
2

tomhmambo at seznam dot cz ¶

11 years ago
<?
// 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;
}
?>

2

Michael Schuijff ¶

5 years ago
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($keysarray_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$i1, array(substr($array[$i], 0$pos), $replace[$key], substr($array[$i], $pos strlen($key))));
$count += 2;
}
}
next($length);
}
return 
implode($array);
}
?>

1

horak.jan AT centrum.cz ¶

10 years ago
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) => 'ý'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) => 'Ý'chr(142) => 'Ž',
chr(150) => '-');
return 
strtr($text$dict);
}
?>

1

Fernando “Malk” Piancastelli ¶

13 years ago
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

2

joeldegan AT yahoo ¶

11 years ago
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;
}
?>

0

Romain ¶

2 years ago
<?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''Þ'=>'B''ß'=>'Ss''à'=>'a''á'=>'a''â'=>'a''ã'=>'a''ä'=>'a''å'=>'a''æ'=>'a''ç'=>'c',
'è'=>'e''é'=>'e''ê'=>'e''ë'=>'e''ì'=>'i''í'=>'i''î'=>'i''ï'=>'i''ð'=>'o''ñ'=>'n''ò'=>'o''ó'=>'o''ô'=>'o''õ'=>'o',
'ö'=>'o''ø'=>'o''ù'=>'u''ú'=>'u''û'=>'u''ý'=>'y''ý'=>'y''þ'=>'b''ÿ'=>'y',
' ' => '''_' => '''-' => '''.'=> ''',' => ''';' => '');

return mb_strtolower(strtr($string$unwanted_array ));
}

2

bisqwit at iki dot fi ¶

15 years ago
#!/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
0

Sam ¶

5 years ago
Case Insensitive strtr

<?php
function stritr($string$one$two=null) {
if (
is_string($one)) {
return 
strtr($stringstrtoupper($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;
}
?>

0

troelskn at gmail dot com ¶

9 years ago
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"));

0

ajitsingh4u at gmail dot com ¶

10 years ago
/**
* 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;
}
0

martin[dot]pelikan[at]gmail[dot]com ¶

11 years ago
// 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

0

j at pureftpd dot org ¶

13 years ago
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");
}

0

hotmail – marksteward ¶

14 years ago
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

0

symlink23-remove-my-spleen at yahoo dot com ¶

15 years ago
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");

-2

volkris at tamu dot edu ¶

13 years ago
Regarding christophe's conversion, note that the \x## values should be in double quotes, not single, so that the escape will be applied.
-3

lichail at sohu dot com ¶

4 years ago
<?php
//note this output null
echo strtr('abc', array('' => ''));
?>
-4

Chris ¶

6 years ago
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++]), ')';
?>

-4

patrick dot rauchfuss at gmail dot com ¶

5 years ago
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'));
?>

-4

m dot frank at beam dot ag ¶

14 years ago
to get the ascii equivalent of unicode characters simply use the

utf8_decode() function

-7

antimoz at gmail dot com ¶

5 years ago
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''Ð'=>'Eth',
'Ñ'=>'N''Ó'=>'O''Ò'=>'O''Ô'=>'O''Õ'=>'O''Ö'=>'O''Ø'=>'O',
'Ú'=>'U''Ù'=>'U''Û'=>'U''Ü'=>'U''Ý'=>'Y',

'á'=>'a''à'=>'a''â'=>'a''ã'=>'a''å'=>'a''ä'=>'a''æ'=>'ae''ç'=>'c',
'é'=>'e''è'=>'e''ê'=>'e''ë'=>'e''í'=>'i''ì'=>'i''î'=>'i''ï'=>'i''ð'=>'eth',
'ñ'=>'n''ó'=>'o''ò'=>'o''ô'=>'o''õ'=>'o''ö'=>'o''ø'=>'o',
'ú'=>'u''ù'=>'u''û'=>'u''ü'=>'u''ý'=>'y',

'ß'=>'sz''þ'=>'thorn''ÿ'=>'y'
);
?>

-3

erik at eldata dot se ¶

15 years ago
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.

-8

Ezbakhe Yassin <yassin88 at gmail dot com> ¶

12 years ago
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"

-4

oliver at modix dot de ¶

12 years ago
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);
}

?>

-3

stewey at ambitious dot ca ¶

13 years ago
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"
);
}

?>

PHP 获取远程图片到指定目录

require 'QueryList.class.php'; 
 
$pattern = array("img" => array("#index_banner img", "src")); 
$url = "http://www.sucaihuo.com/"$qy = new QueryList($url$pattern'''''utf-8'); 
$rs = $qy->jsonArr; 
 
$file = "upload/"//保存路径 
foreach ($rs as $v) { 
    $img = $v['img']; 
    $name = substr($img, strrpos($img'/') + 1); //去除图片路径,获取图片名 
    $img_url = "http://www.sucaihuo.com" . $img . ""; 
    $img_content = file_get_contents($img_url); 
    $img_save = $file . $name//采集保存的图片 
    if (!file_exists($img_save)) {//若是upload没有该图片 
        file_put_contents($img_save$img_content); //保存图片 
    } 
}

PHP匿名函数和use子句用法

输出 hello everyone

function test()
{
    $param2 = 'every';
    // 返回一个匿名函数
    return function ($param1) use ($param2) {
        // use子句 让匿名函数使用其作用域的变量
        $param2 .= 'one';
        print $param1 . ' ' . $param2;
    };
}
$anonymous_func = test();
$anonymous_func('hello');



下面的方式 输出hello everybody

$param2中多了一个引用

1
2
3
4
5
6
7
8
9
10
11
12
function test()
{
  $param2 = 'everyone';
  $func = function ($param1) use (&$param2) {
    // use子句 让匿名函数使用其父作用域的变量
    print $param1 . ' ' . $param2;
  };
  $param2 = 'everybody';
  return $func;
}
$anonymous_func = test();
$anonymous_func('hello');

php 设计模式

php 设计模式

1.单例模式

 

单例模式顾名思义,就是只有一个实例。作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

 

单例模式的要点有三个:

  1. 一是某个类只能有一个实例;
  2. 二是它必须自行创建这个实例;
  3. 三是它必须自行向整个系统提供这个实例。
为什么要使用PHP单例模式
  1. 1. php的应用主要在于数据库应用, 一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免大量的new 操作消耗的资源,还可以减少数据库连接这样就不容易出现 too many connections情况。
  2. 2. 如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看zend Framework的FrontController部分。
  3. 3. 在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。

 

例子: 

复制代码
/**
* 设计模式之单例模式
* $_instance必须声明为静态的私有变量
* 构造函数必须声明为私有,防止外部程序new类从而失去单例模式的意义
* getInstance()方法必须设置为公有的,必须调用此方法以返回实例的一个引用
* ::操作符只能访问静态变量和静态函数
* new对象都会消耗内存
* 使用场景:最常用的地方是数据库连接。
* 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。
*/
class man
{
//保存例实例在此属性中
private static $_instance;

//构造函数声明为private,防止直接创建对象
private function __construct()
{
echo ‘我被实例化了!’;
}

//单例方法
public static function get_instance()
{
var_dump(isset(self::$_instance));

if(!isset(self::$_instance))
{
self::$_instance=new self();
}
return self::$_instance;
}

//阻止用户复制对象实例
private function __clone()
{
trigger_error(‘Clone is not allow’ ,E_USER_ERROR);
}

function test()
{
echo(“test”);

}
}

// 这个写法会出错,因为构造方法被声明为private
//$test = new man;

// 下面将得到Example类的单例对象
$test = man::get_instance();
$test = man::get_instance();
$test->test();

// 复制对象将导致一个E_USER_ERROR.
//$test_clone = clone $test;

php 数组插入

$arr=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p');//目标数组

$i_arr=array('1','2','3','4');//要插入的数组
$n=4;//插入的位置
$num = $n+1;
for($i=0;$i<count($i_arr);$i++){
    array_splice($arr,$n,0,$i_arr[$i]); //第个参数大于零时删除原数组元素
    $n+=$num;
}
print_r($arr);






/*
* 多维数组插入,数组结构要一样
* $arr 目标数组
 * $i_arr 要插入的数组
*/
function splice_list_data($arr,$i_arr){
     $tmpArray=array();
    $n=4; //隔$n个插入一个,
    for($i=0;$i<count($i_arr);$i++){
        $tmpArray[0]=$i_arr[$i];
        array_splice($arr,$n,0,$tmpArray);
        unset($tmpArray);
        $n+=5;
    }
    return $arr;
}