PHP中数组按键名和键值排序函数

 更新时间:2016年11月25日 15:02  点击:1879
大家知道,数组排序最常用的函数就是 sort($arr); 它的作用是按数组的键值升序排列,并且排序后的数组键名不再是原来的键名,是按新数组来重新设置的键名。

而有时我们要求更复杂的排序。如按键名排序,这里用到 ksort($arr); 函数,它会根据数组的键名排序,并维持原有的键值关系。相对应的 asort($arr); 函数,是按键值排序,且维持原有的键值关系。

同样原理,rsort(); arsort(); krsort(); 函数除了排序是按降序排列外,其它与sort(); rsort(); ksort(); 相同。
数组操作是PHP很重要的基础,希望能好好运用。

一维数组


例子

 代码如下 复制代码

<?php
function my_sort($a, $b)
  {
  if ($a == $b) return 0;
  return ($a > $b) ? -1 : 1;
  }

$people = array("Swanson" => "Joe",
"Griffin" => "Peter", "Quagmire" => "Glenn",
"swanson" => "joe", "griffin" => "peter",
"quagmire" => "glenn");

uksort($people, "my_sort");

print_r ($people);
?>输出:

Array
(
[swanson] => joe
[quagmire] => glenn
[griffin] => peter
[Swanson] => Joe
[Quagmire] => Glenn
[Griffin] => Peter
)

如下面这个二维数组,需要按照sort键名来排序,那么array_multisort() 就无法直接实现了:

 代码如下 复制代码

$data[5] = array('volume' => 67, 'edition' => 2);
$data[4] = array('volume' => 86, 'edition' => 1);
$data[2] = array('volume' => 85, 'edition' => 6);
$data[3] = array('volume' => 98, 'edition' => 2);
$data[1] = array('volume' => 86, 'edition' => 6);
$data[6] = array('volume' => 67, 'edition' => 7);
// 准备要排序的数组
foreach ($data as $k => $v) {
    $edition[] = $v['edition'];
}
array_multisort($edition, SORT_ASC, $data);
print_r($data);将输出:

Array
(
    [0] => Array
        (
            [volume] => 86
            [edition] => 1
        )

    [1] => Array
        (
            [volume] => 67
            [edition] => 2
        )

    [2] => Array
        (
            [volume] => 98
            [edition] => 2
        )

    [3] => Array
        (
            [volume] => 85
            [edition] => 6
        )

    [4] => Array
        (
            [volume] => 86
            [edition] => 6
        )

    [5] => Array
        (
            [volume] => 67
            [edition] => 7
        )

)


•sort() 函数用于对数组单元从低到高进行排序。
•rsort() 函数用于对数组单元从高到低进行排序。
•asort() 函数用于对数组单元从低到高进行排序并保持索引关系。
•arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。
•ksort() 函数用于对数组单元按照键名从低到高进行排序。
•krsort() 函数用于对数组单元按照键名从高到低进行排序。

在php中文件上传我们都是利用表单的post来实例了,注意:
标签的 enctype 属性规定了在提交表单时要使用哪种内容类型。在表单需要二进制数据时,比如文件内容,请使用 \"multipart/form-data\"

这是一种非常简单文件上传方式。基于安全方面的考虑,您应当增加有关什么用户有权上传文件的限制。

 代码如下 复制代码


<!DOCTYPE html>  
    <html>  
    <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  
    <meta http-equiv="Content-Language" content="zh-cn" />  
    </head>  
    <body>  
    <form action="/upload.php" method="post" enctype="multipart/form-data">  
    <label for="file">Filename:</label>  
    <input type="file" name="file" id="file" /><br />  
    <input type="submit" name="submit" value="Submit" />  
    </form>  
    <?php  
    if($_POST){  
     if ( $_FILES["file"]["size"] < 2000000 )  
       {  
       if ($_FILES["file"]["error"] > 0)  
         {  
         echo "Return Code: " . $_FILES["file"]["error"] . "<br />";  
         }  
       else 
         {  
         echo "Upload: " . $_FILES["file"]["name"] . "<br />";  
         echo "Type: " . $_FILES["file"]["type"] . "<br />";  
         echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";  
         echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";  
       
         if (file_exists("upload/" . $_FILES["file"]["name"]))  
           {  
           echo $_FILES["file"]["name"] . " already exists. ";  
           }  
         else 
           {  
           move_uploaded_file($_FILES["file"]["tmp_name"],  
           "upload/" . $_FILES["file"]["name"]);  
           echo "Stored in: " . "upload/" . $_FILES["file"]["name"];  
           }  
         }  
       }  
     else 
       {  
       echo "Invalid file";  
       }  
    }  
    ?>  
    </body>  
    </html> 


