Skip to content
This repository

Replaced time() with $_SERVER['REQUEST_TIME'] #944

Closed
wants to merge 17 commits into from

6 participants

Tobias Mathes M. Vugteveen Andrey Andreev flashover Phil Sturgeon Ryan Neufeld
Tobias Mathes

As discussed in 7bb95df#commitcomment-881705

Replacement of time() calls with $_SERVER['REQUEST_TIME'] , I left out the date_helper for now.

M. Vugteveen

http://php.net/manual/en/reserved.variables.server.php

"REQUEST_TIME": The timestamp of the start of the request. Available since PHP 5.1.0. It is float with microseconds since PHP 5.4.0.

Does this pull request give a problem with PHP 5.4?

Tobias Mathes

Regarding to the changelog of 5.4:

Changed $_SERVER['REQUEST_TIME'] to include microsecond precision. (Ilia)

But I have no possibility to test this with PHP 5.4 :/

I could add a floor to it, but I guess it will vanish the performance improvement. :/

M. Vugteveen

In versions before 5.4 the request_time is a int, but from PHP 5.4 it will be a float (eg. 1326987371.123123)

then time() is maybe better to use... Maybe define a time() somewhere in the code (index.php), so you don't have to call time() multiple times?

Tobias Mathes

Yes, I got this the first time.

Basically PHP 5.4 $_SERVER['REQUEST_TIME'] has microtime(TRUE); as value.

I tested

print(date("c", microtime(TRUE)));

which works perfectly fine.

I ran also some other test, which had no problems with the float variant.

php -r '$now = microtime(TRUE); print($now . PHP_EOL);print(mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now)));'

php -r 'print(microtime(TRUE)-14440);'

Andrey Andreev
Collaborator

This can only break something.

Tobias Mathes

I will test this further on the weekend, probably with a PHP 5.4 RC version and make the appropiate additions if necessary or drop the changes completely.

Tobias Mathes tobiasmathes closed this
M. Vugteveen

Haha, the new PHP 5.4 RC6 release (yesterday), https://svn.php.net/repository/php/php-src/tags/php_5_4_0RC6/NEWS

Restoring $_SERVER['REQUEST_TIME'] as a long and introducing $_SERVER['REQUEST_TIME_FLOAT'] to include microsecond precision.

So your pull request should work ;-)

Tobias Mathes tobiasmathes reopened this
Tobias Mathes

oh oops, I could have re-opened ... :/ sorry, I am new to this. =)

flashover

What about using $this->input->server('REQUEST_TIME') for each $_SERVER['REQUEST_TIME'] ?

Tobias Mathes

Well, this would make sense if the client actually had access to this global. But it's filled by the php process with time() on the beginning of the request processing.

Andrey Andreev
Collaborator

@flashover The point is to not have the overhead of calling a function and use a variable instead - calling a custom method (that reads from this very same variable) doesn't make any sense.

I still think this is not needed though. I'd usually do crazy stuff to optimize for speed, but time() is one of the fastest functions available and $_SERVER is not a constant - it's elements' values can be manipulated both prior and after it's initialization, so I'm not sure if relying on it is 100% safe.

Tobias Mathes

@narfbg

If something or someone is modifying $_SERVER in your app, you will have other problems than performance. :)

So, this pull request is rejected then?

Andrey Andreev
Collaborator

@twobee

Indeed, but using time() makes that impossible, at least in those particular cases. :)
But ... I don't make the decisions of what's merged and rejected and unfortunately sometimes that seems to take too long to be done.

Phil Sturgeon

I am listening guys, I was just waiting for you two to hash out your argument as I am on the fence. So it seems, this change will work in 5.1-5.3, but COULD cause problems in 5.4 due to the int/float change.

Test it, does it cause problems. If so, typecasting for the win?

@narbg I don't think we need to worry about security here, nobody is going to be messing around with the $_SERVER variable and if they are they deserve any confusion they get. I also don't think this change is about speed differences of variable access over function calls, it is about reporting the time more accurately on slow page calls.

Andrey Andreev
Collaborator

@philsturgeon

Um, no - the int/float issue only exist in beta and some of the RC versions for PHP 5.4. This is a quote from the changelog for 5.4.0 RC6:

Restoring $_SERVER['REQUEST_TIME'] as a long and introducing $_SERVER['REQUEST_TIME_FLOAT'] to include microsecond precision. (Patrick)

IMO, time accuracy is a completely different argument, as in some cases it might be more convenient to have records for when did a certain process take place instead of when the request was initiated. Actually, now that you've mentioned that ... most of the changed libraries are only useful in web applications, but e.g. the DB utility class could be used via CLI.

