I can't seem to find the MemcacheD extension for PHP.
There are a few compilations of php_memcache.dll, but that's not the same.
The main thing I'm missing is getMulti(), which doesn't exist in Memcache.
So far I found this, but there's no DLL:
http://pecl.php.net/package/memcached
Officially - it does not exist. There are several people who have created their own DLL's though. Here is one person's blog who has created the dll:
http://trondn.blogspot.com/2010/07/libmemcached-on-win32.html
Here is a link to the repository with the source so you can build your own DLL for memcached:
http://bazaar.launchpad.net/~trond-norbye/libmemcached/mingw32/files
I know the memcached has some other features but its interface is nearly identical with that of memcache extension. You can very easily get away with such code and in my case it works perfectly well. If you don't have the memcached loaded create this file:
<?php
class Memcached {
const OPT_LIBKETAMA_COMPATIBLE = true;
const OPT_COMPRESSION = true;
const OPT_NO_BLOCK = true;
//if you code relies on any other constants define them to avoid
//undefined constant notice
//http://www.php.net/manual/en/memcached.constants.php
public $_instance;
public function __construct() {
$this->_instance = new Memcache;
}
public function __call($name, $args) {
return call_user_func_array(array($this->_instance, $name), $args);
}
public function setOption() {}
}
Either include it or configure autoloader to pick it up.
Of course you'll need a properly configured memcache instance and addServer calls but such calls should already be in the code if the codebase assumes Memcached.
I hope it helps someone/
Related
I want to implement the threading concept in CakePHP 3.0 ,
But when I try to extend the thread class, it gives an error of "Thread class not found"
I have also implemented it in core php and its working as expected,
But somehow its not working with cakephp.
Here is the corephp code
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = rand(1,60);
for ($i=0; $i < 100 ; $i++) {
sleep(1);
echo $this->arg."----------->".$i."<br/>";
}
}
}
}
class CallingClass {
public function runScript($var)
{
print_r("start run script");
$th = new AsyncOperation($var);
$th->start();
print_r("continue running");
}
}
$wow = new AsyncOperation("First");
$wow->start();
$wow2 = new AsyncOperation("Last");
$wow2->start();
?>
And in CakePHP 3
class AsyncOperation extends Thread
You want to learn about namespaces in php. Cake and almost every lib these days uses them. You need to use the use keyword and import the class from another namespace if it does not exist within the namespace your current class is in. Or, not really best practice, provide the absolute namespace.
Also I'm not sure what you try to do, but instead of threads I would recommend to take a look at work queues likes RabbitMQ or ZeroMQ.
Your php version doesn't have the thread class. By default, if you install it on LINUX, you won't have the thread class.
You need to download the php source code, enable the zts and then compile it.
This is how I did on linux:
Enable zts on redhat - pthreads on php
Just add simple line
use Thread;
I've been searching and reading a lot about how is the best way (code-wise) to get application's config variables in a PHP environment. After that I've sum up that are two more generally used ways to manage with configuration files and variables.
But I'm a bit confused about it, one, method 1, is using an static class. The other one, method 2 is using an instantiable class.
First one is worse to unit testing than second one. And It's similar to a global variable. Isn't it?
Second one need a global varaible in order to use instantiated object.
I'll try to explain myself.
Facts:
- App's settings are kept on a INI file.
- This INI file has sections, in order to maintain configuration variables.
- I've got only one INI file.
- Class do some validation of configuration file.
- Code examples below aren't complete, it's only a sample to ilustrate my question.
Method 1: Using static class
This method use a Config static class, it uses static because only one Config object would be used in all application.
Code example:
class Config
{
static private $data;
static public function load($configFile) {
self::$data = parse_ini_file($configFile, true, INI_SCANNER_RAW)
}
static public get($key) {
// code stuff to deal with sections and keys, but basically
return self::$data[$key];
}
}
On my application I create the static object, once, using this code:
\Config::load('/where/is/my/ini/file.ini');
In this case, every time i want to get a value i use:
$host = \Config::get('database.host');
function example()
{
echo \Config::get('another.value');
}
Method 2: Using instable object
In this scenario I use a Config class object.
Code example:
class Config {
private $data = array();
public function __construct($configFile) {
$this->data = parse_ini_file($configFile, true, INI_SCANNER_RAW)
}
public function get($key) {
// code stuff to deal with sections and keys, but basically
return $this->data[$key];
}
public function __get($key) {
return $this->get($key);
}
}
To use it, first we need to instantiate an object and then get the value:
$settings = new \Config('/where/is/my/ini/file.ini');
$host = $settings->get('database.host');
echo $settings->database->host;
But when I need this value inside a function, I need to use a global variable, which I think isn't right at all:
global $settings;
$settings = new \Config('/where/is/my/ini/file.ini');
function example()
{
global $settings;
echo $settings->get('another.value');
}
What I miss leading?
Thanks in advance to read and answer my question.
Simply you may also use a php file to keep your configurations for example, config.php and then you may use require from anywhere to get it:
// config.php
<?php
return array(
'database' => 'mysql',
'pagination' => array(
'per_page' => 10
)
);
Then use:
$config = require "path/to/config.php";
print_r($config);
You may use this with a function too, for example:
function someFunc()
{
$config = require "path/to/config.php";
// Now use it
}
You may create a class to get the the configurations using a method like, for example:
class Config {
static function get()
{
$config = require "path/to/config.php";
return $config;
}
}
So you may use:
$config = Config::get();
This is just another simple idea, you may extend it to use it like:
$perPage = Config::get('pagination.per_page');
Just need to add some more code to make it working like this way, give it a try.
Update:
Btw, I built a package named IConfig for my own MVC Framework back in 2013, it's also available on Packagist. You may use it or check it's source code, maybe you'll get better idea and can build a better one. But probably there are a lot better ones available on the web as well.
I think the problem you're trying to solve isn't really specific to PHP and either of the two techniques you've described could be viable ways to handle global configurations.
Having said that, I agree with Rangad, the solution is to use Dependency Injection. At it's simplest this pattern just means passing dependency's to a class/object/function as arguments. For example,
class Thing () {
private $host = '';
function __contructor($host) {
$this->host = $host;
}
function getHost()
{
echo $this->host;
}
}
$thing = new Thing( Config::get('database.host') );
$thing->getHost();
$thing2 = new Thing (Config::get('someOtherDatabase.host') );
$thing2.getHost();
This encapsulates your classes. Now they can be used in tests or even other applications so long as the needed dependences can be provided.
The nice thing about this is that you can use it with either of your proposed config options and probably others. For example if you're looking for something simple there's Pimple, a PHP Dependency Injection container written by the creator of the Symphoy PHP framework that in my opinion is great for smaller PHP projects http://pimple.sensiolabs.org/.
When such situation occurs?
If your are using shared memory and semaphores for interpocess locking (with pcntl extension) you should care about semaphore and shared memory segment life circle. For example, you writing backgroud worker application and use master and some child (forked) process for job processing. Using shared memory and semaphores good idea for IPC between them. And RAII like class wrapper around shm_xxx and sem_xxx php functions look`s like good idea too.
Example
class Semaphore
{
private $file;
private $sem;
public function __construct()
{
$this->file = tempnam(sys_get_temp_dir(), 's');
$semKey = ftok($this->file, 'a');
$this->sem = sem_get($semKey, 1); //auto_release = 1 by default
}
public function __destruct()
{
if (is_resource($this->sem) {
sem_remove($this->sem);
}
}
....
}
Not the good choise - after fork we have one instanse in parent and one in child process. And destructor in any of them destroy the semaphore.
Why important
Most of linux systems has limit about semaphore of shared memory count. If you have application which should create and remove many shared memory segfments of semaphores you can`t wait while it be automatically released on process shutdown.
Question
Using с you can use shmctl with IPC_RMID - it marks the segment for removal. The actual removal itself occurs when the last process currently attached to the segment has properly detached it. Of course, if no processes are currently attached to the segment, the removal seems immediate. It works like simple referenc counter. But php do not implements shmctl.
The other strategy - destroy semaphore only in destructor of master process:
class Semaphore
{
...
private $pid;
public function __construct()
{
$this->pid = getmypid();
...
}
public function __destruct()
{
if (is_resource($this->sem) && $this->pid === getmypid()) {
sem_remove($this->sem);
}
}
....
}
So, the questions is
If any way to use IPC_RMID in php?
What strategy should be used in such cases? Destroy in master process only? Other cases?
I checked the current PHP source code and IPC_RMID is not used. However, PHP uses semop() and with it, the SEM_UNDO flag, in case auto_release (see PHP sem_get() manual) is set. But be aware that this works on a per process level. So in case you are using PHP as Apache module, or FCGI or FPM, it might not work as expected. It should work nicely for CLI, though.
For your cleanup, it depends on whether the "master" terminates last or not.
If you do not know, you can implement reference counting yourself.
class Semaphore
{
static private $m_referenceCount = 0;
public function __construct()
{
++self::$m_referenceCount;
// aquire semaphore
}
public function __destruct()
{
if (--self::$m_referenceCount <= 0) {
// clean up
}
}
}
But be aware that the destructor is NOT executed in some circuumstances.
I'm playin' around with zend framework 1.11 and mongo. I've decided to use Shanty_Mongo as a library to easy couple Zend and Mongo, but I'm stuck in this exception:
Can not save documet. Document is not connected to a db and collection
This is the code in the controller:
public function indexAction()
{
try {
$guestbook = new Application_Model_Guestbook();
$guestbook->setComment('Commento di prova')
->setEmail('info#example.net')
->save();
$all_elements = Application_Model_Guestbook::all();
$this->view->entries = $all_elements;
} catch (Exception $exc) {
echo $exc->getMessage();
}
}
This is (part) of the model:
class Application_Model_Guestbook extends Shanty_Mongo_Document
{
protected static $_db = 'test';
protected static $_collection = 'user';
protected $_comment;
.....
Shanty is in my library folder, and in application.ini i've added it:
resources.view[] =
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
autoloaderNamespaces[] = "Shanty"
On Shanty-Mongo docs, it's reported that
"If you are connecting to localhost without any authentication then no need to worry about connections any further. Shanty Mongo will connect automatically on the first request if no connections have previously been added."
but this does not happen.. I really can't guess why.
Obviously, mongo is running, since if i use php Mongo() i can access it and perform insertions, etc...
I'm running the latest version of mongo, zend on php 5.3.6 on osx 10.6.8
Thanks!
Your model should be like this
class Application_Model_Guestbook extends Shanty_Mongo_Document
{
protected static $_db = 'test';
protected static $_collection = 'user';
protected static $_requirements = array('comment'=>'Required')
I think you may want to switch that autoloaderNamespaces[] = "Shanty" line to be:
autoloaderNamespaces[] = 'Shanty_Mongo'
Other than that it looks OK....
That's an odd error message. Notice it doesn't say "unable to connect to MongoDB" or similar. It says that this document isn't connected to a collection. It sounds like a configuration issue to me.
In other areas of your code are you able to connect to the database?
Read from the database?
Allesio,
the element that both you and Adam C have put on the autoloaderNamespaces array are not quite correct. Try the following:
autoloaderNamespaces[] = "Shanty_"
You only need to put the top-level prefix followed by an underscore. Please let me know if this doesn't resolve the situation. Also, I've not seen that error message before. For sure, if you have a local install of mongoDB running, you won't need to specify any authentication parameters.
If the collection doesn't exist, Shanty will create it and if the document doesn't exist, Shanty will create that as well.
What operating system are you using?
I had a number of troubles with the package in the Ubuntu repositories. However, adding the 10gen repository in to apt and installing the latest stable version helped me out. Though even that seems to crash periodically.
Try adding this to Bootstrap.php:
protected function _initMongoDB() {
$connection = new Shanty_Mongo_Connection('mongodb://localhost:27017');
Shanty_Mongo::addMaster($connection);
}
I have read a lot of articles on developing classes (I am using php), with the tag lines :
'scalable, robust, maintainable and extensible'.
But as a beginner, I have been creating classes that are, in my words, "just abstracted". Meaning I just separated a bunch or repetitive codes and put them in a class and provide methods for accessing common tasks.
The thing is, I can't find a way to make my class extensible (I know the concept of abstract classes and such, I am even using them, but just to define methods that my other classes will follow). The thing is, I always find myself editing the core class just to add functionlities.
Any tips on making my class extensible? (I have googled on this and everything that pops out are explanations of abstract classes, interfaces and OOP, no discussions on pointers or some tips for making extensible classses).
Oh, btw, go easy on me, I have started "actual" oop programming 9 mos ago (the university I'm from had me going on theories on OOP, but they had us working PROCEDURALLY, because it's faster and it meets damn project deadlines, and that went on for 4 years until I graduated).
You should check out the book Design Patterns: Elements of Reusable Object-Oriented Software
The problem with making extensible classes, as you've discovered, is decomposing the system into useful and reusable objects.
The task is difficult because many factors come into play: encapsulation, granularity, dependency, flexibility, performance, evolution, reusability, and on and on.
Are you trying to model some real world scenario, or are you focusing on communication / collaboration and dependencies inside your application?
Here's an example that I think kinda demonstrates what you are looking for. There are certainly a far more, far better examples:
I wanted to develop a caching system that offered my developers a simple, normalized API no matter what / where they were caching something. What do I want in a caching system (at the basic level)?
I want to be able to cache something (set)
I want to be able to retrieve that something (get)
I want to be able to invalidate the cache (delete)
I came up with this:
abstract class MyNs_Cache
{
abstract public function Set($key, $data, $ttl);
abstract public function Get($key);
abstract public function Delete($key, $ttl);
}
There's my extensible base class. I've then got three caching classes MyNs_Cache_Fs, MyNs_Cache_Apc and MyNs_Cache_Memcache
class MyNs_Cache_Fs
{
...
public function Set($key, $data, $ttl)
{
// here I use fopen/fwrite/etc. to create the cached data
}
public function Get($key)
{
// here I retrieve the file from the filesystem (if it exists)
}
public function Delete($key) { ... }
}
That's fairly straight forward. It implements the cache in terms of a FileSystem. It doesn't offer anything past my original class.
class MyNs_Cache_Apc
{
...
public function Set($key, $data, $ttl)
{
return apc_add($key, $data, $ttl); // NOT A FILESYSTEM CALL
}
public function Get($key) { ... } // you get the idea.
// This is specific to APC, so I add the functionality HERE
// NOT in my main Caching class.
public function PurgeCache()
{
return apc_clear_cache();
}
}
My APC cache does everything I want in a caching system (set/get/delete) but it also offers the ability to clear the entire cache (something that's not useful for my FileSystem cache and impossible with memcached)
class MyNs_Cache_Memcache
{
// Memcached needs a pool of servers. APC and filesystem don't.
private $servers = array(..);
// It also uses a memcached object.
private $conn;
public function __construct()
{
$this->conn = new Memcached;
foreach ($this->$servers as $server)
$this->AddServer($server);
}
... // we do all the standard stuff using memcached methods
// We also want to be able to manage our connection pool
public function AddServer($server)
{
$this->conn->addServer(...);
}
// And in some cases, we use inc/dec from memcached
// APC doesn't have this, and it makes little sense in a filesystem
public function Increment($key) { ... }
}
Now I know that I can always get one of my cache objects and just in with $obj->Get('some_key') and I'll always get a result.
Likewise, I also have access to functionality specific to what I'm currently trying to work with.
You don't need to edit your core class to add functionality you can overwrite a method in a child class, eg:
class A {
public function filter_string($str){
return str_replace ('foo', 'bar', $str);
}
}
class B extends A {
public function filter_string($str){
return str_replace ('machin', 'chose', parent::filter_string ($str));
}
}
$a = new A;
echo $a->filter_string('foo machin'); // echoes 'bar machin'
$b = new B;
echo $b->filter_string('foo machin'); // echoes 'bar chose'