第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。就像这样:

$_FILES["file"]["name"] - 被上传文件的名称
$_FILES["file"]["type"] - 被上传文件的类型
$_FILES["file"]["size"] - 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码

实例

首先是上传的提交页面upfile.html

 代码如下 复制代码

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<form action="upload.php" enctype="multipart/form-data" method="POST">
<input type="hidden" name="max_file_size" value="33554432">
<input type="file" name="file">
<input type="submit" name="submit" value="上传" />
</form>

1. PHP支持HTML以POST的方法传输文件,但是form中必须声明enctype的属性="multipart/form-data",否则整个form表单将不起任何作用。

2. form表单中必须含有一个name为MAX_FILE_SIZE的隐藏域,这个隐藏域用来指定用户最大能上传的文件大小,必须声明在所有其他input标签之前。如果文件超大的话,浏览器直接就可以给出提示,不必浪费上传的时间。

下面就是上传处理文件upload.php

 代码如下 复制代码

<?php
 
    /* 设定上传目录 */
    $dest_dir='uploads';
 
    /* 检测上传目录是否存在 */
    if( !is_dir($dest_dir) || !is_writeable($dest_dir) )
    {
        die("上传目录 ".$dest_dir." 不存在或无法写入");
    }
 
    /* 设置允许上传文件的类型 */
    $type=array("rar","zip","txt","c");
 
    /* 获取上传文件信息 */
    $upfile=&$HTTP_POST_FILES['file'];
 
    /* 获取文件后缀名函数 */
    function fileext($filename)
    {
        return substr(strrchr($filename, '.'), 1);
    }
 
    /* 判断上传文件类型 */
    if( !in_array( strtolower( fileext($upfile['name'] ) ),$type) )
     {
        $text=implode(",",$type);
        echo "对不起,您只能上传以下类型文件: ",$text,"<br>";
     }
     else
     {
        /* 设置文件名为"日期_文件名" */
        $dest=$dest_dir.'/'.date("ymdHis")."_".$upfile['name'];
 
        /* 移动上传文件到指定文件夹 */
        $state=move_uploaded_file($upfile['tmp_name'],$dest);
 
        if ($state)
        {
            print("文件上传成功!<br>");
            print("文件名:".$dest."<br>");
            print("上传的文件大小:".( round($upfile['size'] / 1024,2) )." KB<br>");
        }
        else
        {
            /* 处理错误信息 */
            switch($upfile['error'])
            {
                case 1 : die("上传文件大小超出 php.ini:upload_max_filesize 限制<br>");
                case 2 : die("上传文件大小超出 MAX_FILE_SIZE 限制<br>");
                case 3 : die("文件仅被部分上传<br>");
                case 4 : die("没有文件被上传<br>");
                case 5 : die("找不到临时文件夹<br>");
                case 6 : die("文件写入失败<br>");
            }
        }
     }
 
?>

本文章来给各位朋友介绍php中include_once和require_once性能分析,有需要了解的朋友不防参考参考。


我们知道, PHP去判断一个文件是否被加载, 是需要得到这个文件的opened_path的, 意思是说, 比如:

 代码如下 复制代码

 <?php

    set_include_path("/tmp/:/tmp2/");

    include_once("2.php");

    ?>

当PHP看到include_once “2.php”的时候, 他并不知道这个文件的实际路径是什么, 也就无法从已加载的文件列表去判断是否已经加载, 所以在include_once的实现中, 会首先尝试解析这个文件的真实路径(对于普通文件这个解析仅仅类似是检查getcwd和文件路径, 所以如果是相对路径, 一般是不会成功), 如果解析成功, 则查找EG(include_files), 如果存在则说明包含过了, 返回, 否则open这个文件, 从而得到这个文件的opened_path. 比如上面的例子, 这个文件存在于 “/tmp2/2.php”.

 

然后, 得到了这个opened_path以后, PHP去已加载的文件列表去查找, 是否已经包含, 如果没有包含, 那么就直接compile, 不再需要open file了.


 

1. 尝试解析文件的绝对路径, 如果能解析成功, 则检查EG(included_files), 存在则返回, 不存在继续

 

2. 打开文件, 得到文件的打开路径(opened path)

 

3. 拿opened path去EG(included_files)查找, 是否存在, 如果存在则返回, 不存在继续
 

4. 编译文件(compile_file)

 
 

这个在大多数情况下, 不是问题, 然而问题出在当你使用APC的时候…

 
 

在使用APC的时候, APC劫持了compile_file这个编译文件的指针, 从而直接从cache中得到编译结果, 避免了对实际文件的open, 避免了对open的system call.

 