Let's say we have a daemon like script that does database backups every n hours (it's stupid, because that should be done via crontab, but still possible and in this case - just an example). And here's what happens:

  • a PHP process is started/forked and $_SERVER['REQUEST_TIME'] is initiated with the value of time()
  • after a few hours, it's time to make a backup of the database
  • the developer has not specified a custom name for the output file and the DB utility class creates one based on a timestamp
  • each time the backup procedure is triggered, due to $_SERVER['REQUEST_TIME'] not being changed - the same timestamp-based filename is overwritten

A similar issue can be expected with the ZIP and probably Image manipulation libraries.

Phil Sturgeon
Tobias Mathes

Because of the accuracy thing I left out the Date Helper in the pull request. But usually on high traffic sites you will need 'minor' win this change is providing.

@narfbg
I really love your example, it's a good example how not to do the job for such kind of backup mechanism. :)

We could leave out the DB_utility and Calendar, if this is the issue. :)

Andrey Andreev
Collaborator

If it's not used in DB utility, Image_lib and Zip (or in other words - if it's only applied to HTTP-only libraries) - I'm OK with it. Indeed it's more a matter of preference there and I'm probably way too concerned about security at times. :)

Andrey Andreev
Collaborator

@twobee Seems like we replied at the same time. :)

Calendar generates HTML code and is useless in the CLI, so it's good in there.

Tobias Mathes

@narfbg

As I mentioned before, if someone messes with your $_SERVER you really have other (more serious) problems.
Usually I agree with pro security measures, but in this case I thinks it's missing the point. :)

Yes, I agree on a CLI level this could lead to a certain inaccurancy.

I can revoke it or we discuss which measure are useful and doing just them instead of all. I would then apply this changes only to my system. :)

Tobias Mathes

I will update the repository later this week to the changes we discussed.

M. Vugteveen

What's the status @twobee ?

Tobias Mathes

I will update the request within the next two days. :)

Ryan Neufeld

Radical thought here:

Why not just have in the constants config file

<?php
define('REQUEST_TIME', time());

then use that?

Andrey Andreev
Collaborator

Probably because a variable with the same value already exists?

Ryan Neufeld
Tobias Mathes

@ryanneufeld Still, it's missing the whole point here.

Tobias Mathes

@IT-Can Sorry, got a bit tied up in the last time :(

Andrey Andreev
Collaborator

@ryanneufeld Actually, it was me pointing out all of the cons against using $_SERVER['REQUEST_TIME'].
But apart from my own arguments, I'd rather see this one as a performance improvement than anything to do with precision.

Ryan Neufeld

@twobee Well, perhaps I'm missing the point. But I've seen two arguments here. What is the point then?

Tobias Mathes

@ryanneufeld We discussed this topic more than enough, I will revert the changes as discussed with @narfbg . Then it will be either merged or not.

added some commits
Tobias Mathes Revert "+ system/libraries/Zip.php: Replaced time()"
This reverts commit a6b60917216c69c2ca047f300eadaf1c6e10061e.
3fbcfc8
Tobias Mathes Revert "+ system/libraries/Image_lib.php: Replaced time()"
This reverts commit c0deb5d697504b76e6877c4d449fb6bf7e5c6af5.
950349f
Tobias Mathes Revert "+ system/database/DB_utility.php: Replaced time()"
This reverts commit 88c38d57d18e8da55f4a5bf96e3d449df2d297c9.
4c35c3b
Tobias Mathes

I finally applied the changes, do I need anything else to do? :)

Tobias Mathes Merge branch 'develop' into replace_time
Conflicts:
	system/libraries/Session.php
79820d7
Andrey Andreev
Collaborator

So far, so good. But why are file permissions for the cache drivers changed?
I'm also not sure about replacing time() in the documentation.

Tobias Mathes

