Using data stored in cache/storage instead of database - laravel

I was thinking about using cache/storage to store source for api routes which doesnt update that much. I mean i would like to update stored data every one minute (example) and my routes will use that data as source instead of database as source. It will make less database queries. Im I thinking in good way? How to achieve that in Laravel?

You could setup an instance of memcached which is supported by Laravel. The Laravel caching documentation is a good place to start learning how to setup a cache driver for memcached. Once setup, your logic could look something like this:
if (Cache::has('key')) {
//your key exists in the cache. get it.
$value = Cache::get('key');
//and use it
useMyValue($value);
}
else
{
//the cache does not contain the key you are looking for
//you can get it from the DB and cache it.
//the next time your function runs it will get the value from cache instead
//of reading from the db
$value = Cache::get('key', function () {
return DB::table(...)->get();
});
//and use your value now like normal
useMyValue()
}

Related

Effiecient way to get data from database in foreach

I am loading data from excel. In foreach I am checking for each record if it does exist in database:
$recordExists = $this->checkIfExists($record);
function checkIfExists($record) {
$foundRecord = $this->repository->newQuery()
->where(..., $record[...])
->where(..., $record[...])
...
->get();
}
When the excel contains up to 1000 values which is relatively small piece of data - the code runs around 2 minutes. I am guessing this is very inefficient way to do it.
I was thinking of passing the array of loaded data to the method checkIfExists but then I could not query on the data.
What would be a way to proceed?
You can use laravel queue if you want to do a lot of work within a very short time. Your code will run on backend. Client can not recognize the process. just show a message to client that this process is under queue. Thats it
You can check the Official Documentation From Below Url
https://laravel.com/docs/5.8/queues
If you passes all the data from the database to the function (so no more queries to the database), you can use laravel collections functions to filter.
On of them is where => https://laravel.com/docs/5.8/collections#method-where
function checkIfExists($record, Collection $fetchedDataFromDatabase) {
// laravel collectons 'where' function
$foundRecord = $fetchedDataFromDatabase
->where(..., $record[...])
->where(..., $record[...]);
}
other helpful functions.
filter
contains

Make the entire symfony app read-only

I need to set up a live demo of a Symfony app.
How can I make everything read-only? The users should be able to try all the features but not make any persistent change visible to others.
I could remove the INSERT and UPDATE privileges to the mysql user, but that would be an ugly error 500 when they try to save something...
Quick and dirty way to make your entire app Read-Only.
AppBundle/EventSubscriber/EntitySubscriber.php
namespace AppBundle\EventSubscriber;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreFlushEventArgs;
class EntitySubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return [
'preFlush'
];
}
public function preFlush(PreFlushEventArgs $args)
{
$entityManager = $args->getEntityManager();
$entityManager->clear();
}
}
services.yml
app.entity_subscriber:
class: AppBundle\EventSubscriber\EntitySubscriber
tags:
- { name: doctrine.event_subscriber, connection: default }
I suppose that you've already made it. But if not:
Use dummy database. Copy it from original DB. Let them play. Drop it when you don't need it.
If you have no access to database creation and drop you can still do the trick. Just add temporary prefixes to table names in Doctrine entities. No need to rewrite the entire app, just a few lines. Run migrations to create new tables. Drop them whenever you want later.
Use virtual machine. Make a snapshot before the show. Roll back to the saved snapshot after the show.
These are more or less easy ways and they are platform independent.
Changing this based on the Symfony app level might have one of two disadvantages. You either do not save anything and thus your demo is not working so nice to show it to the customer. Or you have to do to much manipulations with the code and throw this huge work away right after the show.
Maybe you can use Session to do that or Memcache that you can implement in Symfony (Some examples are available on the web). Hope this will help.

How to save a collection for later use in Magento?

I want to write a cronjob in Magento that loads a product collection following certain parameters and saves it somewhere I can use in a cms/page.
My first approach was to use Magento's registry, but that doesn't work, ie a simple
Mage::register('label',$product_collection);
... doesn't work, as it seems "label" is not available in Mage::registry in my PHTML file...
Can someone point me in the right direction? Is this the correct approach? If so, how to make it work; if not, how to do it?
Thanks in advance!
Unfortunately, Mage::register will not get you where you want to go. The Mage registry keys are saved in the memory of the running PHP script, so it is scoped to the page request that is running the PHP code and therefor not shared between cron and your PHTML file.
In order to accomplish what you're looking for, you would need to cache the collection to persistent storage, such as hard-disk or Memcache. You may have to call the load() function specifically before caching, like so:
<?php
// ...
// ... Somewhere in your cron script
$product_collection = Mage::getModel('catalog/product')->getCollection()
->addFieldToFilter('some_field', 'some_value');
$product_collection->load(); // Magento kind of "lazy-loads" its data, so
// without this, you might not save yourself
// from executing MySQL code in the PHTML
// Serialize the data so it can be saved to cache as a string
$cacheData = serialize($product_collection);
$cacheKey = 'some sort of unique cache key';
// Save the serialized collection to the cache (defined in app/etc/local.xml)
Mage::app()->getCacheInstance()->save($cacheData, $cacheKey);
Then, in your PHTML file try:
<?php
// ...
$cacheKey = 'same unique cache key set in the cron script';
// Load the collection from cache
$product_collection = Mage::app()->getCacheInstance()->load($cacheKey);
// I'm not sure if Magento will auto-unserialize your object, so if
// the cache gives us a string, then we will do it ourselves
if ( is_string($product_collection) ) {
$product_collection = unserialize($product_collectoin);
}
// ...
See http://www.magentocommerce.com/boards/viewthread/240836

