Passing Data between Two Snippets II

Using a file to pass data between two snippets


Variable values don't persist across different snippets, even when they're on the same page or in the same template. In the previous article, we looked at using $mods->runSnippet() to pass data to another snippet. In this one, we'll see how to do it with a file..

MODX logo

Using a File to Pass Data to Another Snippet

Say you want to pass a string created in one custom snippet to another custom snippet. As we mentioned in the previous article, the best solution here is often to combine the two snippets. For some use cases, though, this is impractical. One alternative (we'll see others in the upcoming articles) is to use a file to store the data. Assume that you've created a string you want to pass in the first snippet and placed it in the $string variable. For simplicity and speed, we'll put our file in the MODX root directory. In that first snippet, you'd do this:

$path = MODX_BASE_PATH . 'my-data-file.txt';
$success = file_put_contents($path, $string);
if (! $success) {
  $modx->log(modX::LOG_LEVEL_ERROR, 'Could not write to ' . $path);
}

To retrieve the string in the second snippet, you'd do this:

$path = MODX_BASE_PATH . 'my-data-file.txt';
$string = file_get_content($path);

What if I have more than one data item?

The best solution here is to put the data in a PHP array, convert it to a JSON string and save it, then in the second snippet, get the string and convert it back to a PHP array. Assume that your PHP array is in a variable called $data. In the first snippet, do this:

$jsonData = $modx->toJSON($data);
$path = MODX_BASE_PATH . 'my-data-file.txt';
$success = file_put_contents($path, $jsonData);
if (! $success) {
  $modx->log(modX::LOG_LEVEL_ERROR, 'Could not write to ' . $path);
}

Then in the second snippet, do this:

$path = MODX_BASE_PATH . 'my-data-file.txt';
$jsonData = file_get_content($path);
$data = $modx->fromJSON($jsonData);

An alternative

Another method is to replace toJSON() and fromJSON with PHP's serialize() and unserialize. Which method is faster depends on the version of PHP you're using, but the differences are trivial unless you have a huge amount of data. One advantage of the JSON functions is that the result is much more readable than that produced by serialize(). For example, the JSON version of the array of getResources properties we used in the previous article looks like this with toJSON():

{"parents":"12","tpl":"MyTplChunk","depth":"5","sortby":"pagetitle","sortdir":"ASC"}

With serialize() it looks like this:

a:5:{s:7:"parents";s:2:"12";s:3:"tpl";s:10:"MyTplChunk";s:5:"depth";s:1:"5";s:6:"sortby";s:9:"pagetitle";s:7:"sortdir";s:3:"ASC";}

One advantage of serialize() comes when you want to save and retrieve a PHP object rather than an array. In that case, serialize/unserialize will usually do a better job than JSON.


Speeding Things Up

The MODX toJSON() and fromJSON() methods (which are actually xPDO methods) call the PHP functions json_encode() and json_decode(). But first, they check to see if those functions exist. If not, they pull in local copies of those functions from the xPDO package. This was necessary when the methods were written because older versions of PHP did not support those functions. This is no longer necessary because any version of PHP that will run MODX Revolution will contain both functions.

Calling json_encode() and json_decode() directly will be a little faster because it will skip both an unnecessary function call, and the unnecessary test for the existence of the functions. Another reason for calling those two PHP functions directly is that it allows you to use the JSON Predefined Constants to control how json_encode() operates. By default, json_encode() escapes unicode characters (like the Euro symbol), escapes slashes, and converts single quotes to double quotes. To prevent the first two conversions, you can use json_encode($fields, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);, but be aware that those constants are not available until PHP 5.4.

Note that json_decode() will undo those conversions except for the conversion of single to double quotes.

In PHP 5.4 you can use the JSON_NUMERIC_CHECK constant, which will convert quoted integers to actual integers.

Also available in PHP 5.4 is the JSON_PRETTY_PRINT constant, which will make our array above appear in a much more readable form in the file:

{
    "parents": "12",
    "tpl": "MyTplChunk",
    "depth": "5",
    "sortby": "pagetitle",
    "sortdir": "ASC"
}

The JSON_PRETTY_PRINT constant is very handy when you're building a processor or REST interface that returns a JSON string. Both JavaScript and PHP will handle the formatted JSON fine, since they ignore whitespace, but you can go to your endpoints with your browser and see JSON that's being returned in much more readable form.


Limitations

Using a file to pass data between snippets only works when the data will be the same for all users. If multiple users visit your site and you use a file to store data that's for a particular user, other users visiting at the same time may see that same data. In some cases, a file that contains data for a single user may be overwritten by another user's data before the first user gets to see it. You could use the user's username as the file name, but if you have a lot of users, you'd have a lot of files unless you figure out a way to delete them after the user leaves the site.

In those cases, using a $_SESSION variable is much more appropriate. We'll see how to use $_SESSION variables in the next article in this series.


Coming Up

In the next article, we'll look at passing data to another snippet using $_SESSION variables.



Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)



Comments (0)


Please login to comment.

  (Login)