然而, 当你在代码中使用include_once的时候, 在compile_file之前, PHP已经尝试去open file了, 然后才进入被APC劫持的compile file中, 这样一来, 就会产生一次额外的open操作. 而APC正是为了解决这个问题, 引入了include_once_override, 在include_once_override开启的情况下, APC会劫持PHP的ZEND_INCLUDE_OR_EVAL opcode handler, 通过stat来确定文件的绝对路径, 然后如果发现没有被加载, 就改写opcode为include, 做一个tricky解决方案.


 

但是, 很可惜, 如我所说, APC的include_once_override实现的一直不好, 会有一些未定义的问题, 比如:

 

 代码如下 复制代码

    <?php

    set_include_path("/tmp");

    function a($arg = array()) {

        include_once("b.php");

    }

    a();

    a();

    ?>

然后, 我们的b.php放置在”/tmp/b.php”, 内容如下:

 

 代码如下 复制代码

    <?php

      class B {}

    ?>

那么在打开apc.include_once_override的情况下, 连续访问就会得到如下错误:

 
Fatal error – include() : Cannot redeclare class

 

排除这些技术因素, 我也一直认为, 我们应该使用include, 而不是include_once, 因为我们完全能做到自己规划, 一个文件只被加载一次. 还可以借助自动加载, 来做到这一点.

 

你使用include_once,只能证明, 你对自己的代码没信心.

 

所以, 建议大家, 不要再使用include_once,不过我建义大家使用autoload和spl_autoload自动加载

(1) autoload机制概述

在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利。这 也是OO设计的基本思想之一。在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可。下面是一个实际的例 子:

 代码如下 复制代码

/* Person.class.php */
<?php
class Person {
var $name, $age;

function __construct ($name, $age)
{
$this->name = $name;
$this->age = $age;
}
}
?>

/* no_autoload.php */
<?php
require_once (”Person.class.php”);

$person = new Person(”Altair”, 6);
var_dump ($person);
?>

在这个例子中,no-autoload.php文件需要使用Person类,它使用了require_once将其包含,然后就可以直接使用Person类来实例化一个对象。

但 随着项目规模的不断扩大,使用这种方式会带来一些隐含的问题:如果一个PHP文件需要使用很多其它类,那么就需要很多的require/include语 句,这样有可能会造成遗漏或者包含进不必要的类文件。如果大量的文件都需要使用其它的类,那么要保证每个文件都包含正确的类文件肯定是一个噩梦。

PHP5为这个问题提供了一个解决方案,这就是类的自动装载(autoload)机制。autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。

下面是使用autoload机制加载Person类的例子:

 代码如下 复制代码

/* autoload.php */
<?php
function __autoload($classname) {
require_once ($classname . “class.php”);
}

$person = new Person(”Altair”, 6);
var_dump ($person);
?>

在php中访问mysql我们需要利用php的各种函数来实现的,最常用的函数是mysql_connect()函数了,用它就可以连接数据库,其它的我们后面再廛。

mysql_connect()函数

定义和用法

mysql_connect() 函数打开非持久的 MySQL 连接。

语法

mysql_connect(server,user,pwd,newlink,clientflag)

例子

 代码如下 复制代码

<?php
$con = mysql_connect("localhost","mysql_user","mysql_pwd");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

// 一些代码...

mysql_close($con);
?>

下面我们来看个连接数据库实例

先建一个名为test的数据库(使用phpadmin)见下图:

然后,在该表内建一个名为 user的表,

准备工作完成,正式开始:)

 代码如下 复制代码

<?php
//connect.php
$db_server="localhost";// 数据库服务器名称
$db_user="root"; // 连接数据库用户名
$db_pwd="leaf";//连接数据库密码
$db_name="test";//数据库的名字
$db=mysql_connect($db_server,$db_user,$db_pwd,$db_name);
/*
面向对像
$db=new mysql($db_server,$db_user,$db_pwd,$db_name);
*/
 
if(!$db)echo "fail";
else echo "connect success"
?>


如果PHP是4.0以后版本,可以使用mysqli库,相应的代码这样写:

 代码如下 复制代码

<?php ......
$db=mysqli_connect($db_server,$db_user,$db_pwd,$db_name);
/*
面向对象
$db=new mysqli($db_server,$db_user,$db_pwd,$db_name);
*/
if(mysqli_connect_errno()){
  echo "Error: Could not connect to database. Please try again laer.";
  exit;
}
else echo "Success!";
?>

说明:使用了函数库mysqli,所以需要将php.ini文件中的extension=php.mysqli 打开

通常,我们将代码前面的几行单独放在一配制文件中,这里取名为 db_config.php

 代码如下 复制代码

