Using Memcache Directly in Laravel 5 instead of using through Cache - laravel

I am using local memcache server for storing values. It works fine if I go through defining Memcache as selected driver for Cache. in config/cache.php However, if I use memcache outside laravel the memcache accessing is much faster than within Laravel controllers using Cache::get( ).
I need to store decent amount of data in Memcache and will be accessed across the system. So I was trying to use memcache directly but I am getting Following error.
[2016-08-23 14:11:19] local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Class 'App\Http\Controllers\Memcache' not found in....
My Code is as following :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Cache;
use stdClass;
use DB;
use Memcache;
class InternalCommunication extends Controller
{
public function update_stock_prices_memcache()
{
echo "\n before the memcache obj creation ".microtime(true);
$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");
//$res1 = $memcache->set('key1',"Some value 2");
$res1 = $memcache->get('key1');
.....
Just to be clear - memcache packages are installed and working fine, as I could get it working via Cache: as well as directly accessing memcache from outside Laravel installation.
Appreciate any sort of help I can get.

As per laravel cache docs, you need to set memcached configuration in config/cache.php, and specify driver to use as "memcached".
Then, simply use \Cache as below example.
// to get value
$value = \Cache::get('key');
// to set value
$minuts = 30;
\Cache::put('key', 'value', $minutes);
You could also specify driver on your code if have multiple caches
$value = \Cache::store('memcached')->get('key');

I was able to figure out the required changes needed to access the memcache within Laravel. Following is the code that is working smoothly for me now.
use Memcached;
....
$memcache = new Memcached;
$memcache->addServer('localhost', 11211) or die ("Could not connect");
$res1 = $memcache->get('key1');
....
This is definitely faster than Cache::get using memcache driver!

Related

Get `LoggerInterface` instance in Laravel >=5.6 (replacement for `Log::getMonolog()`)?

I am using a 3rd party library that provides a constructor which expects an instance of Psr\Log\LoggerInterface. The constructor in that code looks like:
public function __construct(
$configuration = null,
\Psr\Log\LoggerInterface $logger = null
)
{
In my Laravel 5.5 application I had written a service provider to set up that library for me, and I got access to a LoggerInterface for it by using Laravel's Log::getMonolog():
$connection_manager = ConnectionManager::factory(
config('the_lib_config'),
\Log::getMonolog()
);
With the changes to logging that took place in Laravel 5.6, however, the method getMonolog has gone away. I understand why this method isn't there now, but I'm wondering what the prescribed method is to get what this class needs so that it can log in context of the Laravel app (with all the new Laravel logging goodness).
My Google-Fu got stronger throughout the day, and I found the answer I was looking for in a response by #ermyril at https://laracasts.com/discuss/channels/laravel/getting-laravels-logger-instance?reply=530098
The answer is:
\Log::getLogger();

Testing multiple databases in Laravel with phpunit

In my application I have tests that use Sqlite and seeding to cover my functionality. So my phpunit env value is set to:
<env name="DB_DEFAULT" value="sqlite" />
However, I'd also like a small subset of my tests to look at my current db data. So within 1 test file, connect to my MySQL connection.
The reason for this is I want to check if we have images for all the records in one of my tables, so the test needs to access the latest data, dummy data would not help in this case.
I presumed I could just connect using the following:
$pdo = DB::connection('mysql')->getPdo();
However, the test only connects if I specify "sqlite" here, which is the name of my sqlite connection.
The testing I want to do is not based on a Model, so I don't want to have a solution built into my Model file, I'd like to switch database just in this 1 test file if possible.
How do I configure a small number of tests to use a different database connection, the existing MySQL connection?
So, the reason why I could not connect was because there were no DB_ values in my .env.testing file. The mysql connection was then using the Laravel config defaults so the connection did not error.
.env.testing
DB_DEFAULT=mysql
DB_HOST=database
DB_NAME=my_database_name
DB_USER=root
DB_PASS=root
Adding the lines above got everything working and now my test file can access the current local database.
public function __construct()
{
$this->imgPath = dirname(__FILE__, 3) . '/public/images/';
}
public function testImages()
{
$items = DB::connection('mysql')
->select(DB::raw('SELECT image_filename FROM items')
);
foreach ($items as $item) {
$this->assertFileExists($this->imgPath . $item->image_filename . '.jpg');
}
}

laravel: get name of active log at runtime

I need to know the name of the current log in an app Laravel 5.
Try search for this on Iluminate\Log\Writer.
Only see $path var on call to some functions, but I don't understand how to get this value.
Basically, I need to compress the file and send it if the app gets some exceptions. For this, I need to know the name of active log.
My app conf log for daily rotation and see name of logs such laravel-2016-04-29.log
I know the name using PHP, but I imagine it is possible to know using the Log class itself.
The best I've thought
use Carbon\Carbon;
...
$carbon = new Carbon();
$log = storage_path().'/logs/laravel-'.$carbon->toDateString().'.log';
I think there is a better way
I happened to dig a little bit into Laravel logging a few days ago and possibly have a solution for you.
Log::info('abc');
foreach (Log::getMonolog()->getHandlers() as $handler) {
$stream = $handler->getStream();
if ($stream) {
$meta = stream_get_meta_data($stream);
echo $meta['uri'] . "<br/>";
}
}
This will output paths of log files that have been written to.
Otherwise getStream() will return null and therefore path cannot be extracted so easily. It is stored in url property of Monolog\Handler\RotatingFileHandler, unfortunately protected, therefore you would need to extend this class to get the path.

Selective cache clearing from models with sfMemcache

I have a multilingual site (culture depends on the host URL eg.: uk.site.com, fr.site.com etc.). I'm caching a partial in the frontend and set its cache key. Then from the model I do something like:
$cacheManager = sfContext::getInstance()->getViewCacheManager();
$cacheUri = $cacheManager->getPartialUri($module, $action, $cacheKey);
$cacheManager->remove($cacheUri, *); //second param is to clear this cache for all hosts
// $cacheManager->remove($cacheUri); when is like that it works for fine but only for the domain it's been called from.
The code above calls the sf core method sfMemCache->removePattern($pattern) which has:
$regexp = self::patternToRegexp($this->getOption('prefix').$pattern);
foreach ($this->getCacheInfo() as $key)
{
if (preg_match($regexp, $key))
{
$this->remove(substr($key, strlen($this->getOption('prefix'))));
}
}
and $this->getCacheInfo() is always empty and it can't clear anything.
It always throw "To use the "removePattern" method, you must set the "storeCacheInfo" option to "true"." exception. I cant find where does that cacheInfos() has to be filled or what exactly is its role.
Simplified version of my question is: "Why is $this->getCacheInfo empty"
If the removePattern method is throwing that error then memcached is not configured correctly in your factories.yml configuration.
The answer you want is discussed on this page under the heading 'Alternative Caching storage'
You need to set your class and parameter correctly to use the removePattern method. For instance:
view_cache:
class: sfMemcacheCache
param:
host: localhost
port: 11211
persistent: true
storeCacheInfo: true
You will also need to insure that the memcached daemon is operational. If memcached is running on the same host as the script in it's default configuration then the above settings should be fine. If you are running memcached on a separate host or you have multiple hosts sharing a memcached service then you must insure your host, port and firewall settings are correct for your environment.

how to run a function in a config file on codeigniter

How to run an function in config file ?
when i try this, i getting an error like this
Fatal error: Call to undefined function setting() in C:\wamp\www\urunsite\application\config\site.php on line 7
my config file
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// default language
$config['lang'] = 'tr';
// Default user role id
$config['default_role'] = setting('company', 'name');
/* End of file site.php */
the setting() function is auto loading.
please help me.
Config files are loaded early in execution, but you should have no problem running any functions there as long as they have been defined. If you need access to functions that aren't defined at config load time, you have no choice but to load the config file manually instead of automatically, or use a hook to load the needed resources. You will have to use the latter if you want to run helper functions in a core config file, custom config files are usually loaded on demand so it's a bit easier.
setting() isn't a valid function.. If it's your own custom function from a model file or elsewhere, you're not giving this config file proper access to that function.
You said that the setting() function is autoloading, but how is it being autoloaded? Is it from a custom Library? Helper? Model? Depending on which it is, you would need to call the function with:
$this->library_name->setting('company', 'name');
or
$this->model_name->setting('company', 'name');
etc.

Resources