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
Related
I have to read a file and do some computation, than save the result of this computation inside a variable.
I just need to do this once. In Java + Servlet I can do this using a servlet container and, for instance, the singleton pattern.
I know that in PHP I can't act like this. Which is the better way to do this? Save the computation (or transfer the data) on DB?
No, it won't work like with Java Servlets. You'll have to find a workaround.
First, I assume that using $_SESSION, $_COOKIE or $_REQUEST in general isn't practicable to you as you want to save the state per server (or per application) and not per 'User Session'.
Using a database sounds practicable in your case. In a regular application design it will be the most common solution.
Also you can do something like this, using the serialization capabilities of PHP:
<?php
$resultfile = 'result.dat';
if(!file_exists($resultfile)) {
$result = compute_result('foo bar');
file_put_contents($resultfile, serialize($result));
} else {
$result = unserialize(file_get_contents($resultfile));
}
Using PHP's serialize() attempt is especially practicable when
You are in a PHP only environment
$result is a complex datatype but you don't want to create a database structure and map $result too it
If you are not in a PHP only environment you might prefer other serialization formats as JSON or XML.
Also the serialization result can be stored as a string in a database instead of a file. Saving it to a database instead of a file would make the application more scalable as the result would be available to all servers that access the same database (cluster).
In short: I would suggest using a database maybe combined with serialization.
i have a query that, how can i transfer an object from php file A to php file B?.
but i know a solution using session.But what i need to know is, is their any other method to transfer object between php files other than session?
APC is probabaly the easiest method:
example:
// new object
$object = new ClassName('Kieran', 123);
// Store it
apc_store('object', $object);
The other script
$obj = apc_fetch('object');
print_r($obj->method());
Save in a file, save in a database, save in shared memory, save in a cache server.
One way is to store the serialized object - or its data - into a database, using the session ID as the key to "find" it again.
The same could be done using a cache file.
A faster way is using a shared memory cache like memcache. These solutions always require server-side administration and root access to set up.
you can use this method:
serialize() and unserialize()
fileA.php :
<?php
require_once 'employee.class.php';
$employee=new employee($id,$firstname,$lastname);
$serializeemployee=serialize($employee);
session_start();
$_SESSION['employee']=$serializeemployee;
header('location: ./fileB.php');
?>
fileB.php :
<?php
session_start();
if(isset($_SESSION['employee']) && $_SESSION['employee'])
{
require_once 'employee.class.php';
$employee=unserialize($_SESSION['employee']);
echo $employee->getFirstname();
?>
Serialize the object and store in one of the following (Database,Temp,Memcache).
Depending on what the object consists of i would take a look at implementing the __sleep and __wake magic methods to make sure the object is able to be transferred correctly.
by using cURL you can transfer any thing... try this..
http://php.net/manual/en/book.curl.php
The easiest way (besides using sessions) is probably to save it as an APC (Alternative PHP Cache) user variable, as you probably will install APC for opcode caching purposes already. This way you have one extension for two things.
APC stores values inmemory as Memcached does, but is way easier to install, because it's not an extra daemon running, but a PHP extension.
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
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?