0

I'm setting up a configuration file for a website, which will be read using the parse_ini_file method. One of the options is number of seconds prior to some action. I tried setting the value to 60*60*24*3 to get three day's worth of seconds:

[mailer]
; Number of seconds before trial expiration an email should be sent
seconds     = 60*60*24*3;

but the variable is just read into php as the string "60*60*24*3". I don't want to use eval, for security reasons. Is there any way to make this (a) easier to use and (b) more intuitive to read than by simply listing the number of seconds to a given date?

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
eykanal
  • 26,437
  • 19
  • 82
  • 113
  • How do you plan on knowing everywhere an INI-initiated setting that *may* requires processing? INI files, by dint, are typically a cluster of finite key and value sets. So it feels like the values should be pre-calculated (which you already indicate in the comment above the setting). That being said, there is [bcMathParser](http://www.bestcode.com/math-parser-php-docs/). – Jared Farrish Mar 03 '13 at 16:40
  • @JaredFarrish - I know because I'm the one writing it. I would specify which entries could be "processed" and which ones won't. – eykanal Mar 03 '13 at 16:44
  • Seems like possibly a lot of trouble and "brittle" (to me) for something so easy to do manually. My opinion, of course. – Jared Farrish Mar 03 '13 at 16:51
  • @JaredFarrish - No prob, if it's a bad idea I can avoid it. Just trying to make the file that much easier to read (`60*60*24*3` makes more intuitive sense than `259200`). – eykanal Mar 03 '13 at 16:52
  • That is true. You could allow a `strtotime()` statement, such as: https://ignite.io/code/5133811cec221e283b000000 – Jared Farrish Mar 03 '13 at 16:58
  • @JaredFarrish - Not bad; that function only accepts very limited input, which makes it safe to use, and I can leave instructions for use in the ini file. Thanks. Post it as an answer and I'll vote it up. – eykanal Mar 03 '13 at 17:04
  • You might modify the question to represent the problem at hand, which seems to be how to handle formatting time intervals in settings files. Technically, the bcMathParser seems the right answer to your current question. – Jared Farrish Mar 03 '13 at 17:10
  • Also note, [`DateTimeInterval::createFromString`](http://www.php.net/manual/en/dateinterval.createfromdatestring.php) gives the same functionality, where I believe `DateTime::diff` should give the difference. I think the `strtotime() - time()` is probably good enough, but may not handle leap years well, so seeding the current time to a specific date (`2010-04-01`) and then seeding the `strtotime()` with that should bypass situations where the end of February might be an issue in the calculation. – Jared Farrish Mar 03 '13 at 17:14
  • @JaredFarrish - Thanks, I updated the question to better reflect what I'm asking. – eykanal Mar 03 '13 at 17:27

2 Answers2

1

You can use supported date and time formats to make a human-readable string, which may then be used to initialize and calculate the difference in seconds:

$diff = "3 days 5 hours 10 seconds";
$now = strtotime('2010-04-01 00:00:00'); // No leap year funny business
$then = strtotime($diff, $now);
$diff = $then - $now;

echo "
Now: " . date('r', $now) . "
Then: " . date('r', $then) . "
Diff (seconds): $diff";

https://ignite.io/code/51338967ec221e0d3b000000

Note: The concern about leap year is whether it will calculate the seconds correctly (add/remove a day?). If this is possible, it should be tested independently.

The above outputs:

Now: Thu, 01 Apr 2010 00:00:00 +0000
Then: Sun, 04 Apr 2010 05:00:10 +0000
Diff (seconds): 277210

Which would then let you do:

[mailer]
; Period before trial expiration an email should be sent.
; Use PHP-supported time statements in an expression to
; specify an interval, such as 3 days, or 72 hours, etc.
; See: http://www.php.net/manual/en/datetime.formats.php
expires     = 3 days;

As I noted in the comments, you can also use DateTimeInterval::createFromString() with DateTime::diff to do the same thing.

I will note as well that getting the string formatted correctly, while not difficult, can sometimes be trickier than you might think. For simple strings like 3 days that's not hard, but 3d doesn't work. So the time that is calculated should be validated, and an error provided to the person setting the configuration if what was entered is not a valid expression, or is "out of bounds" to what was expected (in the past maybe?).

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
-1

rename your ini to php and write it this way

# Number of seconds before trial expiration an email should be sent
$cfg['somesection']['someparam'] = 'foo';
...
$cfg['mailer']['seconds'] = 60*60*24*3;

or use a screen calculator to do the math and paste result as a value.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345