Change server side cached variable from outside of website? - php

I'm playing with laravel/php and was using the Cache to store a specific cached variable. I wanted to avoid hitting the database for a property / setting I need all my users to rely on. This setting controls whether certain events can occur. This wasnt difficult as I could simply check if I have the cached variable and assign it otherwise get it from my backend (SQL Server):
if (Cache::has('myKey')){
$value = Cache::get('myKey');
} else {
$value = DB::table('myTable')->get();
Cache::put('myKey', $value);
}
//use cached value...
This cached value or db setting is caused by a certain action of an administrator he / she can turn this setting on (true) or off (false). However, we also have an outside process (not on the actual site but an actual sql job) that has to also set this setting. In the SQL job I can easily assign the db setting (true or false) but how do I write that setting to my cached value in laravel / php if I am inside of my sql job?
The short of this is how can I set a server side cached variable value from outside of my website?

So in that case I would either go with exposing a REST API (protected by authentication of course) that does this. Something like http://my-host/api/clear-cache.
Or ssh into the server directly and change the cache.

Related

How to set and retrieve dynamic global variables in PHP without functions

I am trying to write a simple page that will save some data to the GLOBAL state (stored in server memory) using a dynamic variable name. In simple terms, there are only two parameters that can be sent by the query string (GET only).
jam: the parameter identifying a unique piece of data, which can be virtually any text string (including numbers). This value is appended to the string "jam" to create the dynamic variable name. So ?jam=123 results in global variable jam123. Likewise So ?jam=Booboo results in global variable jamBooboo.
section: the value to which the global variable mentioned above will be set (must be numeric). So if ?jam=Booboo&section=4 is passed, the value of global variable jamBooboo is set to 4.
The idea is that once the values are set for each dynamically named jam (jamXXXX), any future requests specifying that same jam should output the set value. For instance, and requests specifying ?jam=Booboo AFTER the page is called with parameters ?jam=Booboo&section=4, should simply output "4". But if the next request is ?jam=Booboo&section=6, then subsequent requests should output "6".
This is set up on PHP7 on the AWS Lightsail LAMP Stack. I am open to using another variable scope if it will persist in Server memory (not a cookie).
I have tried the code below, but while I see the initial value properly when the global variable is SET, I do not see it output on subsequent requests. I am not sure if there is a missing setting in PHP, or if my code is off somehow. I have also tried using the global keyword and looking for a register_globals setting in php.ini (doesn't exist currently).
<?php
if(isset($_GET['jam']) == false){
// Do nothing, it's a bad request - jam is a required variable
}
else if (isset($_GET['section']) == false){
// section is not specified, so output the global value of jam if it exists
if(isset($GLOBALS["jam".$_GET['jam']])){
echo $GLOBALS["jam".$_GET['jam']];
}
}
else if (is_numeric($_GET['section'])){
// section is specified and its a number so set the global value for jam to that number and output it
$GLOBALS["jam".$_GET['jam']] = $_GET['section'];
echo $GLOBALS["jam".$_GET['jam']];
}
else{
// Do nothing, it's a bad request as none of the mandatory conditions have been met
}
?>
If I'm not mistaken, you seem to expect $GLOBALS to persist between 2 different PHP request.
Unless otherwise programmed, each PHP call would recieve its own memory space that DO NOT share with each another. So a variable saved to the $GLOBALS array will only be available to that request, and will be forgotten immediately when that request end. Subsequent call to the PHP code on the same server (even the same script file) do not received the $GLOBALS values from previous calls.
You need to program you persistent storage with files, cache service or databases.

PHP $_REQUEST server setting

I'm currently in the process of migrating servers.
My old server accepted GET/POST variables without defining them, for example:
$model_id = $model_id;
But on my new server, variables needs to be defined, eg:
$model_id = $_REQUEST['model_id'];
I'm trying to save time without having to rewrite all existing scripts, is there a quick solution?

Define php variable at php initialization

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

Saving variables (not sessions)

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 !

In PHP what is the right approach for loading configuration parameters into application variables?

I have a database where I keep my configuration parameters, I want to load the configuration parameters into my application variables only once (or upon specific request to reload the parameters), I also want these variables which holds the configuration parameters to be accessible from all php pages/scripts, the idea is to save hits on the database and improve the application response time.
What is the 'classic' php solution to this matter?
It seems to me that this is essentially the same as any other caching question. The fact that the content to be cached is configuration parameters rather than say the content of Web pages or user profile information is unimportant from a technical perspective.
So what you have to do is come up with some caching solution, whether it's memcached or just writing static files with the data you want to cache.
The trick here is that you're not caching HTML to be presented to the user but rather database query results, so you'll probably want to look at approaches like this one:
http://devzone.zend.com/article/1258
I like using the Zend_Config_Ini class. Creating separate sections that can extend others is easy, and with Zend_Cache with Zend_Cache_Frontend_File (to check for updates to the .ini file) and a backend (I use APC) that is particularly fast to access to avoid any overhead of re-parsing.
; Production site configuration data
[production]
webhost = www.example.com
database.adapter = pdo_mysql
database.params.host = db.example.com
database.params.username = dbuser
database.params.password = secret
database.params.dbname = dbname
; Staging site configuration data inherits from production and
; overrides values as necessary
[staging : production]
; 'database.adapter' is inherited
; others are overridden
database.params.host = dev.example.com
database.params.username = devuser
database.params.password = devsecret
Make a page that sets constants (key word 'define') early in your routines. Just include it wherever needed.
Like Smandoli's answer, I use a single file that has my configuration.
However, my configuration is actually a multi-dimensional array - meaning I have much greater control over my config - I can change it on the fly if I need to, as well as breaking up the varialbes.
$config['error']['nologin'] = "You're not logged in";
$config['db']['host'] = "localhost";
$config['something']['else'] = "hello world";
Edit: I use a file for values that do not change too much. I do use variables from a database occasionally, but not too often.
My rule of thumb is "If the user doesn't need to change it, load from the file; if they need to change it, then it comes from a database".
I came from the world of C++ the paradigm there was to use a singleton which load the parameters on first (and only) instantiation and export an interface with relevant get'ters (like 'int GetVal(char* key,int &val)' ) the singletone was accessible from all parts of the application, is there anything like that in PHP?

Categories