I have a problem.
In my project I have few servers which modify same data in redis.
All the servers may have different time.
In other words, I can't rely on app server time in some cases.
So I would like to use Redis time as general base point.
Everything could be fine, PHPRedis documentation says there is a function which does exactly what I need: time().
But here is a BIG surprise:
//... create connection etc...
var_dump($redis->time());
Output is:
bool(false)
The question is - what the hell is this?
Have you ever faced such a problem?
How can I get redis server time using it's functions?
Note: other redis functions work fine, I am able to read and write data. Connection is ok and is created correctly.
Got no help here.
As well as anywhere else.
So I needed to invent a walkaround...
Here is it, if someone needs it.
// Generate unique temporary key
$key = uniqid() . time();
// Take some random future TS
$future_ts = time() + 1000;
$redis->setex($key, time(), 5);
$redis->expireAt($key, $future_ts);
// This variable now contains what I need
$redis_ts = $future_ts - $redis->ttl($key);
Related
I implemented a login functionality using Google Plus API. It was working fine until we moved the deployment timezone. The problem below started appearing from time to time even though the server time has been adjusted properly:
Cannot handle token prior to 2018-02-01T06:30:07+0000
This was implemented in PHP and using the SDK for Google Plus. Has anyone encountered this before and resolved it properly?
This worked for me as well. I had to go into my vendor folder that composer generates for me in vendor\google\apiclient\src\Google\AccessToken\Verify.php and look for a function getJwtService() which should look exactly like this
private function getJwtService()
{
$jwtClass = 'JWT';
if (class_exists('\Firebase\JWT\JWT')) {
$jwtClass = 'Firebase\JWT\JWT';
}
if (property_exists($jwtClass, 'leeway')) {
// adds 1 second to JWT leeway
// #see https://github.com/google/google-api-php-client/issues/827
$jwtClass::$leeway += 1;
}
return new $jwtClass;
}
Then I changed the value of the $jwtClass::$leeway += 1; to $jwtClass::$leeway += 200; due to my timezone. I was about 2mins 30 seconds behind. Beware this comes with security vulnerabilities.
While the answer provided by richard4s works well but it's not a good practice to edit files in vendor directory as they are created by composer and would typically be outside your project's Git/Svn repo. The Google_Client accepts custom jwt object as a parameter to it's constructor. So here's a proper way to fix this:
$jwt = new \Firebase\JWT\JWT;
$jwt::$leeway = 5; // adjust this value
// we explicitly pass jwt object whose leeway is set to 5
$this->client = new \Google_Client(['jwt' => $jwt]);
Copied from this article.
This error appears to occur when the server's clock is a few seconds behind Auth servers clock. You probably have a slight skew between the clock on the server that mints the tokens and the clock on the server that's validating the token if the iat or nbf is in the future, then the token isn't yet valid.
One solution would be to use a small leeway, like this:
JWT::$leeway = 5; // Allows a 5 second tolerance on timing checks
see issue 1172
I'm currently coding one of my first php applications.
The application has to connect to a LDAP server and change some user attributes in the directory.
That application has some parameters to read in a mySQL Database in order to run.
Some examples of these parameters could be:
-LDAP Address
-LDAP Service Account
-LDAP Password
there are much more parameters, which rule, for example, the way users authenticate to my application,...
Currently, the database is read at each user session initialization, but, it doesn't have any sense because parameters do not vary from a session to another.
So, i'm looking for a way to load these parameters from the database, only one time (for example, at the php service initialization), and access to these parameters in the "normal" php code through variables.
What would be the best way to do this?
Thank you in advance.
You are looking for a persistent cross-request storage. There are many options for this.
The simplest is APCu (which can be used in conjunction with Zend OpCache, or for PHP < 5.5, APC).
Simply:
if (apc_exists('mykey')) {
$data = apc_fetch('mykey');
} else {
// create it from scratch
apc_store('mike', $data);
}
$data can be most any PHP type, arrays, objects, or scalars.
You can even put this code in the auto_prepend_file INI setting so it is run automatically on every request.
However: this is per server (and per SAPI, so mod_php/php-fpm/cli don't share the cache) so you will have to create it once per server.
Alternatively, for a multi-server setup you can use something like memcached or redis. These are stand-alone daemons that will let you store arbitrary key/value pairs of string data (so you may need to serialize()/unserialize() on the values).
I personally prefer memcache, which has two extensions for PHP, pecl/memcached and pecl/memcache (I prefer pecl/memcached, it has more features).
Both of them are pretty simple.
pecl/memcached:
$memcache = new Memcached();
$memcache->addServer('localhost', '11211');
$data = $memcache->get('mykey');
if (empty($data)) {
// Create data
$memcache->set('mykey', $data);
}
pecl/memcache:
$memcache = new Memcache();
$memcache->connect(); // uses localhost:11211, the default memcache host/port
$data = $memcache->get('mykey');
if (empty($data)) {
// Create data
$memcache->set('mykey', $data);
}
Both extensions support storage of arrays and objects without serialization.
You can of course store multiple keys with any of these solutions and just pull them all, instead of using one, or one with an array/object.
You can use Memcache do cache database requests. See here how to use.
Another way is using Php Sessions.
<?php
session_start(); // need to be before any html code
$_SESSION['something'] = 'Something here...';
echo $_SESSION['something']; // will show "Something here..."
And you can remove using...
unset($_SESSION['something']);
You also can use cookies, using the function setcookie. See here.
And you can get cookies using...
echo $_COOKIE['something'];
Production mode
In a production mode, this will work as set_transient of Wordpress. You will do the first db request to get the value and will cache this value using cookies, sessions or memcache.
If you want to show this values inside of your page, you can use a standard caching library.
My understanding of the question is that you have some SQL data that is more or less constant and you don't want to have to read that in from the SQL connection on every request.
If that is the case you can use memcache to store the data:
http://php.net/manual/en/book.memcache.php
The data will still be persistent and you will only need to go to the database if the cached data isn't there or needs to be refreshed.
If the data is specific to a particular user you can just use a session.
http://php.net/manual/en/book.session.php
http://php.net/manual/en/session.examples.basic.php
If this is only to be used when starting up your server (so once and done) and you don't want to bother to with memcached/xcache (as they would be over kill) you can still use environment variables. See get_env
I am fairly new to php.
I have a text file on my computer which changes the content frequently. I want to get the content of the file as soon as it is changed and insert it to an html form.
I wanted to use the filemtime function on php but I didn't know exactly how to do it. I did put a do while loop :
$oldtime=filemtime($filename);
$newtime = $oldtime;
do {
sleep (1);
$newtime = filemtime($filename);
echo "old: $oldtime"."<br />";
echo "new: $newtime";
}
while ($newtime == $oldtime);
but this will keep executing. I did also try to do some if statements but this also won't work on my side.
Can you please suggest any way to do this ? If there is any other functions that may help ?
thank you for looking at this thread
Switch your assignment to a comparison (= for ==) to correct the bug in your code.
There may be more of a problem here, though. Files are not the best of places to store information, when you want to know if it's changed.
Ideally, you'd put the information that's being saved in that file inside of a database, where you can use fun things like triggers to let you know if data has changed. Otherwise, your solution will be wasting clock cycles trying to test the file endlessly for changes, which isn't very efficient
Your condition in the while is logically incorrect. You are doing an assignment
$newtime = $oldtime
it should be a comparison:
$newtime == $oldtime
It keeps executing because you are assigning rather than comparing.
This:
while ($newtime = $oldtime);
Should be this:
while ($newtime == $oldtime);
Polling the file frequently is kind of a crappy way to publish updates.
Why not just have a php script at the end point of the HTTP request which formats the source data (optionally caching it, if the source file is remote). Or using inotify to trigger the generation of a static file?
This may be a silly question, but how do I save variables that are not specific to a particular session. An simple example of why you might want to do this would be a visitor counter - a number that increases by one each time someone visits a web page (note - I'm not actually doing that, my application is different, but that is the functionality I need). The only ways I can think of doing this are either writing the variables to a file, or putting the variables into a database. Both seem a bit inelegant. Is there a better way to to this kind of thing?
If you need to save global state, you need to save global state. This is typically done in either a file or a database as you already noted.
It's not "inelegant" at all. If you need to save something (semi-)permanently, you put it in a database. That's what databases are for.
Have a look at the serialize() function in PHP http://uk3.php.net/serialize where you'll be able to write an array or such to a file and re-retrieve:
<?php
// Save contents
$var = array('pageCounter' => 1);
file_put_contents('counter.txt', serialize($var));
// Retrieve it
$var = unserialize(file_get_contents('counter.txt'));
?>
Otherwise save the value to a database.
Given that PHP is stateless and that each pageload is essentially re-running your page anew, if you're going to be saving variables that will increment over multiple pageloads (e.g., number of distinct users), you'll have to use some form of server-end storage - file-based, database, whatever - to save the variable.
You could try installing APC (Alternative PHP Cache) which has cool features for sharing data between all PHP scripts, you could try using shared memory too or like you said, use a file or database
I think I've found the answer - session_name('whatever') can be used to have a fixed name for a session, I can refer to that data as well as the session specific session.
If you want it to be permanent, database and files are really your only two choices.
If you only want to temporarily store these values in memory, if APC is installed, you can do this:
// Fetch counter value back from memory
$success = false;
$counter = apc_fetch('counter', &$success);
if ($success) {
// fetch succeeded
} else {
// fetch failed
$counter = 0;
}
// Increment the counter and store again
// Note that nothing stops another request/page from changing this value
// between the fetch and store calls.
$counter++;
apc_store('counter', $counter);
That was just an example.
For a counter, you're better off using apc_inc('counter') / apc_dec('counter').
Presumably other opcode caches have similar methods. If you're not running an opcode cache... really? You want PHP to recompile a page every time its requested?
Elegant, no database and no file ?
Store it in your server memory with shmop and hope your server does not reboot !
My Google-fu hasn't revealed what I'm looking for, so I'm putting this one out to the crowd.
Coming from an ASP.NET development background, I'm used to having the Application and Cache collections available for me to stash rarely-modified but often-used resources (such as lookup rows from a database or the contents of static XML documents) in the memory of the web server, so I don't have to reload these often-used items during every request.
Does PHP have an equivalent? I've read up briefly on the memcache extension, but this won't work for me (as I don't have control over the server configuration.) I'm tempted to implement something that would allow me to pre-parse or pre-select the resources and generate a sort of PHP cache "file" that would construct the cached object from literals stored in the file, but this seems like a very hacky solution to me.
Is there something in PHP (or, alternatively, a helper library of some sort) that will allow me to accomplish this using best practices?
In short, no, such a thing is not available natively in PHP. To understand why, you have to understand that PHP has its entire environment built for each request, and it is subsequently torn down at the end of the request. PHP does give you $_SESSION to store per session variables, but after digging into the docs you will see that that variable is built during each request also. PHP (or mod php to be more specific) is fundamentally different from other "application servers". Basically, it is not an application server. It is a per request script runner.
Now, don't get me wrong, PHP lets you do application level data store, but you will have to go to a database, or to disk to get it. Remember this though, don't worry about optimizing for performance until it is shown that preformance is a problem. And I will guess that 99 times out of 100, by the time performance is an issue that isn't due to some poor code you wrote, you will have the resources to build your own pretty little memcached server.
Take a look at Zend_Cache library, for example. It can cache in multiple backends.
This is a bit of a hack but but works in php 7+
Basically you cache your data to a temp file and then use include to read the file, which is cached in memory by the php engine’s in-memory file caching (opcache)
function cache_set($key, $val) {
$val = var_export($val, true);
// HHVM fails at __set_state, so just use object cast for now
$val = str_replace('stdClass::__set_state', '(object)', $val);
// Write to temp file first to ensure atomicity
$tmp = "/tmp/$key." . uniqid('', true) . '.tmp';
file_put_contents($tmp, '<?php $val = ' . $val . ';', LOCK_EX);
rename($tmp, "/tmp/$key");
}
And here’s how we “get” a value from the cache:
function cache_get($key) {
#include "/tmp/$key";
return isset($val) ? $val : false;
}
from https://medium.com/#dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad