【问题标题】:Saving array to php file将数组保存到 php 文件
【发布时间】:2014-02-26 11:04:31
【问题描述】:

我需要将数组保存并读取到文件中。我知道有诸如序列化或 JSON 编码/解码之类的功能,以及保存到 csv 的各种方法,但我希望尽可能快地读取数组。所以我考虑写入生成变量代码的 php 文件,然后将其包含到我当前的代码中。这是一个好主意吗?我知道这可能是一个安全问题。但是,即使我将 htmlspecialchars 应用于值,是否也是如此?是不是更快?

生成的.php

<?php
$array = array("a","b","c");

包括

include 'generated.php'; 

我只对这种方法的阅读速度比其他方法更快以及是否存在任何安全问题感兴趣。

【问题讨论】:

  • 这不是一个好主意。将其以某种格式存储然后读取它会更快。
  • 顺便说一句 - serialize()json_encode() 快​​ - 如果您打算通过 JavaScript 读取输出(AJAX ...我想现在应该真的是 AJaJ,不记得我上次在 AJAX 中实际使用 XML 是什么时候了)。
  • 不,我只会在服务器端(php)使用它。
  • @MMM 我只对阅读速度感兴趣。加载文件、解析文件并分配给变量(所有这些都在 php 中完成)真的比使用单个包含更快吗?
  • @Kudlas:逻辑证明:在“我的”解决方案中,您逐个字符地执行文件读取,使用简单逻辑对其进行分析,然后将其存储为数组。在“你的”解决方案中,我们不只是“使用单个包含”,我们还读取一个文件,缓冲整个内容,然后在其上运行 PHP 解析器,不仅分析数据结构,还分析语言的语法总是比你简单的数据结构更复杂。在处理、分析和计算结果之后,将其分配给您的变量。所以是的,它肯定会更慢。

标签: php arrays file security include


【解决方案1】:

你要找的函数是var_export,你可以这样使用它:

file_put_contents($filename, '<?php $arr = ' . var_export($arr, true) . ';');

