0

I need to save and read array to file. I know there are functions like serialize, or JSON encode/decode, various methods for saving to csv, but I want to have the array read as fast as possible. So I thought about writing to php file where I generate variable code, and then including it into my current code. Is that a good idea? I know it might be a security issue. But is it even if I apply htmlspecialchars to values? Is it faster?

generated.php

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

include

include 'generated.php'; 

I am only interested if this method is faster in reading, than others and if there are any security issues.

Kudlas
  • 659
  • 7
  • 24
  • It's not a good idea. It's faster to store it in a certain format and then read it. – MMM Feb 26 '14 at 11:10
  • As an aside - `serialize()` is quicker than `json_encode()` - you should only really use `json_encode()` if you're intending the output to be read in by JavaScript (AJAX ... though it should really be AJaJ now I suppose, can't remember the last time I actually used XML in AJAX). – CD001 Feb 26 '14 at 11:11
  • No, I am only gonna use it on server side (php). – Kudlas Feb 26 '14 at 11:14
  • @MMM I am only interested in speed of read. Is really faster to load file, parse it and than assign to variable (all of this done in php), than use single include? – Kudlas Feb 26 '14 at 11:16
  • @Kudlas: Logical proof: In "my" solution you perform a file read, character by character, this is analysed using simple logic and then stored as an array. In "your" solution we don't just "use a single include", we also read a file, buffer the whole contents, then run a PHP parser on top of it, analysing not only the data structure but also the language's syntax which will always be more complicated than your simple data structure. After this is processed, analysed, and the result is computed, it is then assigned to your variable. So yes, it will definitely be slower. – MMM Feb 26 '14 at 14:49

4 Answers4

2

The function you're looking for is var_export, you would use it like this:

file_put_contents($filename, '<?php $arr = ' . var_export($arr, true) . ';');
siannone
  • 6,617
  • 15
  • 59
  • 89
lexotrion
  • 84
  • 1
  • 4
1

I just cobbled this together for the purposes of testing - because I was curious (I didn't bother with XML parsing as that's even slower than 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";

?>

Hit refresh a few times to see reasonably consistent results, but this is sort of what you're looking at:

  • serialize execution time (10000 iterations) : 4.6746249198914s

  • json_encode execution time (10000 iterations) : 5.132187128067s

  • native include execution time with fixed data (10000 iterations) : 4.863872051239s

  • native include execution time with dynamic data (10000 iterations) : 5.5474679470062s

So, in short : if you can build your php include as a string (native fixed data) then writing and including that file repeatedly is potentially the quickest method (see notes). However, if you want to include some sanity checks or convert an array to a string that can be used within that include (native dynamic data) you're into a whole world of hurt - you've got function and processing overheads as well as any/all security vulnerabilities introduced by your 'roll your own' solution. It's the slowest and worst way to go.

In very short : PHP has functions for storing variables as text ( serialize() ) and retrieving them ( unserialize() ) ... just use them instead of trying to reinvent the wheel.


Note: the difference in execution time between using serialize() and fixed native data wobbled with each refresh, sometimes one was faster, sometimes the other - essentially it made very little difference to the actual speed.

CD001
  • 8,332
  • 3
  • 24
  • 28
0

Use CSV as a files.

This is a sample code:

$fileContent = 'a,b,c'; // Read it from file
$array = explode(',' , $fileContent);
echo '<pre>';
print_r($array);
echo '</pre>';
Waqar Alamgir
  • 9,828
  • 4
  • 30
  • 36
  • You may also use [`fgetcsv()`](http://uk3.php.net/fgetcsv) for reading csv files, or [`str_getcsv()`](http://uk3.php.net/manual/en/function.str-getcsv.php) for parsing csv strings. (: – Sean Feb 26 '14 at 11:11
  • And to build on this a little more, (and closely related to the original question), you may use [`fputcsv()`](http://uk1.php.net/fputcsv) to directly insert an array of data into a csv file properly formatted. If you're wanting to convert an array into a raw CSV string, there's an [answer here](http://stackoverflow.com/questions/3933668/convert-array-into-csv) which provides a function to do just that. – Sean Feb 26 '14 at 11:13
  • thanks, just to be note there could be multiple line in case of fgetcsv, so I used explode – Waqar Alamgir Feb 26 '14 at 11:45
0

You could store the array as JSON or XML. JSON is a lightweight method for exchanging text data. It is much lighter than XML, however it cannot store anything other than text and numbers, where XML can store any number of different types of data.

The JSON Approach

If you find JSON suits your data storage needs better, then I recommend PHP's json_encode() method. Here is a quick function to store data into a file.

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 ) );
}

This is overly simplistic, and is for the purposes of conveying the simplest point. However, like with everything else, proper sanitation and validation of content being placed must be performed. You also have to make sure that the file is even writable.

The XML Approach

If you do not like the JSON approach for whatever reason, then you can use PHP's SimpleXMLElement for array to XML conversion. More on that here, and here. This will follow pretty much the same procedure that our JSON function above follows, only you will be encoding, decoding, reading and writing in XML.

Community
  • 1
  • 1
Franco Selem
  • 175
  • 1
  • 9