<?php
//db_config.php
$db_server="localhost";// 数据库服务器名称
$db_user="root"; // 连接数据库用户名
$db_pwd="leaf";//连接数据库密码
$db_name="test";//数据库的名字
?>

如此一来,最初的那个连接测试代码就成了这样的:

 代码如下 复制代码

<?php
// connect.php
require_once(“db_config.php”);//包含配置文件
$db=mysql_connect($db_server,$db_user,$db_pwd,$db_name);
//同样也可以用面向对像的语法
if(!$db)echo "fail";
else echo "connect success"
?>

以前有讲过关于php mvc的各种用法,本文章主要介绍PHP MVC框架之错误捕捉用法说明,各位同学可参考。

前三篇文章已经把MVC的结构原理都简单的进行了说明和演示。。。当然,不是说一个框架就只有那点东西,一个良好的框架所要求的功能还是要很全面的,例如友好的错误输出,安全处理,防止跨域攻击等

好了,我们一步一步来。这节要说的是错误捕捉,其实这个不难,只要理解2个方法就可以做好错误捕捉的程序。

 代码如下 复制代码


register_shutdown_function(‘functionname’);  
set_error_handler(‘functionname’); 

第一个方法,是注册一个shutdown的回调函数,当php脚本关闭时调用,当然这个关闭可以是正常的代码执行完毕,也可以是程序抛出致命错误关闭的脚本,那我怎么区分呢?别急,php还有一个方法叫error_get_last() 就像函数名说的那样,获取php最后一个错误信息,这样就可以判断是代码正常执行完毕还是遇到fatal error。。。

第二个方法,是注册一个error的回调函数,当脚本执行遇到错误时调用。

这2个方法最大的区别是,第一个是脚本关闭调用,也就是1次访问,只会调用一次(因为发生致命错误脚本就退出执行了),二第二个方法的触发调用是发生错误的时候,例如访问数组中不存在的index,使用未定义的变量,就是这些warning,notice错误的捕捉。。。如果你想更了解二者的区别,建议访问php官网查看文档说明。。。

这里我就不贴代码了,有兴趣的同学,可以去github那里下回来慢慢看。。。

 

 代码如下 复制代码

<?php

# 定义application路径

define('APPPATH', trim(__DIR__,'/'));

# 获得请求地址

$root = $_SERVER['SCRIPT_NAME'];

$request = $_SERVER['REQUEST_URI'];

$URI = array();

# 获得index.php 后面的地址

$url = trim(str_replace($root, '', $request), '/');


# 如果为空,则是访问根地址

if (empty($url))

{

    # 默认控制器和默认方法

    $class = 'Index';

    $func = 'welcome';

}

else

{

    $URI = explode('/', $url);

 


    # 如果function为空 则默认访问index

    if (count($URI) < 2)

    {

        $class = ucfirst($URI[0]);

        $func = 'index';

    }

    else

    {

        $class = ucfirst($URI[0]);

        $func = $URI[1];

    }

}

 

# 把class加载进来

include(APPPATH . '/' . 'application/controllers/' . $class . '.php');

 


#实例化

$obj = new $class;

 


call_user_func_array(

    # 调用内部function

    array($obj,$func),

    # 传递参数

    array_slice($URI, 2)

);

 

 

我们来看看最终的效果。。。我们来试试访问不存在的controller里的方法试试

先看看没有错误捕捉的时候:

 

再来对比下做了错误捕捉的时候

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • php数组操作 键名比较 差集 交集赋值

    本文章提供在量的数据中级操作实例有如对键名比较计算数组的差集 计算差集 给指定数组中插入一个元素 反转数组 交集赋值新的数组实例。 //定义回调函数 funct...2016-11-25
  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09
  • C#二维数组基本用法实例

    这篇文章主要介绍了C#二维数组基本用法,以实例形式分析了C#中二维数组的定义、初始化、遍历及打印等用法,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#数组的常用操作方法小结

    Array数组在C#中同样是最基本的数据结构,下面为大家C#数组的常用操作方法小结,皆为细小的代码段,欢迎收看收藏...2020-06-25
  • php curl模拟post请求和提交多维数组的示例代码

    下面一段代码给大家介绍php curl模拟post请求的示例代码,具体代码如下: <&#63;php$uri = "http://www.cnblogs.com/test.php";//这里换成自己的服务器的地址// 参数数组$data = array ( 'name' => 'tanteng'// 'passwor...2015-11-24
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • C# 拷贝数组的几种方法(总结)

    下面小编就为大家带来一篇C# 拷贝数组的几种方法(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C# 参数按照ASCII码从小到大排序(字典序)

    这篇文章主要介绍了C# 参数按照ASCII码从小到大排序(字典序)的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25