I can revert the examples, too. Sorry about the permissions, I guess my VMWARE settings are responsible for this. I try to fix it. :(

Tobias Mathes tobiasmathes closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 17 unique commits by 2 authors.

Jan 19, 2012
+ system/core/Input.php: replaced time() 95c15cc
+ system/core/Output.php: replaced time() 4b0ebe1
+ system/core/Security.php: Replaced time() bf5ce72
+ system/database/DB_utility.php: Replaced time() 88c38d5
+ system/libraries/Calendar.php: Replaced time() 11251cd
+ system/libraries/Image_lib.php: Replaced time() c0deb5d
+ system/libraries/Session.php: Replaced time() 0fdd2e3
+ system/libraries/Zip.php: Replaced time() a6b6091
+ system/libraries/Cache/drivers/Cache_apc.php: Replaced time() 4faa08a
+ system/libraries/Cache/drivers/Cache_file.php: Replaced time() f8c864f
+ system/libraries/Cache/drivers/Cache_memcached.php: Replaced time() 57cc34f
+ user_guide_src/source/general/models.rst: Replaced time() in examples db6ddcf
+ user_guide_src/source/helpers/captcha_helper.rst: Replaced time() i…
…n examples
c1bf755
Mar 31, 2012
Tobias Mathes Revert "+ system/libraries/Zip.php: Replaced time()"
This reverts commit a6b60917216c69c2ca047f300eadaf1c6e10061e.
3fbcfc8
Tobias Mathes Revert "+ system/libraries/Image_lib.php: Replaced time()"
This reverts commit c0deb5d697504b76e6877c4d449fb6bf7e5c6af5.
950349f
Tobias Mathes Revert "+ system/database/DB_utility.php: Replaced time()"
This reverts commit 88c38d57d18e8da55f4a5bf96e3d449df2d297c9.
4c35c3b
Tobias Mathes Merge branch 'develop' into replace_time
Conflicts:
	system/libraries/Session.php
79820d7
This page is out of date. Refresh to see the latest.
4  system/core/Input.php
@@ -278,11 +278,11 @@ public function set_cookie($name = '', $value = '', $expire = '', $domain = '',
278 278
 
279 279
 		if ( ! is_numeric($expire))
280 280
 		{
281  
-			$expire = time() - 86500;
  281
+			$expire = $_SERVER['REQUEST_TIME'] - 86500;
282 282
 		}
283 283
 		else
284 284
 		{
285  
-			$expire = ($expire > 0) ? time() + $expire : 0;
  285
+			$expire = ($expire > 0) ? $_SERVER['REQUEST_TIME'] + $expire : 0;
286 286
 		}
287 287
 
288 288
 		setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
4  system/core/Output.php
@@ -448,7 +448,7 @@ public function _write_cache($output)
448 448
 			return;
449 449
 		}
450 450
 
451  
-		$expire = time() + ($this->cache_expiration * 60);
  451
+		$expire = $_SERVER['REQUEST_TIME'] + ($this->cache_expiration * 60);
452 452
 
453 453
 		if (flock($fp, LOCK_EX))
454 454
 		{
@@ -518,4 +518,4 @@ public function _display_cache(&$CFG, &$URI)
518 518
 }
519 519
 
520 520
 /* End of file Output.php */
521  
-/* Location: ./system/core/Output.php */
  521
+/* Location: ./system/core/Output.php */
2  system/core/Security.php
@@ -188,7 +188,7 @@ public function csrf_verify()
188 188
 	 */
189 189
 	public function csrf_set_cookie()
190 190
 	{
191  
-		$expire = time() + $this->_csrf_expire;
  191
+		$expire = $_SERVER['REQUEST_TIME'] + $this->_csrf_expire;
192 192
 		$secure_cookie = (bool) config_item('cookie_secure');
193 193
 
194 194
 		if ($secure_cookie && (empty($_SERVER['HTTPS']) OR strtolower($_SERVER['HTTPS']) === 'off'))
4  system/libraries/Cache/drivers/Cache_apc.php 100644 → 100755
@@ -66,7 +66,7 @@ public function get($id)
66 66
 	public function save($id, $data, $ttl = 60)
67 67
 	{
68 68
 		$ttl = (int) $ttl;
69  
-		return apc_store($id, array($data, time(), $ttl), $ttl);
  69
+		return apc_store($id, array($data, $_SERVER['REQUEST_TIME'], $ttl), $ttl);
70 70
 	}
71 71
 
72 72
 	// ------------------------------------------------------------------------
@@ -156,4 +156,4 @@ public function is_supported()
156 156
 }
157 157
 
158 158
 /* End of file Cache_apc.php */
159  
-/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
  159
+/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
4  system/libraries/Cache/drivers/Cache_file.php 100644 → 100755
@@ -86,7 +86,7 @@ public function get($id)
86 86
 	public function save($id, $data, $ttl = 60)
87 87
 	{
88 88
 		$contents = array(
89  
-				'time'		=> time(),
  89
+				'time'		=> $_SERVER['REQUEST_TIME'],
90 90
 				'ttl'		=> $ttl,
91 91
 				'data'		=> $data
92 92
 			);
@@ -192,4 +192,4 @@ public function is_supported()
192 192
 }
193 193
 
194 194
 /* End of file Cache_file.php */
195  
-/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
  195
+/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
6  system/libraries/Cache/drivers/Cache_memcached.php 100644 → 100755
@@ -73,11 +73,11 @@ public function save($id, $data, $ttl = 60)
73 73
 	{
74 74
 		if (get_class($this->_memcached) === 'Memcached')
75 75
 		{
76  
-			return $this->_memcached->set($id, array($data, time(), $ttl), $ttl);
  76
+			return $this->_memcached->set($id, array($data, $_SERVER['REQUEST_TIME'], $ttl), $ttl);
77 77
 		}
78 78
 		elseif (get_class($this->_memcached) === 'Memcache')
79 79
 		{
80  
-			return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
  80
+			return $this->_memcached->set($id, array($data, $_SERVER['REQUEST_TIME'], $ttl), 0, $ttl);
81 81
 		}
82 82
 
83 83
 		return FALSE;
@@ -249,4 +249,4 @@ public function is_supported()
249 249
 }
250 250
 
251 251
 /* End of file Cache_memcached.php */
252  
-/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
  252
+/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
4  system/libraries/Calendar.php 100644 → 100755
@@ -65,7 +65,7 @@ public function __construct($config = array())
65 65
 			$this->CI->lang->load('calendar');
66 66
 		}