Codeigniter pre_system hook for DB driven dynamic controller selection - best approach?

Although I can tentatively see a solution to this, I was wondering if there may be a glaringly obvious simpler approach.
My aim is to use the first segment of a given URI to query the DB as to which controller should be run.
I assume I would have to reform the URI with the resultant controller name in segment 1, then allow the system to continue processing as normal (hence a pre_system hook).
Although not essential I would also like to hold a couple of other variables from the same DB request to be used later in the call stack, and assume this would have to be done using global variables?
Any better suggestions would be gladly received.
Thanks.
Should it be of use to anyone else, here is the code to acheive the desired result. This does however not take into account passing additional variables because I can live without them.
function set_controller()
{
include_once APPPATH.'config/database.php'; //Gather the DB connection settings
$link = mysql_connect($db[$active_group]['hostname'], $db[$active_group]['username'], $db[$active_group]['password']) or die('Could not connect to server.' ); //Connect to the DB server
mysql_select_db($db[$active_group]['database'], $link) or die('Could not select database.'); //Select the DB
$URI = explode('/',key($_GET)); //Break apart the URL variable
$query = 'SELECT * FROM theDomainTable WHERE domainName = "'.$URI[1].'"'; //Query the DB with the URI segment
if($results = mysql_fetch_array(mysql_query($query))){ //Only deal with controller requests that exist in the database
$URI[1] = $results['controllerName']; //Replace the controller segment
$_GET = array(implode('/',$URI)=>NULL); //Reconstruct and replace the GET variable
}
mysql_close($link); //Close the DB link
}
I wouldn't use global variables, Id prefer to store it in a library for retrieval later if possible. Global variables are kind of messy in the context of CI.
Although at pre_system Only the benchmark and hooks class have been loaded at this point. This means you're pretty-much stuck with global variables unless you can find a way to select the controller on pre_controller as all the base-classes are loaded and you can put the data somewhere more logical.

Ajax / Json How to run an INSERT/UPDATE into mysql

Again related with my weekend project, I'm trying to learn a bit more of web-development. So I'm putting in the list of features i want to implement, some stuff i absolutely have no idea how to do.
I've been reading tutorials on how to use ajax, but i can't find a simple one, that i can copy-paste (with one or two changes) to see it work before i go into the how it works.
What I've been searching is just a simple example on an ajax function, that triggers a mysql insert or update. Anyone as a simple example on how to do this? I think it would prove a nice start to learn it. (Ajax or Json are both ok).
Correct me if I'm mystaken: I'm basing myself on this tutorial. So as obviously the client side doesn't have access to database calls, what I should do, would be something like creating a code snippet to add stuff to the database right? For example create an "addcomment.php" that can be called with xhr.open(GET, "addcomment.php?comment=mycomment", true);
Sounds like you got it right. Use Ajax to call a server side script which then does the database work for you.
A good setup is to use a framework like jQuery on the client side. This framework will encode and decode JSON automatically. On the server side you could create a class that handles all the ajax (or rather, ajaj, since we are using JSON) requests. Here is a short PHP file that shows the general idea. Add more elements to the functionMap array, and add the respective functions to the class.
class Ajaj{
private $callback = "";
private $functionMap = array( "select" => 'getIt');
function Ajaj(){
if(array_key_exists('jsoncallback',$_GET)){
$this->callback=$_GET['jsoncallback'];
}
}
function parse(){
echo "$this->callback(";
if(array_key_exists('action', $_POST)){
$action = $_POST['action'];
if(array_key_exists($action, $this->functionMap)){
echo $this->functionMap[$action];
}
}else{
echo "{}";
}
echo ")";
}
function getIt(){
return json_encode(//get the database stuff here);
}
}
$ajaj = new Ajaj();
$ajaj->parse();

Resources