【讨论】:

    【解决方案2】:

    我只是为了测试的目的拼凑了这些 - 因为我很好奇(我没有费心解析 XML,因为它比 json_encode() 还要慢):

    <?php
    
    header('Content-Type: text/plain;charset=utf-8');
    set_time_limit(120);
    
    //define variables
    $iLoopCount = 10000;
    $aTheArray = 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", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    $fStartTime = microtime(true);
    
    //function to convert an array into a string used to create a PHP include file
    function convertArrayToInclude(array $aIn) {
      $sOut = 'array(';
      foreach($aIn as $key => $value) {
        $formattedKey = is_string($key) ? "'{$key}'" : $key;
        $formattedValue = is_string($value) ? "'{$value}'" : $value;
    
        $sOut .= "{$formattedKey} => {$formattedValue},"; 
      }
      $sOut = substr($sOut, 0, -1) . ');';
    
      return $sOut;
    }
    
    //test serialize
    for($i = 0; $i < $iLoopCount; $i++) {
      file_put_contents("serialize.txt", serialize($aTheArray), LOCK_EX);
      $aReadArray1 = unserialize(file_get_contents("serialize.txt"));
    }
    
    $fStopTime1 = microtime(true);
    echo "serialize execution time ({$iLoopCount} iterations) : " . ($fStopTime1 - $fStartTime) . "s\n\n";
    
    //test json_encode
    for($i = 0; $i < $iLoopCount; $i++) {
      file_put_contents("json_encode.txt", json_encode($aTheArray), LOCK_EX);
      $aReadArray2 = json_decode(file_get_contents("serialize.txt"));
    }
    
    $fStopTime2 = microtime(true);
    echo "json_encode execution time ({$iLoopCount} iterations) : " . ($fStopTime2 - $fStopTime1) . "s\n\n";
    
    //test native using fixed data
    for($i = 0; $i < $iLoopCount; $i++) {
      file_put_contents("include.php", 
      '<?php $aReadArray3 = 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", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); ?>'  
      , LOCK_EX);
    
      include 'include.php';
    }
    
    $fStopTime3 = microtime(true);
    echo "native include execution time with fixed data ({$iLoopCount} iterations) : " . ($fStopTime3 - $fStopTime2) . "s\n\n";
    
    //test native using dynamic data
    for($i = 0; $i < $iLoopCount; $i++) {
      file_put_contents("include2.php", 
      '<?php $aReadArray4 = ' . convertArrayToInclude($aTheArray) . ' ?>'  
      , LOCK_EX);
    
      include 'include2.php';
    }
    
    $fStopTime4 = microtime(true);
    echo "native include execution time with dynamic data ({$iLoopCount} iterations) : " . ($fStopTime4 - $fStopTime3) . "s\n\n";
    
    ?>
    

    点击刷新几次以查看相当一致的结果,但这就是您正在查看的内容:

    • 序列化执行时间(10000 次迭代):4.6746249198914s

    • json_encode执行时间(10000次迭代):5.132187128067s

    • 原生包括固定数据的执行时间(10000 次迭代):4.863872051239s

    • 原生包括动态数据的执行时间(10000 次迭代):5.5474679470062s

    所以,简而言之:如果您可以将 php 包含构建为字符串(本机固定数据),那么重复写入和包含该文件可能是最快的方法(见注释)。但是,如果您想包含一些完整性检查或将数组转换为可在该包含(本机动态数据)中使用的字符串,那么您将进入一个充满伤害的世界 - 您有功能和处理开销以及您的“自行开发”解决方案引入的任何/所有安全漏洞。这是最慢也是最糟糕的方式。

    非常短:PHP 具有将变量存储为文本 (serialize()) 并检索它们 (unserialize()) 的函数......只需使用它们而不是试图重新发明轮子。


    注意:使用serialize()fixed native data 之间的执行时间差异会随着每次刷新而摇摆不定,有时一个更快,有时另一个 - 本质上它对实际速度几乎没有影响。

    【讨论】:

      【解决方案3】:

      使用 CSV 作为文件。

      这是一个示例代码:

      $fileContent = 'a,b,c'; // Read it from file
      $array = explode(',' , $fileContent);
      echo '<pre>';
      print_r($array);
      echo '</pre>';
      

      【讨论】:

      • 你也可以使用fgetcsv()来读取csv文件,或者str_getcsv()来解析csv字符串。 (:
      • 在此基础上再做一点,(并且与原始问题密切相关),您可以使用fputcsv() 将数据数组直接插入格式正确的 csv 文件中。如果您想将数组转换为原始 CSV 字符串,可以使用 answer here 来实现此目的。
      • 谢谢,请注意在 fgetcsv 的情况下可能会有多行,所以我使用了 explode
      【解决方案4】:

      您可以将数组存储为 JSON 或 XML。 JSON 是一种用于交换文本数据的轻量级方法。它比 XML 轻很多,但是它不能存储文本和数字以外的任何内容,而 XML 可以存储任意数量的不同类型的数据。

      JSON 方法

      如果您发现 JSON 更适合您的数据存储需求,那么我推荐 PHP 的 json_encode() 方法。这是一个将数据存储到文件中的快速函数。

      function storeData( $path, $data ) {
          // Get data currently in file and convert it to a PHP array
          $contents = json_decode( file_get_contents( $path ) );
          // Update data
          $currentData = array_merge( $contents, $data );
          // Rewrite file with updated content
          file_put_contents( json_encode( $data ) );
      }
      

      这是过于简单化了,是为了传达最简单的观点。然而,与其他一切一样,必须对放置的内容进行适当的卫生和验证。您还必须确保该文件甚至是可写的。

      XML 方法

      如果您出于某种原因不喜欢 JSON 方法,那么您可以使用 PHP 的 SimpleXMLElement 进行数组到 XML 的转换。 More on that hereand here。这将遵循我们上面的 JSON 函数所遵循的几乎相同的过程,只是您将在 XML 中进行编码、解码、读取和写入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 2010-12-31
        • 2021-06-25
        • 2021-05-25
        • 2015-05-30
        相关资源
        最近更新 更多