67 67
 
68  
-		$this->local_time = time();
  68
+		$this->local_time = $_SERVER['REQUEST_TIME'];
69 69
 
70 70
 		if (count($config) > 0)
71 71
 		{
@@ -464,4 +464,4 @@ public function parse_template()
464 464
 }
465 465
 
466 466
 /* End of file Calendar.php */
467  
-/* Location: ./system/libraries/Calendar.php */
  467
+/* Location: ./system/libraries/Calendar.php */
4  system/libraries/Session.php 100644 → 100755
@@ -656,7 +656,7 @@ protected function _get_time()
656 656
 	{
657 657
 		return (strtolower($this->time_reference) === 'gmt')
658 658
 			? mktime(gmdate('H'), gmdate('i'), gmdate('s'), gmdate('m'), gmdate('d'), gmdate('Y'))
659  
-			: time();
  659
+			: $_SERVER['REQUEST_TIME'];
660 660
 	}
661 661
 
662 662
 	// --------------------------------------------------------------------
@@ -686,7 +686,7 @@ protected function _set_cookie($cookie_data = NULL)
686 686
 			$cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
687 687
 		}
688 688
 
689  
-		$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
  689
+		$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + $_SERVER['REQUEST_TIME'];
690 690
 
691 691
 		// Set the cookie
692 692
 		setcookie(
6  user_guide_src/source/general/models.rst 100644 → 100755
Source Rendered
@@ -38,7 +38,7 @@ model class might look like::
38 38
 	    {
39 39
 	        $this->title   = $_POST['title']; // please read the below note
40 40
 	        $this->content = $_POST['content'];
41  
-	        $this->date    = time();
  41
+	        $this->date    = $_SERVER['REQUEST_TIME'];
42 42
 
43 43
 	        $this->db->insert('entries', $this);
44 44
 	    }
@@ -47,7 +47,7 @@ model class might look like::
47 47
 	    {
48 48
 	        $this->title   = $_POST['title'];
49 49
 	        $this->content = $_POST['content'];
50  
-	        $this->date    = time();
  50
+	        $this->date    = $_SERVER['REQUEST_TIME'];
51 51
 
52 52
 	        $this->db->update('entries', $this, array('id' => $_POST['id']));
53 53
 	    }
@@ -140,7 +140,7 @@ view::
140 140
 	        $this->load->view('blog', $data);
141 141
 	    }
142 142
 	}
143  
-	
  143
+
144 144
 
145 145
 Auto-loading Models
146 146
 ===================
4  user_guide_src/source/helpers/captcha_helper.rst 100644 → 100755
Source Rendered
@@ -130,7 +130,7 @@ CAPTCHA will be shown you'll have something like this
130 130
 	$this->db->query($query);
131 131
 
132 132
 	echo 'Submit the word you see below:';
133  
-	echo $cap['image']; 
  133
+	echo $cap['image'];
134 134
 	echo '<input type="text" name="captcha" value="" />';
135 135
 
136 136
 Then, on the page that accepts the submission you'll have something like
@@ -139,7 +139,7 @@ this
139 139
 ::
140 140
 
141 141
 	// First, delete old captchas
142  
-	$expiration = time() - 7200; // Two hour limit
  142
+	$expiration = $_SERVER['REQUEST_TIME'] - 7200; // Two hour limit
143 143
 	$this->db->where('captcha_time < ', $expiration)
144 144
 		 ->delete('captcha');
145 145
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.